using System;
using System.Collections.ObjectModel;
using System.Linq;
using System.Threading.Tasks;
using CommunityToolkit.Mvvm.ComponentModel;
using CommunityToolkit.Mvvm.Input;
using Elfisa.Core;
namespace Elfisa.Avalonia.ViewModels;
///
/// Отправить — отправка НЕОТПРАВЛЕННЫХ накладных (черновиков заказов из раздела
/// «Заказы»). Список готовых накладных, кнопка «Отправить» (создаёт реальный заказ
/// у поставщика). Без поиска по прайсу и наименований — только сами накладные.
///
public partial class SendOrderViewModel : ViewModelBase
{
private readonly ApiClient _api = new();
/// Неотправленные накладные (черновики).
public ObservableCollection Drafts { get; } = new();
[ObservableProperty] private DraftOrder? _selected;
[ObservableProperty] private bool _busy;
[ObservableProperty] private string? _status;
[ObservableProperty] private decimal _totalSum;
[ObservableProperty] private bool _isEmpty = true;
[ObservableProperty] private int _count;
public SendOrderViewModel()
{
_api.SetToken(Session.Current.Token);
Load();
}
[RelayCommand]
private void Refresh() => Load();
private void Load()
{
Drafts.Clear();
foreach (var d in DraftStore.All.OrderByDescending(x => x.CreatedAt))
Drafts.Add(d);
TotalSum = Drafts.Sum(d => d.Total);
Count = Drafts.Count;
IsEmpty = Drafts.Count == 0;
if (Selected is null || !Drafts.Contains(Selected))
Selected = Drafts.FirstOrDefault();
}
/// Отправить одну накладную.
[RelayCommand]
private async Task SendAsync(DraftOrder? draft)
{
var d = draft ?? Selected;
if (d is null) { Status = "Выберите накладную для отправки."; return; }
Status = null;
try
{
Busy = true;
var resp = await CreateFromDraft(d);
DraftStore.Remove(d.Id);
Status = $"✓ Накладная {resp.GlobalSign ?? resp.OrderId} отправлена ({resp.ItemsCount} поз., {resp.TotalAmount:N2}).";
}
catch (Exception ex) { Status = "Ошибка отправки: " + ex.Message; }
finally { Busy = false; Load(); }
}
/// Отправить все неотправленные накладные.
[RelayCommand]
private async Task SendAllAsync()
{
if (Drafts.Count == 0) { Status = "Нет неотправленных накладных."; return; }
Status = null;
int ok = 0;
string? lastErr = null;
try
{
Busy = true;
foreach (var d in DraftStore.All.ToList())
{
try
{
await CreateFromDraft(d);
DraftStore.Remove(d.Id);
ok++;
}
catch (Exception ex) { lastErr = ex.Message; }
}
}
finally { Busy = false; Load(); }
Status = lastErr is null
? $"✓ Отправлено накладных: {ok}."
: $"Отправлено: {ok}. Не удалось часть — {lastErr}";
}
/// Удалить неотправленную накладную (не отправляя).
[RelayCommand]
private void Delete(DraftOrder? draft)
{
var d = draft ?? Selected;
if (d is null) return;
DraftStore.Remove(d.Id);
Load();
Status = "Накладная удалена.";
}
private async Task CreateFromDraft(DraftOrder d)
{
var req = new BuyerOrderCreateRequest
{
// Номер EX резервировался при сохранении черновика — используем его.
GlobalSign = d.Number.StartsWith("EX-", StringComparison.OrdinalIgnoreCase) ? d.Number : null,
LocationId = d.LocationId,
Comment = d.Comment,
Items = d.Items.Select(i => new BuyerOrderItemReq
{
SupplierPriceId = i.SupplierPriceId,
Qty = (double)i.Qty,
ItemName = i.Name,
Barcode = i.Barcode
}).ToList()
};
return await _api.CreateOrderAsync(req);
}
}