mirror of
https://github.com/Mercantec-GHC/h4-projekt-gruppe-0-sm.git
synced 2025-04-28 00:34:06 +02:00
receipt/all and receipt/one for frontend
This commit is contained in:
parent
c729175a28
commit
fd288dafee
@ -1,85 +1,16 @@
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:mobile/controllers/session.dart';
|
||||||
import 'package:mobile/models/cart_item.dart';
|
import 'package:mobile/models/receipt.dart';
|
||||||
import 'package:mobile/models/product.dart';
|
import 'package:mobile/results.dart';
|
||||||
|
import 'package:mobile/server/server.dart';
|
||||||
|
|
||||||
class ReceiptController extends ChangeNotifier {
|
class ReceiptController {
|
||||||
int nextId = 0;
|
final Server server;
|
||||||
final List<Receipt> receipts = [];
|
final SessionController sessionController;
|
||||||
|
|
||||||
List<Receipt> allReceipts() {
|
ReceiptController({required this.server, required this.sessionController});
|
||||||
return receipts;
|
|
||||||
}
|
|
||||||
|
|
||||||
List<Receipt> sortedReceiptsByDate() {
|
Future<Result<Receipt, String>> receiptWithId(int id) async {
|
||||||
List<Receipt> clonedReceipts = [];
|
return await sessionController.requestWithSession(
|
||||||
for (var i = 0; i < receipts.length; i++) {
|
(Server server, String token) => server.oneReceipt(token, id));
|
||||||
clonedReceipts.add(receipts[i]);
|
|
||||||
}
|
|
||||||
clonedReceipts.sort((a, b) => b.date.compareTo(a.date));
|
|
||||||
return clonedReceipts;
|
|
||||||
}
|
|
||||||
|
|
||||||
Receipt? receiptWithId(int id) {
|
|
||||||
for (var i = 0; i < receipts.length; i++) {
|
|
||||||
if (receipts[i].id == id) {
|
|
||||||
return receipts[i];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
void createReceipt(List<CartItem> cartItems) {
|
|
||||||
List<ReceiptItem> receiptItems = [];
|
|
||||||
for (var i = 0; i < cartItems.length; i++) {
|
|
||||||
final ReceiptItem receiptItem = ReceiptItem(
|
|
||||||
amount: cartItems[i].amount, product: cartItems[i].product);
|
|
||||||
receiptItems.add(receiptItem);
|
|
||||||
}
|
|
||||||
receipts.add(Receipt(
|
|
||||||
date: DateTime.now(), receiptItems: receiptItems, id: nextId++));
|
|
||||||
notifyListeners();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
class Receipt {
|
|
||||||
final int id;
|
|
||||||
final DateTime date;
|
|
||||||
final List<ReceiptItem> receiptItems;
|
|
||||||
|
|
||||||
Receipt({required this.date, required this.receiptItems, required this.id});
|
|
||||||
|
|
||||||
List<ReceiptItem> allReceiptItems() {
|
|
||||||
return receiptItems;
|
|
||||||
}
|
|
||||||
|
|
||||||
ReceiptItem? withProductId(int productId) {
|
|
||||||
for (var i = 0; i < receiptItems.length; i++) {
|
|
||||||
if (receiptItems[i].product.id == productId) {
|
|
||||||
return receiptItems[i];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
int totalPrice() {
|
|
||||||
var result = 0;
|
|
||||||
for (var i = 0; i < receiptItems.length; i++) {
|
|
||||||
result += receiptItems[i].totalPrice();
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
String dateFormatted() {
|
|
||||||
return "${date.day}-${date.month}-${date.year}";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
class ReceiptItem {
|
|
||||||
final Product product;
|
|
||||||
final int amount;
|
|
||||||
ReceiptItem({required this.product, required this.amount});
|
|
||||||
|
|
||||||
int totalPrice() {
|
|
||||||
return product.priceDkkCent * amount;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
40
mobile/lib/controllers/receipt_header.dart
Normal file
40
mobile/lib/controllers/receipt_header.dart
Normal file
@ -0,0 +1,40 @@
|
|||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:mobile/controllers/session.dart';
|
||||||
|
import 'package:mobile/models/receipt.dart';
|
||||||
|
import 'package:mobile/results.dart';
|
||||||
|
import 'package:mobile/server/server.dart';
|
||||||
|
|
||||||
|
class ReceiptHeaderController extends ChangeNotifier {
|
||||||
|
List<ReceiptHeader> _receiptHeaders = [];
|
||||||
|
|
||||||
|
final Server server;
|
||||||
|
|
||||||
|
final SessionController sessionController;
|
||||||
|
|
||||||
|
ReceiptHeaderController(
|
||||||
|
{required this.server, required this.sessionController}) {
|
||||||
|
fetchReceiptsFromServer();
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<void> fetchReceiptsFromServer() async {
|
||||||
|
final res = await sessionController.requestWithSession(
|
||||||
|
(Server server, String token) => server.allReceipts(token));
|
||||||
|
|
||||||
|
switch (res) {
|
||||||
|
case Ok<List<ReceiptHeader>, String>(value: final receiptHeaders):
|
||||||
|
_receiptHeaders = receiptHeaders;
|
||||||
|
case Err<List<ReceiptHeader>, String>():
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
notifyListeners();
|
||||||
|
}
|
||||||
|
|
||||||
|
List<ReceiptHeader> receiptHeadersSortedByDate() {
|
||||||
|
List<ReceiptHeader> clonedReceiptHeaders = [];
|
||||||
|
for (var i = 0; i < _receiptHeaders.length; i++) {
|
||||||
|
clonedReceiptHeaders.add(_receiptHeaders[i]);
|
||||||
|
}
|
||||||
|
clonedReceiptHeaders.sort((a, b) => b.timestamp.compareTo(a.timestamp));
|
||||||
|
return clonedReceiptHeaders;
|
||||||
|
}
|
||||||
|
}
|
@ -1,5 +1,6 @@
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:google_fonts/google_fonts.dart';
|
import 'package:google_fonts/google_fonts.dart';
|
||||||
|
import 'package:mobile/controllers/receipt_header.dart';
|
||||||
import 'package:mobile/controllers/session.dart';
|
import 'package:mobile/controllers/session.dart';
|
||||||
import 'package:mobile/pages/dashboard.dart';
|
import 'package:mobile/pages/dashboard.dart';
|
||||||
import 'package:mobile/pages/log_in_page.dart';
|
import 'package:mobile/pages/log_in_page.dart';
|
||||||
@ -56,7 +57,12 @@ class MyApp extends StatelessWidget {
|
|||||||
ChangeNotifierProvider(
|
ChangeNotifierProvider(
|
||||||
create: (_) => CartControllerCache(
|
create: (_) => CartControllerCache(
|
||||||
server: server, sessionController: sessionController)),
|
server: server, sessionController: sessionController)),
|
||||||
ChangeNotifierProvider(create: (_) => ReceiptController()),
|
Provider(
|
||||||
|
create: (_) => ReceiptController(
|
||||||
|
server: server, sessionController: sessionController)),
|
||||||
|
ChangeNotifierProvider(
|
||||||
|
create: (_) => ReceiptHeaderController(
|
||||||
|
server: server, sessionController: sessionController)),
|
||||||
ChangeNotifierProvider(create: (_) => PayingStateController()),
|
ChangeNotifierProvider(create: (_) => PayingStateController()),
|
||||||
ChangeNotifierProvider(create: (_) => AddToCartStateController()),
|
ChangeNotifierProvider(create: (_) => AddToCartStateController()),
|
||||||
ChangeNotifierProvider(create: (_) => LocationImageController()),
|
ChangeNotifierProvider(create: (_) => LocationImageController()),
|
||||||
|
72
mobile/lib/models/receipt.dart
Normal file
72
mobile/lib/models/receipt.dart
Normal file
@ -0,0 +1,72 @@
|
|||||||
|
class Receipt {
|
||||||
|
final int id;
|
||||||
|
final DateTime timestamp;
|
||||||
|
final List<ReceiptItem> receiptItems;
|
||||||
|
|
||||||
|
Receipt(
|
||||||
|
{required this.timestamp, required this.receiptItems, required this.id});
|
||||||
|
|
||||||
|
List<ReceiptItem> allReceiptItems() {
|
||||||
|
return receiptItems;
|
||||||
|
}
|
||||||
|
|
||||||
|
ReceiptItem? withProductId(int productId) {
|
||||||
|
for (var i = 0; i < receiptItems.length; i++) {
|
||||||
|
if (receiptItems[i].productId == productId) {
|
||||||
|
return receiptItems[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
int totalPrice() {
|
||||||
|
var result = 0;
|
||||||
|
for (var i = 0; i < receiptItems.length; i++) {
|
||||||
|
result += receiptItems[i].totalPrice();
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
Receipt.fromJson(Map<String, dynamic> json)
|
||||||
|
: id = json["receipt_id"],
|
||||||
|
timestamp = DateTime.parse(json["timestamp"]),
|
||||||
|
receiptItems = (json["products"] as List<dynamic>)
|
||||||
|
.map(((receiptItem) => ReceiptItem.fromJson(receiptItem)))
|
||||||
|
.toList();
|
||||||
|
}
|
||||||
|
|
||||||
|
class ReceiptItem {
|
||||||
|
final int productId;
|
||||||
|
final String name;
|
||||||
|
final int priceDkkCent;
|
||||||
|
final int amount;
|
||||||
|
ReceiptItem(
|
||||||
|
{required this.productId,
|
||||||
|
required this.name,
|
||||||
|
required this.priceDkkCent,
|
||||||
|
required this.amount});
|
||||||
|
|
||||||
|
int totalPrice() {
|
||||||
|
return priceDkkCent * amount;
|
||||||
|
}
|
||||||
|
|
||||||
|
ReceiptItem.fromJson(Map<String, dynamic> json)
|
||||||
|
: productId = json["product_id"],
|
||||||
|
name = json["name"],
|
||||||
|
priceDkkCent = json["price_dkk_cent"],
|
||||||
|
amount = json["amount"];
|
||||||
|
}
|
||||||
|
|
||||||
|
class ReceiptHeader {
|
||||||
|
final int id;
|
||||||
|
final DateTime timestamp;
|
||||||
|
final int totalDkkCent;
|
||||||
|
|
||||||
|
ReceiptHeader(
|
||||||
|
{required this.timestamp, required this.id, required this.totalDkkCent});
|
||||||
|
|
||||||
|
ReceiptHeader.fromJson(Map<String, dynamic> json)
|
||||||
|
: id = json["id"],
|
||||||
|
totalDkkCent = json["total_dkk_cent"],
|
||||||
|
timestamp = DateTime.parse(json["timestamp"]);
|
||||||
|
}
|
@ -1,18 +1,14 @@
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:mobile/controllers/receipt_header.dart';
|
||||||
|
import 'package:mobile/models/receipt.dart';
|
||||||
import 'package:mobile/pages/receipt_page.dart';
|
import 'package:mobile/pages/receipt_page.dart';
|
||||||
import 'package:mobile/controllers/receipt.dart';
|
import 'package:mobile/utils/date.dart';
|
||||||
import 'package:mobile/utils/price.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 {
|
||||||
final String dateFormatted;
|
final ReceiptHeader receiptHeader;
|
||||||
final int totalPrice;
|
const ReceiptsListItem({super.key, required this.receiptHeader});
|
||||||
final ReceiptPage receiptPage;
|
|
||||||
const ReceiptsListItem(
|
|
||||||
{super.key,
|
|
||||||
required this.dateFormatted,
|
|
||||||
required this.totalPrice,
|
|
||||||
required this.receiptPage});
|
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
@ -21,14 +17,19 @@ class ReceiptsListItem extends StatelessWidget {
|
|||||||
child: InkWell(
|
child: InkWell(
|
||||||
borderRadius: const BorderRadius.all(Radius.circular(10)),
|
borderRadius: const BorderRadius.all(Radius.circular(10)),
|
||||||
onTap: () {
|
onTap: () {
|
||||||
Navigator.of(context)
|
Navigator.of(context).push(MaterialPageRoute(
|
||||||
.push(MaterialPageRoute(builder: (context) => receiptPage));
|
builder: (context) => ReceiptPage(
|
||||||
|
receiptId: receiptHeader.id,
|
||||||
|
)));
|
||||||
},
|
},
|
||||||
child: Container(
|
child: Container(
|
||||||
padding: const EdgeInsets.all(20),
|
padding: const EdgeInsets.all(20),
|
||||||
child: Row(
|
child: Row(
|
||||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||||
children: [Text(dateFormatted), Text(formatDkkCents(totalPrice))],
|
children: [
|
||||||
|
Text(dateFormatted(receiptHeader.timestamp)),
|
||||||
|
Text(formatDkkCents(receiptHeader.totalDkkCent))
|
||||||
|
],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
@ -41,20 +42,21 @@ class AllReceiptsPage extends StatelessWidget {
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
|
context.read<ReceiptHeaderController>().fetchReceiptsFromServer();
|
||||||
return Column(
|
return Column(
|
||||||
children: [
|
children: [
|
||||||
Expanded(child: Consumer<ReceiptController>(
|
Expanded(child: Consumer<ReceiptHeaderController>(
|
||||||
builder: (_, receiptRepo, __) {
|
builder: (_, receiptHeaderController, __) {
|
||||||
final allReceipts = receiptRepo.sortedReceiptsByDate();
|
final allReceiptHeaders =
|
||||||
|
receiptHeaderController.receiptHeadersSortedByDate();
|
||||||
return ListView.builder(
|
return ListView.builder(
|
||||||
shrinkWrap: true,
|
shrinkWrap: true,
|
||||||
itemBuilder: (_, idx) {
|
itemBuilder: (_, idx) {
|
||||||
return ReceiptsListItem(
|
return ReceiptsListItem(
|
||||||
dateFormatted: allReceipts[idx].dateFormatted(),
|
receiptHeader: allReceiptHeaders[idx],
|
||||||
totalPrice: allReceipts[idx].totalPrice(),
|
);
|
||||||
receiptPage: ReceiptPage(receipt: allReceipts[idx]));
|
|
||||||
},
|
},
|
||||||
itemCount: allReceipts.length,
|
itemCount: allReceiptHeaders.length,
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
)),
|
)),
|
||||||
|
@ -2,7 +2,6 @@ import 'package:flutter/material.dart';
|
|||||||
import 'package:mobile/controllers/routing.dart';
|
import 'package:mobile/controllers/routing.dart';
|
||||||
import 'package:mobile/controllers/cart.dart';
|
import 'package:mobile/controllers/cart.dart';
|
||||||
import 'package:mobile/controllers/paying_state.dart';
|
import 'package:mobile/controllers/paying_state.dart';
|
||||||
import 'package:mobile/controllers/receipt.dart';
|
|
||||||
import 'package:mobile/results.dart';
|
import 'package:mobile/results.dart';
|
||||||
import 'package:mobile/utils/price.dart';
|
import 'package:mobile/utils/price.dart';
|
||||||
import 'package:mobile/widgets/primary_button.dart';
|
import 'package:mobile/widgets/primary_button.dart';
|
||||||
@ -16,7 +15,6 @@ class FinishShoppingPage extends StatelessWidget {
|
|||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
final CartControllerCache cartController =
|
final CartControllerCache cartController =
|
||||||
context.read<CartControllerCache>();
|
context.read<CartControllerCache>();
|
||||||
final ReceiptController receiptRepo = context.read<ReceiptController>();
|
|
||||||
final PayingStateController payingStateRepo =
|
final PayingStateController payingStateRepo =
|
||||||
context.watch<PayingStateController>();
|
context.watch<PayingStateController>();
|
||||||
final cart = cartController.allCartItems();
|
final cart = cartController.allCartItems();
|
||||||
@ -70,8 +68,8 @@ class FinishShoppingPage extends StatelessWidget {
|
|||||||
actions: <Widget>[
|
actions: <Widget>[
|
||||||
TextButton(
|
TextButton(
|
||||||
onPressed: () =>
|
onPressed: () =>
|
||||||
Navigator.pop(context, 'OK'),
|
Navigator.pop(context, 'Ok'),
|
||||||
child: const Text('OK'),
|
child: const Text('Ok'),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
@ -80,7 +78,6 @@ class FinishShoppingPage extends StatelessWidget {
|
|||||||
payingStateRepo.reset();
|
payingStateRepo.reset();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
receiptRepo.createReceipt(cart);
|
|
||||||
payingStateRepo.next();
|
payingStateRepo.next();
|
||||||
await Future.delayed(const Duration(seconds: 1));
|
await Future.delayed(const Duration(seconds: 1));
|
||||||
cartController.clearCart();
|
cartController.clearCart();
|
||||||
|
@ -1,15 +1,19 @@
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:mobile/controllers/receipt.dart';
|
import 'package:mobile/controllers/receipt.dart';
|
||||||
|
import 'package:mobile/models/receipt.dart';
|
||||||
|
import 'package:mobile/results.dart';
|
||||||
|
import 'package:mobile/utils/date.dart';
|
||||||
import 'package:mobile/utils/price.dart';
|
import 'package:mobile/utils/price.dart';
|
||||||
import 'package:mobile/widgets/receipt_item.dart';
|
import 'package:mobile/widgets/receipt_item.dart';
|
||||||
|
import 'package:provider/provider.dart';
|
||||||
|
|
||||||
class ReceiptView extends StatelessWidget {
|
class ReceiptView extends StatelessWidget {
|
||||||
final Receipt receipt;
|
final int receiptId;
|
||||||
const ReceiptView({super.key, required this.receipt});
|
const ReceiptView({super.key, required this.receiptId});
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
final receiptItems = receipt.allReceiptItems();
|
final receiptController = context.read<ReceiptController>();
|
||||||
|
|
||||||
return SafeArea(
|
return SafeArea(
|
||||||
child: Column(
|
child: Column(
|
||||||
@ -19,34 +23,65 @@ class ReceiptView extends StatelessWidget {
|
|||||||
Expanded(
|
Expanded(
|
||||||
child: Container(
|
child: Container(
|
||||||
margin: const EdgeInsets.all(20),
|
margin: const EdgeInsets.all(20),
|
||||||
child: Column(
|
child: FutureBuilder(
|
||||||
children: [
|
future: receiptController.receiptWithId(receiptId),
|
||||||
Text(receipt.dateFormatted()),
|
builder: (context, snapshot) {
|
||||||
Expanded(
|
final error = snapshot.error;
|
||||||
child: Column(
|
if (error != null) {
|
||||||
children: [
|
throw error;
|
||||||
ListView.builder(
|
}
|
||||||
shrinkWrap: true,
|
final receipt = snapshot.data;
|
||||||
itemBuilder: (_, idx) => ReceiptItemView(
|
switch (receipt) {
|
||||||
pricePerAmount:
|
case null:
|
||||||
receiptItems[idx].product.priceDkkCent,
|
return const CircularProgressIndicator();
|
||||||
name: receiptItems[idx].product.name,
|
case Err<Receipt, String>(value: final message):
|
||||||
amount: receiptItems[idx].amount),
|
showDialog<String>(
|
||||||
itemCount: receiptItems.length),
|
context: context,
|
||||||
Row(
|
builder: (BuildContext context) => AlertDialog(
|
||||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
content: Text(message),
|
||||||
children: [
|
actions: <Widget>[
|
||||||
const Text(
|
TextButton(
|
||||||
"Total:",
|
onPressed: () => Navigator.pop(context, 'Ok'),
|
||||||
style: TextStyle(fontWeight: FontWeight.bold),
|
child: const Text('Ok'),
|
||||||
|
),
|
||||||
|
],
|
||||||
),
|
),
|
||||||
Text(formatDkkCents(receipt.totalPrice())),
|
);
|
||||||
],
|
return Container();
|
||||||
),
|
case Ok<Receipt, String>(value: final receipt):
|
||||||
],
|
return Column(
|
||||||
)),
|
children: [
|
||||||
],
|
Text(dateFormatted(receipt.timestamp)),
|
||||||
),
|
Expanded(
|
||||||
|
child: Column(
|
||||||
|
children: [
|
||||||
|
ListView.builder(
|
||||||
|
shrinkWrap: true,
|
||||||
|
itemBuilder: (_, idx) => ReceiptItemView(
|
||||||
|
pricePerAmount: receipt
|
||||||
|
.receiptItems[idx].priceDkkCent,
|
||||||
|
name: receipt.receiptItems[idx].name,
|
||||||
|
amount:
|
||||||
|
receipt.receiptItems[idx].amount),
|
||||||
|
itemCount: receipt.receiptItems.length),
|
||||||
|
Row(
|
||||||
|
mainAxisAlignment:
|
||||||
|
MainAxisAlignment.spaceBetween,
|
||||||
|
children: [
|
||||||
|
const Text(
|
||||||
|
"Total:",
|
||||||
|
style: TextStyle(
|
||||||
|
fontWeight: FontWeight.bold),
|
||||||
|
),
|
||||||
|
Text(formatDkkCents(receipt.totalPrice())),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
],
|
||||||
|
)),
|
||||||
|
],
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
@ -56,12 +91,12 @@ class ReceiptView extends StatelessWidget {
|
|||||||
}
|
}
|
||||||
|
|
||||||
class ReceiptPage extends StatelessWidget {
|
class ReceiptPage extends StatelessWidget {
|
||||||
final Receipt receipt;
|
final int receiptId;
|
||||||
|
|
||||||
const ReceiptPage({super.key, required this.receipt});
|
const ReceiptPage({super.key, required this.receiptId});
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return Scaffold(body: ReceiptView(receipt: receipt));
|
return Scaffold(body: ReceiptView(receiptId: receiptId));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -42,8 +42,8 @@ class SaldoSettingsPage extends StatelessWidget {
|
|||||||
content: Text('Serverfejl: $message'),
|
content: Text('Serverfejl: $message'),
|
||||||
actions: <Widget>[
|
actions: <Widget>[
|
||||||
TextButton(
|
TextButton(
|
||||||
onPressed: () => Navigator.pop(context, 'OK'),
|
onPressed: () => Navigator.pop(context, 'Ok'),
|
||||||
child: const Text('OK'),
|
child: const Text('Ok'),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
));
|
));
|
||||||
|
@ -3,6 +3,7 @@ import 'dart:convert';
|
|||||||
import 'package:http/http.dart' as http;
|
import 'package:http/http.dart' as http;
|
||||||
import 'package:mobile/models/cart_item.dart';
|
import 'package:mobile/models/cart_item.dart';
|
||||||
import 'package:mobile/models/product.dart';
|
import 'package:mobile/models/product.dart';
|
||||||
|
import 'package:mobile/models/receipt.dart';
|
||||||
import 'package:mobile/models/user.dart';
|
import 'package:mobile/models/user.dart';
|
||||||
import 'package:mobile/results.dart';
|
import 'package:mobile/results.dart';
|
||||||
import 'package:mobile/server/server.dart';
|
import 'package:mobile/server/server.dart';
|
||||||
@ -30,7 +31,7 @@ class BackendServer implements Server {
|
|||||||
.then((res) => json.decode(res.body));
|
.then((res) => json.decode(res.body));
|
||||||
if (res["ok"]) {
|
if (res["ok"]) {
|
||||||
return Ok((res["products"] as List<dynamic>)
|
return Ok((res["products"] as List<dynamic>)
|
||||||
.map(((product) => Product.fromJson(product)))
|
.map(((productJson) => Product.fromJson(productJson)))
|
||||||
.toList());
|
.toList());
|
||||||
} else {
|
} else {
|
||||||
return Err(res["msg"]);
|
return Err(res["msg"]);
|
||||||
@ -149,4 +150,43 @@ class BackendServer implements Server {
|
|||||||
return Err(res["msg"]);
|
return Err(res["msg"]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Future<Result<List<ReceiptHeader>, String>> allReceipts(String token) async {
|
||||||
|
final res = await http.get(
|
||||||
|
Uri.parse("$_apiUrl/receipts/all"),
|
||||||
|
headers: {
|
||||||
|
"Content-Type": "application/json",
|
||||||
|
"Accept": "application/json",
|
||||||
|
"Session-Token": token
|
||||||
|
},
|
||||||
|
).then((res) => json.decode(res.body));
|
||||||
|
|
||||||
|
if (res["ok"]) {
|
||||||
|
return Ok((res["receipts"] as List<dynamic>)
|
||||||
|
.map(((receiptHeaderJson) =>
|
||||||
|
ReceiptHeader.fromJson(receiptHeaderJson)))
|
||||||
|
.toList());
|
||||||
|
} else {
|
||||||
|
return Err(res["msg"]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Future<Result<Receipt, String>> oneReceipt(String token, int id) async {
|
||||||
|
final res = await http.get(
|
||||||
|
Uri.parse("$_apiUrl/receipts/one?receipt_id=$id"),
|
||||||
|
headers: {
|
||||||
|
"Content-Type": "application/json",
|
||||||
|
"Accept": "application/json",
|
||||||
|
"Session-Token": token
|
||||||
|
},
|
||||||
|
).then((res) => json.decode(res.body));
|
||||||
|
|
||||||
|
if (res["ok"]) {
|
||||||
|
return Ok((Receipt.fromJson(res["receipt"] as Map<String, dynamic>)));
|
||||||
|
} else {
|
||||||
|
return Err(res["msg"]);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
import 'package:mobile/models/cart_item.dart';
|
import 'package:mobile/models/cart_item.dart';
|
||||||
import 'package:mobile/models/coordinate.dart';
|
import 'package:mobile/models/coordinate.dart';
|
||||||
import 'package:mobile/models/product.dart';
|
import 'package:mobile/models/product.dart';
|
||||||
|
import 'package:mobile/models/receipt.dart';
|
||||||
import 'package:mobile/models/user.dart';
|
import 'package:mobile/models/user.dart';
|
||||||
import 'package:mobile/results.dart';
|
import 'package:mobile/results.dart';
|
||||||
import 'package:mobile/server/server.dart';
|
import 'package:mobile/server/server.dart';
|
||||||
@ -132,4 +133,17 @@ class MockServer implements Server {
|
|||||||
Future<Result<Null, String>> addBalance(String token) async {
|
Future<Result<Null, String>> addBalance(String token) async {
|
||||||
return const Ok(null);
|
return const Ok(null);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Future<Result<List<ReceiptHeader>, String>> allReceipts(String token) async {
|
||||||
|
return Ok([
|
||||||
|
ReceiptHeader(timestamp: DateTime.now(), id: 0, totalDkkCent: 1242431)
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Future<Result<Receipt, String>> oneReceipt(String token, int id) async {
|
||||||
|
return Ok(Receipt(
|
||||||
|
timestamp: DateTime.now(), id: id, receiptItems: <ReceiptItem>[]));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
import 'package:mobile/models/cart_item.dart';
|
import 'package:mobile/models/cart_item.dart';
|
||||||
import 'package:mobile/models/product.dart';
|
import 'package:mobile/models/product.dart';
|
||||||
|
import 'package:mobile/models/receipt.dart';
|
||||||
import 'package:mobile/models/user.dart';
|
import 'package:mobile/models/user.dart';
|
||||||
import 'package:mobile/results.dart';
|
import 'package:mobile/results.dart';
|
||||||
|
|
||||||
@ -24,4 +25,7 @@ abstract class Server {
|
|||||||
String token, List<CartItem> cartItems);
|
String token, List<CartItem> cartItems);
|
||||||
|
|
||||||
Future<Result<Null, String>> addBalance(String token);
|
Future<Result<Null, String>> addBalance(String token);
|
||||||
|
|
||||||
|
Future<Result<List<ReceiptHeader>, String>> allReceipts(String token);
|
||||||
|
Future<Result<Receipt, String>> oneReceipt(String token, int id);
|
||||||
}
|
}
|
||||||
|
3
mobile/lib/utils/date.dart
Normal file
3
mobile/lib/utils/date.dart
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
String dateFormatted(DateTime date) {
|
||||||
|
return "${date.day}-${date.month}-${date.year} ${date.hour}:${date.minute}";
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user