device infos
This commit is contained in:
@@ -16,7 +16,8 @@ import 'package:miler/views/helpers/constants/design_constants.dart';
|
||||
import 'package:miler/views/helpers/constants/miler_type.dart';
|
||||
import 'package:miler/views/helpers/constants/Font_constant.dart';
|
||||
import 'package:miler/Models/stop_status.dart';
|
||||
import 'package:miler/data/bag_manifest.dart';
|
||||
import 'package:miler/data/order_manifest.dart';
|
||||
import 'package:miler/data/stop_area.dart';
|
||||
import 'package:miler/data/milk_run.dart';
|
||||
import 'package:miler/data/service_profile.dart';
|
||||
|
||||
@@ -258,6 +259,10 @@ class TripCard extends StatelessWidget {
|
||||
// on the same footing. See [Trip.outstanding].
|
||||
remaining: trip.outstanding(
|
||||
collectedIds: collectedIds,
|
||||
// Work he has declined is not work in front of him — see the note on
|
||||
// [Trip.outstanding]. Without this the Distance cell measured a route
|
||||
// through stops the rider had refused.
|
||||
rejectedIds: rejectedIds,
|
||||
originLat: riderLat,
|
||||
originLng: riderLng,
|
||||
),
|
||||
@@ -311,7 +316,7 @@ class TripCard extends StatelessWidget {
|
||||
for (var i = 0; i < trip.stops.length; i++) {
|
||||
if (_stateOf(trip.stops[i]) != rung) continue;
|
||||
final stop = trip.stops[i];
|
||||
final key = MilkRun.sourceKeyOf(stop);
|
||||
final key = MilkRun.sourceKeyOf(stop, within: trip.stops);
|
||||
final grouped = ServiceProfile.active.sourceIsKitchen && key.isNotEmpty;
|
||||
final stops = grouped
|
||||
? [
|
||||
@@ -430,13 +435,22 @@ class TripCard extends StatelessWidget {
|
||||
// the screen. See [RouteGroup.allStops].
|
||||
for (var i = 0; i < trip.stops.length; i++) {
|
||||
final stop = trip.stops[i];
|
||||
// Key on the id where there is one, falling back to the name: the id is
|
||||
// what the hub controls, but a payload that only carries a name still has
|
||||
// to group rather than collapsing every stop into one nameless pile.
|
||||
// ── One reader for "which counter is this", not two ──
|
||||
//
|
||||
// This built its own key — `stopSourceId`, falling back to
|
||||
// `stopSourceName` — while [MilkRun.sourceKeyOf] is the function that
|
||||
// exists to answer exactly this, and is what the bulk collect, the
|
||||
// per-kitchen gate and `sameSourceAs` all key on.
|
||||
//
|
||||
// They did not agree. `stopSourceId` reads `kitchenid` and `sourceid`;
|
||||
// `sourceKeyOf` reads those **and `pickuplocationid`** — so a row
|
||||
// identified only by its location id was one place according to the
|
||||
// collect and a different one according to the card that offers it. That
|
||||
// is the same two-readers-one-question failure `sourceNameOf` documents,
|
||||
// repeated on the id, and it splits a kitchen's orders across two groups
|
||||
// on the screen while the collect still treats them as one.
|
||||
final key = grouped
|
||||
? (stopSourceId(stop).isNotEmpty
|
||||
? stopSourceId(stop)
|
||||
: stopSourceName(stop))
|
||||
? MilkRun.sourceKeyOf(stop, within: trip.stops)
|
||||
: 'stop:${_idOf(stop)}';
|
||||
if (!buckets.containsKey(key)) {
|
||||
buckets[key] = <int>[];
|
||||
@@ -473,17 +487,56 @@ class TripCard extends StatelessWidget {
|
||||
groups.add(() {
|
||||
final stops = visible;
|
||||
final first = all.first;
|
||||
|
||||
// ── An unnamed counter is named by where it is ──
|
||||
//
|
||||
// A grouped place with no source name fell through to
|
||||
// `MilkRun.navigationLabel`, which answers with the **customer** — so
|
||||
// the heading over a dropdown read as one more order rather than as the
|
||||
// place the orders under it are collected from.
|
||||
//
|
||||
// The address is what names a place the payload did not name, and it is
|
||||
// what the rider wants off that line anyway: he is deciding where to
|
||||
// ride, not who to hand a bag to.
|
||||
final place = compactAddress(pickupAddressOf(first));
|
||||
|
||||
// ── When a lone stop is a *place*, and when it is the stop ──
|
||||
//
|
||||
// `flat` means the header **is** the stop: no counter above it worth
|
||||
// naming, so the card is titled with the customer and opens the detail
|
||||
// sheet instead of a list. That is always right on a parcel route,
|
||||
// where the rider goes to one door for one consignment.
|
||||
//
|
||||
// On a kitchen line it was reached by a different route and gave the
|
||||
// wrong answer. A lone stop was flat whenever the payload carried **no
|
||||
// source name** — and a missing name is a gap in the data, not evidence
|
||||
// that there is no counter. So an order whose row lost its kitchen name
|
||||
// was drawn as a bare header with the customer's name on it, sitting
|
||||
// above the dropdown its seven siblings were in: seven bags in a list
|
||||
// and one stranded over it, off the same shelf.
|
||||
//
|
||||
// [MilkRun.sourceKeyOf] now groups such a row back in by its address,
|
||||
// which fixes that case at the root. This is the same correction one
|
||||
// level down, for a place that genuinely does hold a single order: on a
|
||||
// kitchen line a lone stop is only flat when there is **nothing at all**
|
||||
// to name its place with — no counter name and no address. With an
|
||||
// address it is a place holding one order, headed by where it is, with
|
||||
// the order in the list under it.
|
||||
final flat =
|
||||
all.length == 1 && (!grouped || stopSourceName(first).isEmpty);
|
||||
// A grouped place is named by its counter. A flat one *is* the stop, so
|
||||
// it is named by the customer — `MilkRun.navigationLabel` answers
|
||||
// "pickup" for a parcel that has not been collected yet, which is a
|
||||
// description of the leg rather than a name the rider can read off a
|
||||
// gate.
|
||||
all.length == 1 &&
|
||||
(!grouped || (stopSourceName(first).isEmpty && place.isEmpty));
|
||||
|
||||
// A grouped place is named by its counter, or failing that by where it
|
||||
// is. A flat one *is* the stop, so it is named by the customer —
|
||||
// `MilkRun.navigationLabel` answers "pickup" for a parcel that has not
|
||||
// been collected yet, which is a description of the leg rather than a
|
||||
// name the rider can read off a gate.
|
||||
final name = flat
|
||||
? BagManifest.customerOf(first)
|
||||
? OrderManifest.customerOf(first)
|
||||
: (grouped
|
||||
? stopSourceName(first)
|
||||
? (stopSourceName(first).trim().isNotEmpty
|
||||
? stopSourceName(first)
|
||||
: place)
|
||||
: MilkRun.navigationLabel(first));
|
||||
return RouteGroup(
|
||||
key: key,
|
||||
@@ -493,6 +546,20 @@ class TripCard extends StatelessWidget {
|
||||
name: name.trim().isEmpty
|
||||
? MilkRun.navigationLabel(first)
|
||||
: name.trim(),
|
||||
// ── The counter's street, under its name ──
|
||||
//
|
||||
// Grouped places only. A flat node *is* the stop and is already named
|
||||
// by its customer or its own address, so an address line under it
|
||||
// would print the same place twice; a kitchen is a name the rider has
|
||||
// to convert into a location, and until now the only thing that could
|
||||
// do that conversion was the preview sheet.
|
||||
//
|
||||
// Trimmed through [compactAddress] — the geocoder appends
|
||||
// `Tamil Nadu, 641002, India` to every row, which is three
|
||||
// components that are identical on every stop of every route and
|
||||
// would push the part that names the street off the end of the line.
|
||||
// Not repeated when it is already the heading — see [name] above.
|
||||
location: flat || name.trim() == place ? '' : place,
|
||||
stops: stops,
|
||||
allStops: all,
|
||||
firstIndex: indices.first,
|
||||
@@ -706,13 +773,12 @@ class TripCard extends StatelessWidget {
|
||||
|
||||
for (var i = 0; i < trip.stops.length; i++) {
|
||||
if (!_showsOnHome(_stateOf(trip.stops[i]))) continue;
|
||||
// Key on the id where there is one, falling back to the name: the id is
|
||||
// what the hub controls, but a payload that only carries a name still has
|
||||
// to group rather than collapsing every stop into one nameless pile.
|
||||
// [MilkRun.sourceKeyOf], the same reader [routeGroups] uses and the same
|
||||
// one the bulk collect keys on. This had its own id-then-name expression,
|
||||
// which misses `pickuplocationid` and therefore split a kitchen the
|
||||
// collect still treats as one — see the note in [routeGroups].
|
||||
final stop = trip.stops[i];
|
||||
final key = stopSourceId(stop).isNotEmpty
|
||||
? stopSourceId(stop)
|
||||
: stopSourceName(stop);
|
||||
final key = MilkRun.sourceKeyOf(stop);
|
||||
if (!groups.containsKey(key)) {
|
||||
groups[key] = <int>[];
|
||||
order.add(key);
|
||||
@@ -804,11 +870,11 @@ class TripCard extends StatelessWidget {
|
||||
// him comparing "5 meals" on the phone against a shelf of bags.
|
||||
// The count he can *check* is orders against bags, and under
|
||||
// this workflow they are the same number by definition. See
|
||||
// [BagManifest].
|
||||
// [OrderManifest].
|
||||
Text(
|
||||
pending > 0
|
||||
? '${BagManifest.countLabel(indices.length)} · $pending to accept'
|
||||
: BagManifest.countLabel(indices.length),
|
||||
? '${OrderManifest.countLabel(indices.length)} · $pending to accept'
|
||||
: OrderManifest.countLabel(indices.length),
|
||||
maxLines: 1,
|
||||
overflow: TextOverflow.ellipsis,
|
||||
style: TextStyle(
|
||||
@@ -1204,7 +1270,7 @@ class TripCard extends StatelessWidget {
|
||||
state: state,
|
||||
address: address,
|
||||
service: roundTripDuration(Trip.serviceTimeFor(stop)),
|
||||
bag: _bagOf(stop),
|
||||
label: _labelOf(stop),
|
||||
// The kitchen heading above already names where this came from.
|
||||
groupedUnderSource: ServiceProfile.active.sourceIsKitchen,
|
||||
selected: selectedIds.contains(id),
|
||||
@@ -1258,21 +1324,19 @@ class TripCard extends StatelessWidget {
|
||||
// `_tag` is gone — it built the tinted Deliver / Collect / ₹ chips. See
|
||||
// [_MetaLine], which says the same three things on one uncoloured line.
|
||||
|
||||
/// Which bag this order travels in.
|
||||
/// The label the counter printed on this order, or `''`.
|
||||
///
|
||||
/// Derived from its position in **its own pickup group**, not from the whole
|
||||
/// route: the rider counts bags off one counter at a time, so the third order
|
||||
/// from Kitchen 2 is *its* Bag 3 and not the route's ninth. A label the
|
||||
/// kitchen actually printed always wins — see [BagManifest].
|
||||
String _bagOf(Map<String, dynamic> stop) {
|
||||
if (!ServiceProfile.active.sourceIsKitchen) return stopBagLabel(stop);
|
||||
final key = MilkRun.sourceKeyOf(stop);
|
||||
final group = [
|
||||
for (final s in trip.stops)
|
||||
if (MilkRun.sourceKeyOf(s) == key) s,
|
||||
];
|
||||
return BagManifest.bagFor(stop, group);
|
||||
}
|
||||
/// ── It used to be derived, and that was the problem ──
|
||||
///
|
||||
/// This computed the order's position in its own pickup group and returned
|
||||
/// `Bag 3` — the app numbering a list it had built and presenting the result
|
||||
/// as something stencilled on an object. On a route where no counter prints
|
||||
/// labels that was every row, and it sat two columns from a rail numbering
|
||||
/// the same rows.
|
||||
///
|
||||
/// Only what the payload actually carries survives. See
|
||||
/// [OrderManifest.labelFor].
|
||||
String _labelOf(Map<String, dynamic> stop) => OrderManifest.labelFor(stop);
|
||||
|
||||
// ── Footer: accept remaining, or go work the trip ──────────────────────
|
||||
Widget _footerBar(List<String> pendingIds) {
|
||||
|
||||
Reference in New Issue
Block a user