mirror of
https://github.com/Mercantec-GHC/h4-projekt-gruppe-0-sm.git
synced 2025-05-12 06:04:05 +02:00
caching for cart
This commit is contained in:
parent
44ef95ba63
commit
de4e91db72
@ -1,16 +1,38 @@
|
|||||||
|
import 'dart:convert';
|
||||||
|
import 'dart:io';
|
||||||
|
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:mobile/models/cart_item.dart';
|
||||||
import 'package:mobile/models/product.dart';
|
import 'package:mobile/models/product.dart';
|
||||||
import 'package:mobile/results.dart';
|
import 'package:mobile/results.dart';
|
||||||
|
import 'package:path_provider/path_provider.dart';
|
||||||
|
|
||||||
class ProductIdException implements Exception {}
|
class ProductIdException implements Exception {}
|
||||||
|
|
||||||
class CartController extends ChangeNotifier {
|
abstract class CartController extends ChangeNotifier {
|
||||||
|
List<CartItem> allCartItems();
|
||||||
|
CartItem? withProductId(int productId);
|
||||||
|
void incrementAmount(int productId);
|
||||||
|
void decrementAmount(int productId);
|
||||||
|
bool willRemoveOnNextDecrement(int productId);
|
||||||
|
void removeCartItem(int productId);
|
||||||
|
void addToCart(Product product);
|
||||||
|
int totalItemsInCart();
|
||||||
|
int totalPrice();
|
||||||
|
void clearCart();
|
||||||
|
}
|
||||||
|
|
||||||
|
class CartControllerMemory extends CartController {
|
||||||
final List<CartItem> cart = [];
|
final List<CartItem> cart = [];
|
||||||
|
|
||||||
|
CartControllerMemory();
|
||||||
|
|
||||||
|
@override
|
||||||
List<CartItem> allCartItems() {
|
List<CartItem> allCartItems() {
|
||||||
return cart;
|
return cart;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
CartItem? withProductId(int productId) {
|
CartItem? withProductId(int productId) {
|
||||||
for (var i = 0; i < cart.length; i++) {
|
for (var i = 0; i < cart.length; i++) {
|
||||||
if (cart[i].product.id == productId) {
|
if (cart[i].product.id == productId) {
|
||||||
@ -20,6 +42,7 @@ class CartController extends ChangeNotifier {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
void incrementAmount(int productId) {
|
void incrementAmount(int productId) {
|
||||||
final cartItem = withProductId(productId);
|
final cartItem = withProductId(productId);
|
||||||
if (cartItem == null) {
|
if (cartItem == null) {
|
||||||
@ -29,6 +52,7 @@ class CartController extends ChangeNotifier {
|
|||||||
notifyListeners();
|
notifyListeners();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
void decrementAmount(int productId) {
|
void decrementAmount(int productId) {
|
||||||
final cartItem = withProductId(productId);
|
final cartItem = withProductId(productId);
|
||||||
if (cartItem == null) {
|
if (cartItem == null) {
|
||||||
@ -41,6 +65,7 @@ class CartController extends ChangeNotifier {
|
|||||||
notifyListeners();
|
notifyListeners();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
bool willRemoveOnNextDecrement(int productId) {
|
bool willRemoveOnNextDecrement(int productId) {
|
||||||
final cartItem = withProductId(productId);
|
final cartItem = withProductId(productId);
|
||||||
if (cartItem == null) {
|
if (cartItem == null) {
|
||||||
@ -49,6 +74,7 @@ class CartController extends ChangeNotifier {
|
|||||||
return cartItem.amount <= 1;
|
return cartItem.amount <= 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
void removeCartItem(int productId) {
|
void removeCartItem(int productId) {
|
||||||
final cartItem = withProductId(productId);
|
final cartItem = withProductId(productId);
|
||||||
if (cartItem == null) {
|
if (cartItem == null) {
|
||||||
@ -58,6 +84,7 @@ class CartController extends ChangeNotifier {
|
|||||||
notifyListeners();
|
notifyListeners();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
void addToCart(Product product) {
|
void addToCart(Product product) {
|
||||||
final cartItem = withProductId(product.id);
|
final cartItem = withProductId(product.id);
|
||||||
if (cartItem == null) {
|
if (cartItem == null) {
|
||||||
@ -68,17 +95,20 @@ class CartController extends ChangeNotifier {
|
|||||||
notifyListeners();
|
notifyListeners();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
int totalItemsInCart() {
|
int totalItemsInCart() {
|
||||||
return cart.fold<int>(0, (prev, cartItem) => prev + cartItem.amount);
|
return cart.fold<int>(0, (prev, cartItem) => prev + cartItem.amount);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
int totalPrice() {
|
int totalPrice() {
|
||||||
return cart.fold<int>(
|
return cart.fold<int>(
|
||||||
0,
|
0,
|
||||||
(prev, cartItem) =>
|
(prev, cartItem) =>
|
||||||
prev + cartItem.amount * cartItem.product.priceInDkkCents);
|
prev + cartItem.amount * cartItem.product.priceDkkCent);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
void clearCart() {
|
void clearCart() {
|
||||||
cart.clear();
|
cart.clear();
|
||||||
notifyListeners();
|
notifyListeners();
|
||||||
@ -89,9 +119,63 @@ class CartController extends ChangeNotifier {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class CartItem {
|
class CartControllerCache extends CartControllerMemory {
|
||||||
final Product product;
|
static Future<File> get _cacheFile async {
|
||||||
int amount;
|
final directory = await getApplicationCacheDirectory();
|
||||||
|
return File("${directory.path}/cart.json").create();
|
||||||
|
}
|
||||||
|
|
||||||
CartItem({required this.product, required this.amount});
|
CartControllerCache() {
|
||||||
|
load();
|
||||||
|
}
|
||||||
|
|
||||||
|
void save() async {
|
||||||
|
final json =
|
||||||
|
jsonEncode(cart.map((cartItem) => CartItem.toJson(cartItem)).toList());
|
||||||
|
(await _cacheFile).writeAsString(json);
|
||||||
|
}
|
||||||
|
|
||||||
|
void load() async {
|
||||||
|
final json = await (await _cacheFile).readAsString();
|
||||||
|
print("Loading cache: $json");
|
||||||
|
if (json.isEmpty) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
final res = jsonDecode(json);
|
||||||
|
final cartItems = (res as List<dynamic>)
|
||||||
|
.map(((cartItems) => CartItem.fromJson(cartItems)))
|
||||||
|
.toList();
|
||||||
|
cart.insertAll(0, cartItems);
|
||||||
|
notifyListeners();
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
void incrementAmount(int productId) {
|
||||||
|
super.incrementAmount(productId);
|
||||||
|
save();
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
void decrementAmount(int productId) {
|
||||||
|
super.decrementAmount(productId);
|
||||||
|
save();
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
void removeCartItem(int productId) {
|
||||||
|
super.removeCartItem(productId);
|
||||||
|
save();
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
void addToCart(Product product) {
|
||||||
|
super.addToCart(product);
|
||||||
|
save();
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
void clearCart() {
|
||||||
|
super.clearCart();
|
||||||
|
save();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -23,7 +23,7 @@ class ProductController extends ChangeNotifier {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
get filteredProducts {
|
List<Product> get filteredProducts {
|
||||||
if (query.trim().isEmpty) {
|
if (query.trim().isEmpty) {
|
||||||
return products;
|
return products;
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:mobile/models/cart_item.dart';
|
||||||
import 'package:mobile/models/product.dart';
|
import 'package:mobile/models/product.dart';
|
||||||
import 'package:mobile/controllers/cart.dart';
|
|
||||||
|
|
||||||
class ReceiptController extends ChangeNotifier {
|
class ReceiptController extends ChangeNotifier {
|
||||||
int nextId = 0;
|
int nextId = 0;
|
||||||
@ -80,6 +80,6 @@ class ReceiptItem {
|
|||||||
ReceiptItem({required this.product, required this.amount});
|
ReceiptItem({required this.product, required this.amount});
|
||||||
|
|
||||||
int totalPrice() {
|
int totalPrice() {
|
||||||
return product.priceInDkkCents * amount;
|
return product.priceDkkCent * amount;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -29,7 +29,7 @@ class MyApp extends StatelessWidget {
|
|||||||
ChangeNotifierProvider(create: (_) => RoutingController()),
|
ChangeNotifierProvider(create: (_) => RoutingController()),
|
||||||
ChangeNotifierProvider(
|
ChangeNotifierProvider(
|
||||||
create: (_) => ProductController(server: server)),
|
create: (_) => ProductController(server: server)),
|
||||||
ChangeNotifierProvider(create: (_) => CartController()),
|
ChangeNotifierProvider(create: (_) => CartControllerCache()),
|
||||||
ChangeNotifierProvider(create: (_) => ReceiptController()),
|
ChangeNotifierProvider(create: (_) => ReceiptController()),
|
||||||
ChangeNotifierProvider(create: (_) => PayingStateController()),
|
ChangeNotifierProvider(create: (_) => PayingStateController()),
|
||||||
ChangeNotifierProvider(create: (_) => AddToCartStateController()),
|
ChangeNotifierProvider(create: (_) => AddToCartStateController()),
|
||||||
|
19
mobile/lib/models/cart_item.dart
Normal file
19
mobile/lib/models/cart_item.dart
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
import 'package:mobile/models/product.dart';
|
||||||
|
|
||||||
|
class CartItem {
|
||||||
|
final Product product;
|
||||||
|
int amount;
|
||||||
|
|
||||||
|
CartItem({required this.product, required this.amount});
|
||||||
|
|
||||||
|
static Map<String, dynamic> toJson(CartItem cartItem) {
|
||||||
|
return {
|
||||||
|
"product": Product.toJson(cartItem.product),
|
||||||
|
"amount": cartItem.amount
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
CartItem.fromJson(Map<String, dynamic> json)
|
||||||
|
: product = Product.fromJson(json["product"]),
|
||||||
|
amount = json["amount"];
|
||||||
|
}
|
@ -4,24 +4,35 @@ class Product {
|
|||||||
final int id;
|
final int id;
|
||||||
final String name;
|
final String name;
|
||||||
final String description;
|
final String description;
|
||||||
final int priceInDkkCents;
|
final int priceDkkCent;
|
||||||
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.priceInDkkCents,
|
required this.priceDkkCent,
|
||||||
required this.description,
|
required this.description,
|
||||||
this.location,
|
this.location,
|
||||||
this.barcode,
|
this.barcode,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
static Map<String, dynamic> toJson(Product product) {
|
||||||
|
return {
|
||||||
|
"id": product.id,
|
||||||
|
"name": product.name,
|
||||||
|
"description": product.description,
|
||||||
|
"price_dkk_cent": product.priceDkkCent,
|
||||||
|
"location": product.location,
|
||||||
|
"barcode": product.barcode,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
Product.fromJson(Map<String, dynamic> json)
|
Product.fromJson(Map<String, dynamic> json)
|
||||||
: id = json["id"],
|
: id = json["id"],
|
||||||
name = json["name"],
|
name = json["name"],
|
||||||
description = json["description"],
|
description = json["description"],
|
||||||
priceInDkkCents = json["price_dkk_cent"],
|
priceDkkCent = json["price_dkk_cent"],
|
||||||
location = null,
|
location = null,
|
||||||
barcode = json["barcode"];
|
barcode = json["barcode"];
|
||||||
}
|
}
|
||||||
|
@ -6,30 +6,30 @@ class User {
|
|||||||
final String name;
|
final String name;
|
||||||
|
|
||||||
// balance is in øre
|
// balance is in øre
|
||||||
int balanceInDkkCents;
|
int balanceDkkCents;
|
||||||
|
|
||||||
User({
|
User({
|
||||||
required this.id,
|
required this.id,
|
||||||
required this.email,
|
required this.email,
|
||||||
required this.name,
|
required this.name,
|
||||||
required this.balanceInDkkCents,
|
required this.balanceDkkCents,
|
||||||
});
|
});
|
||||||
|
|
||||||
User.fromJson(Map<String, dynamic> json)
|
User.fromJson(Map<String, dynamic> json)
|
||||||
: email = json["email"],
|
: email = json["email"],
|
||||||
id = json["id"],
|
id = json["id"],
|
||||||
name = json["name"],
|
name = json["name"],
|
||||||
balanceInDkkCents = json["balance_dkk_cent"];
|
balanceDkkCents = json["balance_dkk_cent"];
|
||||||
|
|
||||||
void addBalanceFounds(int amount) {
|
void addBalanceFounds(int amount) {
|
||||||
balanceInDkkCents += amount;
|
balanceDkkCents += amount;
|
||||||
}
|
}
|
||||||
|
|
||||||
Result<int, String> pay(int amount) {
|
Result<int, String> pay(int amount) {
|
||||||
if (balanceInDkkCents < amount) {
|
if (balanceDkkCents < amount) {
|
||||||
return Err("User can not afford paying amount $amount");
|
return Err("User can not afford paying amount $amount");
|
||||||
}
|
}
|
||||||
balanceInDkkCents -= amount;
|
balanceDkkCents -= amount;
|
||||||
return Ok(balanceInDkkCents);
|
return Ok(balanceDkkCents);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -129,7 +129,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].priceInDkkCents,
|
price: products[idx].priceDkkCent,
|
||||||
productPage: ProductPage(product: products[idx]),
|
productPage: ProductPage(product: products[idx]),
|
||||||
product: products[idx],
|
product: products[idx],
|
||||||
),
|
),
|
||||||
|
@ -13,7 +13,7 @@ import 'package:mobile/widgets/sized_card.dart';
|
|||||||
import 'package:provider/provider.dart';
|
import 'package:provider/provider.dart';
|
||||||
|
|
||||||
class CartItemView extends StatelessWidget {
|
class CartItemView extends StatelessWidget {
|
||||||
final CartController cartRepo;
|
final CartControllerCache cartRepo;
|
||||||
final int productId;
|
final int productId;
|
||||||
final String name;
|
final String name;
|
||||||
final int price;
|
final int price;
|
||||||
@ -150,7 +150,7 @@ class CartPage extends StatelessWidget {
|
|||||||
return Column(
|
return Column(
|
||||||
children: [
|
children: [
|
||||||
Expanded(
|
Expanded(
|
||||||
child: Consumer<CartController>(
|
child: Consumer<CartControllerCache>(
|
||||||
builder: (_, cartRepo, __) {
|
builder: (_, cartRepo, __) {
|
||||||
final cart = cartRepo.allCartItems();
|
final cart = cartRepo.allCartItems();
|
||||||
return ListView.builder(
|
return ListView.builder(
|
||||||
@ -159,7 +159,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.priceInDkkCents,
|
price: cart[idx].product.priceDkkCent,
|
||||||
amount: cart[idx].amount),
|
amount: cart[idx].amount),
|
||||||
itemCount: cart.length,
|
itemCount: cart.length,
|
||||||
);
|
);
|
||||||
@ -202,9 +202,9 @@ class CartPage extends StatelessWidget {
|
|||||||
onPressed: () {
|
onPressed: () {
|
||||||
final productRepo = context
|
final productRepo = context
|
||||||
.read<ProductController>();
|
.read<ProductController>();
|
||||||
final CartController cartRepo =
|
final CartControllerCache
|
||||||
context
|
cartRepo = context.read<
|
||||||
.read<CartController>();
|
CartControllerCache>();
|
||||||
final productResult = productRepo
|
final productResult = productRepo
|
||||||
.productWithBarcode(
|
.productWithBarcode(
|
||||||
inputController.text);
|
inputController.text);
|
||||||
@ -260,8 +260,8 @@ class CartPage extends StatelessWidget {
|
|||||||
if (!context.mounted) {
|
if (!context.mounted) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
final CartController cartRepo =
|
final CartControllerCache cartRepo =
|
||||||
context.read<CartController>();
|
context.read<CartControllerCache>();
|
||||||
final productRepo =
|
final productRepo =
|
||||||
context.read<ProductController>();
|
context.read<ProductController>();
|
||||||
final productResult = productRepo
|
final productResult = productRepo
|
||||||
|
@ -23,7 +23,7 @@ class Dashboard extends StatelessWidget {
|
|||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
final pageIndexProvider = Provider.of<RoutingController>(context);
|
final pageIndexProvider = Provider.of<RoutingController>(context);
|
||||||
int currentIndex = pageIndexProvider.currentIndex;
|
int currentIndex = pageIndexProvider.currentIndex;
|
||||||
final CartController cartRepo = context.watch<CartController>();
|
final CartControllerCache cartRepo = context.watch<CartControllerCache>();
|
||||||
|
|
||||||
return Scaffold(
|
return Scaffold(
|
||||||
bottomNavigationBar: BottomNavigationBar(
|
bottomNavigationBar: BottomNavigationBar(
|
||||||
|
@ -14,7 +14,8 @@ class FinishShoppingPage extends StatelessWidget {
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
final CartController cartController = context.read<CartController>();
|
final CartControllerCache cartController =
|
||||||
|
context.read<CartControllerCache>();
|
||||||
final ReceiptController receiptRepo = context.read<ReceiptController>();
|
final ReceiptController receiptRepo = context.read<ReceiptController>();
|
||||||
final PayingStateController payingStateRepo =
|
final PayingStateController payingStateRepo =
|
||||||
context.watch<PayingStateController>();
|
context.watch<PayingStateController>();
|
||||||
@ -33,7 +34,7 @@ class FinishShoppingPage extends StatelessWidget {
|
|||||||
child: ListView.builder(
|
child: ListView.builder(
|
||||||
shrinkWrap: true,
|
shrinkWrap: true,
|
||||||
itemBuilder: (_, idx) => ReceiptItemView(
|
itemBuilder: (_, idx) => ReceiptItemView(
|
||||||
pricePerAmount: cart[idx].product.priceInDkkCents,
|
pricePerAmount: cart[idx].product.priceDkkCent,
|
||||||
name: cart[idx].product.name,
|
name: cart[idx].product.name,
|
||||||
amount: cart[idx].amount),
|
amount: cart[idx].amount),
|
||||||
itemCount: cart.length),
|
itemCount: cart.length),
|
||||||
|
@ -38,7 +38,7 @@ class HomePage extends StatelessWidget {
|
|||||||
sessionController: sessionController,
|
sessionController: sessionController,
|
||||||
placeholder: const CircularProgressIndicator(),
|
placeholder: const CircularProgressIndicator(),
|
||||||
builder: (context, user) => Text(
|
builder: (context, user) => Text(
|
||||||
"Saldo: ${formatDkkCents(user.balanceInDkkCents)}",
|
"Saldo: ${formatDkkCents(user.balanceDkkCents)}",
|
||||||
style: Theme.of(context).textTheme.headlineSmall))),
|
style: Theme.of(context).textTheme.headlineSmall))),
|
||||||
),
|
),
|
||||||
Expanded(
|
Expanded(
|
||||||
|
@ -38,7 +38,7 @@ class ProductPage extends StatelessWidget {
|
|||||||
),
|
),
|
||||||
),
|
),
|
||||||
Text(
|
Text(
|
||||||
formatDkkCents(product.priceInDkkCents),
|
formatDkkCents(product.priceDkkCent),
|
||||||
style: const TextStyle(
|
style: const TextStyle(
|
||||||
fontSize: 16,
|
fontSize: 16,
|
||||||
),
|
),
|
||||||
@ -66,7 +66,7 @@ class ProductPage extends StatelessWidget {
|
|||||||
style: Theme.of(context).textTheme.bodyLarge,
|
style: Theme.of(context).textTheme.bodyLarge,
|
||||||
),
|
),
|
||||||
Text(
|
Text(
|
||||||
formatDkkCents(product.priceInDkkCents),
|
formatDkkCents(product.priceDkkCent),
|
||||||
style: Theme.of(context).textTheme.bodyLarge,
|
style: Theme.of(context).textTheme.bodyLarge,
|
||||||
),
|
),
|
||||||
Padding(
|
Padding(
|
||||||
@ -90,7 +90,7 @@ class ProductPage extends StatelessWidget {
|
|||||||
duration: const Duration(seconds: 2),
|
duration: const Duration(seconds: 2),
|
||||||
);
|
);
|
||||||
ScaffoldMessenger.of(context).removeCurrentSnackBar();
|
ScaffoldMessenger.of(context).removeCurrentSnackBar();
|
||||||
final cartRepo = context.read<CartController>();
|
final cartRepo = context.read<CartControllerCache>();
|
||||||
cartRepo.addToCart(product);
|
cartRepo.addToCart(product);
|
||||||
ScaffoldMessenger.of(context).showSnackBar(snackBar);
|
ScaffoldMessenger.of(context).showSnackBar(snackBar);
|
||||||
},
|
},
|
||||||
|
@ -29,7 +29,7 @@ class ReceiptView extends StatelessWidget {
|
|||||||
shrinkWrap: true,
|
shrinkWrap: true,
|
||||||
itemBuilder: (_, idx) => ReceiptItemView(
|
itemBuilder: (_, idx) => ReceiptItemView(
|
||||||
pricePerAmount:
|
pricePerAmount:
|
||||||
receiptItems[idx].product.priceInDkkCents,
|
receiptItems[idx].product.priceDkkCent,
|
||||||
name: receiptItems[idx].product.name,
|
name: receiptItems[idx].product.name,
|
||||||
amount: receiptItems[idx].amount),
|
amount: receiptItems[idx].amount),
|
||||||
itemCount: receiptItems.length),
|
itemCount: receiptItems.length),
|
||||||
|
@ -29,7 +29,7 @@ class SaldoSettingsPage extends StatelessWidget {
|
|||||||
sessionController: sessionController,
|
sessionController: sessionController,
|
||||||
placeholder: const CircularProgressIndicator(),
|
placeholder: const CircularProgressIndicator(),
|
||||||
builder: (context, user) => Text(
|
builder: (context, user) => Text(
|
||||||
"Nuværende saldo: ${formatDkkCents(user.balanceInDkkCents)}",
|
"Nuværende saldo: ${formatDkkCents(user.balanceDkkCents)}",
|
||||||
style: Theme.of(context).textTheme.bodyLarge),
|
style: Theme.of(context).textTheme.bodyLarge),
|
||||||
),
|
),
|
||||||
ElevatedButton.icon(
|
ElevatedButton.icon(
|
||||||
|
@ -11,90 +11,80 @@ class MockServer implements Server {
|
|||||||
Product(
|
Product(
|
||||||
id: nextId++,
|
id: nextId++,
|
||||||
name: "Minimælk",
|
name: "Minimælk",
|
||||||
priceInDkkCents: 1200,
|
priceDkkCent: 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",
|
||||||
priceInDkkCents: 1300,
|
priceDkkCent: 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",
|
||||||
priceInDkkCents: 2000,
|
priceDkkCent: 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",
|
||||||
priceInDkkCents: 1000,
|
priceDkkCent: 1000,
|
||||||
description: ""),
|
description: ""),
|
||||||
Product(
|
Product(
|
||||||
id: nextId++,
|
id: nextId++, name: "Øko Agurk", priceDkkCent: 1000, description: ""),
|
||||||
name: "Øko Agurk",
|
|
||||||
priceInDkkCents: 1000,
|
|
||||||
description: ""),
|
|
||||||
Product(
|
Product(
|
||||||
id: nextId++,
|
id: nextId++,
|
||||||
name: "Æbler 1 kg",
|
name: "Æbler 1 kg",
|
||||||
priceInDkkCents: 1000,
|
priceDkkCent: 1000,
|
||||||
description: ""),
|
description: ""),
|
||||||
Product(
|
Product(
|
||||||
id: nextId++,
|
id: nextId++,
|
||||||
name: "Basmati Ris",
|
name: "Basmati Ris",
|
||||||
priceInDkkCents: 2000,
|
priceDkkCent: 2000,
|
||||||
description: ""),
|
description: ""),
|
||||||
Product(
|
Product(
|
||||||
id: nextId++,
|
id: nextId++,
|
||||||
name: "Haribo Mix",
|
name: "Haribo Mix",
|
||||||
priceInDkkCents: 3000,
|
priceDkkCent: 3000,
|
||||||
description: ""),
|
description: ""),
|
||||||
Product(
|
Product(id: nextId++, name: "Smør", priceDkkCent: 3000, description: ""),
|
||||||
id: nextId++, name: "Smør", priceInDkkCents: 3000, description: ""),
|
|
||||||
Product(
|
Product(
|
||||||
id: nextId++,
|
id: nextId++,
|
||||||
name: "Harboe Cola",
|
name: "Harboe Cola",
|
||||||
priceInDkkCents: 500,
|
priceDkkCent: 500,
|
||||||
description: ""),
|
description: ""),
|
||||||
Product(
|
Product(
|
||||||
id: nextId++,
|
id: nextId++,
|
||||||
barcode: "5060337502900",
|
barcode: "5060337502900",
|
||||||
name: "Monster Energi Drik",
|
name: "Monster Energi Drik",
|
||||||
priceInDkkCents: 1500,
|
priceDkkCent: 1500,
|
||||||
description: ""),
|
description: ""),
|
||||||
Product(
|
Product(
|
||||||
id: nextId++,
|
id: nextId++,
|
||||||
barcode: "5712870659220",
|
barcode: "5712870659220",
|
||||||
name: "Amper Energi Drik",
|
name: "Amper Energi Drik",
|
||||||
priceInDkkCents: 750,
|
priceDkkCent: 750,
|
||||||
description: ""),
|
description: ""),
|
||||||
Product(
|
Product(
|
||||||
id: nextId++,
|
id: nextId++,
|
||||||
barcode: "5710326001937",
|
barcode: "5710326001937",
|
||||||
name: "Danskvand Med Brus",
|
name: "Danskvand Med Brus",
|
||||||
priceInDkkCents: 500,
|
priceDkkCent: 500,
|
||||||
description: "Med smag a blåbær"),
|
description: "Med smag a blåbær"),
|
||||||
Product(
|
Product(
|
||||||
id: nextId++,
|
id: nextId++, name: "Spaghetti", priceDkkCent: 1000, description: ""),
|
||||||
name: "Spaghetti",
|
|
||||||
priceInDkkCents: 1000,
|
|
||||||
description: ""),
|
|
||||||
Product(
|
Product(
|
||||||
id: nextId++,
|
id: nextId++, name: "Rød Cecil", priceDkkCent: 6000, description: ""),
|
||||||
name: "Rød Cecil",
|
|
||||||
priceInDkkCents: 6000,
|
|
||||||
description: ""),
|
|
||||||
Product(
|
Product(
|
||||||
id: nextId++,
|
id: nextId++,
|
||||||
name: "Jägermeister 750 ml",
|
name: "Jägermeister 750 ml",
|
||||||
priceInDkkCents: 12000,
|
priceDkkCent: 12000,
|
||||||
description: ""),
|
description: ""),
|
||||||
Product(
|
Product(
|
||||||
id: nextId++,
|
id: nextId++,
|
||||||
barcode: "5711953068881",
|
barcode: "5711953068881",
|
||||||
name: "Protein Chokoladedrik",
|
name: "Protein Chokoladedrik",
|
||||||
priceInDkkCents: 1500,
|
priceDkkCent: 1500,
|
||||||
description: "Arla's protein chokolade drik der giver store muskler"),
|
description: "Arla's protein chokolade drik der giver store muskler"),
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
@ -128,7 +118,7 @@ class MockServer implements Server {
|
|||||||
id: 0,
|
id: 0,
|
||||||
email: "test@test.com",
|
email: "test@test.com",
|
||||||
name: "testuser",
|
name: "testuser",
|
||||||
balanceInDkkCents: 10000));
|
balanceDkkCents: 10000));
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
import 'package:intl/intl.dart';
|
import 'package:intl/intl.dart';
|
||||||
|
|
||||||
String formatDkkCents(int priceInDkkCents) {
|
String formatDkkCents(int priceDkkCents) {
|
||||||
final formatter = NumberFormat("###,##0.00", "da_DK");
|
final formatter = NumberFormat("###,##0.00", "da_DK");
|
||||||
return "${formatter.format(priceInDkkCents / 100.0)} kr";
|
return "${formatter.format(priceDkkCents / 100.0)} kr";
|
||||||
}
|
}
|
||||||
|
@ -268,7 +268,7 @@ packages:
|
|||||||
source: hosted
|
source: hosted
|
||||||
version: "1.9.1"
|
version: "1.9.1"
|
||||||
path_provider:
|
path_provider:
|
||||||
dependency: transitive
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
name: path_provider
|
name: path_provider
|
||||||
sha256: "50c5dd5b6e1aaf6fb3a78b33f6aa3afca52bf903a8a5298f53101fdaee55bbcd"
|
sha256: "50c5dd5b6e1aaf6fb3a78b33f6aa3afca52bf903a8a5298f53101fdaee55bbcd"
|
||||||
|
@ -39,6 +39,7 @@ dependencies:
|
|||||||
google_fonts: ^6.2.1
|
google_fonts: ^6.2.1
|
||||||
intl: ^0.20.2
|
intl: ^0.20.2
|
||||||
http: ^1.3.0
|
http: ^1.3.0
|
||||||
|
path_provider: ^2.1.5
|
||||||
|
|
||||||
dev_dependencies:
|
dev_dependencies:
|
||||||
flutter_test:
|
flutter_test:
|
||||||
|
Loading…
x
Reference in New Issue
Block a user