PerplexityA comprehensive Enterprise Resource Planning system with product, customer, supplier, and sales management. Features real-time inventory tracking and dashboard analytics.
Copy the syntax below into a file named erp_project.txt and run:
Access dashboard at: http://localhost:5000

erp_system/
├─ static/
│ └─ style.css(begincontenu)
│ /* ERP System - Modern Admin Dashboard CSS */
│ :root {
│ --primary-color: #2563eb;
│ --primary-dark: #1d4ed8;
│ --secondary-color: #64748b;
│ --success-color: #10b981;
│ --danger-color: #ef4444;
│ --warning-color: #f59e0b;
│ --info-color: #3b82f6;
│ --dark-color: #1f2937;
│ --light-color: #f8fafc;
│ --gray-100: #f1f5f9;
│ --gray-200: #e2e8f0;
│ --gray-300: #cbd5e1;
│ --gray-400: #94a3b8;
│ --gray-500: #64748b;
│ --gray-600: #475569;
│ --gray-700: #334155;
│ --gray-800: #1e293b;
│ --gray-900: #0f172a;
│ --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.05);
│ --shadow: 0 1px 3px 0 rgb(0 0 0 / 0.1), 0 1px 2px -1px rgb(0 0 0 / 0.1);
│ --shadow-md: 0 4px 6px -1px rgb(0 0 0 / 0.1), 0 2px 4px -2px rgb(0 0 0 / 0.1);
│ --shadow-lg: 0 10px 15px -3px rgb(0 0 0 / 0.1), 0 4px 6px -4px rgb(0 0 0 / 0.1);
│ --shadow-xl: 0 20px 25px -5px rgb(0 0 0 / 0.1), 0 8px 10px -6px rgb(0 0 0 / 0.1);
│ --border-radius: 0.5rem;
│ --border-radius-lg: 0.75rem;
│ --transition: all 0.2s ease-in-out;
│ }
│
│ * {
│ margin: 0;
│ padding: 0;
│ box-sizing: border-box;
│ }
│
│ body {
│ font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, sans-serif;
│ line-height: 1.6;
│ color: var(--gray-700);
│ background-color: var(--light-color);
│ }
│
│ /* Navbar */
│ .navbar {
│ background: var(--gray-900);
│ padding: 1rem 0;
│ box-shadow: var(--shadow-lg);
│ position: sticky;
│ top: 0;
│ z-index: 1000;
│ }
│
│ .nav-brand {
│ display: flex;
│ align-items: center;
│ color: white;
│ text-decoration: none;
│ font-weight: 700;
│ font-size: 1.5rem;
│ }
│
│ .nav-brand h1 {
│ margin: 0;
│ color: var(--primary-color);
│ }
│
│ .nav-menu {
│ display: flex;
│ list-style: none;
│ margin: 0;
│ padding: 0;
│ }
│
│ .nav-menu li {
│ margin-left: 2rem;
│ }
│
│ .nav-menu a {
│ color: var(--gray-300);
│ text-decoration: none;
│ padding: 0.5rem 1rem;
│ border-radius: var(--border-radius);
│ transition: var(--transition);
│ font-weight: 500;
│ }
│
│ .nav-menu a:hover {
│ background: var(--gray-800);
│ color: white;
│ }
│
│ /* Container */
│ .container {
│ max-width: 1400px;
│ margin: 0 auto;
│ padding: 2rem;
│ }
│
│ /* Page Header */
│ .page-header {
│ display: flex;
│ justify-content: space-between;
│ align-items: center;
│ margin-bottom: 2rem;
│ padding-bottom: 1rem;
│ border-bottom: 2px solid var(--gray-200);
│ }
│
│ .page-header h2 {
│ font-size: 2rem;
│ font-weight: 700;
│ color: var(--gray-900);
│ margin: 0;
│ }
│
│ /* Buttons */
│ .btn {
│ display: inline-flex;
│ align-items: center;
│ gap: 0.5rem;
│ padding: 0.75rem 1.5rem;
│ border: none;
│ border-radius: var(--border-radius);
│ font-weight: 600;
│ text-decoration: none;
│ cursor: pointer;
│ transition: var(--transition);
│ font-size: 0.875rem;
│ }
│
│ .btn-primary {
│ background: var(--primary-color);
│ color: white;
│ }
│
│ .btn-primary:hover {
│ background: var(--primary-dark);
│ transform: translateY(-1px);
│ }
│
│ .btn-success {
│ background: var(--success-color);
│ color: white;
│ }
│
│ .btn-secondary {
│ background: var(--gray-500);
│ color: white;
│ }
│
│ .btn-danger {
│ background: var(--danger-color);
│ color: white;
│ }
│
│ .btn-small {
│ padding: 0.5rem 1rem;
│ font-size: 0.75rem;
│ }
│
│ /* Dashboard */
│ .dashboard {
│ padding: 1rem 0;
│ }
│
│ .dashboard-grid {
│ display: grid;
│ grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
│ gap: 1.5rem;
│ margin-bottom: 2rem;
│ }
│
│ .dashboard-card {
│ background: white;
│ padding: 1.5rem;
│ border-radius: var(--border-radius-lg);
│ box-shadow: var(--shadow-md);
│ border-top: 4px solid var(--primary-color);
│ transition: var(--transition);
│ }
│
│ .dashboard-card:hover {
│ transform: translateY(-4px);
│ box-shadow: var(--shadow-xl);
│ }
│
│ .dashboard-card h3 {
│ color: var(--gray-700);
│ margin-bottom: 0.5rem;
│ font-size: 1.125rem;
│ }
│
│ .card-number {
│ font-size: 2.5rem;
│ font-weight: 800;
│ color: var(--primary-color);
│ margin-bottom: 1rem;
│ }
│
│ /* Forms */
│ .form {
│ background: white;
│ padding: 2rem;
│ border-radius: var(--border-radius-lg);
│ box-shadow: var(--shadow-lg);
│ max-width: 600px;
│ }
│
│ .form-group {
│ margin-bottom: 1.5rem;
│ }
│
│ .form-group label {
│ display: block;
│ margin-bottom: 0.5rem;
│ font-weight: 600;
│ color: var(--gray-800);
│ }
│
│ .form-group input,
│ .form-group textarea,
│ .form-group select {
│ width: 100%;
│ padding: 0.75rem;
│ border: 2px solid var(--gray-200);
│ border-radius: var(--border-radius);
│ font-size: 1rem;
│ transition: var(--transition);
│ }
│
│ .form-group input:focus,
│ .form-group textarea:focus,
│ .form-group select:focus {
│ outline: none;
│ border-color: var(--primary-color);
│ box-shadow: 0 0 0 3px rgb(37 99 235 / 0.1);
│ }
│
│ .form-row {
│ display: grid;
│ grid-template-columns: 1fr 1fr;
│ gap: 1rem;
│ }
│
│ .form-actions {
│ display: flex;
│ gap: 1rem;
│ justify-content: flex-end;
│ margin-top: 2rem;
│ }
│
│ /* Tables */
│ .table-container {
│ background: white;
│ border-radius: var(--border-radius-lg);
│ box-shadow: var(--shadow-lg);
│ overflow: hidden;
│ }
│
│ .data-table {
│ width: 100%;
│ border-collapse: collapse;
│ }
│
│ .data-table th {
│ background: var(--gray-800);
│ color: white;
│ padding: 1rem;
│ text-align: left;
│ font-weight: 600;
│ font-size: 0.875rem;
│ text-transform: uppercase;
│ letter-spacing: 0.05em;
│ }
│
│ .data-table td {
│ padding: 1rem;
│ border-bottom: 1px solid var(--gray-200);
│ }
│
│ .data-table tr:hover {
│ background: var(--gray-50);
│ }
│
│ /* Quick Actions */
│ .quick-actions {
│ background: white;
│ padding: 2rem;
│ border-radius: var(--border-radius-lg);
│ box-shadow: var(--shadow-lg);
│ }
│
│ .action-buttons {
│ display: flex;
│ flex-wrap: wrap;
│ gap: 1rem;
│ margin-top: 1rem;
│ }
│
│ /* Alerts */
│ .alert {
│ padding: 1rem 1.5rem;
│ border-radius: var(--border-radius);
│ margin-bottom: 1rem;
│ font-weight: 500;
│ }
│
│ .alert-success {
│ background: #d1fae5;
│ color: #065f46;
│ border: 1px solid #a7f3d0;
│ }
│
│ .alert-error {
│ background: #fee2e2;
│ color: #991b1b;
│ border: 1px solid #fecaca;
│ }
│
│ /* Responsive */
│ @media (max-width: 768px) {
│ .container {
│ padding: 1rem;
│ }
│
│ .page-header {
│ flex-direction: column;
│ align-items: stretch;
│ gap: 1rem;
│ }
│
│ .form-row {
│ grid-template-columns: 1fr;
│ }
│
│ .action-buttons {
│ flex-direction: column;
│ }
│
│ .nav-menu {
│ flex-direction: column;
│ gap: 0.5rem;
│ }
│
│ .nav-menu li {
│ margin: 0;
│ }
│ }
│
│ /* Footer */
│ footer {
│ background: var(--gray-900);
│ color: var(--gray-400);
│ text-align: center;
│ padding: 2rem;
│ margin-top: 4rem;
│ }
│
│
│ (endcontenu)
├─ templates/
│ ├─ add_product.html(begincontenu)
│ │ {% extends "base.html" %}
│ │
│ │ {% block title %}Add Product - ERP System{% endblock %}
│ │
│ │ {% block content %}
│ │ <div class="page-header">
│ │ <h2>Add New Product</h2>
│ │ </div>
│ │
│ │ <form method="POST" class="form">
│ │ <div class="form-group">
│ │ <label for="name">Product Name *</label>
│ │ <input type="text" id="name" name="name" required>
│ │ </div>
│ │
│ │ <div class="form-group">
│ │ <label for="description">Description</label>
│ │ <textarea id="description" name="description" rows="3"></textarea>
│ │ </div>
│ │
│ │ <div class="form-row">
│ │ <div class="form-group">
│ │ <label for="category">Category *</label>
│ │ <input type="text" id="category" name="category" required>
│ │ </div>
│ │
│ │ <div class="form-group">
│ │ <label for="unit">Unit *</label>
│ │ <select id="unit" name="unit" required>
│ │ <option value="piece">Piece</option>
│ │ <option value="kg">Kilogram</option>
│ │ <option value="liter">Liter</option>
│ │ <option value="meter">Meter</option>
│ │ <option value="box">Box</option>
│ │ </select>
│ │ </div>
│ │ </div>
│ │
│ │ <div class="form-row">
│ │ <div class="form-group">
│ │ <label for="cost">Cost Price *</label>
│ │ <input type="number" id="cost" name="cost" step="0.01" required>
│ │ </div>
│ │
│ │ <div class="form-group">
│ │ <label for="price">Selling Price *</label>
│ │ <input type="number" id="price" name="price" step="0.01" required>
│ │ </div>
│ │ </div>
│ │
│ │ <div class="form-group">
│ │ <label for="min_stock">Minimum Stock Level *</label>
│ │ <input type="number" id="min_stock" name="min_stock" required>
│ │ </div>
│ │
│ │ <div class="form-actions">
│ │ <button type="submit" class="btn btn-primary">Save Product</button>
│ │ <a href="{{ url_for('products') }}" class="btn btn-secondary">Cancel</a>
│ │ </div>
│ │ </form>
│ │ {% endblock %}
│ │
│ │ (endcontenu)
│ ├─ base.html(begincontenu)
│ │ <!DOCTYPE html>
│ │ <html lang="en">
│ │ <head>
│ │ <meta charset="UTF-8">
│ │ <meta name="viewport" content="width=device-width, initial-scale=1.0">
│ │ <title>{% block title %}ERP System{% endblock %}</title>
│ │ <link rel="stylesheet" href="{{ url_for('static', filename='style.css') }}">
│ │ </head>
│ │ <body>
│ │ <nav class="navbar">
│ │ <div class="container">
│ │ <a href="{{ url_for('index') }}" class="nav-brand">
│ │ <h1>ERP</h1>
│ │ </a>
│ │ <ul class="nav-menu">
│ │ <li><a href="{{ url_for('index') }}">Dashboard</a></li>
│ │ <li><a href="{{ url_for('products') }}">Products</a></li>
│ │ <li><a href="{{ url_for('customers') }}">Customers</a></li>
│ │ <li><a href="{{ url_for('suppliers') }}">Suppliers</a></li>
│ │ <li><a href="{{ url_for('sales') }}">Sales</a></li>
│ │ <li><a href="{{ url_for('purchases') }}">Purchases</a></li>
│ │ <li><a href="{{ url_for('inventory') }}">Inventory</a></li>
│ │ <li><a href="{{ url_for('reports') }}">Reports</a></li>
│ │ </ul>
│ │ </div>
│ │ </nav>
│ │
│ │ <div class="container">
│ │ {% with messages = get_flashed_messages(with_categories=true) %}
│ │ {% if messages %}
│ │ {% for category, message in messages %}
│ │ <div class="alert alert-{{ 'success' if category == 'success' else 'error' }}">
│ │ {{ message }}
│ │ </div>
│ │ {% endfor %}
│ │ {% endif %}
│ │ {% endwith %}
│ │
│ │ {% block content %}{% endblock %}
│ │ </div>
│ │
│ │ <footer>
│ │ <p>© 2026 ERP System. All rights reserved. | Built with Flask</p>
│ │ </footer>
│ │ </body>
│ │ </html>
│ │
│ │
│ │ (endcontenu)
│ ├─ customers.html(begincontenu)
│ │ {% extends "base.html" %}
│ │
│ │ {% block title %}Customers - ERP System{% endblock %}
│ │
│ │ {% block content %}
│ │ <div class="page-header">
│ │ <h2>Customers</h2>
│ │ <a href="{{ url_for('add_customer') }}" class="btn btn-primary">Add New Customer</a>
│ │ </div>
│ │
│ │ <div class="table-container">
│ │ <table class="data-table">
│ │ <thead>
│ │ <tr>
│ │ <th>ID</th>
│ │ <th>Name</th>
│ │ <th>Email</th>
│ │ <th>Phone</th>
│ │ <th>City</th>
│ │ <th>Country</th>
│ │ <th>Actions</th>
│ │ </tr>
│ │ </thead>
│ │ <tbody>
│ │ {% for customer in customers %}
│ │ <tr>
│ │ <td>{{ customer.id }}</td>
│ │ <td>{{ customer.name }}</td>
│ │ <td>{{ customer.email }}</td>
│ │ <td>{{ customer.phone }}</td>
│ │ <td>{{ customer.city }}</td>
│ │ <td>{{ customer.country }}</td>
│ │ <td>
│ │ <a href="{{ url_for('edit_customer', customer_id=customer.id) }}" class="btn btn-small">Edit</a>
│ │ </td>
│ │ </tr>
│ │ {% else %}
│ │ <tr>
│ │ <td colspan="7" style="text-align:center;">No customers found. Add your first customer!</td>
│ │ </tr>
│ │ {% endfor %}
│ │ </tbody>
│ │ </table>
│ │ </div>
│ │ {% endblock %}
│ │
│ │ (endcontenu)
│ ├─ edit_product.html(begincontenu)
│ │ {% extends "base.html" %}
│ │
│ │ {% block title %}Edit Product - ERP System{% endblock %}
│ │
│ │ {% block content %}
│ │ <div class="page-header">
│ │ <h2>Edit Product</h2>
│ │ </div>
│ │
│ │ <form method="POST" class="form">
│ │ <div class="form-group">
│ │ <label for="name">Product Name *</label>
│ │ <input type="text" id="name" name="name" value="{{ product.name }}" required>
│ │ </div>
│ │
│ │ <div class="form-group">
│ │ <label for="description">Description</label>
│ │ <textarea id="description" name="description" rows="3">{{ product.description }}</textarea>
│ │ </div>
│ │
│ │ <div class="form-row">
│ │ <div class="form-group">
│ │ <label for="category">Category *</label>
│ │ <input type="text" id="category" name="category" value="{{ product.category }}" required>
│ │ </div>
│ │
│ │ <div class="form-group">
│ │ <label for="unit">Unit *</label>
│ │ <select id="unit" name="unit" required>
│ │ <option value="piece" {% if product.unit == 'piece' %}selected{% endif %}>Piece</option>
│ │ <option value="kg" {% if product.unit == 'kg' %}selected{% endif %}>Kilogram</option>
│ │ <option value="liter" {% if product.unit == 'liter' %}selected{% endif %}>Liter</option>
│ │ <option value="meter" {% if product.unit == 'meter' %}selected{% endif %}>Meter</option>
│ │ <option value="box" {% if product.unit == 'box' %}selected{% endif %}>Box</option>
│ │ </select>
│ │ </div>
│ │ </div>
│ │
│ │ <div class="form-row">
│ │ <div class="form-group">
│ │ <label for="cost">Cost Price *</label>
│ │ <input type="number" id="cost" name="cost" step="0.01" value="{{ product.cost }}" required>
│ │ </div>
│ │
│ │ <div class="form-group">
│ │ <label for="price">Selling Price *</label>
│ │ <input type="number" id="price" name="price" step="0.01" value="{{ product.price }}" required>
│ │ </div>
│ │ </div>
│ │
│ │ <div class="form-group">
│ │ <label for="min_stock">Minimum Stock Level *</label>
│ │ <input type="number" id="min_stock" name="min_stock" value="{{ product.min_stock }}" required>
│ │ </div>
│ │
│ │ <div class="form-actions">
│ │ <button type="submit" class="btn btn-primary">Update Product</button>
│ │ <a href="{{ url_for('products') }}" class="btn btn-secondary">Cancel</a>
│ │ </div>
│ │ </form>
│ │ {% endblock %}
│ │
│ │ (endcontenu)
│ ├─ index.html(begincontenu)
│ │ {% extends "base.html" %}
│ │
│ │ {% block title %}Dashboard - ERP System{% endblock %}
│ │
│ │ {% block content %}
│ │ <div class="dashboard">
│ │ <h2>Dashboard</h2>
│ │
│ │ <div class="dashboard-grid">
│ │ <div class="dashboard-card">
│ │ <h3>Products</h3>
│ │ <p class="card-number">{{ products|length if products else 0 }}</p>
│ │ <a href="{{ url_for('products') }}" class="btn btn-primary">Manage Products</a>
│ │ </div>
│ │
│ │ <div class="dashboard-card">
│ │ <h3>Customers</h3>
│ │ <p class="card-number">{{ customers|length if customers else 0 }}</p>
│ │ <a href="{{ url_for('customers') }}" class="btn btn-primary">Manage Customers</a>
│ │ </div>
│ │
│ │ <div class="dashboard-card">
│ │ <h3>Sales</h3>
│ │ <p class="card-number">{{ sales|length if sales else 0 }}</p>
│ │ <a href="{{ url_for('sales') }}" class="btn btn-primary">View Sales</a>
│ │ </div>
│ │
│ │ <div class="dashboard-card">
│ │ <h3>Purchases</h3>
│ │ <p class="card-number">{{ purchases|length if purchases else 0 }}</p>
│ │ <a href="{{ url_for('purchases') }}" class="btn btn-primary">View Purchases</a>
│ │ </div>
│ │ </div>
│ │
│ │ <div class="quick-actions">
│ │ <h3>Quick Actions</h3>
│ │ <div class="action-buttons">
│ │ <a href="{{ url_for('add_product') }}" class="btn btn-success">Add Product</a>
│ │ <a href="{{ url_for('add_customer') }}" class="btn btn-success">Add Customer</a>
│ │ <a href="{{ url_for('add_sale') }}" class="btn btn-success">New Sale</a>
│ │ <a href="{{ url_for('add_purchase') }}" class="btn btn-success">New Purchase</a>
│ │ </div>
│ │ </div>
│ │ </div>
│ │ {% endblock %}
│ │
│ │ (endcontenu)
│ └─ products.html(begincontenu)
│ {% extends "base.html" %}
│
│ {% block title %}Products - ERP System{% endblock %}
│
│ {% block content %}
│ <div class="page-header">
│ <h2>Products</h2>
│ <a href="{{ url_for('add_product') }}" class="btn btn-primary">Add New Product</a>
│ </div>
│
│ <div class="table-container">
│ <table class="data-table">
│ <thead>
│ <tr>
│ <th>ID</th>
│ <th>Name</th>
│ <th>Category</th>
│ <th>Unit</th>
│ <th>Cost</th>
│ <th>Price</th>
│ <th>Min Stock</th>
│ <th>Actions</th>
│ </tr>
│ </thead>
│ <tbody>
│ {% for product in products %}
│ <tr>
│ <td>{{ product.id }}</td>
│ <td>{{ product.name }}</td>
│ <td>{{ product.category }}</td>
│ <td>{{ product.unit }}</td>
│ <td>${{ "%.2f"|format(product.cost) }}</td>
│ <td>${{ "%.2f"|format(product.price) }}</td>
│ <td>{{ product.min_stock }}</td>
│ <td>
│ <a href="{{ url_for('edit_product', product_id=product.id) }}" class="btn btn-small">Edit</a>
│ <form method="POST" action="{{ url_for('delete_product', product_id=product.id) }}" style="display:inline;">
│ <button type="submit" class="btn btn-small btn-danger" onclick="return confirm('Are you sure?')">Delete</button>
│ </form>
│ </td>
│ </tr>
│ {% else %}
│ <tr>
│ <td colspan="8" style="text-align:center;">No products found. Add your first product!</td>
│ </tr>
│ {% endfor %}
│ </tbody>
│ </table>
│ </div>
│ {% endblock %}
│
│ (endcontenu)
├─ README.md(begincontenu)
│ # ERP System
│
│ A comprehensive Enterprise Resource Planning system built with Flask.
│
│ ## Features
│
│ - **Product Management**: Add, edit, and manage products with categories and pricing
│ - **Customer Management**: Maintain customer database with contact information
│ - **Supplier Management**: Track suppliers and their details
│ - **Sales Management**: Create and track sales orders
│ - **Purchase Management**: Manage purchase orders from suppliers
│ - **Inventory Tracking**: Real-time inventory levels and alerts
│ - **Reports**: Sales summaries and inventory status reports
│
│ ## Installation
│
│ 1. Install Python 3.8 or higher
│ 2. Install dependencies: `pip install -r requirements.txt`
│ 3. Run the application: `python app.py`
│ 4. Open browser to: http://localhost:5000
│
│ ## Project Structure
│
│ - `app.py`: Main application file
│ - `templates/`: HTML templates
│ - `static/`: CSS, JavaScript, and images
│ - `data/`: JSON data storage
│
│ ## Usage
│
│ 1. Start by adding products in the Products section
│ 2. Add customers and suppliers
│ 3. Create purchase orders to stock inventory
│ 4. Create sales orders to sell products
│ 5. Monitor inventory levels
│ 6. Generate reports for business insights
│
│ Generated by mkarchi.
│
│ (endcontenu)
├─ app.py(begincontenu)
│ from flask import Flask, render_template, request, redirect, url_for, flash, jsonify
│ from datetime import datetime
│ import json
│ import os
│
│ app = Flask(__name__)
│ app.secret_key = 'your-secret-key-here-change-in-production'
│
│ # In-memory database (replace with real database in production)
│ class Database:
│ def __init__(self):
│ self.products = []
│ self.customers = []
│ self.suppliers = []
│ self.sales = []
│ self.purchases = []
│ self.inventory = []
│ self.users = []
│ self.load_data()
│
│ def load_data(self):
│ """Load data from JSON files if they exist"""
│ try:
│ if os.path.exists('data/products.json'):
│ with open('data/products.json', 'r') as f:
│ self.products = json.load(f)
│ if os.path.exists('data/customers.json'):
│ with open('data/customers.json', 'r') as f:
│ self.customers = json.load(f)
│ if os.path.exists('data/suppliers.json'):
│ with open('data/suppliers.json', 'r') as f:
│ self.suppliers = json.load(f)
│ if os.path.exists('data/sales.json'):
│ with open('data/sales.json', 'r') as f:
│ self.sales = json.load(f)
│ if os.path.exists('data/purchases.json'):
│ with open('data/purchases.json', 'r') as f:
│ self.purchases = json.load(f)
│ except Exception as e:
│ print(f"Error loading data: {e}")
│
│ def save_data(self):
│ """Save data to JSON files"""
│ os.makedirs('data', exist_ok=True)
│ try:
│ with open('data/products.json', 'w') as f:
│ json.dump(self.products, f, indent=2)
│ with open('data/customers.json', 'w') as f:
│ json.dump(self.customers, f, indent=2)
│ with open('data/suppliers.json', 'w') as f:
│ json.dump(self.suppliers, f, indent=2)
│ with open('data/sales.json', 'w') as f:
│ json.dump(self.sales, f, indent=2)
│ with open('data/purchases.json', 'w') as f:
│ json.dump(self.purchases, f, indent=2)
│ except Exception as e:
│ print(f"Error saving data: {e}")
│
│ db = Database()
│
│ # Helper functions
│ def generate_id(items):
│ """Generate a unique ID for new items"""
│ if not items:
│ return 1
│ return max(item['id'] for item in items) + 1
│
│ def calculate_inventory():
│ """Calculate current inventory levels"""
│ inventory = {}
│ for purchase in db.purchases:
│ for item in purchase['items']:
│ product_id = item['product_id']
│ if product_id not in inventory:
│ inventory[product_id] = 0
│ inventory[product_id] += item['quantity']
│
│ for sale in db.sales:
│ for item in sale['items']:
│ product_id = item['product_id']
│ if product_id not in inventory:
│ inventory[product_id] = 0
│ inventory[product_id] -= item['quantity']
│
│ return inventory
│
│ # Routes
│ @app.route('/')
│ def index():
│ return render_template('index.html')
│
│ # Product Management
│ @app.route('/products')
│ def products():
│ return render_template('products.html', products=db.products)
│
│ @app.route('/products/add', methods=['GET', 'POST'])
│ def add_product():
│ if request.method == 'POST':
│ product = {
│ 'id': generate_id(db.products),
│ 'name': request.form['name'],
│ 'description': request.form['description'],
│ 'category': request.form['category'],
│ 'unit': request.form['unit'],
│ 'price': float(request.form['price']),
│ 'cost': float(request.form['cost']),
│ 'min_stock': int(request.form['min_stock']),
│ 'created_at': datetime.now().isoformat()
│ }
│ db.products.append(product)
│ db.save_data()
│ flash('Product added successfully!', 'success')
│ return redirect(url_for('products'))
│ return render_template('add_product.html')
│
│ @app.route('/products/edit/<int:product_id>', methods=['GET', 'POST'])
│ def edit_product(product_id):
│ product = next((p for p in db.products if p['id'] == product_id), None)
│ if not product:
│ flash('Product not found!', 'error')
│ return redirect(url_for('products'))
│
│ if request.method == 'POST':
│ product['name'] = request.form['name']
│ product['description'] = request.form['description']
│ product['category'] = request.form['category']
│ product['unit'] = request.form['unit']
│ product['price'] = float(request.form['price'])
│ product['cost'] = float(request.form['cost'])
│ product['min_stock'] = int(request.form['min_stock'])
│ product['updated_at'] = datetime.now().isoformat()
│ db.save_data()
│ flash('Product updated successfully!', 'success')
│ return redirect(url_for('products'))
│
│ return render_template('edit_product.html', product=product)
│
│ @app.route('/products/delete/<int:product_id>', methods=['POST'])
│ def delete_product(product_id):
│ db.products = [p for p in db.products if p['id'] != product_id]
│ db.save_data()
│ flash('Product deleted successfully!', 'success')
│ return redirect(url_for('products'))
│
│ # Customer Management
│ @app.route('/customers')
│ def customers():
│ return render_template('customers.html', customers=db.customers)
│
│ @app.route('/customers/add', methods=['GET', 'POST'])
│ def add_customer():
│ if request.method == 'POST':
│ customer = {
│ 'id': generate_id(db.customers),
│ 'name': request.form['name'],
│ 'email': request.form['email'],
│ 'phone': request.form['phone'],
│ 'address': request.form['address'],
│ 'city': request.form['city'],
│ 'country': request.form['country'],
│ 'tax_id': request.form['tax_id'],
│ 'created_at': datetime.now().isoformat()
│ }
│ db.customers.append(customer)
│ db.save_data()
│ flash('Customer added successfully!', 'success')
│ return redirect(url_for('customers'))
│ return render_template('add_customer.html')
│
│ @app.route('/customers/edit/<int:customer_id>', methods=['GET', 'POST'])
│ def edit_customer(customer_id):
│ customer = next((c for c in db.customers if c['id'] == customer_id), None)
│ if not customer:
│ flash('Customer not found!', 'error')
│ return redirect(url_for('customers'))
│
│ if request.method == 'POST':
│ customer['name'] = request.form['name']
│ customer['email'] = request.form['email']
│ customer['phone'] = request.form['phone']
│ customer['address'] = request.form['address']
│ customer['city'] = request.form['city']
│ customer['country'] = request.form['country']
│ customer['tax_id'] = request.form['tax_id']
│ customer['updated_at'] = datetime.now().isoformat()
│ db.save_data()
│ flash('Customer updated successfully!', 'success')
│ return redirect(url_for('customers'))
│
│ return render_template('edit_customer.html', customer=customer)
│
│ # Supplier Management
│ @app.route('/suppliers')
│ def suppliers():
│ return render_template('suppliers.html', suppliers=db.suppliers)
│
│ @app.route('/suppliers/add', methods=['GET', 'POST'])
│ def add_supplier():
│ if request.method == 'POST':
│ supplier = {
│ 'id': generate_id(db.suppliers),
│ 'name': request.form['name'],
│ 'email': request.form['email'],
│ 'phone': request.form['phone'],
│ 'address': request.form['address'],
│ 'city': request.form['city'],
│ 'country': request.form['country'],
│ 'tax_id': request.form['tax_id'],
│ 'payment_terms': request.form['payment_terms'],
│ 'created_at': datetime.now().isoformat()
│ }
│ db.suppliers.append(supplier)
│ db.save_data()
│ flash('Supplier added successfully!', 'success')
│ return redirect(url_for('suppliers'))
│ return render_template('add_supplier.html')
│
│ # Sales Management
│ @app.route('/sales')
│ def sales():
│ sales_with_details = []
│ for sale in db.sales:
│ customer = next((c for c in db.customers if c['id'] == sale['customer_id']), None)
│ sale_detail = sale.copy()
│ sale_detail['customer_name'] = customer['name'] if customer else 'Unknown'
│ sales_with_details.append(sale_detail)
│ return render_template('sales.html', sales=sales_with_details)
│
│ @app.route('/sales/add', methods=['GET', 'POST'])
│ def add_sale():
│ if request.method == 'POST':
│ items = []
│ total = 0
│
│ product_ids = request.form.getlist('product_id[]')
│ quantities = request.form.getlist('quantity[]')
│ prices = request.form.getlist('price[]')
│
│ for i in range(len(product_ids)):
│ if product_ids[i]:
│ item = {
│ 'product_id': int(product_ids[i]),
│ 'quantity': int(quantities[i]),
│ 'price': float(prices[i]),
│ 'subtotal': int(quantities[i]) * float(prices[i])
│ }
│ items.append(item)
│ total += item['subtotal']
│
│ sale = {
│ 'id': generate_id(db.sales),
│ 'customer_id': int(request.form['customer_id']),
│ 'date': request.form['date'],
│ 'status': request.form['status'],
│ 'payment_method': request.form['payment_method'],
│ 'items': items,
│ 'subtotal': total,
│ 'tax': total * 0.1,
│ 'total': total * 1.1,
│ 'notes': request.form.get('notes', ''),
│ 'created_at': datetime.now().isoformat()
│ }
│ db.sales.append(sale)
│ db.save_data()
│ flash('Sale created successfully!', 'success')
│ return redirect(url_for('sales'))
│
│ return render_template('add_sale.html', customers=db.customers, products=db.products)
│
│ @app.route('/sales/view/<int:sale_id>')
│ def view_sale(sale_id):
│ sale = next((s for s in db.sales if s['id'] == sale_id), None)
│ if not sale:
│ flash('Sale not found!', 'error')
│ return redirect(url_for('sales'))
│
│ customer = next((c for c in db.customers if c['id'] == sale['customer_id']), None)
│ items_with_details = []
│ for item in sale['items']:
│ product = next((p for p in db.products if p['id'] == item['product_id']), None)
│ item_detail = item.copy()
│ item_detail['product_name'] = product['name'] if product else 'Unknown'
│ items_with_details.append(item_detail)
│
│ return render_template('view_sale.html', sale=sale, customer=customer, items=items_with_details)
│
│ # Purchase Management
│ @app.route('/purchases')
│ def purchases():
│ purchases_with_details = []
│ for purchase in db.purchases:
│ supplier = next((s for s in db.suppliers if s['id'] == purchase['supplier_id']), None)
│ purchase_detail = purchase.copy()
│ purchase_detail['supplier_name'] = supplier['name'] if supplier else 'Unknown'
│ purchases_with_details.append(purchase_detail)
│ return render_template('purchases.html', purchases=purchases_with_details)
│
│ @app.route('/purchases/add', methods=['GET', 'POST'])
│ def add_purchase():
│ if request.method == 'POST':
│ items = []
│ total = 0
│
│ product_ids = request.form.getlist('product_id[]')
│ quantities = request.form.getlist('quantity[]')
│ costs = request.form.getlist('cost[]')
│
│ for i in range(len(product_ids)):
│ if product_ids[i]:
│ item = {
│ 'product_id': int(product_ids[i]),
│ 'quantity': int(quantities[i]),
│ 'cost': float(costs[i]),
│ 'subtotal': int(quantities[i]) * float(costs[i])
│ }
│ items.append(item)
│ total += item['subtotal']
│
│ purchase = {
│ 'id': generate_id(db.purchases),
│ 'supplier_id': int(request.form['supplier_id']),
│ 'date': request.form['date'],
│ 'status': request.form['status'],
│ 'payment_method': request.form['payment_method'],
│ 'items': items,
│ 'subtotal': total,
│ 'tax': total * 0.1,
│ 'total': total * 1.1,
│ 'notes': request.form.get('notes', ''),
│ 'created_at': datetime.now().isoformat()
│ }
│ db.purchases.append(purchase)
│ db.save_data()
│ flash('Purchase created successfully!', 'success')
│ return redirect(url_for('purchases'))
│
│ return render_template('add_purchase.html', suppliers=db.suppliers, products=db.products)
│
│ # Inventory Management
│ @app.route('/inventory')
│ def inventory():
│ current_inventory = calculate_inventory()
│ inventory_list = []
│
│ for product in db.products:
│ stock = current_inventory.get(product['id'], 0)
│ inventory_list.append({
│ 'product': product,
│ 'stock': stock,
│ 'status': 'Low' if stock < product['min_stock'] else 'Normal'
│ })
│
│ return render_template('inventory.html', inventory=inventory_list)
│
│ # Reports
│ @app.route('/reports')
│ def reports():
│ return render_template('reports.html')
│
│ @app.route('/reports/sales-summary')
│ def sales_summary():
│ total_sales = sum(sale['total'] for sale in db.sales)
│ total_orders = len(db.sales)
│
│ monthly_sales = {}
│ for sale in db.sales:
│ month = sale['date'][:7]
│ if month not in monthly_sales:
│ monthly_sales[month] = 0
│ monthly_sales[month] += sale['total']
│
│ return render_template('sales_summary.html',
│ total_sales=total_sales,
│ total_orders=total_orders,
│ monthly_sales=monthly_sales)
│
│ @app.route('/reports/inventory-status')
│ def inventory_status():
│ current_inventory = calculate_inventory()
│ low_stock = []
│ out_of_stock = []
│
│ for product in db.products:
│ stock = current_inventory.get(product['id'], 0)
│ if stock == 0:
│ out_of_stock.append(product)
│ elif stock < product['min_stock']:
│ low_stock.append(product)
│
│ return render_template('inventory_status.html',
│ low_stock=low_stock,
│ out_of_stock=out_of_stock)
│
│ # API Endpoints
│ @app.route('/api/products')
│ def api_products():
│ return jsonify(db.products)
│
│ @app.route('/api/product/<int:product_id>')
│ def api_product(product_id):
│ product = next((p for p in db.products if p['id'] == product_id), None)
│ if product:
│ return jsonify(product)
│ return jsonify({'error': 'Product not found'}), 404
│
│ if __name__ == '__main__':
│ app.run(debug=True, host='0.0.0.0', port=5000)
│
│ (endcontenu)
└─ requirements.txt(begincontenu)
Flask==2.3.0
Werkzeug==2.3.0
Jinja2==3.1.2
(endcontenu)