diff --git a/cloudbank-v2/flutter-app/.placeholder b/cloudbank-v2/flutter-app/.placeholder deleted file mode 100644 index e69de29bb..000000000 diff --git a/cloudbank-v2/flutter-app/lib/components/accountdetailarguments.dart b/cloudbank-v2/flutter-app/lib/components/accountdetailarguments.dart new file mode 100755 index 000000000..4efd3b75c --- /dev/null +++ b/cloudbank-v2/flutter-app/lib/components/accountdetailarguments.dart @@ -0,0 +1,11 @@ +// Copyright (c) 2023, Oracle and/or its affiliates. +// Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl/ + +import 'credentials.dart'; + +class AccountDetailArguments { + final Credentials creds; + final int accountId; + + AccountDetailArguments(this.creds, this.accountId); +} diff --git a/cloudbank-v2/flutter-app/lib/components/appbar.dart b/cloudbank-v2/flutter-app/lib/components/appbar.dart index dffea7831..d5dde7539 100755 --- a/cloudbank-v2/flutter-app/lib/components/appbar.dart +++ b/cloudbank-v2/flutter-app/lib/components/appbar.dart @@ -1,3 +1,6 @@ +// Copyright (c) 2023, Oracle and/or its affiliates. +// Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl/ + import 'package:flutter/material.dart'; class CloudBankAppBar extends StatefulWidget implements PreferredSizeWidget { diff --git a/cloudbank-v2/flutter-app/lib/components/bottombuttonbar.dart b/cloudbank-v2/flutter-app/lib/components/bottombuttonbar.dart index 8310cdef8..1c053ae6d 100755 --- a/cloudbank-v2/flutter-app/lib/components/bottombuttonbar.dart +++ b/cloudbank-v2/flutter-app/lib/components/bottombuttonbar.dart @@ -1,3 +1,6 @@ +// Copyright (c) 2023, Oracle and/or its affiliates. +// Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl/ + import 'package:flutter/material.dart'; import 'package:go_router/go_router.dart'; @@ -38,20 +41,6 @@ class BottomButtonBar extends StatelessWidget { ], ), const SizedBox(height: 10), - Row( - children: [ - ElevatedButton( - onPressed: () => GoRouter.of(context).go('/resttest'), - style: ElevatedButton.styleFrom( - backgroundColor: Colors.amber[400], - ), - child: const Padding( - padding: EdgeInsets.all(16), - child: Text('REST Test'), - ), - ), - ], - ), ], ); } diff --git a/cloudbank-v2/flutter-app/lib/components/credentials.dart b/cloudbank-v2/flutter-app/lib/components/credentials.dart index 2b67848f1..ca8779324 100755 --- a/cloudbank-v2/flutter-app/lib/components/credentials.dart +++ b/cloudbank-v2/flutter-app/lib/components/credentials.dart @@ -1,3 +1,6 @@ +// Copyright (c) 2023, Oracle and/or its affiliates. +// Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl/ + class Credentials { final String username; final String email; diff --git a/cloudbank-v2/flutter-app/lib/components/myaccounts.dart b/cloudbank-v2/flutter-app/lib/components/myaccounts.dart index f61abbf36..876f45fb8 100755 --- a/cloudbank-v2/flutter-app/lib/components/myaccounts.dart +++ b/cloudbank-v2/flutter-app/lib/components/myaccounts.dart @@ -1,8 +1,18 @@ +// Copyright (c) 2023, Oracle and/or its affiliates. +// Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl/ + +import 'dart:ffi'; + import 'package:flutter/material.dart'; import 'package:loginapp/components/credentials.dart'; import 'package:loginapp/screens/accountdetail.dart'; import 'package:http/http.dart' as http; import 'dart:convert'; +import 'package:intl/intl.dart'; + +import 'accountdetailarguments.dart'; + +final formatCurrency = new NumberFormat.simpleCurrency(); class Accounts { final List accounts; @@ -87,12 +97,14 @@ class _MyAccountsState extends State { children: [ Text(data[index]['accountName'].toString()), Text( - data[index]['accountBalance'].toString(), + formatCurrency + .format(data[index]['accountBalance']), textScaleFactor: 1.5, ), ], ), - subtitle: Text(data[index]['accountId'].toString()), + subtitle: + Text("CB ACCT-${data[index]['accountId']}"), ), Row( mainAxisAlignment: MainAxisAlignment.end, @@ -103,12 +115,11 @@ class _MyAccountsState extends State { Navigator.push( context, MaterialPageRoute( - builder: (context) => - const AccountDetail(), - // Pass the arguments as part of the RouteSettings. The - // DetailScreen reads the arguments from these settings. - settings: RouteSettings( - arguments: widget.creds, + builder: (context) => AccountDetail( + args: AccountDetailArguments( + widget.creds, + data[index]['accountId'], + ), ), ), ); diff --git a/cloudbank-v2/flutter-app/lib/components/mycreditcards.dart b/cloudbank-v2/flutter-app/lib/components/mycreditcards.dart index e1b8e319e..321f33f10 100755 --- a/cloudbank-v2/flutter-app/lib/components/mycreditcards.dart +++ b/cloudbank-v2/flutter-app/lib/components/mycreditcards.dart @@ -1,3 +1,6 @@ +// Copyright (c) 2023, Oracle and/or its affiliates. +// Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl/ + import 'package:flutter/material.dart'; import 'package:go_router/go_router.dart'; diff --git a/cloudbank-v2/flutter-app/lib/main.dart b/cloudbank-v2/flutter-app/lib/main.dart index be1952359..15fcedade 100755 --- a/cloudbank-v2/flutter-app/lib/main.dart +++ b/cloudbank-v2/flutter-app/lib/main.dart @@ -1,3 +1,6 @@ +// Copyright (c) 2023, Oracle and/or its affiliates. +// Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl/ + import 'dart:io'; import 'package:flutter/material.dart'; @@ -11,7 +14,7 @@ import 'package:loginapp/screens/transfer.dart'; import 'package:parse_server_sdk_flutter/parse_server_sdk.dart'; import 'package:go_router/go_router.dart'; -const String backendUrl = 'http://129.158.244.40'; +const String backendUrl = 'http://1.2.3.4'; // GoRouter configuration final _router = GoRouter( @@ -40,10 +43,6 @@ final _router = GoRouter( path: '/transfer', builder: (context, state) => const Transfer(), ), - GoRoute( - path: '/accountdetail', - builder: (context, state) => const AccountDetail(), - ), GoRoute( path: '/applycc', builder: (context, state) => const ApplyForCreditCard(), @@ -52,25 +51,19 @@ final _router = GoRouter( ); void main() async { -// Parse code + // Initialize Parse WidgetsFlutterBinding.ensureInitialized(); const keyApplicationId = 'APPLICATION_ID'; - // WebLogicOnDocker Old Install - const keyParseServerUrl = 'http://129.80.94.27/parse'; - // MaaCloud New Install Not Working Yet, Parse Server Keep crashing - // const keyParseServerUrl = 'http://129.159.115.55/parse'; + const keyParseServerUrl = '$backendUrl/parse'; var response = await Parse().initialize(keyApplicationId, keyParseServerUrl); if (!response.hasParseBeenInitialized()) { - // https://stackoverflow.com/questions/45109557/flutter-how-to-programmatically-exit-the-app exit(0); } var firstObject = ParseObject('FirstClass') - ..set('message', 'LoginApp is Connected 2'); + ..set('message', 'LoginApp is Connected 3'); await firstObject.save(); - - print('done'); -// Parse code done + // Parse code done runApp(const MyApp()); } diff --git a/cloudbank-v2/flutter-app/lib/screens/accountdetail.dart b/cloudbank-v2/flutter-app/lib/screens/accountdetail.dart index 3dee87ddf..712b3f9d9 100755 --- a/cloudbank-v2/flutter-app/lib/screens/accountdetail.dart +++ b/cloudbank-v2/flutter-app/lib/screens/accountdetail.dart @@ -1,38 +1,225 @@ +// Copyright (c) 2023, Oracle and/or its affiliates. +// Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl/ + import 'package:flutter/material.dart'; import 'package:go_router/go_router.dart'; +import 'package:loginapp/components/accountdetailarguments.dart'; import '../components/credentials.dart'; import 'home.dart'; +import 'package:http/http.dart' as http; +import 'package:intl/intl.dart'; +import 'dart:convert'; + +final formatCurrency = new NumberFormat.simpleCurrency(); class AccountDetail extends StatefulWidget { - const AccountDetail({Key? key}) : super(key: key); + final AccountDetailArguments args; + + const AccountDetail({Key? key, required this.args}) : super(key: key); @override State createState() => _AccountDetailState(); } +class Account { + // {"accountId":2,"accountName":"Mark's CCard","accountType":"CC","accountCustomerId":"bkzLp8cozi", + //"accountOpenedDate":"2023-03-12T16:06:03.000+00:00","accountOtherDetails":"Mastercard account", + //"accountBalance":800} + final int accountId; + final String accountName; + final String accountType; + final String accountCustomerId; + final String accountOpenedDate; + final String accountOtherDetails; + final double accountBalance; + + const Account({ + required this.accountId, + required this.accountName, + required this.accountType, + required this.accountCustomerId, + required this.accountOpenedDate, + required this.accountOtherDetails, + required this.accountBalance, + }); + + factory Account.fromJson(Map json) { + return Account( + accountId: json['accountId'], + accountName: json['accountName'], + accountType: json['accountType'], + accountCustomerId: json['accountCustomerId'], + accountOpenedDate: json['accountOpenedDate'], + accountOtherDetails: json['accountOtherDetails'], + accountBalance: double.parse(json['accountBalance'].toString()), + ); + } +} + +class Transactions { + final List transactions; + + const Transactions({ + required this.transactions, + }); + + List getTransactions() { + return transactions; + } + + factory Transactions.fromJson({required transactions}) { + return Transactions( + transactions: transactions, + ); + } +} + class _AccountDetailState extends State { + late Future futureAccountData; + late Future futureTransactionData; + + @override + void initState() { + super.initState(); + futureAccountData = fetchAccountData(); + futureTransactionData = fetchTransactionData(); + } + + Future fetchAccountData() async { + String accountsUrl = + '${widget.args.creds.backendUrl}/api/v1/account/${widget.args.accountId}'; + final response = await http.get(Uri.parse(accountsUrl)); + + if (response.statusCode == 200) { + // If the server did return a 200 OK response, + // then parse the JSON. + return Account.fromJson(jsonDecode(response.body)); + } else { + // If the server did not return a 200 OK response, + // then throw an exception. + throw Exception('Failed to retrieve score'); + } + } + + Future fetchTransactionData() async { + String transcationsUrl = + '${widget.args.creds.backendUrl}/api/v1/account/${widget.args.accountId}/transactions'; + final response = await http.get(Uri.parse(transcationsUrl)); + + if (response.statusCode == 200) { + // If the server did return a 200 OK response, + // then parse the JSON. + return Transactions.fromJson(transactions: jsonDecode(response.body)); + } else { + // If the server did not return a 200 OK response, + // then throw an exception. + throw Exception('Failed to retrieve score'); + } + } + @override Widget build(BuildContext context) { - final creds = ModalRoute.of(context)!.settings.arguments as Credentials; - print(creds.username); - print(creds.email); + // final args = + // ModalRoute.of(context)!.settings.arguments as AccountDetailArguments; + print(widget.args.creds.username); + print(widget.args.creds.email); + print(widget.args.accountId); return Scaffold( - appBar: AppBar(title: const Text("Account Detail")), + appBar: AppBar(title: const Text("Your Transactions")), body: Center( child: Container( padding: const EdgeInsets.all(16), child: ListView( children: [ - const Text( - 'Account detail and transaction list goes here', - style: TextStyle( - color: Colors.black, - fontWeight: FontWeight.w800, - fontFamily: 'Roboto', - letterSpacing: 0.5, - fontSize: 20, - ), + const Text("Account Details", textScaleFactor: 1.5), + FutureBuilder( + future: futureAccountData, + builder: (context, snapshot) { + if (snapshot.hasData) { + print(snapshot.data); + return Card( + child: Column( + mainAxisSize: MainAxisSize.min, + children: [ + ListTile( + title: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Text(snapshot.data!.accountName), + Text( + formatCurrency + .format(snapshot.data!.accountBalance), + textScaleFactor: 1.5, + ), + ], + ), + subtitle: + Text("CB ACCT-${snapshot.data!.accountId}"), + ), + ], + ), + ); + } else if (snapshot.hasError) { + return Text('${snapshot.error}'); + } + // By default, show a loading spinner. + return const Text("Loading..."); + }, + ), + const SizedBox(height: 20), + const Text("Recent Transactions", textScaleFactor: 1.5), + const SizedBox(height: 20), + FutureBuilder( + future: futureTransactionData, + builder: (context, snapshot) { + // {"journalId":3, + // "journalType":"WITHDRAW", + // "accountId":2, + // "lraId":"http://otmm-tcs.otmm.svc.cluster.local:9000/api/v1/lra-coordinator/144d7ad8-653e-4540-987c-cc2fcf0643e0", + // "lraState":"Closed", + // "journalAmount":100} + if (snapshot.hasData) { + print(snapshot.data!.transactions.length); + List data = snapshot.data!.transactions; + print(data); + return ListView.builder( + scrollDirection: Axis.vertical, + shrinkWrap: true, + physics: const ClampingScrollPhysics(), + itemCount: snapshot.data!.transactions.length, + itemBuilder: (context, index) { + return Card( + child: Column( + mainAxisSize: MainAxisSize.min, + children: [ + ListTile( + leading: const Icon(Icons.attach_money), + title: Row( + mainAxisAlignment: + MainAxisAlignment.spaceBetween, + children: [ + Text(data[index]['journalType'].toString()), + Text( + formatCurrency + .format(data[index]['journalAmount']), + textScaleFactor: 1.5, + ), + ], + ), + subtitle: Text(data[index]['lraState']), + ), + ], + ), + ); + }, + ); + } else if (snapshot.hasError) { + return Text('${snapshot.error}'); + } + // By default, show a loading spinner. + return const CircularProgressIndicator(); + }, ), const SizedBox( height: 20, @@ -46,7 +233,7 @@ class _AccountDetailState extends State { // Pass the arguments as part of the RouteSettings. The // DetailScreen reads the arguments from these settings. settings: RouteSettings( - arguments: creds, + arguments: widget.args.creds, ), ), ); @@ -54,7 +241,7 @@ class _AccountDetailState extends State { //=> GoRouter.of(context).go('/home'), child: const Padding( padding: EdgeInsets.all(16), - child: Text('Go back to Home'), + child: Text('Account List'), ), ) ], diff --git a/cloudbank-v2/flutter-app/lib/screens/applycc.dart b/cloudbank-v2/flutter-app/lib/screens/applycc.dart index ae97821eb..ee3ebbace 100755 --- a/cloudbank-v2/flutter-app/lib/screens/applycc.dart +++ b/cloudbank-v2/flutter-app/lib/screens/applycc.dart @@ -1,3 +1,6 @@ +// Copyright (c) 2023, Oracle and/or its affiliates. +// Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl/ + import 'package:flutter/material.dart'; import 'package:parse_server_sdk_flutter/parse_server_sdk.dart'; import 'package:go_router/go_router.dart'; diff --git a/cloudbank-v2/flutter-app/lib/screens/deposit.dart b/cloudbank-v2/flutter-app/lib/screens/deposit.dart index e600d7c41..bfb40db86 100755 --- a/cloudbank-v2/flutter-app/lib/screens/deposit.dart +++ b/cloudbank-v2/flutter-app/lib/screens/deposit.dart @@ -1,3 +1,6 @@ +// Copyright (c) 2023, Oracle and/or its affiliates. +// Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl/ + import 'package:flutter/material.dart'; import 'package:go_router/go_router.dart'; diff --git a/cloudbank-v2/flutter-app/lib/screens/home.dart b/cloudbank-v2/flutter-app/lib/screens/home.dart index b0fef1c65..4c578dace 100755 --- a/cloudbank-v2/flutter-app/lib/screens/home.dart +++ b/cloudbank-v2/flutter-app/lib/screens/home.dart @@ -1,3 +1,6 @@ +// Copyright (c) 2023, Oracle and/or its affiliates. +// Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl/ + import 'package:flutter/material.dart'; import 'package:go_router/go_router.dart'; import 'package:loginapp/components/appbar.dart'; diff --git a/cloudbank-v2/flutter-app/lib/screens/login.dart b/cloudbank-v2/flutter-app/lib/screens/login.dart index bb3eb4a1c..f905f6a2d 100755 --- a/cloudbank-v2/flutter-app/lib/screens/login.dart +++ b/cloudbank-v2/flutter-app/lib/screens/login.dart @@ -1,3 +1,6 @@ +// Copyright (c) 2023, Oracle and/or its affiliates. +// Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl/ + import 'package:flutter/material.dart'; import 'package:loginapp/components/appbar.dart'; import 'package:loginapp/screens/home.dart'; diff --git a/cloudbank-v2/flutter-app/lib/screens/signup.dart b/cloudbank-v2/flutter-app/lib/screens/signup.dart index 452584485..dc76b43e6 100755 --- a/cloudbank-v2/flutter-app/lib/screens/signup.dart +++ b/cloudbank-v2/flutter-app/lib/screens/signup.dart @@ -1,3 +1,6 @@ +// Copyright (c) 2023, Oracle and/or its affiliates. +// Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl/ + import 'package:flutter/material.dart'; import 'package:loginapp/screens/home.dart'; import 'package:parse_server_sdk_flutter/parse_server_sdk.dart'; diff --git a/cloudbank-v2/flutter-app/lib/screens/transfer.dart b/cloudbank-v2/flutter-app/lib/screens/transfer.dart index dd5c8c804..cc47071db 100755 --- a/cloudbank-v2/flutter-app/lib/screens/transfer.dart +++ b/cloudbank-v2/flutter-app/lib/screens/transfer.dart @@ -1,3 +1,6 @@ +// Copyright (c) 2023, Oracle and/or its affiliates. +// Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl/ + import 'package:flutter/material.dart'; import 'package:go_router/go_router.dart'; diff --git a/cloudbank-v2/spring-apps/customer/src/main/resources/application.yaml b/cloudbank-v2/spring-apps/customer/src/main/resources/application.yaml index ebd88de57..29a8abd5a 100644 --- a/cloudbank-v2/spring-apps/customer/src/main/resources/application.yaml +++ b/cloudbank-v2/spring-apps/customer/src/main/resources/application.yaml @@ -18,9 +18,9 @@ spring: show-sql: true liquibase: change-log: classpath:db/changelog/controller.yaml - url: ${CONNECT_STRING} - user: ${DB_USERNAME} - password: ${DB_PASSWORD} + url: ${spring.datasource.url} + user: ${spring.datasource.username} + password: ${spring.datasource.password} enabled: ${LIQUIBASE_ENABLED:true} datasource: