production
This commit is contained in:
@@ -1,5 +1,6 @@
|
||||
import 'package:miler/Models/stop_status.dart';
|
||||
import 'package:miler/views/Dashboard/pickups/stop_type.dart';
|
||||
import 'package:miler/data/pickup_locations.dart';
|
||||
import 'package:miler/data/service_profile.dart';
|
||||
|
||||
/// ─────────────────────────────────────────────────────────────────────────
|
||||
@@ -136,14 +137,33 @@ class MilkRun {
|
||||
/// prevent, produced by the two halves of the decision disagreeing.
|
||||
///
|
||||
/// One key list, one answer.
|
||||
static String sourceNameOf(Map<String, dynamic> stop) =>
|
||||
(stop['sourcename'] ??
|
||||
stop['SourceName'] ??
|
||||
stop['kitchenname'] ??
|
||||
stop['KitchenName'] ??
|
||||
'')
|
||||
.toString()
|
||||
.trim();
|
||||
///
|
||||
/// ── The tenant's own location list wins ──
|
||||
///
|
||||
/// The booking row's `sourcename` is filled by the backend from
|
||||
/// `providercompany` / `providerlocation`, and what lands there is often
|
||||
/// whoever is on the account rather than the counter — the route card's
|
||||
/// heading, the biggest type on Home, read `Sudharsan`.
|
||||
///
|
||||
/// The booking does carry the location's **id**, and the tenant's locations
|
||||
/// are a list with proper names on them, so the name is joined rather than
|
||||
/// read off the row. See [PickupLocations]: when the table is empty — not
|
||||
/// loaded yet, or the rider's token is not admitted to the admin route —
|
||||
/// this falls through to exactly what it returned before.
|
||||
static String sourceNameOf(Map<String, dynamic> stop) {
|
||||
final resolved = PickupLocations.nameFor(
|
||||
stop['sourceid'] ?? stop['kitchenid'] ?? stop['pickuplocationid'],
|
||||
);
|
||||
if (resolved.isNotEmpty) return resolved;
|
||||
|
||||
return (stop['sourcename'] ??
|
||||
stop['SourceName'] ??
|
||||
stop['kitchenname'] ??
|
||||
stop['KitchenName'] ??
|
||||
'')
|
||||
.toString()
|
||||
.trim();
|
||||
}
|
||||
|
||||
/// True when two stops are collected from the same counter.
|
||||
static bool sameSource(Map<String, dynamic> a, Map<String, dynamic> b) =>
|
||||
@@ -300,8 +320,8 @@ class MilkRun {
|
||||
.trim();
|
||||
return name.isEmpty ? 'customer' : name;
|
||||
}
|
||||
final kitchen = sourceNameOf(stop);
|
||||
if (kitchen.isNotEmpty) return kitchen;
|
||||
final place = pickupPlaceOf(stop);
|
||||
if (place.isNotEmpty) return place;
|
||||
|
||||
// ── The word "pickup" is never a place ──
|
||||
//
|
||||
@@ -313,11 +333,31 @@ class MilkRun {
|
||||
// promoted to a title.
|
||||
//
|
||||
// A rider thinks in PLACES, and the payload still knows one: the pickup
|
||||
// address. Its first non-numeric component is the neighbourhood — the
|
||||
// same reading the timeline's area line uses — and "RS Puram" is
|
||||
// something he can ride to in a way "pickup" is not. Only when the
|
||||
// payload has no address either does the label fall back to a word, and
|
||||
// then it is at least a capitalised noun.
|
||||
// address. Only when it has no address either does the label fall back to
|
||||
// a word, and then it is at least a capitalised noun. See [pickupPlaceOf].
|
||||
return 'Pickup';
|
||||
}
|
||||
|
||||
/// **Where the rider is collecting from**, or `''` when the payload says.
|
||||
///
|
||||
/// ── Why this is not the customer's name ──
|
||||
///
|
||||
/// The route card's heading is the biggest type on Home, and on a group of
|
||||
/// one order it was the *customer* — so a rider planning his next collection
|
||||
/// read `Sudharsan`, which is a person, not somewhere he can ride to. The
|
||||
/// place was on the card the whole time, one line down, in grey.
|
||||
///
|
||||
/// The order of preference is the order of usefulness at a kerb:
|
||||
///
|
||||
/// 1. the counter's own name — what is written on the sign
|
||||
/// 2. the neighbourhood off the pickup address — what he steers by
|
||||
///
|
||||
/// Split out of [navigationLabel] so a caller can tell "no place in this
|
||||
/// payload" from the word *Pickup*, which reads as a name and is not one.
|
||||
static String pickupPlaceOf(Map<String, dynamic> stop) {
|
||||
final kitchen = sourceNameOf(stop);
|
||||
if (kitchen.isNotEmpty) return kitchen;
|
||||
|
||||
for (final key in const ['pickupaddress', 'PickupAddress']) {
|
||||
final raw = (stop[key] ?? '').toString().trim();
|
||||
if (raw.isEmpty) continue;
|
||||
@@ -333,7 +373,7 @@ class MilkRun {
|
||||
return p.replaceFirst(RegExp(r'^[0-9][0-9/\-]*\s+'), '');
|
||||
}
|
||||
}
|
||||
return 'Pickup';
|
||||
return '';
|
||||
}
|
||||
|
||||
/// Stops still owing the rider a collection at a given counter.
|
||||
@@ -387,6 +427,23 @@ class MilkRun {
|
||||
required Set<String> collectedIds,
|
||||
Set<String> outForDeliveryIds = const {},
|
||||
Set<String> deliveredIds = const {},
|
||||
|
||||
/// Stops the rider has reported arriving at.
|
||||
///
|
||||
/// ── Why arrival is a set and not a status ──
|
||||
///
|
||||
/// The backend team confirmed there is no Arrived rung in the booking
|
||||
/// lifecycle: `/reached` records the arrival as a **timestamp**
|
||||
/// (`reachedat`) beside a status that stays `pickup_scheduled`. And
|
||||
/// `GET /miler/bookings` does not return that stamp — see
|
||||
/// `getArrivedOrderIds` — so there is no server field to reconstruct
|
||||
/// arrival from after a refresh.
|
||||
///
|
||||
/// It therefore arrives the same way the other two rider-owned facts do,
|
||||
/// as a set of ids, and it is subject to the same precedence: it speaks
|
||||
/// only where nothing further along has happened. Delete this parameter,
|
||||
/// not the rung, on the day the stamp appears on a booking row.
|
||||
Set<String> arrivedIds = const {},
|
||||
}) {
|
||||
final id = idOf(stop);
|
||||
final reported = stopStatusOf(stop);
|
||||
@@ -422,7 +479,15 @@ class MilkRun {
|
||||
reported == StopStatus.outForDelivery) {
|
||||
return StopStatus.picked;
|
||||
}
|
||||
if (reported == StopStatus.arrived) return StopStatus.arrived;
|
||||
// ── Arrived, from either source ──
|
||||
//
|
||||
// Below everything above it, deliberately: the pickup milestone outranks
|
||||
// the arrival, and the delivery rungs outrank both. A rider's own arrival
|
||||
// record can never walk a stop the hub has moved on backwards — the same
|
||||
// rule the local store obeys everywhere else in the app.
|
||||
if (reported == StopStatus.arrived || arrivedIds.contains(id)) {
|
||||
return StopStatus.arrived;
|
||||
}
|
||||
if (acceptedIds.contains(id) || reported == StopStatus.accepted) {
|
||||
return StopStatus.accepted;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user