private string[,] BuildPricingMatrix(
            Module module, ref Dictionary<Tuple<Expertise, Priority>, decimal> hourSummary)
        {
            var values = new string[Enum.GetValues(typeof(Priority)).GetUpperBound(0) + 3, Enum.GetValues(typeof(Expertise)).GetUpperBound(0) + 2];

            values[0, 0] = string.Empty;

            int currentRow = 0;
            int currentColumn = 0;
            decimal sum;

            hourSummary = new Dictionary<Tuple<Expertise, Priority>, decimal>();

            foreach (Expertise expertise in Enum.GetValues(typeof(Expertise)))
            {
                foreach (Priority priorty in Enum.GetValues(typeof(Priority)))
                {
                    var tuple = new Tuple<Expertise, Priority>(expertise, priorty);

                    hourSummary.Add(tuple, 0);

                    if (currentColumn == 0)
                    {
                        values[currentRow + 1, 0] = priorty.ToString() + " (" + this.GetModifier(priorty) + ")";
                    }

                    if (currentRow == 0)
                    {
                        values[0, currentColumn + 1] = expertise.ToString() + " @" + this.GetRate(expertise).ToString("C");
                    }

                    var hours = module.GetHours(priorty, expertise);
                    var rate = this.GetRate(expertise) * this.GetModifier(priorty);

                    hourSummary[tuple] += hours;

                    if (hours > 0)
                    {
                        values[currentRow + 1, currentColumn + 1] = hours.ToString("F") + " @" + rate.ToString("C");
                    }

                    currentRow++;
                }

                values[currentRow + 1, 0] = "Totals";

                decimal hrs = 0;
                decimal money = 0;
                foreach (var x in hourSummary)
                {
                    if (x.Key.Item1 == expertise)
                    {
                        hrs += x.Value;
                        money += x.Value * this.GetRate(x.Key.Item1) * this.GetModifier(x.Key.Item2);
                    }
                }

                values[currentRow + 1, currentColumn + 1] = hrs > 0
                                                                ? hrs.ToString("F") + " (" + money.ToString("C")
                                                                  + ")"
                                                                : string.Empty;

                currentColumn++;
                currentRow = 0;
            }

            return values;
        }
        private void FormatTitle(Body body, Module module)
        {
            var para = body.AppendChild(new Paragraph().ApplyStyle(StyleDefinitions.Heading1.Id));

            var run = para.AppendChild(new Run());

            run.AppendChild(new Text(module.Name));
        }
        public string[,] CalculateSummaryValues(Dictionary<Tuple<Expertise, Priority>, decimal> summary, Module module)
        {
            var values = new string[2, 4];
            decimal totalCost = 0;
            foreach (KeyValuePair<Tuple<Expertise, Priority>, decimal> value in summary)
            {
                totalCost += value.Value * this.GetRate(value.Key.Item1) * this.GetModifier(value.Key.Item2);
            }

            values[0, 0] = "Hourly Labor";
            values[0, 1] = "License Discount";
            values[0, 2] = "License (Monthly)";
            values[0, 3] = "Total";

            values[1, 0] = totalCost.ToString("C");
            values[1, 1] = 0.ToString("C");
            values[1, 2] = 0.ToString("C");
            values[1, 3] = totalCost.ToString("C");

            return values;
        }