order success
This commit is contained in:
@@ -56,10 +56,11 @@ class CheckoutPage extends HookConsumerWidget {
|
|||||||
// Payment method (will be set to first payment term name from API)
|
// Payment method (will be set to first payment term name from API)
|
||||||
final paymentMethod = useState<String>('');
|
final paymentMethod = useState<String>('');
|
||||||
|
|
||||||
// Price negotiation
|
// Price negotiation (ignore_pricing_rule in API)
|
||||||
final needsNegotiation = useState<bool>(false);
|
final ignorePricingRule = useState<bool>(false);
|
||||||
|
|
||||||
final needsContract = useState(false);
|
// Contract request (contract_request in API)
|
||||||
|
final contractRequest = useState<bool>(false);
|
||||||
|
|
||||||
// Watch API provider for payment terms
|
// Watch API provider for payment terms
|
||||||
final paymentTermsListAsync = ref.watch(paymentTermsListProvider);
|
final paymentTermsListAsync = ref.watch(paymentTermsListProvider);
|
||||||
@@ -145,8 +146,8 @@ class CheckoutPage extends HookConsumerWidget {
|
|||||||
|
|
||||||
const SizedBox(height: AppSpacing.md),
|
const SizedBox(height: AppSpacing.md),
|
||||||
|
|
||||||
// Payment Method Section (hidden if negotiation is checked)
|
// Payment Method Section (hidden if price negotiation is checked)
|
||||||
if (!needsNegotiation.value)
|
if (!ignorePricingRule.value)
|
||||||
paymentTermsListAsync.when(
|
paymentTermsListAsync.when(
|
||||||
data: (paymentTerms) {
|
data: (paymentTerms) {
|
||||||
// Set default payment method to first term if not set
|
// Set default payment method to first term if not set
|
||||||
@@ -220,7 +221,7 @@ class CheckoutPage extends HookConsumerWidget {
|
|||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
|
||||||
if (!needsNegotiation.value)
|
if (!ignorePricingRule.value)
|
||||||
const SizedBox(height: AppSpacing.md),
|
const SizedBox(height: AppSpacing.md),
|
||||||
|
|
||||||
// Discount Code Section
|
// Discount Code Section
|
||||||
@@ -240,7 +241,7 @@ class CheckoutPage extends HookConsumerWidget {
|
|||||||
const SizedBox(height: AppSpacing.md),
|
const SizedBox(height: AppSpacing.md),
|
||||||
|
|
||||||
// Price Negotiation Section
|
// Price Negotiation Section
|
||||||
PriceNegotiationSection(needsNegotiation: needsNegotiation),
|
PriceNegotiationSection(ignorePricingRule: ignorePricingRule),
|
||||||
|
|
||||||
const SizedBox(height: AppSpacing.md),
|
const SizedBox(height: AppSpacing.md),
|
||||||
|
|
||||||
@@ -256,9 +257,9 @@ class CheckoutPage extends HookConsumerWidget {
|
|||||||
child: Row(
|
child: Row(
|
||||||
children: [
|
children: [
|
||||||
Checkbox(
|
Checkbox(
|
||||||
value: needsContract.value,
|
value: contractRequest.value,
|
||||||
onChanged: (value) {
|
onChanged: (value) {
|
||||||
needsContract.value = value ?? false;
|
contractRequest.value = value ?? false;
|
||||||
},
|
},
|
||||||
activeColor: AppColors.warning,
|
activeColor: AppColors.warning,
|
||||||
),
|
),
|
||||||
@@ -308,7 +309,8 @@ class CheckoutPage extends HookConsumerWidget {
|
|||||||
// Place Order Button
|
// Place Order Button
|
||||||
CheckoutSubmitButton(
|
CheckoutSubmitButton(
|
||||||
formKey: formKey,
|
formKey: formKey,
|
||||||
needsNegotiation: needsNegotiation.value,
|
ignorePricingRule: ignorePricingRule.value,
|
||||||
|
contractRequest: contractRequest.value,
|
||||||
needsInvoice: needsInvoice.value,
|
needsInvoice: needsInvoice.value,
|
||||||
selectedAddress: selectedAddress.value,
|
selectedAddress: selectedAddress.value,
|
||||||
paymentMethod: paymentMethod.value,
|
paymentMethod: paymentMethod.value,
|
||||||
|
|||||||
@@ -20,7 +20,8 @@ class CheckoutSubmitButton extends HookConsumerWidget {
|
|||||||
const CheckoutSubmitButton({
|
const CheckoutSubmitButton({
|
||||||
super.key,
|
super.key,
|
||||||
required this.formKey,
|
required this.formKey,
|
||||||
required this.needsNegotiation,
|
required this.ignorePricingRule,
|
||||||
|
required this.contractRequest,
|
||||||
required this.needsInvoice,
|
required this.needsInvoice,
|
||||||
required this.selectedAddress,
|
required this.selectedAddress,
|
||||||
required this.paymentMethod,
|
required this.paymentMethod,
|
||||||
@@ -30,7 +31,8 @@ class CheckoutSubmitButton extends HookConsumerWidget {
|
|||||||
});
|
});
|
||||||
|
|
||||||
final GlobalKey<FormState> formKey;
|
final GlobalKey<FormState> formKey;
|
||||||
final bool needsNegotiation;
|
final bool ignorePricingRule;
|
||||||
|
final bool contractRequest;
|
||||||
final bool needsInvoice;
|
final bool needsInvoice;
|
||||||
final Address? selectedAddress;
|
final Address? selectedAddress;
|
||||||
final String paymentMethod;
|
final String paymentMethod;
|
||||||
@@ -62,7 +64,7 @@ class CheckoutSubmitButton extends HookConsumerWidget {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
style: ElevatedButton.styleFrom(
|
style: ElevatedButton.styleFrom(
|
||||||
backgroundColor: needsNegotiation
|
backgroundColor: ignorePricingRule
|
||||||
? AppColors.warning
|
? AppColors.warning
|
||||||
: AppColors.primaryBlue,
|
: AppColors.primaryBlue,
|
||||||
foregroundColor: Colors.white,
|
foregroundColor: Colors.white,
|
||||||
@@ -73,7 +75,7 @@ class CheckoutSubmitButton extends HookConsumerWidget {
|
|||||||
),
|
),
|
||||||
),
|
),
|
||||||
child: Text(
|
child: Text(
|
||||||
needsNegotiation ? 'Gửi yêu cầu đàm phán' : 'Đặt hàng',
|
ignorePricingRule ? 'Gửi yêu cầu đàm phán' : 'Đặt hàng',
|
||||||
style: const TextStyle(
|
style: const TextStyle(
|
||||||
fontSize: 16,
|
fontSize: 16,
|
||||||
fontWeight: FontWeight.w600,
|
fontWeight: FontWeight.w600,
|
||||||
@@ -122,7 +124,8 @@ class CheckoutSubmitButton extends HookConsumerWidget {
|
|||||||
deliveryAddress: deliveryAddressData,
|
deliveryAddress: deliveryAddressData,
|
||||||
paymentMethod: paymentMethod,
|
paymentMethod: paymentMethod,
|
||||||
needsInvoice: needsInvoice,
|
needsInvoice: needsInvoice,
|
||||||
needsNegotiation: needsNegotiation,
|
ignorePricingRule: ignorePricingRule,
|
||||||
|
contractRequest: contractRequest,
|
||||||
notes: notes,
|
notes: notes,
|
||||||
).future);
|
).future);
|
||||||
|
|
||||||
@@ -131,7 +134,7 @@ class CheckoutSubmitButton extends HookConsumerWidget {
|
|||||||
result['orderId'] as String? ??
|
result['orderId'] as String? ??
|
||||||
'DH${DateTime.now().millisecondsSinceEpoch.toString().substring(7)}';
|
'DH${DateTime.now().millisecondsSinceEpoch.toString().substring(7)}';
|
||||||
|
|
||||||
if (needsNegotiation) {
|
if (ignorePricingRule) {
|
||||||
// Navigate to order success page with negotiation flag
|
// Navigate to order success page with negotiation flag
|
||||||
if (context.mounted) {
|
if (context.mounted) {
|
||||||
Navigator.of(context).pop();
|
Navigator.of(context).pop();
|
||||||
|
|||||||
@@ -13,8 +13,8 @@ import 'package:worker/core/theme/colors.dart';
|
|||||||
/// Allows user to request price negotiation instead of direct order.
|
/// Allows user to request price negotiation instead of direct order.
|
||||||
class PriceNegotiationSection extends HookWidget {
|
class PriceNegotiationSection extends HookWidget {
|
||||||
|
|
||||||
const PriceNegotiationSection({super.key, required this.needsNegotiation});
|
const PriceNegotiationSection({super.key, required this.ignorePricingRule});
|
||||||
final ValueNotifier<bool> needsNegotiation;
|
final ValueNotifier<bool> ignorePricingRule;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
@@ -29,9 +29,9 @@ class PriceNegotiationSection extends HookWidget {
|
|||||||
child: Row(
|
child: Row(
|
||||||
children: [
|
children: [
|
||||||
Checkbox(
|
Checkbox(
|
||||||
value: needsNegotiation.value,
|
value: ignorePricingRule.value,
|
||||||
onChanged: (value) {
|
onChanged: (value) {
|
||||||
needsNegotiation.value = value ?? false;
|
ignorePricingRule.value = value ?? false;
|
||||||
},
|
},
|
||||||
activeColor: AppColors.warning,
|
activeColor: AppColors.warning,
|
||||||
),
|
),
|
||||||
|
|||||||
@@ -92,6 +92,8 @@ class OrderRemoteDataSource {
|
|||||||
/// "customer_address": "...",
|
/// "customer_address": "...",
|
||||||
/// "description": "...",
|
/// "description": "...",
|
||||||
/// "payment_terms": "...",
|
/// "payment_terms": "...",
|
||||||
|
/// "ignore_pricing_rule": true,
|
||||||
|
/// "contract_request": true,
|
||||||
/// "items": [{"item_id": "...", "qty_entered": 0, "primary_qty": 0, "price_entered": 0}]
|
/// "items": [{"item_id": "...", "qty_entered": 0, "primary_qty": 0, "price_entered": 0}]
|
||||||
/// }
|
/// }
|
||||||
/// Returns: { "message": { "name": "SAL-ORD-2025-00001", ... } }
|
/// Returns: { "message": { "name": "SAL-ORD-2025-00001", ... } }
|
||||||
@@ -100,7 +102,8 @@ class OrderRemoteDataSource {
|
|||||||
required Map<String, dynamic> deliveryAddress,
|
required Map<String, dynamic> deliveryAddress,
|
||||||
required String paymentMethod,
|
required String paymentMethod,
|
||||||
bool needsInvoice = false,
|
bool needsInvoice = false,
|
||||||
bool needsNegotiation = false,
|
bool ignorePricingRule = false,
|
||||||
|
bool contractRequest = false,
|
||||||
String? notes,
|
String? notes,
|
||||||
}) async {
|
}) async {
|
||||||
try {
|
try {
|
||||||
@@ -126,6 +129,8 @@ class OrderRemoteDataSource {
|
|||||||
'customer_address': deliveryAddress['name'] ?? '',
|
'customer_address': deliveryAddress['name'] ?? '',
|
||||||
'description': notes ?? 'Order from mobile app',
|
'description': notes ?? 'Order from mobile app',
|
||||||
'payment_terms': paymentMethod,
|
'payment_terms': paymentMethod,
|
||||||
|
'ignore_pricing_rule': ignorePricingRule,
|
||||||
|
'contract_request': contractRequest,
|
||||||
'items': formattedItems,
|
'items': formattedItems,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -98,7 +98,8 @@ class OrderRepositoryImpl implements OrderRepository {
|
|||||||
required Map<String, dynamic> deliveryAddress,
|
required Map<String, dynamic> deliveryAddress,
|
||||||
required String paymentMethod,
|
required String paymentMethod,
|
||||||
bool needsInvoice = false,
|
bool needsInvoice = false,
|
||||||
bool needsNegotiation = false,
|
bool ignorePricingRule = false,
|
||||||
|
bool contractRequest = false,
|
||||||
String? notes,
|
String? notes,
|
||||||
}) async {
|
}) async {
|
||||||
try {
|
try {
|
||||||
@@ -107,7 +108,8 @@ class OrderRepositoryImpl implements OrderRepository {
|
|||||||
deliveryAddress: deliveryAddress,
|
deliveryAddress: deliveryAddress,
|
||||||
paymentMethod: paymentMethod,
|
paymentMethod: paymentMethod,
|
||||||
needsInvoice: needsInvoice,
|
needsInvoice: needsInvoice,
|
||||||
needsNegotiation: needsNegotiation,
|
ignorePricingRule: ignorePricingRule,
|
||||||
|
contractRequest: contractRequest,
|
||||||
notes: notes,
|
notes: notes,
|
||||||
);
|
);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
|
|||||||
@@ -31,7 +31,8 @@ abstract class OrderRepository {
|
|||||||
required Map<String, dynamic> deliveryAddress,
|
required Map<String, dynamic> deliveryAddress,
|
||||||
required String paymentMethod,
|
required String paymentMethod,
|
||||||
bool needsInvoice = false,
|
bool needsInvoice = false,
|
||||||
bool needsNegotiation = false,
|
bool ignorePricingRule = false,
|
||||||
|
bool contractRequest = false,
|
||||||
String? notes,
|
String? notes,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -183,7 +183,7 @@ class OrderSuccessPage extends StatelessWidget {
|
|||||||
// Navigate to order details page
|
// Navigate to order details page
|
||||||
context.pushReplacementNamed(
|
context.pushReplacementNamed(
|
||||||
RouteNames.orderDetail,
|
RouteNames.orderDetail,
|
||||||
pathParameters: {'orderId': orderNumber},
|
pathParameters: {'id': orderNumber},
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
icon: const FaIcon(FontAwesomeIcons.eye, size: 18),
|
icon: const FaIcon(FontAwesomeIcons.eye, size: 18),
|
||||||
|
|||||||
@@ -31,7 +31,8 @@ Future<Map<String, dynamic>> createOrder(
|
|||||||
required Map<String, dynamic> deliveryAddress,
|
required Map<String, dynamic> deliveryAddress,
|
||||||
required String paymentMethod,
|
required String paymentMethod,
|
||||||
bool needsInvoice = false,
|
bool needsInvoice = false,
|
||||||
bool needsNegotiation = false,
|
bool ignorePricingRule = false,
|
||||||
|
bool contractRequest = false,
|
||||||
String? notes,
|
String? notes,
|
||||||
}) async {
|
}) async {
|
||||||
final repository = await ref.watch(orderRepositoryProvider.future);
|
final repository = await ref.watch(orderRepositoryProvider.future);
|
||||||
@@ -40,7 +41,8 @@ Future<Map<String, dynamic>> createOrder(
|
|||||||
deliveryAddress: deliveryAddress,
|
deliveryAddress: deliveryAddress,
|
||||||
paymentMethod: paymentMethod,
|
paymentMethod: paymentMethod,
|
||||||
needsInvoice: needsInvoice,
|
needsInvoice: needsInvoice,
|
||||||
needsNegotiation: needsNegotiation,
|
ignorePricingRule: ignorePricingRule,
|
||||||
|
contractRequest: contractRequest,
|
||||||
notes: notes,
|
notes: notes,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -83,7 +83,8 @@ final class CreateOrderProvider
|
|||||||
Map<String, dynamic> deliveryAddress,
|
Map<String, dynamic> deliveryAddress,
|
||||||
String paymentMethod,
|
String paymentMethod,
|
||||||
bool needsInvoice,
|
bool needsInvoice,
|
||||||
bool needsNegotiation,
|
bool ignorePricingRule,
|
||||||
|
bool contractRequest,
|
||||||
String? notes,
|
String? notes,
|
||||||
})
|
})
|
||||||
super.argument,
|
super.argument,
|
||||||
@@ -120,7 +121,8 @@ final class CreateOrderProvider
|
|||||||
Map<String, dynamic> deliveryAddress,
|
Map<String, dynamic> deliveryAddress,
|
||||||
String paymentMethod,
|
String paymentMethod,
|
||||||
bool needsInvoice,
|
bool needsInvoice,
|
||||||
bool needsNegotiation,
|
bool ignorePricingRule,
|
||||||
|
bool contractRequest,
|
||||||
String? notes,
|
String? notes,
|
||||||
});
|
});
|
||||||
return createOrder(
|
return createOrder(
|
||||||
@@ -129,7 +131,8 @@ final class CreateOrderProvider
|
|||||||
deliveryAddress: argument.deliveryAddress,
|
deliveryAddress: argument.deliveryAddress,
|
||||||
paymentMethod: argument.paymentMethod,
|
paymentMethod: argument.paymentMethod,
|
||||||
needsInvoice: argument.needsInvoice,
|
needsInvoice: argument.needsInvoice,
|
||||||
needsNegotiation: argument.needsNegotiation,
|
ignorePricingRule: argument.ignorePricingRule,
|
||||||
|
contractRequest: argument.contractRequest,
|
||||||
notes: argument.notes,
|
notes: argument.notes,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@@ -145,7 +148,7 @@ final class CreateOrderProvider
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
String _$createOrderHash() => r'2d13526815e19a2bbef2f2974dad991d8ffcb594';
|
String _$createOrderHash() => r'622a1d98d53a6696a302cde85842d449a8164fe7';
|
||||||
|
|
||||||
/// Create Order Provider
|
/// Create Order Provider
|
||||||
///
|
///
|
||||||
@@ -160,7 +163,8 @@ final class CreateOrderFamily extends $Family
|
|||||||
Map<String, dynamic> deliveryAddress,
|
Map<String, dynamic> deliveryAddress,
|
||||||
String paymentMethod,
|
String paymentMethod,
|
||||||
bool needsInvoice,
|
bool needsInvoice,
|
||||||
bool needsNegotiation,
|
bool ignorePricingRule,
|
||||||
|
bool contractRequest,
|
||||||
String? notes,
|
String? notes,
|
||||||
})
|
})
|
||||||
> {
|
> {
|
||||||
@@ -182,7 +186,8 @@ final class CreateOrderFamily extends $Family
|
|||||||
required Map<String, dynamic> deliveryAddress,
|
required Map<String, dynamic> deliveryAddress,
|
||||||
required String paymentMethod,
|
required String paymentMethod,
|
||||||
bool needsInvoice = false,
|
bool needsInvoice = false,
|
||||||
bool needsNegotiation = false,
|
bool ignorePricingRule = false,
|
||||||
|
bool contractRequest = false,
|
||||||
String? notes,
|
String? notes,
|
||||||
}) => CreateOrderProvider._(
|
}) => CreateOrderProvider._(
|
||||||
argument: (
|
argument: (
|
||||||
@@ -190,7 +195,8 @@ final class CreateOrderFamily extends $Family
|
|||||||
deliveryAddress: deliveryAddress,
|
deliveryAddress: deliveryAddress,
|
||||||
paymentMethod: paymentMethod,
|
paymentMethod: paymentMethod,
|
||||||
needsInvoice: needsInvoice,
|
needsInvoice: needsInvoice,
|
||||||
needsNegotiation: needsNegotiation,
|
ignorePricingRule: ignorePricingRule,
|
||||||
|
contractRequest: contractRequest,
|
||||||
notes: notes,
|
notes: notes,
|
||||||
),
|
),
|
||||||
from: this,
|
from: this,
|
||||||
|
|||||||
Reference in New Issue
Block a user