# SwiftCart — E‑commerce & POS Platform

SwiftCart is a full-stack retail solution: a **Flask** web storefront and REST API, plus optional **PyQt5** desktop POS clients that sync inventory, orders, and marketing data with the same backend.

This repository is organized as a **workspace** with three main parts:

| Path | Description |
|------|-------------|
| **`app_server/`** | Flask application: public web shop, `/api` for desktop/mobile, Socket.IO for live events, SQLite database |
| **`FYP Swiftcart/`** | Standalone **SwiftCart Enterprise** desktop app (POS, inventory, dashboard, coupons, etc.) |
| **`Swift_Cart/`** | **UR POS**–style desktop client with optional **SwiftCart API** sync to the same Flask server |

---

## Features

### Web storefront (`app_server`)

- Product catalog, categories, collection filters, wishlist, cart, checkout  
- Customer accounts (signup/login), **My Orders** (linked to `user_id` + legacy email/phone match), reviews  
- Home page sections: Recently Viewed, Gifts, Deals, Video Showcases (per-product flags)  
- Promo codes at checkout (`Coupon` model + API)  
- **Admin panel** (sidebar): Overview, Sales & analytics, Cash & finance, Orders, Online customers, Inventory alerts — `/admin` (requires `role=admin`)  
- Real-time **Socket.IO** notifications for new online orders (desktop can listen)

### REST API (`/api`)

- Products, categories, orders, coupons, dashboard stats, finance, khata, etc.  
- Used by desktop apps to push/pull catalog and run back-office flows  

### Desktop clients

- **FYP Swiftcart**: `desktop_app/config.py` points to `http://127.0.0.1:5000/api`  
- **Swift_Cart**: `swiftcart_api/config.py` — same API, configurable via environment variables (see below)

---

## Requirements

- **Python 3.10+** (3.11+ recommended)  
- **pip**  
- Optional: **MySQL** if you adapt `Swift_Cart` models (default project uses SQLite for Flask)

Install Python dependencies from the **workspace root**:

```bash
pip install -r requirements.txt
```

Contents typically include: Flask, Flask-SQLAlchemy, Flask-SocketIO, PyMySQL, python-dotenv, PyQt5, requests, matplotlib.

---

## Quick start — Flask server

Run from the **directory that contains `app_server` and `run.py`** (workspace root):

```bash
python run.py
```

- **App URL:** `http://127.0.0.1:5000`  
- **Web shop:** `http://127.0.0.1:5000/` (home)  
- **API base:** `http://127.0.0.1:5000/api`  
- **Admin UI:** `http://127.0.0.1:5000/admin` (after logging in as admin on the site)

The server uses **SQLite** by default:

- Database file: **`swiftcart_cloud.db`** (created next to the app root when `app_server` runs)

### Default web admin user (first run)

If no `admin` user exists, the app creates one:

- **Username:** `admin`  
- **Email:** `admin@swiftcart.com`  
- **Password:** `admin`  
- **Role:** `admin`  

Log in via the **web** login page, then open **Admin Panel** from the user menu.

> **Security:** Change the default password and `SECRET_KEY` in `app_server/__init__.py` before production.

---

## Configuration

### `app_server`

| Setting | Location | Notes |
|--------|----------|--------|
| Database | `SQLALCHEMY_DATABASE_URI` in `app_server/__init__.py` | Default `sqlite:///swiftcart_cloud.db` |
| Currency | `app_server/currency_config.py` | Display `Rs.` / PKR by default |
| Secret key | `SECRET_KEY` in `create_app()` | Replace for production |

### Swift_Cart → Flask (`Swift_Cart/src/swiftcart_api/config.py`)

Override with environment variables:

| Variable | Purpose |
|----------|---------|
| `SWIFTCART_API_URL` | API base, default `http://127.0.0.1:5000/api` |
| `SWIFTCART_SERVER_BASE` | Origin for static uploads, default `http://127.0.0.1:5000` |
| `SWIFTCART_ENABLED` | `1` / `0` — enable API checks |
| `SWIFTCART_SYNC_PRODUCTS` | Push local products to Flask (default on in many setups) |
| `SWIFTCART_PULL_FROM_WEB` | Link `swiftcart_remote_id` from web catalog |
| `SWIFTCART_PRUNE_REMOTE` | Delete remote products not in POS (dangerous — understand before enabling) |
| `SWIFTCART_RESET_KEY` | Must match server for admin reset endpoints |

### FYP Swiftcart desktop

Edit `FYP Swiftcart/desktop_app/config.py`:

- `API_BASE_URL` — API base URL  
- `SERVER_BASE_URL` — Flask static root for product images  

---

## Important URLs

| URL | Description |
|-----|-------------|
| `/` | Store home |
| `/collection` | Catalog / filters |
| `/login`, `/signup` | Customer auth |
| `/checkout` | Checkout (requires login) |
| `/my-orders` | Purchase history |
| `/wishlist` | Wishlist |
| `/admin`, `/admin/overview` | Admin dashboard (sidebar) |
| `/admin/sales`, `/admin/finance`, `/admin/orders`, `/admin/customers`, `/admin/inventory` | Admin sections |
| `/low-stock` | Low-stock list (also linked from admin) |
| `/api/...` | REST API (see `app_server/api/routes.py`) |

---

## Architecture (high level)

```
┌─────────────────┐     HTTP/REST      ┌──────────────────┐
│  PyQt5 POS      │ ◄──────────────►  │  Flask app_server │
│  (FYP / UR POS) │     /api          │  + SQLite +       │
└─────────────────┘                   │  Socket.IO        │
                                      └────────┬──────────┘
┌─────────────────┐     HTTP           │      │
│  Web browser     │ ◄──────────────────┘      │
│  (customers)     │  templates + sessions   │
└─────────────────┘
```

- **Orders** from the web set `user_id` when the customer is logged in so **My Orders** works; legacy rows can match by email/phone.  
- **Products** on the web store can expose **home sections** via `show_in_*` flags; desktop POS forms should set the same fields when syncing.

---

## Running the FYP Swiftcart desktop app

From `FYP Swiftcart` (with dependencies installed):

```bash
python desktop_app/main.py
```

Ensure the Flask server is running first if you use online features, inventory sync, and coupons.

---

## Running Swift_Cart (UR POS)

Typical entry (adjust paths to your install):

```bash
cd Swift_Cart/src
python main.py
```

Configure `swiftcart_api` env vars if the API is not on `localhost:5000`.

---

## Development notes

- **Migrations:** Mostly `db.create_all()`; new columns sometimes added via helper functions in `Swift_Cart` SQLAlchemy models — check `models/__init__.py` for `_ensure_*` ALTER patterns.  
- **Coupons:** `Coupon` must be imported in `app_server/__init__.py` so `create_all()` creates the `coupon` table.  
- **Tests:** Add your own; none are required for basic run.  

---

## Troubleshooting

| Issue | What to check |
|-------|----------------|
| API connection refused | Flask running on port 5000, firewall, correct `API_BASE_URL` |
| My Orders empty | Orders must set `user_id` at checkout; or use matching email/phone for old rows |
| Desktop sync fails | `SWIFTCART_ENABLED`, network, API auth, server logs |
| Admin panel 403 | User `role` must be `admin` in the `user` table |
| Coupon table missing | Restart app after `Coupon` import in `create_app`; or run `db.create_all()` |

---

## License

Specify your license here (proprietary / MIT / etc.).

---

## Credits

SwiftCart / UR POS — adjust attribution for your team or organization.
