added product import and billing integration
This commit is contained in:
@@ -350,20 +350,41 @@ class _PaymentScreenState extends ConsumerState<PaymentScreen> {
|
||||
return GlassCard(
|
||||
padding: const EdgeInsets.all(AppSpacing.lg),
|
||||
radius: AppRadius.xl,
|
||||
child: state.activeMethod.needsChange
|
||||
? _cashTender(controller)
|
||||
: _referenceTender(controller, state),
|
||||
child: _amountTender(controller, state),
|
||||
);
|
||||
}
|
||||
|
||||
Widget _cashTender(PaymentController controller) {
|
||||
/// Amount entry for whichever method is active. Every method works the
|
||||
/// same way now — a keypad, an Exact shortcut, and an explicit amount —
|
||||
/// rather than cash alone asking what was received while card/UPI/wallet
|
||||
/// silently assumed the full balance. Cash additionally gets denomination
|
||||
/// chips and a change-due row, since only cash can be over-tendered; a
|
||||
/// method that captures a reference (card, UPI, gift card) additionally
|
||||
/// gets that field below the keypad.
|
||||
Widget _amountTender(PaymentController controller, PaymentState state) {
|
||||
final cash = state.activeMethod.needsChange;
|
||||
|
||||
return Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.stretch,
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
const Text(
|
||||
'Cash received',
|
||||
style: TextStyle(fontSize: 15, fontWeight: FontWeight.w600),
|
||||
Row(
|
||||
children: [
|
||||
Text(state.activeMethod.emoji, style: const TextStyle(fontSize: 20)),
|
||||
const SizedBox(width: AppSpacing.sm),
|
||||
Expanded(
|
||||
child: Text(
|
||||
cash
|
||||
? 'Cash received'
|
||||
: '${state.activeMethod.label} amount received',
|
||||
overflow: TextOverflow.ellipsis,
|
||||
style: const TextStyle(
|
||||
fontSize: 15,
|
||||
fontWeight: FontWeight.w600,
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
const SizedBox(height: AppSpacing.md),
|
||||
Container(
|
||||
@@ -405,16 +426,20 @@ class _PaymentScreenState extends ConsumerState<PaymentScreen> {
|
||||
label: const Text('Exact'),
|
||||
onPressed: () => _setCash(controller.balanceDue),
|
||||
),
|
||||
for (final note in const [50, 100, 200, 500, 2000])
|
||||
ActionChip(
|
||||
label: Text('₹$note'),
|
||||
onPressed: () =>
|
||||
_setCash((double.tryParse(_cashBuffer) ?? 0) + note),
|
||||
),
|
||||
// Denomination shortcuts only make sense for physical notes.
|
||||
if (cash)
|
||||
for (final note in const [50, 100, 200, 500, 2000])
|
||||
ActionChip(
|
||||
label: Text('₹$note'),
|
||||
onPressed: () =>
|
||||
_setCash((double.tryParse(_cashBuffer) ?? 0) + note),
|
||||
),
|
||||
],
|
||||
),
|
||||
const SizedBox(height: AppSpacing.md),
|
||||
_changeRow(controller.changeDue),
|
||||
if (cash) ...[
|
||||
const SizedBox(height: AppSpacing.md),
|
||||
_changeRow(controller.changeDue),
|
||||
],
|
||||
const SizedBox(height: AppSpacing.md),
|
||||
Center(
|
||||
child: NumericKeypad(
|
||||
@@ -424,6 +449,21 @@ class _PaymentScreenState extends ConsumerState<PaymentScreen> {
|
||||
onBackspace: _backspaceCash,
|
||||
),
|
||||
),
|
||||
if (state.activeMethod.needsReference) ...[
|
||||
const SizedBox(height: AppSpacing.md),
|
||||
TextField(
|
||||
onChanged: controller.setReference,
|
||||
decoration: InputDecoration(
|
||||
labelText: switch (state.activeMethod) {
|
||||
PaymentMethod.card => 'Approval code',
|
||||
PaymentMethod.upi => 'UPI transaction ID',
|
||||
PaymentMethod.giftCard => 'Gift card number',
|
||||
_ => 'Reference',
|
||||
},
|
||||
prefixIcon: const Icon(Icons.tag_rounded),
|
||||
),
|
||||
),
|
||||
],
|
||||
const SizedBox(height: AppSpacing.md),
|
||||
_splitButton(controller, amount: double.tryParse(_cashBuffer) ?? 0),
|
||||
],
|
||||
@@ -473,71 +513,6 @@ class _PaymentScreenState extends ConsumerState<PaymentScreen> {
|
||||
);
|
||||
}
|
||||
|
||||
Widget _referenceTender(PaymentController controller, PaymentState state) {
|
||||
return Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.stretch,
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
Row(
|
||||
children: [
|
||||
Text(state.activeMethod.emoji,
|
||||
style: const TextStyle(fontSize: 20),),
|
||||
const SizedBox(width: AppSpacing.sm),
|
||||
Expanded(
|
||||
child: Text(
|
||||
'${state.activeMethod.label} payment',
|
||||
overflow: TextOverflow.ellipsis,
|
||||
style:
|
||||
const TextStyle(fontSize: 15, fontWeight: FontWeight.w600),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
const SizedBox(height: AppSpacing.xxl),
|
||||
Center(
|
||||
child: Container(
|
||||
width: 104,
|
||||
height: 104,
|
||||
decoration: const BoxDecoration(
|
||||
color: AppColors.primarySurface,
|
||||
borderRadius: AppRadius.brXl,
|
||||
),
|
||||
alignment: Alignment.center,
|
||||
child: Text(state.activeMethod.emoji,
|
||||
style: const TextStyle(fontSize: 46),),
|
||||
),
|
||||
),
|
||||
const SizedBox(height: AppSpacing.lg),
|
||||
Text(
|
||||
'Charge ${Formatters.money(controller.balanceDue)} on the '
|
||||
'${state.activeMethod.label.toLowerCase()} terminal',
|
||||
textAlign: TextAlign.center,
|
||||
style: const TextStyle(
|
||||
fontSize: 13.5,
|
||||
color: AppColors.textSecondary,
|
||||
height: 1.5,
|
||||
),
|
||||
),
|
||||
const SizedBox(height: AppSpacing.xxl),
|
||||
if (state.activeMethod.needsReference)
|
||||
TextField(
|
||||
onChanged: controller.setReference,
|
||||
decoration: InputDecoration(
|
||||
labelText: switch (state.activeMethod) {
|
||||
PaymentMethod.card => 'Approval code',
|
||||
PaymentMethod.upi => 'UPI transaction ID',
|
||||
PaymentMethod.giftCard => 'Gift card number',
|
||||
_ => 'Reference',
|
||||
},
|
||||
prefixIcon: const Icon(Icons.tag_rounded),
|
||||
),
|
||||
),
|
||||
const SizedBox(height: AppSpacing.lg),
|
||||
_splitButton(controller),
|
||||
],
|
||||
);
|
||||
}
|
||||
|
||||
Widget _splitButton(PaymentController controller, {double? amount}) {
|
||||
return OutlinedButton.icon(
|
||||
onPressed: controller.balanceDue > 0
|
||||
@@ -622,18 +597,17 @@ class _PaymentScreenState extends ConsumerState<PaymentScreen> {
|
||||
),
|
||||
),
|
||||
),
|
||||
if (state.activeMethod.needsChange)
|
||||
TextButton(
|
||||
onPressed: () => _setCash(controller.balanceDue),
|
||||
style: TextButton.styleFrom(
|
||||
minimumSize: const Size(0, 30),
|
||||
padding: const EdgeInsets.symmetric(
|
||||
horizontal: AppSpacing.md,
|
||||
),
|
||||
TextButton(
|
||||
onPressed: () => _setCash(controller.balanceDue),
|
||||
style: TextButton.styleFrom(
|
||||
minimumSize: const Size(0, 30),
|
||||
padding: const EdgeInsets.symmetric(
|
||||
horizontal: AppSpacing.md,
|
||||
),
|
||||
child: const Text('Exact',
|
||||
style: TextStyle(fontSize: 12.5),),
|
||||
),
|
||||
child: const Text('Exact',
|
||||
style: TextStyle(fontSize: 12.5),),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
|
||||
Reference in New Issue
Block a user