Add version files and update imports for trip model; enhance error handling

This commit is contained in:
ImBenji
2026-03-27 21:17:56 +00:00
parent e41e14e252
commit 427bcadc77
89 changed files with 9455 additions and 395 deletions
+57 -26
View File
@@ -3,7 +3,7 @@ import "dart:typed_data";
import "package:archive/archive.dart";
import "package:excel/excel.dart";
import "package:flutter/services.dart";
import "../models/trip.dart";
import "../models/operations/trip.dart";
import "../models/brr_metadata.dart";
import "brr_exporter.dart";
@@ -20,7 +20,10 @@ class ArrivaBRRExporter implements BRRExporter {
// strip the whole numFmts block — Numbers export puts built-in IDs
// in there which the excel package rejects
xml = xml.replaceAll(RegExp(r'<numFmts[^>]*>.*?</numFmts>', dotAll: true), "");
xml = xml.replaceAll(
RegExp(r'<numFmts[^>]*>.*?</numFmts>', dotAll: true),
"",
);
// reset all numFmtId refs in xf elements to 0 (General)
// so nothing tries to look up the stripped formats
@@ -36,10 +39,9 @@ class ArrivaBRRExporter implements BRRExporter {
return ZipEncoder().encode(output)!;
}
static const int _dataStartRow = 8; // row 9 (0-indexed)
static const int _dataStartRow = 8; // row 9 (0-indexed)
static const int _templateDataRows = 15; // rows 923
@override
Future<Uint8List> export(List<Trip> trips, BRRMetadata metadata) async {
final templateBytes = await rootBundle.load("assets/arriva_brr.xlsx");
@@ -62,7 +64,8 @@ class ArrivaBRRExporter implements BRRExporter {
// Shifts all rows from (_dataStartRow + _templateDataRows) onwards down by extraRows
void _shiftRowsDown(Sheet sheet, int extraRows) {
final firstRowToShift = _dataStartRow + _templateDataRows; // row 24 (index 23)
final firstRowToShift =
_dataStartRow + _templateDataRows; // row 24 (index 23)
// figure out how many rows exist beyond the data block
final maxRow = sheet.rows.length;
@@ -77,10 +80,14 @@ class ArrivaBRRExporter implements BRRExporter {
final cell = srcRow[c];
if (cell == null) continue;
sheet.cell(CellIndex.indexByColumnRow(columnIndex: c, rowIndex: destRow)).value =
cell.value;
sheet.cell(CellIndex.indexByColumnRow(columnIndex: c, rowIndex: destRow)).cellStyle =
cell.cellStyle;
sheet
.cell(CellIndex.indexByColumnRow(columnIndex: c, rowIndex: destRow))
.value = cell
.value;
sheet
.cell(CellIndex.indexByColumnRow(columnIndex: c, rowIndex: destRow))
.cellStyle = cell
.cellStyle;
}
}
@@ -88,7 +95,10 @@ class ArrivaBRRExporter implements BRRExporter {
for (var r = firstRowToShift; r < firstRowToShift + extraRows; r++) {
if (r >= sheet.rows.length) break;
for (var c = 0; c < 18; c++) {
sheet.cell(CellIndex.indexByColumnRow(columnIndex: c, rowIndex: r)).value = null;
sheet
.cell(CellIndex.indexByColumnRow(columnIndex: c, rowIndex: r))
.value =
null;
}
}
}
@@ -98,30 +108,51 @@ class ArrivaBRRExporter implements BRRExporter {
final trip = trips[i];
final row = _dataStartRow + i;
sheet.cell(CellIndex.indexByColumnRow(columnIndex: 0, rowIndex: row)).value =
TextCellValue(trip.scheduledTime);
sheet.cell(CellIndex.indexByColumnRow(columnIndex: 1, rowIndex: row)).value =
TextCellValue(trip.tripNumber);
sheet
.cell(CellIndex.indexByColumnRow(columnIndex: 0, rowIndex: row))
.value = TextCellValue(
trip.scheduledTime,
);
sheet
.cell(CellIndex.indexByColumnRow(columnIndex: 1, rowIndex: row))
.value = TextCellValue(
trip.tripNumber,
);
if (trip.actualDepartureTime != null) {
sheet.cell(CellIndex.indexByColumnRow(columnIndex: 2, rowIndex: row)).value =
TextCellValue(trip.actualDepartureTime!);
sheet
.cell(CellIndex.indexByColumnRow(columnIndex: 2, rowIndex: row))
.value = TextCellValue(
trip.actualDepartureTime!,
);
}
if (trip.actualFleetNumber != null) {
sheet.cell(CellIndex.indexByColumnRow(columnIndex: 3, rowIndex: row)).value =
TextCellValue(trip.actualFleetNumber!);
sheet
.cell(CellIndex.indexByColumnRow(columnIndex: 3, rowIndex: row))
.value = TextCellValue(
trip.actualFleetNumber!,
);
}
sheet.cell(CellIndex.indexByColumnRow(columnIndex: 4, rowIndex: row)).value =
TextCellValue(trip.dutyNumber);
sheet.cell(CellIndex.indexByColumnRow(columnIndex: 5, rowIndex: row)).value =
TextCellValue(trip.runningNumber);
sheet
.cell(CellIndex.indexByColumnRow(columnIndex: 4, rowIndex: row))
.value = TextCellValue(
trip.dutyNumber,
);
sheet
.cell(CellIndex.indexByColumnRow(columnIndex: 5, rowIndex: row))
.value = TextCellValue(
trip.busWorkNumber,
);
final didOperate = trip.actualDepartureTime != null && trip.actualFleetNumber != null;
sheet.cell(CellIndex.indexByColumnRow(columnIndex: 6, rowIndex: row)).value =
TextCellValue(didOperate ? "Y" : "N");
final didOperate =
trip.actualDepartureTime != null && trip.actualFleetNumber != null;
sheet
.cell(CellIndex.indexByColumnRow(columnIndex: 6, rowIndex: row))
.value = TextCellValue(
didOperate ? "Y" : "N",
);
}
}
}
+1 -1
View File
@@ -1,5 +1,5 @@
import "dart:typed_data";
import "../models/trip.dart";
import "../models/operations/trip.dart";
import "../models/brr_metadata.dart";
abstract class BRRExporter {
+34 -16
View File
@@ -1,11 +1,10 @@
import "dart:typed_data";
import "package:excel/excel.dart";
import "../models/trip.dart";
import "../models/operations/trip.dart";
import "../models/brr_metadata.dart";
import "brr_exporter.dart";
class StagecoachBRRExporter implements BRRExporter {
@override
Future<Uint8List> export(List<Trip> trips, BRRMetadata metadata) async {
final excel = Excel.createExcel();
@@ -26,24 +25,31 @@ class StagecoachBRRExporter implements BRRExporter {
final bold = CellStyle(bold: true);
for (var c = 0; c < headers.length; c++) {
final cell = sheet.cell(CellIndex.indexByColumnRow(columnIndex: c, rowIndex: 0));
final cell = sheet.cell(
CellIndex.indexByColumnRow(columnIndex: c, rowIndex: 0),
);
cell.value = TextCellValue(headers[c]);
cell.cellStyle = bold;
}
for (var i = 0; i < trips.length; i++) {
final trip = trips[i];
final row = i + 1;
// Dep Time (HHMM no colon)
sheet.cell(CellIndex.indexByColumnRow(columnIndex: 0, rowIndex: row)).value =
TextCellValue(trip.scheduledTime.replaceAll(":", ""));
sheet
.cell(CellIndex.indexByColumnRow(columnIndex: 0, rowIndex: row))
.value = TextCellValue(
trip.scheduledTime.replaceAll(":", ""),
);
// (+/-) No. - user fills in
if (trip.actualDepartureTime != null) {
sheet.cell(CellIndex.indexByColumnRow(columnIndex: 1, rowIndex: row)).value =
TextCellValue(trip.actualDepartureTime!);
sheet
.cell(CellIndex.indexByColumnRow(columnIndex: 1, rowIndex: row))
.value = TextCellValue(
trip.actualDepartureTime!,
);
}
// Ser. — outbound shows route name, inbound shows "PARK"
@@ -51,22 +57,34 @@ class StagecoachBRRExporter implements BRRExporter {
final ser = trip.direction == "outbound"
? (metadata.route != "Unknown" ? metadata.route : "OUT")
: "PARK";
sheet.cell(CellIndex.indexByColumnRow(columnIndex: 2, rowIndex: row)).value =
TextCellValue(ser);
sheet
.cell(CellIndex.indexByColumnRow(columnIndex: 2, rowIndex: row))
.value = TextCellValue(
ser,
);
// Bus Wk No
sheet.cell(CellIndex.indexByColumnRow(columnIndex: 3, rowIndex: row)).value =
TextCellValue(trip.dutyNumber);
sheet
.cell(CellIndex.indexByColumnRow(columnIndex: 3, rowIndex: row))
.value = TextCellValue(
trip.busWorkNumber,
);
// Fleet No. — actual fleet number entered by user
if (trip.actualFleetNumber != null) {
sheet.cell(CellIndex.indexByColumnRow(columnIndex: 4, rowIndex: row)).value =
TextCellValue(trip.actualFleetNumber!);
sheet
.cell(CellIndex.indexByColumnRow(columnIndex: 4, rowIndex: row))
.value = TextCellValue(
trip.actualFleetNumber!,
);
}
// Crew Duty
sheet.cell(CellIndex.indexByColumnRow(columnIndex: 5, rowIndex: row)).value =
TextCellValue(trip.tripNumber);
sheet
.cell(CellIndex.indexByColumnRow(columnIndex: 5, rowIndex: row))
.value = TextCellValue(
trip.dutyNumber,
);
}
final bytes = excel.encode();