initial_commit

This commit is contained in:
MelvynFaith
2026-11-02 14:58:43 +07:00
commit b06be6e0a7
20 changed files with 547 additions and 0 deletions
+65
View File
@@ -0,0 +1,65 @@
"""Model produk Catalog. Atribut khusus per kategori mengikuti AR-01 / FR-CAT-03."""
from abc import ABC, abstractmethod
from datetime import date
CLOTHING_SIZES = ("S", "M", "L", "XL")
class Product(ABC):
"""Kelas dasar produk. Subclass menentukan atribut khusus kategorinya."""
category = "generic"
def __init__(self, product_id, shop_id, name, price, on_hand, reserved=0):
if price < 0:
raise ValueError("price tidak boleh negatif")
if not 0 <= reserved <= on_hand:
raise ValueError("reserved harus di antara 0 dan on_hand")
self.product_id = product_id
self.shop_id = shop_id
self.name = name
self.price = price
self.on_hand = on_hand
self.reserved = reserved
@property
def available(self):
"""Stok yang dapat dipesan: onHand - reserved (glosarium SRS)."""
return self.on_hand - self.reserved
def is_orderable(self, today):
"""Aturan dasar: produk dapat dipesan jika masih ada stok tersedia."""
return self.available > 0
@abstractmethod
def attributes(self):
"""Atribut khusus kategori, dikembalikan sebagai dict."""
class FoodProduct(Product):
category = "food"
def __init__(self, product_id, shop_id, name, price, on_hand, expiry_date, reserved=0):
super().__init__(product_id, shop_id, name, price, on_hand, reserved)
self.expiry_date = expiry_date
def is_orderable(self, today):
"""Makanan tidak boleh dipesan setelah tanggal kedaluwarsa."""
return super().is_orderable(today) and today <= self.expiry_date
def attributes(self):
return {"expiryDate": self.expiry_date.isoformat()}
class ClothingProduct(Product):
category = "clothing"
def __init__(self, product_id, shop_id, name, price, on_hand, size, reserved=0):
if size not in CLOTHING_SIZES:
raise ValueError(f"size harus salah satu dari {CLOTHING_SIZES}")
super().__init__(product_id, shop_id, name, price, on_hand, reserved)
self.size = size
def attributes(self):
return {"size": self.size}