import 'package:flutter/material.dart'; import 'package:niogu_app/core/constants/app_color.dart'; import 'package:niogu_app/core/constants/app_font_size.dart'; import 'package:niogu_app/core/utils/currency_format.dart'; import 'package:niogu_app/core/widgets/custom_form_input.dart'; import 'package:niogu_app/features/stock_in/domain/entities/stock_in.dart'; import 'package:sizer/sizer.dart'; class FinancialSection extends StatelessWidget { final GlobalKey formKey; final double totalPurchase; final bool isOtherFormVisible; final List items; final bool validateChange; final double totalAmount; final String selectedPaymentStatus; final VoidCallback onOtherFormTap; final TextEditingController discountController; final TextEditingController taxController; final TextEditingController noteController; final TextEditingController payController; final void Function(String)? onCalculateChange; final double changeAmount; final void Function(String)? discountOnChanged; final void Function(String)? taxOnChanged; final void Function(String?) onChanged; const FinancialSection({ super.key, required this.formKey, required this.totalPurchase, required this.isOtherFormVisible, required this.items, required this.validateChange, required this.totalAmount, required this.selectedPaymentStatus, required this.onOtherFormTap, required this.discountController, required this.taxController, required this.noteController, required this.payController, required this.onCalculateChange, required this.changeAmount, required this.discountOnChanged, required this.taxOnChanged, required this.onChanged, }); @override Widget build(BuildContext context) { final bool isTablet = 100.w >= 600; String? discountErrorText; String? taxErrorText; String? payErrorText; final double payAmount = double.tryParse(payController.text.trim()) ?? 0.0; bool isViewChangeAmount = payAmount >= totalAmount && items.isNotEmpty; if (selectedPaymentStatus == 'Bayar Sebagian') { isViewChangeAmount = totalAmount > payAmount && items.isNotEmpty; } try { if (discountController.text.isNotEmpty) { final double discount = double.parse(discountController.text.trim()); if (discount <= 0) { discountErrorText = "Diskon harus lebih dari 0"; } } } catch (e) { discountErrorText = "Nominal diskon tidak valid"; } try { if (taxController.text.isNotEmpty) { final double tax = double.parse(taxController.text.trim()); if (tax <= 0) { taxErrorText = "Pajak harus lebih dari 0"; } } } catch (e) { taxErrorText = "Nominal pajak tidak valid"; } try { if (payController.text.isNotEmpty && validateChange) { final double payAmount = double.parse(payController.text.trim()); if (payAmount <= 0) { payErrorText = "Nominal pembayaran harus lebih dari 0"; } if (selectedPaymentStatus == 'Lunas' && totalAmount > payAmount) { payErrorText = "Kurang ${CurrencyFormat.formatToIdr((totalAmount - payAmount), 0)}"; } } } catch (e) { payErrorText = "Nominal pembayaran tidak valid"; } return Container( padding: EdgeInsets.all(4.w), decoration: BoxDecoration( color: Colors.white, borderRadius: BorderRadius.circular(2.5.w), border: Border.all(color: Colors.grey.shade200), ), child: Form( key: formKey, child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ Text( "Subtotal", style: TextStyle( color: Colors.grey[700], fontSize: isTablet ? AppFontSize.medium.sp : AppFontSize.small.sp, ), ), Text( CurrencyFormat.formatToIdr(totalPurchase, 0), style: TextStyle( fontWeight: FontWeight.bold, fontSize: isTablet ? AppFontSize.medium.sp : AppFontSize.small.sp, ), ), ], ), Divider(height: 3.h), Container( decoration: BoxDecoration( color: Colors.white, borderRadius: BorderRadius.circular(2.5.w), border: Border.all(color: Colors.grey.shade300), ), child: Column( children: [ InkWell( onTap: onOtherFormTap, borderRadius: BorderRadius.vertical( top: Radius.circular(2.5.w), bottom: Radius.circular(isOtherFormVisible ? 0 : 2.5.w), ), child: Padding( padding: EdgeInsets.symmetric( horizontal: 4.w, vertical: 1.5.h, ), child: Row( children: [ Container( padding: EdgeInsets.all(1.5.w), decoration: BoxDecoration( color: isOtherFormVisible ? AppColor.primaryColor.withOpacity(0.1) : Colors.grey[100], shape: BoxShape.circle, ), child: Icon( Icons.info_outlined, color: isOtherFormVisible ? AppColor.primaryColor : Colors.grey, size: 5.w, ), ), SizedBox(width: 3.w), Expanded( child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( "Informasi Lain", style: TextStyle( fontWeight: FontWeight.bold, fontSize: isTablet ? AppFontSize.medium.sp : AppFontSize.small.sp, color: Colors.black87, ), ), SizedBox(height: 1.h), Text( "Opsional (Diskon, Pajak, Catatan)", style: TextStyle( fontSize: isTablet ? AppFontSize.medium.sp : AppFontSize.small.sp, color: Colors.grey, ), ), ], ), ), Icon( isOtherFormVisible ? Icons.keyboard_arrow_up_rounded : Icons.keyboard_arrow_down_rounded, color: Colors.grey, size: 6.w, ), ], ), ), ), if (isOtherFormVisible) ...[ Divider(height: 1, color: Colors.grey.shade200), Padding( padding: EdgeInsets.all(4.w), child: Column( children: [ CustomFormInput( label: "Diskon (Rp)", icon: Icons.discount_outlined, controller: discountController, onChanged: discountOnChanged, inputType: TextInputType.number, validator: (value) { if (value != null && value.isNotEmpty) { try { final double discount = double.parse(value); if (discount <= 0) { return "Diskon harus lebih dari 0"; } } catch (e) { return "Nominal diskon tidak valid"; } } return null; }, errorText: discountErrorText, ), SizedBox(height: 1.5.h), CustomFormInput( label: "Pajak (Rp)", icon: Icons.money_outlined, controller: taxController, onChanged: taxOnChanged, inputType: TextInputType.number, validator: (value) { if (value != null && value.isNotEmpty) { try { final double tax = double.parse(value); if (tax <= 0) { return "Pajak harus lebih dari 0"; } } catch (e) { return "Nominal pajak tidak valid"; } } return null; }, errorText: taxErrorText, ), SizedBox(height: 1.5.h), CustomFormInput( label: "Catatan", icon: Icons.note_alt_outlined, controller: noteController, ), ], ), ), ], ], ), ), SizedBox(height: 2.h), Container( padding: EdgeInsets.all(3.w), decoration: BoxDecoration( color: AppColor.primaryColor.withOpacity(0.05), borderRadius: BorderRadius.circular(2.w), ), child: Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ Text( "Total Pembelian", style: TextStyle( fontWeight: FontWeight.bold, fontSize: isTablet ? AppFontSize.medium.sp : AppFontSize.small.sp, ), ), Text( CurrencyFormat.formatToIdr(totalAmount, 0), style: TextStyle( fontWeight: FontWeight.bold, fontSize: isTablet ? AppFontSize.medium.sp : AppFontSize.small.sp, color: AppColor.primaryColor, ), ), ], ), ), SizedBox(height: 2.h), Text( "Status Pembelian", style: TextStyle( fontSize: isTablet ? AppFontSize.medium.sp : AppFontSize.small.sp, fontWeight: FontWeight.bold, ), ), SizedBox(height: 1.h), DropdownButtonFormField( value: selectedPaymentStatus, isExpanded: true, items: ["Lunas", "Bayar Sebagian", "Hutang"] .map( (value) => DropdownMenuItem( value: value, child: Text( value, style: isTablet ? null : TextStyle(fontSize: AppFontSize.small.sp), ), ), ) .toList(), onChanged: onChanged, icon: const Icon(Icons.keyboard_arrow_down_rounded), decoration: InputDecoration( filled: true, fillColor: Colors.white, contentPadding: EdgeInsets.symmetric( horizontal: 4.w, vertical: 1.8.h, ), enabledBorder: OutlineInputBorder( borderRadius: BorderRadius.circular(2.5.w), borderSide: BorderSide(color: Colors.grey.shade300), ), focusedBorder: OutlineInputBorder( borderRadius: BorderRadius.circular(2.5.w), borderSide: const BorderSide( color: AppColor.primaryColor, width: 1.5, ), ), ), ), SizedBox(height: 2.h), if (selectedPaymentStatus == 'Lunas' || selectedPaymentStatus == 'Bayar Sebagian') ...[ Text( "Pembayaran", style: TextStyle( fontWeight: FontWeight.bold, fontSize: isTablet ? AppFontSize.medium.sp : AppFontSize.small.sp, ), ), SizedBox(height: 1.h), TextFormField( controller: payController, keyboardType: TextInputType.number, style: TextStyle( fontSize: isTablet ? AppFontSize.medium.sp : AppFontSize.small.sp, ), autovalidateMode: AutovalidateMode.onUserInteraction, onChanged: onCalculateChange, validator: (value) { try { if (value == null || value.isEmpty) { return "Masukkan nominal pembayaran"; } final double payAmount = double.parse(value); if (payAmount <= 0) { return "Nominal pembayaran harus lebih dari 0"; } } catch (e) { return "Nominal pembayaran tidak valid"; } return null; }, decoration: InputDecoration( labelText: "Bayar (Rp)", labelStyle: TextStyle( color: Colors.blue, fontSize: AppFontSize.medium.sp, ), prefixIcon: Padding( padding: isTablet ? EdgeInsets.symmetric(horizontal: 3.w) : EdgeInsets.zero, child: Icon( Icons.payments_outlined, color: Colors.blue, size: 5.w, ), ), border: OutlineInputBorder( borderRadius: BorderRadius.circular(2.5.w), ), errorText: payErrorText, errorStyle: TextStyle( color: Colors.red, fontSize: isTablet ? AppFontSize.medium.sp : AppFontSize.small.sp, ), errorBorder: OutlineInputBorder( borderRadius: BorderRadius.circular(2.5.w), borderSide: const BorderSide(color: Colors.redAccent), ), enabledBorder: OutlineInputBorder( borderRadius: BorderRadius.circular(2.5.w), borderSide: const BorderSide(color: Colors.blue), ), contentPadding: EdgeInsets.symmetric( vertical: isTablet ? 3.6.h : 1.8.h, ), ), ), SizedBox(height: 2.h), TextField( controller: TextEditingController( text: isViewChangeAmount ? CurrencyFormat.formatToIdr(changeAmount, 0) : '', ), readOnly: true, decoration: InputDecoration( labelText: selectedPaymentStatus == 'Lunas' ? "Kembali" : 'Kurang Bayar', labelStyle: TextStyle(fontSize: AppFontSize.medium.sp), prefixIcon: Padding( padding: isTablet ? EdgeInsets.symmetric(horizontal: 3.w) : EdgeInsets.zero, child: Icon( Icons.change_circle_outlined, color: selectedPaymentStatus == 'Lunas' ? Colors.green : Colors.red, size: 5.w, ), ), filled: true, fillColor: Colors.grey[100], border: OutlineInputBorder( borderRadius: BorderRadius.circular(2.5.w), borderSide: BorderSide.none, ), contentPadding: EdgeInsets.symmetric( vertical: isTablet ? 3.6.h : 1.8.h, ), ), style: TextStyle( fontSize: isTablet ? AppFontSize.medium.sp : AppFontSize.small.sp, fontWeight: FontWeight.bold, color: selectedPaymentStatus == 'Lunas' ? Colors.green : Colors.red, ), ), ] else ...[ TextField( controller: TextEditingController( text: items.isNotEmpty ? CurrencyFormat.formatToIdr(totalAmount, 0) : '', ), readOnly: true, decoration: InputDecoration( labelText: 'Hutang', labelStyle: TextStyle(fontSize: AppFontSize.medium.sp), prefixIcon: Padding( padding: isTablet ? EdgeInsets.symmetric(horizontal: 3.w) : EdgeInsets.zero, child: Icon( Icons.change_circle_outlined, color: Colors.red, size: 5.w, ), ), filled: true, fillColor: Colors.grey[100], border: OutlineInputBorder( borderRadius: BorderRadius.circular(2.5.w), borderSide: BorderSide.none, ), contentPadding: EdgeInsets.symmetric( vertical: isTablet ? 3.6.h : 1.8.h, ), ), style: TextStyle( fontSize: isTablet ? AppFontSize.medium.sp : AppFontSize.small.sp, fontWeight: FontWeight.bold, color: Colors.red, ), ), ], ], ), ), ); } }