class MainApp(App):

    string_property = StringProperty()

    def __init__(self, **kwargs):

        """Initializer to construct the app"""

        super(MainApp, self).__init__(**kwargs)
        self.item_list = ItemList()
        stock = open("inventory.csv", "r+")
        for items in stock:
            self.item_list.store(items)

    def build(self):
        self.title = "A2"
        self.root = Builder.load_file('layout.kv')
        return self.root

    def itemlist(self):

        """Function to show all the list item in the inventory.csv"""

        self.root.ids.itemlistbox.clear_widgets()
        self.root.ids.bottomlabel.text = 'Choose action from the left menu, then select items on the right'
        self.root.ids.listitem.background_color = (1, 1, 0.5, 1)
        self.root.ids.hireitem.background_color = (1, 1, 1, 1)
        self.root.ids.returnitem.background_color = (1, 1, 1, 1)
        self.root.ids.confirm.background_color = (1, 1, 1, 1)
        self.root.ids.additem.background_color = (1, 1, 1, 1)
        for items in self.item_list:
            name, desc, price, availability = items.split(",")
            if "in" in availability:
                tempbutton = Button(text=name, background_color=(0, 1, 0, 1))
            else:
                tempbutton = Button(text=name, background_color=(0.9, 0.3, 0.5, 1))
            tempbutton.bind(on_press=self.pressitem)
            self.root.ids.itemlistbox.add_widget(tempbutton)


    def itemhire(self):

        """Function to hire the items from inventory.csv, red color item mean the item is out"""

        self.root.ids.itemlistbox.clear_widgets()
        self.root.ids.bottomlabel.text = 'Choose action from the left menu, then select items on the right'
        self.root.ids.listitem.background_color = (1, 1, 1, 1)
        self.root.ids.hireitem.background_color = (1, 1, 0.5, 1)
        self.root.ids.returnitem.background_color = (1, 1, 1, 1)
        self.root.ids.confirm.background_color = (1, 1, 1, 1)
        self.root.ids.additem.background_color = (1, 1, 1, 1)
        for items in self.item_list:
            name, desc, price, availability = items.split(",")
            if "in" in availability:
                tempbutton = Button(text=name, background_color=(0, 1, 0, 1))
            else:
                tempbutton = Button(text=name, background_color=(0.9, 0.3, 0.5, 1))
            tempbutton.bind(on_press=self.pressitem)
            self.root.ids.itemlistbox.add_widget(tempbutton)

    def itemreturn(self):

        """Function to return the items that is out from the inventory.csv"""

        self.root.ids.itemlistbox.clear_widgets()
        self.root.ids.bottomlabel.text = 'Choose action from the left menu, then select items on the right'
        self.root.ids.listitem.background_color = (1, 1, 1, 1)
        self.root.ids.hireitem.background_color = (1, 1, 1, 1)
        self.root.ids.returnitem.background_color = (1, 1, 0.5, 1)
        self.root.ids.confirm.background_color = (1, 1, 1, 1)
        self.root.ids.additem.background_color = (1, 1, 1, 1)
        for items in self.item_list:
            name, desc, price, availability = items.split(",")
            if "in" in availability:
                tempbutton = Button(text=name, background_color=(0, 1, 0, 1))
            else:
                tempbutton = Button(text=name, background_color=(0.9, 0.3, 0.5, 1))
            tempbutton.bind(on_press=self.pressitem)
            self.root.ids.itemlistbox.add_widget(tempbutton)


    def pressitem(self, instance):

        """Function will show the description of the selected item the bottomlabel
        will also change when the item_return or item_hire button is being selected"""

        for items in self.item_list:
            name, desc, price, availability = items.split(",")
            if instance.text == name:
                if self.root.ids.listitem.background_color == [1, 1, 0.5, 1]:
                    self.root.ids.bottomlabel.text = "{} ({}), ${:,.2f} is {}".format(name, desc, float(price), availability)
                elif self.root.ids.hireitem.background_color == [1, 1, 0.5, 1]:
                    if "in" in availability:
                        self.root.ids.bottomlabel.text = "Hiring: {} for ${:,.2f}".format(name, float(price))
                    else:
                        self.root.ids.bottomlabel.text = "Hiring: no items for $0.00"
                elif self.root.ids.returnitem.background_color == [1, 1, 0.5, 1]:
                    if "out" in availability:
                        self.root.ids.bottomlabel.text = "Returning: {}".format(name)
                    else:
                        self.root.ids.bottomlabel.text = "Returning: no items"

    def confirm(self):

        """Function to make changes on the inventory.csv file"""

        itemcount = 0
        with open("inventory.csv") as itemfile:
            read = itemfile.readlines()
        for items in read:
            name, desc, price, availability = items.split(",")
            if name in self.root.ids.bottomlabel.text:
                if self.root.ids.hireitem.background_color == [1, 1, 0.5, 1]:
                    self.item_list.clear()
                    read[itemcount] = read[itemcount].replace("in", "out")
                    with open("inventory.csv", "w") as itemfile:
                        itemfile.writelines(read)
                    for items in read:
                        self.item_list.store(items)
                    itemfile.close()
                    self.itemlist()
                elif self.root.ids.returnitem.background_color == [1, 1, 0.5, 1]:
                    self.item_list.clear()
                    read[itemcount] = read[itemcount].replace("out","in")
                    with open("inventory.csv", "w") as itemfile:
                        itemfile.writelines(read)
                    for items in read:
                        self.item_list.store(items)
                    itemfile.close()
                    self.itemlist()
            itemcount += 1

    def additem(self):

        """Function to display the popup window"""

        self.root.ids.listitem.background_color = (1, 1, 1, 1)
        self.root.ids.hireitem.background_color = (1, 1, 1, 1)
        self.root.ids.returnitem.background_color = (1, 1, 1, 1)
        self.root.ids.confirm.background_color = (1, 1, 1, 1)
        self.root.ids.additem.background_color = (1, 1, 0.5, 1)
        self.string_property = 'Enter new item'
        self.root.ids.popupbox.open()

    def save(self, name, desc, price, instruction):

        """Function to save the input item to inventory.csv and dismiss the pop up window after saving"""

        def error(price): # error checking
            try:
                float(price)
                return True
            except ValueError:
                return False

        if name.strip == '' or desc == '' or price == '':
            instruction.text = "All fields must be completed"
        elif error(price) == False:
            instruction.text = "Price must be valid number"
        elif error(price) == True and float(price) < 0:
            instruction.text = "Price cannot be negative"
        else:
            additems = "\n{},{},{},in".format(name, desc, float(price))
            with open("inventory.csv", "a") as itemfile:
                itemfile.writelines(additems)
            self.item_list.store(additems)
            self.cancel()
            self.itemlist()

    def cancel(self):

        """Function to dismiss pop up window"""

        self.root.ids.popupbox.dismiss()
        self.root.ids.itemname.text = ""
        self.root.ids.desc.text = ""
        self.root.ids.priceinput.text = ""
