d
This commit is contained in:
@@ -6,15 +6,18 @@ import 'package:flux/core/blocs/session/session_cubit.dart';
|
||||
import 'package:flux/core/widgets/shared_forms/customer_section.dart';
|
||||
import 'package:flux/core/widgets/shared_forms/model_section.dart';
|
||||
import 'package:flux/core/widgets/shared_forms/shared_files_section.dart';
|
||||
import 'package:flux/core/widgets/staff_selector_modal.dart';
|
||||
import 'package:flux/features/attachments/blocs/attachments_bloc.dart';
|
||||
import 'package:flux/features/company/models/company_model.dart';
|
||||
import 'package:flux/features/master_data/staff/models/staff_member_model.dart';
|
||||
import 'package:flux/features/tickets/blocs/ticket_form_cubit.dart';
|
||||
import 'package:flux/features/tickets/blocs/ticket_form_state.dart';
|
||||
import 'package:flux/features/tickets/blocs/ticket_list_cubit.dart';
|
||||
import 'package:flux/features/tickets/models/ticket_model.dart';
|
||||
import 'package:flux/core/widgets/shared_forms/staff_section.dart';
|
||||
import 'package:flux/features/tickets/models/ticket_status_extension.dart';
|
||||
import 'package:flux/features/tickets/ui/ticket_timeline_section.dart';
|
||||
import 'package:flux/features/tickets/ui/ticket_workspace_screen.dart';
|
||||
import 'package:flux/features/tickets/ui/ticket_workspace/ticket_workspace_screen.dart';
|
||||
import 'package:flux/features/tickets/utils/ticket_pdf_service.dart';
|
||||
import 'package:flux/features/tracking/blocs/tracking_cubit.dart';
|
||||
import 'package:flux/features/tracking/models/tracking_model.dart';
|
||||
@@ -36,7 +39,9 @@ class _TicketFormScreenState extends State<TicketFormScreen> {
|
||||
|
||||
final _altPhoneCtrl = TextEditingController();
|
||||
final _targetSerialCtrl = TextEditingController();
|
||||
final _targetPasswordCtrl = TextEditingController();
|
||||
final _sourceSerialCtrl = TextEditingController();
|
||||
final _sourcePasswordCtrl = TextEditingController();
|
||||
final _requestCtrl = TextEditingController();
|
||||
final _accessoriesCtrl = TextEditingController();
|
||||
final _publicNotesCtrl = TextEditingController();
|
||||
@@ -59,6 +64,8 @@ class _TicketFormScreenState extends State<TicketFormScreen> {
|
||||
void dispose() {
|
||||
_altPhoneCtrl.dispose();
|
||||
_targetSerialCtrl.dispose();
|
||||
_targetPasswordCtrl.dispose();
|
||||
_sourcePasswordCtrl.dispose();
|
||||
_sourceSerialCtrl.dispose();
|
||||
_requestCtrl.dispose();
|
||||
_accessoriesCtrl.dispose();
|
||||
@@ -76,9 +83,15 @@ class _TicketFormScreenState extends State<TicketFormScreen> {
|
||||
if (_targetSerialCtrl.text.isEmpty) {
|
||||
_targetSerialCtrl.text = model.targetSn ?? '';
|
||||
}
|
||||
if (_targetPasswordCtrl.text.isEmpty) {
|
||||
_targetPasswordCtrl.text = model.targetPassword ?? '';
|
||||
}
|
||||
if (_sourceSerialCtrl.text.isEmpty) {
|
||||
_sourceSerialCtrl.text = model.sourceSn ?? '';
|
||||
}
|
||||
if (_sourcePasswordCtrl.text.isEmpty) {
|
||||
_sourcePasswordCtrl.text = model.sourcePassword ?? '';
|
||||
}
|
||||
if (_requestCtrl.text.isEmpty) _requestCtrl.text = model.request;
|
||||
if (_accessoriesCtrl.text.isEmpty) {
|
||||
_accessoriesCtrl.text = model.includedAccessories ?? '';
|
||||
@@ -102,6 +115,8 @@ class _TicketFormScreenState extends State<TicketFormScreen> {
|
||||
context.read<TicketFormCubit>().updateFields(
|
||||
alternativePhoneNumber: _altPhoneCtrl.text,
|
||||
targetSn: _targetSerialCtrl.text,
|
||||
targetPassword: _targetPasswordCtrl.text,
|
||||
sourcePassword: _sourcePasswordCtrl.text,
|
||||
sourceSn: _sourceSerialCtrl.text,
|
||||
request: _requestCtrl.text,
|
||||
includedAccessories: _accessoriesCtrl.text,
|
||||
@@ -275,6 +290,7 @@ class _TicketFormScreenState extends State<TicketFormScreen> {
|
||||
}
|
||||
|
||||
if (state.status == TicketFormStatus.success) {
|
||||
context.read<TicketListCubit>().fetchTickets();
|
||||
_showSuccessActions(
|
||||
context,
|
||||
state.ticket,
|
||||
@@ -313,7 +329,7 @@ class _TicketFormScreenState extends State<TicketFormScreen> {
|
||||
|
||||
// CONDIZIONE A: Da iniziare
|
||||
if (ticket.ticketStatus == TicketStatus.open ||
|
||||
ticket.ticketStatus == TicketStatus.inProgress) {
|
||||
ticket.ticketStatus == TicketStatus.waitingForParts) {
|
||||
return Padding(
|
||||
padding: const EdgeInsets.symmetric(
|
||||
horizontal: 16.0,
|
||||
@@ -324,28 +340,27 @@ class _TicketFormScreenState extends State<TicketFormScreen> {
|
||||
backgroundColor:
|
||||
Colors.amber.shade700, // Colore Action
|
||||
),
|
||||
onPressed: () {
|
||||
final currentUserId = GetIt.I
|
||||
.get<SessionCubit>()
|
||||
.state
|
||||
.currentStaffMember!
|
||||
.id!;
|
||||
final currentUserName = GetIt.I
|
||||
.get<SessionCubit>()
|
||||
.state
|
||||
.currentStaffMember!
|
||||
.name;
|
||||
|
||||
context.read<TicketFormCubit>().takeInCharge(
|
||||
staffId: currentUserId,
|
||||
staffName: currentUserName,
|
||||
onPressed: () async {
|
||||
StaffMemberModel? takenBy = await getStaffMember(
|
||||
context,
|
||||
);
|
||||
|
||||
if (takenBy == null || !context.mounted) return;
|
||||
final formCubit = context.read<TicketFormCubit>();
|
||||
_flushControllersToCubit();
|
||||
context.read<TicketFormCubit>().takeInCharge(
|
||||
staffId: takenBy.id!,
|
||||
staffName: takenBy.name,
|
||||
);
|
||||
if (!context.mounted) return;
|
||||
Navigator.push(
|
||||
context,
|
||||
MaterialPageRoute(
|
||||
builder: (_) =>
|
||||
TicketWorkspaceScreen(ticket: ticket),
|
||||
builder: (_) => BlocProvider.value(
|
||||
value:
|
||||
formCubit, // Magia! La nuova schermata userà lo stesso Cubit!
|
||||
child:
|
||||
const TicketWorkspaceScreen(), // Non passiamo più il ticket
|
||||
),
|
||||
),
|
||||
);
|
||||
},
|
||||
@@ -366,8 +381,21 @@ class _TicketFormScreenState extends State<TicketFormScreen> {
|
||||
),
|
||||
child: FilledButton.icon(
|
||||
onPressed: () {
|
||||
final formCubit = context.read<TicketFormCubit>();
|
||||
// Naviga direttamente alla schermata di lavorazione
|
||||
// Navigator.push(context, MaterialPageRoute(builder: (_) => TicketWorkspaceScreen(ticket: ticket)));
|
||||
_flushControllersToCubit();
|
||||
if (!context.mounted) return;
|
||||
Navigator.push(
|
||||
context,
|
||||
MaterialPageRoute(
|
||||
builder: (_) => BlocProvider.value(
|
||||
value:
|
||||
formCubit, // Magia! La nuova schermata userà lo stesso Cubit!
|
||||
child:
|
||||
const TicketWorkspaceScreen(), // Non passiamo più il ticket
|
||||
),
|
||||
),
|
||||
);
|
||||
},
|
||||
icon: const Icon(Icons.handyman),
|
||||
label: const Text('Vai a Lavorazione'),
|
||||
@@ -614,6 +642,14 @@ class _TicketFormScreenState extends State<TicketFormScreen> {
|
||||
prefixIcon: Icon(Icons.qr_code),
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 16),
|
||||
TextFormField(
|
||||
controller: _targetPasswordCtrl, // Controller per il seriale TARGET
|
||||
decoration: const InputDecoration(
|
||||
labelText: 'PIN / Password',
|
||||
prefixIcon: Icon(Icons.qr_code),
|
||||
),
|
||||
),
|
||||
|
||||
// --- DISPOSITIVO SORGENTE (Animato per Passaggio Dati) ---
|
||||
AnimatedSize(
|
||||
@@ -704,6 +740,38 @@ class _TicketFormScreenState extends State<TicketFormScreen> {
|
||||
),
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 16),
|
||||
TextFormField(
|
||||
controller: _sourcePasswordCtrl,
|
||||
decoration: InputDecoration(
|
||||
labelText: 'PIN / Password Sorgente',
|
||||
prefixIcon: Icon(
|
||||
Icons.qr_code,
|
||||
color: Colors.orange.shade700.withValues(
|
||||
alpha: 0.7,
|
||||
),
|
||||
),
|
||||
// Usiamo lo stesso riempimento tenue per coerenza
|
||||
fillColor: Colors.white.withValues(alpha: 0.1),
|
||||
filled: true,
|
||||
enabledBorder: OutlineInputBorder(
|
||||
borderSide: BorderSide(
|
||||
color: Colors.orange.shade300.withValues(
|
||||
alpha: 0.2,
|
||||
),
|
||||
),
|
||||
borderRadius: BorderRadius.circular(8),
|
||||
),
|
||||
focusedBorder: OutlineInputBorder(
|
||||
borderSide: BorderSide(
|
||||
color: Colors.orange.shade500.withValues(
|
||||
alpha: 0.5,
|
||||
),
|
||||
),
|
||||
borderRadius: BorderRadius.circular(8),
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
@@ -755,6 +823,26 @@ class _TicketFormScreenState extends State<TicketFormScreen> {
|
||||
),
|
||||
],
|
||||
),
|
||||
if (ticket.ticketType == TicketType.repair) ...[
|
||||
const SizedBox(height: 16),
|
||||
DropdownButtonFormField<WarrantyType>(
|
||||
initialValue: ticket
|
||||
.warrantyType, // Assicurati di avere questo campo nel TicketModel
|
||||
decoration: const InputDecoration(
|
||||
labelText: 'Tipo Garanzia',
|
||||
prefixIcon: Icon(Icons.verified_user_outlined),
|
||||
),
|
||||
items: WarrantyType.values
|
||||
.map(
|
||||
(w) =>
|
||||
DropdownMenuItem(value: w, child: Text(w.displayValue)),
|
||||
)
|
||||
.toList(),
|
||||
onChanged: (val) {
|
||||
context.read<TicketFormCubit>().updateFields(warrantyType: val);
|
||||
},
|
||||
),
|
||||
],
|
||||
const SizedBox(height: 16),
|
||||
TextFormField(
|
||||
controller: _requestCtrl,
|
||||
|
||||
Reference in New Issue
Block a user