File size: 3,932 Bytes
3d7a961
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
import gradio as gr
import pandas as pd

# 1. Mock Inventory (Simulates your database)
INVENTORY = {
    "Apples (1kg)": 2.50,
    "Bananas (1kg)": 1.20,
    "Oranges (1kg)": 1.80,
    "Mangoes (1kg)": 4.00,
    "Strawberries (box)": 3.50,
    "Watermelon (each)": 5.00
}

def format_cart_df(cart):
    """Formats the cart state into a pandas DataFrame for UI display."""
    if not cart:
        return pd.DataFrame(columns=["Product", "Price ($)", "Quantity", "Total ($)"])
    df = pd.DataFrame(cart)
    # Reorder and format columns
    df = df[["name", "price", "quantity", "total"]]
    df.columns = ["Product", "Price ($)", "Quantity", "Total ($)"]
    return df

def calculate_total(cart):
    """Calculates the sum total of the cart."""
    total = sum(item['total'] for item in cart)
    return f"${total:.2f}"

def add_item(cart, fruit, quantity):
    """Adds a product to the cart or updates its quantity if it already exists."""
    if not fruit or quantity <= 0:
        return cart, format_cart_df(cart), gr.update(), calculate_total(cart)
    
    price = INVENTORY[fruit]
    found = False
    
    for item in cart:
        if item['name'] == fruit:
            item['quantity'] += quantity
            item['total'] = item['quantity'] * price
            found = True
            break
            
    if not found:
        cart.append({
            "name": fruit,
            "price": price,
            "quantity": quantity,
            "total": price * quantity
        })
        
    choices = [item['name'] for item in cart]
    return cart, format_cart_df(cart), gr.update(choices=choices), calculate_total(cart)

def remove_item(cart, fruit_to_remove):
    """Removes a specific product entirely from the cart."""
    if fruit_to_remove:
        cart = [item for item in cart if item['name'] != fruit_to_remove]
        
    choices = [item['name'] for item in cart]
    return cart, format_cart_df(cart), gr.update(choices=choices, value=None), calculate_total(cart)

# 2. Gradio User Interface
with gr.Blocks(theme=gr.themes.Soft(), title="Fruit Cart POS") as demo:
    gr.Markdown("# 🛒 Fruit Seller Shopping Cart System")
    gr.Markdown("Streamline billing by adding items from the inventory, removing mistakes, and generating an automated total bill.")
    
    # Hidden state to store cart data across interactions
    cart_state = gr.State([])

    with gr.Row():
        # Left Column: Controls
        with gr.Column(scale=1):
            gr.Markdown("### ➕ Add Products")
            fruit_dropdown = gr.Dropdown(choices=list(INVENTORY.keys()), label="Select Product")
            quantity_input = gr.Number(value=1, minimum=1, label="Quantity")
            add_btn = gr.Button("Add to Cart", variant="primary")
            
            gr.Markdown("---")
            
            gr.Markdown("### ➖ Remove Products")
            remove_dropdown = gr.Dropdown(choices=[], label="Select Product to Remove", interactive=True)
            remove_btn = gr.Button("Remove Item", variant="stop")

        # Right Column: Cart Display
        with gr.Column(scale=2):
            gr.Markdown("### 🧾 Current Cart & Billing")
            cart_display = gr.Dataframe(
                headers=["Product", "Price ($)", "Quantity", "Total ($)"], 
                interactive=False,
                row_count=(5, "dynamic")
            )
            total_display = gr.Textbox(label="Total Bill", value="$0.00", text_align="right")

    # 3. Event Listeners (Wiring UI to logic)
    add_btn.click(
        fn=add_item,
        inputs=[cart_state, fruit_dropdown, quantity_input],
        outputs=[cart_state, cart_display, remove_dropdown, total_display]
    )
    
    remove_btn.click(
        fn=remove_item,
        inputs=[cart_state, remove_dropdown],
        outputs=[cart_state, cart_display, remove_dropdown, total_display]
    )

# Run the app
if __name__ == "__main__":
    demo.launch()