private int CalculateNumberOfBoxes(PalletModel palletModel, ConfigurationModel output, int boxesPerLayer, out int maxVolume, out int boxVolume)
        {
            maxVolume = output.PalletSize.X * output.PalletSize.Z * (palletModel.PalletHeight - output.PalletSize.Y);
            boxVolume = palletModel.BoxSizeX * palletModel.BoxSizeY * palletModel.BoxSizeZ;

            return(boxesPerLayer * output.LayersQuantity);
        }
 public void Start()
 {
     Configurations     = new List <ConfigurationModel>();
     PalletData         = new PalletModel();
     configurationModel = new ConfigurationModel();
     EventCommand       = "start";
 }
        /// <summary>
        /// Calculates quantity of layers on pallet
        /// </summary>
        /// <param name="palletModel">PalletModel from form</param>
        /// <param name="palletSizeY">Height of pallet</param>
        /// <param name="boxesPerLayer">Quantity of all boxes per pallet</param>
        /// <returns>Integer value of layers on pallet</returns>
        private int CalculateLayersQuantity(PalletModel palletModel, int palletSizeY, int boxesPerLayer)
        {
            double weightPerLayer          = boxesPerLayer * palletModel.BoxWeight;
            int    maxWeightLayersQuantity = Convert.ToInt32(Math.Floor(palletModel.PalletWeight / weightPerLayer));
            int    maxHeightLayersQuantity = Convert.ToInt32(Math.Floor(Convert.ToDouble(palletModel.PalletHeight - palletSizeY) / palletModel.BoxSizeY));

            return(Math.Min(maxHeightLayersQuantity, maxWeightLayersQuantity));
        }
        public List <ConfigurationModel> CalculatePalletConfiguration(PalletModel palletModel)
        {
            var output = new List <ConfigurationModel>();

            foreach (var option in StackingOptionModel.GenerateListOfStackingOptions())
            {
                output.Add(CalculateOption(palletModel, option));
            }

            return(output);
        }
        /// <summary>
        /// Takes Pallet size from form (model) and return in CoordinatesModel format
        /// </summary>
        /// <param name="_palletModel">PalletModel from form</param>
        /// <returns>Pallet Size as CoordinatesModel</returns>
        private CoordinatesModel GetPalletSize(PalletModel _palletModel)
        {
            var output = new CoordinatesModel
            {
                X = _palletModel.PalletSizeX,
                Y = _palletModel.PalletSizeY,
                Z = _palletModel.PalletSizeZ
            };

            return(output);
        }
        /// <summary>
        /// Takes Box size from form (model) and return in CoordinatesModel format
        /// </summary>
        /// <param name="palletModel">PalletModel from form</param>
        /// <returns>Box Size as CoordinatesModel</returns>
        private CoordinatesModel GetBoxSize(PalletModel palletModel)
        {
            var output = new CoordinatesModel
            {
                X = palletModel.BoxSizeX,
                Y = palletModel.BoxSizeY,
                Z = palletModel.BoxSizeZ
            };

            return(output);
        }
        private void IsModelValid(PalletModel palletModel)
        {
            var context = new ValidationContext(palletModel, serviceProvider: null, items: null);
            var results = new List <ValidationResult>();

            var isValid = Validator.TryValidateObject(palletModel, context, results, true);

            if (!isValid)
            {
                throw new ValidationException();
            }
        }
        public ConfigurationModel CalculateOption(PalletModel palletModel, StackingOptionModel stackingOption)
        {
            // PalletModel validation
            IsModelValid(palletModel);

            var output = new ConfigurationModel();

            // GetBoxSize
            output.BoxSize = GetBoxSize(palletModel);
            // GetPalletSize
            output.PalletSize = GetPalletSize(palletModel);
            // Option Name
            output.OptionName = stackingOption.Name;
            // Calculate max possible rows and collumns
            var maxRows    = output.PalletSize.X / palletModel.BoxSizeX;
            var maxColumns = output.PalletSize.Z / palletModel.BoxSizeZ;
            // Calculate Standard Layer
            var standardPalletZ = CalculateStandardPalletZ(stackingOption.Rotation, maxColumns, palletModel.BoxSizeZ, stackingOption.Mode);

            output.Standard = CalculateLayer(output.PalletSize.X, palletModel.BoxSizeX, standardPalletZ, palletModel.BoxSizeZ);
            // Calculate Rotated Layer
            var rotatedPalletZ = output.PalletSize.Z - standardPalletZ;

            output.Rotated = CalculateLayer(output.PalletSize.X, palletModel.BoxSizeZ, rotatedPalletZ, palletModel.BoxSizeX);
            // Calculate boxes per layer
            int boxesPerLayer = (output.Standard.RowsPerLayer * output.Standard.ColumnsPerLayer)
                                + (output.Rotated.RowsPerLayer * output.Rotated.ColumnsPerLayer);

            // Calculate Layers Quantity
            output.LayersQuantity = CalculateLayersQuantity(palletModel, output.PalletSize.Y, boxesPerLayer);
            // Calculate total number of boxes
            int maxVolume, boxVolume;

            output.NumberOfBoxes = CalculateNumberOfBoxes(palletModel, output, boxesPerLayer, out maxVolume, out boxVolume);
            int actualVolume = output.NumberOfBoxes * boxVolume;

            // Calculate Volume
            output.Volume = Convert.ToDouble(actualVolume) / Convert.ToDouble(maxVolume);
            // Calculate total Weight and Height
            output.TotalHeight = output.PalletSize.Y + (palletModel.BoxSizeY * output.LayersQuantity);
            output.TotalWeight = output.NumberOfBoxes * palletModel.BoxWeight;

            return(output);
        }
        /// <summary>
        /// Responsible for managing events in application, switch between different actions.
        /// </summary>
        public void EventHandler()
        {
            switch (EventCommand.ToLower())
            {
            case "start":
                Start();
                break;

            case "confirm":
                GenerateConfigurations();
                break;

            case "reset":
                PalletData         = new PalletModel();
                configurationModel = new ConfigurationModel();
                break;

            default:
                break;
            }
        }