[go: up one dir, main page]

0% found this document useful (0 votes)
6 views4 pages

Message 3

The document defines two classes, CustOrder and OrderItem, for managing customer orders and their items. It includes methods for adding and removing items, calculating totals, and validating input data. The main function demonstrates creating an order, adding items, modifying quantities, and removing items while displaying the order details.

Uploaded by

justintey19
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as TXT, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
6 views4 pages

Message 3

The document defines two classes, CustOrder and OrderItem, for managing customer orders and their items. It includes methods for adding and removing items, calculating totals, and validating input data. The main function demonstrates creating an order, adding items, modifying quantities, and removing items while displaying the order details.

Uploaded by

justintey19
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as TXT, PDF, TXT or read online on Scribd
You are on page 1/ 4

from datetime import timedelta, datetime

class CustOrder:
def __init__(self, ref_no: int, recipient: str, address: str, date_ordered:
datetime, date_delivered: datetime):
self._ref_no = ref_no
self.recipient = recipient
self.address = address
self._date_ordered = date_ordered
self._date_delivered = date_delivered
self.item_list = []

@property
def ref_no(self):
return self._ref_no

@ref_no.setter
def ref_no(self, value):
if value == "": # Prevent from entering an empty value
raise ValueError("Reference number cannot be empty, must be a positive
integer")
try:
value = int(value)
if value > 0:
self._ref_no = value
else:
raise ValueError("Reference number must be a positive integer")
except (ValueError, TypeError): # Prevent from entering a value that cannot
be converted into an integer (list, dictionary ...)
raise ValueError("Reference number must be a valid positive integer")

@property
def date_ordered(self):
return self._date_ordered

@date_ordered.setter
def date_ordered(self, value):
if isinstance(value, datetime): # Value wil be an instance of the datetime
class, not the class itself (Cannot use if value == datetime:)
self._date_ordered = value
else:
raise ValueError("Date ordered must be a datetime object")

@property
def date_delivered(self):
return self._date_delivered

@date_delivered.setter
def date_delivered(self, value):
if isinstance(value, datetime): # check if value is an instance of the
datetime class
self._date_delivered = value
else:
raise ValueError("Date delivered must be a datetime object")

def add_item(self, item: 'OrderItem'): # Because class OrderItem is defined


later, using '' for OrderItem allow to reference class name as string to avoid
circular reference issue
for existing_item in self.item_list:
if existing_item.prod == item.prod:
existing_item.qty = existing_item.qty + item.qty
return
self.item_list.append(item)

def remove_item(self, item: 'OrderItem'):


for existing_item in self.item_list:
if existing_item.prod == item.prod:
if existing_item.qty >= item.qty: # Check for multiple condition
(True or False)
item_new_qty = existing_item.qty - item.qty
if item_new_qty > 0:
existing_item.qty = item_new_qty
else:
self.item_list.remove(existing_item)
return True
else:
return False
return False

def get_total(self):
return sum(item.get_total_amount() for item in self.item_list) # Without
special mention, sum is +

def __str__(self):
order_detail = "=" * 70 + "\n" # Horizontal Line
order_detail += f"Reference Number: {self.ref_no}\n"
order_detail += f"Name: {self.recipient}\n"
order_detail += f"Address: {self.address}\n"
order_detail += f"Date ordered/delivered: {self.date_ordered.strftime('%d-
%b-%Y %I:%M%p')} / {self.date_delivered.strftime('%d-%b-%Y %I:%M%p')}\n" # strftime
is a method in datetime, format date and time into strings based on specific format
order_detail += "-" * 70 + "\n"
order_detail += f"{'S/N':<4}{'Product':<20}{'Price':>10}{'Qty':>8}
{'SubTotal':>16}\n" # <4 will align the 'S/N' to the left in width of 4, >10 will
align the 'Price' to the right within a total width of 10 character
i = 1
for item in self.item_list:
order_detail += f"{i:<4}{str(item)}\n"
i += 1
order_detail += "-" * 70 + "\n"
order_detail += f"{'Total':>48.5} ${self.get_total():,.2f}\n"
order_detail += "* - discounted price\n"
order_detail += "=" * 70
return order_detail

class OrderItem:
def __init__(self, prod: str, unit_price: float, discount: float, qty: int):
self.prod = prod
self.unit_price = unit_price #Calls the setter
self.discount = discount # Using self._discount = discount will bypass
validation
self.qty = qty # Using self.qty = qty will go through validation

@property
def unit_price(self):
return self._unit_price # Getter uses _unit_price, this needs to return the
internal unit_price
@unit_price.setter
def unit_price(self, value): # When self.unit_price = value is called
if value == "":
raise ValueError("Unit price cannot be empty, must be a positive
number")
try:
value = float(value)
if value > 0:
self._unit_price = value #Setter stores in unit_price after
validation
else:
raise ValueError("Unit price must be a positive number")
except (ValueError, TypeError):
raise ValueError("Unit price must be a valid positive number")

@property
def discount(self):
return self._discount

@discount.setter
def discount(self, value):
if value == "":
raise ValueError("Discount amount cannot be empty, must be a float
between 0 and 1")
try:
value = float(value)
if 0 <= value <= 1: #Using decimal point to represent percentage (0.20
as 20% discount)
self._discount = value
else:
raise ValueError("Discount must be a float between 0 and 1")
except (ValueError, TypeError):
raise ValueError("Discount must be a valid float between 0 and 1")

@property
def qty(self):
return self._qty

@qty.setter
def qty(self, value):
if value == "":
raise ValueError("Quantity cannot be empty")
try:
value = int(value)
if value > 0:
self._qty = value
else:
raise ValueError("Quantity must be a positive integer greater than
0")
except (ValueError, TypeError):
raise ValueError("Quantity must be a valid positive integer greater
than 0")

def get_total_amount(self):
return self._unit_price * self._qty * (1 - self._discount)

def get_discount_amount(self):
return (self._unit_price * self._qty) * self._discount
def get_actual_amount(self):
return self.get_total_amount()

def __str__(self):
price = self._unit_price * (1 - self._discount)
discount_indicator = "*" if self._discount > 0 else "" # Display a * beside
subtotal for the amount of product which has been given a discount
return f"{self.prod:<20}{price:>10.2f}{self._qty:>8} {'$':>5}
{self.get_total_amount():>10.2f}{discount_indicator}" # Display 2 digit after
decimal point (Floating-point number)

def main():
current_time = datetime.now()
delivery_time = current_time + timedelta(days=2) # Set delivery date is 2 day
later than date ordered (Based on the current time)

order = CustOrder(
ref_no=170772,
recipient="Erick Aspas Santos",
address="12, Saint George Lane, Singapore 543210",
date_ordered=current_time,
date_delivered=delivery_time
)

order.add_item(OrderItem(prod="Laptop", unit_price=2000, qty=1, discount=0))


order.add_item(OrderItem(prod="Phone", unit_price=3000, qty=2, discount=0))
order.add_item(OrderItem(prod="Keyboard", unit_price=100, qty=1, discount=0))
order.add_item(OrderItem(prod="Mouse", unit_price=35.50, qty=3, discount=0))
print(order)

print("\n\nAdd Earphone as a new item: ")


order.add_item(OrderItem(prod="Earphone", unit_price=55.50, qty=1, discount=0))
print(order)

print("\n\nAdd quantity for Keyboard: ")


order.add_item(OrderItem(prod="Keyboard", unit_price=100, qty=5, discount=0))
print(order)

print("\n\nRemove Phone from order: ")


order.remove_item(OrderItem(prod="Phone", unit_price=3000, qty=2, discount=0))
print(order)

print("\n\nDeduct Keyboard quantity from order: ")


order.remove_item(OrderItem(prod="Keyboard", unit_price=100, qty=4,
discount=0))
print(order)

print("\n\nRemove non-existing item(Tablet): ")


order.remove_item(OrderItem(prod="Tablet", unit_price=1500, qty=1, discount=0))
print(order)

if __name__ == "__main__":
main()

You might also like