class Assignment2(App):

    def __init__(self, **kwargs):
        super (Assignment2, self).__init__(**kwargs)
        self.item_list = ItemList()
        items_storage = open("items.csv", "r+")
        for line in items_storage:
            self.item_list.store(line)

    def build(self):

        self.title = "Items Hire"
        self.root = Builder.load_file('Assignment2.kv')
        self.itemlist()
        return self.root

    def itemlist(self):

        self.root.ids.itemsBox.clear_widgets()
        self.root.ids.label.text = 'Choose action from the left menu, then select items on the right'
        self.root.ids.item_list.background_color =  [0, 0.5, 0.5, 1]
        self.root.ids.hire_item.background_color = [1, 1, 1, 1]
        self.root.ids.return_item.background_color = [1, 1, 1, 1]
        self.root.ids.confirm.background_color = [1, 1, 1, 1]
        self.root.ids.add_item.background_color = [1, 1, 1, 1]
        item_count = 0
        for line in self.item_list:
            name, description, price_per_day, availability = line.split(",")
            if "in" in availability:
                temp_button = Button(text=name, background_color=[0, 1, 0, 1])
            else:
                temp_button = Button(text=name, background_color=[0.9, 0.3, 0.5, 1])
            temp_button.bind(on_press=self.press_item)
            self.root.ids.itemsBox.add_widget(temp_button)
            item_count += 1

    def itemreturn(self):

        self.root.ids.itemsBox.clear_widgets()
        self.root.ids.label.text = 'Choose action from the left menu, then select items on the right'
        self.root.ids.item_list.background_color = [1, 1, 1, 1]
        self.root.ids.hire_item.background_color = [1, 1, 1, 1]
        self.root.ids.return_item.background_color = [0, 0.5, 0.5, 1]
        self.root.ids.confirm.background_color = [1, 1, 1, 1]
        self.root.ids.add_item.background_color = [1, 1, 1, 1]
        for line in self.item_list:
            name, description, price_per_day, availability = line.split(",")
            if "in" in availability:
                temp_button = Button(text=name, background_color=[0, 1, 0, 1])
            else:
                temp_button = Button(text=name, background_color=[0.9, 0.3, 0.5, 1])
            temp_button.bind(on_press=self.press_item)
            self.root.ids.itemsBox.add_widget(temp_button)

    def itemhire(self):
        self.root.ids.itemsBox.clear_widgets()
        self.root.ids.item_list.background_color = [1, 1, 1, 1]
        self.root.ids.hire_item.background_color = [0, 0.5, 0.5, 1]
        self.root.ids.return_item.background_color = [1, 1, 1, 1]
        self.root.ids.confirm.background_color = [1, 1, 1, 1]
        self.root.ids.add_item.background_color = [1, 1, 1, 1]
        for line in self.item_list:
            name, description, price_per_day, availability = line.split(",")
            if "in" in availability:
                temp_button = Button(text=name, background_color=[0, 1, 0, 1])
            else:
                temp_button = Button(text=name, background_color=[0.9, 0.3, 0.5, 1])
            temp_button.bind(on_press=self.press_item)
            self.root.ids.itemsBox.add_widget(temp_button)

    def press_item(self, instance):

        for line in self.item_list:
            name, description, price_per_day, availability = line.split(",")
            if instance.text == name:
                if self.root.ids.item_list.background_color == [0, 0.5, 0.5, 1]:
                    self.root.ids.label.text = "{} ({}), ${:,.2f} is {}".format(name, description, float(price_per_day), availability)
                elif self.root.ids.hire_item.background_color == [0, 0.5, 0.5, 1]:
                    if "in" in availability:
                        self.root.ids.label.text = "Hiring: {} for ${:,.2f}".format(name, float(price_per_day))
                    else:
                        self.root.ids.label.text = "Hiring: no items for $0.00"
                elif self.root.ids.return_item.background_color == [0, 0.5, 0.5, 1]:
                    if "out" in availability:
                        self.root.ids.label.text = "Returning: {}".format(name)
                    else:
                        self.root.ids.label.text = "Returning: no items"

    def confirm(self): #this made a confirm change on the hire/return

        item_count = 0
        with open("items.csv") as file:
            read_items = file.readlines()
        for line in read_items:
            name, description, price_per_day, availibility = line.split(",")
            if name in self.root.ids.label.text:
                if self.root.ids.hire_item.background_color == [0, 0.5, 0.5, 1]:
                    self.item_list.clear()
                    read_items[item_count] = read_items[item_count].replace("in", "out")
                    with open("items.csv", "w") as file:
                        file.writelines(read_items)
                    for line in read_items:
                        self.item_list.store(line)
                    file.close()
                    self.itemlist()
                elif self.root.ids.return_item.background_color == [0, 0.5, 0.5, 1]:
                    self.item_list.clear()
                    read_items[item_count] = read_items[item_count].replace("out", "in")
                    with open("items.csv", "w") as file:
                        file.writelines(read_items)  # commit changes to the csv file
                    for line in read_items:
                        self.item_list.store(line)
                    file.close()
                    self.itemlist()
            item_count += 1

    def save(self, name, description, price_per_day, availibility): #saves the details in the popup menu

        def price_check(cost):
            try:
                float(cost)
                return True
            except ValueError:
                return False

        if len(name.strip()) == 0 or len(description.strip()) == 0 or len(price_per_day.strip()) == 0:
            availibility.text = "All fields must be completed"
        elif price_check(price_per_day) == False:
            availibility.text = "Price must be valid number"
        elif price_check(price_per_day) == True and float(price_per_day) < 0:
            availibility.text = "Price cannot be negative"
        else:
            add_item = "\n{},{},{},in".format(name, description, float(price_per_day))
            with open("items.csv", "a") as file:
                file.writelines(add_item)
            self.item_list.store(add_item)
            self.cancel()
            self.itemlist()

    def additem(self): #opens up the popup menu

        self.root.ids.item_list.background_color = [1, 1, 1, 1]
        self.root.ids.hire_item.background_color = [1, 1, 1, 1]
        self.root.ids.return_item.background_color = [1, 1, 1, 1]
        self.root.ids.confirm.background_color = [1, 1, 1, 1]
        self.root.ids.add_item.background_color = [0, 0.5, 0.5, 1]
        self.root.ids.popup.open()
    def cancel(self): #turn back the popup as it's default
        self.root.ids.itemName.text = ""
        self.root.ids.description.text = ""
        self.root.ids.price_per_day.text = ""
        self.root.ids.popup.dismiss() #closes the popup
