- Навигация перенесена из левого сайдбара в ВЕРХНЮЮ горизонтальную панель, как в исходной программе: логотип слева, вкладки (иконка+подпись) по центру, пользователь+Выйти справа - Раздел «Заказы»: мастер-детали (список слева, состав заказа справа с позициями и итогом), на данных /api/buyer/report - Числовые колонки выровнены вправо (стиль DataGridCell.num) - Отчёты: тулбар на WrapPanel, стабильные ширины колонок Проверено запуском (скриншоты): верхняя навигация, отчёты, заказы. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
100 lines
3.4 KiB
C#
100 lines
3.4 KiB
C#
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 sealed class OrderItemRow
|
|
{
|
|
public string Name { get; init; } = "";
|
|
public string Code { get; init; } = "";
|
|
public decimal Qty { get; init; }
|
|
public decimal Price { get; init; }
|
|
public decimal Sum { get; init; }
|
|
}
|
|
|
|
public sealed class OrderSummary
|
|
{
|
|
public string Date { get; init; } = "";
|
|
public string Number { get; init; } = "";
|
|
public string Supplier { get; init; } = "";
|
|
public string Location { get; init; } = "";
|
|
public string Status { get; init; } = "";
|
|
public int ItemsCount { get; init; }
|
|
public decimal Sum { get; init; }
|
|
public ObservableCollection<OrderItemRow> Items { get; init; } = new();
|
|
}
|
|
|
|
/// <summary>
|
|
/// Заказы: список + состав. Пока строится из /api/buyer/report (он работает);
|
|
/// после деплоя фикса /api/buyer/orders можно перейти на «родной» эндпоинт
|
|
/// (даст ещё PlacedAt, Comment, отмену/размещение).
|
|
/// </summary>
|
|
public partial class OrdersViewModel : ViewModelBase
|
|
{
|
|
private readonly ApiClient _api = new();
|
|
|
|
public ObservableCollection<OrderSummary> Orders { get; } = new();
|
|
|
|
[ObservableProperty] private OrderSummary? _selectedOrder;
|
|
[ObservableProperty] private bool _busy;
|
|
[ObservableProperty] private string? _status;
|
|
|
|
public OrdersViewModel()
|
|
{
|
|
_api.SetToken(Session.Current.Token);
|
|
if (Session.Current.IsAuthenticated) _ = LoadAsync();
|
|
}
|
|
|
|
[RelayCommand]
|
|
private async Task LoadAsync()
|
|
{
|
|
Status = null;
|
|
try
|
|
{
|
|
Busy = true;
|
|
var to = DateTime.Today;
|
|
var from = to.AddMonths(-24);
|
|
var lines = await _api.GetBuyerReportAsync(from, to);
|
|
|
|
Orders.Clear();
|
|
foreach (var g in lines.GroupBy(l => l.OrderId)
|
|
.OrderByDescending(x => x.First().OrderDate ?? DateTime.MinValue))
|
|
{
|
|
var f = g.First();
|
|
var items = new ObservableCollection<OrderItemRow>(
|
|
g.Select(l => new OrderItemRow
|
|
{
|
|
Name = l.ItemName ?? "",
|
|
Code = l.ItemCode ?? "",
|
|
Qty = l.Qty,
|
|
Price = l.UnitPrice,
|
|
Sum = l.Sum
|
|
}));
|
|
|
|
Orders.Add(new OrderSummary
|
|
{
|
|
Date = f.OrderDate?.ToLocalTime().ToString("dd.MM.yyyy") ?? "",
|
|
Number = f.GlobalSign ?? "",
|
|
Supplier = string.Join(", ", g.Select(x => x.Supplier)
|
|
.Where(s => !string.IsNullOrWhiteSpace(s)).Distinct()),
|
|
Location = f.Location ?? "",
|
|
Status = f.Status ?? "",
|
|
ItemsCount = g.Count(),
|
|
Sum = g.Sum(x => x.Sum),
|
|
Items = items
|
|
});
|
|
}
|
|
|
|
SelectedOrder = Orders.FirstOrDefault();
|
|
if (Orders.Count == 0) Status = "Заказов за последние 2 года нет.";
|
|
}
|
|
catch (Exception ex) { Status = ex.Message; }
|
|
finally { Busy = false; }
|
|
}
|
|
}
|