161 lines
6.7 KiB
HTML
161 lines
6.7 KiB
HTML
{% extends "base.html" %}
|
|
|
|
{% block page_title %}庫存警告{% endblock %}
|
|
|
|
{% block content %}
|
|
<!-- 統計卡片 -->
|
|
<div class="row g-3 mb-4">
|
|
<div class="col-12 col-md-4">
|
|
<div class="card stat-card bg-primary text-white">
|
|
<div class="card-body">
|
|
<div class="d-flex justify-content-between align-items-center">
|
|
<div>
|
|
<h6 class="card-subtitle mb-1">總商品數</h6>
|
|
<h2 class="mb-0">{{ summary.total_products }}</h2>
|
|
</div>
|
|
<div class="fs-1">
|
|
<i class="bi bi-box"></i>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="col-12 col-md-4">
|
|
<div class="card stat-card {{ 'bg-danger' if summary.low_stock_count > 0 else 'bg-success' }} text-white">
|
|
<div class="card-body">
|
|
<div class="d-flex justify-content-between align-items-center">
|
|
<div>
|
|
<h6 class="card-subtitle mb-1">警告商品數</h6>
|
|
<h2 class="mb-0">{{ summary.low_stock_count }}</h2>
|
|
</div>
|
|
<div class="fs-1">
|
|
<i class="bi bi-exclamation-triangle"></i>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="col-12 col-md-4">
|
|
<div class="card stat-card bg-info text-white">
|
|
<div class="card-body">
|
|
<div class="d-flex justify-content-between align-items-center">
|
|
<div>
|
|
<h6 class="card-subtitle mb-1">警告比例</h6>
|
|
<h2 class="mb-0">{{ "%.1f"|format(summary.alert_percentage) }}%</h2>
|
|
</div>
|
|
<div class="fs-1">
|
|
<i class="bi bi-percent"></i>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- 庫存警告列表 -->
|
|
<div class="card">
|
|
<div class="card-header d-flex justify-content-between align-items-center flex-wrap gap-2">
|
|
<h5 class="card-title mb-0">庫存狀態</h5>
|
|
<button onclick="refreshData()" class="btn btn-light">
|
|
<i class="bi bi-arrow-clockwise me-1"></i>
|
|
<span class="d-none d-sm-inline">刷新</span>
|
|
</button>
|
|
</div>
|
|
<div class="card-body p-0">
|
|
<div class="table-responsive">
|
|
<table class="table table-hover align-middle mb-0">
|
|
<thead class="bg-light">
|
|
<tr>
|
|
<th class="ps-3">商品資訊</th>
|
|
<th class="text-end">庫存狀態</th>
|
|
<th class="text-center d-none d-md-table-cell">庫存比例</th>
|
|
<th class="text-end pe-3">操作</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
{% for item in status %}
|
|
<tr class="{{ 'table-danger' if item.status == 'danger' }}">
|
|
<td class="ps-3">
|
|
<div class="d-flex flex-column">
|
|
<span class="fw-medium">{{ item.product.name }}</span>
|
|
<small class="text-muted">{{ item.product.code }}</small>
|
|
</div>
|
|
</td>
|
|
<td class="text-end">
|
|
<div class="d-flex flex-column align-items-end">
|
|
<div class="d-flex align-items-center gap-2">
|
|
<span>{{ item.product.quantity }} / {{ item.product.min_quantity }}</span>
|
|
{% if item.status == 'danger' %}
|
|
<span class="badge bg-danger">庫存不足</span>
|
|
{% else %}
|
|
<span class="badge bg-success">正常</span>
|
|
{% endif %}
|
|
</div>
|
|
<small class="text-{{ 'danger' if item.margin < 0 else 'success' }}">
|
|
差額: {{ item.margin }}
|
|
</small>
|
|
</div>
|
|
</td>
|
|
<td class="text-center d-none d-md-table-cell">
|
|
<div class="progress" style="height: 20px;">
|
|
<div class="progress-bar {{ 'bg-danger' if item.percentage < 100 else 'bg-success' }}"
|
|
role="progressbar"
|
|
style="width: {{ min(item.percentage, 100) }}%"
|
|
aria-valuenow="{{ item.percentage }}"
|
|
aria-valuemin="0"
|
|
aria-valuemax="100">
|
|
{{ "%.0f"|format(item.percentage) }}%
|
|
</div>
|
|
</div>
|
|
</td>
|
|
<td class="text-end pe-3">
|
|
<a href="{{ url_for('transaction.create_transaction', product_id=item.product.id, type='in') }}"
|
|
class="btn btn-primary btn-sm">
|
|
<i class="bi bi-box-arrow-in-down"></i>
|
|
<span class="d-none d-sm-inline ms-1">入庫</span>
|
|
</a>
|
|
</td>
|
|
</tr>
|
|
{% else %}
|
|
<tr>
|
|
<td colspan="4" class="text-center py-4">
|
|
<div class="text-muted">
|
|
<i class="bi bi-emoji-smile fs-2"></i>
|
|
<p class="mt-2">沒有庫存警告</p>
|
|
</div>
|
|
</td>
|
|
</tr>
|
|
{% endfor %}
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- 移動端庫存比例顯示 -->
|
|
<div class="d-md-none mt-3">
|
|
{% for item in status %}
|
|
{% if item.status == 'danger' %}
|
|
<div class="card mb-2">
|
|
<div class="card-body">
|
|
<h6 class="card-title">{{ item.product.name }}</h6>
|
|
<div class="progress mb-2" style="height: 20px;">
|
|
<div class="progress-bar bg-danger"
|
|
role="progressbar"
|
|
style="width: {{ min(item.percentage, 100) }}%"
|
|
aria-valuenow="{{ item.percentage }}"
|
|
aria-valuemin="0"
|
|
aria-valuemax="100">
|
|
{{ "%.0f"|format(item.percentage) }}%
|
|
</div>
|
|
</div>
|
|
<small class="text-muted">
|
|
庫存量: {{ item.product.quantity }} / {{ item.product.min_quantity }}
|
|
</small>
|
|
</div>
|
|
</div>
|
|
{% endif %}
|
|
{% endfor %}
|
|
</div>
|
|
{% endblock %}
|