Пример #3
0
class ItemsForHire(App):

    # INITIALISER

    def __init__(self, **kwargs):
        """
        Acts as the constructor for ItemsForHire which loads the items.csv to read the files and stores them in
        a list.
        """
        super(ItemsForHire, self).__init__(**kwargs)
        self.list_item = ItemList()
        item_lines_list = open("items.csv", "r+")
        self.items = []
        for line in item_lines_list:
            self.items.append(line + ",False")
            self.list_item.store(line)
        self.names = []
        self.price = 0.00

# LOAD KIVY FILE

    def build(self):
        """
        Is used to set the title of the app and loads the Kivy file for listing, hiring, returning, confirming.
        """
        self.title = "Equipment Hire"
        self.root = Builder.load_file('main.kv')
        self.listing_items()
        return self.root

# LIST ITEMS

    def listing_items(self):
        """
        Is used to list items present in items.csv
        """
        self.root.ids.item_buttons.clear_widgets()
        self.root.ids.list_item.background_color = (0, 0.99, 0.99, 1)
        self.root.ids.hire_item.background_color = (1, 1, 1, 1)
        self.root.ids.return_item.background_color = (1, 1, 1, 1)
        item_count = 0
        for line in self.list_item:
            name, desc, price, hire = line.split(',')
            if "in" in hire:
                temp_button = Button(text=name, background_color=(0, 1, 0, 1))
            else:
                temp_button = Button(text=name, background_color=(1, 0, 0, 1))
            temp_button.bind(on_press=self.item_press)
            self.root.ids.item_buttons.add_widget(temp_button)
            item_count += 1

