532 lines
25 KiB
HTML
532 lines
25 KiB
HTML
{% extends "base.html" %}
|
|
{% load static %}
|
|
|
|
{% block title %}{{ supplier.name }} - Suppliers - {{ block.super }}{% endblock %}
|
|
|
|
{% block content %}
|
|
<div class="container-fluid">
|
|
<!-- Page Header -->
|
|
<div class="d-flex justify-content-between align-items-center mb-4">
|
|
<div>
|
|
<h1 class="h3 mb-1">
|
|
<i class="fas fa-truck me-2"></i>{{ supplier.name }}
|
|
</h1>
|
|
<nav aria-label="breadcrumb">
|
|
<ol class="breadcrumb mb-0">
|
|
<li class="breadcrumb-item"><a href="{% url 'inventory:dashboard' %}">Inventory</a></li>
|
|
<li class="breadcrumb-item"><a href="{% url 'inventory:supplier_list' %}">Suppliers</a></li>
|
|
<li class="breadcrumb-item active">{{ supplier.name }}</li>
|
|
</ol>
|
|
</nav>
|
|
</div>
|
|
<div class="btn-group">
|
|
<a href="{% url 'inventory:supplier_update' supplier.pk %}" class="btn btn-outline-primary">
|
|
<i class="fas fa-edit me-2"></i>Edit
|
|
</a>
|
|
<div class="btn-group">
|
|
<button type="button" class="btn btn-primary dropdown-toggle" data-bs-toggle="dropdown">
|
|
<i class="fas fa-cog me-2"></i>Actions
|
|
</button>
|
|
<ul class="dropdown-menu">
|
|
<li><a class="dropdown-item" href="{% url 'inventory:purchase_order_create' %}?supplier={{ supplier.id }}">
|
|
<i class="fas fa-shopping-cart me-2"></i>Create Purchase Order
|
|
</a></li>
|
|
<li><a class="dropdown-item" href="#" onclick="contactSupplier()">
|
|
<i class="fas fa-envelope me-2"></i>Send Email
|
|
</a></li>
|
|
<li><a class="dropdown-item" href="#" onclick="printSupplierInfo()">
|
|
<i class="fas fa-print me-2"></i>Print Details
|
|
</a></li>
|
|
<li><hr class="dropdown-divider"></li>
|
|
<li><a class="dropdown-item" href="#" onclick="exportSupplierData()">
|
|
<i class="fas fa-download me-2"></i>Export Data
|
|
</a></li>
|
|
<li><hr class="dropdown-divider"></li>
|
|
<li><a class="dropdown-item text-danger" href="{% url 'inventory:supplier_delete' supplier.pk %}">
|
|
<i class="fas fa-trash me-2"></i>Delete Supplier
|
|
</a></li>
|
|
</ul>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="row">
|
|
<!-- Supplier Information -->
|
|
<div class="col-lg-8">
|
|
<!-- Basic Information -->
|
|
<div class="card mb-4">
|
|
<div class="card-header">
|
|
<h5 class="mb-0">
|
|
<i class="fas fa-info-circle me-2"></i>Supplier Information
|
|
</h5>
|
|
</div>
|
|
<div class="card-body">
|
|
<div class="row">
|
|
<div class="col-md-6">
|
|
<table class="table table-borderless">
|
|
<tr>
|
|
<td class="text-muted" width="120">Supplier Code:</td>
|
|
<td class="fw-semibold">{{ supplier.supplier_code }}</td>
|
|
</tr>
|
|
<tr>
|
|
<td class="text-muted">Name:</td>
|
|
<td class="fw-semibold">{{ supplier.name }}</td>
|
|
</tr>
|
|
<tr>
|
|
<td class="text-muted">Type:</td>
|
|
<td>
|
|
<span class="badge bg-secondary">{{ supplier.get_supplier_type_display }}</span>
|
|
</td>
|
|
</tr>
|
|
<tr>
|
|
<td class="text-muted">Status:</td>
|
|
<td>
|
|
<span class="badge bg-{% if supplier.is_active %}success{% else %}secondary{% endif %}">
|
|
{% if supplier.is_active %}Active{% else %}Inactive{% endif %}
|
|
</span>
|
|
</td>
|
|
</tr>
|
|
<tr>
|
|
<td class="text-muted">Rating:</td>
|
|
<td>
|
|
{% if supplier.rating %}
|
|
<div class="d-flex align-items-center">
|
|
<div class="text-warning me-2">
|
|
{% for i in "12345" %}
|
|
{% if forloop.counter <= supplier.rating %}
|
|
<i class="fas fa-star"></i>
|
|
{% else %}
|
|
<i class="far fa-star"></i>
|
|
{% endif %}
|
|
{% endfor %}
|
|
</div>
|
|
<span class="fw-semibold">{{ supplier.rating }}/5</span>
|
|
</div>
|
|
{% else %}
|
|
<span class="text-muted">Not rated</span>
|
|
{% endif %}
|
|
</td>
|
|
</tr>
|
|
</table>
|
|
</div>
|
|
<div class="col-md-6">
|
|
<table class="table table-borderless">
|
|
<tr>
|
|
<td class="text-muted" width="120">Tax ID:</td>
|
|
<td>{{ supplier.tax_id|default:"—" }}</td>
|
|
</tr>
|
|
<tr>
|
|
<td class="text-muted">License:</td>
|
|
<td>{{ supplier.license_number|default:"—" }}</td>
|
|
</tr>
|
|
<tr>
|
|
<td class="text-muted">Payment Terms:</td>
|
|
<td>{{ supplier.get_payment_terms_display|default:"—" }}</td>
|
|
</tr>
|
|
<tr>
|
|
<td class="text-muted">Credit Limit:</td>
|
|
<td>
|
|
{% if supplier.credit_limit %}
|
|
${{ supplier.credit_limit|floatformat:2 }}
|
|
{% else %}
|
|
—
|
|
{% endif %}
|
|
</td>
|
|
</tr>
|
|
<tr>
|
|
<td class="text-muted">Member Since:</td>
|
|
<td>{{ supplier.created_at|date:"M d, Y" }}</td>
|
|
</tr>
|
|
</table>
|
|
</div>
|
|
</div>
|
|
|
|
{% if supplier.description %}
|
|
<div class="mt-3">
|
|
<h6 class="text-muted mb-2">Description</h6>
|
|
<p class="mb-0">{{ supplier.description }}</p>
|
|
</div>
|
|
{% endif %}
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Contact Information -->
|
|
<div class="card mb-4">
|
|
<div class="card-header">
|
|
<h5 class="mb-0">
|
|
<i class="fas fa-address-book me-2"></i>Contact Information
|
|
</h5>
|
|
</div>
|
|
<div class="card-body">
|
|
<div class="row">
|
|
<div class="col-md-6">
|
|
<h6 class="text-muted mb-3">Primary Contact</h6>
|
|
<table class="table table-borderless">
|
|
<tr>
|
|
<td class="text-muted" width="100">Name:</td>
|
|
<td>{{ supplier.contact_person|default:"—" }}</td>
|
|
</tr>
|
|
<tr>
|
|
<td class="text-muted">Title:</td>
|
|
<td>{{ supplier.contact_title|default:"—" }}</td>
|
|
</tr>
|
|
<tr>
|
|
<td class="text-muted">Phone:</td>
|
|
<td>
|
|
{% if supplier.phone %}
|
|
<a href="tel:{{ supplier.phone }}" class="text-decoration-none">
|
|
<i class="fas fa-phone me-1"></i>{{ supplier.phone }}
|
|
</a>
|
|
{% else %}
|
|
—
|
|
{% endif %}
|
|
</td>
|
|
</tr>
|
|
<tr>
|
|
<td class="text-muted">Email:</td>
|
|
<td>
|
|
{% if supplier.email %}
|
|
<a href="mailto:{{ supplier.email }}" class="text-decoration-none">
|
|
<i class="fas fa-envelope me-1"></i>{{ supplier.email }}
|
|
</a>
|
|
{% else %}
|
|
—
|
|
{% endif %}
|
|
</td>
|
|
</tr>
|
|
<tr>
|
|
<td class="text-muted">Website:</td>
|
|
<td>
|
|
{% if supplier.website %}
|
|
<a href="{{ supplier.website }}" target="_blank" class="text-decoration-none">
|
|
<i class="fas fa-globe me-1"></i>{{ supplier.website }}
|
|
</a>
|
|
{% else %}
|
|
—
|
|
{% endif %}
|
|
</td>
|
|
</tr>
|
|
</table>
|
|
</div>
|
|
<div class="col-md-6">
|
|
<h6 class="text-muted mb-3">Address</h6>
|
|
{% if supplier.address %}
|
|
<div class="mb-3">
|
|
<i class="fas fa-map-marker-alt me-2 text-muted"></i>
|
|
<span>{{ supplier.address }}</span>
|
|
{% if supplier.city or supplier.state or supplier.zip_code %}
|
|
<br>
|
|
<span class="ms-4">
|
|
{{ supplier.city }}{% if supplier.city and supplier.state %}, {% endif %}{{ supplier.state }} {{ supplier.zip_code }}
|
|
</span>
|
|
{% endif %}
|
|
{% if supplier.country %}
|
|
<br>
|
|
<span class="ms-4">{{ supplier.country }}</span>
|
|
{% endif %}
|
|
</div>
|
|
<a href="https://maps.google.com/?q={{ supplier.address|urlencode }}"
|
|
target="_blank" class="btn btn-outline-secondary btn-sm">
|
|
<i class="fas fa-map me-1"></i>View on Map
|
|
</a>
|
|
{% else %}
|
|
<p class="text-muted">No address provided</p>
|
|
{% endif %}
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Recent Orders -->
|
|
<div class="card mb-4">
|
|
<div class="card-header">
|
|
<div class="d-flex justify-content-between align-items-center">
|
|
<h5 class="mb-0">
|
|
<i class="fas fa-shopping-cart me-2"></i>Recent Orders
|
|
</h5>
|
|
<a href="{% url 'inventory:purchase_order_list' %}?supplier={{ supplier.id }}"
|
|
class="btn btn-outline-primary btn-sm">
|
|
<i class="fas fa-list me-1"></i>View All
|
|
</a>
|
|
</div>
|
|
</div>
|
|
<div class="card-body">
|
|
{% if recent_orders %}
|
|
<div class="table-responsive">
|
|
<table class="table table-hover mb-0">
|
|
<thead class="table-light">
|
|
<tr>
|
|
<th>Order #</th>
|
|
<th>Date</th>
|
|
<th>Status</th>
|
|
<th>Items</th>
|
|
<th>Total</th>
|
|
<th>Actions</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
{% for order in recent_orders %}
|
|
<tr>
|
|
<td>
|
|
<a href="{% url 'inventory:purchase_order_detail' order.pk %}"
|
|
class="text-decoration-none fw-semibold">
|
|
{{ order.order_number }}
|
|
</a>
|
|
</td>
|
|
<td>{{ order.order_date|date:"M d, Y" }}</td>
|
|
<td>
|
|
<span class="badge bg-{% if order.status == 'COMPLETED' %}success{% elif order.status == 'PENDING' %}warning{% elif order.status == 'CANCELLED' %}danger{% else %}info{% endif %}">
|
|
{{ order.get_status_display }}
|
|
</span>
|
|
</td>
|
|
<td>{{ order.total_items }}</td>
|
|
<td>${{ order.total_amount|floatformat:2 }}</td>
|
|
<td>
|
|
<a href="{% url 'inventory:purchase_order_detail' order.pk %}"
|
|
class="btn btn-outline-primary btn-sm">
|
|
<i class="fas fa-eye"></i>
|
|
</a>
|
|
</td>
|
|
</tr>
|
|
{% endfor %}
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
{% else %}
|
|
<div class="text-center py-4">
|
|
<i class="fas fa-shopping-cart fa-2x text-muted mb-3"></i>
|
|
<h6 class="text-muted">No orders yet</h6>
|
|
<p class="text-muted">Create your first purchase order with this supplier</p>
|
|
<a href="{% url 'inventory:purchase_order_create' %}?supplier={{ supplier.id }}"
|
|
class="btn btn-primary">
|
|
<i class="fas fa-plus me-2"></i>Create Order
|
|
</a>
|
|
</div>
|
|
{% endif %}
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Sidebar -->
|
|
<div class="col-lg-4">
|
|
<!-- Quick Stats -->
|
|
<div class="card mb-4">
|
|
<div class="card-header">
|
|
<h5 class="mb-0">
|
|
<i class="fas fa-chart-bar me-2"></i>Quick Stats
|
|
</h5>
|
|
</div>
|
|
<div class="card-body">
|
|
<div class="row text-center">
|
|
<div class="col-6 mb-3">
|
|
<div class="border-end">
|
|
<h4 class="text-primary mb-0">{{ total_orders }}</h4>
|
|
<small class="text-muted">Total Orders</small>
|
|
</div>
|
|
</div>
|
|
<div class="col-6 mb-3">
|
|
<h4 class="text-success mb-0">${{ total_spent|floatformat:0 }}</h4>
|
|
<small class="text-muted">Total Spent</small>
|
|
</div>
|
|
<div class="col-6">
|
|
<div class="border-end">
|
|
<h4 class="text-info mb-0">{{ avg_delivery_days|floatformat:0 }}</h4>
|
|
<small class="text-muted">Avg Delivery</small>
|
|
</div>
|
|
</div>
|
|
<div class="col-6">
|
|
<h4 class="text-warning mb-0">{{ on_time_percentage|floatformat:0 }}%</h4>
|
|
<small class="text-muted">On Time</small>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="mt-3">
|
|
<div class="d-flex justify-content-between align-items-center mb-1">
|
|
<small class="text-muted">Performance Score</small>
|
|
<small class="text-muted">{{ performance_score|floatformat:0 }}/100</small>
|
|
</div>
|
|
<div class="progress" style="height: 6px;">
|
|
<div class="progress-bar bg-{% if performance_score >= 80 %}success{% elif performance_score >= 60 %}warning{% else %}danger{% endif %}"
|
|
role="progressbar" style="width: {{ performance_score }}%"></div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Quick Actions -->
|
|
<div class="card mb-4">
|
|
<div class="card-header">
|
|
<h5 class="mb-0">
|
|
<i class="fas fa-bolt me-2"></i>Quick Actions
|
|
</h5>
|
|
</div>
|
|
<div class="card-body">
|
|
<div class="d-grid gap-2">
|
|
<a href="{% url 'inventory:purchase_order_create' %}?supplier={{ supplier.id }}"
|
|
class="btn btn-primary">
|
|
<i class="fas fa-shopping-cart me-2"></i>Create Purchase Order
|
|
</a>
|
|
<button type="button" class="btn btn-outline-primary" onclick="contactSupplier()">
|
|
<i class="fas fa-envelope me-2"></i>Send Email
|
|
</button>
|
|
<button type="button" class="btn btn-outline-secondary" onclick="scheduleCall()">
|
|
<i class="fas fa-phone me-2"></i>Schedule Call
|
|
</button>
|
|
<button type="button" class="btn btn-outline-info" onclick="requestQuote()">
|
|
<i class="fas fa-file-invoice me-2"></i>Request Quote
|
|
</button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Supplier Items -->
|
|
<div class="card mb-4">
|
|
<div class="card-header">
|
|
<div class="d-flex justify-content-between align-items-center">
|
|
<h5 class="mb-0">
|
|
<i class="fas fa-boxes me-2"></i>Supplier Items
|
|
</h5>
|
|
<span class="badge bg-primary">{{ supplier_items.count }}</span>
|
|
</div>
|
|
</div>
|
|
<div class="card-body">
|
|
{% if supplier_items %}
|
|
{% for item in supplier_items|slice:":5" %}
|
|
<div class="d-flex align-items-center mb-3">
|
|
<div class="bg-secondary bg-gradient rounded-circle d-flex align-items-center justify-content-center me-3" style="width: 32px; height: 32px;">
|
|
<i class="fas fa-box text-white small"></i>
|
|
</div>
|
|
<div class="flex-grow-1">
|
|
<div class="fw-semibold small">{{ item.item_name }}</div>
|
|
<div class="text-muted small">{{ item.item_code }}</div>
|
|
</div>
|
|
<div class="text-end">
|
|
<div class="fw-semibold small">${{ item.unit_cost|floatformat:2 }}</div>
|
|
<div class="text-muted small">{{ item.get_category_display }}</div>
|
|
</div>
|
|
</div>
|
|
{% endfor %}
|
|
|
|
{% if supplier_items.count > 5 %}
|
|
<div class="text-center mt-3">
|
|
<a href="{% url 'inventory:item_list' %}?supplier={{ supplier.id }}"
|
|
class="btn btn-outline-primary btn-sm">
|
|
<i class="fas fa-list me-1"></i>View All {{ supplier_items.count }} Items
|
|
</a>
|
|
</div>
|
|
{% endif %}
|
|
{% else %}
|
|
<div class="text-center py-3">
|
|
<i class="fas fa-boxes fa-2x text-muted mb-2"></i>
|
|
<p class="text-muted small mb-0">No items from this supplier</p>
|
|
</div>
|
|
{% endif %}
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Notes -->
|
|
<div class="card">
|
|
<div class="card-header">
|
|
<h5 class="mb-0">
|
|
<i class="fas fa-sticky-note me-2"></i>Notes
|
|
</h5>
|
|
</div>
|
|
<div class="card-body">
|
|
{% if supplier.notes %}
|
|
<p class="mb-0">{{ supplier.notes|linebreaks }}</p>
|
|
{% else %}
|
|
<p class="text-muted mb-0">No notes available</p>
|
|
{% endif %}
|
|
<div class="mt-3">
|
|
<button type="button" class="btn btn-outline-secondary btn-sm" onclick="editNotes()">
|
|
<i class="fas fa-edit me-1"></i>Edit Notes
|
|
</button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<script>
|
|
function contactSupplier() {
|
|
{% if supplier.email %}
|
|
window.location.href = 'mailto:{{ supplier.email }}?subject=Inquiry from {{ request.user.tenant.name }}';
|
|
{% else %}
|
|
alert('No email address available for this supplier.');
|
|
{% endif %}
|
|
}
|
|
|
|
function printSupplierInfo() {
|
|
window.print();
|
|
}
|
|
|
|
function exportSupplierData() {
|
|
window.location.href = '{% url "inventory:supplier_export" supplier.pk %}';
|
|
}
|
|
|
|
function scheduleCall() {
|
|
// Implement call scheduling functionality
|
|
alert('Call scheduling feature coming soon!');
|
|
}
|
|
|
|
function requestQuote() {
|
|
// Implement quote request functionality
|
|
alert('Quote request feature coming soon!');
|
|
}
|
|
|
|
function editNotes() {
|
|
// Implement inline notes editing
|
|
alert('Notes editing feature coming soon!');
|
|
}
|
|
</script>
|
|
|
|
<style>
|
|
.table-borderless td {
|
|
border: none;
|
|
padding: 0.25rem 0;
|
|
}
|
|
|
|
.border-end {
|
|
border-right: 1px solid #dee2e6 !important;
|
|
}
|
|
|
|
.progress {
|
|
background-color: #e9ecef;
|
|
}
|
|
|
|
.bg-gradient {
|
|
background-image: linear-gradient(180deg, rgba(255, 255, 255, 0.15), rgba(255, 255, 255, 0));
|
|
}
|
|
|
|
@media print {
|
|
.btn, .btn-group, .dropdown {
|
|
display: none !important;
|
|
}
|
|
|
|
.card {
|
|
border: 1px solid #dee2e6 !important;
|
|
box-shadow: none !important;
|
|
}
|
|
}
|
|
|
|
@media (max-width: 768px) {
|
|
.d-flex.justify-content-between {
|
|
flex-direction: column;
|
|
gap: 1rem;
|
|
}
|
|
|
|
.btn-group {
|
|
display: flex;
|
|
flex-direction: column;
|
|
gap: 0.5rem;
|
|
}
|
|
|
|
.col-6 {
|
|
margin-bottom: 1rem;
|
|
}
|
|
}
|
|
</style>
|
|
{% endblock %}
|
|
|