Mango.Nop.Plugins/Nop.Plugin.Misc.AIPlugin/Areas/Admin/Views/OrderDraft/Detail.cshtml

378 lines
18 KiB
Plaintext

@model Nop.Plugin.Misc.FruitBankPlugin.Areas.Admin.Models.OrderDraftDetailModel
@{
ViewBag.PageTitle = "Rendelés tervezet #" + Model.Id;
}
<div class="content-header clearfix">
<h1 class="float-left">
<i class="fas fa-inbox" style="color:#f4a236"></i>
Rendelés tervezet <strong>#@Model.Id</strong>
<span class="badge @(Model.Status == "Pending" ? "badge-warning" : Model.Status == "Approved" ? "badge-success" : "badge-danger")"
style="font-size:14px; vertical-align:middle">@Model.Status</span>
</h1>
<div class="float-right">
<a href="/Admin/OrderDraft" class="btn btn-default">
<i class="fas fa-arrow-left"></i> Vissza a listára
</a>
</div>
</div>
<section class="content">
<div class="container-fluid">
@Html.AntiForgeryToken()
<div class="row">
{{-- BAL OLDAL: meta + üzenet --}}
<div class="col-md-4">
{{-- Eredeti üzenet --}}
<div class="card card-default">
<div class="card-header" style="background:#1a3c22; color:#fff">
<i class="fas fa-envelope"></i> Eredeti üzenet
</div>
<div class="card-body">
<pre style="white-space:pre-wrap; font-size:13px; background:#f5f7f2; border-radius:6px; padding:12px; border:1px solid #ddd">@Model.RawMessageText</pre>
</div>
</div>
{{-- Meta adatok --}}
<div class="card card-default">
<div class="card-header"><i class="fas fa-info-circle"></i> Adatok</div>
<div class="card-body p-0">
<table class="table table-sm m-0">
<tr>
<td class="text-muted" style="width:40%">Feladó</td>
<td><code>@Model.ExternalUsername</code></td>
</tr>
<tr>
<td class="text-muted">Partner</td>
<td id="partner-cell">
@if (Model.CustomerId.HasValue)
{
<a href="/Admin/Customer/Edit/@Model.CustomerId" target="_blank">@Model.CustomerName</a>
}
else
{
<span class="text-danger"><i class="fas fa-exclamation-triangle"></i> Nincs hozzárendelve</span>
}
</td>
</tr>
<tr>
<td class="text-muted">Szállítás</td>
<td>
<strong>@Model.ParsedDeliveryDate.ToString("yyyy-MM-dd")</strong>
@if (Model.IsPreorder)
{
<span class="badge badge-info ml-1">Előrendelés</span>
}
else
{
<span class="badge badge-warning ml-1">Azonnali</span>
}
</td>
</tr>
<tr>
<td class="text-muted">Beérkezett</td>
<td>@Model.CreatedOnUtc</td>
</tr>
@if (!string.IsNullOrEmpty(Model.AdminNote))
{
<tr>
<td class="text-muted">Megjegyzés</td>
<td class="text-danger">@Model.AdminNote</td>
</tr>
}
</table>
</div>
</div>
{{-- Partner hozzárendelés (csak ha nincs még) --}}
@if (!Model.CustomerId.HasValue && Model.CanApprove)
{
<div class="card card-warning">
<div class="card-header"><i class="fas fa-user-plus"></i> Partner hozzárendelése</div>
<div class="card-body">
<p class="text-muted" style="font-size:13px">
Ismeretlen feladó: <code>@Model.ExternalUsername</code><br>
Rendeld hozzá a megfelelő partnerhez. A rendszer megjegyzi a kapcsolatot.
</p>
<input type="text" id="customer-search" class="form-control form-control-sm"
placeholder="Ügyfél neve vagy e-mail..." autocomplete="off" />
<input type="hidden" id="selected-customer-id" />
<div id="customer-search-results" class="list-group mt-1" style="display:none; position:absolute; z-index:999; width:300px"></div>
<button type="button" id="btn-assign-customer" class="btn btn-warning btn-sm mt-2" disabled>
<i class="fas fa-link"></i> Hozzárendelés
</button>
</div>
</div>
}
</div>{{-- /col-md-4 --}}
{{-- JOBB OLDAL: tételek --}}
<div class="col-md-8">
<div class="card card-default">
<div class="card-header" style="background:#2d7a3a; color:#fff">
<i class="fas fa-list"></i> Tételek
<span class="badge badge-light float-right" style="color:#333">@Model.Items.Count db</span>
</div>
<div class="card-body p-0">
<table class="table table-bordered m-0" id="items-table">
<thead class="thead-light">
<tr>
<th style="width:200px">Eredeti szöveg</th>
<th>AI javaslat / Termék kiválasztása</th>
<th style="width:90px">Menny. (kt.)</th>
<th style="width:80px">Típus</th>
</tr>
</thead>
<tbody>
@foreach (var item in Model.Items)
{
<tr data-item-id="@item.Id">
<td>
<strong style="color:#1a3c22">@item.RawProductText</strong>
@if (!string.IsNullOrEmpty(item.AiResolvedProductName) && item.AiResolvedProductName != item.RawProductText)
{
<br><small class="text-muted">→ @item.AiResolvedProductName</small>
}
</td>
<td>
<select class="form-control form-control-sm product-select"
data-item-id="@item.Id"
@(Model.CanApprove ? "" : "disabled")>
<option value="">— válassz terméket —</option>
@foreach (var c in item.Candidates)
{
var selected = c.Id == item.SelectedProductId ? "selected" : "";
<option value="@c.Id" @selected>
@c.Name (készlet: @c.Stock)
</option>
}
@if (item.SelectedProductId.HasValue && !item.Candidates.Any(c => c.Id == item.SelectedProductId))
{
<option value="@item.SelectedProductId" selected>@item.SelectedProductName</option>
}
</select>
<div class="save-indicator text-success" style="display:none; font-size:11px; margin-top:2px">
<i class="fas fa-check"></i> Mentve
</div>
</td>
<td>
<input type="number" class="form-control form-control-sm qty-input"
value="@item.RequestedQuantity" min="1" step="1"
data-item-id="@item.Id"
@(Model.CanApprove ? "" : "disabled") />
</td>
<td class="text-center">
@if (item.IsPreorder)
{
<span class="badge badge-info">Elő</span>
}
else
{
<span class="badge badge-warning">Azonnali</span>
}
</td>
</tr>
}
</tbody>
</table>
</div>
</div>
{{-- Akció gombok --}}
@if (Model.CanApprove)
{
<div class="card card-default">
<div class="card-body">
<div class="row">
<div class="col-md-8">
<button type="button" id="btn-approve" class="btn btn-success btn-lg">
<i class="fas fa-check-circle"></i> Jóváhagyás és rendelés/előrendelés létrehozása
</button>
</div>
<div class="col-md-4 text-right">
<button type="button" id="btn-reject" class="btn btn-danger">
<i class="fas fa-times-circle"></i> Elutasítás
</button>
</div>
</div>
<div id="approve-result" class="mt-3" style="display:none"></div>
</div>
</div>
}
</div>{{-- /col-md-8 --}}
</div>{{-- /row --}}
</div>
</section>
<style>
.badge-info { background: #17a2b8; color:#fff; }
.badge-warning { background: #f4a236; color:#fff; }
.badge-success { background: #2d7a3a; color:#fff; }
.badge-danger { background: #c0392b; color:#fff; }
.badge-light { background: #eee; }
#items-table select { min-width: 200px; }
</style>
<script>
$(function () {
var _token = $('input[name="__RequestVerificationToken"]').val();
var _draftId = @Model.Id;
// ── Termék kiválasztás mentése blur/change-re ─────────────────────────
var _saveTimer = {};
function saveItem(itemId) {
var $row = $('tr[data-item-id="' + itemId + '"]');
var prodId = $row.find('.product-select').val();
var qty = parseInt($row.find('.qty-input').val()) || 1;
var $ind = $row.find('.save-indicator');
if (!prodId) return;
clearTimeout(_saveTimer[itemId]);
_saveTimer[itemId] = setTimeout(function() {
$.post('/Admin/OrderDraft/UpdateItem', {
__RequestVerificationToken : _token,
draftItemId : itemId,
selectedProductId: prodId,
quantity : qty
}).done(function(res) {
if (res.success) {
$ind.fadeIn(200).delay(1500).fadeOut(400);
}
});
}, 400);
}
$(document).on('change', '.product-select', function() {
saveItem($(this).data('item-id'));
});
$(document).on('change', '.qty-input', function() {
saveItem($(this).data('item-id'));
});
// ── Partner keresés ──────────────────────────────────────────────────
var _searchTimer;
$('#customer-search').on('input', function() {
var q = $(this).val().trim();
if (q.length < 2) { $('#customer-search-results').hide(); return; }
clearTimeout(_searchTimer);
_searchTimer = setTimeout(function() {
$.get('/Admin/CustomOrder/CustomerSearchAutoComplete', { term: q }, function(data) {
var $res = $('#customer-search-results').empty().show();
if (!data || data.length === 0) {
$res.append('<a class="list-group-item list-group-item-action text-muted">Nincs találat</a>');
return;
}
$.each(data, function(i, item) {
$res.append(
$('<a class="list-group-item list-group-item-action" href="#">')
.text(item.label)
.on('click', function(e) {
e.preventDefault();
$('#customer-search').val(item.label);
$('#selected-customer-id').val(item.value);
$('#btn-assign-customer').prop('disabled', false);
$res.hide();
})
);
});
});
}, 300);
});
// Partner hozzárendelés
$('#btn-assign-customer').on('click', function() {
var custId = $('#selected-customer-id').val();
if (!custId) return;
$.post('/Admin/OrderDraft/AssignCustomer', {
__RequestVerificationToken: _token,
draftId : _draftId,
customerId : custId
}).done(function(res) {
if (res.success) {
$('#partner-cell').html('<a href="/Admin/Customer/Edit/' + custId + '" target="_blank">' + res.customerName + '</a>');
$('.card-warning').slideUp();
}
});
});
// ── Elutasítás ───────────────────────────────────────────────────────
$('#btn-reject').on('click', function() {
var note = prompt('Opcionális megjegyzés az elutasítás okáról:');
if (note === null) return; // Cancel
$.post('/Admin/OrderDraft/Reject', {
__RequestVerificationToken: _token,
draftId : _draftId,
adminNote: note || ''
}).done(function(res) {
if (res.success) location.reload();
});
});
// ── Jóváhagyás ──────────────────────────────────────────────────────
$('#btn-approve').on('click', function() {
var $btn = $(this);
// Ellenőrzés: minden tétel ki van töltve?
var missingCount = 0;
$('.product-select').each(function() {
if (!$(this).val()) missingCount++;
});
if (missingCount > 0) {
showResult('danger', missingCount + ' tétel nincs kitöltve. Minden sorban válassz terméket a jóváhagyás előtt.');
return;
}
$btn.prop('disabled', true).html('<i class="fas fa-spinner fa-spin"></i> Feldolgozás...');
$.post('/Admin/OrderDraft/Approve', {
__RequestVerificationToken: _token,
draftId: _draftId
}).done(function(res) {
if (res.success) {
var lines = ['<strong><i class="fas fa-check-circle"></i> Sikeresen létrehozva!</strong><br>'];
if (res.orderIds && res.orderIds.length > 0) {
lines.push('Rendelés(ek): ' + res.orderIds.map(function(id) {
return '<a href="/Admin/Order/Edit/' + id + '" target="_blank">#' + id + '</a>';
}).join(', '));
}
if (res.preOrderIds && res.preOrderIds.length > 0) {
lines.push('Előrendelés(ek): ' + res.preOrderIds.map(function(id) {
return '<a href="/Admin/PreOrders/Detail/' + id + '" target="_blank">#' + id + '</a>';
}).join(', '));
}
showResult('success', lines.join('<br>'));
setTimeout(function() { location.reload(); }, 2500);
} else {
showResult('danger', res.error || 'Ismeretlen hiba.');
$btn.prop('disabled', false).html('<i class="fas fa-check-circle"></i> Jóváhagyás és rendelés/előrendelés létrehozása');
}
}).fail(function() {
showResult('danger', 'Szerverhiba. Próbáld újra.');
$btn.prop('disabled', false).html('<i class="fas fa-check-circle"></i> Jóváhagyás és rendelés/előrendelés létrehozása');
});
});
function showResult(type, html) {
$('#approve-result')
.removeClass('alert-success alert-danger')
.addClass('alert alert-' + type)
.html(html)
.show();
}
// Kattintás máshova: customer search bezárás
$(document).on('click', function(e) {
if (!$(e.target).closest('#customer-search, #customer-search-results').length)
$('#customer-search-results').hide();
});
});
</script>