| | | 1 | | using System.ComponentModel.DataAnnotations; |
| | | 2 | | using System.ComponentModel.DataAnnotations.Schema; |
| | | 3 | | |
| | | 4 | | namespace OzonDomains.Models.SupplierStatuses; |
| | | 5 | | |
| | | 6 | | /// <summary> |
| | | 7 | | /// Состояние заказа Studio2 у API-поставщика. Одна строка ведёт заказ через обе стадии: |
| | | 8 | | /// создаётся при попадании в корзину (Stage = Cart), при оформлении переходит в Stage = Ordered |
| | | 9 | | /// и дальше несёт статус заказа от API. Модель Order не расширяется — связь только отсюда. |
| | | 10 | | /// </summary> |
| | | 11 | | [Table("OrderSupplierStates")] |
| | | 12 | | public class OrderSupplierState |
| | | 13 | | { |
| | 609 | 14 | | public long Id { get; set; } |
| | | 15 | | |
| | 832 | 16 | | public int OrderId { get; set; } |
| | | 17 | | |
| | 0 | 18 | | public virtual Order? Order { get; set; } |
| | | 19 | | |
| | | 20 | | /// <summary>Ключ провайдера: Avd / Armtek / ArmtekBy / MlAuto / MlAutoRu.</summary> |
| | | 21 | | [Required, MaxLength(64)] |
| | 1451 | 22 | | public string ProviderKey { get; set; } = string.Empty; |
| | | 23 | | |
| | | 24 | | /// <summary>Системный поставщик на момент создания строки.</summary> |
| | 21 | 25 | | public int? SupplierId { get; set; } |
| | | 26 | | |
| | | 27 | | /// <summary>Cart / Ordered / Closed — см. OrderSupplierStage.</summary> |
| | | 28 | | [Required, MaxLength(20)] |
| | 1487 | 29 | | public string Stage { get; set; } = OrderSupplierStage.Cart; |
| | | 30 | | |
| | | 31 | | /// <summary> |
| | | 32 | | /// Текущий статус: корзины (StatusKind = Cart) или заказа (StatusKind = Order), |
| | | 33 | | /// в зависимости от <see cref="Stage"/>. |
| | | 34 | | /// </summary> |
| | 174 | 35 | | public int? SupplierStatusId { get; set; } |
| | | 36 | | |
| | 0 | 37 | | public virtual SupplierStatus? SupplierStatus { get; set; } |
| | | 38 | | |
| | | 39 | | /// <summary> |
| | | 40 | | /// Равен <see cref="OrderId"/>, пока строка активна, и NULL после закрытия. |
| | | 41 | | /// Уникальный индекс (ProviderKey, ActiveOrderId) не даёт завести двойное отслеживание |
| | | 42 | | /// одного заказа у одного поставщика, но сохраняет закрытые строки для истории. |
| | | 43 | | /// </summary> |
| | 650 | 44 | | public int? ActiveOrderId { get; set; } |
| | | 45 | | |
| | | 46 | | /// <summary>Id строки локальной корзины: ArmtekCartItems / MlAutoCartItems / MlAutoRuCartItems.</summary> |
| | 1 | 47 | | public long? CartItemId { get; set; } |
| | | 48 | | |
| | | 49 | | /// <summary>Id строки удалённой корзины АВД (у неё локальной таблицы нет).</summary> |
| | | 50 | | [MaxLength(50)] |
| | 3 | 51 | | public string? ExternalBasketItemId { get; set; } |
| | | 52 | | |
| | | 53 | | /// <summary>Номер заказа у поставщика: Vbeln (Armtek) / OrderNumber (ML-Auto) / номер заказа АВД.</summary> |
| | | 54 | | [MaxLength(50)] |
| | 117 | 55 | | public string? ExternalOrderNumber { get; set; } |
| | | 56 | | |
| | | 57 | | /// <summary>Внутренний идентификатор заказа поставщика (AvdOrder.OrderId).</summary> |
| | | 58 | | [MaxLength(50)] |
| | 2 | 59 | | public string? ExternalOrderId { get; set; } |
| | | 60 | | |
| | | 61 | | /// <summary>Идентификатор строки заказа поставщика: AvdOrderItem.Id, Armtek Posnr.</summary> |
| | | 62 | | [MaxLength(50)] |
| | 1 | 63 | | public string? ExternalLineId { get; set; } |
| | | 64 | | |
| | 13 | 65 | | public decimal? QuantityOrdered { get; set; } |
| | | 66 | | |
| | 0 | 67 | | public decimal? QuantityConfirmed { get; set; } |
| | | 68 | | |
| | 0 | 69 | | public decimal? QuantityShipped { get; set; } |
| | | 70 | | |
| | 65 | 71 | | public decimal? QuantityRejected { get; set; } |
| | | 72 | | |
| | 66 | 73 | | public DateTime? ExpectedDeliveryAt { get; set; } |
| | | 74 | | |
| | | 75 | | /// <summary>Момент фактического оформления заказа (первый переход в Stage = Ordered) — не смещается последующими см |
| | 136 | 76 | | public DateTime? OrderedAt { get; set; } |
| | | 77 | | |
| | | 78 | | /// <summary>Срок поставки (дни) на момент проценки/оформления — снимок, опросом статуса не обновляется.</summary> |
| | 7 | 79 | | public int? DeliveryDaysMin { get; set; } |
| | | 80 | | |
| | 7 | 81 | | public int? DeliveryDaysMax { get; set; } |
| | | 82 | | |
| | | 83 | | /// <summary>Направление/склад отгрузки поставщика на момент проценки, например «ЦЗ Москва (0000116774)».</summary> |
| | | 84 | | [MaxLength(255)] |
| | 9 | 85 | | public string? Direction { get; set; } |
| | | 86 | | |
| | 107 | 87 | | public DateTime? LastStatusChangeAt { get; set; } |
| | | 88 | | |
| | | 89 | | /// <summary>Ведёт выборку джобы синхронизации.</summary> |
| | 635 | 90 | | public DateTime? LastSyncedAt { get; set; } |
| | | 91 | | |
| | | 92 | | /// <summary> |
| | | 93 | | /// Последняя ошибка опроса API. Записывается, не затирая уже известный статус: |
| | | 94 | | /// недоступность поставщика не должна выглядеть как смена состояния заказа. |
| | | 95 | | /// </summary> |
| | | 96 | | [MaxLength(1000)] |
| | 95 | 97 | | public string? SyncError { get; set; } |
| | | 98 | | |
| | | 99 | | [MaxLength(450)] |
| | 46 | 100 | | public string? CreatedBy { get; set; } |
| | | 101 | | |
| | 1326 | 102 | | public DateTime CreatedAt { get; set; } = DateTime.UtcNow; |
| | | 103 | | |
| | 813 | 104 | | public DateTime UpdatedAt { get; set; } = DateTime.UtcNow; |
| | | 105 | | } |