145 lines
4.8 KiB
Dart
145 lines
4.8 KiB
Dart
import 'package:flutter/material.dart';
|
|
import 'package:provider/provider.dart';
|
|
|
|
import '../labels.dart';
|
|
import '../models/models.dart';
|
|
import '../services/auth_controller.dart';
|
|
import '../ui/feedback.dart';
|
|
|
|
class StockFormScreen extends StatefulWidget {
|
|
const StockFormScreen({super.key, required this.dealers});
|
|
|
|
final List<Dealer> dealers;
|
|
|
|
@override
|
|
State<StockFormScreen> createState() => _StockFormScreenState();
|
|
}
|
|
|
|
class _StockFormScreenState extends State<StockFormScreen> {
|
|
final _chassis = TextEditingController();
|
|
final _engine = TextEditingController();
|
|
final _color = TextEditingController();
|
|
String _model = modelOptions.first;
|
|
String? _dealerId;
|
|
DateTime _received = DateTime.now();
|
|
bool _saving = false;
|
|
|
|
@override
|
|
void initState() {
|
|
super.initState();
|
|
final user = context.read<AuthController>().user;
|
|
if (user?.role == 'dealer') {
|
|
_dealerId = user?.dealerId ?? (widget.dealers.isNotEmpty ? widget.dealers.first.id : null);
|
|
} else if (widget.dealers.length == 1) {
|
|
_dealerId = widget.dealers.first.id;
|
|
}
|
|
}
|
|
|
|
@override
|
|
void dispose() {
|
|
_chassis.dispose();
|
|
_engine.dispose();
|
|
_color.dispose();
|
|
super.dispose();
|
|
}
|
|
|
|
Future<void> _save() async {
|
|
if (_dealerId == null) {
|
|
showError(context, 'Choose a dealer');
|
|
return;
|
|
}
|
|
setState(() => _saving = true);
|
|
try {
|
|
await context.read<AuthController>().api.createStock({
|
|
'chassisNumber': _chassis.text.trim(),
|
|
'engineNumber': _engine.text.trim(),
|
|
'model': _model,
|
|
'color': _color.text.trim(),
|
|
'currentDealerId': _dealerId,
|
|
'dateReceived': _received.toUtc().toIso8601String(),
|
|
});
|
|
if (mounted) Navigator.pop(context, true);
|
|
} catch (error) {
|
|
if (mounted) showError(context, error);
|
|
} finally {
|
|
if (mounted) setState(() => _saving = false);
|
|
}
|
|
}
|
|
|
|
@override
|
|
Widget build(BuildContext context) {
|
|
final lockedToOwnDealer = context.watch<AuthController>().user?.role == 'dealer';
|
|
Dealer? ownDealer;
|
|
for (final dealer in widget.dealers) {
|
|
if (dealer.id == _dealerId) {
|
|
ownDealer = dealer;
|
|
break;
|
|
}
|
|
}
|
|
return Scaffold(
|
|
appBar: AppBar(title: const Text('Add stock')),
|
|
body: ListView(
|
|
padding: const EdgeInsets.all(16),
|
|
children: [
|
|
TextField(controller: _chassis, decoration: const InputDecoration(labelText: 'Chassis number')),
|
|
const SizedBox(height: 12),
|
|
TextField(controller: _engine, decoration: const InputDecoration(labelText: 'Engine number')),
|
|
const SizedBox(height: 12),
|
|
DropdownButtonFormField<String>(
|
|
initialValue: _model,
|
|
decoration: const InputDecoration(labelText: 'Model'),
|
|
items: [
|
|
for (final model in modelOptions)
|
|
DropdownMenuItem(value: model, child: Text(modelLabel(model))),
|
|
],
|
|
onChanged: (value) {
|
|
if (value != null) setState(() => _model = value);
|
|
},
|
|
),
|
|
const SizedBox(height: 12),
|
|
TextField(controller: _color, decoration: const InputDecoration(labelText: 'Color')),
|
|
const SizedBox(height: 12),
|
|
if (lockedToOwnDealer)
|
|
InputDecorator(
|
|
decoration: const InputDecoration(labelText: 'Dealer'),
|
|
child: Text(
|
|
ownDealer == null ? 'Your dealership' : '${ownDealer.name} (${ownDealer.code})',
|
|
),
|
|
)
|
|
else
|
|
DropdownButtonFormField<String>(
|
|
initialValue: _dealerId,
|
|
decoration: const InputDecoration(labelText: 'Dealer'),
|
|
items: [
|
|
for (final dealer in widget.dealers)
|
|
DropdownMenuItem(value: dealer.id, child: Text('${dealer.name} (${dealer.code})')),
|
|
],
|
|
onChanged: (value) => setState(() => _dealerId = value),
|
|
),
|
|
const SizedBox(height: 12),
|
|
ListTile(
|
|
contentPadding: EdgeInsets.zero,
|
|
title: const Text('Received date'),
|
|
subtitle: Text(_received.toLocal().toString().split(' ').first),
|
|
trailing: const Icon(Icons.calendar_today),
|
|
onTap: () async {
|
|
final picked = await showDatePicker(
|
|
context: context,
|
|
initialDate: _received,
|
|
firstDate: DateTime(2000),
|
|
lastDate: DateTime.now().add(const Duration(days: 1)),
|
|
);
|
|
if (picked != null) setState(() => _received = picked);
|
|
},
|
|
),
|
|
const SizedBox(height: 16),
|
|
FilledButton(
|
|
onPressed: _saving ? null : _save,
|
|
child: Text(_saving ? 'Saving' : 'Save stock'),
|
|
),
|
|
],
|
|
),
|
|
);
|
|
}
|
|
}
|