bakery-erp / src /BakeryErp.Web /Pages /Inventory.cshtml
Neil67's picture
Deploy Bakery ERP Space
13240d3
Raw
History Blame Contribute Delete
9.07 kB
@page
@using BakeryErp.Infrastructure.Database
@using BakeryErp.Infrastructure.Repositories
@model InventoryModel
@{
ViewData["Title"] = "庫存管理";
}
<header class="page-header">
<div>
<p class="eyebrow">庫存管理</p>
<h1>即時庫存與異動審核</h1>
</div>
<a class="button-link" href="/">返回總覽</a>
</header>
@if (!string.IsNullOrWhiteSpace(Model.Message))
{
<div class="notice success">@Model.Message</div>
}
@if (!string.IsNullOrWhiteSpace(Model.ErrorMessage))
{
<div class="notice error">@Model.ErrorMessage</div>
}
<section class="metrics compact">
<article>
<span>庫存品項</span>
<strong>@Model.Report.StockItemCount</strong>
</article>
<article>
<span>低庫存</span>
<strong>@Model.Report.LowStockCount</strong>
</article>
<article>
<span>待審核</span>
<strong>@Model.Report.PendingApprovalCount</strong>
</article>
<article>
<span>已審核異動</span>
<strong>@Model.Report.ApprovedTransactionCount</strong>
</article>
<article>
<span>總庫存數量</span>
<strong>@Model.Report.TotalQuantityOnHand.ToString("N0")</strong>
</article>
</section>
<section class="form-panel">
<h2>@(Model.Form.Id == Guid.Empty ? "新增庫存異動" : "編輯庫存異動")</h2>
<form method="post" class="data-form">
<input type="hidden" asp-for="Form.Id" />
<div class="field">
<label asp-for="Form.TransactionNumber">異動單號</label>
<input asp-for="Form.TransactionNumber" placeholder="例如 INV-20260525-002" />
</div>
<div class="field">
<label asp-for="Form.WarehouseName">倉庫</label>
<input asp-for="Form.WarehouseName" list="warehouseOptions" placeholder="例如 中央廚房主倉" />
</div>
<div class="field">
<label asp-for="Form.ItemSku">品項代號</label>
<input asp-for="Form.ItemSku" list="itemSkuOptions" placeholder="例如 RM-FLOUR-001" />
</div>
<div class="field">
<label asp-for="Form.ItemName">品項名稱</label>
<input asp-for="Form.ItemName" list="itemNameOptions" placeholder="例如 高筋麵粉" />
</div>
<div class="field">
<label asp-for="Form.TransactionType">異動類型</label>
<select asp-for="Form.TransactionType">
@foreach (var type in Model.TransactionTypeOptions)
{
<option value="@type">@InventoryRepository.GetTransactionTypeName(type)</option>
}
</select>
</div>
<div class="field">
<label asp-for="Form.Quantity">數量</label>
<input asp-for="Form.Quantity" type="number" step="0.01" />
</div>
<div class="field">
<label asp-for="Form.Unit">單位</label>
<input asp-for="Form.Unit" list="unitOptions" placeholder="kg / 個 / 箱" />
</div>
<div class="field">
<label asp-for="OccurredDateText">異動日期</label>
<input asp-for="OccurredDateText" type="date" />
</div>
<div class="field">
<label asp-for="Form.SourceDocumentNumber">來源單號</label>
<input asp-for="Form.SourceDocumentNumber" placeholder="進貨單 / OCR 單號 / 調撥單" />
</div>
<div class="field wide">
<label asp-for="Form.Note">備註</label>
<textarea asp-for="Form.Note" rows="3"></textarea>
</div>
<div class="form-actions">
<button class="primary-button" type="submit" asp-page-handler="Save">儲存待審核</button>
<a class="secondary-button" href="/Inventory">清空表單</a>
</div>
<datalist id="warehouseOptions">
@foreach (var warehouse in Model.WarehouseOptions)
{
<option value="@warehouse.Value">@warehouse.Label</option>
}
</datalist>
<datalist id="itemSkuOptions">
@foreach (var item in Model.ItemOptions)
{
<option value="@item.Sku">@item.Label</option>
}
</datalist>
<datalist id="itemNameOptions">
@foreach (var item in Model.ItemOptions)
{
<option value="@item.Name">@item.Label</option>
}
</datalist>
<datalist id="unitOptions">
@foreach (var unit in Model.ItemOptions.Select(item => item.Unit).Distinct())
{
<option value="@unit"></option>
}
</datalist>
</form>
</section>
<section class="table-panel">
<div class="section-title">
<h2>即時庫存清單</h2>
<span>@Model.StockBalances.Count 筆</span>
</div>
<div class="table-wrap">
<table>
<thead>
<tr>
<th>狀態</th>
<th>倉庫</th>
<th>品項代號</th>
<th>品項名稱</th>
<th>現有庫存</th>
<th>安全庫存</th>
<th>單位</th>
<th>最後異動</th>
</tr>
</thead>
<tbody>
@foreach (var stock in Model.StockBalances)
{
var isLowStock = stock.QuantityOnHand <= stock.SafetyStockQuantity;
<tr class="@(isLowStock ? "muted-row" : null)">
<td>
<span class="badge @(isLowStock ? "warn" : "ok")">
@(isLowStock ? "低庫存" : "正常")
</span>
</td>
<td>@stock.WarehouseName</td>
<td>@stock.ItemSku</td>
<td>@stock.ItemName</td>
<td>@stock.QuantityOnHand.ToString("N2")</td>
<td>@stock.SafetyStockQuantity.ToString("N2")</td>
<td>@stock.Unit</td>
<td>@stock.LastTransactionAt.ToLocalTime().ToString("yyyy-MM-dd HH:mm")</td>
</tr>
}
</tbody>
</table>
</div>
</section>
<section class="table-panel">
<div class="section-title">
<h2>庫存異動清單</h2>
<span>@Model.Transactions.Count 筆</span>
</div>
<div class="table-wrap">
<table>
<thead>
<tr>
<th>狀態</th>
<th>異動單號</th>
<th>類型</th>
<th>倉庫</th>
<th>品項</th>
<th>數量</th>
<th>日期</th>
<th>操作</th>
</tr>
</thead>
<tbody>
@foreach (var transaction in Model.Transactions)
{
<tr>
<td>
<span class="badge @Model.GetStatusClass(transaction.Status)">
@InventoryRepository.GetStatusName(transaction.Status)
</span>
</td>
<td>@transaction.TransactionNumber</td>
<td>@InventoryRepository.GetTransactionTypeName(transaction.TransactionType)</td>
<td>@transaction.WarehouseName</td>
<td>@transaction.ItemName</td>
<td>@transaction.Quantity.ToString("N2") @transaction.Unit</td>
<td>@transaction.OccurredAt.ToLocalTime().ToString("yyyy-MM-dd")</td>
<td class="row-actions">
@if (transaction.Status != LocalInventoryTransactionStatus.Approved)
{
<a class="small-link" href="/Inventory?editId=@transaction.Id">編輯</a>
<form method="post">
<input type="hidden" name="id" value="@transaction.Id" />
<button class="text-button" type="submit" asp-page-handler="Approve">審核入帳</button>
</form>
<form method="post">
<input type="hidden" name="id" value="@transaction.Id" />
<button class="text-button" type="submit" asp-page-handler="Cancel">取消</button>
</form>
}
else
{
<span class="muted-text">已入帳</span>
}
</td>
</tr>
}
</tbody>
</table>
</div>
</section>