mirror of
https://github.com/Mercantec-GHC/h4-projekt-gruppe-0-sm.git
synced 2025-04-28 08:44:06 +02:00
Store prices as DkkCents and format kr
Co-authored-by: SimonFJ20 <simonfromjakobsen@gmail.com>
This commit is contained in:
parent
8a8dce419e
commit
17f2392ab6
@ -1,5 +1,6 @@
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:mobile/repos/product.dart';
|
import 'package:mobile/repos/product.dart';
|
||||||
|
import 'package:mobile/utils/price.dart';
|
||||||
import 'package:mobile/widgets/sized_card.dart';
|
import 'package:mobile/widgets/sized_card.dart';
|
||||||
import 'package:provider/provider.dart';
|
import 'package:provider/provider.dart';
|
||||||
import 'product_page.dart';
|
import 'product_page.dart';
|
||||||
@ -77,7 +78,7 @@ class ProductListItem extends StatelessWidget {
|
|||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
children: [
|
children: [
|
||||||
Text(name, style: Theme.of(context).textTheme.bodyLarge),
|
Text(name, style: Theme.of(context).textTheme.bodyLarge),
|
||||||
Text("${price.toString()} kr",
|
Text(formatDkkCents(price),
|
||||||
style: Theme.of(context).textTheme.bodyMedium),
|
style: Theme.of(context).textTheme.bodyMedium),
|
||||||
],
|
],
|
||||||
)),
|
)),
|
||||||
@ -127,7 +128,7 @@ class AllProductsPage extends StatelessWidget {
|
|||||||
itemBuilder: (_, idx) => ProductListItem(
|
itemBuilder: (_, idx) => ProductListItem(
|
||||||
productId: products[idx].id,
|
productId: products[idx].id,
|
||||||
name: products[idx].name,
|
name: products[idx].name,
|
||||||
price: products[idx].price,
|
price: products[idx].priceInDkkCent,
|
||||||
productPage: ProductPage(product: products[idx]),
|
productPage: ProductPage(product: products[idx]),
|
||||||
product: products[idx],
|
product: products[idx],
|
||||||
),
|
),
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:mobile/pages/receipt_page.dart';
|
import 'package:mobile/pages/receipt_page.dart';
|
||||||
import 'package:mobile/repos/receipt.dart';
|
import 'package:mobile/repos/receipt.dart';
|
||||||
|
import 'package:mobile/utils/price.dart';
|
||||||
import 'package:provider/provider.dart';
|
import 'package:provider/provider.dart';
|
||||||
|
|
||||||
class ReceiptsListItem extends StatelessWidget {
|
class ReceiptsListItem extends StatelessWidget {
|
||||||
@ -27,7 +28,7 @@ class ReceiptsListItem extends StatelessWidget {
|
|||||||
padding: const EdgeInsets.all(20),
|
padding: const EdgeInsets.all(20),
|
||||||
child: Row(
|
child: Row(
|
||||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||||
children: [Text(dateFormatted), Text("$totalPrice kr")],
|
children: [Text(dateFormatted), Text(formatDkkCents(totalPrice))],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
@ -7,6 +7,7 @@ import 'package:mobile/repos/cart.dart';
|
|||||||
import 'package:mobile/repos/product.dart';
|
import 'package:mobile/repos/product.dart';
|
||||||
import 'package:mobile/repos/user.dart';
|
import 'package:mobile/repos/user.dart';
|
||||||
import 'package:mobile/results.dart';
|
import 'package:mobile/results.dart';
|
||||||
|
import 'package:mobile/utils/price.dart';
|
||||||
import 'package:mobile/widgets/primary_button.dart';
|
import 'package:mobile/widgets/primary_button.dart';
|
||||||
import 'package:mobile/widgets/sized_card.dart';
|
import 'package:mobile/widgets/sized_card.dart';
|
||||||
import 'package:provider/provider.dart';
|
import 'package:provider/provider.dart';
|
||||||
@ -44,7 +45,7 @@ class CartItemView extends StatelessWidget {
|
|||||||
child: Text(name,
|
child: Text(name,
|
||||||
style: Theme.of(context).textTheme.bodyLarge),
|
style: Theme.of(context).textTheme.bodyLarge),
|
||||||
),
|
),
|
||||||
Text("$price kr",
|
Text(formatDkkCents(price),
|
||||||
style: Theme.of(context).textTheme.bodyMedium),
|
style: Theme.of(context).textTheme.bodyMedium),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
@ -160,7 +161,7 @@ class CartPage extends StatelessWidget {
|
|||||||
cartRepo: cartRepo,
|
cartRepo: cartRepo,
|
||||||
productId: cart[idx].product.id,
|
productId: cart[idx].product.id,
|
||||||
name: cart[idx].product.name,
|
name: cart[idx].product.name,
|
||||||
price: cart[idx].product.price,
|
price: cart[idx].product.priceInDkkCent,
|
||||||
amount: cart[idx].amount),
|
amount: cart[idx].amount),
|
||||||
itemCount: cart.length,
|
itemCount: cart.length,
|
||||||
);
|
);
|
||||||
|
@ -4,6 +4,7 @@ import 'package:mobile/repos/paying_state.dart';
|
|||||||
import 'package:mobile/repos/receipt.dart';
|
import 'package:mobile/repos/receipt.dart';
|
||||||
import 'package:mobile/repos/user.dart';
|
import 'package:mobile/repos/user.dart';
|
||||||
import 'package:mobile/results.dart';
|
import 'package:mobile/results.dart';
|
||||||
|
import 'package:mobile/utils/price.dart';
|
||||||
import 'package:mobile/widgets/primary_button.dart';
|
import 'package:mobile/widgets/primary_button.dart';
|
||||||
import 'package:mobile/widgets/receipt_item.dart';
|
import 'package:mobile/widgets/receipt_item.dart';
|
||||||
import 'package:provider/provider.dart';
|
import 'package:provider/provider.dart';
|
||||||
@ -21,122 +22,125 @@ class FinishShoppingPage extends StatelessWidget {
|
|||||||
final cart = cartRepo.allCartItems();
|
final cart = cartRepo.allCartItems();
|
||||||
|
|
||||||
return Scaffold(
|
return Scaffold(
|
||||||
body: Stack(
|
body: SafeArea(
|
||||||
children: [
|
child: Stack(
|
||||||
Column(
|
children: [
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
Column(
|
||||||
children: [
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
const BackButton(),
|
|
||||||
Container(
|
|
||||||
margin: const EdgeInsets.all(20),
|
|
||||||
child: Expanded(
|
|
||||||
child: ListView.builder(
|
|
||||||
shrinkWrap: true,
|
|
||||||
itemBuilder: (_, idx) => ReceiptItemView(
|
|
||||||
pricePerAmount: cart[idx].product.price,
|
|
||||||
name: cart[idx].product.name,
|
|
||||||
amount: cart[idx].amount),
|
|
||||||
itemCount: cart.length)),
|
|
||||||
),
|
|
||||||
Container(
|
|
||||||
margin: const EdgeInsets.all(20),
|
|
||||||
child: Expanded(
|
|
||||||
child: Row(
|
|
||||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
|
||||||
children: [
|
|
||||||
const Text(
|
|
||||||
"Total:",
|
|
||||||
style: TextStyle(fontWeight: FontWeight.bold),
|
|
||||||
),
|
|
||||||
Text("${cartRepo.totalPrice()} kr"),
|
|
||||||
],
|
|
||||||
)),
|
|
||||||
),
|
|
||||||
Expanded(
|
|
||||||
child: Center(
|
|
||||||
child: PrimaryButton(
|
|
||||||
onPressed: () async {
|
|
||||||
payingStateRepo.next();
|
|
||||||
await Future.delayed(const Duration(seconds: 1));
|
|
||||||
if (user.pay(cartRepo.totalPrice()) is Err) {
|
|
||||||
if (context.mounted) {
|
|
||||||
showDialog<String>(
|
|
||||||
context: context,
|
|
||||||
builder: (BuildContext context) => AlertDialog(
|
|
||||||
content: const Text(
|
|
||||||
'Du har desværre ikke råd til at købe dette'),
|
|
||||||
actions: <Widget>[
|
|
||||||
TextButton(
|
|
||||||
onPressed: () =>
|
|
||||||
Navigator.pop(context, 'OK'),
|
|
||||||
child: const Text('OK'),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
payingStateRepo.reset();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
receiptRepo.createReceipt(cart);
|
|
||||||
payingStateRepo.next();
|
|
||||||
await Future.delayed(const Duration(seconds: 1));
|
|
||||||
cartRepo.clearCart();
|
|
||||||
payingStateRepo.reset();
|
|
||||||
if (context.mounted) Navigator.pop(context);
|
|
||||||
},
|
|
||||||
child: const Text("Betal"))),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
if (payingStateRepo.state != PayingState.unset) ...[
|
|
||||||
Container(
|
|
||||||
color: Colors.black.withValues(alpha: 0.5),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
Center(
|
|
||||||
child: Column(
|
|
||||||
mainAxisAlignment: MainAxisAlignment.center,
|
|
||||||
children: [
|
children: [
|
||||||
...switch (payingStateRepo.state) {
|
const BackButton(),
|
||||||
PayingState.unset => [],
|
Container(
|
||||||
PayingState.loading => [
|
margin: const EdgeInsets.all(20),
|
||||||
Container(
|
child: Expanded(
|
||||||
decoration: const BoxDecoration(
|
child: ListView.builder(
|
||||||
borderRadius: BorderRadius.all(Radius.circular(10)),
|
shrinkWrap: true,
|
||||||
color: Colors.white,
|
itemBuilder: (_, idx) => ReceiptItemView(
|
||||||
),
|
pricePerAmount: cart[idx].product.priceInDkkCent,
|
||||||
padding: const EdgeInsets.all(20),
|
name: cart[idx].product.name,
|
||||||
child: SizedBox(
|
amount: cart[idx].amount),
|
||||||
width: 50,
|
itemCount: cart.length)),
|
||||||
height: 50,
|
),
|
||||||
child: CircularProgressIndicator(
|
Container(
|
||||||
valueColor: AlwaysStoppedAnimation<Color>(
|
margin: const EdgeInsets.all(20),
|
||||||
Theme.of(context).primaryColor),
|
child: Expanded(
|
||||||
strokeWidth: 6.0,
|
child: Row(
|
||||||
),
|
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||||
),
|
children: [
|
||||||
|
const Text(
|
||||||
|
"Total:",
|
||||||
|
style: TextStyle(fontWeight: FontWeight.bold),
|
||||||
),
|
),
|
||||||
|
Text(formatDkkCents(cartRepo.totalPrice())),
|
||||||
],
|
],
|
||||||
PayingState.done => [
|
)),
|
||||||
Container(
|
),
|
||||||
padding: const EdgeInsets.all(10),
|
Expanded(
|
||||||
decoration: const BoxDecoration(
|
child: Center(
|
||||||
borderRadius: BorderRadius.all(Radius.circular(10)),
|
child: PrimaryButton(
|
||||||
color: Colors.white,
|
onPressed: () async {
|
||||||
),
|
payingStateRepo.next();
|
||||||
child: Icon(
|
await Future.delayed(const Duration(seconds: 1));
|
||||||
Icons.check_rounded,
|
if (user.pay(cartRepo.totalPrice()) is Err) {
|
||||||
color: Theme.of(context).primaryColor,
|
if (context.mounted) {
|
||||||
size: 70,
|
showDialog<String>(
|
||||||
),
|
context: context,
|
||||||
)
|
builder: (BuildContext context) =>
|
||||||
]
|
AlertDialog(
|
||||||
},
|
content: const Text(
|
||||||
|
'Du har desværre ikke råd til at købe dette'),
|
||||||
|
actions: <Widget>[
|
||||||
|
TextButton(
|
||||||
|
onPressed: () =>
|
||||||
|
Navigator.pop(context, 'OK'),
|
||||||
|
child: const Text('OK'),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
payingStateRepo.reset();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
receiptRepo.createReceipt(cart);
|
||||||
|
payingStateRepo.next();
|
||||||
|
await Future.delayed(const Duration(seconds: 1));
|
||||||
|
cartRepo.clearCart();
|
||||||
|
payingStateRepo.reset();
|
||||||
|
if (context.mounted) Navigator.pop(context);
|
||||||
|
},
|
||||||
|
child: const Text("Betal"))),
|
||||||
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
)
|
if (payingStateRepo.state != PayingState.unset) ...[
|
||||||
],
|
Container(
|
||||||
|
color: Colors.black.withValues(alpha: 0.5),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
Center(
|
||||||
|
child: Column(
|
||||||
|
mainAxisAlignment: MainAxisAlignment.center,
|
||||||
|
children: [
|
||||||
|
...switch (payingStateRepo.state) {
|
||||||
|
PayingState.unset => [],
|
||||||
|
PayingState.loading => [
|
||||||
|
Container(
|
||||||
|
decoration: const BoxDecoration(
|
||||||
|
borderRadius: BorderRadius.all(Radius.circular(10)),
|
||||||
|
color: Colors.white,
|
||||||
|
),
|
||||||
|
padding: const EdgeInsets.all(20),
|
||||||
|
child: SizedBox(
|
||||||
|
width: 50,
|
||||||
|
height: 50,
|
||||||
|
child: CircularProgressIndicator(
|
||||||
|
valueColor: AlwaysStoppedAnimation<Color>(
|
||||||
|
Theme.of(context).primaryColor),
|
||||||
|
strokeWidth: 6.0,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
PayingState.done => [
|
||||||
|
Container(
|
||||||
|
padding: const EdgeInsets.all(10),
|
||||||
|
decoration: const BoxDecoration(
|
||||||
|
borderRadius: BorderRadius.all(Radius.circular(10)),
|
||||||
|
color: Colors.white,
|
||||||
|
),
|
||||||
|
child: Icon(
|
||||||
|
Icons.check_rounded,
|
||||||
|
color: Theme.of(context).primaryColor,
|
||||||
|
size: 70,
|
||||||
|
),
|
||||||
|
)
|
||||||
|
]
|
||||||
|
},
|
||||||
|
],
|
||||||
|
),
|
||||||
|
)
|
||||||
|
],
|
||||||
|
),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:mobile/pages/log_in_page.dart';
|
import 'package:mobile/pages/log_in_page.dart';
|
||||||
import 'package:mobile/repos/user.dart';
|
import 'package:mobile/repos/user.dart';
|
||||||
|
import 'package:mobile/utils/price.dart';
|
||||||
|
|
||||||
class HomePage extends StatelessWidget {
|
class HomePage extends StatelessWidget {
|
||||||
final User user;
|
final User user;
|
||||||
@ -19,6 +20,17 @@ class HomePage extends StatelessWidget {
|
|||||||
child: const SettingsMenu()),
|
child: const SettingsMenu()),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
|
Card(
|
||||||
|
child: Container(
|
||||||
|
decoration: const BoxDecoration(
|
||||||
|
borderRadius: BorderRadius.all(Radius.circular(10)),
|
||||||
|
color: Color(0xFFFFFFFF),
|
||||||
|
),
|
||||||
|
padding: const EdgeInsets.all(10),
|
||||||
|
child: Text("Saldo: ${formatDkkCents(user.balanceInDkkCents)}",
|
||||||
|
style: Theme.of(context).textTheme.headlineSmall),
|
||||||
|
),
|
||||||
|
),
|
||||||
Expanded(
|
Expanded(
|
||||||
child: Column(
|
child: Column(
|
||||||
mainAxisAlignment: MainAxisAlignment.center,
|
mainAxisAlignment: MainAxisAlignment.center,
|
||||||
|
@ -3,6 +3,7 @@ import 'package:mobile/pages/product_location_page.dart';
|
|||||||
import 'package:mobile/repos/add_to_cart_state.dart';
|
import 'package:mobile/repos/add_to_cart_state.dart';
|
||||||
import 'package:mobile/repos/cart.dart';
|
import 'package:mobile/repos/cart.dart';
|
||||||
import 'package:mobile/repos/product.dart';
|
import 'package:mobile/repos/product.dart';
|
||||||
|
import 'package:mobile/utils/price.dart';
|
||||||
import 'package:mobile/widgets/primary_button.dart';
|
import 'package:mobile/widgets/primary_button.dart';
|
||||||
import 'package:provider/provider.dart';
|
import 'package:provider/provider.dart';
|
||||||
|
|
||||||
@ -38,7 +39,7 @@ class ProductPage extends StatelessWidget {
|
|||||||
),
|
),
|
||||||
),
|
),
|
||||||
Text(
|
Text(
|
||||||
"${product.price} kr",
|
formatDkkCents(product.priceInDkkCent),
|
||||||
style: const TextStyle(
|
style: const TextStyle(
|
||||||
fontSize: 16,
|
fontSize: 16,
|
||||||
),
|
),
|
||||||
@ -66,7 +67,7 @@ class ProductPage extends StatelessWidget {
|
|||||||
style: Theme.of(context).textTheme.bodyLarge,
|
style: Theme.of(context).textTheme.bodyLarge,
|
||||||
),
|
),
|
||||||
Text(
|
Text(
|
||||||
"${product.price} kr",
|
formatDkkCents(product.priceInDkkCent),
|
||||||
style: Theme.of(context).textTheme.bodyLarge,
|
style: Theme.of(context).textTheme.bodyLarge,
|
||||||
),
|
),
|
||||||
Padding(
|
Padding(
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:mobile/repos/receipt.dart';
|
import 'package:mobile/repos/receipt.dart';
|
||||||
|
import 'package:mobile/utils/price.dart';
|
||||||
import 'package:mobile/widgets/receipt_item.dart';
|
import 'package:mobile/widgets/receipt_item.dart';
|
||||||
|
|
||||||
class ReceiptView extends StatelessWidget {
|
class ReceiptView extends StatelessWidget {
|
||||||
@ -27,7 +28,8 @@ class ReceiptView extends StatelessWidget {
|
|||||||
ListView.builder(
|
ListView.builder(
|
||||||
shrinkWrap: true,
|
shrinkWrap: true,
|
||||||
itemBuilder: (_, idx) => ReceiptItemView(
|
itemBuilder: (_, idx) => ReceiptItemView(
|
||||||
pricePerAmount: receiptItems[idx].product.price,
|
pricePerAmount:
|
||||||
|
receiptItems[idx].product.priceInDkkCent,
|
||||||
name: receiptItems[idx].product.name,
|
name: receiptItems[idx].product.name,
|
||||||
amount: receiptItems[idx].amount),
|
amount: receiptItems[idx].amount),
|
||||||
itemCount: receiptItems.length),
|
itemCount: receiptItems.length),
|
||||||
@ -38,7 +40,7 @@ class ReceiptView extends StatelessWidget {
|
|||||||
"Total:",
|
"Total:",
|
||||||
style: TextStyle(fontWeight: FontWeight.bold),
|
style: TextStyle(fontWeight: FontWeight.bold),
|
||||||
),
|
),
|
||||||
Text("${receipt.totalPrice()} kr"),
|
Text(formatDkkCents(receipt.totalPrice())),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
|
@ -9,14 +9,14 @@ class CartRepo extends ChangeNotifier {
|
|||||||
product: Product(
|
product: Product(
|
||||||
id: 1,
|
id: 1,
|
||||||
name: "Letmælk",
|
name: "Letmælk",
|
||||||
price: 13,
|
priceInDkkCent: 1295,
|
||||||
description: "Konventionel letmælk med fedtprocent på 1,5%"),
|
description: "Konventionel letmælk med fedtprocent på 1,5%"),
|
||||||
amount: 1),
|
amount: 1),
|
||||||
CartItem(
|
CartItem(
|
||||||
product: Product(
|
product: Product(
|
||||||
id: 2,
|
id: 2,
|
||||||
name: "Frilands Øko Supermælk",
|
name: "Frilands Øko Supermælk",
|
||||||
price: 20,
|
priceInDkkCent: 1995,
|
||||||
description:
|
description:
|
||||||
"Økologisk mælk af frilandskøer med fedtprocent på 3,5%. Ikke homogeniseret eller pasteuriseret. Skaber store muskler og styrker knoglerne 💪"),
|
"Økologisk mælk af frilandskøer med fedtprocent på 3,5%. Ikke homogeniseret eller pasteuriseret. Skaber store muskler og styrker knoglerne 💪"),
|
||||||
amount: 6),
|
amount: 6),
|
||||||
@ -24,7 +24,7 @@ class CartRepo extends ChangeNotifier {
|
|||||||
product: Product(
|
product: Product(
|
||||||
id: 3,
|
id: 3,
|
||||||
name: "Minimælk",
|
name: "Minimælk",
|
||||||
price: 12,
|
priceInDkkCent: 1195,
|
||||||
description: "Konventionel minimælk med fedtprocent på 0,4%"),
|
description: "Konventionel minimælk med fedtprocent på 0,4%"),
|
||||||
amount: 1),
|
amount: 1),
|
||||||
];
|
];
|
||||||
@ -96,7 +96,9 @@ class CartRepo extends ChangeNotifier {
|
|||||||
|
|
||||||
int totalPrice() {
|
int totalPrice() {
|
||||||
return cart.fold<int>(
|
return cart.fold<int>(
|
||||||
0, (prev, cartItem) => prev + cartItem.amount * cartItem.product.price);
|
0,
|
||||||
|
(prev, cartItem) =>
|
||||||
|
prev + cartItem.amount * cartItem.product.priceInDkkCent);
|
||||||
}
|
}
|
||||||
|
|
||||||
void clearCart() {
|
void clearCart() {
|
||||||
|
@ -48,48 +48,77 @@ class ProductRepo extends ChangeNotifier {
|
|||||||
Product(
|
Product(
|
||||||
id: _nextId++,
|
id: _nextId++,
|
||||||
name: "Minimælk",
|
name: "Minimælk",
|
||||||
price: 12,
|
priceInDkkCent: 1200,
|
||||||
description: "Konventionel minimælk med fedtprocent på 0,4%"),
|
description: "Konventionel minimælk med fedtprocent på 0,4%"),
|
||||||
Product(
|
Product(
|
||||||
id: _nextId++,
|
id: _nextId++,
|
||||||
name: "Letmælk",
|
name: "Letmælk",
|
||||||
price: 13,
|
priceInDkkCent: 1300,
|
||||||
description: "Konventionel letmælk med fedtprocent på 1,5%",
|
description: "Konventionel letmælk med fedtprocent på 1,5%",
|
||||||
location: Coordinate(x: 1800, y: 100)),
|
location: Coordinate(x: 1800, y: 100)),
|
||||||
Product(
|
Product(
|
||||||
id: _nextId++,
|
id: _nextId++,
|
||||||
name: "Frilands Øko Supermælk",
|
name: "Frilands Øko Supermælk",
|
||||||
price: 20,
|
priceInDkkCent: 2000,
|
||||||
description:
|
description:
|
||||||
"Økologisk mælk af frilandskøer med fedtprocent på 3,5%. Ikke homogeniseret eller pasteuriseret. Skaber store muskler og styrker knoglerne 💪"),
|
"Økologisk mælk af frilandskøer med fedtprocent på 3,5%. Ikke homogeniseret eller pasteuriseret. Skaber store muskler og styrker knoglerne 💪"),
|
||||||
Product(
|
Product(
|
||||||
id: _nextId++,
|
id: _nextId++,
|
||||||
name: "Øko Gulerødder 1 kg",
|
name: "Øko Gulerødder 1 kg",
|
||||||
price: 10,
|
priceInDkkCent: 1000,
|
||||||
|
description: ""),
|
||||||
|
Product(
|
||||||
|
id: _nextId++,
|
||||||
|
name: "Øko Agurk",
|
||||||
|
priceInDkkCent: 1000,
|
||||||
|
description: ""),
|
||||||
|
Product(
|
||||||
|
id: _nextId++,
|
||||||
|
name: "Æbler 1 kg",
|
||||||
|
priceInDkkCent: 1000,
|
||||||
|
description: ""),
|
||||||
|
Product(
|
||||||
|
id: _nextId++,
|
||||||
|
name: "Basmati Ris",
|
||||||
|
priceInDkkCent: 2000,
|
||||||
|
description: ""),
|
||||||
|
Product(
|
||||||
|
id: _nextId++,
|
||||||
|
name: "Haribo Mix",
|
||||||
|
priceInDkkCent: 3000,
|
||||||
|
description: ""),
|
||||||
|
Product(
|
||||||
|
id: _nextId++, name: "Smør", priceInDkkCent: 3000, description: ""),
|
||||||
|
Product(
|
||||||
|
id: _nextId++,
|
||||||
|
name: "Harboe Cola",
|
||||||
|
priceInDkkCent: 500,
|
||||||
description: ""),
|
description: ""),
|
||||||
Product(id: _nextId++, name: "Øko Agurk", price: 10, description: ""),
|
|
||||||
Product(id: _nextId++, name: "Æbler 1 kg", price: 10, description: ""),
|
|
||||||
Product(id: _nextId++, name: "Basmati Ris", price: 20, description: ""),
|
|
||||||
Product(id: _nextId++, name: "Haribo Mix", price: 30, description: ""),
|
|
||||||
Product(id: _nextId++, name: "Smør", price: 30, description: ""),
|
|
||||||
Product(id: _nextId++, name: "Harboe Cola", price: 5, description: ""),
|
|
||||||
Product(
|
Product(
|
||||||
id: _nextId++,
|
id: _nextId++,
|
||||||
name: "Monster Energi Drik",
|
name: "Monster Energi Drik",
|
||||||
price: 20,
|
priceInDkkCent: 2000,
|
||||||
|
description: ""),
|
||||||
|
Product(
|
||||||
|
id: _nextId++,
|
||||||
|
name: "Spaghetti",
|
||||||
|
priceInDkkCent: 1000,
|
||||||
|
description: ""),
|
||||||
|
Product(
|
||||||
|
id: _nextId++,
|
||||||
|
name: "Rød Cecil",
|
||||||
|
priceInDkkCent: 6000,
|
||||||
description: ""),
|
description: ""),
|
||||||
Product(id: _nextId++, name: "Spaghetti", price: 10, description: ""),
|
|
||||||
Product(id: _nextId++, name: "Rød Cecil", price: 60, description: ""),
|
|
||||||
Product(
|
Product(
|
||||||
id: _nextId++,
|
id: _nextId++,
|
||||||
name: "Jägermeister 750 ml",
|
name: "Jägermeister 750 ml",
|
||||||
price: 120,
|
priceInDkkCent: 12000,
|
||||||
description: ""),
|
description: ""),
|
||||||
Product(
|
Product(
|
||||||
id: _nextId++,
|
id: _nextId++,
|
||||||
barcode: "5711953068881",
|
barcode: "5711953068881",
|
||||||
name: "Protein Chokoladedrik",
|
name: "Protein Chokoladedrik",
|
||||||
price: 15,
|
priceInDkkCent: 1500,
|
||||||
description: "Arla's protein chokolade drik der giver store muskler"),
|
description: "Arla's protein chokolade drik der giver store muskler"),
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
@ -106,14 +135,14 @@ class Product {
|
|||||||
final int id;
|
final int id;
|
||||||
final String name;
|
final String name;
|
||||||
final String description;
|
final String description;
|
||||||
final int price;
|
final int priceInDkkCent;
|
||||||
final Coordinate? location;
|
final Coordinate? location;
|
||||||
final String? barcode;
|
final String? barcode;
|
||||||
|
|
||||||
Product({
|
Product({
|
||||||
required this.id,
|
required this.id,
|
||||||
required this.name,
|
required this.name,
|
||||||
required this.price,
|
required this.priceInDkkCent,
|
||||||
required this.description,
|
required this.description,
|
||||||
this.location,
|
this.location,
|
||||||
this.barcode,
|
this.barcode,
|
||||||
|
@ -13,14 +13,14 @@ class ReceiptRepo extends ChangeNotifier {
|
|||||||
product: Product(
|
product: Product(
|
||||||
id: 1243,
|
id: 1243,
|
||||||
name: "Letmælk",
|
name: "Letmælk",
|
||||||
price: 13,
|
priceInDkkCent: 13,
|
||||||
description: "Konventionel minimælk med fedtprocent på 0,4%"),
|
description: "Konventionel minimælk med fedtprocent på 0,4%"),
|
||||||
amount: 1),
|
amount: 1),
|
||||||
ReceiptItem(
|
ReceiptItem(
|
||||||
product: Product(
|
product: Product(
|
||||||
id: 340,
|
id: 340,
|
||||||
name: "Minimælk",
|
name: "Minimælk",
|
||||||
price: 12,
|
priceInDkkCent: 12,
|
||||||
description: "Konventionel minimælk med fedtprocent på 0,4%"),
|
description: "Konventionel minimælk med fedtprocent på 0,4%"),
|
||||||
amount: 3),
|
amount: 3),
|
||||||
]),
|
]),
|
||||||
@ -32,14 +32,14 @@ class ReceiptRepo extends ChangeNotifier {
|
|||||||
product: Product(
|
product: Product(
|
||||||
id: 12341,
|
id: 12341,
|
||||||
name: "Letmælk",
|
name: "Letmælk",
|
||||||
price: 13,
|
priceInDkkCent: 13,
|
||||||
description: "Konventionel minimælk med fedtprocent på 0,4%"),
|
description: "Konventionel minimælk med fedtprocent på 0,4%"),
|
||||||
amount: 3),
|
amount: 3),
|
||||||
ReceiptItem(
|
ReceiptItem(
|
||||||
product: Product(
|
product: Product(
|
||||||
id: 1234443,
|
id: 1234443,
|
||||||
name: "Minimælk",
|
name: "Minimælk",
|
||||||
price: 12,
|
priceInDkkCent: 12,
|
||||||
description: "Konventionel minimælk med fedtprocent på 0,4%"),
|
description: "Konventionel minimælk med fedtprocent på 0,4%"),
|
||||||
amount: 1),
|
amount: 1),
|
||||||
])
|
])
|
||||||
@ -119,6 +119,6 @@ class ReceiptItem {
|
|||||||
ReceiptItem({required this.product, required this.amount});
|
ReceiptItem({required this.product, required this.amount});
|
||||||
|
|
||||||
int totalPrice() {
|
int totalPrice() {
|
||||||
return product.price * amount;
|
return product.priceInDkkCent * amount;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -33,7 +33,11 @@ class UsersRepo extends ChangeNotifier {
|
|||||||
}
|
}
|
||||||
|
|
||||||
final user = User(
|
final user = User(
|
||||||
id: nextId++, name: name, mail: mail, password: password, balance: 0);
|
id: nextId++,
|
||||||
|
name: name,
|
||||||
|
mail: mail,
|
||||||
|
password: password,
|
||||||
|
balanceInDkkCents: 0);
|
||||||
users.add(user);
|
users.add(user);
|
||||||
|
|
||||||
return Ok(user);
|
return Ok(user);
|
||||||
@ -67,9 +71,13 @@ class UsersRepo extends ChangeNotifier {
|
|||||||
mail: "test@test.com",
|
mail: "test@test.com",
|
||||||
name: "test",
|
name: "test",
|
||||||
password: "test",
|
password: "test",
|
||||||
balance: 1000))
|
balanceInDkkCents: 10000))
|
||||||
..add(
|
..add(User(
|
||||||
User(id: nextId++, mail: "", name: "", password: "", balance: 10000));
|
id: nextId++,
|
||||||
|
mail: "",
|
||||||
|
name: "",
|
||||||
|
password: "",
|
||||||
|
balanceInDkkCents: 100000));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -78,20 +86,22 @@ class User {
|
|||||||
final String mail;
|
final String mail;
|
||||||
final String name;
|
final String name;
|
||||||
final String password;
|
final String password;
|
||||||
int balance;
|
|
||||||
|
// balance is in øre
|
||||||
|
int balanceInDkkCents;
|
||||||
|
|
||||||
User(
|
User(
|
||||||
{required this.id,
|
{required this.id,
|
||||||
required this.mail,
|
required this.mail,
|
||||||
required this.name,
|
required this.name,
|
||||||
required this.password,
|
required this.password,
|
||||||
required this.balance});
|
required this.balanceInDkkCents});
|
||||||
|
|
||||||
Result<int, String> pay(int amount) {
|
Result<int, String> pay(int amount) {
|
||||||
if (balance < amount) {
|
if (balanceInDkkCents < amount) {
|
||||||
return Err("User can not afford paying amount $amount");
|
return Err("User can not afford paying amount $amount");
|
||||||
}
|
}
|
||||||
balance -= amount;
|
balanceInDkkCents -= amount;
|
||||||
return Ok(balance);
|
return Ok(balanceInDkkCents);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
6
mobile/lib/utils/price.dart
Normal file
6
mobile/lib/utils/price.dart
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
import 'package:intl/intl.dart';
|
||||||
|
|
||||||
|
String formatDkkCents(int priceInDkkCents) {
|
||||||
|
final formatter = NumberFormat("###,##0.00", "da_DK");
|
||||||
|
return "${formatter.format(priceInDkkCents / 100.0)} kr";
|
||||||
|
}
|
@ -1,4 +1,5 @@
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:mobile/utils/price.dart';
|
||||||
|
|
||||||
class ReceiptItemView extends StatelessWidget {
|
class ReceiptItemView extends StatelessWidget {
|
||||||
final int pricePerAmount;
|
final int pricePerAmount;
|
||||||
@ -20,16 +21,16 @@ class ReceiptItemView extends StatelessWidget {
|
|||||||
Row(
|
Row(
|
||||||
children: [
|
children: [
|
||||||
SizedBox(
|
SizedBox(
|
||||||
width: 60,
|
width: 80,
|
||||||
child: Text(
|
child: Text(
|
||||||
"$amount stk",
|
"$amount stk",
|
||||||
textAlign: TextAlign.end,
|
textAlign: TextAlign.end,
|
||||||
overflow: TextOverflow.ellipsis,
|
overflow: TextOverflow.ellipsis,
|
||||||
)),
|
)),
|
||||||
SizedBox(
|
SizedBox(
|
||||||
width: 60,
|
width: 80,
|
||||||
child: Text(
|
child: Text(
|
||||||
"${pricePerAmount * amount} kr",
|
formatDkkCents(pricePerAmount * amount),
|
||||||
textAlign: TextAlign.end,
|
textAlign: TextAlign.end,
|
||||||
overflow: TextOverflow.ellipsis,
|
overflow: TextOverflow.ellipsis,
|
||||||
))
|
))
|
||||||
|
@ -131,6 +131,14 @@ packages:
|
|||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "4.1.2"
|
version: "4.1.2"
|
||||||
|
intl:
|
||||||
|
dependency: "direct main"
|
||||||
|
description:
|
||||||
|
name: intl
|
||||||
|
sha256: "3df61194eb431efc39c4ceba583b95633a403f46c9fd341e550ce0bfa50e9aa5"
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "0.20.2"
|
||||||
leak_tracker:
|
leak_tracker:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
|
@ -37,6 +37,7 @@ dependencies:
|
|||||||
provider: ^6.1.2
|
provider: ^6.1.2
|
||||||
barcode_scan2: ^4.4.0
|
barcode_scan2: ^4.4.0
|
||||||
google_fonts: ^6.2.1
|
google_fonts: ^6.2.1
|
||||||
|
intl: ^0.20.2
|
||||||
|
|
||||||
dev_dependencies:
|
dev_dependencies:
|
||||||
flutter_test:
|
flutter_test:
|
||||||
|
Loading…
x
Reference in New Issue
Block a user