public void DisplayAddress(int id, bool newLine = false, int tabIndents = 0)
        {
            string indentation = new string(' ', tabIndents * 2);
            string address     = (StoreManagerApplication.GetData <Address>(id) as AddressData).ToString();

            Console.Write($"{(newLine ? "\n" : "")}{indentation}{address}");
        }
        public void DisplayCustomer(int id, bool newLine = false, int tabIndents = 0)
        {
            string indentation = new string(' ', tabIndents * 2);
            var    data        = StoreManagerApplication.GetData <Customer>(id) as CustomerData;
            var    address     = (StoreManagerApplication.GetData <Address>(data.AddressId) as AddressData).ToString();
            var    prefix      = $"{(newLine ? "\n" : "")}{indentation}";
            var    items       = new List <string>
            {
                //   Name
                data.Name,
                //   Email
                data.Email,
                //   PhoneNumber
                data.PhoneNumber,
                //   AddressId -> Address
                address,
                //   BirthDate
                data.BirthDate.ToString()
            };

            Console.Write($"{prefix}{string.Join(prefix, items)}");
            //   DefaultStoreLocationId -> OperatingLocation&store (if exists)
            if (data.DefaultStoreLocationId.HasValue)
            {
                DisplayOperatingLocation(data.DefaultStoreLocationId.Value);
            }
        }
        protected OrderData CreateOrderData()
        {
            int customerId          = -1;
            int operatingLocationId = -1;
            Dictionary <int, int> productsRequested = new Dictionary <int, int>();

            // Get the customer id
            customerId = PromptForCreateOrExist <Customer>(
                () => {
                // Create a new customer
                var data = CreateCustomerData();
                return(StoreManagerApplication.Create <Customer>(data));
            },
                // Get the customer id
                () => PromptForId <Customer>()
                );

            // Get the store that owns the location
            int storeId = PromptForCreateOrExist <Store>(
                () => {
                var data = CreateStoreData();
                return(StoreManagerApplication.Create <Store>(data));
            },
                () => PromptForId <Store>()
                );

            var store = StoreManagerApplication.GetData <Store>(storeId) as StoreData;
            // Prompt for a store, then look through the locations it has
            var options = store.OperatingLocationIds.Select(id => {
                var data    = StoreManagerApplication.GetData <OperatingLocation>(id) as OperatingLocationData;
                var address = StoreManagerApplication.GetData <Address>(data.AddressId) as AddressData;
                return($"{store.Name} - {address}");
            }).ToArray();
            // Show the available locations that can be chosen from
            int selectedOption = CUI.PromptForMenuSelection(options, false);

            operatingLocationId = store.OperatingLocationIds[selectedOption];

            // Get the products the user wants
            UntilItIsDone(() => {
                // Add products and the inventory they have
                int productId = PromptForCreateOrExist <Product>(
                    () => {
                    var data = CreateProductData();
                    return(StoreManagerApplication.Create <Product>(data));
                },
                    () => PromptForId <Product>()
                    );

                int threshold = store.Inventory[productId].Item2 ?? store.Inventory[productId].Item1;

                // Get the count
                int count = CUI.PromptRange("Enter the count of said product", 0, threshold);
                productsRequested[productId] = count;

                return(!CUI.PromptForBool("Add another product?", "yes", "no"));
            });

            return(new OrderData(customerId, operatingLocationId, productsRequested));
        }
        public void DisplayProduct(int id, int count = 1, bool newLine = false, int tabIndents = 0)
        {
            var    data        = StoreManagerApplication.GetData <Product>(id) as ProductData;
            string indentation = new string(' ', tabIndents * 2);
            string discount    = data.Discount.HasValue ? $" ({data.Discount.Value}% off, making it {data.Price * (100 - data.Discount) / 100})" : "";

            Console.Write($"{(newLine ? "\n" : "")}{indentation}{data.Name} - ${data.Price * count} (x{count}) {discount}");
        }
        public void DisplayStore(int id, bool newLine = false, int tabIndents = 0)
        {
            string indentation = new string(' ', tabIndents * 2);
            string prefix      = $"{(newLine ? "\n" : "")}{indentation}";
            var    data        = StoreManagerApplication.GetData <Store>(id) as StoreData;
            // Name
            string storeName = data.Name;

            // Operating Locations
            // var operatingLocationAddressIds = data.OperatingLocationIds.ConvertAll(ol => (StoreManagerApplication.Get<OperatingLocation>(ol) as  OperatingLocationData).AddressId);
            // var addresses = operatingLocationAddressIds.ConvertAll(ola => StoreManagerApplication.Get<Address>(ola) as AddressData);
            // addresses.ForEach(ol => );
            Console.Write($"{prefix}{storeName}");
            data.OperatingLocationIds.ForEach(olid => DisplayOperatingLocation(olid, true, tabIndents + 1));
        }
        protected IData GetData <T>()
            where T : SEntity
        {
            // Get the data associated with the id
            IData result = null;

            UntilItIsDone(() => {
                // Get the id
                int id = PromptForId <T>();
                result = StoreManagerApplication.GetData <T>(id);

                return(result is not null);
            });

            return(result);
        }
        public void DisplayOperatingLocation(int id, bool newLine = false, int tabIndents = 0)
        {
            string indentation = new string(' ', tabIndents * 2);

            // Get the store and address id from the operating location's data
            (int storeId, int addressId) = new Func <Tuple <int, int> >(() => {
                var tempData = StoreManagerApplication.GetData <OperatingLocation>(id) as OperatingLocationData;
                return(new Tuple <int, int>(tempData.StoreId, tempData.AddressId));
            }).Invoke();
            // Get the name of the store
            string storeName = StoreManagerApplication.GetName <Store>(storeId);

            // Get the address as a string
            Console.Write($"{(newLine ? "\n" : "")}{indentation}{storeName} - ");
            DisplayAddress(addressId);
        }
        public void DisplayOrder(int orderId, bool newLine = false, int tabIndents = 0)
        {
            var    data         = StoreManagerApplication.GetData <Order>(orderId) as OrderData;
            string customerName = StoreManagerApplication.GetName <Customer>(data.CustomerId);
            // Get the addressId and storeId from the operating location
            int storeId = (StoreManagerApplication.GetData <OperatingLocation>(data.OperatingLocationId) as OperatingLocationData).StoreId;
            // get the store that owns the operating location
            string storeName = StoreManagerApplication.GetName <Store>(storeId);

            // Display the order id and display the Customer name
            Console.Write($"Order Details for Order#{orderId} from {storeName}:\n{new string(' ', (tabIndents + 1) * 2)}Customer: {customerName}");
            // Display the Operating Location
            DisplayOperatingLocation(data.OperatingLocationId, true, tabIndents + 1);
            // Display the products requested
            Console.Write($"{new string(' ', (tabIndents + 1) * 2)}Products Requested:");
            foreach (var kv in data.ProductsRequested)
            {
                DisplayProduct(kv.Key, kv.Value, true, tabIndents + 2);
            }
        }
        protected string[] CustomerDataToStringArray(CustomerData data)
        {
            var address = (StoreManagerApplication.GetData <Address>(data.AddressId) as AddressData).ToString();
            var items   = new List <string>
            {
                //   Name
                data.Name,
                //   Email
                data.Email,
                //   PhoneNumber
                data.PhoneNumber,
                //   AddressId -> Address
                address,
                //   BirthDate
                data.BirthDate.ToString()
            };
            var defaultStoreLocation = StoreManagerApplication.GetData <OperatingLocation>(data.DefaultStoreLocationId.Value) as OperatingLocationData;
            var dslStoreName         = StoreManagerApplication.GetName <Store>(defaultStoreLocation.StoreId);
            var dslAddress           = (StoreManagerApplication.GetData <Address>(defaultStoreLocation.AddressId) as AddressData).ToString();

            items.Add($"{dslStoreName} - {dslAddress}");

            return(items.ToArray());
        }