public static ColPerfBillPerformance New(BillCode billCode, IEnumerable <CollectorPerfCell> cells)
        {
            var bp = new ColPerfBillPerformance(billCode);

            bp.Target   = cells.Sum(_ => _.Target);
            bp.Actual   = cells.Sum(_ => _.Actual);
            bp.NoExcess = cells.Sum(_ => _.NoExcess);
            if (bp.Target != 0)
            {
                bp.PerfRate = bp.NoExcess / bp.Target;
            }

            bp.UnderpaidCount = cells.Count(_ => _.IsShort);
            bp.UnderpaidTotal = cells.Sum(_ => _.Shortage);

            bp.OverpaidCount = cells.Count(_ => _.IsOver);
            bp.OverpaidTotal = cells.Sum(_ => _.Overage);

            return(bp);
        }
        public static CollectorPerformanceRow New(CollectorDTO collector, IStallsRepo fallbackStallsRepo, ICollectionsDB db, IMarketStateDB mkt)
        {
            var cp       = new CollectorPerformanceRow(collector);
            var sections = db.SectionsSnapshot ?? mkt.Sections.GetAll();

            foreach (var sec in sections)
            {
                cp.AddSubRows(collector, sec, db, fallbackStallsRepo);
            }

            cp.Sections = cp.DistinctBy(_ => _.Section.Id)
                          .Select(_ => _.Section)
                          .ToList();

            cp.StallCoverage = ColPerfStallCoverage.New(cp, db);
            cp.RentBill      = ColPerfBillPerformance.New(BillCode.Rent, cp.Select(_ => _.Rent));
            cp.RightsBill    = ColPerfBillPerformance.New(BillCode.Rights, cp.Select(_ => _.Rights));

            cp.SetSummary(new CollectorPerfSubRowsTotal(cp));

            return(cp);
        }