using System.Collections.Generic; using System.Diagnostics.CodeAnalysis; using System.Linq; using Content.Server.Access.Systems; using Content.Shared.Cargo; using Robust.Shared.GameObjects; using Robust.Shared.Localization; namespace Content.Server.Cargo { public sealed class CargoOrderDatabase { private readonly Dictionary _orders = new(); private int _orderNumber = 0; public CargoOrderDatabase(int id) { Id = id; CurrentOrderSize = 0; MaxOrderSize = 20; } public int Id { get; private set; } public int CurrentOrderSize { get; private set; } public int MaxOrderSize { get; private set; } /// /// Removes all orders from the database. /// public void Clear() { _orders.Clear(); } /// /// Returns a list of all orders. /// /// A list of orders public List GetOrders() { return _orders.Values.ToList(); } public bool TryGetOrder(int id, [NotNullWhen(true)] out CargoOrderData? order) { return _orders.TryGetValue(id, out order); } public List SpliceApproved() { var orders = _orders.Values.Where(order => order.Approved).ToList(); foreach (var order in orders) _orders.Remove(order.OrderNumber); return orders; } /// /// Adds an order to the database. /// /// The person who requested the item. /// The reason the product was requested. /// The ID of the product requested. /// The amount of the products requested. /// The ID of the bank account paying for the order. /// Whether the order will be bought when the orders are processed. public void AddOrder(string requester, string reason, string productId, int amount, int payingAccountId) { var order = new CargoOrderData(_orderNumber, requester, reason, productId, amount, payingAccountId); if (Contains(order)) return; _orders.Add(_orderNumber, order); _orderNumber += 1; } /// /// Removes an order from the database. /// /// The order to be removed. /// Whether it could be removed or not public bool RemoveOrder(int orderNumber) { return _orders.Remove(orderNumber); } /// /// Approves an order in the database. /// /// The order to be approved. public bool ApproveOrder(string approver, int orderNumber) { if (CurrentOrderSize == MaxOrderSize || !_orders.TryGetValue(orderNumber, out var order) || order.Approved) { return false; } else if (CurrentOrderSize + order.Amount > MaxOrderSize) { AddOrder( order.Requester, Loc.GetString("cargo-order-database-order-overflow-message", ("placeholder", order.Reason.Replace(" (Overflow)", string.Empty))), order.ProductId, order.Amount - MaxOrderSize - CurrentOrderSize, order.PayingAccountId); order.Amount = MaxOrderSize - CurrentOrderSize; } order.Approved = true; order.Approver = approver; CurrentOrderSize += order.Amount; return true; } /// /// Returns whether the database contains the order or not. /// /// The order to check /// Whether the database contained the order or not. public bool Contains(CargoOrderData order) { return _orders.ContainsValue(order); } /// /// Clears the current order capacity. This allows more orders to be processed and is invoked after an order is dispatched. /// public void ClearOrderCapacity() { CurrentOrderSize = 0; } } }