# HIRE ITEMS

    def hiring_items(self):
        """
        Is used to hire an item if it is available
        """
        self.names = []
        self.price = 0.00
        for item_count, line in enumerate(self.items):
            part = line.split(',')
            part[4] = "False"
            self.items[item_count] = "{},{},{},{},{}".format(
                str(part[0]).strip("[]").replace("'", ""),
                str(part[1]).strip("[]").replace("'", ""),
                str(part[2]).strip("[]").replace("'", ""),
                part[3].replace("'", ""),
                str(part[4]).strip("[]").replace("'", ""))
        self.root.ids.item_buttons.clear_widgets()
        self.root.ids.list_item.background_color = (1, 1, 1, 1)
        self.root.ids.hire_item.background_color = (0, 0.99, 0.99, 1)
        self.root.ids.return_item.background_color = (1, 1, 1, 1)
        for line in self.list_item:
            name, desc, price, hire = line.split(',')
            if "in" in hire:
                temp_button = Button(text=name, background_color=(0, 1, 0, 1))
            else:
                temp_button = Button(text=name, background_color=(1, 0, 0, 1))
            temp_button.bind(on_press=self.item_press)
            self.root.ids.item_buttons.add_widget(temp_button)

# RETURN ITEM

    def returning_items(self):
        """
        Is used to return an item that has been hired.
        """
        self.names = []
        for item_count, line in enumerate(self.items):
            part = line.split(',')
            part[4] = "False"
            self.items[item_count] = "{},{},{},{},{}".format(
                str(part[0]).strip("[]").replace("'", ""),
                str(part[1]).strip("[]").replace("'", ""),
                str(part[2]).strip("[]").replace("'", ""),
                part[3].replace("'", ""),
                str(part[4]).strip("[]").replace("'", ""))
        self.names = []
        self.root.ids.item_buttons.clear_widgets()
        self.root.ids.list_item.background_color = (1, 1, 1, 1)
        self.root.ids.hire_item.background_color = (1, 1, 1, 1)
        self.root.ids.return_item.background_color = (0, 0.99, 0.99, 1)
        for line in self.list_item:
            name, desc, price, hire = line.split(',')
            if 'in' in hire:
                temp_button = Button(text=name, background_color=(0, 1, 0, 1))
            else:
                temp_button = Button(text=name, background_color=(1, 0, 0, 1))
            temp_button.bind(on_press=self.item_press)
            self.root.ids.item_buttons.add_widget(temp_button)

