
Adds pull-to-refresh functionality to the reception details page, allowing users to manually update the displayed information. Ensures that when a product is scanned, both the move line and the main move entities have their quantities correctly incremented, improving data consistency.
155 lines
6.6 KiB
Dart
155 lines
6.6 KiB
Dart
import 'package:e_scan/backend/objectbox/entities/stock_picking/stock_picking_record_entity.dart';
|
|
import 'package:e_scan/components/components.dart';
|
|
import 'package:e_scan/pages/operation/reception/reception_details_page_model.dart';
|
|
import 'package:e_scan/router/go_secure_router_builder.dart';
|
|
import 'package:e_scan/themes/app_theme.dart';
|
|
import 'package:flutter/scheduler.dart';
|
|
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
|
import 'package:flutter/material.dart';
|
|
|
|
class ReceptionDetailsPage extends ConsumerStatefulWidget {
|
|
const ReceptionDetailsPage({super.key, required this.receptionId});
|
|
final int receptionId;
|
|
@override
|
|
ConsumerState<ReceptionDetailsPage> createState() =>
|
|
_ReceptionDetailsPageState();
|
|
}
|
|
|
|
class _ReceptionDetailsPageState extends ConsumerState<ReceptionDetailsPage> {
|
|
@override
|
|
void initState() {
|
|
super.initState();
|
|
SchedulerBinding.instance.addPostFrameCallback((_) {
|
|
ref
|
|
.read(receptionDetailsPageModelProvider.notifier)
|
|
.getReceptionById(id: widget.receptionId);
|
|
});
|
|
}
|
|
|
|
@override
|
|
Widget build(BuildContext context) {
|
|
final state = ref.watch(receptionDetailsPageModelProvider);
|
|
final reception = state.reception;
|
|
return Scaffold(
|
|
backgroundColor: AppTheme.of(context).primaryBackground,
|
|
appBar: MainAppbarComponent(
|
|
leading: BackButton(color: AppTheme.of(context).white),
|
|
title: "Réceptions",
|
|
subTitle: "Opérations d'Entrepôt",
|
|
),
|
|
body: state.loading
|
|
? Center(child: LoadingProgressComponent())
|
|
: RefreshIndicator(
|
|
color: AppTheme.of(context).white,
|
|
backgroundColor: AppTheme.of(context).primary,
|
|
onRefresh: () async {
|
|
await ref
|
|
.read(receptionDetailsPageModelProvider.notifier)
|
|
.getReceptionById(id: widget.receptionId);
|
|
},
|
|
child: Padding(
|
|
padding: const EdgeInsets.symmetric(horizontal: 16),
|
|
child: ListView(
|
|
children: [
|
|
const SizedBox(height: 16),
|
|
if (reception?.isDone == false) ...[
|
|
QuickActionComponent(
|
|
onTapScan: () {
|
|
final id = reception?.id;
|
|
if (id == null) return;
|
|
ReceptionScanRoute(receptionId: id).push(context);
|
|
},
|
|
),
|
|
const SizedBox(height: 16),
|
|
],
|
|
Text(
|
|
'Détails réception',
|
|
style: AppTheme.of(
|
|
context,
|
|
).bodyMedium.copyWith(fontWeight: FontWeight.bold),
|
|
),
|
|
SizedBox(height: 10),
|
|
StockPickingCard(
|
|
isDone: reception?.isDone == true,
|
|
margin: EdgeInsets.symmetric(horizontal: 5),
|
|
reference: reception?.name ?? '',
|
|
from: reception?.locationId.target?.completeName,
|
|
to: reception?.locationDestId.target?.completeName,
|
|
contact: reception?.partnerId.target?.displayName,
|
|
origin: reception?.origin,
|
|
status: reception?.state,
|
|
),
|
|
SizedBox(height: 20),
|
|
Text(
|
|
'Produits',
|
|
style: AppTheme.of(
|
|
context,
|
|
).bodyMedium.copyWith(fontWeight: FontWeight.bold),
|
|
),
|
|
SizedBox(height: 10),
|
|
...reception?.moveIdsWithoutPackage
|
|
.map(
|
|
(move) => Card(
|
|
color: AppTheme.of(context).primaryBackground,
|
|
child: ListTile(
|
|
title: Text(
|
|
move.productId.target?.displayName ?? '',
|
|
style: TextStyle(color: Colors.black),
|
|
),
|
|
subtitle: Wrap(
|
|
spacing: 5,
|
|
children: [
|
|
Chip(
|
|
backgroundColor: AppTheme.of(
|
|
context,
|
|
).secondaryBackground,
|
|
label: Text(
|
|
"Qté demandée: ${move.productUomQty}",
|
|
),
|
|
),
|
|
Chip(
|
|
backgroundColor: AppTheme.of(
|
|
context,
|
|
).secondaryBackground,
|
|
label: Text(
|
|
"Qté reçue: ${move.quantity}",
|
|
),
|
|
),
|
|
Chip(
|
|
backgroundColor: AppTheme.of(
|
|
context,
|
|
).secondaryBackground,
|
|
label: Text(
|
|
"Ecart: ${move.ecart}",
|
|
style: TextStyle(
|
|
color: Colors.green,
|
|
fontWeight: FontWeight.bold,
|
|
),
|
|
),
|
|
),
|
|
],
|
|
),
|
|
),
|
|
),
|
|
)
|
|
.toList() ??
|
|
[],
|
|
],
|
|
),
|
|
),
|
|
),
|
|
floatingActionButton: reception?.isDone == false
|
|
? FloatingActionButton(
|
|
backgroundColor: AppTheme.of(context).primary,
|
|
onPressed: () {
|
|
final id = reception?.id;
|
|
if (id == null) return;
|
|
ReceptionScanRoute(receptionId: id).push(context);
|
|
},
|
|
child: Icon(Icons.qr_code, color: AppTheme.of(context).white),
|
|
)
|
|
: null,
|
|
);
|
|
}
|
|
}
|