diff options
author | Matthew Lemon <lemon@matthewlemon.com> | 2020-12-06 17:03:59 +0000 |
---|---|---|
committer | Matthew Lemon <lemon@matthewlemon.com> | 2020-12-06 17:03:59 +0000 |
commit | 4c6a364551196833aef9d4ad74ec29510f5068ae (patch) | |
tree | ed30bf98c6159a87fa51616aa4cca1431802b2a1 | |
parent | c4e2c664a5f7488ab11e4433aeb9efcffc33a871 (diff) |
ridded of extranneous pkg directory
-rw-r--r-- | .gitignore | 1 | ||||
-rw-r--r-- | Makefile | 8 | ||||
-rw-r--r-- | cmd/datamaps/main.go | 2 | ||||
-rw-r--r-- | pkg/datamaps/config.go | 267 | ||||
-rw-r--r-- | pkg/datamaps/config_test.go | 35 | ||||
-rw-r--r-- | pkg/datamaps/db.go | 267 | ||||
-rw-r--r-- | pkg/datamaps/db_test.go | 235 | ||||
-rw-r--r-- | pkg/datamaps/reader.go | 293 | ||||
-rw-r--r-- | pkg/datamaps/reader_test.go | 251 | ||||
-rw-r--r-- | pkg/datamaps/testdata/datamap.csv | 1948 | ||||
-rw-r--r-- | pkg/datamaps/testdata/datamap_for_master_test.csv | 19 | ||||
-rw-r--r-- | pkg/datamaps/testdata/datamap_matches_test_template.csv | 10 | ||||
-rw-r--r-- | pkg/datamaps/testdata/test_template.xlsm | bin | 9390 -> 0 bytes | |||
-rw-r--r-- | pkg/datamaps/testdata/test_template.xlsx | bin | 9389 -> 0 bytes | |||
-rw-r--r-- | pkg/datamaps/testdata/test_template2.xlsx | bin | 9395 -> 0 bytes | |||
-rw-r--r-- | pkg/datamaps/testdata/test_template3.xlsx | bin | 9459 -> 0 bytes | |||
-rw-r--r-- | pkg/datamaps/writer.go | 153 | ||||
-rw-r--r-- | pkg/datamaps/writer_test.go | 195 |
18 files changed, 6 insertions, 3678 deletions
@@ -6,3 +6,4 @@ go.sum pkg/datamaps/testdata/test.db /main /bin/datamaps +build/ @@ -1,14 +1,14 @@ debug-datamaps: - dlv test ./pkg/datamaps/ --wd ./pkg/datamaps/ + dlv test ./datamaps/ --wd .`/datamaps/ dummy-import: - ./datamaps import --returnname "Hunkers" --datamapname "Tonk 1" --xlsxpath pkg/datamaps/testdata/ + ./build/datamaps import --returnname "Hunkers" --datamapname "Tonk 1" --xlsxpath datamaps/testdata/ dummy-datamap-import: - ./datamaps datamap --datamapname "Tonk 1" --import pkg/datamaps/testdata/datamap_matches_test_template.csv + ./build/datamaps datamap --datamapname "Tonk 1" --import datamaps/testdata/datamap_matches_test_template.csv build: - go build -o datamaps ./cmd/datamaps/main.go + go build -o build/datamaps ./cmd/datamaps/main.go test-all: go test ./... diff --git a/cmd/datamaps/main.go b/cmd/datamaps/main.go index 66f78a0..e9e34f6 100644 --- a/cmd/datamaps/main.go +++ b/cmd/datamaps/main.go @@ -8,7 +8,7 @@ import ( "net/http" "os" - "github.com/yulqen/datamaps-go/pkg/datamaps" + "github.com/yulqen/datamaps-go/datamaps" ) func main() { diff --git a/pkg/datamaps/config.go b/pkg/datamaps/config.go deleted file mode 100644 index ec6f91e..0000000 --- a/pkg/datamaps/config.go +++ /dev/null @@ -1,267 +0,0 @@ -package datamaps - -import ( - "log" - "os" - "path/filepath" -) - -const ( - configDirName = "datamaps" - dbName = "datamaps.db" -) - -// Help text. -const Usage = ` -usage: datamaps COMMAND [OPTIONS] - --Managing datamap files- - -Command: datamap - -All datamap related actions. Before datamaps can do much, it must know about a datamap. -A datamap starts life as a CSV file with the format: - -cell_key,template_sheet,cell_reference,type -key1,sheet1,A10,TEXT -key2,sheet1,A11,NUMBER -... - -Options: - --import PATH Import a datamap the csv datamap at PATH - --datamapname NAME Name for imported datamap -` - -// mocking funcs in go https://stackoverflow.com/questions/19167970/mock-functions-in-go -// we only need the func signature to create the type. This is pretty weird, we're want to mock -// os.UserHomeDir so that we can set it to something like /tmp in our tests. Here we are creating -// two types: getUserConfigDir to represent the os.UserConfigDir function, dbPathChecker as a wrapper -// which which we can assign methods to that holds the value of the func os.UserConfigDir and the -// method, check(), which does the work, using the passed in func to determine the user $HOME/.config -// directory. -// Which is a lot of work for what it is, but it does make this testable and serves as an example -// of how things could be done in Go. - -// getUserConfigDir allows replaces os.UserConfigDir -// for testing purposes. -type getUserConfigDir func() (string, error) - -// DBPathChecker contains the func used to create the user config dir. -type DBPathChecker struct { - userConfig getUserConfigDir -} - -// NewDBPathChecker creates a DBPathChecker using whatever -// func you want as the argument, as long as it matches the -// type os.UserConfigDir. This makes it convenient for testing -// and was done as an experiment here to practice mocking in Go. -func NewDBPathChecker(h getUserConfigDir) *DBPathChecker { - return &DBPathChecker{userConfig: h} -} - -// Check returns true if the necessary config files (including -// the database) are in place - false if not -func (db *DBPathChecker) Check() bool { - userConfig, err := db.userConfig() - if err != nil { - log.Fatal(err) - } - dbPath := filepath.Join(userConfig, "datamaps.db") - if _, err := os.Stat(dbPath); os.IsNotExist(err) { - return false - } - return true -} - -// SetUp creates the config directory and requisite files -func SetUp() (string, error) { - dir, err := os.UserConfigDir() - if err != nil { - return "", err - } - // check if config folder exists - configPath := filepath.Join(dir, configDirName) - dbPath := filepath.Join(configPath, dbName) - if _, err := os.Stat(configPath); os.IsNotExist(err) { - log.Println("Config directory does not exist.") - log.Printf("Creating config directory %s.\n", configPath) - if err := os.Mkdir(filepath.Join(dir, "datamaps"), 0700); err != nil { - return "", err - } - } else { - log.Println("Config directory found.") - } - if _, err := os.Stat(dbPath); os.IsNotExist(err) { - log.Println("Database does not exist.") - _, err = os.Create(dbPath) - if err != nil { - return "", err - } - log.Printf("Creating database file at %s.\n", dbPath) - _, err := setupDB(dbPath) - if err != nil { - return "", err - } - } else { - log.Println("Database file found.") - } - return dir, nil -} - -func userConfigDir() (string, error) { - dir, err := os.UserConfigDir() - if err != nil { - return "", err - } - - configPath := filepath.Join(dir, configDirName) - - return configPath, nil -} - -func defaultDMPath() (string, error) { - dir, err := os.UserHomeDir() - if err != nil { - return "", err - } - - return filepath.Join(dir, "Documents", "datamaps"), nil -} - -func defaultXLSXPath() (string, error) { - dir, err := os.UserHomeDir() - if err != nil { - return "", err - } - - return filepath.Join(dir, "Documents", "datamaps", "import"), nil -} - -// Options for the whole CLI application. -type Options struct { - // Command is the main CLI sub-command (e.g. "datamap" handles all datamap - // operations and the flags that follow pertain only to that operation. - Command string - - // DBPath is the path to the database file. - DBPath string - - // DMPath is the path to a datamap file. - DMPath string - - // DMNane is the name of a datamap, whether setting or querying. - DMName string - - // XLSXPath is the path to a directory containing ".xlsx" files for - // importing. - XLSXPath string - - // ReturnName is the name of a Return, whether setting or querying. - ReturnName string - - // DMOverwrite is currently not used. - DMOverwrite bool - - // DMInitial is currently not used. - DMInitial bool - - // MasterOutPutPath is where the master.xlsx file is to be saved - MasterOutPutPath string -} - -func defaultOptions() *Options { - dbpath, err := userConfigDir() - if err != nil { - log.Fatalf("Unable to get user config directory %v", err) - } - - dmPath, err := defaultDMPath() - if err != nil { - log.Fatalf("unable to get default datamaps directory path: %v", err) - } - - xlsxPath, err := defaultXLSXPath() - if err != nil { - log.Fatalf("unable to get default XLSX directory path: %v", err) - } - - homeDir, err := os.UserHomeDir() - if err != nil { - log.Fatal("unable to get user home directory") - } - - return &Options{ - Command: "help", - DBPath: filepath.Join(dbpath, dbName), - DMPath: dmPath, - DMName: "Unnamed Datamap", - XLSXPath: xlsxPath, - ReturnName: "Unnamed Return", - DMOverwrite: false, - DMInitial: false, - MasterOutPutPath: filepath.Join(homeDir, "Desktop"), - } -} - -// nextString get the next string in a slice. -func nextString(args []string, i *int, message string) string { - if len(args) > *i+1 { - *i++ - } else { - log.Fatal(message) - } - - return args[*i] -} - -func processOptions(opts *Options, allArgs []string) { - if len(allArgs) == 0 { - allArgs = append(allArgs, "help") - } - switch allArgs[0] { - case "import": - opts.Command = "import" - case "help": - opts.Command = "help" - case "datamap": - opts.Command = "datamap" - case "setup": - opts.Command = "setup" - case "server": - opts.Command = "server" - case "createmaster": - opts.Command = "createmaster" - default: - log.Fatal("No relevant command provided.") - } - - restArgs := allArgs[1:] - - for i := 0; i < len(allArgs[1:]); i++ { - arg := restArgs[i] - switch arg { - case "--xlsxpath": - opts.XLSXPath = nextString(restArgs, &i, "xlsx directory path required") - case "--returnname": - opts.ReturnName = nextString(restArgs, &i, "return name required") - case "--import": - opts.DMPath = nextString(restArgs, &i, "import path required") - case "--datamapname": - opts.DMName = nextString(restArgs, &i, "datamap name required") - case "--overwrite": - opts.DMOverwrite = true - case "--initial": - opts.DMInitial = true - case "--masteroutputdir": - opts.MasterOutPutPath = nextString(restArgs, &i, "master output directory required") - } - } -} - -//ParseOptions for CLI. -func ParseOptions() *Options { - opts := defaultOptions() - processOptions(opts, os.Args[1:]) - - return opts -} diff --git a/pkg/datamaps/config_test.go b/pkg/datamaps/config_test.go deleted file mode 100644 index dadaf6d..0000000 --- a/pkg/datamaps/config_test.go +++ /dev/null @@ -1,35 +0,0 @@ -package datamaps - -import ( - "os" - "path/filepath" - "testing" -) - -// mocking funcs in go https://stackoverflow.com/questions/19167970/mock-functions-in-go - -func mockConfigDir() (string, error) { - return "/tmp/CONFIG/datamaps/", nil -} - -func TestDBDetect(t *testing.T) { - - cPath := filepath.Join("/tmp", "CONFIG", "datamaps") - t.Logf("%s\n", cPath) - if err := os.MkdirAll(cPath, 0700); err != nil { - t.Fatalf("cannot create temporary directory - %v", err) - } - - if _, err := os.Create(filepath.Join("/tmp", "CONFIG", "datamaps", "datamaps.db")); err != nil { - t.Fatalf("cannot open '/tmp/CONFIG/datamaps/databamps.db': %v", err) - } - defer func() { - os.RemoveAll(filepath.Join("/tmp", "CONFIG")) - }() - - dbpc := NewDBPathChecker(mockConfigDir) - h := dbpc.Check() - if !h { - t.Error("the db file should be found but isn't") - } -} diff --git a/pkg/datamaps/db.go b/pkg/datamaps/db.go deleted file mode 100644 index 296b1b2..0000000 --- a/pkg/datamaps/db.go +++ /dev/null @@ -1,267 +0,0 @@ -package datamaps - -import ( - "database/sql" - "errors" - "fmt" - "log" - "os" - "path" - "time" - - // Needed for the sqlite3 driver - _ "github.com/mattn/go-sqlite3" -) - -// setupDB creates the intitial database -func setupDB(path string) (*sql.DB, error) { - stmtBase := `DROP TABLE IF EXISTS datamap; - DROP TABLE IF EXISTS datamap_line; - DROP TABLE IF EXISTS return; - DROP TABLE IF EXISTS return_data; - - CREATE TABLE datamap( - id INTEGER PRIMARY KEY, - name TEXT, - date_created TEXT); - - CREATE TABLE datamap_line( - id INTEGER PRIMARY KEY, - dm_id INTEGER, - key TEXT NOT NULL, - sheet TEXT NOT NULL, - cellref TEXT, - FOREIGN KEY (dm_id) - REFERENCES datamap(id) - ON DELETE CASCADE - ); - - CREATE TABLE return( - id INTEGER PRIMARY KEY, - name TEXT, - date_created TEXT - ); - - CREATE TABLE return_data( - id INTEGER PRIMARY KEY, - dml_id INTEGER, - ret_id INTEGER, - filename TEXT, - value TEXT, - numfmt TEXT, - vFormatted TEXT, - FOREIGN KEY (dml_id) - REFERENCES datamap_line(id) - ON DELETE CASCADE - FOREIGN KEY (ret_id) - REFERENCES return(id) - ON DELETE CASCADE - ); - ` - if _, err := os.Create(path); err != nil { - return nil, err - } - db, err := sql.Open("sqlite3", path) - if err != nil { - return db, errors.New("Cannot open that damn database file") - } - - // We probably don't need pragma here but we have it for later. - pragma := "PRAGMA foreign_keys = ON;" - _, err = db.Exec(pragma) - if err != nil { - // log.Printf("%q: %s\n", err, pragma) - return nil, err - } - - _, err = db.Exec(stmtBase) - if err != nil { - // log.Printf("%q: %s\n", err, stmt_base) - return nil, err - } - - return db, nil -} - -// ImportToDB imports a directory of xlsx files to the database, using the datamap -// to filter the data. -func ImportToDB(opts *Options) error { - log.Printf("Importing files in %s as return named %s using datamap named %s.", opts.XLSXPath, opts.ReturnName, opts.DMName) - - target, err := getTargetFiles(opts.XLSXPath) - if err != nil { - return err - } - - db, err := sql.Open("sqlite3", opts.DBPath) - if err != nil { - return err - } - - for _, vv := range target { - // TODO: Do the work! - - if err := importXLSXtoDB(opts.DMName, opts.ReturnName, vv, db); err != nil { - return err - } - } - return nil -} - -// DatamapToDB takes a slice of datamapLine and writes it to a sqlite3 db file. -func DatamapToDB(opts *Options) error { - log.Printf("Importing datamap file %s and naming it %s.\n", opts.DMPath, opts.DMName) - - data, err := ReadDML(opts.DMPath) - if err != nil { - log.Fatal(err) - } - - d, err := sql.Open("sqlite3", opts.DBPath) - if err != nil { - return errors.New("Cannot open that damn database file") - } - - tx, err := d.Begin() - if err != nil { - return err - } - - pragma := "PRAGMA foreign_keys = ON;" - _, err = d.Exec(pragma) - if err != nil { - log.Printf("%q: %s\n", err, pragma) - return err - } - - stmtDm, err := tx.Prepare("INSERT INTO datamap (name, date_created) VALUES(?,?)") - if err != nil { - return err - } - - res, err := stmtDm.Exec(opts.DMName, time.Now()) - if err != nil { - return err - } - - lastID, err := res.LastInsertId() - if err != nil { - return err - } - - stmtDml, err := tx.Prepare("INSERT INTO datamap_line (dm_id, key, sheet, cellref) VALUES(?,?,?,?);") - if err != nil { - return err - } - - defer stmtDm.Close() - defer stmtDml.Close() - - for _, dml := range data { - _, err = stmtDml.Exec(lastID, dml.Key, dml.Sheet, dml.Cellref) - if err != nil { - return err - } - } - err = tx.Commit() - if err != nil { - return err - } - - return nil -} - -func importXLSXtoDB(dmName string, returnName string, file string, db *sql.DB) error { - // d, err := ExtractDBDatamap(dmName, file, db) - _, filename := path.Split(file) - d, err := ExtractDBDatamap(dmName, file, db) - if err != nil { - return err - } - log.Printf("Extracting from %s.\n", file) - - // If there is already a return with a matching name, use that. - rtnQuery, err := db.Prepare("select id from return where (return.name=?)") - if err != nil { - fmt.Errorf("cannot create a query to get the return - %v", err) - } - defer rtnQuery.Close() - - var retID int64 - err = rtnQuery.QueryRow(returnName).Scan(&retID) - if err != nil { - log.Printf("Couldn't find an existing return named '%s' so let's create it.\n", returnName) - } - - if retID == 0 { - stmtReturn, err := db.Prepare("insert into return(name, date_created) values(?,?)") - if err != nil { - fmt.Errorf("cannot prepare a statement to create a new return - %v", err) - } - defer stmtReturn.Close() - - res, err := stmtReturn.Exec(returnName, time.Now()) - if err != nil { - err := fmt.Errorf("%v\nCannot create %s", err, returnName) - log.Println(err.Error()) - os.Exit(1) - } - - retID, err = res.LastInsertId() - if err != nil { - fmt.Errorf("cannot get id of return - %v", err) - } - } - - // We're going to need a transaction for the big stuff - tx, err := db.Begin() - if err != nil { - fmt.Errorf("cannot start a database transaction - %v", err) - } - - for sheetName, sheetData := range d { - - for cellRef, cellData := range sheetData { - - dmlQuery, err := db.Prepare("select id from datamap_line where (sheet=? and cellref=?)") - if err != nil { - fmt.Errorf("cannot prepare a statement to get the datamap line - %v", err) - } - defer dmlQuery.Close() - dmlIDRow := dmlQuery.QueryRow(sheetName, cellRef) - - var dmlID *int - - if err := dmlIDRow.Scan(&dmlID); err != nil { - err := fmt.Errorf("cannot find a datamap_line row for %s and %s: %s", sheetName, cellRef, err) - log.Println(err.Error()) - } - - insertStmt, err := db.Prepare("insert into return_data (dml_id, ret_id, filename, value, numfmt, vFormatted) values(?,?,?,?,?,?)") - if err != nil { - fmt.Errorf("cannot insert row into return_data - %v", err) - } - defer insertStmt.Close() - - // Hack to fix bug in Libreoffice numformats for dates - if cellData.NumFmt == "DD/MM/YY" { - cellData.SetFormat("dd/mm/yy") - } - fValue, err := cellData.FormattedValue() - if err != nil { - fmt.Errorf("cannot get the formatted value for %#v, %v", cellData, err) - } - - _, err = insertStmt.Exec(dmlID, retID, filename, cellData.Value, cellData.NumFmt, fValue) - if err != nil { - fmt.Errorf("cannot execute statement to insert return data - %v", err) - } - } - } - - err = tx.Commit() - if err != nil { - return err - } - return nil -} diff --git a/pkg/datamaps/db_test.go b/pkg/datamaps/db_test.go deleted file mode 100644 index 87801a0..0000000 --- a/pkg/datamaps/db_test.go +++ /dev/null @@ -1,235 +0,0 @@ -package datamaps - -import ( - "database/sql" - "fmt" - "os" - "os/exec" - "strings" - "testing" -) - -var singleTarget string = "./testdata/test_template.xlsm" - -var opts = Options{ - DBPath: "./testdata/test.db", - DMName: "First Datamap", - DMPath: "./testdata/datamap_matches_test_template.csv", - XLSXPath: "./testdata/", -} - -func dbSetup() (*sql.DB, error) { - db, err := setupDB("./testdata/test.db") - if err != nil { - return nil, err - } - return db, nil -} - -func dbTeardown(db *sql.DB) { - db.Close() - os.Remove("./testdata/test.db") -} - -func TestOpenSQLiteFile(t *testing.T) { - - db, err := dbSetup() - if err != nil { - t.Fatal(err) - } - defer dbTeardown(db) - - stmt := `insert into datamap(id, name) values(1,'cock')` - _, err = db.Exec(stmt) - - if err != nil { - t.Errorf("Cannot add record to db") - } - - rows, err := db.Query("select name from datamap") - - if err != nil { - t.Errorf("Cannot run select statement") - } - - defer rows.Close() - - for rows.Next() { - var name string - err = rows.Scan(&name) - if err != nil { - t.Errorf("Cannot scan resulting row") - } - } -} - -func TestDatamapGoesIntoDB(t *testing.T) { - db, err := dbSetup() - if err != nil { - t.Fatal(err) - } - defer dbTeardown(db) - - if err := DatamapToDB(&opts); err != nil { - t.Errorf("unable to write datamap to database file because %v", err) - } -} - -// TestImportSimpleTemplate uses importXLSXtoDB() to import data from a -// populated template and then uses the sqlite3 executible to test the -// contents of the database. This does not test datamaps functionality -// in querying data in the database. -func TestImportSimpleTemplate(t *testing.T) { - - var tests = []struct { - sheet string - cellref string - value string - }{ - {"Introduction", "A1", "10"}, - {"Introduction", "C9", "Test Department"}, - {"Introduction", "C22", "VUNT"}, - {"Introduction", "J9", "Greedy Parrots"}, - {"Summary", "B3", "This is a string"}, - {"Summary", "B4", "2.2"}, - {"Another Sheet", "N34", "23"}, - {"Another Sheet", "DI15", "Rabbit Helga"}, - } - - db, err := dbSetup() - if err != nil { - t.Fatal(err) - } - defer dbTeardown(db) - - // We need a datamap in there. - if err := DatamapToDB(&opts); err != nil { - t.Fatalf("cannot open %s", opts.DMPath) - } - if err := importXLSXtoDB(opts.DMName, "TEST RETURN", singleTarget, db); err != nil { - t.Fatalf("Something wrong: %v", err) - } - - for _, test := range tests { - sql := fmt.Sprintf(`SELECT return_data.value FROM return_data, datamap_line - WHERE - (return_data.filename='test_template.xlsm' - AND datamap_line.cellref=%q - AND datamap_line.sheet=%q - AND return_data.dml_id=datamap_line.id);`, test.cellref, test.sheet) - - got, err := exec.Command("sqlite3", opts.DBPath, sql).Output() - if err != nil { - t.Fatalf("something wrong %v", err) - } - got_s := strings.TrimSuffix(string(got), "\n") - if strings.Compare(got_s, test.value) != 0 { - t.Errorf("we wanted %s in test_template.xlsm but got %s", test.value, got_s) - } - } -} - -// TestImportToDB uses ImportToDB() to import data from a -// directory of populated templates and then uses the sqlite3 executible to test the -// contents of the database. This does not test datamaps functionality -// in querying data in the database. -func TestImportToDB(t *testing.T) { - var tests = []struct { - filename string - sheet string - cellref string - value string - }{ - {"test_template.xlsm", "Introduction", "A1", "10"}, - {"test_template.xlsm", "Introduction", "C9", "Test Department"}, - {"test_template.xlsm", "Introduction", "C22", "VUNT"}, - {"test_template.xlsm", "Introduction", "J9", "Greedy Parrots"}, - {"test_template.xlsm", "Summary", "B3", "This is a string"}, - {"test_template.xlsm", "Summary", "B4", "2.2"}, - {"test_template.xlsm", "Another Sheet", "N34", "23"}, - {"test_template.xlsm", "Another Sheet", "DI15", "Rabbit Helga"}, - - {"test_template.xlsx", "Introduction", "A1", "10"}, - {"test_template.xlsx", "Introduction", "C9", "Test Department"}, - {"test_template.xlsx", "Introduction", "C22", "VUNT"}, - {"test_template.xlsx", "Introduction", "J9", "Greedy Parrots"}, - {"test_template.xlsx", "Summary", "B3", "This is a string"}, - {"test_template.xlsx", "Summary", "B4", "2.2"}, - {"test_template.xlsx", "Another Sheet", "N34", "23"}, - {"test_template.xlsx", "Another Sheet", "DI15", "Rabbit Helga"}, - - {"test_template2.xlsx", "Introduction", "A1", "10"}, - {"test_template2.xlsx", "Introduction", "C9", "Test Department"}, - {"test_template2.xlsx", "Introduction", "C22", "VUNT"}, - {"test_template2.xlsx", "Introduction", "J9", "Greedy Parrots"}, - {"test_template2.xlsx", "Summary", "B3", "This is a string"}, - {"test_template2.xlsx", "Summary", "B4", "2.2"}, - {"test_template2.xlsx", "Another Sheet", "N34", "23"}, - {"test_template2.xlsx", "Another Sheet", "DI15", "Rabbit Helga"}, - - {"test_template3.xlsx", "Introduction", "A1", "10"}, - {"test_template3.xlsx", "Introduction", "C9", "Test Department"}, - {"test_template3.xlsx", "Introduction", "C22", "VUNT"}, - {"test_template3.xlsx", "Introduction", "J9", "Greedy Parrots"}, - {"test_template3.xlsx", "Summary", "B3", "This is a string"}, - {"test_template3.xlsx", "Summary", "B4", "2.2"}, - {"test_template3.xlsx", "Another Sheet", "N34", "23"}, - {"test_template3.xlsx", "Another Sheet", "DI15", - "Printers run amok in the land of carnivores when bacchus rings 1009.ff faiioif !!!]=-=-1290909"}, - } - - db, err := dbSetup() - if err != nil { - t.Fatal(err) - } - - // We need a datamap in there. - if err := DatamapToDB(&opts); err != nil { - t.Fatalf("cannot open %s", opts.DMPath) - } - defer dbTeardown(db) - - if err := ImportToDB(&opts); err != nil { - t.Fatal(err) - } - - for _, test := range tests { - sql := fmt.Sprintf(`SELECT return_data.value FROM return_data, datamap_line - WHERE - (return_data.filename=%q - AND datamap_line.cellref=%q - AND datamap_line.sheet=%q - AND return_data.dml_id=datamap_line.id);`, test.filename, test.cellref, test.sheet) - - got, err := exec.Command("sqlite3", opts.DBPath, sql).Output() - if err != nil { - t.Fatalf("something wrong %v", err) - } - got_s := strings.TrimSuffix(string(got), "\n") - if strings.Compare(got_s, test.value) != 0 { - t.Errorf("we wanted value %q in file %s sheet %s %s but got %s", - test.value, test.filename, test.sheet, test.cellref, got_s) - } - } -} - -// TODO: - -// USING THE INDEX TO tests STRUCT WE COULD DO ALL THESE IN TEST ABOVE - -// Returns useful error messages when querying for stuff not in datamap -// func TestImportSimpleQueryValueNotInDatamap(t *testing.T) { -// var tests = []struct { -// sheet string -// cellref string -// value string -// }{ -// {"Summary", "B2", "20/10/19"}, // this is not referenced in datamap -// } -// } - -// TODO: -// When a date is returned from the spreadsheet it is an integer and needs -// to be handled appropriately. -// func TestValuesReturnedAsDates(t *testing.T) { -// } diff --git a/pkg/datamaps/reader.go b/pkg/datamaps/reader.go deleted file mode 100644 index 25e6c99..0000000 --- a/pkg/datamaps/reader.go +++ /dev/null @@ -1,293 +0,0 @@ -/* datmamaps packages handles datamap files and populated spreadsheets. - */ - -package datamaps - -import ( - "database/sql" - "encoding/csv" - "errors" - "fmt" - "io" - "io/ioutil" - "log" - "path/filepath" - "strings" - - // Required for the sqlite3 driver - _ "github.com/mattn/go-sqlite3" - - "github.com/tealeg/xlsx/v3" -) - -type ( - // sheetData is the data from the sheet. - sheetData map[string]extractedCell - - // FileData is the data from the file. - FileData map[string]sheetData - - // ExtractedData is the Extracted data from the file, filtered by a Datamap. - ExtractedData map[string]map[string]xlsx.Cell -) - -//datamapLine - a line from the datamap. -type datamapLine struct { - Key string - Sheet string - Cellref string -} - -//extractedCell is data pulled from a cell. -type extractedCell struct { - Cell *xlsx.Cell - Col string - Row int - Value string -} - -var ( - inner = make(sheetData) -) - -// ExtractedDatamapFile is a slice of datamapLine structs, each of which encodes a single line -// in the datamap file/database table. -type ExtractedDatamapFile []datamapLine - -//sheetInSlice is a helper which returns true -// if a string is in a slice of strings. -func sheetInSlice(list []string, key string) bool { - for _, x := range list { - if x == key { - return true - } - } - - return false -} - -//getSheetNames returns the number of Sheet field entries -// in a slice of datamapLine structs. -func getSheetNames(dmls ExtractedDatamapFile) []string { - var sheetNames []string - - for _, dml := range dmls { - if !sheetInSlice(sheetNames, dml.Sheet) { - sheetNames = append(sheetNames, dml.Sheet) - } - } - - return sheetNames -} - -// ReadDML returns a slice of datamapLine structs given a -// path to a datamap file. -func ReadDML(path string) (ExtractedDatamapFile, error) { - var s ExtractedDatamapFile - - data, err := ioutil.ReadFile(path) - - if err != nil { - return s, fmt.Errorf("Cannot find file: %s", path) - } - - r := csv.NewReader(strings.NewReader(string(data))) - - for { - record, err := r.Read() - if err == io.EOF { - break - } - - if err != nil { - return s, errors.New("Cannot read line %s") - } - - if record[0] == "cell_key" { - // this must be the header - continue - } - - dml := datamapLine{ - Key: strings.Trim(record[0], " "), - Sheet: strings.Trim(record[1], " "), - Cellref: strings.Trim(record[2], " ")} - s = append(s, dml) - } - - return s, nil -} - -// cellVisitor is used by datamaps.rowVisitor() and is called -// on every cell in the target xlsx file in order to extract -// the data. -func cellVisitor(c *xlsx.Cell) error { - x, y := c.GetCoordinates() - cellref := xlsx.GetCellIDStringFromCoords(x, y) - - // TODO: we need to store the c.NumFmt value here in the - // database so we can reply it again when we write the values - // to the master or elsewhere. We should keep the value itself - // in its unformatted state - i.e a date being something like 488594. - - ex := extractedCell{ - Cell: c, - Value: c.Value, - } - - inner[cellref] = ex - - return nil -} - -// rowVisitor is used as a callback by xlsx.sheet.ForEachRow(). It wraps -// a call to xlsx.Row.ForEachCell() which actually extracts the data. -func rowVisitor(r *xlsx.Row) error { - if err := r.ForEachCell(cellVisitor, xlsx.SkipEmptyCells); err != nil { - return err - } - return nil -} - -// ReadXLSX returns a file at path's data as a map, -// keyed on sheet name. All values are returned as strings. -// Paths to a datamap and the spreadsheet file required. -func ReadXLSX(path string) FileData { - wb, err := xlsx.OpenFile(path) - if err != nil { - fmt.Errorf("cannot open file at %s - %v", path, err) - } - - outer := make(FileData, 1) - - // get the data - for _, sheet := range wb.Sheets { - - if err := sheet.ForEachRow(rowVisitor); err != nil { - fmt.Errorf("cannot call ForEachRow() in sheet %s - %v", sheet.Name, err) - } - outer[sheet.Name] = inner - inner = make(sheetData) - } - - return outer -} - -// DatamapFromDB creates an ExtractedDatamapFile from the database given -// the name of a datamap. Of course, in this instance, the data is not -// coming from a datamap file (such as datamap.csv) but from datamap data -// previous stored in the database by DatamapToDB or similar. -func DatamapFromDB(name string, db *sql.DB) (ExtractedDatamapFile, error) { - - var out ExtractedDatamapFile - - query := ` - select - key, sheet, cellref - from datamap_line - join datamap on datamap_line.dm_id = datamap.id where datamap.name = ?; - ` - rows, err := db.Query(query, name) - if err != nil { - erstr := fmt.Sprintf("cannot query for datamap key, sheet and cellref - %v", err) - return nil, errors.New(erstr) - } - defer rows.Close() - - for rows.Next() { - var ( - key string - sheet string - cellref string - ) - if err := rows.Scan(&key, &sheet, &cellref); err != nil { - return nil, err - } - - out = append(out, datamapLine{Key: key, Sheet: sheet, Cellref: cellref}) - } - - return out, nil -} - -// ExtractDBDatamap uses a datamap named from the database db to extract values -// from the populated spreadsheet file file. -func ExtractDBDatamap(name string, file string, db *sql.DB) (ExtractedData, error) { - ddata, err := DatamapFromDB(name, db) // this will need to return an ExtractedDatamapFile - if err != nil { - erstr := fmt.Sprintf("cannot call DatamapFromDB() - %v", err) - return nil, errors.New(erstr) - } - if len(ddata) == 0 { - return nil, fmt.Errorf("there is no datamap in the database matching name '%s'. Try running 'datamaps datamap --import...'", name) - } - xdata := ReadXLSX(file) - - names := getSheetNames(ddata) - outer := make(ExtractedData, len(names)) - // var inner map[string]xlsx.Cell - - for _, s := range names { - outer[s] = make(map[string]xlsx.Cell) - } - - for _, i := range ddata { - sheet := i.Sheet - cellref := i.Cellref - - if val, ok := xdata[sheet][cellref]; ok { - outer[sheet][cellref] = *val.Cell - } - } - - return outer, nil -} - -// extract returns the file at path's data as a map, -// using the datamap as a filter, keyed on sheet name. All values -// are returned as strings. (Currently deprecated in favour of -// ExtractDBDatamap. -func extract(dm string, path string) ExtractedData { - xdata := ReadXLSX(path) - ddata, err := ReadDML(dm) - - if err != nil { - log.Fatal(err) - } - - names := getSheetNames(ddata) - outer := make(ExtractedData, len(names)) - inner := make(map[string]xlsx.Cell) - - for _, i := range ddata { - sheet := i.Sheet - cellref := i.Cellref - - if val, ok := xdata[sheet][cellref]; ok { - inner[cellref] = *val.Cell - outer[sheet] = inner - } - } - - return outer -} - -//getTargetFiles finds all xlsx and xlsm files in directory. -func getTargetFiles(path string) ([]string, error) { - if lastchar := path[len(path)-1:]; lastchar != string(filepath.Separator) { - return nil, fmt.Errorf("path must end in a %s character", string(filepath.Separator)) - } - - fullpath := strings.Join([]string{path, "*.xls[xm]"}, "") - output, err := filepath.Glob(fullpath) - - if err != nil { - return nil, err - } - - if output == nil { - return nil, fmt.Errorf("cannot find any xlsx files in %s", path) - } - - return output, nil -} diff --git a/pkg/datamaps/reader_test.go b/pkg/datamaps/reader_test.go deleted file mode 100644 index e214930..0000000 --- a/pkg/datamaps/reader_test.go +++ /dev/null @@ -1,251 +0,0 @@ -package datamaps - -import ( - "os" - "testing" -) - -func TestReadDML(t *testing.T) { - d, _ := ReadDML("testdata/datamap.csv") - cases := []struct { - idx int - val string - }{ - {0, "Project/Programme Name"}, - {1, "Department"}, - {2, "Delivery Body"}, - } - - for _, c := range cases { - if got := d[c.idx].Key; got != c.val { - t.Errorf("The test expected %s, got %s.", c.val, d[c.idx].Key) - } - } -} - -func TestNoFileReturnsError(t *testing.T) { - // this file does not exist - _, err := ReadDML("/home/bobbins.csv") - // if we get no error, something has gone wrong - - if err == nil { - t.Errorf("Should have thrown error %s", err) - } -} - -func TestBadDMLLine(t *testing.T) { - _, err := ReadDML("/home/lemon/code/python/bcompiler-engine/tests/resources/datamap_empty_cols.csv") - - if err == nil { - t.Errorf("No error so test failed.") - } -} - -func TestGetSheetsFromDM(t *testing.T) { - slice, _ := ReadDML("testdata/datamap.csv") - sheetNames := getSheetNames(slice) - - if len(sheetNames) != 15 { - t.Errorf("The test expected 14 sheets in slice, got %d.", - len(sheetNames)) - } -} - -func TestReadXLSX(t *testing.T) { - d := ReadXLSX("testdata/test_template.xlsx") - cases := []struct { - sheet, cellref, val string - }{ - {"Summary", "A2", "Date:"}, - {"Summary", "IG10", "botticelli"}, - {"Another Sheet", "F5", "4.2"}, - {"Another Sheet", "J22", "18"}, - } - - for _, c := range cases { - got := d[c.sheet][c.cellref].Value - if got != c.val { - t.Errorf("The test expected %s in %s sheet to be %s "+ - " - instead it is %s.", c.cellref, c.sheet, c.val, d[c.sheet][c.cellref].Value) - } - } -} - -// func TestExtractWithDBDatamap(t *testing.T) { -// // setup - we need the datamap in the test database -// db, err := setupDB("./testdata/test.db") -// defer func() { -// db.Close() -// os.Remove("./testdata/test.db") -// }() - -// if err != nil { -// t.Fatal("Expected to be able to set up the database.") -// } - -// opts := Options{ -// DBPath: "./testdata/test.db", -// DMName: "First Datamap", -// DMPath: "./testdata/datamap.csv", -// } - -// if err := DatamapToDB(&opts); err != nil { -// t.Errorf("Unable to write datamap to database file because %v.", err) -// } - -// d := extractDBDatamap("First Datamap", "testdata/test_template.xlsx") -// } - -func TestDMLSliceFromDatabase(t *testing.T) { - // setup - we need the datamap in the test database - db, err := setupDB("./testdata/test.db") - defer func() { - db.Close() - os.Remove("./testdata/test.db") - }() - - if err != nil { - t.Fatal("Expected to be able to set up the database.") - } - - opts := Options{ - DBPath: "./testdata/test.db", - DMName: "First Datamap", - DMPath: "./testdata/datamap.csv", - } - - if err := DatamapToDB(&opts); err != nil { - t.Errorf("Unable to write datamap to database file because %v.", err) - } - - cases := []struct { - index int - key string - }{ - {0, "Project/Programme Name"}, - {1, "Department"}, - {2, "Delivery Body"}, - {3, "Stoogge value"}, - {4, "DRRDD - IPA ID Number"}, - {5, "Controls Project ID number"}, - {6, "Jokey Entry"}, - {7, "Parrots Name"}, - } - - data, _ := DatamapFromDB("First Datamap", db) - - for _, c := range cases { - got := data[c.index].Key - if got != c.key { - t.Errorf("The test expected %s but got %s\n", c.key, data[c.index].Key) - } - } - - if data[0].Key != "Project/Programme Name" { - t.Errorf("expected to see Project/Programme Name and got %q\n", data[0]) - } -} - -func TestExtractUsingDBDM(t *testing.T) { - // setup - we need the datamap in the test database - db, err := setupDB("./testdata/test.db") - defer func() { - db.Close() - os.Remove("./testdata/test.db") - }() - - if err != nil { - t.Fatal("Expected to be able to set up the database.") - } - - opts := Options{ - DBPath: "./testdata/test.db", - DMName: "First Datamap", - DMPath: "./testdata/datamap_matches_test_template.csv", - } - - if err := DatamapToDB(&opts); err != nil { - t.Errorf("Unable to write datamap to database file because %v.", err) - } - - d, _ := ExtractDBDatamap("First Datamap", "testdata/test_template.xlsx", db) - cases := []struct { - sheet, cellref, val string - }{ - {"Introduction", "C9", "Test Department"}, - {"Introduction", "J9", "Greedy Parrots"}, - {"Introduction", "A1", "10"}, - {"Introduction", "C22", "VUNT"}, - } - - for _, c := range cases { - got := d[c.sheet][c.cellref].Value - if got != c.val { - t.Errorf("test_template.xlsx: The test expected %s in %s sheet to be %s "+ - "- instead it is %s.", c.sheet, c.cellref, c.val, - d[c.sheet][c.cellref].Value) - } - } -} - -func TestExtract(t *testing.T) { - d := extract("testdata/datamap.csv", "testdata/test_template.xlsx") - cases := []struct { - sheet, cellref, val string - }{ - {"Introduction", "C9", "Test Department"}, - {"Introduction", "J9", "Greedy Parrots"}, - {"Introduction", "A1", "10"}, - {"Introduction", "C22", "VUNT"}, - } - - for _, c := range cases { - got := d[c.sheet][c.cellref].Value - if got != c.val { - t.Errorf("The test expected %s in %s sheet to be %s "+ - "- instead it is %s.", c.sheet, c.cellref, c.val, - d[c.sheet][c.cellref].Value) - } - } - - if d["Another Sheet"]["E26"].Value != "Integer:" { - t.Errorf("Expected E26 in Another Sheet sheet to be Integer: - instead it is %s", d["Another Sheet"]["E26"].Value) - } -} - -// func TestGetTargetFiles(t *testing.T) { -// // This is not a suitable test for parameterisation, but doing it this way anyway. -// type args struct { -// path string -// } -// tests := []struct { -// name string -// args args -// want []string -// wantErr bool -// }{ -// {"Get files in testdata", -// args{"./testdata/"}, -// []string{ -// "testdata/test_template.xlsm", -// "testdata/test_template.xlsx", -// "testdata/test_template2.xlsx", -// "testdata/test_template3.xlsx", -// }, -// false, -// }, -// } -// for _, tt := range tests { -// t.Log("Running the test") -// t.Run(tt.name, func(t *testing.T) { -// got, err := getTargetFiles(tt.args.path) -// if (err != nil) != tt.wantErr { -// t.Errorf("getTargetFiles() error = %v, wantErr %v", err, tt.wantErr) -// return -// } -// if !reflect.DeepEqual(got, tt.want) { -// t.Errorf("getTargetFiles() = %v, want %v", got, tt.want) -// } -// }) -// } -// } diff --git a/pkg/datamaps/testdata/datamap.csv b/pkg/datamaps/testdata/datamap.csv deleted file mode 100644 index d13bd27..0000000 --- a/pkg/datamaps/testdata/datamap.csv +++ /dev/null @@ -1,1948 +0,0 @@ -cell_key,template_sheet,cellreference -Project/Programme Name,Introduction,C11 -Department ,Introduction,C9 -Delivery Body ,Introduction,C10 -Stoogge value,Another Sheet,E26 -DRRDD - IPA ID Number,Introduction,C12 -Controls Project ID number,Introduction,C13 -Jokey Entry,Introduction,A1 -Parrots Name,Introduction,J9 -Project Type (for IPA use),Introduction,C14 -Classification,Introduction,C15 -DRRDD (GMPP - formally joined GMPP),Introduction,C16 -Reporting period (DRRDD - Snapshot Date),Introduction,C17 -Snapshot Date,Introduction,C18 -Senior Responsible Owner (SRO),Introduction,C21 -Senior Responsible Owner (SRO) - Email,Introduction,C22 -Senior Responsible Owner (SRO) - ID number,Introduction,C23 -SRO Sign-Off,Introduction,C24 -Project Director (PD),Introduction,C26 -Project Director (PD) - Email,Introduction,C27 -Project Director (PD) - ID number,Introduction,C28 -Date Report Approved by PD?,Introduction,C29 -Working Contact Name,Introduction,C31 -Working Contact Email,Introduction,C32 -Project Accountant with responsibility for Spend - Email,Introduction,C33 -Project Benefits Mngr with responsibility for Benefits - Email,Introduction,C34 -Project Planner with responsibility for Milestones - Email,Introduction,C35 -IPA's Departmental Single Point of Contact,Introduction,C38 -IPA's Departmental Single Point of Contact - Email,Introduction,C39 -IPA Analysis & Insight Unit (AIU) Lead,Introduction,C40 -IPA Analysis & Insight Unit (AIU) Lead - Email,Introduction,C41 -Date Report Approved by AIU?,Introduction,C42 -IPA Strategic Delivery Advisor (SDA) - Email,Introduction,C43 -Date Report Approved by SDA?,Introduction,C44 -Departmental PPM HoP copied in submission email?,Introduction,C46 -Departmental PPM HoP - Email,Introduction,C47 -Departmental HR HoP copied in submission email?,Introduction,C48 -Departmental HR HoP - Email,Introduction,C49 -Departmental Finance HoP copied in submission email?,Introduction,C50 -Departmental Finance HoP - Email,Introduction,C51 -Departmental Economics HoP copied in submission email?,Introduction,C52 -Departmental Economics HoP - Email,Introduction,C53 -Departmental Legal HoP copied in submission email?,Introduction,C54 -Departmental Legal HoP - Email,Introduction,C55 -Departmental Commercial l HoP copied in submission email?,Introduction,C56 -Departmental Commercial HoP - Email,Introduction,C57 -Departmental IT HoP copied in submission email?,Introduction,C58 -Departmental IT HoP - Email,Introduction,C59 -HMT Spending Team Lead copied in submission email?,Introduction,C60 -HMT Spending Team Lead - Email,Introduction,C61 -Quarter Joined,Introduction,C66 -DFT ID Number,Introduction,C65 -Working Contact Telephone,Introduction,C67 -DfT Group,Introduction,C63 -DfT Division,Introduction,C64 -Brief project description (DRRDD - brief descripton),1 - Project Info,E6 -DRRDD - Dept,1 - Project Info,E7 -Agency or delivery partner (DRRDD - Delivery Organisation primary),1 - Project Info,E8 -Delivery Organisation Secondary,1 - Project Info,E9 -Project status,1 - Project Info,E10 -Is the SRO for this project an MPLA Graduate?,1 - Project Info,E11 -Is the PD for this project an MPLA Graduate?,1 - Project Info,E12 -Does the Project have an issued SRO appointment letter?,1 - Project Info,E13 -Has the SRO issued an appointment letter to the PD?,1 - Project Info,E14 -Delivery Structure,1 - Project Info,E17 -Change Delivery Methodology,1 - Project Info,E18 -Delivery Narrative,1 - Project Info,E19 -DN Type 1,1 - Project Info,D23 -DN Description 1,1 - Project Info,E23 -DN Type 2,1 - Project Info,D24 -DN Description 2,1 - Project Info,E24 -DN Type 3,1 - Project Info,D25 -DN Description 3,1 - Project Info,E25 -DN Type 4,1 - Project Info,D26 -DN Description 4,1 - Project Info,E26 -DN Type 5,1 - Project Info,D27 -DN Description 5,1 - Project Info,E27 -Primary Category,1 - Project Info,E30 -Secondary Category,1 - Project Info,E31 -Tertiary Category,1 - Project Info,E32 -DRRDD Annual Report Category,1 - Project Info,E33 -Significant Steel Requirement,1 - Project Info,E34 -"For all construction, infrastructure or capital investment procurements >£10M, have you adopted the Government's Balanced Scorecard approach",1 - Project Info,E35 -DRRDD - Main reason for joining GMPP,1 - Project Info,E36 -Second reason for joining DRRDD (if applicable),1 - Project Info,E37 -List Strategic Outcomes (DRRDD - Intended Outcome 1),1 - Project Info,D41 -IO1,1 - Project Info,G41 -IO1 - Monetised?,1 - Project Info,H41 -IO1 PESTLE,1 - Project Info,J41 -List Strategic Outcomes (DRRDD - Intended Outcome 2),1 - Project Info,D42 -IO2,1 - Project Info,G42 -IO2 - Monetised?,1 - Project Info,H42 -IO2 PESTLE,1 - Project Info,J42 -List Strategic Outcomes (DRRDD - Intended Outcome 3),1 - Project Info,D43 -IO3,1 - Project Info,G43 -IO3 - Monetised?,1 - Project Info,H43 -IO3 PESTLE,1 - Project Info,J43 -List Strategic Outcomes (DRRDD - Intended Outcome 4),1 - Project Info,D44 -IO4,1 - Project Info,G44 -IO4 - Monetised?,1 - Project Info,H44 -IO4 PESTLE,1 - Project Info,J44 -List Strategic Outcomes (DRRDD - Intended Outcome 5),1 - Project Info,D45 -IO5,1 - Project Info,G45 -IO5 - Monetised?,1 - Project Info,H45 -IO5 PESTLE,1 - Project Info,J45 -List Strategic Outcomes (DRRDD - Intended Outcome 6),1 - Project Info,D46 -IO6,1 - Project Info,G46 -IO6 - Monetised?,1 - Project Info,H46 -IO6 PESTLE,1 - Project Info,J46 -List Strategic Outcomes (DRRDD - Intended Outcome 7),1 - Project Info,D47 -IO7,1 - Project Info,G47 -IO7 - Monetised?,1 - Project Info,H47 -IO7 PESTLE,1 - Project Info,J47 -List Strategic Outcomes (DRRDD - Intended Outcome 8),1 - Project Info,D48 -IO8,1 - Project Info,G48 -IO8 - Monetised?,1 - Project Info,H48 -IO8 PESTLE,1 - Project Info,J48 -List Strategic Outcomes (DRRDD - Intended Outcome 9),1 - Project Info,D49 -IO9,1 - Project Info,G49 -IO9 - Monetised?,1 - Project Info,H49 -IO9 PESTLE,1 - Project Info,J49 -List Strategic Outcomes (DRRDD - Intended Outcome 10),1 - Project Info,D50 -IO10,1 - Project Info,G50 -IO10 - Monetised?,1 - Project Info,H50 -IO10 PESTLE,1 - Project Info,J50 -Primary investment Objective,1 - Project Info,E54 -IO11 Monetised,1 - Project Info,K54 -Secondary Investment Objective,1 - Project Info,E55 -IO12 Monetised,1 - Project Info,K55 -Is successful completion of this project dependent on another DRRDD project? ,1 - Project Info,E58 -Dependency 1 - Department,1 - Project Info,E59 -Dependency 1 - DRRDD Project,1 - Project Info,E60 -Dependency 2 - Department,1 - Project Info,E61 -Dependency 2 - DRRDD Project,1 - Project Info,E62 -Dependency 3 - Department,1 - Project Info,E63 -Dependency 3 - DRRDD Project,1 - Project Info,E64 -Project Bobbins,1 - Project Info,E67 -Departmental DCA,2 - DCA & Risk,E7 -Departmental DCA Narrative,2 - DCA & Risk,E8 -DRRDD - IPA DCA,2 - DCA & Risk,E10 -DRRDD - IPA DCA Commentary,2 - DCA & Risk,E11 -DRRDD - IPA DCA last quarter,2 - DCA & Risk,P10 -Risk Level (RPA),2 - DCA & Risk,E12 -Risk Level (RPA) Date,2 - DCA & Risk,E13 -Brief Risk Decription 1,2 - DCA & Risk,D17 -BRD 1Risk Category,2 - DCA & Risk,E17 -BRD 1 Primary Risk to ,2 - DCA & Risk,G17 -BRD 1 Internal Control,2 - DCA & Risk,I17 -BRD 1 Residual Impact,2 - DCA & Risk,J17 -BRD 1 Residual Likelihood,2 - DCA & Risk,K17 -Brief Risk Decription 2,2 - DCA & Risk,D18 -BRD 2 Risk Category,2 - DCA & Risk,E18 -BRD 2 Primary Risk to ,2 - DCA & Risk,G18 -BRD 2 Internal Control,2 - DCA & Risk,I18 -BRD 2 Residual Impact,2 - DCA & Risk,J18 -BRD 2 Residual Likelihood,2 - DCA & Risk,K18 -Brief Risk Decription 3,2 - DCA & Risk,D19 -BRD 3 Risk Category,2 - DCA & Risk,E19 -BRD 3 Primary Risk to ,2 - DCA & Risk,G19 -BRD 3 Internal Control,2 - DCA & Risk,I19 -BRD 3 Residual Impact,2 - DCA & Risk,J19 -BRD 3 Residual Likelihood,2 - DCA & Risk,K19 -Brief Risk Decription 4,2 - DCA & Risk,D20 -BRD 4 Risk Category,2 - DCA & Risk,E20 -BRD 4 Primary Risk to ,2 - DCA & Risk,G20 -BRD 4 Internal Control,2 - DCA & Risk,I20 -BRD 4 Residual Impact,2 - DCA & Risk,J20 -BRD 4 Residual Likelihood,2 - DCA & Risk,K20 -Brief Risk Decription 5,2 - DCA & Risk,D21 -BRD 5 Risk Category,2 - DCA & Risk,E21 -BRD 5 Primary Risk to ,2 - DCA & Risk,G21 -BRD 5 Internal Control,2 - DCA & Risk,I21 -BRD 5 Residual Impact,2 - DCA & Risk,J21 -BRD 5 Residual Likelihood,2 - DCA & Risk,K21 -1st Bobbins Change - Description / Type,3 - Scope History,E6 -SC1 Date Bobbins Change Implemented,3 - Scope History,E7 -SC1 Date Implemented: Actual or Forecast?,3 - Bobbins History,K7 -SC1 Impact on Project End Date?,3 - Bobbins History,E8 -SC1 Is change in Project End Date solely due to the Bobbins change? ,3 - Scope History,E9 -SC1 Impact on Costs?,3 - Bobbins History,E10 -SC1 Is change in Costs solely due to the Bobbins change? ,3 - Scope History,E11 -SC1 Impact on Intended Outcomes?,3 - Bobbins History,E12 -SC1 Has the Business Case been updated as a result of this Bobbins change?,3 - Scope History,E13 -"SC1 If Yes, new Business Case Type?",3 - Bobbins History,K14 -SC1 New Business Case Version Number,3 - Bobbins History,E14 -SC1 Has HMT approved this new business case?,3 - Bobbins History,E15 -2nd Bobbins Change - Description / Type,3 - Scope History,E18 -SC2 Date Bobbins Change Implemented,3 - Scope History,E19 -SC2 Date Implemented: Actual or Forecast?,3 - Bobbins History,K19 -SC2 Impact on Project End Date?,3 - Bobbins History,E20 -SC2 Is change in Project End Date solely due to the Bobbins change? ,3 - Scope History,E21 -SC2 Impact on Costs?,3 - Bobbins History,E22 -SC2 Is change in Costs solely due to the Bobbins change? ,3 - Scope History,E23 -SC2 Impact on Intended Outcomes?,3 - Bobbins History,E24 -SC2 Has the Business Case been updated as a result of this Bobbins change?,3 - Scope History,E25 -"SC2 If Yes, new Business Case Type?",3 - Bobbins History,E26 -SC2 New Business Case Version Number,3 - Bobbins History,K26 -SC2 Has HMT approved this new business case?,3 - Bobbins History,E27 -3rd Bobbins Change - Description / Type,3 - Scope History,E30 -SC3 Date Bobbins Change Implemented,3 - Scope History,E31 -SC3 Date Implemented: Actual or Forecast?,3 - Bobbins History,K31 -SC3 Impact on Project End Date?,3 - Bobbins History,E32 -SC3 Is change in Project End Date solely due to the Bobbins change? ,3 - Scope History,E33 -SC3 Impact on Costs?,3 - Bobbins History,E34 -SC3 Is change in Costs solely due to the Bobbins change? ,3 - Scope History,E35 -SC3 Impact on Intended Outcomes?,3 - Bobbins History,E36 -SC3 Has the Business Case been updated as a result of this Bobbins change?,3 - Scope History,E37 -"SC3 If Yes, new Business Case Type?",3 - Bobbins History,E38 -SC3 New Business Case Version Number,3 - Bobbins History,K38 -SC3 Has HMT approved this new business case?,3 - Bobbins History,E39 -4th Bobbins Change - Description / Type,3 - Scope History,E42 -SC4 Date Bobbins Change Implemented,3 - Scope History,E43 -SC4 Date Implemented: Actual or Forecast?,3 - Bobbins History,K43 -SC4 Impact on Project End Date?,3 - Bobbins History,E44 -SC4 Is change in Project End Date solely due to the Bobbins change? ,3 - Scope History,E45 -SC4 Impact on Costs?,3 - Bobbins History,E46 -SC4 Is change in Costs solely due to the Bobbins change? ,3 - Scope History,E47 -SC4 Impact on Intended Outcomes?,3 - Bobbins History,E48 -SC4 Has the Business Case been updated as a result of this Bobbins change?,3 - Scope History,E49 -"SC4 If Yes, new Business Case Type?",3 - Bobbins History,E50 -SC4 New Business Case Version Number,3 - Bobbins History,K50 -SC4 Has HMT approved this new business case?,3 - Bobbins History,E51 -SRO Is this position currently filled?,4 - Leaders,E6 -DRRDD - SRO ID,4 - Leaders,E7 -SRO Last Name,4 - Leaders,E8 -SRO First Name,4 - Leaders,E9 -SRO Full Name,4 - Leaders,E10 -SRO Email,4 - Leaders,E11 -SRO Phone No.,4 - Leaders,E12 -SRO Tenure Start Date,4 - Leaders,E13 -SRO Tenure End Date,4 - Leaders,E14 -SRO Length of tenure (years),4 - Leaders,E15 -"If SRO Tenure End Date change, please advise reason",4 - Leaders,E16 -Job Title / Grade,4 - Leaders,E17 -SRO Grade,4 - Leaders,K17 -SRO Career Anchor - Primary,4 - Leaders,E18 -SRO Career Anchor - Secondary,4 - Leaders,E19 -Percentage of time spent on SRO Role,4 - Leaders,E20 -If new SRO reason for change,4 - Leaders,E21 -"If there are further SROs, please name, and explain why?",4 - Leaders,E22 -PD Is this position currently filled?,4 - Leaders,E25 -DRRDD - PD ID,4 - Leaders,E26 -PD Last Name,4 - Leaders,E27 -PD First Name,4 - Leaders,E28 -PD Full Name,4 - Leaders,E29 -PD Email,4 - Leaders,E30 -PD Phone No.,4 - Leaders,E31 -PD Tenure Start Date,4 - Leaders,E32 -PD Tenure End Date,4 - Leaders,E33 -PD Length of tenure (years),4 - Leaders,E34 -"If PD Tenure End Date change, please advise reason, and Type",4 - Leaders,E35 -Job Title,4 - Leaders,E36 -PD Grade,4 - Leaders,K36 -PD Career Anchor - Primary,4 - Leaders,E37 -PD Career Anchor - Secondary,4 - Leaders,E38 -Percentage of time spent on PD Role,4 - Leaders,E39 -If new PD reason for change,4 - Leaders,E40 -Secondary PDs please name?,4 - Leaders,E41 -No public sector employees working on the project,5 - People,E6 -No external contractors working on the project,5 - People,E7 -TOTAL Number working in the project team (FTEs),5 - People,E8 -No employees funded to work on project,5 - People,E9 -Total Number or vacancies on the project,5 - People,E10 -Resource Gap (%),5 - People,E11 -Project Team Turnover since last Quarter - Qualitative Assessment,5 - People,E12 -Resources commentary,5 - People,E13 -Digital - Now,5 - People,E17 -Digital - Future,5 - People,G17 -Digital Short Narrative (Amber or Red),5 - People,I17 -Information Technology - Now,5 - People,E18 -Information Technology - Future,5 - People,G18 -Information Technology Short Narrative (Amber or Red),5 - People,I18 -Legal Commercial Contract Management - Now,5 - People,E19 -Legal Commercial Contract Management - Future,5 - People,G19 -"Legal, Commercial & Contract Management Short Narrative (Amber or Red)",5 - People,I19 -Project Delivery - Now,5 - People,E20 -Project Delivery - Future,5 - People,G20 -Project Delivery Short Narrative (Amber or Red),5 - People,I20 -Change Implementation - Now,5 - People,E21 -Change Implementation - Future,5 - People,G21 -Change Implementation Short Narrative (Amber or Red),5 - People,I21 -Technical - Now,5 - People,E22 -Technical - Future,5 - People,G22 -Technical Short Narrative (Amber or Red),5 - People,I22 -Industry Knowledge - Now,5 - People,E23 -Industry Knowledge - Future,5 - People,G23 -Industry Knowledge Short Narrative (Amber or Red),5 - People,I23 -Finance - Now,5 - People,E24 -Finance - Future,5 - People,G24 -Finance Short Narrative (Amber or Red),5 - People,I24 -Analysis Now,5 - People,E25 -Analysis - future,5 - People,G25 -Analysis Short Narrative (Amber or Red),5 - People,I25 -Communications & Stakeholder Engagement - Now,5 - People,E26 -Communications & Stakeholder Engagement - Future,5 - People,G26 -Communications & Stakeholder Engagement Short Narrative (Amber or Red),5 - People,I26 -Additional Capability 1 Now,5 - People,E27 -Additional Capability 1 Future,5 - People,G27 -Additional Capability 1 Short Narrative (Amber or Red),5 - People,I27 -Additional Capability 2 Now,5 - People,E28 -Additional Capability 2 Future,5 - People,G28 -Additional Capability 2 Short Narrative (Amber or Red),5 - People,I28 -Other Capability 3 - Now,5 - People,E29 -Other Capability 3 - Future,5 - People,G29 -Additional Capability 3 Short Narrative (Amber or Red),5 - People,I29 -Other Capability 4 - Now,5 - People,E30 -Other Capability 4 - Future,5 - People,G30 -Additional Capability 4 Short Narrative (Amber or Red),5 - People,I30 -Additional Capability 5 Now,5 - People,E31 -Additional Capability 5 Future,5 - People,G31 -Additional Capability 5 Short Narrative (Amber or Red),5 - People,I31 -Overall Resource DCA - Now,5 - People,E35 -Overall Resource DCA - Future,5 - People,G35 -Approval MM1,6a - Milestones - Approvals,D7 -Approval MM1 Gov Type,6a - Milestones - Approvals,E7 -Approval MM1 Ver No,6a - Milestones - Approvals,F7 -Approval MM1 Original Bobline,6a - Milestones - Approvals,G7 -Approval MM1 Forecast / Actual,6a - Milestones - Approvals,H7 -Approval MM1 Variance,6a - Milestones - Approvals,I7 -Approval MM1 Status,6a - Milestones - Approvals,J7 -Approval MM1 Notes,6a - Milestones - Approvals,K7 -Approval MM2,6a - Milestones - Approvals,D8 -Approval MM2 Gov Type,6a - Milestones - Approvals,E8 -Approval MM2 Ver No,6a - Milestones - Approvals,F8 -Approval MM2 Original Bobline,6a - Milestones - Approvals,G8 -Approval MM2 Forecast / Actual,6a - Milestones - Approvals,H8 -Approval MM2 Variance,6a - Milestones - Approvals,I8 -Approval MM2 Status,6a - Milestones - Approvals,J8 -Approval MM2 Notes,6a - Milestones - Approvals,K8 -Approval MM3,6a - Milestones - Approvals,D9 -Approval MM3 Gov Type,6a - Milestones - Approvals,E9 -Approval MM3 Ver No,6a - Milestones - Approvals,F9 -Approval MM3 Original Bobline,6a - Milestones - Approvals,G9 -Approval MM3 Forecast / Actual,6a - Milestones - Approvals,H9 -Approval MM3 Variance,6a - Milestones - Approvals,I9 -Approval MM3 Status,6a - Milestones - Approvals,J9 -Approval MM3 Notes,6a - Milestones - Approvals,K9 -Approval MM4,6a - Milestones - Approvals,D10 -Approval MM4 Gov Type,6a - Milestones - Approvals,E10 -Approval MM4 Ver No,6a - Milestones - Approvals,F10 -Approval MM4 Original Bobline,6a - Milestones - Approvals,G10 -Approval MM4 Forecast / Actual,6a - Milestones - Approvals,H10 -Approval MM4 Variance,6a - Milestones - Approvals,I10 -Approval MM4 Status,6a - Milestones - Approvals,J10 -Approval MM4 Notes,6a - Milestones - Approvals,K10 -Approval MM5,6a - Milestones - Approvals,D11 -Approval MM5 Gov Type,6a - Milestones - Approvals,E11 -Approval MM5 Ver No,6a - Milestones - Approvals,F11 -Approval MM5 Original Bobline,6a - Milestones - Approvals,G11 -Approval MM5 Forecast / Actual,6a - Milestones - Approvals,H11 -Approval MM5 Variance,6a - Milestones - Approvals,I11 -Approval MM5 Status,6a - Milestones - Approvals,J11 -Approval MM5 Notes,6a - Milestones - Approvals,K11 -Approval MM6,6a - Milestones - Approvals,D12 -Approval MM6 Gov Type,6a - Milestones - Approvals,E12 -Approval MM6 Ver No,6a - Milestones - Approvals,F12 -Approval MM6 Original Bobline,6a - Milestones - Approvals,G12 -Approval MM6 Forecast / Actual,6a - Milestones - Approvals,H12 -Approval MM6 Variance,6a - Milestones - Approvals,I12 -Approval MM6 Status,6a - Milestones - Approvals,J12 -Approval MM6 Notes,6a - Milestones - Approvals,K12 -Approval MM7,6a - Milestones - Approvals,D13 -Approval MM7 Gov Type,6a - Milestones - Approvals,E13 -Approval MM7 Ver No,6a - Milestones - Approvals,F13 -Approval MM7 Original Bobline,6a - Milestones - Approvals,G13 -Approval MM7 Forecast / Actual,6a - Milestones - Approvals,H13 -Approval MM7 Variance,6a - Milestones - Approvals,I13 -Approval MM7 Status,6a - Milestones - Approvals,J13 -Approval MM7 Notes,6a - Milestones - Approvals,K13 -Approval MM8,6a - Milestones - Approvals,D14 -Approval MM8 Gov Type,6a - Milestones - Approvals,E14 -Approval MM8 Ver No,6a - Milestones - Approvals,F14 -Approval MM8 Original Bobline,6a - Milestones - Approvals,G14 -Approval MM8 Forecast / Actual,6a - Milestones - Approvals,H14 -Approval MM8 Variance,6a - Milestones - Approvals,I14 -Approval MM8 Status,6a - Milestones - Approvals,J14 -Approval MM8 Notes,6a - Milestones - Approvals,K14 -Approval MM9,6a - Milestones - Approvals,D15 -Approval MM9 Gov Type,6a - Milestones - Approvals,E15 -Approval MM9 Ver No,6a - Milestones - Approvals,F15 -Approval MM9 Original Bobline,6a - Milestones - Approvals,G15 -Approval MM9 Forecast / Actual,6a - Milestones - Approvals,H15 -Approval MM9 Variance,6a - Milestones - Approvals,I15 -Approval MM9 Status,6a - Milestones - Approvals,J15 -Approval MM9 Notes,6a - Milestones - Approvals,K15 -Approval MM10,6a - Milestones - Approvals,D16 -Approval MM10 Gov Type,6a - Milestones - Approvals,E16 -Approval MM10 Ver No,6a - Milestones - Approvals,F16 -Approval MM10 Original Bobline,6a - Milestones - Approvals,G16 -Approval MM10 Forecast / Actual,6a - Milestones - Approvals,H16 -Approval MM10 Variance,6a - Milestones - Approvals,I16 -Approval MM10 Status,6a - Milestones - Approvals,J16 -Approval MM10 Notes,6a - Milestones - Approvals,K16 -Approval MM11,6a - Milestones - Approvals,D17 -Approval MM11 Gov Type,6a - Milestones - Approvals,E17 -Approval MM11 Ver No,6a - Milestones - Approvals,F17 -Approval MM11 Original Bobline,6a - Milestones - Approvals,G17 -Approval MM11 Forecast / Actual,6a - Milestones - Approvals,H17 -Approval MM11 Variance,6a - Milestones - Approvals,I17 -Approval MM11 Status,6a - Milestones - Approvals,J17 -Approval MM11 Notes,6a - Milestones - Approvals,K17 -Approval MM12,6a - Milestones - Approvals,D18 -Approval MM12 Gov Type,6a - Milestones - Approvals,E18 -Approval MM12 Ver No,6a - Milestones - Approvals,F18 -Approval MM12 Original Bobline,6a - Milestones - Approvals,G18 -Approval MM12 Forecast / Actual,6a - Milestones - Approvals,H18 -Approval MM12 Variance,6a - Milestones - Approvals,I18 -Approval MM12 Status,6a - Milestones - Approvals,J18 -Approval MM12 Notes,6a - Milestones - Approvals,K18 -Approval MM13,6a - Milestones - Approvals,D19 -Approval MM13 Gov Type,6a - Milestones - Approvals,E19 -Approval MM13 Ver No,6a - Milestones - Approvals,F19 -Approval MM13 Original Bobline,6a - Milestones - Approvals,G19 -Approval MM13 Forecast - Actual,6a - Milestones - Approvals,H19 -Approval MM13 Variance,6a - Milestones - Approvals,I19 -Approval MM13 Status,6a - Milestones - Approvals,J19 -Approval MM13 Notes,6a - Milestones - Approvals,K19 -Approval MM14,6a - Milestones - Approvals,D20 -Approval MM14 Gov Type,6a - Milestones - Approvals,E20 -Approval MM14 Ver No,6a - Milestones - Approvals,F20 -Approval MM14 Original Bobline,6a - Milestones - Approvals,G20 -Approval MM14 Forecast - Actual,6a - Milestones - Approvals,H20 -Approval MM14 Variance,6a - Milestones - Approvals,I20 -Approval MM14 Status,6a - Milestones - Approvals,J20 -Approval MM14 Notes,6a - Milestones - Approvals,K20 -Approval MM15,6a - Milestones - Approvals,D21 -Approval MM15 Gov Type,6a - Milestones - Approvals,E21 -Approval MM15 Ver No,6a - Milestones - Approvals,F21 -Approval MM15 Original Bobline,6a - Milestones - Approvals,G21 -Approval MM15 Forecast - Actual,6a - Milestones - Approvals,H21 -Approval MM15 Variance,6a - Milestones - Approvals,I21 -Approval MM15 Status,6a - Milestones - Approvals,J21 -Approval MM15 Notes,6a - Milestones - Approvals,K21 -Approval MM16,6a - Milestones - Approvals,D22 -Approval MM16 Gov Type,6a - Milestones - Approvals,E22 -Approval MM16 Ver No,6a - Milestones - Approvals,F22 -Approval MM16 Original Bobline,6a - Milestones - Approvals,G22 -Approval MM16 Forecast - Actual,6a - Milestones - Approvals,H22 -Approval MM16 Variance,6a - Milestones - Approvals,I22 -Approval MM16 Status,6a - Milestones - Approvals,J22 -Approval MM16 Notes,6a - Milestones - Approvals,K22 -Approval MM17,6a - Milestones - Approvals,D23 -Approval MM17 Gov Type,6a - Milestones - Approvals,E23 -Approval MM17 Ver No,6a - Milestones - Approvals,F23 -Approval MM17 Original Bobline,6a - Milestones - Approvals,G23 -Approval MM17 Forecast / Actual,6a - Milestones - Approvals,H23 -Approval MM17 Variance,6a - Milestones - Approvals,I23 -Approval MM17 Status,6a - Milestones - Approvals,J23 -Approval MM17 Notes,6a - Milestones - Approvals,K23 -Approval MM18,6a - Milestones - Approvals,D24 -Approval MM18 Gov Type,6a - Milestones - Approvals,E24 -Approval MM18 Ver No,6a - Milestones - Approvals,F24 -Approval MM18 Original Bobline,6a - Milestones - Approvals,G24 -Approval MM18 Forecast / Actual,6a - Milestones - Approvals,H24 -Approval MM18 Variance,6a - Milestones - Approvals,I24 -Approval MM18 Status,6a - Milestones - Approvals,J24 -Approval MM18 Notes,6a - Milestones - Approvals,K24 -Approval MM19,6a - Milestones - Approvals,D25 -Approval MM19 Gov Type,6a - Milestones - Approvals,E25 -Approval MM19 Ver No,6a - Milestones - Approvals,F25 -Approval MM19 Original Bobline,6a - Milestones - Approvals,G25 -Approval MM19 Forecast / Actual,6a - Milestones - Approvals,H25 -Approval MM19 Variance,6a - Milestones - Approvals,I25 -Approval MM19 Status,6a - Milestones - Approvals,J25 -Approval MM19 Notes,6a - Milestones - Approvals,K25 -Approval MM20,6a - Milestones - Approvals,D26 -Approval MM20 Gov Type,6a - Milestones - Approvals,E26 -Approval MM20 Ver No,6a - Milestones - Approvals,F26 -Approval MM20 Original Bobline,6a - Milestones - Approvals,G26 -Approval MM20 Forecast / Actual,6a - Milestones - Approvals,H26 -Approval MM20 Variance,6a - Milestones - Approvals,I26 -Approval MM20 Status,6a - Milestones - Approvals,J26 -Approval MM20 Notes,6a - Milestones - Approvals,K26 -Approval MM21,6a - Milestones - Approvals,D27 -Approval MM21 Gov Type,6a - Milestones - Approvals,E27 -Approval MM21 Ver No,6a - Milestones - Approvals,F27 -Approval MM21 Original Bobline,6a - Milestones - Approvals,G27 -Approval MM21 Forecast / Actual,6a - Milestones - Approvals,H27 -Approval MM21 Variance,6a - Milestones - Approvals,I27 -Approval MM21 Status,6a - Milestones - Approvals,J27 -Approval MM21 Notes,6a - Milestones - Approvals,K27 -Approval MM22,6a - Milestones - Approvals,D28 -Approval MM22 Gov Type,6a - Milestones - Approvals,E28 -Approval MM22 Ver No,6a - Milestones - Approvals,F28 -Approval MM22 Original Bobline,6a - Milestones - Approvals,G28 -Approval MM22 Forecast / Actual,6a - Milestones - Approvals,H28 -Approval MM22 Variance,6a - Milestones - Approvals,I28 -Approval MM22 Status,6a - Milestones - Approvals,J28 -Approval MM22 Notes,6a - Milestones - Approvals,K28 -Approval MM23,6a - Milestones - Approvals,D29 -Approval MM23 Gov Type,6a - Milestones - Approvals,E29 -Approval MM23 Ver No,6a - Milestones - Approvals,F29 -Approval MM23 Original Bobline,6a - Milestones - Approvals,G29 -Approval MM23 Forecast / Actual,6a - Milestones - Approvals,H29 -Approval MM23 Variance,6a - Milestones - Approvals,I29 -Approval MM23 Status,6a - Milestones - Approvals,J29 -Approval MM23 Notes,6a - Milestones - Approvals,K29 -Approval MM24,6a - Milestones - Approvals,D30 -Approval MM24 Gov Type,6a - Milestones - Approvals,E30 -Approval MM24 Ver No,6a - Milestones - Approvals,F30 -Approval MM24 Original Bobline,6a - Milestones - Approvals,G30 -Approval MM24 Forecast / Actual,6a - Milestones - Approvals,H30 -Approval MM24 Variance,6a - Milestones - Approvals,I30 -Approval MM24 Status,6a - Milestones - Approvals,J30 -Approval MM24 Notes,6a - Milestones - Approvals,K30 -Approval MM25,6a - Milestones - Approvals,D31 -Approval MM25 Gov Type,6a - Milestones - Approvals,E31 -Approval MM25 Ver No,6a - Milestones - Approvals,F31 -Approval MM25 Original Bobline,6a - Milestones - Approvals,G31 -Approval MM25 Forecast / Actual,6a - Milestones - Approvals,H31 -Approval MM25 Variance,6a - Milestones - Approvals,I31 -Approval MM25 Status,6a - Milestones - Approvals,J31 -Approval MM25 Notes,6a - Milestones - Approvals,K31 -Approval MM26,6a - Milestones - Approvals,D32 -Approval MM26 Gov Type,6a - Milestones - Approvals,E32 -Approval MM26 Ver No,6a - Milestones - Approvals,F32 -Approval MM26 Original Bobline,6a - Milestones - Approvals,G32 -Approval MM26 Forecast / Actual,6a - Milestones - Approvals,H32 -Approval MM26 Variance,6a - Milestones - Approvals,I32 -Approval MM26 Status,6a - Milestones - Approvals,J32 -Approval MM26 Notes,6a - Milestones - Approvals,K32 -Approval MM27,6a - Milestones - Approvals,D33 -Approval MM27 Gov Type,6a - Milestones - Approvals,E33 -Approval MM27 Ver No,6a - Milestones - Approvals,F33 -Approval MM27 Original Bobline,6a - Milestones - Approvals,G33 -Approval MM27 Forecast / Actual,6a - Milestones - Approvals,H33 -Approval MM27 Variance,6a - Milestones - Approvals,I33 -Approval MM27 Status,6a - Milestones - Approvals,J33 -Approval MM27 Notes,6a - Milestones - Approvals,K33 -Approval MM28,6a - Milestones - Approvals,D34 -Approval MM28 Gov Type,6a - Milestones - Approvals,E34 -Approval MM28 Ver No,6a - Milestones - Approvals,F34 -Approval MM28 Original Bobline,6a - Milestones - Approvals,G34 -Approval MM28 Forecast / Actual,6a - Milestones - Approvals,H34 -Approval MM28 Variance,6a - Milestones - Approvals,I34 -Approval MM28 Status,6a - Milestones - Approvals,J34 -Approval MM28 Notes,6a - Milestones - Approvals,K34 -Approval MM29,6a - Milestones - Approvals,D35 -Approval MM29 Gov Type,6a - Milestones - Approvals,E35 -Approval MM29 Ver No,6a - Milestones - Approvals,F35 -Approval MM29 Original Bobline,6a - Milestones - Approvals,G35 -Approval MM29 Forecast / Actual,6a - Milestones - Approvals,H35 -Approval MM29 Variance,6a - Milestones - Approvals,I35 -Approval MM29 Status,6a - Milestones - Approvals,J35 -Approval MM29 Notes,6a - Milestones - Approvals,K35 -Approval MM30,6a - Milestones - Approvals,D36 -Approval MM30 Gov Type,6a - Milestones - Approvals,E36 -Approval MM30 Ver No,6a - Milestones - Approvals,F36 -Approval MM30 Original Bobline,6a - Milestones - Approvals,G36 -Approval MM30 Forecast / Actual,6a - Milestones - Approvals,H36 -Approval MM30 Variance,6a - Milestones - Approvals,I36 -Approval MM30 Status,6a - Milestones - Approvals,J36 -Approval MM30 Notes,6a - Milestones - Approvals,K36 -Approval MM31,6a - Milestones - Approvals,D37 -Approval MM31 Gov Type,6a - Milestones - Approvals,E37 -Approval MM31 Ver No,6a - Milestones - Approvals,F37 -Approval MM31 Original Bobline,6a - Milestones - Approvals,G37 -Approval MM31 Forecast / Actual,6a - Milestones - Approvals,H37 -Approval MM31 Variance,6a - Milestones - Approvals,I37 -Approval MM31 Status,6a - Milestones - Approvals,J37 -Approval MM31 Notes,6a - Milestones - Approvals,K37 -Approval MM32,6a - Milestones - Approvals,D38 -Approval MM32 Gov Type,6a - Milestones - Approvals,E38 -Approval MM32 Ver No,6a - Milestones - Approvals,F38 -Approval MM32 Original Bobline,6a - Milestones - Approvals,G38 -Approval MM32 Forecast / Actual,6a - Milestones - Approvals,H38 -Approval MM32 Variance,6a - Milestones - Approvals,I38 -Approval MM32 Status,6a - Milestones - Approvals,J38 -Approval MM32 Notes,6a - Milestones - Approvals,K38 -Approval MM33,6a - Milestones - Approvals,D39 -Approval MM33 Gov Type,6a - Milestones - Approvals,E39 -Approval MM33 Ver No,6a - Milestones - Approvals,F39 -Approval MM33 Original Bobline,6a - Milestones - Approvals,G39 -Approval MM33 Forecast / Actual,6a - Milestones - Approvals,H39 -Approval MM33 Variance,6a - Milestones - Approvals,I39 -Approval MM33 Status,6a - Milestones - Approvals,J39 -Approval MM33 Notes,6a - Milestones - Approvals,K39 -Approval MM34,6a - Milestones - Approvals,D40 -Approval MM34 Gov Type,6a - Milestones - Approvals,E40 -Approval MM34 Ver No,6a - Milestones - Approvals,F40 -Approval MM34 Original Bobline,6a - Milestones - Approvals,G40 -Approval MM34 Forecast / Actual,6a - Milestones - Approvals,H40 -Approval MM34 Variance,6a - Milestones - Approvals,I40 -Approval MM34 Status,6a - Milestones - Approvals,J40 -Approval MM34 Notes,6a - Milestones - Approvals,K40 -Approval MM35,6a - Milestones - Approvals,D41 -Approval MM35 Gov Type,6a - Milestones - Approvals,E41 -Approval MM35 Ver No,6a - Milestones - Approvals,F41 -Approval MM35 Original Bobline,6a - Milestones - Approvals,G41 -Approval MM35 Forecast / Actual,6a - Milestones - Approvals,H41 -Approval MM35 Variance,6a - Milestones - Approvals,I41 -Approval MM35 Status,6a - Milestones - Approvals,J41 -Approval MM35 Notes,6a - Milestones - Approvals,K41 -Approval MM36,6a - Milestones - Approvals,D42 -Approval MM36 Gov Type,6a - Milestones - Approvals,E42 -Approval MM36 Ver No,6a - Milestones - Approvals,F42 -Approval MM36 Original Bobline,6a - Milestones - Approvals,G42 -Approval MM36 Forecast / Actual,6a - Milestones - Approvals,H42 -Approval MM36 Variance,6a - Milestones - Approvals,I42 -Approval MM36 Status,6a - Milestones - Approvals,J42 -Approval MM36 Notes,6a - Milestones - Approvals,K42 -Approval MM37,6a - Milestones - Approvals,D43 -Approval MM37 Gov Type,6a - Milestones - Approvals,E43 -Approval MM37 Ver No,6a - Milestones - Approvals,F43 -Approval MM37 Original Bobline,6a - Milestones - Approvals,G43 -Approval MM37 Forecast / Actual,6a - Milestones - Approvals,H43 -Approval MM37 Variance,6a - Milestones - Approvals,I43 -Approval MM37 Status,6a - Milestones - Approvals,J43 -Approval MM37 Notes,6a - Milestones - Approvals,K43 -Approval MM38,6a - Milestones - Approvals,D44 -Approval MM38 Gov Type,6a - Milestones - Approvals,E44 -Approval MM38 Ver No,6a - Milestones - Approvals,F44 -Approval MM38 Original Bobline,6a - Milestones - Approvals,G44 -Approval MM38 Forecast / Actual,6a - Milestones - Approvals,H44 -Approval MM38 Variance,6a - Milestones - Approvals,I44 -Approval MM38 Status,6a - Milestones - Approvals,J44 -Approval MM38 Notes,6a - Milestones - Approvals,K44 -Approval MM39,6a - Milestones - Approvals,D45 -Approval MM39 Gov Type,6a - Milestones - Approvals,E45 -Approval MM39 Ver No,6a - Milestones - Approvals,F45 -Approval MM39 Original Bobline,6a - Milestones - Approvals,G45 -Approval MM39 Forecast / Actual,6a - Milestones - Approvals,H45 -Approval MM39 Variance,6a - Milestones - Approvals,I45 -Approval MM39 Status,6a - Milestones - Approvals,J45 -Approval MM39 Notes,6a - Milestones - Approvals,K45 -Approval MM40,6a - Milestones - Approvals,D46 -Approval MM40 Gov Type,6a - Milestones - Approvals,E46 -Approval MM40 Ver No,6a - Milestones - Approvals,F46 -Approval MM40 Original Bobline,6a - Milestones - Approvals,G46 -Approval MM40 Forecast / Actual,6a - Milestones - Approvals,H46 -Approval MM40 Variance,6a - Milestones - Approvals,I46 -Approval MM40 Status,6a - Milestones - Approvals,J46 -Approval MM40 Notes,6a - Milestones - Approvals,K46 -Approval MM41,6a - Milestones - Approvals,D47 -Approval MM41 Gov Type,6a - Milestones - Approvals,E47 -Approval MM41 Ver No,6a - Milestones - Approvals,F47 -Approval MM41 Original Bobline,6a - Milestones - Approvals,G47 -Approval MM41 Forecast / Actual,6a - Milestones - Approvals,H47 -Approval MM41 Variance,6a - Milestones - Approvals,I47 -Approval MM41 Status,6a - Milestones - Approvals,J47 -Approval MM41 Notes,6a - Milestones - Approvals,K47 -Approval MM42,6a - Milestones - Approvals,D48 -Approval MM42 Gov Type,6a - Milestones - Approvals,E48 -Approval MM42 Ver No,6a - Milestones - Approvals,F48 -Approval MM42 Original Bobline,6a - Milestones - Approvals,G48 -Approval MM42 Forecast / Actual,6a - Milestones - Approvals,H48 -Approval MM42 Variance,6a - Milestones - Approvals,I48 -Approval MM42 Status,6a - Milestones - Approvals,J48 -Approval MM42 Notes,6a - Milestones - Approvals,K48 -Approval MM43,6a - Milestones - Approvals,D49 -Approval MM43 Gov Type,6a - Milestones - Approvals,E49 -Approval MM43 Ver No,6a - Milestones - Approvals,F49 -Approval MM43 Original Bobline,6a - Milestones - Approvals,G49 -Approval MM43 Forecast / Actual,6a - Milestones - Approvals,H49 -Approval MM43 Variance,6a - Milestones - Approvals,I49 -Approval MM43 Status,6a - Milestones - Approvals,J49 -Approval MM43 Notes,6a - Milestones - Approvals,K49 -Approval MM44,6a - Milestones - Approvals,D50 -Approval MM44 Gov Type,6a - Milestones - Approvals,E50 -Approval MM44 Ver No,6a - Milestones - Approvals,F50 -Approval MM44 Original Bobline,6a - Milestones - Approvals,G50 -Approval MM44 Forecast / Actual,6a - Milestones - Approvals,H50 -Approval MM44 Variance,6a - Milestones - Approvals,I50 -Approval MM44 Status,6a - Milestones - Approvals,J50 -Approval MM44 Notes,6a - Milestones - Approvals,K50 -Approval MM45,6a - Milestones - Approvals,D51 -Approval MM45 Gov Type,6a - Milestones - Approvals,E51 -Approval MM45 Ver No,6a - Milestones - Approvals,F51 -Approval MM45 Original Bobline,6a - Milestones - Approvals,G51 -Approval MM45 Forecast / Actual,6a - Milestones - Approvals,H51 -Approval MM45 Variance,6a - Milestones - Approvals,I51 -Approval MM45 Status,6a - Milestones - Approvals,J51 -Approval MM45 Notes,6a - Milestones - Approvals,K51 -Approval MM46,6a - Milestones - Approvals,D52 -Approval MM46 Gov Type,6a - Milestones - Approvals,E52 -Approval MM46 Ver No,6a - Milestones - Approvals,F52 -Approval MM46 Original Bobline,6a - Milestones - Approvals,G52 -Approval MM46 Forecast / Actual,6a - Milestones - Approvals,H52 -Approval MM46 Variance,6a - Milestones - Approvals,I52 -Approval MM46 Status,6a - Milestones - Approvals,J52 -Approval MM46 Notes,6a - Milestones - Approvals,K52 -Approval MM47,6a - Milestones - Approvals,D53 -Approval MM47 Gov Type,6a - Milestones - Approvals,E53 -Approval MM47 Ver No,6a - Milestones - Approvals,F53 -Approval MM47 Original Bobline,6a - Milestones - Approvals,G53 -Approval MM47 Forecast / Actual,6a - Milestones - Approvals,H53 -Approval MM47 Variance,6a - Milestones - Approvals,I53 -Approval MM47 Status,6a - Milestones - Approvals,J53 -Approval MM47 Notes,6a - Milestones - Approvals,K53 -Approval MM48,6a - Milestones - Approvals,D54 -Approval MM48 Gov Type,6a - Milestones - Approvals,E54 -Approval MM48 Ver No,6a - Milestones - Approvals,F54 -Approval MM48 Original Bobline,6a - Milestones - Approvals,G54 -Approval MM48 Forecast / Actual,6a - Milestones - Approvals,H54 -Approval MM48 Variance,6a - Milestones - Approvals,I54 -Approval MM48 Status,6a - Milestones - Approvals,J54 -Approval MM48 Notes,6a - Milestones - Approvals,K54 -Approval MM49,6a - Milestones - Approvals,D55 -Approval MM49 Gov Type,6a - Milestones - Approvals,E55 -Approval MM49 Ver No,6a - Milestones - Approvals,F55 -Approval MM49 Original Bobline,6a - Milestones - Approvals,G55 -Approval MM49 Forecast / Actual,6a - Milestones - Approvals,H55 -Approval MM49 Variance,6a - Milestones - Approvals,I55 -Approval MM49 Status,6a - Milestones - Approvals,J55 -Approval MM49 Notes,6a - Milestones - Approvals,K55 -Approval MM50,6a - Milestones - Approvals,D56 -Approval MM50 Gov Type,6a - Milestones - Approvals,E56 -Approval MM50 Ver No,6a - Milestones - Approvals,F56 -Approval MM50 Original Bobline,6a - Milestones - Approvals,G56 -Approval MM50 Forecast / Actual,6a - Milestones - Approvals,H56 -Approval MM50 Variance,6a - Milestones - Approvals,I56 -Approval MM50 Status,6a - Milestones - Approvals,J56 -Approval MM50 Notes,6a - Milestones - Approvals,K56 -BICC approval point,6a - Milestones - Approvals,F113 -Assurance MM1,6b - Milestones - Assurance,D7 -Assurance MM1 LoD,6b - Milestones - Assurance,E7 -Assurance MM1 Original Bobline,6b - Milestones - Assurance,F7 -Assurance MM1 Forecast - Actual,6b - Milestones - Assurance,G7 -Assurance MM1 Variance,6b - Milestones - Assurance,H7 -Assurance MM1 Status,6b - Milestones - Assurance,I7 -Assurance MM1 Notes,6b - Milestones - Assurance,J7 -Assurance MM2,6b - Milestones - Assurance,D8 -Assurance MM2 LoD,6b - Milestones - Assurance,E8 -Assurance MM2 Original Bobline,6b - Milestones - Assurance,F8 -Assurance MM2 Forecast - Actual,6b - Milestones - Assurance,G8 -Assurance MM2 Variance,6b - Milestones - Assurance,H8 -Assurance MM2 Status,6b - Milestones - Assurance,I8 -Assurance MM2 Notes,6b - Milestones - Assurance,J8 -Assurance MM3,6b - Milestones - Assurance,D9 -Assurance MM3 LoD,6b - Milestones - Assurance,E9 -Assurance MM3 Original Bobline,6b - Milestones - Assurance,F9 -Assurance MM3 Forecast - Actual,6b - Milestones - Assurance,G9 -Assurance MM3 Variance,6b - Milestones - Assurance,H9 -Assurance MM3 Status,6b - Milestones - Assurance,I9 -Assurance MM3 Notes,6b - Milestones - Assurance,J9 -Assurance MM4,6b - Milestones - Assurance,D10 -Assurance MM4 LoD,6b - Milestones - Assurance,E10 -Assurance MM4 Original Bobline,6b - Milestones - Assurance,F10 -Assurance MM4 Forecast - Actual,6b - Milestones - Assurance,G10 -Assurance MM4 Variance,6b - Milestones - Assurance,H10 -Assurance MM4 Status,6b - Milestones - Assurance,I10 -Assurance MM4 Notes,6b - Milestones - Assurance,J10 -Assurance MM5,6b - Milestones - Assurance,D11 -Assurance MM5 LoD,6b - Milestones - Assurance,E11 -Assurance MM5 Original Bobline,6b - Milestones - Assurance,F11 -Assurance MM5 Forecast - Actual,6b - Milestones - Assurance,G11 -Assurance MM5 Variance,6b - Milestones - Assurance,H11 -Assurance MM5 Status,6b - Milestones - Assurance,I11 -Assurance MM5 Notes,6b - Milestones - Assurance,J11 -Assurance MM6,6b - Milestones - Assurance,D12 -Assurance MM6 LoD,6b - Milestones - Assurance,E12 -Assurance MM6 Original Bobline,6b - Milestones - Assurance,F12 -Assurance MM6 Forecast - Actual,6b - Milestones - Assurance,G12 -Assurance MM6 Variance,6b - Milestones - Assurance,H12 -Assurance MM6 Status,6b - Milestones - Assurance,I12 -Assurance MM6 Notes,6b - Milestones - Assurance,J12 -Assurance MM7,6b - Milestones - Assurance,D13 -Assurance MM7 LoD,6b - Milestones - Assurance,E13 -Assurance MM7 Original Bobline,6b - Milestones - Assurance,F13 -Assurance MM7 Forecast - Actual,6b - Milestones - Assurance,G13 -Assurance MM7 Variance,6b - Milestones - Assurance,H13 -Assurance MM7 Status,6b - Milestones - Assurance,I13 -Assurance MM7 Notes,6b - Milestones - Assurance,J13 -Assurance MM8,6b - Milestones - Assurance,D14 -Assurance MM8 LoD,6b - Milestones - Assurance,E14 -Assurance MM8 Original Bobline,6b - Milestones - Assurance,F14 -Assurance MM8 Forecast - Actual,6b - Milestones - Assurance,G14 -Assurance MM8 Variance,6b - Milestones - Assurance,H14 -Assurance MM8 Status,6b - Milestones - Assurance,I14 -Assurance MM8 Notes,6b - Milestones - Assurance,J14 -Assurance MM9,6b - Milestones - Assurance,D15 -Assurance MM9 LoD,6b - Milestones - Assurance,E15 -Assurance MM9 Original Bobline,6b - Milestones - Assurance,F15 -Assurance MM9 Forecast - Actual,6b - Milestones - Assurance,G15 -Assurance MM9 Variance,6b - Milestones - Assurance,H15 -Assurance MM9 Status,6b - Milestones - Assurance,I15 -Assurance MM9 Notes,6b - Milestones - Assurance,J15 -Assurance MM10,6b - Milestones - Assurance,D16 -Assurance MM10 LoD,6b - Milestones - Assurance,E16 -Assurance MM10 Original Bobline,6b - Milestones - Assurance,F16 -Assurance MM10 Forecast - Actual,6b - Milestones - Assurance,G16 -Assurance MM10 Variance,6b - Milestones - Assurance,H16 -Assurance MM10 Status,6b - Milestones - Assurance,I16 -Assurance MM10 Notes,6b - Milestones - Assurance,J16 -Assurance MM11,6b - Milestones - Assurance,D17 -Assurance MM11 LoD,6b - Milestones - Assurance,E17 -Assurance MM11 Original Bobline,6b - Milestones - Assurance,F17 -Assurance MM11 Forecast - Actual,6b - Milestones - Assurance,G17 -Assurance MM11 Variance,6b - Milestones - Assurance,H17 -Assurance MM11 Status,6b - Milestones - Assurance,I17 -Assurance MM11 Notes,6b - Milestones - Assurance,J17 -Assurance MM12,6b - Milestones - Assurance,D18 -Assurance MM12 LoD,6b - Milestones - Assurance,E18 -Assurance MM12 Original Bobline,6b - Milestones - Assurance,F18 -Assurance MM12 Forecast - Actual,6b - Milestones - Assurance,G18 -Assurance MM12 Variance,6b - Milestones - Assurance,H18 -Assurance MM12 Status,6b - Milestones - Assurance,I18 -Assurance MM12 Notes,6b - Milestones - Assurance,J18 -Assurance MM13,6b - Milestones - Assurance,D19 -Assurance MM13 LoD,6b - Milestones - Assurance,E19 -Assurance MM13 Original Bobline,6b - Milestones - Assurance,F19 -Assurance MM13 Forecast - Actual,6b - Milestones - Assurance,G19 -Assurance MM13 Variance,6b - Milestones - Assurance,H19 -Assurance MM13 Status,6b - Milestones - Assurance,I19 -Assurance MM13 Notes,6b - Milestones - Assurance,J19 -Assurance MM14,6b - Milestones - Assurance,D20 -Assurance MM14 LoD,6b - Milestones - Assurance,E20 -Assurance MM14 Original Bobline,6b - Milestones - Assurance,F20 -Assurance MM14 Forecast - Actual,6b - Milestones - Assurance,G20 -Assurance MM14 Variance,6b - Milestones - Assurance,H20 -Assurance MM14 Status,6b - Milestones - Assurance,I20 -Assurance MM14 Notes,6b - Milestones - Assurance,J20 -Assurance MM15,6b - Milestones - Assurance,D21 -Assurance MM15 LoD,6b - Milestones - Assurance,E21 -Assurance MM15 Original Bobline,6b - Milestones - Assurance,F21 -Assurance MM15 Forecast - Actual,6b - Milestones - Assurance,G21 -Assurance MM15 Variance,6b - Milestones - Assurance,H21 -Assurance MM15 Status,6b - Milestones - Assurance,I21 -Assurance MM15 Notes,6b - Milestones - Assurance,J21 -Assurance MM16,6b - Milestones - Assurance,D22 -Assurance MM16 LoD,6b - Milestones - Assurance,E22 -Assurance MM16 Original Bobline,6b - Milestones - Assurance,F22 -Assurance MM16 Forecast - Actual,6b - Milestones - Assurance,G22 -Assurance MM16 Variance,6b - Milestones - Assurance,H22 -Assurance MM16 Status,6b - Milestones - Assurance,I22 -Assurance MM16 Notes,6b - Milestones - Assurance,J22 -Assurance MM17,6b - Milestones - Assurance,D23 -Assurance MM17 LoD,6b - Milestones - Assurance,E23 -Assurance MM17 Original Bobline,6b - Milestones - Assurance,F23 -Assurance MM17 Forecast - Actual,6b - Milestones - Assurance,G23 -Assurance MM17 Variance,6b - Milestones - Assurance,H23 -Assurance MM17 Status,6b - Milestones - Assurance,I23 -Assurance MM17 Notes,6b - Milestones - Assurance,J23 -Assurance MM18,6b - Milestones - Assurance,D24 -Assurance MM18 LoD,6b - Milestones - Assurance,E24 -Assurance MM18 Original Bobline,6b - Milestones - Assurance,F24 -Assurance MM18 Forecast - Actual,6b - Milestones - Assurance,G24 -Assurance MM18 Variance,6b - Milestones - Assurance,H24 -Assurance MM18 Status,6b - Milestones - Assurance,I24 -Assurance MM18 Notes,6b - Milestones - Assurance,J24 -Assurance MM19,6b - Milestones - Assurance,D25 -Assurance MM19 LoD,6b - Milestones - Assurance,E25 -Assurance MM19 Original Bobline,6b - Milestones - Assurance,F25 -Assurance MM19 Forecast - Actual,6b - Milestones - Assurance,G25 -Assurance MM19 Variance,6b - Milestones - Assurance,H25 -Assurance MM19 Status,6b - Milestones - Assurance,I25 -Assurance MM19 Notes,6b - Milestones - Assurance,J25 -Assurance MM20,6b - Milestones - Assurance,D26 -Assurance MM20 LoD,6b - Milestones - Assurance,E26 -Assurance MM20 Original Bobline,6b - Milestones - Assurance,F26 -Assurance MM20 Forecast - Actual,6b - Milestones - Assurance,G26 -Assurance MM20 Variance,6b - Milestones - Assurance,H26 -Assurance MM20 Status,6b - Milestones - Assurance,I26 -Assurance MM20 Notes,6b - Milestones - Assurance,J26 -Assurance MM21,6b - Milestones - Assurance,D27 -Assurance MM21 LoD,6b - Milestones - Assurance,E27 -Assurance MM21 Original Bobline,6b - Milestones - Assurance,F27 -Assurance MM21 Forecast - Actual,6b - Milestones - Assurance,G27 -Assurance MM21 Variance,6b - Milestones - Assurance,H27 -Assurance MM21 Status,6b - Milestones - Assurance,I27 -Assurance MM21 Notes,6b - Milestones - Assurance,J27 -Assurance MM22,6b - Milestones - Assurance,D28 -Assurance MM22 LoD,6b - Milestones - Assurance,E28 -Assurance MM22 Original Bobline,6b - Milestones - Assurance,F28 -Assurance MM22 Forecast - Actual,6b - Milestones - Assurance,G28 -Assurance MM22 Variance,6b - Milestones - Assurance,H28 -Assurance MM22 Status,6b - Milestones - Assurance,I28 -Assurance MM22 Notes,6b - Milestones - Assurance,J28 -Assurance MM23,6b - Milestones - Assurance,D29 -Assurance MM23 LoD,6b - Milestones - Assurance,E29 -Assurance MM23 Original Bobline,6b - Milestones - Assurance,F29 -Assurance MM23 Forecast - Actual,6b - Milestones - Assurance,G29 -Assurance MM23 Variance,6b - Milestones - Assurance,H29 -Assurance MM23 Status,6b - Milestones - Assurance,I29 -Assurance MM23 Notes,6b - Milestones - Assurance,J29 -Assurance MM24,6b - Milestones - Assurance,D30 -Assurance MM24 LoD,6b - Milestones - Assurance,E30 -Assurance MM24 Original Bobline,6b - Milestones - Assurance,F30 -Assurance MM24 Forecast - Actual,6b - Milestones - Assurance,G30 -Assurance MM24 Variance,6b - Milestones - Assurance,H30 -Assurance MM24 Status,6b - Milestones - Assurance,I30 -Assurance MM24 Notes,6b - Milestones - Assurance,J30 -Assurance MM25,6b - Milestones - Assurance,D31 -Assurance MM25 LoD,6b - Milestones - Assurance,E31 -Assurance MM25 Original Bobline,6b - Milestones - Assurance,F31 -Assurance MM25 Forecast - Actual,6b - Milestones - Assurance,G31 -Assurance MM25 Variance,6b - Milestones - Assurance,H31 -Assurance MM25 Status,6b - Milestones - Assurance,I31 -Assurance MM25 Notes,6b - Milestones - Assurance,J31 -Assurance MM26,6b - Milestones - Assurance,D32 -Assurance MM26 LoD,6b - Milestones - Assurance,E32 -Assurance MM26 Original Bobline,6b - Milestones - Assurance,F32 -Assurance MM26 Forecast - Actual,6b - Milestones - Assurance,G32 -Assurance MM26 Variance,6b - Milestones - Assurance,H32 -Assurance MM26 Status,6b - Milestones - Assurance,I32 -Assurance MM26 Notes,6b - Milestones - Assurance,J32 -Assurance MM27,6b - Milestones - Assurance,D33 -Assurance MM27 LoD,6b - Milestones - Assurance,E33 -Assurance MM27 Original Bobline,6b - Milestones - Assurance,F33 -Assurance MM27 Forecast - Actual,6b - Milestones - Assurance,G33 -Assurance MM27 Variance,6b - Milestones - Assurance,H33 -Assurance MM27 Status,6b - Milestones - Assurance,I33 -Assurance MM27 Notes,6b - Milestones - Assurance,J33 -Assurance MM28,6b - Milestones - Assurance,D34 -Assurance MM28 LoD,6b - Milestones - Assurance,E34 -Assurance MM28 Original Bobline,6b - Milestones - Assurance,F34 -Assurance MM28 Forecast - Actual,6b - Milestones - Assurance,G34 -Assurance MM28 Variance,6b - Milestones - Assurance,H34 -Assurance MM28 Status,6b - Milestones - Assurance,I34 -Assurance MM28 Notes,6b - Milestones - Assurance,J34 -Assurance MM29,6b - Milestones - Assurance,D35 -Assurance MM29 LoD,6b - Milestones - Assurance,E35 -Assurance MM29 Original Bobline,6b - Milestones - Assurance,F35 -Assurance MM29 Forecast - Actual,6b - Milestones - Assurance,G35 -Assurance MM29 Variance,6b - Milestones - Assurance,H35 -Assurance MM29 Status,6b - Milestones - Assurance,I35 -Assurance MM29 Notes,6b - Milestones - Assurance,J35 -Assurance MM30,6b - Milestones - Assurance,D36 -Assurance MM30 LoD,6b - Milestones - Assurance,E36 -Assurance MM30 Original Bobline,6b - Milestones - Assurance,F36 -Assurance MM30 Forecast - Actual,6b - Milestones - Assurance,G36 -Assurance MM30 Variance,6b - Milestones - Assurance,H36 -Assurance MM30 Status,6b - Milestones - Assurance,I36 -Assurance MM30 Notes,6b - Milestones - Assurance,J36 -Assurance MM31,6b - Milestones - Assurance,D37 -Assurance MM31 LoD,6b - Milestones - Assurance,E37 -Assurance MM31 Original Bobline,6b - Milestones - Assurance,F37 -Assurance MM31 Forecast - Actual,6b - Milestones - Assurance,G37 -Assurance MM31 Variance,6b - Milestones - Assurance,H37 -Assurance MM31 Status,6b - Milestones - Assurance,I37 -Assurance MM31 Notes,6b - Milestones - Assurance,J37 -Assurance MM32,6b - Milestones - Assurance,D38 -Assurance MM32 LoD,6b - Milestones - Assurance,E38 -Assurance MM32 Original Bobline,6b - Milestones - Assurance,F38 -Assurance MM32 Forecast - Actual,6b - Milestones - Assurance,G38 -Assurance MM32 Variance,6b - Milestones - Assurance,H38 -Assurance MM32 Status,6b - Milestones - Assurance,I38 -Assurance MM32 Notes,6b - Milestones - Assurance,J38 -Assurance MM33,6b - Milestones - Assurance,D39 -Assurance MM33 LoD,6b - Milestones - Assurance,E39 -Assurance MM33 Original Bobline,6b - Milestones - Assurance,F39 -Assurance MM33 Forecast - Actual,6b - Milestones - Assurance,G39 -Assurance MM33 Variance,6b - Milestones - Assurance,H39 -Assurance MM33 Status,6b - Milestones - Assurance,I39 -Assurance MM33 Notes,6b - Milestones - Assurance,J39 -Assurance MM34,6b - Milestones - Assurance,D40 -Assurance MM34 LoD,6b - Milestones - Assurance,E40 -Assurance MM34 Original Bobline,6b - Milestones - Assurance,F40 -Assurance MM34 Forecast - Actual,6b - Milestones - Assurance,G40 -Assurance MM34 Variance,6b - Milestones - Assurance,H40 -Assurance MM34 Status,6b - Milestones - Assurance,I40 -Assurance MM34 Notes,6b - Milestones - Assurance,J40 -Assurance MM35,6b - Milestones - Assurance,D41 -Assurance MM35 LoD,6b - Milestones - Assurance,E41 -Assurance MM35 Original Bobline,6b - Milestones - Assurance,F41 -Assurance MM35 Forecast - Actual,6b - Milestones - Assurance,G41 -Assurance MM35 Variance,6b - Milestones - Assurance,H41 -Assurance MM35 Status,6b - Milestones - Assurance,I41 -Assurance MM35 Notes,6b - Milestones - Assurance,J41 -Assurance MM36,6b - Milestones - Assurance,D42 -Assurance MM36 LoD,6b - Milestones - Assurance,E42 -Assurance MM36 Original Bobline,6b - Milestones - Assurance,F42 -Assurance MM36 Forecast - Actual,6b - Milestones - Assurance,G42 -Assurance MM36 Variance,6b - Milestones - Assurance,H42 -Assurance MM36 Status,6b - Milestones - Assurance,I42 -Assurance MM36 Notes,6b - Milestones - Assurance,J42 -Assurance MM37,6b - Milestones - Assurance,D43 -Assurance MM37 LoD,6b - Milestones - Assurance,E43 -Assurance MM37 Original Bobline,6b - Milestones - Assurance,F43 -Assurance MM37 Forecast - Actual,6b - Milestones - Assurance,G43 -Assurance MM37 Variance,6b - Milestones - Assurance,H43 -Assurance MM37 Status,6b - Milestones - Assurance,I43 -Assurance MM37 Notes,6b - Milestones - Assurance,J43 -Assurance MM38,6b - Milestones - Assurance,D44 -Assurance MM38 LoD,6b - Milestones - Assurance,E44 -Assurance MM38 Original Bobline,6b - Milestones - Assurance,F44 -Assurance MM38 Forecast - Actual,6b - Milestones - Assurance,G44 -Assurance MM38 Variance,6b - Milestones - Assurance,H44 -Assurance MM38 Status,6b - Milestones - Assurance,I44 -Assurance MM38 Notes,6b - Milestones - Assurance,J44 -Assurance MM39,6b - Milestones - Assurance,D45 -Assurance MM39 LoD,6b - Milestones - Assurance,E45 -Assurance MM39 Original Bobline,6b - Milestones - Assurance,F45 -Assurance MM39 Forecast - Actual,6b - Milestones - Assurance,G45 -Assurance MM39 Variance,6b - Milestones - Assurance,H45 -Assurance MM39 Status,6b - Milestones - Assurance,I45 -Assurance MM39 Notes,6b - Milestones - Assurance,J45 -Assurance MM40,6b - Milestones - Assurance,D46 -Assurance MM40 LoD,6b - Milestones - Assurance,E46 -Assurance MM40 Original Bobline,6b - Milestones - Assurance,F46 -Assurance MM40 Forecast - Actual,6b - Milestones - Assurance,G46 -Assurance MM40 Variance,6b - Milestones - Assurance,H46 -Assurance MM40 Status,6b - Milestones - Assurance,I46 -Assurance MM40 Notes,6b - Milestones - Assurance,J46 -Assurance MM41,6b - Milestones - Assurance,D47 -Assurance MM41 LoD,6b - Milestones - Assurance,E47 -Assurance MM41 Original Bobline,6b - Milestones - Assurance,F47 -Assurance MM41 Forecast - Actual,6b - Milestones - Assurance,G47 -Assurance MM41 Variance,6b - Milestones - Assurance,H47 -Assurance MM41 Status,6b - Milestones - Assurance,I47 -Assurance MM41 Notes,6b - Milestones - Assurance,J47 -Assurance MM42,6b - Milestones - Assurance,D48 -Assurance MM42 LoD,6b - Milestones - Assurance,E48 -Assurance MM42 Original Bobline,6b - Milestones - Assurance,F48 -Assurance MM42 Forecast - Actual,6b - Milestones - Assurance,G48 -Assurance MM42 Variance,6b - Milestones - Assurance,H48 -Assurance MM42 Status,6b - Milestones - Assurance,I48 -Assurance MM42 Notes,6b - Milestones - Assurance,J48 -Assurance MM43,6b - Milestones - Assurance,D49 -Assurance MM43 LoD,6b - Milestones - Assurance,E49 -Assurance MM43 Original Bobline,6b - Milestones - Assurance,F49 -Assurance MM43 Forecast - Actual,6b - Milestones - Assurance,G49 -Assurance MM43 Variance,6b - Milestones - Assurance,H49 -Assurance MM43 Status,6b - Milestones - Assurance,I49 -Assurance MM43 Notes,6b - Milestones - Assurance,J49 -Assurance MM44,6b - Milestones - Assurance,D50 -Assurance MM44 LoD,6b - Milestones - Assurance,E50 -Assurance MM44 Original Bobline,6b - Milestones - Assurance,F50 -Assurance MM44 Forecast - Actual,6b - Milestones - Assurance,G50 -Assurance MM44 Variance,6b - Milestones - Assurance,H50 -Assurance MM44 Status,6b - Milestones - Assurance,I50 -Assurance MM44 Notes,6b - Milestones - Assurance,J50 -Assurance MM45,6b - Milestones - Assurance,D51 -Assurance MM45 LoD,6b - Milestones - Assurance,E51 -Assurance MM45 Original Bobline,6b - Milestones - Assurance,F51 -Assurance MM45 Forecast - Actual,6b - Milestones - Assurance,G51 -Assurance MM45 Variance,6b - Milestones - Assurance,H51 -Assurance MM45 Status,6b - Milestones - Assurance,I51 -Assurance MM45 Notes,6b - Milestones - Assurance,J51 -Assurance MM46,6b - Milestones - Assurance,D52 -Assurance MM46 LoD,6b - Milestones - Assurance,E52 -Assurance MM46 Original Bobline,6b - Milestones - Assurance,F52 -Assurance MM46 Forecast - Actual,6b - Milestones - Assurance,G52 -Assurance MM46 Variance,6b - Milestones - Assurance,H52 -Assurance MM46 Status,6b - Milestones - Assurance,I52 -Assurance MM46 Notes,6b - Milestones - Assurance,J52 -Assurance MM47,6b - Milestones - Assurance,D53 -Assurance MM47 LoD,6b - Milestones - Assurance,E53 -Assurance MM47 Original Bobline,6b - Milestones - Assurance,F53 -Assurance MM47 Forecast - Actual,6b - Milestones - Assurance,G53 -Assurance MM47 Variance,6b - Milestones - Assurance,H53 -Assurance MM47 Status,6b - Milestones - Assurance,I53 -Assurance MM47 Notes,6b - Milestones - Assurance,J53 -Assurance MM48,6b - Milestones - Assurance,D54 -Assurance MM48 LoD,6b - Milestones - Assurance,E54 -Assurance MM48 Original Bobline,6b - Milestones - Assurance,F54 -Assurance MM48 Forecast - Actual,6b - Milestones - Assurance,G54 -Assurance MM48 Variance,6b - Milestones - Assurance,H54 -Assurance MM48 Status,6b - Milestones - Assurance,I54 -Assurance MM48 Notes,6b - Milestones - Assurance,J54 -Assurance MM49,6b - Milestones - Assurance,D55 -Assurance MM49 LoD,6b - Milestones - Assurance,E55 -Assurance MM49 Original Bobline,6b - Milestones - Assurance,F55 -Assurance MM49 Forecast - Actual,6b - Milestones - Assurance,G55 -Assurance MM49 Variance,6b - Milestones - Assurance,H55 -Assurance MM49 Status,6b - Milestones - Assurance,I55 -Assurance MM49 Notes,6b - Milestones - Assurance,J55 -Assurance MM50,6b - Milestones - Assurance,D56 -Assurance MM50 LoD,6b - Milestones - Assurance,E56 -Assurance MM50 Original Bobline,6b - Milestones - Assurance,F56 -Assurance MM50 Forecast - Actual,6b - Milestones - Assurance,G56 -Assurance MM50 Variance,6b - Milestones - Assurance,H56 -Assurance MM50 Status,6b - Milestones - Assurance,I56 -Assurance MM50 Notes,6b - Milestones - Assurance,J56 -Project MM18,6c - Milestones - Delivery,D7 -Project MM18 CP,6c - Milestones - Delivery,E7 -Project MM18 Original Bobline,6c - Milestones - Delivery,F7 -Project MM18 Forecast - Actual,6c - Milestones - Delivery,G7 -Project MM18 Variance,6c - Milestones - Delivery,H7 -Project MM18 Status,6c - Milestones - Delivery,I7 -Project MM18 Notes,6c - Milestones - Delivery,J7 -Project MM19,6c - Milestones - Delivery,D8 -Project MM19 CP,6c - Milestones - Delivery,E8 -Project MM19 Original Bobline,6c - Milestones - Delivery,F8 -Project MM19 Forecast - Actual,6c - Milestones - Delivery,G8 -Project MM19 Variance,6c - Milestones - Delivery,H8 -Project MM19 Status,6c - Milestones - Delivery,I8 -Project MM19 Notes,6c - Milestones - Delivery,J8 -Project MM20,6c - Milestones - Delivery,D9 -Project MM20 CP,6c - Milestones - Delivery,E9 -Project MM20 Original Bobline,6c - Milestones - Delivery,F9 -Project MM20 Forecast - Actual,6c - Milestones - Delivery,G9 -Project MM20 Variance,6c - Milestones - Delivery,H9 -Project MM20 Status,6c - Milestones - Delivery,I9 -Project MM20 Notes,6c - Milestones - Delivery,J9 -Project MM21,6c - Milestones - Delivery,D10 -Project MM21 CP,6c - Milestones - Delivery,E10 -Project MM21 Original Bobline,6c - Milestones - Delivery,F10 -Project MM21 Forecast - Actual,6c - Milestones - Delivery,G10 -Project MM21 Variance,6c - Milestones - Delivery,H10 -Project MM21 Status,6c - Milestones - Delivery,I10 -Project MM21 Notes,6c - Milestones - Delivery,J10 -Project MM22,6c - Milestones - Delivery,D11 -Project MM22 CP,6c - Milestones - Delivery,E11 -Project MM22 Original Bobline,6c - Milestones - Delivery,F11 -Project MM22 Forecast - Actual,6c - Milestones - Delivery,G11 -Project MM22 Variance,6c - Milestones - Delivery,H11 -Project MM22 Status,6c - Milestones - Delivery,I11 -Project MM22 Notes,6c - Milestones - Delivery,J11 -Project MM23,6c - Milestones - Delivery,D12 -Project MM23 CP,6c - Milestones - Delivery,E12 -Project MM23 Original Bobline,6c - Milestones - Delivery,F12 -Project MM23 Forecast - Actual,6c - Milestones - Delivery,G12 -Project MM23 Variance,6c - Milestones - Delivery,H12 -Project MM23 Status,6c - Milestones - Delivery,I12 -Project MM23 Notes,6c - Milestones - Delivery,J12 -Project MM24,6c - Milestones - Delivery,D13 -Project MM24 CP,6c - Milestones - Delivery,E13 -Project MM24 Original Bobline,6c - Milestones - Delivery,F13 -Project MM24 Forecast - Actual,6c - Milestones - Delivery,G13 -Project MM24 Variance,6c - Milestones - Delivery,H13 -Project MM24 Status,6c - Milestones - Delivery,I13 -Project MM24 Notes,6c - Milestones - Delivery,J13 -Project MM25,6c - Milestones - Delivery,D14 -Project MM25 CP,6c - Milestones - Delivery,E14 -Project MM25 Original Bobline,6c - Milestones - Delivery,F14 -Project MM25 Forecast - Actual,6c - Milestones - Delivery,G14 -Project MM25 Variance,6c - Milestones - Delivery,H14 -Project MM25 Status,6c - Milestones - Delivery,I14 -Project MM25 Notes,6c - Milestones - Delivery,J14 -Project MM26,6c - Milestones - Delivery,D15 -Project MM26 CP,6c - Milestones - Delivery,E15 -Project MM26 Original Bobline,6c - Milestones - Delivery,F15 -Project MM26 Forecast - Actual,6c - Milestones - Delivery,G15 -Project MM26 Variance,6c - Milestones - Delivery,H15 -Project MM26 Status,6c - Milestones - Delivery,I15 -Project MM26 Notes,6c - Milestones - Delivery,J15 -Project MM27,6c - Milestones - Delivery,D16 -Project MM27 CP,6c - Milestones - Delivery,E16 -Project MM27 Original Bobline,6c - Milestones - Delivery,F16 -Project MM27 Forecast - Actual,6c - Milestones - Delivery,G16 -Project MM27 Variance,6c - Milestones - Delivery,H16 -Project MM27 Status,6c - Milestones - Delivery,I16 -Project MM27 Notes,6c - Milestones - Delivery,J16 -Project MM28,6c - Milestones - Delivery,D17 -Project MM28 CP,6c - Milestones - Delivery,E17 -Project MM28 Original Bobline,6c - Milestones - Delivery,F17 -Project MM28 Forecast - Actual,6c - Milestones - Delivery,G17 -Project MM28 Variance,6c - Milestones - Delivery,H17 -Project MM28 Status,6c - Milestones - Delivery,I17 -Project MM28 Notes,6c - Milestones - Delivery,J17 -Project MM29,6c - Milestones - Delivery,D18 -Project MM29 CP,6c - Milestones - Delivery,E18 -Project MM29 Original Bobline,6c - Milestones - Delivery,F18 -Project MM29 Forecast - Actual,6c - Milestones - Delivery,G18 -Project MM29 Variance,6c - Milestones - Delivery,H18 -Project MM29 Status,6c - Milestones - Delivery,I18 -Project MM29 Notes,6c - Milestones - Delivery,J18 -Project MM30,6c - Milestones - Delivery,D19 -Project MM30 CP,6c - Milestones - Delivery,E19 -Project MM30 Original Bobline,6c - Milestones - Delivery,F19 -Project MM30 Forecast - Actual,6c - Milestones - Delivery,G19 -Project MM30 Variance,6c - Milestones - Delivery,H19 -Project MM30 Status,6c - Milestones - Delivery,I19 -Project MM30 Notes,6c - Milestones - Delivery,J19 -Project MM31,6c - Milestones - Delivery,D20 -Project MM31 CP,6c - Milestones - Delivery,E20 -Project MM31 Original Bobline,6c - Milestones - Delivery,F20 -Project MM31 Forecast - Actual,6c - Milestones - Delivery,G20 -Project MM31 Variance,6c - Milestones - Delivery,H20 -Project MM31 Status,6c - Milestones - Delivery,I20 -Project MM31 Notes,6c - Milestones - Delivery,J20 -Project MM32,6c - Milestones - Delivery,D21 -Project MM32 CP,6c - Milestones - Delivery,E21 -Project MM32 Original Bobline,6c - Milestones - Delivery,F21 -Project MM32 Forecast - Actual,6c - Milestones - Delivery,G21 -Project MM32 Variance,6c - Milestones - Delivery,H21 -Project MM32 Status,6c - Milestones - Delivery,I21 -Project MM32 Notes,6c - Milestones - Delivery,J21 -Project MM33,6c - Milestones - Delivery,D22 -Project MM33 CP,6c - Milestones - Delivery,E22 -Project MM33 Original Bobline,6c - Milestones - Delivery,F22 -Project MM33 Forecast - Actual,6c - Milestones - Delivery,G22 -Project MM33 Variance,6c - Milestones - Delivery,H22 -Project MM33 Status,6c - Milestones - Delivery,I22 -Project MM33 Notes,6c - Milestones - Delivery,J22 -Project MM34,6c - Milestones - Delivery,D23 -Project MM34 CP,6c - Milestones - Delivery,E23 -Project MM34 Original Bobline,6c - Milestones - Delivery,F23 -Project MM34 Forecast - Actual,6c - Milestones - Delivery,G23 -Project MM34 Variance,6c - Milestones - Delivery,H23 -Project MM34 Status,6c - Milestones - Delivery,I23 -Project MM34 Notes,6c - Milestones - Delivery,J23 -Project MM35,6c - Milestones - Delivery,D24 -Project MM35 CP,6c - Milestones - Delivery,E24 -Project MM35 Original Bobline,6c - Milestones - Delivery,F24 -Project MM35 Forecast - Actual,6c - Milestones - Delivery,G24 -Project MM35 Variance,6c - Milestones - Delivery,H24 -Project MM35 Status,6c - Milestones - Delivery,I24 -Project MM35 Notes,6c - Milestones - Delivery,J24 -Project MM36,6c - Milestones - Delivery,D25 -Project MM36 CP,6c - Milestones - Delivery,E25 -Project MM36 Original Bobline,6c - Milestones - Delivery,F25 -Project MM36 Forecast - Actual,6c - Milestones - Delivery,G25 -Project MM36 Variance,6c - Milestones - Delivery,H25 -Project MM36 Status,6c - Milestones - Delivery,I25 -Project MM36 Notes,6c - Milestones - Delivery,J25 -Project MM37,6c - Milestones - Delivery,D26 -Project MM37 CP,6c - Milestones - Delivery,E26 -Project MM37 Original Bobline,6c - Milestones - Delivery,F26 -Project MM37 Forecast - Actual,6c - Milestones - Delivery,G26 -Project MM37 Variance,6c - Milestones - Delivery,H26 -Project MM37 Status,6c - Milestones - Delivery,I26 -Project MM37 Notes,6c - Milestones - Delivery,J26 -Project MM38,6c - Milestones - Delivery,D27 -Project MM38 CP,6c - Milestones - Delivery,E27 -Project MM38 Original Bobline,6c - Milestones - Delivery,F27 -Project MM38 Forecast - Actual,6c - Milestones - Delivery,G27 -Project MM38 Variance,6c - Milestones - Delivery,H27 -Project MM38 Status,6c - Milestones - Delivery,I27 -Project MM38 Notes,6c - Milestones - Delivery,J27 -Project MM39,6c - Milestones - Delivery,D28 -Project MM39 CP,6c - Milestones - Delivery,E28 -Project MM39 Original Bobline,6c - Milestones - Delivery,F28 -Project MM39 Forecast - Actual,6c - Milestones - Delivery,G28 -Project MM39 Variance,6c - Milestones - Delivery,H28 -Project MM39 Status,6c - Milestones - Delivery,I28 -Project MM39 Notes,6c - Milestones - Delivery,J28 -Project MM40,6c - Milestones - Delivery,D29 -Project MM40 CP,6c - Milestones - Delivery,E29 -Project MM40 Original Bobline,6c - Milestones - Delivery,F29 -Project MM40 Forecast - Actual,6c - Milestones - Delivery,G29 -Project MM40 Variance,6c - Milestones - Delivery,H29 -Project MM40 Status,6c - Milestones - Delivery,I29 -Project MM40 Notes,6c - Milestones - Delivery,J29 -Project MM41,6c - Milestones - Delivery,D30 -Project MM41 CP,6c - Milestones - Delivery,E30 -Project MM41 Original Bobline,6c - Milestones - Delivery,F30 -Project MM41 Forecast - Actual,6c - Milestones - Delivery,G30 -Project MM41 Variance,6c - Milestones - Delivery,H30 -Project MM41 Status,6c - Milestones - Delivery,I30 -Project MM41 Notes,6c - Milestones - Delivery,J30 -Project MM42,6c - Milestones - Delivery,D31 -Project MM42 CP,6c - Milestones - Delivery,E31 -Project MM42 Original Bobline,6c - Milestones - Delivery,F31 -Project MM42 Forecast - Actual,6c - Milestones - Delivery,G31 -Project MM42 Variance,6c - Milestones - Delivery,H31 -Project MM42 Status,6c - Milestones - Delivery,I31 -Project MM42 Notes,6c - Milestones - Delivery,J31 -Project MM43,6c - Milestones - Delivery,D32 -Project MM43 CP,6c - Milestones - Delivery,E32 -Project MM43 Original Bobline,6c - Milestones - Delivery,F32 -Project MM43 Forecast - Actual,6c - Milestones - Delivery,G32 -Project MM43 Variance,6c - Milestones - Delivery,H32 -Project MM43 Status,6c - Milestones - Delivery,I32 -Project MM43 Notes,6c - Milestones - Delivery,J32 -Project MM44,6c - Milestones - Delivery,D33 -Project MM44 CP,6c - Milestones - Delivery,E33 -Project MM44 Original Bobline,6c - Milestones - Delivery,F33 -Project MM44 Forecast - Actual,6c - Milestones - Delivery,G33 -Project MM44 Variance,6c - Milestones - Delivery,H33 -Project MM44 Status,6c - Milestones - Delivery,I33 -Project MM44 Notes,6c - Milestones - Delivery,J33 -Project MM45,6c - Milestones - Delivery,D34 -Project MM45 CP,6c - Milestones - Delivery,E34 -Project MM45 Original Bobline,6c - Milestones - Delivery,F34 -Project MM45 Forecast - Actual,6c - Milestones - Delivery,G34 -Project MM45 Variance,6c - Milestones - Delivery,H34 -Project MM45 Status,6c - Milestones - Delivery,I34 -Project MM45 Notes,6c - Milestones - Delivery,J34 -Project MM46,6c - Milestones - Delivery,D35 -Project MM46 CP,6c - Milestones - Delivery,E35 -Project MM46 Original Bobline,6c - Milestones - Delivery,F35 -Project MM46 Forecast - Actual,6c - Milestones - Delivery,G35 -Project MM46 Variance,6c - Milestones - Delivery,H35 -Project MM46 Status,6c - Milestones - Delivery,I35 -Project MM46 Notes,6c - Milestones - Delivery,J35 -Project MM47,6c - Milestones - Delivery,D36 -Project MM47 CP,6c - Milestones - Delivery,E36 -Project MM47 Original Bobline,6c - Milestones - Delivery,F36 -Project MM47 Forecast - Actual,6c - Milestones - Delivery,G36 -Project MM47 Variance,6c - Milestones - Delivery,H36 -Project MM47 Status,6c - Milestones - Delivery,I36 -Project MM47 Notes,6c - Milestones - Delivery,J36 -Project MM48 ,6c - Milestones - Delivery,D37 -Project MM48 CP,6c - Milestones - Delivery,E37 -Project MM48 Original Bobline,6c - Milestones - Delivery,F37 -Project MM48 Forecast - Actual,6c - Milestones - Delivery,G37 -Project MM48 Variance,6c - Milestones - Delivery,H37 -Project MM48 Status,6c - Milestones - Delivery,I37 -Project MM48 Notes,6c - Milestones - Delivery,J37 -Project MM49,6c - Milestones - Delivery,D38 -Project MM49 CP,6c - Milestones - Delivery,E38 -Project MM49 Original Bobline,6c - Milestones - Delivery,F38 -Project MM49 Forecast - Actual,6c - Milestones - Delivery,G38 -Project MM49 Variance,6c - Milestones - Delivery,H38 -Project MM49 Status,6c - Milestones - Delivery,I38 -Project MM49 Notes,6c - Milestones - Delivery,J38 -Project MM50,6c - Milestones - Delivery,D39 -Project MM50 CP,6c - Milestones - Delivery,E39 -Project MM50 Original Bobline,6c - Milestones - Delivery,F39 -Project MM50 Forecast - Actual,6c - Milestones - Delivery,G39 -Project MM50 Variance,6c - Milestones - Delivery,H39 -Project MM50 Status,6c - Milestones - Delivery,I39 -Project MM50 Notes,6c - Milestones - Delivery,J39 -Project MM51,6c - Milestones - Delivery,D40 -Project MM51 CP,6c - Milestones - Delivery,E40 -Project MM51 Original Bobline,6c - Milestones - Delivery,F40 -Project MM51 Forecast - Actual,6c - Milestones - Delivery,G40 -Project MM51 Variance,6c - Milestones - Delivery,H40 -Project MM51 Status,6c - Milestones - Delivery,I40 -Project MM51 Notes,6c - Milestones - Delivery,J40 -Project MM52,6c - Milestones - Delivery,D41 -Project MM52 CP,6c - Milestones - Delivery,E41 -Project MM52 Original Bobline,6c - Milestones - Delivery,F41 -Project MM52 Forecast - Actual,6c - Milestones - Delivery,G41 -Project MM52 Variance,6c - Milestones - Delivery,H41 -Project MM52 Status,6c - Milestones - Delivery,I41 -Project MM52 Notes,6c - Milestones - Delivery,J41 -Project MM53,6c - Milestones - Delivery,D42 -Project MM53 CP,6c - Milestones - Delivery,E42 -Project MM53 Original Bobline,6c - Milestones - Delivery,F42 -Project MM53 Forecast - Actual,6c - Milestones - Delivery,G42 -Project MM53 Variance,6c - Milestones - Delivery,H42 -Project MM53 Status,6c - Milestones - Delivery,I42 -Project MM53 Notes,6c - Milestones - Delivery,J42 -Project MM54,6c - Milestones - Delivery,D43 -Project MM54 CP,6c - Milestones - Delivery,E43 -Project MM54 Original Bobline,6c - Milestones - Delivery,F43 -Project MM54 Forecast - Actual,6c - Milestones - Delivery,G43 -Project MM54 Variance,6c - Milestones - Delivery,H43 -Project MM54 Status,6c - Milestones - Delivery,I43 -Project MM54 Notes,6c - Milestones - Delivery,J43 -Project MM55,6c - Milestones - Delivery,D44 -Project MM55 CP,6c - Milestones - Delivery,E44 -Project MM55 Original Bobline,6c - Milestones - Delivery,F44 -Project MM55 Forecast - Actual,6c - Milestones - Delivery,G44 -Project MM55 Variance,6c - Milestones - Delivery,H44 -Project MM55 Status,6c - Milestones - Delivery,I44 -Project MM55 Notes,6c - Milestones - Delivery,J44 -Project MM56,6c - Milestones - Delivery,D45 -Project MM56 CP,6c - Milestones - Delivery,E45 -Project MM56 Original Bobline,6c - Milestones - Delivery,F45 -Project MM56 Forecast - Actual,6c - Milestones - Delivery,G45 -Project MM56 Variance,6c - Milestones - Delivery,H45 -Project MM56 Status,6c - Milestones - Delivery,I45 -Project MM56 Notes,6c - Milestones - Delivery,J45 -Project MM57,6c - Milestones - Delivery,D46 -Project MM57 CP,6c - Milestones - Delivery,E46 -Project MM57 Original Bobline,6c - Milestones - Delivery,F46 -Project MM57 Forecast - Actual,6c - Milestones - Delivery,G46 -Project MM57 Variance,6c - Milestones - Delivery,H46 -Project MM57 Status,6c - Milestones - Delivery,I46 -Project MM57 Notes,6c - Milestones - Delivery,J46 -Project MM58,6c - Milestones - Delivery,D47 -Project MM58 CP,6c - Milestones - Delivery,E47 -Project MM58 Original Bobline,6c - Milestones - Delivery,F47 -Project MM58 Forecast - Actual,6c - Milestones - Delivery,G47 -Project MM58 Variance,6c - Milestones - Delivery,H47 -Project MM58 Status,6c - Milestones - Delivery,I47 -Project MM58 Notes,6c - Milestones - Delivery,J47 -Project MM59,6c - Milestones - Delivery,D48 -Project MM59 CP,6c - Milestones - Delivery,E48 -Project MM59 Original Bobline,6c - Milestones - Delivery,F48 -Project MM59 Forecast - Actual,6c - Milestones - Delivery,G48 -Project MM59 Variance,6c - Milestones - Delivery,H48 -Project MM59 Status,6c - Milestones - Delivery,I48 -Project MM59 Notes,6c - Milestones - Delivery,J48 -Project MM60,6c - Milestones - Delivery,D49 -Project MM60 CP,6c - Milestones - Delivery,E49 -Project MM60 Original Bobline,6c - Milestones - Delivery,F49 -Project MM60 Forecast - Actual,6c - Milestones - Delivery,G49 -Project MM60 Variance,6c - Milestones - Delivery,H49 -Project MM60 Status,6c - Milestones - Delivery,I49 -Project MM60 Notes,6c - Milestones - Delivery,J49 -Project MM61,6c - Milestones - Delivery,D50 -Project MM61 CP,6c - Milestones - Delivery,E50 -Project MM61 Original Bobline,6c - Milestones - Delivery,F50 -Project MM61 Forecast - Actual,6c - Milestones - Delivery,G50 -Project MM61 Variance,6c - Milestones - Delivery,H50 -Project MM61 Status,6c - Milestones - Delivery,I50 -Project MM61 Notes,6c - Milestones - Delivery,J50 -Project MM62,6c - Milestones - Delivery,D51 -Project MM62 CP,6c - Milestones - Delivery,E51 -Project MM62 Original Bobline,6c - Milestones - Delivery,F51 -Project MM62 Forecast - Actual,6c - Milestones - Delivery,G51 -Project MM62 Variance,6c - Milestones - Delivery,H51 -Project MM62 Status,6c - Milestones - Delivery,I51 -Project MM62 Notes,6c - Milestones - Delivery,J51 -Project MM63,6c - Milestones - Delivery,D52 -Project MM63 CP,6c - Milestones - Delivery,E52 -Project MM63 Original Bobline,6c - Milestones - Delivery,F52 -Project MM63 Forecast - Actual,6c - Milestones - Delivery,G52 -Project MM63 Variance,6c - Milestones - Delivery,H52 -Project MM63 Status,6c - Milestones - Delivery,I52 -Project MM63 Notes,6c - Milestones - Delivery,J52 -Project MM64,6c - Milestones - Delivery,D53 -Project MM64 CP,6c - Milestones - Delivery,E53 -Project MM64 Original Bobline,6c - Milestones - Delivery,F53 -Project MM64 Forecast - Actual,6c - Milestones - Delivery,G53 -Project MM64 Variance,6c - Milestones - Delivery,H53 -Project MM64 Status,6c - Milestones - Delivery,I53 -Project MM64 Notes,6c - Milestones - Delivery,J53 -Project MM65,6c - Milestones - Delivery,D54 -Project MM65 CP,6c - Milestones - Delivery,E54 -Project MM65 Original Bobline,6c - Milestones - Delivery,F54 -Project MM65 Forecast - Actual,6c - Milestones - Delivery,G54 -Project MM65 Variance,6c - Milestones - Delivery,H54 -Project MM65 Status,6c - Milestones - Delivery,I54 -Project MM65 Notes,6c - Milestones - Delivery,J54 -Project MM66,6c - Milestones - Delivery,D55 -Project MM66 CP,6c - Milestones - Delivery,E55 -Project MM66 Original Bobline,6c - Milestones - Delivery,F55 -Project MM66 Forecast - Actual,6c - Milestones - Delivery,G55 -Project MM66 Variance,6c - Milestones - Delivery,H55 -Project MM66 Status,6c - Milestones - Delivery,I55 -Project MM66 Notes,6c - Milestones - Delivery,J55 -Project MM67,6c - Milestones - Delivery,D56 -Project MM67 CP,6c - Milestones - Delivery,E56 -Project MM67 Original Bobline,6c - Milestones - Delivery,F56 -Project MM67 Forecast - Actual,6c - Milestones - Delivery,G56 -Project MM67 Variance,6c - Milestones - Delivery,H56 -Project MM67 Status,6c - Milestones - Delivery,I56 -Project MM67 Notes,6c - Milestones - Delivery,J56 -Milestone Commentary,6c - Milestones - Delivery,F110 -SRO Schedule Confidence,6c - Milestones - Delivery,F109 -Project stage,7 - Business Case,E6 -Project Stage if Other,7 - Business Case,E7 -Latest Treasury Approval Point (TAP) or equivalent,7 - Business Case,E10 -Version Number Of Document used to Source Figures (DRRDD - TAP version Number),7 - Business Case,E11 -Business Case & Version No.,7 - Business Case,E12 -Date of TAP used to source figures,7 - Business Case,E13 -"If no HMT Business Case, please advise why?",7 - Business Case,E14 -"Is your HMT Business case updated / approved annually by HMT, or more frequently?",7 - Business Case,E15 -Does the HMT Businesss Case cover the full life of the project?,7 - Business Case,E16 -"If not, please provide explanation as to why",7 - Business Case,E17 -"If not, please advise how many years are covered",7 - Business Case,E18 -"If not, please advise how much cost is covered, as a percentage",7 - Business Case,E19 -Are the baselines in this return from the most recent HMT Approved Business Case?,7 - Business Case,E20 -"If not, what is the source of baselines in this returns?",7 - Business Case,E21 -"If not, please give a reason why baselines",7 - Business Case,E22 -What is the source of all forecasts in this return?,7 - Business Case,E23 -"Please provide details of any formal arrangement with HMT regarding Business cases, that are outside the classical model",7 - Business Case,E24 -BC One Off new costs,7 - Business Case,E29 -BC Recurring new costs,7 - Business Case,F29 -BC Recurring old costs,7 - Business Case,G29 -BC Non Government costs,7 - Business Case,H29 -BC Income,7 - Business Case,I29 -BC Cashable benefits,7 - Business Case,E31 -BC Non-Cashable benefits,7 - Business Case,F31 -BC UK Economic benefits,7 - Business Case,G31 -BC Disbenefits in the cost section,7 - Business Case,H31 -BC Positive AME benefits in Cashable,7 - Business Case,I31 -BC Non Monetised Benefits,7 - Business Case,J31 -Real or Nominal - Bobline,8 - Finance,E6 -Real or Nominal - Actual/Forecast,8 - Finance,E7 -Index Year,8 - Finance,E8 -Deflator,8 - Finance,E9 -Are you reporting the full costs of the project?,8 - Finance,E10 -"If no, please provide reason why?",8 - Finance,E11 -Does this project create income?,8 - Finance,E14 -Who recieves the income?,8 - Finance,E15 -Do you net the income with your costs in the DRRDD return,8 - Finance,E16 -Income Against which Cost category?,8 - Finance,E17 -Income Bobline - Real or Nominal,8 - Finance,E18 -Income Forecast - Real or Nominal,8 - Finance,E19 -"Income If real, Index Year used?",8 - Finance,E20 -"Income If real, Deflator used?",8 - Finance,E21 -Are you reporting the full income of the project?,8 - Finance,E22 -"Income If no, please provide reason why?",8 - Finance,E23 -Does this project create monetised benefits?,8 - Finance,E26 -Benefits Bobline - Real or Nominal,8 - Finance,E27 -Benefits Forecast - Real or Nominal,8 - Finance,E28 -"Benefits If real, Index Year used?",8 - Finance,E29 -"Benefits If real, Deflator used?",8 - Finance,E30 -Are you reporting the full benefits of the project?,8 - Finance,E31 -"Benefits If no, please provide reason why?",8 - Finance,E32 -Source of Finance,8 - Finance,E35 -Other Finance type Description,8 - Finance,E36 -Optimism Bias Percentage Used in Cost Boblines,8 - Finance,E37 -Overall figure for Optimism Bias (£m),8 - Finance,E38 -Built in contingency (% of Whole Life Cost),8 - Finance,E39 -Overall contingency (£m),8 - Finance,E40 -NPV for all projects and NPV for programmes if available,8 - Finance,E41 -Internal Rate of Return (IRR),8 - Finance,E42 -Adjusted Benefits Cost Ratio (BCR),8 - Finance,E43 -Benefits Map,8 - Finance,E47 -Benefits Analysed,8 - Finance,E48 -Benefits Realisation Plan,8 - Finance,E49 -Initial Benefits Cost Ratio (BCR),8 - Finance,E44 -VfM Category,8 - Finance,E50 -Present Value Cost (PVC),8 - Finance,E45 -Present Value Benefit (PVB),8 - Finance,E46 -Project Costs Narrative,9 - Costs,E6 -Cost comparison with last quarters cost - narrative ,9 - Costs,E7 -Cost comparison within this quarters cost - narrative ,9 - Costs,E8 -Total Budget/BL,9 - Costs,F20 -Total Forecast,9 - Costs,H20 -Pre 19-20 TDEL BL one off new costs,9 - Costs,E27 -Pre 19-20 TDEL BL recurring new costs,9 - Costs,F27 -Pre 19-20 TDEL BL recurring old costs,9 - Costs,G27 -Pre 19-20 TDEL BL Non Gov costs,9 - Costs,H27 -Pre 19-20 TDEL BL Total,9 - Costs,I27 -Pre 19-20 TDEL BL Income,9 - Costs,L27 -Pre 19-20 TDEL Forecast one off new costs,9 - Costs,E28 -Pre 19-20 TDEL Forecast recurring new costs,9 - Costs,F28 -Pre 19-20 TDEL Forecast recurring old costs,9 - Costs,G28 -Pre 19-20 TDEL Forecast Non Gov costs,9 - Costs,H28 -Pre 19-20 TDEL Forecast Total,9 - Costs,I28 -Pre 19-20 TDEL Forecast Income,9 - Costs,L28 -19-20 TDEL BL one off new costs,9 - Costs,E29 -19-20 TDEL BL recurring new costs,9 - Costs,F29 -19-20 TDEL BL recurring old costs,9 - Costs,G29 -19-20 TDEL BL Non Gov costs,9 - Costs,H29 -19-20 TDEL BL Total,9 - Costs,I29 -19-20 TDEL BL Income,9 - Costs,L29 -19-20 TDEL Forecast one off new costs,9 - Costs,E30 -19-20 TDEL Forecast recurring new costs,9 - Costs,F30 -19-20 TDEL Forecast recurring old costs,9 - Costs,G30 -19-20 TDEL Forecast Non Gov costs,9 - Costs,H30 -19-20 TDEL Forecast Total,9 - Costs,I30 -19-20 TDEL Forecast Income,9 - Costs,L30 -20-21 TDEL BL one off new costs,9 - Costs,E31 -20-21 TDEL BL recurring new costs,9 - Costs,F31 -20-21 TDEL BL recurring old costs,9 - Costs,G31 -20-21 TDEL BL Non Gov costs,9 - Costs,H31 -20-21 TDEL BL Total,9 - Costs,I31 -20-21 TDEL BL Income,9 - Costs,L31 -20-21 TDEL Forecast one off new costs,9 - Costs,E32 -20-21 TDEL Forecast recurring new costs,9 - Costs,F32 -20-21 TDEL Forecast recurring old costs,9 - Costs,G32 -20-21 TDEL Forecast Non Gov costs,9 - Costs,H32 -20-21 TDEL Forecast Total,9 - Costs,I32 -20-21 TDEL Forecast Income,9 - Costs,L32 -21-22 TDEL BL one off new costs,9 - Costs,E33 -21-22 TDEL BL recurring new costs,9 - Costs,F33 -21-22 TDEL BL recurring old costs,9 - Costs,G33 -21-22 TDEL BL Non Gov costs,9 - Costs,H33 -21-22 TDEL BL Total,9 - Costs,I33 -21-22 TDEL BL Income,9 - Costs,L33 -21-22 TDEL Forecast one off new costs,9 - Costs,E34 -21-22 TDEL Forecast recurring new costs,9 - Costs,F34 -21-22 TDEL Forecast recurring old costs,9 - Costs,G34 -21-22 TDEL Forecast Non Gov costs,9 - Costs,H34 -21-22 TDEL Forecast Total,9 - Costs,I34 -21-22 TDEL Forecast Income,9 - Costs,L34 -22-23 TDEL BL one off new costs,9 - Costs,E35 -22-23 TDEL BL recurring new costs,9 - Costs,F35 -22-23 TDEL BL recurring old costs,9 - Costs,G35 -22-23 TDEL BL Non Gov costs,9 - Costs,H35 -22-23 TDEL BL Total,9 - Costs,I35 -22-23 TDEL BL Income,9 - Costs,L35 -22-23 TDEL Forecast one off new costs,9 - Costs,E36 -22-23 TDEL Forecast recurring new costs,9 - Costs,F36 -22-23 TDEL Forecast recurring old costs,9 - Costs,G36 -22-23 TDEL Forecast Non Gov costs,9 - Costs,H36 -22-23 TDEL Forecast Total,9 - Costs,I36 -22-23 TDEL Forecast Income,9 - Costs,L36 -23-24 TDEL BL one off new costs,9 - Costs,E37 -23-24 TDEL BL recurring new costs,9 - Costs,F37 -23-24 TDEL BL recurring old costs,9 - Costs,G37 -23-24 TDEL BL Non Gov costs,9 - Costs,H37 -23-24 TDEL BL Total,9 - Costs,I37 -23-24 TDEL BL Income,9 - Costs,L37 -23-24 TDEL Forecast one off new costs,9 - Costs,E38 -23-24 TDEL Forecast recurring new costs,9 - Costs,F38 -23-24 TDEL Forecast recurring old costs,9 - Costs,G38 -23-24 TDEL Forecast Non Gov costs,9 - Costs,H38 -23-24 TDEL Forecast Total,9 - Costs,I38 -23-24 TDEL Forecast Income,9 - Costs,L38 -24-25 TDEL BL one off new costs,9 - Costs,E39 -24-25 TDEL BL recurring new costs,9 - Costs,F39 -24-25 TDEL BL recurring old costs,9 - Costs,G39 -24-25 TDEL BL Non Gov costs,9 - Costs,H39 -24-25 TDEL BL Total,9 - Costs,I39 -24-25 TDEL BL Income,9 - Costs,L39 -24-25 TDEL Forecast one off new costs,9 - Costs,E40 -24-25 TDEL Forecast recurring new costs,9 - Costs,F40 -24-25 TDEL Forecast recurring old costs,9 - Costs,G40 -24-25 TDEL Forecast Non Gov costs,9 - Costs,H40 -24-25 TDEL Forecast Total,9 - Costs,I40 -24-25 TDEL Forecast Income,9 - Costs,L40 -25-26 TDEL BL one off new costs,9 - Costs,E41 -25-26 TDEL BL recurring new costs,9 - Costs,F41 -25-26 TDEL BL recurring old costs,9 - Costs,G41 -25-26 TDEL BL Non Gov costs,9 - Costs,H41 -25-26 TDEL BL Total,9 - Costs,I41 -25-26 TDEL BL Income,9 - Costs,L41 -25-26 TDEL Forecast one off new costs,9 - Costs,E42 -25-26 TDEL Forecast recurring new costs,9 - Costs,F42 -25-26 TDEL Forecast recurring old costs,9 - Costs,G42 -25-26 TDEL Forecast Non Gov costs,9 - Costs,H42 -25-26 TDEL Forecast Total,9 - Costs,I42 -25-26 TDEL Forecast Income,9 - Costs,L42 -26-27 TDEL BL one off new costs,9 - Costs,E43 -26-27 TDEL BL recurring new costs,9 - Costs,F43 -26-27 TDEL BL recurring old costs,9 - Costs,G43 -26-27 TDEL BL Non Gov costs,9 - Costs,H43 -26-27 TDEL BL Total,9 - Costs,I43 -26-27 TDEL BL Income,9 - Costs,L43 -26-27 TDEL Forecast one off new costs,9 - Costs,E44 -26-27 TDEL Forecast recurring new costs,9 - Costs,F44 -26-27 TDEL Forecast recurring old costs,9 - Costs,G44 -26-27 TDEL Forecast Non Gov costs,9 - Costs,H44 -26-27 TDEL Forecast Total,9 - Costs,I44 -26-27 TDEL Forecast Income,9 - Costs,L44 -27-28 TDEL BL one off new costs,9 - Costs,E45 -27-28 TDEL BL recurring new costs,9 - Costs,F45 -27-28 TDEL BL recurring old costs,9 - Costs,G45 -27-28 TDEL BL Non Gov costs,9 - Costs,H45 -27-28 TDEL BL Total,9 - Costs,I45 -27-28 TDEL BL Income,9 - Costs,L45 -27-28 TDEL Forecast one off new costs,9 - Costs,E46 -27-28 TDEL Forecast recurring new costs,9 - Costs,F46 -27-28 TDEL Forecast recurring old costs,9 - Costs,G46 -27-28 TDEL Forecast Non Gov costs,9 - Costs,H46 -27-28 TDEL Forecast Total,9 - Costs,I46 -27-28 TDEL Forecast Income,9 - Costs,L46 -28-29 TDEL BL one off new costs,9 - Costs,E47 -28-29 TDEL BL recurring new costs,9 - Costs,F47 -28-29 TDEL BL recurring old costs,9 - Costs,G47 -28-29 TDEL BL Non Gov costs,9 - Costs,H47 -28-29 TDEL BL Total,9 - Costs,I47 -28-29 TDEL BL Income,9 - Costs,L47 -28-29 TDEL Forecast one off new costs,9 - Costs,E48 -28-29 TDEL Forecast recurring new costs,9 - Costs,F48 -28-29 TDEL Forecast recurring old costs,9 - Costs,G48 -28-29 TDEL Forecast Non Gov costs,9 - Costs,H48 -28-29 TDEL Forecast Total,9 - Costs,I48 -28-29 TDEL Forecast Income,9 - Costs,L48 -Unprofiled TDEL BL one off new costs,9 - Costs,E49 -Unprofiled TDEL BL recurring new costs,9 - Costs,F49 -Unprofiled TDEL BL recurring old costs,9 - Costs,G49 -Unprofiled TDEL BL Non Gov costs,9 - Costs,H49 -Unprofiled TDEL BL Total,9 - Costs,I49 -Unprofiled TDEL BL Income,9 - Costs,L49 -Unprofiled TDEL Forecast one off new costs,9 - Costs,E50 -Unprofiled TDEL Forecast recurring new costs,9 - Costs,F50 -Unprofiled TDEL Forecast recurring old costs,9 - Costs,G50 -Unprofiled TDEL Forecast Non Gov costs,9 - Costs,H50 -Unprofiled TDEL Forecast Total,9 - Costs,I50 -Unprofiled TDEL Forecast Income,9 - Costs,L50 -Total TDEL BL one off new costs,9 - Costs,E51 -Total TDEL BL recurring new costs,9 - Costs,F51 -Total TDEL BL recurring old costs,9 - Costs,G51 -Total TDEL BL Non Gov costs,9 - Costs,H51 -Total TDEL BL Total,9 - Costs,I51 -Total TDEL BL Income,9 - Costs,L51 -Total TDEL Forecast one off new costs,9 - Costs,E52 -Total TDEL Forecast recurring new costs,9 - Costs,F52 -Total TDEL Forecast recurring old costs,9 - Costs,G52 -Total TDEL Forecast Non Gov costs,9 - Costs,H52 -Total TDEL Forecast Total,9 - Costs,I52 -Total TDEL Forecast Income,9 - Costs,L52 -Year TDEL spend stops,9 - Costs,E53 -Pre 19-20 CDEL BL one off new costs,9 - Costs,E56 -Pre 19-20 CDEL BL recurring new costs,9 - Costs,F56 -Pre 19-20 CDEL BL recurring old costs,9 - Costs,G56 -Pre 19-20 BL Non-Gov,9 - Costs,H56 -Pre 19-20 CDEL BL WLC,9 - Costs,I56 -Pre 19-20 BL Income both Revenue and Capital,9 - Costs,L56 -Pre 19-20 CDEL Forecast Total,9 - Costs,E57 -Pre 19-20 CDEL Forecast recurring new costs,9 - Costs,F57 -Pre 19-20 CDEL Forecast recurring old costs,9 - Costs,G57 -Pre 19-20 Forecast Non-Gov,9 - Costs,H57 -Pre 19-20 CDEL Forecast Total WLC,9 - Costs,I57 -Pre 19-20 Actual Income both Revenue and Capital,9 - Costs,L57 -19-20 CDEL BL one off new costs,9 - Costs,E58 -19-20 CDEL BL recurring new costs,9 - Costs,F58 -19-20 CDEL BL recurring old costs,9 - Costs,G58 -19-20 BL Non-Gov,9 - Costs,H58 -19-20 CDEL BL WLC,9 - Costs,I58 -19-20 BL Income both Revenue and Capital,9 - Costs,L58 -19-20 CDEL Forecast Total,9 - Costs,E59 -19-20 CDEL Forecast recurring new costs,9 - Costs,F59 -19-20 CDEL Forecast recurring old costs,9 - Costs,G59 -19-20 Forecast Non-Gov,9 - Costs,H59 -19-20 CDEL Forecast Total WLC,9 - Costs,I59 -19-20 Forecast - Income both Revenue and Capital,9 - Costs,L59 -20-21 CDEL BL one off new costs,9 - Costs,E60 -20-21 CDEL BL recurring new costs,9 - Costs,F60 -20-21 CDEL BL recurring old costs,9 - Costs,G60 -20-21 BL Non-Gov,9 - Costs,H60 -20-21 CDEL BL WLC,9 - Costs,I60 -20-21 BL Income both Revenue and Capital,9 - Costs,L60 -20-21 CDEL Forecast Total,9 - Costs,E61 -20-21 CDEL Forecast recurring new costs,9 - Costs,F61 -20-21 CDEL Forecast recurring old costs,9 - Costs,G61 -20-21 Forecast Non-Gov,9 - Costs,H61 -20-21 CDEL Forecast Total WLC,9 - Costs,I61 -20-21 Forecast - Income both Revenue and Capital,9 - Costs,L61 -21-22 CDEL BL one off new costs,9 - Costs,E62 -21-22 CDEL BL recurring new costs,9 - Costs,F62 -21-22 CDEL BL recurring old costs,9 - Costs,G62 -21-22 BL Non-Gov,9 - Costs,H62 -21-22 CDEL BL WLC,9 - Costs,I62 -21-22 BL - Income both Revenue and Capital,9 - Costs,L62 -21-22 CDEL Forecast Total,9 - Costs,E63 -21-22 CDEL Forecast recurring new costs,9 - Costs,F63 -21-22 CDEL Forecast recurring old costs,9 - Costs,G63 -21-22 Forecast Non-Gov,9 - Costs,H63 -21-22 CDEL Forecast Total WLC,9 - Costs,I63 -21-22 Forecast - Income both Revenue and Capital,9 - Costs,L63 -22-23 CDEL BL one off new costs,9 - Costs,E64 -22-23 CDEL BL recurring new costs,9 - Costs,F64 -22-23 CDEL BL recurring old costs,9 - Costs,G64 -22-23 BL Non-Gov,9 - Costs,H64 -22-23 CDEL BL WLC,9 - Costs,I64 -22-23 BL Income both Revenue and Capital,9 - Costs,L64 -22-23 CDEL Forecast Total,9 - Costs,E65 -22-23 CDEL Forecast recurring new costs,9 - Costs,F65 -22-23 CDEL Forecast recurring old costs,9 - Costs,G65 -22-23 Forecast Non-Gov,9 - Costs,H65 -22-23 CDEL Forecast Total WLC,9 - Costs,I65 -22-23 Forecast - Income both Revenue and Capital,9 - Costs,L65 -23-24 CDEL BL one off new costs,9 - Costs,E66 -23-24 CDEL BL recurring new costs,9 - Costs,F66 -23-24 CDEL BL recurring old costs,9 - Costs,G66 -23-24 BL Non-Gov,9 - Costs,H66 -23-24 CDEL BL WLC,9 - Costs,I66 -23-24 BL Income both Revenue and Capital,9 - Costs,L66 -23-24 CDEL Forecast Total,9 - Costs,E67 -23-24 CDEL Forecast recurring new costs,9 - Costs,F67 -23-24 CDEL Forecast recurring old costs,9 - Costs,G67 -23-24 Forecast Non-Gov,9 - Costs,H67 -23-24 CDEL Forecast Total WLC,9 - Costs,I67 -23-24 Forecast - Income both Revenue and Capital,9 - Costs,L67 -24-25 CDEL BL one off new costs,9 - Costs,E68 -24-25 CDEL BL recurring new costs,9 - Costs,F68 -24-25 CDEL BL recurring old costs,9 - Costs,G68 -24-25 BL Non-Gov,9 - Costs,H68 -24-25 CDEL BL WLC,9 - Costs,I68 -24-25 BL Income both Revenue and Capital,9 - Costs,L68 -24-25 CDEL Forecast Total,9 - Costs,E69 -24-25 CDEL Forecast recurring new costs,9 - Costs,F69 -24-25 CDEL Forecast recurring old costs,9 - Costs,G69 -24-25 Forecast Non-Gov,9 - Costs,H69 -24-25 CDEL Forecast Total WLC,9 - Costs,I69 -24-25 Forecast - Income both Revenue and Capital,9 - Costs,L69 -25-26 CDEL BL one off new costs,9 - Costs,E70 -25-26 CDEL BL recurring new costs,9 - Costs,F70 -25-26 CDEL BL recurring old costs,9 - Costs,G70 -25-26 BL Non-Gov,9 - Costs,H70 -25-26 CDEL BL WLC,9 - Costs,I70 -25-26 BL Income both Revenue and Capital,9 - Costs,L70 -25-26 CDEL Forecast Total,9 - Costs,E71 -25-26 CDEL Forecast recurring new costs,9 - Costs,F71 -25-26 CDEL Forecast recurring old costs,9 - Costs,G71 -25-26 Forecast Non-Gov,9 - Costs,H71 -25-26 CDEL Forecast Total WLC,9 - Costs,I71 -25-26 Forecast - Income both Revenue and Capital,9 - Costs,L71 -26-27 CDEL BL one off new costs,9 - Costs,E72 -26-27 CDEL BL recurring new costs,9 - Costs,F72 -26-27 CDEL BL recurring old costs,9 - Costs,G72 -26-27 BL Non-Gov,9 - Costs,H72 -26-27 CDEL BL WLC,9 - Costs,I72 -26-27 BL Income both Revenue and Capital,9 - Costs,L72 -26-27 CDEL Forecast Total,9 - Costs,E73 -26-27 CDEL Forecast recurring new costs,9 - Costs,F73 -26-27 CDEL Forecast recurring old costs,9 - Costs,G73 -26-27 Forecast Non-Gov,9 - Costs,H73 -26-27 CDEL Forecast Total WLC,9 - Costs,I73 -26-27 Forecast - Income both Revenue and Capital,9 - Costs,L73 -27-28 CDEL BL one off new costs,9 - Costs,E74 -27-28 CDEL BL recurring new costs,9 - Costs,F74 -27-28 CDEL BL recurring old costs,9 - Costs,G74 -27-28 BL Non-Gov,9 - Costs,H74 -27-28 CDEL BL WLC,9 - Costs,I74 -27-28 BL Income both Revenue and Capital,9 - Costs,L74 -27-28 CDEL Forecast Total,9 - Costs,E75 -27-28 CDEL Forecast recurring new costs,9 - Costs,F75 -27-28 CDEL Forecast recurring old costs,9 - Costs,G75 -27-28 Forecast Non-Gov,9 - Costs,H75 -27-28 CDEL Forecast Total WLC,9 - Costs,I75 -27-28 Forecast - Income both Revenue and Capital,9 - Costs,L75 -28-29 CDEL BL one off new costs,9 - Costs,E76 -28-29 CDEL BL recurring new costs,9 - Costs,F76 -28-29 CDEL BL recurring old costs,9 - Costs,G76 -28-29 BL Non-Gov,9 - Costs,H76 -28-29 CDEL BL WLC,9 - Costs,I76 -28-29 BL Income both Revenue and Capital,9 - Costs,L76 -28-29 CDEL Forecast Total,9 - Costs,E77 -28-29 CDEL Forecast recurring new costs,9 - Costs,F77 -28-29 CDEL Forecast recurring old costs,9 - Costs,G77 -28-29 Forecast Non-Gov,9 - Costs,H77 -28-29 CDEL Forecast Total WLC,9 - Costs,I77 -28-29 Forecast - Income both Revenue and Capital,9 - Costs,L77 -Unprofiled CDEL BL one off new costs,9 - Costs,E78 -Unprofiled CDEL BL recurring new costs,9 - Costs,F78 -Unprofiled CDEL BL recurring old costs,9 - Costs,G78 -Unprofiled BL Non-Gov,9 - Costs,H78 -Unprofiled CDEL BL WLC,9 - Costs,I78 -Unprofiled BL Income,9 - Costs,L78 -Unprofiled CDEL Forecast Total,9 - Costs,E79 -Unprofiled CDEL Forecast recurring new costs,9 - Costs,F79 -Unprofiled CDEL Forecast recurring old costs,9 - Costs,G79 -Unprofiled Forecast-Gov,9 - Costs,H79 -Unprofiled CDEL Forecast Total WLC,9 - Costs,I79 -Unprofiled Forecast Income,9 - Costs,L79 -Total CDEL BL one off new costs,9 - Costs,E80 -Total CDEL BL recurring new costs,9 - Costs,F80 -Total CDEL BL recurring old costs,9 - Costs,G80 -Non-Gov Total Budget/BL,9 - Costs,H80 -Total CDEL BL WLC,9 - Costs,I80 -Total Bobline - Income both Revenue and Capital,9 - Costs,L80 -Total CDEL Forecast Total,9 - Costs,E81 -Total CDEL Forecast recurring new costs,9 - Costs,F81 -Total CDEL Forecast recurring old costs,9 - Costs,G81 -Non-Gov Total Forecast,9 - Costs,H81 -Total CDEL Forecast Total WLC,9 - Costs,I81 -Total Forecast - Income both Revenue and Capital,9 - Costs,L81 -Year CDEL spend stops,9 - Costs,E82 -SRO Finance confidence,9 - Costs,E118 -Benefits Narrative,10 - Benefits,E6 -Ben comparison with last quarters cost - narrative ,10 - Benefits,E7 -Ben comparison within this quarters cost - narrative ,10 - Benefits,E8 -Narrative on any project Non-Monetised benefits,10 - Benefits,E9 -"If benefits profile (by years) not provided, please provide reason and date for when they will be",10 - Benefits,E10 -Pre 19-20 BEN Bobline - Gov. Cashable,10 - Benefits,E25 -Pre 19-20 BEN Bobline - Gov. Non-Cashable,10 - Benefits,F25 -Pre 19-20 BEN Bobline - Economic (inc Private Partner),10 - Benefits,G25 -Pre 19-20 BEN Bobline - Disbenefit UK Economic,10 - Benefits,H25 -Pre 19-20 BEN Bobline - Total Monetised Benefits,10 - Benefits,K25 -Pre 19-20 BEN Forecast - Gov. Cashable,10 - Benefits,E26 -Pre 19-20 BEN Forecast - Gov. Non-Cashable,10 - Benefits,F26 -Pre 19-20 BEN Forecast - Economic (inc Private Partner),10 - Benefits,G26 -Pre 19-20 BEN Forecast - Disbenefit UK Economic,10 - Benefits,H26 -Pre 19-20 BEN Forecast - Total Monetised Benefits,10 - Benefits,K26 -19-20 BEN Bobline - Gov. Cashable,10 - Benefits,E27 -19-20 BEN Bobline - Gov. Non-Cashable,10 - Benefits,F27 -19-20 BEN Bobline - Economic (inc Private Partner),10 - Benefits,G27 -19-20 BEN Bobline - Disbenefit UK Economic,10 - Benefits,H27 -19-20 BEN Bobline - Total Monetised Benefits,10 - Benefits,K27 -19-20 BEN Forecast - Gov. Cashable,10 - Benefits,E28 -19-20 BEN Forecast - Gov. Non-Cashable,10 - Benefits,F28 -19-20 BEN Forecast - Economic (inc Private Partner),10 - Benefits,G28 -19-20 BEN Forecast - Disbenefit UK Economic,10 - Benefits,H28 -19-20 BEN Forecast - Total Monetised Benefits,10 - Benefits,K28 -20-21 BEN Bobline - Gov. Cashable,10 - Benefits,E29 -20-21 BEN Bobline - Gov. Non-Cashable,10 - Benefits,F29 -20-21 BEN Bobline - Economic (inc Private Partner),10 - Benefits,G29 -20-21 BEN Bobline - Disbenefit UK Economic,10 - Benefits,H29 -20-21 BEN Bobline - Total Monetised Benefits,10 - Benefits,K29 -20-21 BEN Forecast - Gov. Cashable,10 - Benefits,E30 -20-21 BEN Forecast - Gov. Non-Cashable,10 - Benefits,F30 -20-21 BEN Forecast - Economic (inc Private Partner),10 - Benefits,G30 -20-21 BEN Forecast - Disbenefit UK Economic,10 - Benefits,H30 -20-21 BEN Forecast - Total Monetised Benefits,10 - Benefits,K30 -21-22 BEN Bobline - Gov. Cashable,10 - Benefits,E31 -21-22 BEN Bobline - Gov. Non-Cashable,10 - Benefits,F31 -21-22 BEN Bobline - Economic (inc Private Partner),10 - Benefits,G31 -21-22 BEN Bobline - Disbenefit UK Economic,10 - Benefits,H31 -21-22 BEN Bobline - Total Monetised Benefits,10 - Benefits,K31 -21-22 BEN Forecast - Gov. Cashable,10 - Benefits,E32 -21-22 BEN Forecast - Gov. Non-Cashable,10 - Benefits,F32 -21-22 BEN Forecast - Economic (inc Private Partner),10 - Benefits,G32 -21-22 BEN Forecast - Disbenefit UK Economic,10 - Benefits,H32 -21-22 BEN Forecast - Total Monetised Benefits,10 - Benefits,K32 -22-23 BEN Bobline - Gov. Cashable,10 - Benefits,E33 -22-23 BEN Bobline - Gov. Non-Cashable,10 - Benefits,F33 -22-23 BEN Bobline - Economic (inc Private Partner),10 - Benefits,G33 -22-23 BEN Bobline - Disbenefit UK Economic,10 - Benefits,H33 -22-23 BEN Bobline - Total Monetised Benefits,10 - Benefits,K33 -22-23 BEN Forecast - Gov. Cashable,10 - Benefits,E34 -22-23 BEN Forecast - Gov. Non-Cashable,10 - Benefits,F34 -22-23 BEN Forecast - Economic (inc Private Partner),10 - Benefits,G34 -22-23 BEN Forecast - Disbenefit UK Economic,10 - Benefits,H34 -22-23 BEN Forecast - Total Monetised Benefits,10 - Benefits,K34 -23-24 BEN Bobline - Gov. Cashable,10 - Benefits,E35 -23-24 BEN Bobline - Gov. Non-Cashable,10 - Benefits,F35 -23-24 BEN Bobline - Economic (inc Private Partner),10 - Benefits,G35 -23-24 BEN Bobline - Disbenefit UK Economic,10 - Benefits,H35 -23-24 BEN Bobline - Total Monetised Benefits,10 - Benefits,K35 -23-24 BEN Forecast - Gov. Cashable,10 - Benefits,E36 -23-24 BEN Forecast - Gov. Non-Cashable,10 - Benefits,F36 -23-24 BEN Forecast - Economic (inc Private Partner),10 - Benefits,G36 -23-24 BEN Forecast - Disbenefit UK Economic,10 - Benefits,H36 -23-24 BEN Forecast - Total Monetised Benefits,10 - Benefits,K36 -24-25 BEN Bobline - Gov. Cashable,10 - Benefits,E37 -24-25 BEN Bobline - Gov. Non-Cashable,10 - Benefits,F37 -24-25 BEN Bobline - Economic (inc Private Partner),10 - Benefits,G37 -24-25 BEN Bobline - Disbenefit UK Economic,10 - Benefits,H37 -24-25 BEN Bobline - Total Monetised Benefits,10 - Benefits,K37 -24-25 BEN Forecast - Gov. Cashable,10 - Benefits,E38 -24-25 BEN Forecast - Gov. Non-Cashable,10 - Benefits,F38 -24-25 BEN Forecast - Economic (inc Private Partner),10 - Benefits,G38 -24-25 BEN Forecast - Disbenefit UK Economic,10 - Benefits,H38 -24-25 BEN Forecast - Total Monetised Benefits,10 - Benefits,K38 -25-26 BEN Bobline - Gov. Cashable,10 - Benefits,E39 -25-26 BEN Bobline - Gov. Non-Cashable,10 - Benefits,F39 -25-26 BEN Bobline - Economic (inc Private Partner),10 - Benefits,G39 -25-26 BEN Bobline - Disbenefit UK Economic,10 - Benefits,H39 -25-26 BEN Bobline - Total Monetised Benefits,10 - Benefits,K39 -25-26 BEN Forecast - Gov. Cashable,10 - Benefits,E40 -25-26 BEN Forecast - Gov. Non-Cashable,10 - Benefits,F40 -25-26 BEN Forecast - Economic (inc Private Partner),10 - Benefits,G40 -25-26 BEN Forecast - Disbenefit UK Economic,10 - Benefits,H40 -25-26 BEN Forecast - Total Monetised Benefits,10 - Benefits,K40 -26-27 BEN Bobline - Gov. Cashable,10 - Benefits,E41 -26-27 BEN Bobline - Gov. Non-Cashable,10 - Benefits,F41 -26-27 BEN Bobline - Economic (inc Private Partner),10 - Benefits,G41 -26-27 BEN Bobline - Disbenefit UK Economic,10 - Benefits,H41 -26-27 BEN Bobline - Total Monetised Benefits,10 - Benefits,K41 -26-27 BEN Forecast - Gov. Cashable,10 - Benefits,E42 -26-27 BEN Forecast - Gov. Non-Cashable,10 - Benefits,F42 -26-27 BEN Forecast - Economic (inc Private Partner),10 - Benefits,G42 -26-27 BEN Forecast - Disbenefit UK Economic,10 - Benefits,H42 -26-27 BEN Forecast - Total Monetised Benefits,10 - Benefits,K42 -27-28 BEN Bobline - Gov. Cashable,10 - Benefits,E43 -27-28 BEN Bobline - Gov. Non-Cashable,10 - Benefits,F43 -27-28 BEN Bobline - Economic (inc Private Partner),10 - Benefits,G43 -27-28 BEN Bobline - Disbenefit UK Economic,10 - Benefits,H43 -27-28 BEN Bobline - Total Monetised Benefits,10 - Benefits,K43 -27-28 BEN Forecast - Gov. Cashable,10 - Benefits,E44 -27-28 BEN Forecast - Gov. Non-Cashable,10 - Benefits,F44 -27-28 BEN Forecast - Economic (inc Private Partner),10 - Benefits,G44 -27-28 BEN Forecast - Disbenefit UK Economic,10 - Benefits,H44 -27-28 BEN Forecast - Total Monetised Benefits,10 - Benefits,K44 -28-29 BEN Bobline - Gov. Cashable,10 - Benefits,E45 -28-29 BEN Bobline - Gov. Non-Cashable,10 - Benefits,F45 -28-29 BEN Bobline - Economic (inc Private Partner),10 - Benefits,G45 -28-29 BEN Bobline - Disbenefit UK Economic,10 - Benefits,H45 -28-29 BEN Bobline - Total Monetised Benefits,10 - Benefits,K45 -28-29 BEN Forecast - Gov. Cashable,10 - Benefits,E46 -28-29 BEN Forecast - Gov. Non-Cashable,10 - Benefits,F46 -28-29 BEN Forecast - Economic (inc Private Partner),10 - Benefits,G46 -28-29 BEN Forecast - Disbenefit UK Economic,10 - Benefits,H46 -28-29 BEN Forecast - Total Monetised Benefits,10 - Benefits,K46 -Unprofiled Remainder BEN Bobline - Gov. Cashable,10 - Benefits,E47 -Unprofiled Remainder BEN Bobline - Gov. Non-Cashable,10 - Benefits,F47 -Unprofiled Remainder BEN Bobline - Economic (inc Private Partner),10 - Benefits,G47 -Unprofiled Remainder BEN Bobline - Disbenefit UK Economic,10 - Benefits,H47 -Unprofiled Remainder BEN Bobline - Total Monetised Benefits,10 - Benefits,K47 -Unprofiled Remainder BEN Forecast - Gov. Cashable,10 - Benefits,E48 -Unprofiled Remainder BEN Forecast - Gov. Non-Cashable,10 - Benefits,F48 -Unprofiled Remainder BEN Forecast - Economic (inc Private Partner),10 - Benefits,G48 -Unprofiled Remainder BEN Forecast - Disbenefit UK Economic,10 - Benefits,H48 -Unprofiled Remainder BEN Forecast - Total Monetised Benefits,10 - Benefits,K48 -Total BEN Bobline - Gov. Cashable,10 - Benefits,E49 -Total BEN Bobline - Gov. Non-Cashable,10 - Benefits,F49 -Total BEN Bobline - Economic (inc Private Partner),10 - Benefits,G49 -Total BEN Bobline - Disbenefit UK Economic,10 - Benefits,H49 -Total BEN Bobline - Total Monetised Benefits,10 - Benefits,K49 -Total BEN Forecast - Gov. Cashable,10 - Benefits,E50 -Total BEN Forecast - Gov. Non-Cashable,10 - Benefits,F50 -Total BEN Forecast - Economic (inc Private Partner),10 - Benefits,G50 -Total BEN Forecast - Disbenefit UK Economic,10 - Benefits,H50 -Total BEN Forecast - Total Monetised Benefits,10 - Benefits,K50 -Year BEN spend stops,10 - Benefits,E51 -No Deductions - Net Benefits Provided,10 - Benefits,K54 -Deduct TDEL One Off New Costs?,10 - Benefits,K55 -Deduct CDEL one off New Costs?,10 - Benefits,K56 -Deduct TDEL Recurring New Costs?,10 - Benefits,K57 -Deduct CDEL Recurring New Costs?,10 - Benefits,K58 -Deduct TDEL Recurring Old Costs?,10 - Benefits,K59 -Deduct CDEL Recurring Old Costs?,10 - Benefits,K60 -No Monetised Benefits / Initial Business Case Being Prepared,10 - Benefits,K61 -SRO Benefits RAG,10 - Benefits,E64 diff --git a/pkg/datamaps/testdata/datamap_for_master_test.csv b/pkg/datamaps/testdata/datamap_for_master_test.csv deleted file mode 100644 index cb6178a..0000000 --- a/pkg/datamaps/testdata/datamap_for_master_test.csv +++ /dev/null @@ -1,19 +0,0 @@ -cell_key,template_sheet,cellreference -A Date,Summary,B2 -A String,Summary,B3 -A String2,Summary,C3 -A String3,Summary,D3 -A Float,Summary,B4 -An Integer,Summary,B5 -A Date 1,Another Sheet,B3 -A String 1,Another Sheet,B4 -A Float 1,Another Sheet,B5 -An Integer 1,Another Sheet,B6 -A Date 2,Another Sheet,D3 -A String 2,Another Sheet,D4 -A Float 3,Another Sheet,D5 -An Integer 3,Another Sheet,D6 -A Ten Integer,Introduction,A1 -A Test String,Introduction,C9 -A Vunt String,Introduction,C22 -A Parrot String,Introduction,J9 diff --git a/pkg/datamaps/testdata/datamap_matches_test_template.csv b/pkg/datamaps/testdata/datamap_matches_test_template.csv deleted file mode 100644 index 9ff8c8c..0000000 --- a/pkg/datamaps/testdata/datamap_matches_test_template.csv +++ /dev/null @@ -1,10 +0,0 @@ -cell_key,template_sheet,cellreference -A Ten,Introduction,A1 -A Test,Introduction,C9 -A Vunt,Introduction,C22 -Floaty,Another Sheet,D5 -A Parrot,Introduction,J9 -A String,Summary,B3 -A Float,Summary,B4 -A Number,Another Sheet,N34 -A Rabbit,Another Sheet,DI15 diff --git a/pkg/datamaps/testdata/test_template.xlsm b/pkg/datamaps/testdata/test_template.xlsm Binary files differdeleted file mode 100644 index 7681c04..0000000 --- a/pkg/datamaps/testdata/test_template.xlsm +++ /dev/null diff --git a/pkg/datamaps/testdata/test_template.xlsx b/pkg/datamaps/testdata/test_template.xlsx Binary files differdeleted file mode 100644 index 4b46dbb..0000000 --- a/pkg/datamaps/testdata/test_template.xlsx +++ /dev/null diff --git a/pkg/datamaps/testdata/test_template2.xlsx b/pkg/datamaps/testdata/test_template2.xlsx Binary files differdeleted file mode 100644 index 23513bd..0000000 --- a/pkg/datamaps/testdata/test_template2.xlsx +++ /dev/null diff --git a/pkg/datamaps/testdata/test_template3.xlsx b/pkg/datamaps/testdata/test_template3.xlsx Binary files differdeleted file mode 100644 index 8de40da..0000000 --- a/pkg/datamaps/testdata/test_template3.xlsx +++ /dev/null diff --git a/pkg/datamaps/writer.go b/pkg/datamaps/writer.go deleted file mode 100644 index 9e7973f..0000000 --- a/pkg/datamaps/writer.go +++ /dev/null @@ -1,153 +0,0 @@ -package datamaps - -import ( - "database/sql" - "fmt" - "log" - "path/filepath" - - "github.com/tealeg/xlsx/v3" - - // Needed for the sqlite3 driver - _ "github.com/mattn/go-sqlite3" -) - -// CreateMaster creates a master spreadsheet for a specific return given, -// based on a datamap name - both of which already need to be in the database, -// along with the data associated with the return. The datamap and return data -// must already have been imported. -func CreateMaster(opts *Options) error { - wb := xlsx.NewFile() - sh, err := wb.AddSheet("Master Data") - if err != nil { - return fmt.Errorf("cannot add 'Master Data' sheet to new XLSX file: %v", err) - } - - db, err := sql.Open("sqlite3", opts.DBPath) - if err != nil { - return fmt.Errorf("cannot open database %v", err) - } - - // Get number amount of datamap keys in target datamap - keyCountRows := db.QueryRow("SELECT count(key) FROM datamap_line, datamap WHERE datamap.name=?;", opts.DMName) - - var datamapKeysNumber int64 - if err := keyCountRows.Scan(&datamapKeysNumber); err != nil { - return err - } - - datamapKeysRows, err := db.Query("SELECT key FROM datamap_line, datamap WHERE datamap.name=?;", opts.DMName) - if err != nil { - return fmt.Errorf("cannot query for keys in database - %v", err) - } - - var datamapKeys []string - - var i int64 - for i = 0; i < datamapKeysNumber; i++ { - if k := datamapKeysRows.Next(); k { - var key string - if err := datamapKeysRows.Scan(&key); err != nil { - return fmt.Errorf("cannot Scan for key %s - %v", key, err) - } - datamapKeys = append(datamapKeys, key) - } - } - - sqlCount := `SELECT count(return_data.id) - FROM (((return_data - INNER JOIN datamap_line ON return_data.dml_id=datamap_line.id) - INNER JOIN datamap ON datamap_line.dm_id=datamap.id) - INNER JOIN return on return_data.ret_id=return.id) - WHERE datamap.name=? AND return.name=?;` - - var rowCount int64 - rowCountRes := db.QueryRow(sqlCount, opts.DMName, opts.ReturnName) - - if err := rowCountRes.Scan(&rowCount); err != nil { - return err - } - - getDataSQL := `SELECT datamap_line.key, return_data.vFormatted, return_data.filename - FROM (((return_data - INNER JOIN datamap_line ON return_data.dml_id=datamap_line.id) - INNER JOIN datamap ON datamap_line.dm_id=datamap.id) - INNER JOIN return on return_data.ret_id=return.id) - WHERE datamap.name=? AND return.name=? AND datamap_line.key=? - ORDER BY return_data.filename;` - - seen := make(map[string]struct{}) // homemade Set https://emersion.fr/blog/2017/sets-in-go/ - - var values = make(map[string][]string) - headerSlice := make([]string, 0) - for _, k := range datamapKeys { - masterData, err := db.Query(getDataSQL, opts.DMName, opts.ReturnName, k) - if err != nil { - return err - } - for masterData.Next() { - var key, filename, fmttedValue string - if err := masterData.Scan(&key, &fmttedValue, &filename); err != nil { - fmt.Errorf("Problem scanning data from database for master: %v", err) - } - values, err = appendValueMap(key, fmttedValue, values) - if _, ok := seen[filename]; !ok { - headerSlice = append(headerSlice, filename) - seen[filename] = struct{}{} - } - if err != nil { - return err - } - } - } - - for masterRow := 0; masterRow <= len(datamapKeys); masterRow++ { - r, err := sh.AddRowAtIndex(masterRow) - if err != nil { - return fmt.Errorf("cannot create row %d in output spreadsheet: %v", masterRow, err) - } - if masterRow == 0 { - if hdr := r.WriteSlice(append([]string{""}, headerSlice...), -1); hdr == -1 { - return fmt.Errorf("cannot write header values into header row: %v", err) - } - continue - } - dmlKey := datamapKeys[masterRow-1] - - // TODO - we need to format the cells here too, e.g. dates - if sl := r.WriteSlice(append([]string{dmlKey}, values[dmlKey]...), -1); sl == -1 { - log.Printf("not a slice type") - } - } - - log.Printf("saving master at %s", opts.MasterOutPutPath) - if err := wb.Save(filepath.Join(opts.MasterOutPutPath, "master.xlsx")); err != nil { - log.Fatalf("cannot save file to %s", opts.MasterOutPutPath) - } - sh.Close() - return nil -} - -func appendValueMap(k, v string, values map[string][]string) (map[string][]string, error) { - - var keyIn bool - for kv := range values { - if kv == k { - keyIn = true - break - } - } - - if keyIn { - slice, ok := values[k] - if !ok { - return nil, fmt.Errorf("%s is not a key in this map", k) - } - slice = append(slice, v) - values[k] = slice - return values, nil - } else { - values[k] = []string{v} - return values, nil - } -} diff --git a/pkg/datamaps/writer_test.go b/pkg/datamaps/writer_test.go deleted file mode 100644 index c6cf547..0000000 --- a/pkg/datamaps/writer_test.go +++ /dev/null @@ -1,195 +0,0 @@ -package datamaps - -import ( - "fmt" - "os" - "os/exec" - "path/filepath" - "strings" - "testing" - - "github.com/tealeg/xlsx/v3" -) - -var ( - // filesInMaster is a map of each filename from the header row of a master, mapped to its - // column number - filesInMaster = make(map[string]int) -) - -func testSetup() (*Options, error) { - // setup - we need the datamap in the test database - _, err := setupDB("./testdata/test.db") - - if err != nil { - fmt.Errorf("expected to be able to set up the database") - } - - opts := Options{ - DBPath: "./testdata/test.db", - DMName: "First Datamap", - DMPath: "./testdata/datamap_for_master_test.csv", - ReturnName: "Unnamed Return", - MasterOutPutPath: "./testdata/", - XLSXPath: "./testdata/", - } - - if err := DatamapToDB(&opts); err != nil { - fmt.Errorf("unable to write datamap to database file because %v", err) - } - - if err := ImportToDB(&opts); err != nil { - fmt.Errorf("cannot read test XLSX files needed before exporting to master - %v", err) - } - return &opts, nil -} - -func TestWriteMaster(t *testing.T) { - - opts, err := testSetup() - if err != nil { - t.Fatal(err) - } - - defer func() { - os.Remove(filepath.Join(opts.MasterOutPutPath, "master.xlsx")) - }() - - defer func() { - os.Remove("./testdata/test.db") - }() - - if err := CreateMaster(opts); err != nil { - t.Fatal(err) - } - - var tests = []struct { - key string - filename string - sheet string - cellref string - value string - }{ - {"A Date", "test_template.xlsx", "Summary", "B2", "20/10/19"}, - {"A String", "test_template.xlsx", "Summary", "B3", "This is a string"}, - {"A String2", "test_template.xlsx", "Summary", "C3", "This is a string"}, - {"A String3", "test_template.xlsx", "Summary", "D3", "This is a string"}, - {"A Float", "test_template.xlsx", "Summary", "B4", "2.2"}, - {"An Integer", "test_template.xlsx", "Summary", "B5", "10"}, - {"A Date 1", "test_template.xlsx", "Another Sheet", "B3", "20/10/19"}, - {"A String 1", "test_template.xlsx", "Another Sheet", "B4", "This is a string"}, - {"A Float 1", "test_template.xlsx", "Another Sheet", "B5", "2.2"}, - {"An Integer 1", "test_template.xlsx", "Another Sheet", "B6", "10"}, - {"A Date 2", "test_template.xlsx", "Another Sheet", "D3", "21/10/19"}, - {"A String 2", "test_template.xlsx", "Another Sheet", "D4", "This is a string"}, - {"A Float 3", "test_template.xlsx", "Another Sheet", "D5", "3.2"}, - {"An Integer 3", "test_template.xlsx", "Another Sheet", "D6", "11"}, - {"A Ten Integer", "test_template.xlsx", "Introduction", "A1", "10"}, - {"A Test String", "test_template.xlsx", "Introduction", "C9", "Test Department"}, - {"A Vunt String", "test_template.xlsx", "Introduction", "C22", "VUNT"}, - {"A Parrot String", "test_template.xlsx", "Introduction", "J9", "Greedy Parrots"}, - - {"A Date", "test_template.xlsm", "Summary", "B2", "20/10/19"}, - {"A String", "test_template.xlsm", "Summary", "B3", "This is a string"}, - {"A String2", "test_template.xlsm", "Summary", "C3", "This is a string"}, - {"A String3", "test_template.xlsm", "Summary", "D3", "This is a string"}, - {"A Float", "test_template.xlsm", "Summary", "B4", "2.2"}, - {"An Integer", "test_template.xlsm", "Summary", "B5", "10"}, - {"A Date 1", "test_template.xlsm", "Another Sheet", "B3", "20/10/19"}, - {"A String 1", "test_template.xlsm", "Another Sheet", "B4", "This is a string"}, - {"A Float 1", "test_template.xlsm", "Another Sheet", "B5", "2.2"}, - {"An Integer 1", "test_template.xlsm", "Another Sheet", "B6", "10"}, - {"A Date 2", "test_template.xlsm", "Another Sheet", "D3", "21/10/19"}, - {"A String 2", "test_template.xlsm", "Another Sheet", "D4", "This is a string"}, - {"A Float 3", "test_template.xlsm", "Another Sheet", "D5", "3.2"}, - {"An Integer 3", "test_template.xlsm", "Another Sheet", "D6", "11"}, - {"A Ten Integer", "test_template.xlsm", "Introduction", "A1", "10"}, - {"A Test String", "test_template.xlsm", "Introduction", "C9", "Test Department"}, - {"A Vunt String", "test_template.xlsm", "Introduction", "C22", "VUNT"}, - {"A Parrot String", "test_template.xlsm", "Introduction", "J9", "Greedy Parrots"}, - } - - // Regular testing of import - // TODO fix date formatting - for _, test := range tests { - sql := fmt.Sprintf(`SELECT return_data.vFormatted FROM return_data, datamap_line - WHERE - (return_data.filename=%q - AND datamap_line.cellref=%q - AND datamap_line.sheet=%q - AND return_data.dml_id=datamap_line.id);`, test.filename, test.cellref, test.sheet) - - got, err := exec.Command("sqlite3", opts.DBPath, sql).Output() - if err != nil { - t.Fatalf("something wrong %v", err) - } - gots := strings.TrimSuffix(string(got), "\n") - if strings.Compare(gots, test.value) != 0 { - t.Errorf("when testing the database, for key %s in file %s we expected %s but got %s", test.key, - test.filename, test.value, gots) - } - } - - // Open the master and the target sheet - master, err := xlsx.OpenFile("./testdata/master.xlsx") - if err != nil { - t.Fatal(err) - } - sheetName := "Master Data" - sh, ok := master.Sheet[sheetName] - if !ok { - t.Errorf("Sheet named %s does not exist", sheetName) - } - defer sh.Close() - - err = sh.ForEachRow(rowVisitorTest) - - for _, tt := range tests { - got, err := masterLookup(sh, tt.key, tt.filename) - if err != nil { - t.Fatal("Problem calling masterLookup()") - } - if got != tt.value { - t.Errorf("when testing the master, for key %s we expected value %s in col %s - got %s", - tt.key, tt.value, tt.filename, got) - } - } -} - -func masterLookup(sheet *xlsx.Sheet, key string, filename string) (string, error) { - var out string - if err := sheet.ForEachRow(func(r *xlsx.Row) error { - if r.GetCell(0).Value == key { - out = r.GetCell(filesInMaster[filename]).Value - return nil - } - return nil - }); err != nil { - return "", err - } - return out, nil -} - -func cellVisitorTest(c *xlsx.Cell) error { - seen := make(map[string]struct{}) - if _, ok := seen[c.Value]; !ok { - if c.Value != "" { - x, _ := c.GetCoordinates() - filesInMaster[c.Value] = x - } - seen[c.Value] = struct{}{} - } - - return nil -} - -func rowVisitorTest(r *xlsx.Row) error { - // TODO here we want to first find the file names from the header row, - // then test that all key (from col 0) matches the value. - - if r.GetCoordinate() == 0 { - r.ForEachCell(cellVisitorTest) - return nil - } - return nil -} |