# CONFIRM ITEM TO BE HIRED OR RETURNED

    def confirming_items(self):
        """
        Is used to confirm an item when it is needed to be hired or returned
        """
        with open("items.csv") as file:
            item_lines_list = file.readlines()
        for instance in self.root.ids.item_buttons.children:
            for item_count in range(len(self.items)):
                self.part = self.items[item_count].split(',')
                if instance.text in self.part:
                    if (self.part)[3] == 'in\n' and (self.part)[4] == 'True':
                        (self.part)[3] = 'out\n'
                        (self.part)[4] = "False"
                        self.items[item_count] = "{},{},{},{},{}".format(
                            str(self.part[0]).strip("[]").replace("'", ""),
                            str(self.part[1]).strip("[]").replace("'", ""),
                            str(self.part[2]).strip("[]").replace("'", ""),
                            self.part[3].replace("'", ""),
                            str(self.part[4]).strip("[]").replace("'", ""))
                        item_lines_list[item_count] = item_lines_list[
                            item_count].replace('in', 'out')
                        self.list_item.clear()
                        for line in item_lines_list:
                            self.list_item.store(line)
                        with open("items.csv", "w") as file:
                            file.writelines(item_lines_list)
                        self.listing_items()
                    elif (self.part)[3] == 'out\n' and (
                            self.part)[4] == 'True':
                        (self.part)[3] = 'in\n'
                        (self.part)[4] = "False"
                        self.items[item_count] = "{},{},{},{},{}".format(
                            str(self.part[0]).strip("[]").replace("'", ""),
                            str(self.part[1]).strip("[]").replace("'", ""),
                            str(self.part[2]).strip("[]").replace("'", ""),
                            self.part[3].replace("'", ""),
                            str(self.part[4]).strip("[]").replace("'", ""))
                        item_lines_list[item_count] = item_lines_list[
                            item_count].replace('out', 'in')
                        self.list_item.clear()
                        for line in item_lines_list:
                            self.list_item.store(line)
                        with open("items.csv", "w") as file:
                            file.writelines(item_lines_list)
                        self.listing_items()

    def item_press(self, instance):
        """
        This converts an item from hire to hired and also displays message if an item is available to hire inside the
         label.
        """
        item_count = 0
        for line in self.list_item:
            name, desc, price, hire = line.split(',')
            if instance.text == name:
                if self.root.ids.list_item.background_color == [
                        0, 0.99, 0.99, 1
                ]:
                    self.root.ids.main_label.text = "{} ({}), ${:,.2f} is {}".format(
                        name, desc, float(price), hire)

                elif self.root.ids.hire_item.background_color == [
                        0, 0.99, 0.99, 1
                ]:
                    part = self.items[item_count].split(",")
                    if "in" in hire:
                        if part[4] == "False":
                            part[4] = "True"
                            self.items[item_count] = "{},{},{},{},{}".format(
                                str(part[0]).strip("[]").replace("'", ""),
                                str(part[1]).strip("[]").replace("'", ""),
                                str(part[2]).strip("[]").replace("'", ""),
                                part[3].replace("'", ""),
                                str(part[4]).strip("[]").replace("'", ""))
                            self.root.ids.main_label.text = "Hiring: {} for ${:,.2f}.".format(
                                name, float(price))
                    else:
                        self.root.ids.main_label.text = "Hiring nothing."

                elif self.root.ids.return_item.background_color == [
                        0, 0.99, 0.99, 1
                ]:
                    part = self.items[item_count].split(",")
                    if "out" in hire:
                        if part[4] == "False":
                            part[4] = "True"
                            self.items[item_count] = "{},{},{},{},{}".format(
                                str(part[0]).strip("[]").replace("'", ""),
                                str(part[1]).strip("[]").replace("'", ""),
                                str(part[2]).strip("[]").replace("'", ""),
                                part[3].replace("'", ""),
                                str(part[4]).strip("[]").replace("'", ""))
                            self.root.ids.main_label.text = "Returning: {}.".format(
                                name)
                    else:
                        self.root.ids.main_label.text = "Returning nothing."
            item_count += 1


