v2.1.0 update for RazorPay, FreeShipping minimum value, new grid

This commit is contained in:
WooSignal 2020-07-22 22:54:12 +01:00
parent 09050b342d
commit 4269c5b7e0
18 changed files with 196 additions and 75 deletions

View File

@ -1,3 +1,9 @@
## [2.1.0] - 2020-07-22
* Pubspec.yaml update for RazorPay
* FreeShipping minimum value feature
* New grid collection layout
## [2.0.9] - 2020-06-19 ## [2.0.9] - 2020-06-19
* New UI for home products * New UI for home products

View File

@ -169,5 +169,7 @@
"That email is taken, try another": "Diese E-Mail wird genommen, versuchen Sie es mit einer anderen", "That email is taken, try another": "Diese E-Mail wird genommen, versuchen Sie es mit einer anderen",
"The email field is empty": "Das E-Mail-Feld ist leer", "The email field is empty": "Das E-Mail-Feld ist leer",
"No more orders": "Keine Bestellungen mehr", "No more orders": "Keine Bestellungen mehr",
"Account updated": "Konto aktualisiert" "Account updated": "Konto aktualisiert",
"Spend a minimum of": "Geben Sie mindestens ein",
"for": "zum"
} }

View File

@ -169,5 +169,7 @@
"That email is taken, try another": "That email is taken, try another", "That email is taken, try another": "That email is taken, try another",
"The email field is empty": "The email field is empty", "The email field is empty": "The email field is empty",
"No more orders": "No more orders", "No more orders": "No more orders",
"Account updated": "Account updated" "Account updated": "Account updated",
"Spend a minimum of": "Spend a minimum of",
"for": "for"
} }

View File

@ -169,5 +169,7 @@
"That email is taken, try another": "Ese correo electrónico está tomado, prueba con otro", "That email is taken, try another": "Ese correo electrónico está tomado, prueba con otro",
"The email field is empty": "El campo de correo electrónico está vacío.", "The email field is empty": "El campo de correo electrónico está vacío.",
"No more orders": "No mas pedidos", "No more orders": "No mas pedidos",
"Account updated": "Cuenta actualizada" "Account updated": "Cuenta actualizada",
"Spend a minimum of": "Gasta un mínimo de",
"for": "para"
} }

View File

@ -169,5 +169,7 @@
"That email is taken, try another": "Cet e-mail est pris, essayez un autre", "That email is taken, try another": "Cet e-mail est pris, essayez un autre",
"The email field is empty": "Le champ e-mail est vide", "The email field is empty": "Le champ e-mail est vide",
"No more orders": "Plus de commandes", "No more orders": "Plus de commandes",
"Account updated": "Compte mis à jour" "Account updated": "Compte mis à jour",
"Spend a minimum of": "Dépensez un minimum de",
"for": "pour"
} }

View File

@ -169,5 +169,7 @@
"That email is taken, try another": "vah eemel liya gaya hai, doosara prayaas karen", "That email is taken, try another": "vah eemel liya gaya hai, doosara prayaas karen",
"The email field is empty": "eemel feeld khaalee hai", "The email field is empty": "eemel feeld khaalee hai",
"No more orders": "aur koee aadesh nahin", "No more orders": "aur koee aadesh nahin",
"Account updated": "khaata apadet kiya gaya" "Account updated": "khaata apadet kiya gaya",
"Spend a minimum of": "kam se kam kharch karen",
"for": "ke liye"
} }

View File

@ -169,5 +169,7 @@
"That email is taken, try another": "Quell'e-mail è stata presa, provane un'altra", "That email is taken, try another": "Quell'e-mail è stata presa, provane un'altra",
"The email field is empty": "Il campo email è vuoto", "The email field is empty": "Il campo email è vuoto",
"No more orders": "Niente più ordini", "No more orders": "Niente più ordini",
"Account updated": "Account aggiornato" "Account updated": "Account aggiornato",
"Spend a minimum of": "Spendi un minimo di",
"for": "per"
} }

View File

@ -169,5 +169,7 @@
"That email is taken, try another": "Esse e-mail foi recebido, tente outro", "That email is taken, try another": "Esse e-mail foi recebido, tente outro",
"The email field is empty": "O campo de email está vazio", "The email field is empty": "O campo de email está vazio",
"No more orders": "Não há mais pedidos", "No more orders": "Não há mais pedidos",
"Account updated": "Conta atualizada" "Account updated": "Conta atualizada",
"Spend a minimum of": "Gaste um mínimo de",
"for": "para"
} }

View File

@ -11,6 +11,7 @@
import 'dart:developer'; import 'dart:developer';
import 'package:flutter/cupertino.dart'; import 'package:flutter/cupertino.dart';
import 'package:flutter_staggered_grid_view/flutter_staggered_grid_view.dart';
import 'package:intl/intl.dart'; import 'package:intl/intl.dart';
import 'package:label_storemax/app_payment_methods.dart'; import 'package:label_storemax/app_payment_methods.dart';
import 'package:label_storemax/helpers/app_localizations.dart'; import 'package:label_storemax/helpers/app_localizations.dart';
@ -78,7 +79,12 @@ class EdgeAlertStyle {
} }
void showEdgeAlertWith(context, void showEdgeAlertWith(context,
{title = "", desc = "", int gravity = 1, int style = 1, IconData icon}) { {title = "",
desc = "",
int gravity = 1,
int style = 1,
IconData icon,
int duration}) {
switch (style) { switch (style) {
case 1: // SUCCESS case 1: // SUCCESS
EdgeAlert.show(context, EdgeAlert.show(context,
@ -87,7 +93,7 @@ void showEdgeAlertWith(context,
gravity: gravity, gravity: gravity,
backgroundColor: Colors.green, backgroundColor: Colors.green,
icon: icon ?? Icons.check, icon: icon ?? Icons.check,
duration: EdgeAlert.LENGTH_LONG); duration: duration ?? EdgeAlert.LENGTH_LONG);
break; break;
case 2: // WARNING case 2: // WARNING
EdgeAlert.show(context, EdgeAlert.show(context,
@ -96,7 +102,7 @@ void showEdgeAlertWith(context,
gravity: gravity, gravity: gravity,
backgroundColor: Colors.orange, backgroundColor: Colors.orange,
icon: icon ?? Icons.error_outline, icon: icon ?? Icons.error_outline,
duration: EdgeAlert.LENGTH_LONG); duration: duration ?? EdgeAlert.LENGTH_LONG);
break; break;
case 3: // INFO case 3: // INFO
EdgeAlert.show(context, EdgeAlert.show(context,
@ -105,7 +111,7 @@ void showEdgeAlertWith(context,
gravity: gravity, gravity: gravity,
backgroundColor: Colors.teal, backgroundColor: Colors.teal,
icon: icon ?? Icons.info, icon: icon ?? Icons.info,
duration: EdgeAlert.LENGTH_LONG); duration: duration ?? EdgeAlert.LENGTH_LONG);
break; break;
case 4: // DANGER case 4: // DANGER
EdgeAlert.show(context, EdgeAlert.show(context,
@ -114,7 +120,7 @@ void showEdgeAlertWith(context,
gravity: gravity, gravity: gravity,
backgroundColor: Colors.redAccent, backgroundColor: Colors.redAccent,
icon: icon ?? Icons.warning, icon: icon ?? Icons.warning,
duration: EdgeAlert.LENGTH_LONG); duration: duration ?? EdgeAlert.LENGTH_LONG);
break; break;
default: default:
break; break;
@ -509,14 +515,24 @@ Widget refreshableScroll(context,
onRefresh: onRefresh, onRefresh: onRefresh,
onLoading: onLoading, onLoading: onLoading,
child: (products.length != null && products.length > 0 child: (products.length != null && products.length > 0
? GridView.count( ? StaggeredGridView.countBuilder(
crossAxisCount: 2, crossAxisCount: 2,
shrinkWrap: true, itemCount: products.length,
children: List.generate( itemBuilder: (BuildContext context, int index) {
products.length, return Container(
(index) => wsCardProductItem(context, height: 200,
index: index, product: products[index], onTap: onTap), child: wsCardProductItem(
)) context,
index: (index),
product: products[index],
onTap: onTap,
),
);
},
staggeredTileBuilder: (int index) => new StaggeredTile.fit(1),
mainAxisSpacing: 4.0,
crossAxisSpacing: 4.0,
)
: wsNoResults(context)), : wsNoResults(context)),
); );
} }

View File

@ -16,7 +16,7 @@ import 'dart:ui';
Developer Notes Developer Notes
SUPPORT EMAIL - support@woosignal.com SUPPORT EMAIL - support@woosignal.com
VERSION - 2.0.9 VERSION - 2.1.0
https://woosignal.com https://woosignal.com
*/ */

View File

@ -15,12 +15,17 @@ import '../helpers/tools.dart';
class ShippingType { class ShippingType {
String methodId; String methodId;
String cost; String cost;
String minimumValue;
dynamic object; dynamic object;
ShippingType({this.methodId, this.object, this.cost}); ShippingType({this.methodId, this.object, this.cost, this.minimumValue});
Map<String, dynamic> toJson() => Map<String, dynamic> toJson() => {
{'methodId': methodId, 'object': object, 'cost': cost}; 'methodId': methodId,
'object': object,
'cost': cost,
'minimumValue': minimumValue
};
String getTotal({bool withFormatting}) { String getTotal({bool withFormatting}) {
if (this.methodId != null && this.object != null) { if (this.methodId != null && this.object != null) {

View File

@ -12,6 +12,7 @@ import 'package:flutter/material.dart';
import 'package:label_storemax/app_payment_methods.dart'; import 'package:label_storemax/app_payment_methods.dart';
import 'package:label_storemax/app_state_options.dart'; import 'package:label_storemax/app_state_options.dart';
import 'package:label_storemax/helpers/tools.dart'; import 'package:label_storemax/helpers/tools.dart';
import 'package:label_storemax/models/cart.dart';
import 'package:label_storemax/models/checkout_session.dart'; import 'package:label_storemax/models/checkout_session.dart';
import 'package:label_storemax/models/customer_address.dart'; import 'package:label_storemax/models/customer_address.dart';
import 'package:label_storemax/widgets/app_loader.dart'; import 'package:label_storemax/widgets/app_loader.dart';
@ -376,6 +377,29 @@ class CheckoutConfirmationPageState extends State<CheckoutConfirmationPage> {
return; return;
} }
if (CheckoutSession.getInstance.shippingType.minimumValue != null) {
String total = await Cart.getInstance.getTotal();
if (total == null) {
return;
}
double doubleTotal = double.parse(total);
double doubleMinimumValue =
double.parse(CheckoutSession.getInstance.shippingType.minimumValue);
if (doubleTotal < doubleMinimumValue) {
showEdgeAlertWith(context,
title: trans(context, "Sorry"),
desc: trans(context, "Spend a minimum of") +
" " +
formatDoubleCurrency(total: doubleMinimumValue) +
" ${trans(context, "for")} " +
CheckoutSession.getInstance.shippingType.getTitle(),
style: EdgeAlertStyle.INFO,
duration: 3);
return;
}
}
if (_isProcessingPayment == true) { if (_isProcessingPayment == true) {
return; return;
} }

View File

@ -119,13 +119,15 @@ class _CheckoutShippingTypePageState extends State<CheckoutShippingTypePage> {
.where((t) => t != null) .where((t) => t != null)
.toList() .toList()
.forEach((freeShipping) { .forEach((freeShipping) {
if (isNumeric(freeShipping.cost)) { if (isNumeric(freeShipping.cost) ||
freeShipping.cost == 'min_amount') {
Map<String, dynamic> tmpShippingOption = {}; Map<String, dynamic> tmpShippingOption = {};
tmpShippingOption = { tmpShippingOption = {
"id": freeShipping.id, "id": freeShipping.id,
"method_id": "free_shipping", "method_id": "free_shipping",
"title": freeShipping.title, "title": freeShipping.title,
"cost": freeShipping.cost, "cost": "0.00",
"min_amount": freeShipping.minimumOrderAmount,
"object": freeShipping "object": freeShipping
}; };
_wsShippingOptions.add(tmpShippingOption); _wsShippingOptions.add(tmpShippingOption);
@ -246,11 +248,11 @@ class _CheckoutShippingTypePageState extends State<CheckoutShippingTypePage> {
contentPadding: EdgeInsets.only( contentPadding: EdgeInsets.only(
left: 16, right: 16), left: 16, right: 16),
title: Text( title: Text(
_wsShippingOptions[index] _wsShippingOptions[index]['title'],
['title'], style: Theme.of(context)
style: Theme.of(context) .primaryTextTheme
.primaryTextTheme .subtitle1,
.subtitle1), ),
selected: true, selected: true,
subtitle: FutureBuilder<String>( subtitle: FutureBuilder<String>(
future: _getShippingPrice(index), future: _getShippingPrice(index),
@ -267,14 +269,52 @@ class _CheckoutShippingTypePageState extends State<CheckoutShippingTypePage> {
case ConnectionState.done: case ConnectionState.done:
if (snapshot.hasError) if (snapshot.hasError)
return Text(''); return Text('');
return Text( return RichText(
trans(context, "Price") + text: TextSpan(
": " + text: '',
formatStringCurrency( style: DefaultTextStyle.of(
total: snapshot context)
.data)); .style,
children: <TextSpan>[
(_wsShippingOptions[index]
["object"]
is FreeShipping
? TextSpan(
text:
"Free postage")
: TextSpan(
text: trans(
context,
"Price") +
": " +
formatStringCurrency(
total: snapshot
.data),
)),
_wsShippingOptions[index][
"min_amount"] !=
null
? TextSpan(
text: "\nSpend a minimum of " +
formatStringCurrency(
total: _wsShippingOptions[
index]
[
"min_amount"]),
style: Theme.of(
context)
.primaryTextTheme
.bodyText2
.copyWith(
fontSize:
14))
: null,
]
.where((e) => e != null)
.toList(),
));
} }
return null; // unreachable return null;
}, },
), ),
trailing: (CheckoutSession.getInstance trailing: (CheckoutSession.getInstance
@ -288,23 +328,8 @@ class _CheckoutShippingTypePageState extends State<CheckoutShippingTypePage> {
["object"] ["object"]
? Icon(Icons.check) ? Icon(Icons.check)
: null), : null),
onTap: () async { onTap: () =>
ShippingType shippingType = _handleCheckoutTapped(index),
ShippingType();
shippingType.object =
_wsShippingOptions[index]
['object'];
shippingType.methodId =
_wsShippingOptions[index]
['method_id'];
shippingType.cost =
await _getShippingPrice(index);
CheckoutSession.getInstance
.shippingType = shippingType;
Navigator.pop(context);
},
); );
}, },
), ),
@ -339,4 +364,18 @@ class _CheckoutShippingTypePageState extends State<CheckoutShippingTypePage> {
), ),
); );
} }
_handleCheckoutTapped(int index) async {
ShippingType shippingType = ShippingType();
shippingType.object = _wsShippingOptions[index]['object'];
shippingType.methodId = _wsShippingOptions[index]['method_id'];
if (_wsShippingOptions[index]['min_amount'] != null) {
shippingType.minimumValue = _wsShippingOptions[index]['min_amount'];
}
shippingType.cost = await _getShippingPrice(index);
CheckoutSession.getInstance.shippingType = shippingType;
Navigator.pop(context);
}
} }

View File

@ -59,7 +59,8 @@ class _HomePageState extends State<HomePage> {
} }
_fetchCategories() async { _fetchCategories() async {
_categories = await appWooSignal((api) => api.getProductCategories()); _categories =
await appWooSignal((api) => api.getProductCategories(page: 100));
} }
_fetchMoreProducts() async { _fetchMoreProducts() async {
@ -133,6 +134,7 @@ class _HomePageState extends State<HomePage> {
wsCartIcon(context, key: _key), wsCartIcon(context, key: _key),
], ],
), ),
backgroundColor: Colors.white,
body: SafeArea( body: SafeArea(
minimum: safeAreaDefault(), minimum: safeAreaDefault(),
child: Column( child: Column(

View File

@ -220,6 +220,11 @@ Widget wsCardProductItem(BuildContext context,
borderRadius: BorderRadius.circular(3.0), borderRadius: BorderRadius.circular(3.0),
child: Stack( child: Stack(
children: [ children: [
Container(
color: Colors.grey[100],
height: double.infinity,
width: double.infinity,
),
CachedNetworkImage( CachedNetworkImage(
imageUrl: (product.images.length > 0 imageUrl: (product.images.length > 0
? product.images.first.src ? product.images.first.src
@ -237,11 +242,11 @@ Widget wsCardProductItem(BuildContext context,
), ),
(product.onSale && product.type != "variable" (product.onSale && product.type != "variable"
? Positioned( ? Positioned(
bottom: 5, bottom: 0,
left: 8, left: 0,
right: 8, right: 0,
child: Container( child: Container(
padding: EdgeInsets.all(2), padding: EdgeInsets.all(3),
decoration: BoxDecoration( decoration: BoxDecoration(
color: Colors.white70, color: Colors.white70,
borderRadius: BorderRadius.circular(4), borderRadius: BorderRadius.circular(4),
@ -273,7 +278,7 @@ Widget wsCardProductItem(BuildContext context,
), ),
), ),
Container( Container(
margin: const EdgeInsets.only(top: 8, bottom: 8), margin: const EdgeInsets.only(top: 2, bottom: 2),
child: Text( child: Text(
product.name, product.name,
style: Theme.of(context).textTheme.bodyText2, style: Theme.of(context).textTheme.bodyText2,

View File

@ -127,6 +127,13 @@ packages:
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "0.1.4" version: "0.1.4"
fake_async:
dependency: transitive
description:
name: fake_async
url: "https://pub.dartlang.org"
source: hosted
version: "1.1.0"
file: file:
dependency: transitive dependency: transitive
description: description:
@ -193,6 +200,13 @@ packages:
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "4.1.2+1" version: "4.1.2+1"
flutter_staggered_grid_view:
dependency: "direct main"
description:
name: flutter_staggered_grid_view
url: "https://pub.dartlang.org"
source: hosted
version: "0.3.1"
flutter_swiper: flutter_swiper:
dependency: "direct main" dependency: "direct main"
description: description:
@ -293,7 +307,7 @@ packages:
name: path name: path
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "1.6.4" version: "1.7.0"
path_provider: path_provider:
dependency: transitive dependency: transitive
description: description:
@ -385,20 +399,13 @@ packages:
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "1.5.8" version: "1.5.8"
quiver:
dependency: transitive
description:
name: quiver
url: "https://pub.dartlang.org"
source: hosted
version: "2.1.3"
razorpay_flutter: razorpay_flutter:
dependency: "direct main" dependency: "direct main"
description: description:
name: razorpay_flutter name: razorpay_flutter
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "1.2.1" version: "1.2.2"
rxdart: rxdart:
dependency: transitive dependency: transitive
description: description:
@ -508,7 +515,7 @@ packages:
name: test_api name: test_api
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "0.2.15" version: "0.2.16"
transformer_page_view: transformer_page_view:
dependency: transitive dependency: transitive
description: description:
@ -571,7 +578,7 @@ packages:
name: woosignal name: woosignal
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "1.1.0" version: "1.1.2"
woosignal_stripe: woosignal_stripe:
dependency: "direct main" dependency: "direct main"
description: description:

View File

@ -1,5 +1,5 @@
# Label StoreMax # Label StoreMax
# Version 2.0.9 # Version 2.1.0
#authors: - "Anthony Gordon" #authors: - "Anthony Gordon"
#documentation: https://woosignal.com/docs/app/ios/label-storemax #documentation: https://woosignal.com/docs/app/ios/label-storemax
#homepage: https://woosignal.com/ #homepage: https://woosignal.com/
@ -24,9 +24,9 @@ environment:
sdk: ">=2.1.0 <3.0.0" sdk: ">=2.1.0 <3.0.0"
dependencies: dependencies:
woosignal: ^1.1.0 woosignal: ^1.1.2
woosignal_stripe: ^0.0.6 woosignal_stripe: ^0.0.6
razorpay_flutter: ^1.2.1 razorpay_flutter: ^1.2.2
wp_json_api: ^0.1.4 wp_json_api: ^0.1.4
shared_preferences: ^0.5.7+3 shared_preferences: ^0.5.7+3
cached_network_image: ^2.2.0+1 cached_network_image: ^2.2.0+1
@ -47,6 +47,7 @@ dependencies:
flutter_launcher_icons: ^0.7.5 flutter_launcher_icons: ^0.7.5
auto_size_text: ^2.1.0 auto_size_text: ^2.1.0
html: ^0.14.0+3 html: ^0.14.0+3
flutter_staggered_grid_view: ^0.3.1
flutter: flutter:
sdk: flutter sdk: flutter

View File

@ -3,7 +3,9 @@
</p> </p>
# WooCommerce App: Label StoreMax # WooCommerce App: Label StoreMax
### Label StoreMax - v2.0.9
### Label StoreMax - v2.1.0
[Official WooSignal WooCommerce App](https://woosignal.com) [Official WooSignal WooCommerce App](https://woosignal.com)