# ADDING A NEW ITEM

    def adding_new_items(self):
        """
        Is used to add a new item to the csv file and I decided to use a different Kivy file because I found it to be
        messy when it was implemented on the main Kivy file.
        """
        self.root.ids.item_buttons.clear_widgets()
        self.root.ids.list_item.background_color = (1, 1, 1, 1)
        self.root.ids.hire_item.background_color = (1, 1, 1, 1)
        self.root.ids.return_item.background_color = (1, 1, 1, 1)

        new_item = Builder.load_file('new_item.kv')
        self.pop_up = Popup(title="Add New Item", content=new_item)
        self.pop_up.open()

    def saving_new(self, name, desc, price, label):
        """
        Is used to save new item to the csv and also does error checking incase the user enters funny values.
        """
        def price_validity(price):
            try:
                float(price)
                return True
            except ValueError:
                return False

        if len(name.strip()) == 0 or len(desc.strip()) == 0 or len(
                price.strip()) == 0:
            label.text = "All fields must be completed"
        elif price_validity(price) == False:
            label.text = "Price must be valid number"
        elif price_validity(price) == True and float(price) < 0:
            label.text = "Price cannot be negative"
        else:
            item_new = "{},{},{},in".format(name, desc, float(price))
            with open("items.csv", "a") as file:
                file.writelines(item_new)
            self.list_item.store(item_new)
            self.cancelling_new()
            self.listing_items()

    def cancelling_new(self):
        """
        Is used when the user decides not to add a new item.
        """
        self.pop_up.dismiss()
        self.listing_items()

    def on_stop(self):
        """
        Displays the number of items present in items.csv after the App is closed.
        """
        num_lines = sum(1 for line in open('items.csv'))
        print("{} items saved to items.csv".format(num_lines))