Changes and tweaks
This commit is contained in:
parent
b578ac63d4
commit
b3eef2047d
1
LabelStoreMax/.flutter-plugins-dependencies
Normal file
1
LabelStoreMax/.flutter-plugins-dependencies
Normal file
@ -0,0 +1 @@
|
||||
{"_info":"// This is a generated file; do not edit or check into version control.","dependencyGraph":[{"name":"device_info","dependencies":[]},{"name":"flutter_money_formatter","dependencies":[]},{"name":"flutter_web_browser","dependencies":[]},{"name":"fluttertoast","dependencies":[]},{"name":"package_info","dependencies":[]},{"name":"path_provider","dependencies":[]},{"name":"shared_preferences","dependencies":["shared_preferences_macos","shared_preferences_web"]},{"name":"shared_preferences_macos","dependencies":[]},{"name":"shared_preferences_web","dependencies":[]},{"name":"sqflite","dependencies":[]},{"name":"woosignal_stripe","dependencies":[]}]}
|
||||
@ -25,6 +25,12 @@ apply plugin: 'com.android.application'
|
||||
apply plugin: 'kotlin-android'
|
||||
apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle"
|
||||
|
||||
def keystoreProperties = new Properties()
|
||||
def keystorePropertiesFile = rootProject.file('key.properties')
|
||||
if (keystorePropertiesFile.exists()) {
|
||||
keystoreProperties.load(new FileInputStream(keystorePropertiesFile))
|
||||
}
|
||||
|
||||
android {
|
||||
compileSdkVersion 28
|
||||
|
||||
@ -37,7 +43,6 @@ android {
|
||||
}
|
||||
|
||||
defaultConfig {
|
||||
// TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html).
|
||||
applicationId "com.woosignal.label_storemax"
|
||||
minSdkVersion 28
|
||||
targetSdkVersion 28
|
||||
@ -47,13 +52,20 @@ android {
|
||||
multiDexEnabled = true
|
||||
}
|
||||
|
||||
buildTypes {
|
||||
signingConfigs {
|
||||
release {
|
||||
// TODO: Add your own signing config for the release build.
|
||||
// Signing with the debug keys for now, so `flutter run --release` works.
|
||||
signingConfig signingConfigs.debug
|
||||
keyAlias keystoreProperties['keyAlias']
|
||||
keyPassword keystoreProperties['keyPassword']
|
||||
storeFile keystoreProperties['storeFile'] ? file(keystoreProperties['storeFile']) : null
|
||||
storePassword keystoreProperties['storePassword']
|
||||
}
|
||||
}
|
||||
buildTypes {
|
||||
release {
|
||||
signingConfig signingConfigs.release
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
flutter {
|
||||
|
||||
4
LabelStoreMax/android/key.properties
Normal file
4
LabelStoreMax/android/key.properties
Normal file
@ -0,0 +1,4 @@
|
||||
storePassword=<password>
|
||||
keyPassword=<password>
|
||||
keyAlias=key
|
||||
storeFile=<location of the key store file, e.g. /Users/<user name>/key.jks>
|
||||
18
LabelStoreMax/ios/Flutter/Flutter.podspec
Normal file
18
LabelStoreMax/ios/Flutter/Flutter.podspec
Normal file
@ -0,0 +1,18 @@
|
||||
#
|
||||
# NOTE: This podspec is NOT to be published. It is only used as a local source!
|
||||
#
|
||||
|
||||
Pod::Spec.new do |s|
|
||||
s.name = 'Flutter'
|
||||
s.version = '1.0.0'
|
||||
s.summary = 'High-performance, high-fidelity mobile apps.'
|
||||
s.description = <<-DESC
|
||||
Flutter provides an easy and productive way to build and deploy high-performance mobile apps for Android and iOS.
|
||||
DESC
|
||||
s.homepage = 'https://flutter.io'
|
||||
s.license = { :type => 'MIT' }
|
||||
s.author = { 'Flutter Dev Team' => 'flutter-dev@googlegroups.com' }
|
||||
s.source = { :git => 'https://github.com/flutter/engine', :tag => s.version.to_s }
|
||||
s.ios.deployment_target = '8.0'
|
||||
s.vendored_frameworks = 'Flutter.framework'
|
||||
end
|
||||
90
LabelStoreMax/ios/Podfile
Normal file
90
LabelStoreMax/ios/Podfile
Normal file
@ -0,0 +1,90 @@
|
||||
# Uncomment this line to define a global platform for your project
|
||||
# platform :ios, '9.0'
|
||||
|
||||
# CocoaPods analytics sends network stats synchronously affecting flutter build latency.
|
||||
ENV['COCOAPODS_DISABLE_STATS'] = 'true'
|
||||
|
||||
project 'Runner', {
|
||||
'Debug' => :debug,
|
||||
'Profile' => :release,
|
||||
'Release' => :release,
|
||||
}
|
||||
|
||||
def parse_KV_file(file, separator='=')
|
||||
file_abs_path = File.expand_path(file)
|
||||
if !File.exists? file_abs_path
|
||||
return [];
|
||||
end
|
||||
generated_key_values = {}
|
||||
skip_line_start_symbols = ["#", "/"]
|
||||
File.foreach(file_abs_path) do |line|
|
||||
next if skip_line_start_symbols.any? { |symbol| line =~ /^\s*#{symbol}/ }
|
||||
plugin = line.split(pattern=separator)
|
||||
if plugin.length == 2
|
||||
podname = plugin[0].strip()
|
||||
path = plugin[1].strip()
|
||||
podpath = File.expand_path("#{path}", file_abs_path)
|
||||
generated_key_values[podname] = podpath
|
||||
else
|
||||
puts "Invalid plugin specification: #{line}"
|
||||
end
|
||||
end
|
||||
generated_key_values
|
||||
end
|
||||
|
||||
target 'Runner' do
|
||||
use_frameworks!
|
||||
use_modular_headers!
|
||||
|
||||
# Flutter Pod
|
||||
|
||||
copied_flutter_dir = File.join(__dir__, 'Flutter')
|
||||
copied_framework_path = File.join(copied_flutter_dir, 'Flutter.framework')
|
||||
copied_podspec_path = File.join(copied_flutter_dir, 'Flutter.podspec')
|
||||
unless File.exist?(copied_framework_path) && File.exist?(copied_podspec_path)
|
||||
# Copy Flutter.framework and Flutter.podspec to Flutter/ to have something to link against if the xcode backend script has not run yet.
|
||||
# That script will copy the correct debug/profile/release version of the framework based on the currently selected Xcode configuration.
|
||||
# CocoaPods will not embed the framework on pod install (before any build phases can generate) if the dylib does not exist.
|
||||
|
||||
generated_xcode_build_settings_path = File.join(copied_flutter_dir, 'Generated.xcconfig')
|
||||
unless File.exist?(generated_xcode_build_settings_path)
|
||||
raise "Generated.xcconfig must exist. If you're running pod install manually, make sure flutter pub get is executed first"
|
||||
end
|
||||
generated_xcode_build_settings = parse_KV_file(generated_xcode_build_settings_path)
|
||||
cached_framework_dir = generated_xcode_build_settings['FLUTTER_FRAMEWORK_DIR'];
|
||||
|
||||
unless File.exist?(copied_framework_path)
|
||||
FileUtils.cp_r(File.join(cached_framework_dir, 'Flutter.framework'), copied_flutter_dir)
|
||||
end
|
||||
unless File.exist?(copied_podspec_path)
|
||||
FileUtils.cp(File.join(cached_framework_dir, 'Flutter.podspec'), copied_flutter_dir)
|
||||
end
|
||||
end
|
||||
|
||||
# Keep pod path relative so it can be checked into Podfile.lock.
|
||||
pod 'Flutter', :path => 'Flutter'
|
||||
|
||||
# Plugin Pods
|
||||
|
||||
# Prepare symlinks folder. We use symlinks to avoid having Podfile.lock
|
||||
# referring to absolute paths on developers' machines.
|
||||
system('rm -rf .symlinks')
|
||||
system('mkdir -p .symlinks/plugins')
|
||||
plugin_pods = parse_KV_file('../.flutter-plugins')
|
||||
plugin_pods.each do |name, path|
|
||||
symlink = File.join('.symlinks', 'plugins', name)
|
||||
File.symlink(path, symlink)
|
||||
pod name, :path => File.join(symlink, 'ios')
|
||||
end
|
||||
end
|
||||
|
||||
# Prevent Cocoapods from embedding a second Flutter framework and causing an error with the new Xcode build system.
|
||||
install! 'cocoapods', :disable_input_output_paths => true
|
||||
|
||||
post_install do |installer|
|
||||
installer.pods_project.targets.each do |target|
|
||||
target.build_configurations.each do |config|
|
||||
config.build_settings['ENABLE_BITCODE'] = 'NO'
|
||||
end
|
||||
end
|
||||
end
|
||||
95
LabelStoreMax/ios/Podfile.lock
Normal file
95
LabelStoreMax/ios/Podfile.lock
Normal file
@ -0,0 +1,95 @@
|
||||
PODS:
|
||||
- device_info (0.0.1):
|
||||
- Flutter
|
||||
- Flutter (1.0.0)
|
||||
- flutter_money_formatter (0.0.1):
|
||||
- Flutter
|
||||
- flutter_web_browser (0.11.0):
|
||||
- Flutter
|
||||
- fluttertoast (0.0.2):
|
||||
- Flutter
|
||||
- FMDB (2.7.5):
|
||||
- FMDB/standard (= 2.7.5)
|
||||
- FMDB/standard (2.7.5)
|
||||
- package_info (0.0.1):
|
||||
- Flutter
|
||||
- path_provider (0.0.1):
|
||||
- Flutter
|
||||
- shared_preferences (0.0.1):
|
||||
- Flutter
|
||||
- shared_preferences_macos (0.0.1):
|
||||
- Flutter
|
||||
- shared_preferences_web (0.0.1):
|
||||
- Flutter
|
||||
- sqflite (0.0.1):
|
||||
- Flutter
|
||||
- FMDB (~> 2.7.2)
|
||||
- Stripe (19.0.1)
|
||||
- woosignal_stripe (0.0.4):
|
||||
- Flutter
|
||||
- Stripe (= 19.0.1)
|
||||
|
||||
DEPENDENCIES:
|
||||
- device_info (from `.symlinks/plugins/device_info/ios`)
|
||||
- Flutter (from `Flutter`)
|
||||
- flutter_money_formatter (from `.symlinks/plugins/flutter_money_formatter/ios`)
|
||||
- flutter_web_browser (from `.symlinks/plugins/flutter_web_browser/ios`)
|
||||
- fluttertoast (from `.symlinks/plugins/fluttertoast/ios`)
|
||||
- package_info (from `.symlinks/plugins/package_info/ios`)
|
||||
- path_provider (from `.symlinks/plugins/path_provider/ios`)
|
||||
- shared_preferences (from `.symlinks/plugins/shared_preferences/ios`)
|
||||
- shared_preferences_macos (from `.symlinks/plugins/shared_preferences_macos/ios`)
|
||||
- shared_preferences_web (from `.symlinks/plugins/shared_preferences_web/ios`)
|
||||
- sqflite (from `.symlinks/plugins/sqflite/ios`)
|
||||
- woosignal_stripe (from `.symlinks/plugins/woosignal_stripe/ios`)
|
||||
|
||||
SPEC REPOS:
|
||||
trunk:
|
||||
- FMDB
|
||||
- Stripe
|
||||
|
||||
EXTERNAL SOURCES:
|
||||
device_info:
|
||||
:path: ".symlinks/plugins/device_info/ios"
|
||||
Flutter:
|
||||
:path: Flutter
|
||||
flutter_money_formatter:
|
||||
:path: ".symlinks/plugins/flutter_money_formatter/ios"
|
||||
flutter_web_browser:
|
||||
:path: ".symlinks/plugins/flutter_web_browser/ios"
|
||||
fluttertoast:
|
||||
:path: ".symlinks/plugins/fluttertoast/ios"
|
||||
package_info:
|
||||
:path: ".symlinks/plugins/package_info/ios"
|
||||
path_provider:
|
||||
:path: ".symlinks/plugins/path_provider/ios"
|
||||
shared_preferences:
|
||||
:path: ".symlinks/plugins/shared_preferences/ios"
|
||||
shared_preferences_macos:
|
||||
:path: ".symlinks/plugins/shared_preferences_macos/ios"
|
||||
shared_preferences_web:
|
||||
:path: ".symlinks/plugins/shared_preferences_web/ios"
|
||||
sqflite:
|
||||
:path: ".symlinks/plugins/sqflite/ios"
|
||||
woosignal_stripe:
|
||||
:path: ".symlinks/plugins/woosignal_stripe/ios"
|
||||
|
||||
SPEC CHECKSUMS:
|
||||
device_info: cbf09d2ec12aa7110e0b09fabe54b5bd6c8efe74
|
||||
Flutter: 0e3d915762c693b495b44d77113d4970485de6ec
|
||||
flutter_money_formatter: d0d18ddc5be333fad8d09964d741b59fa11a91dc
|
||||
flutter_web_browser: bdea232160dec44dec86540bee05168cc844ef7c
|
||||
fluttertoast: b644586ef3b16f67fae9a1f8754cef6b2d6b634b
|
||||
FMDB: 2ce00b547f966261cd18927a3ddb07cb6f3db82a
|
||||
package_info: 48b108e75b8802c2d5e126f208ef540561c98aef
|
||||
path_provider: f96fff6166a8867510d2c25fdcc346327cc4b259
|
||||
shared_preferences: 430726339841afefe5142b9c1f50cb6bd7793e01
|
||||
shared_preferences_macos: f3f29b71ccbb56bf40c9dd6396c9acf15e214087
|
||||
shared_preferences_web: 141cce0c3ed1a1c5bf2a0e44f52d31eeb66e5ea9
|
||||
sqflite: ff1d9da63c06588cc8d1faf7256d741f16989d5a
|
||||
Stripe: 03313f9520a0786e2c00d9a7a2672c11e08821af
|
||||
woosignal_stripe: 55c9a08f483aae42ca1c9769f5c474802b865f17
|
||||
|
||||
PODFILE CHECKSUM: 1b66dae606f75376c5f2135a8290850eeb09ae83
|
||||
|
||||
COCOAPODS: 1.9.1
|
||||
@ -90,5 +90,7 @@
|
||||
"About Us": "About Us",
|
||||
"Something went wrong": "Something went wrong",
|
||||
"Product variation does not exist": "Product variation does not exist",
|
||||
"This variation is unavailable": "This variation is unavailable"
|
||||
"This variation is unavailable": "This variation is unavailable",
|
||||
"Sorry, something went wrong": "Sorry, something went wrong",
|
||||
"Back": "Back"
|
||||
}
|
||||
@ -1,7 +1,7 @@
|
||||
// Label StoreMAX
|
||||
//
|
||||
// Created by Anthony Gordon.
|
||||
// Copyright © 2019 WooSignal. All rights reserved.
|
||||
// Copyright © 2020 WooSignal. All rights reserved.
|
||||
//
|
||||
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
|
||||
29
LabelStoreMax/lib/app_payment_methods.dart
Normal file
29
LabelStoreMax/lib/app_payment_methods.dart
Normal file
@ -0,0 +1,29 @@
|
||||
import 'package:label_storemax/helpers/tools.dart';
|
||||
import 'package:label_storemax/models/payment_type.dart';
|
||||
import 'package:label_storemax/providers/stripe_pay.dart';
|
||||
|
||||
// Payment methods available for uses in the app
|
||||
// To use use a payment method, include the PaymentType "name" in the app_payment_methods variable in #labelconfig.dart
|
||||
|
||||
List<PaymentType> arrPaymentMethods = [
|
||||
addPayment(
|
||||
PaymentType(
|
||||
id: 1,
|
||||
name: "Stripe",
|
||||
desc: "Debit or Credit Card",
|
||||
assetImage: "dark_powered_by_stripe.png",
|
||||
pay: stripePay,),
|
||||
),
|
||||
|
||||
// e.g. add more here
|
||||
|
||||
// addPayment(
|
||||
// PaymentType(
|
||||
// id: 2,
|
||||
// name: "MyNewPaymentMethod",
|
||||
// desc: "Debit or Credit Card",
|
||||
// assetImage: "add icon image to assets/images/myimage.png",
|
||||
// pay: stripePay
|
||||
// ),
|
||||
// ),
|
||||
];
|
||||
@ -1,72 +0,0 @@
|
||||
// Label StoreMAX
|
||||
//
|
||||
// Created by Anthony Gordon.
|
||||
// Copyright © 2019 WooSignal. All rights reserved.
|
||||
//
|
||||
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
|
||||
var appCountryOptions = [
|
||||
{"code": "*", "title": "Match all states"},
|
||||
{"code": "AL", "title": "Alabama"},
|
||||
{"code": "AK", "title": "Alaska"},
|
||||
{"code": "AS", "title": "American Samoa"},
|
||||
{"code": "AZ", "title": "Arizona"},
|
||||
{"code": "AR", "title": "Arkansas"},
|
||||
{"code": "CA", "title": "California"},
|
||||
{"code": "CO", "title": "Colorado"},
|
||||
{"code": "CT", "title": "Connecticut"},
|
||||
{"code": "DE", "title": "Delaware"},
|
||||
{"code": "DC", "title": "District Of Columbia"},
|
||||
{"code": "FM", "title": "Federated States Of Micronesia"},
|
||||
{"code": "FL", "title": "Florida"},
|
||||
{"code": "GA", "title": "Georgia"},
|
||||
{"code": "GU", "title": "Guam"},
|
||||
{"code": "HI", "title": "Hawaii"},
|
||||
{"code": "ID", "title": "Idaho"},
|
||||
{"code": "IL", "title": "Illinois"},
|
||||
{"code": "IN", "title": "Indiana"},
|
||||
{"code": "IA", "title": "Iowa"},
|
||||
{"code": "KS", "title": "Kansas"},
|
||||
{"code": "KY", "title": "Kentucky"},
|
||||
{"code": "LA", "title": "Louisiana"},
|
||||
{"code": "ME", "title": "Maine"},
|
||||
{"code": "MH", "title": "Marshall Islands"},
|
||||
{"code": "MD", "title": "Maryland"},
|
||||
{"code": "MA", "title": "Massachusetts"},
|
||||
{"code": "MI", "title": "Michigan"},
|
||||
{"code": "MN", "title": "Minnesota"},
|
||||
{"code": "MS", "title": "Mississippi"},
|
||||
{"code": "MO", "title": "Missouri"},
|
||||
{"code": "MT", "title": "Montana"},
|
||||
{"code": "NE", "title": "Nebraska"},
|
||||
{"code": "NV", "title": "Nevada"},
|
||||
{"code": "NH", "title": "New Hampshire"},
|
||||
{"code": "NJ", "title": "New Jersey"},
|
||||
{"code": "NM", "title": "New Mexico"},
|
||||
{"code": "NY", "title": "New York"},
|
||||
{"code": "NC", "title": "North Carolina"},
|
||||
{"code": "ND", "title": "North Dakota"},
|
||||
{"code": "MP", "title": "Northern Mariana Islands"},
|
||||
{"code": "OH", "title": "Ohio"},
|
||||
{"code": "OK", "title": "Oklahoma"},
|
||||
{"code": "OR", "title": "Oregon"},
|
||||
{"code": "PW", "title": "Palau"},
|
||||
{"code": "PA", "title": "Pennsylvania"},
|
||||
{"code": "PR", "title": "Puerto Rico"},
|
||||
{"code": "RI", "title": "Rhode Island"},
|
||||
{"code": "SC", "title": "South Carolina"},
|
||||
{"code": "SD", "title": "South Dakota"},
|
||||
{"code": "TN", "title": "Tennessee"},
|
||||
{"code": "TX", "title": "Texas"},
|
||||
{"code": "UT", "title": "Utah"},
|
||||
{"code": "VT", "title": "Vermont"},
|
||||
{"code": "VI", "title": "Virgin Islands"},
|
||||
{"code": "VA", "title": "Virginia"},
|
||||
{"code": "WA", "title": "Washington"},
|
||||
{"code": "WV", "title": "West Virginia"},
|
||||
{"code": "WI", "title": "Wisconsin"},
|
||||
{"code": "WY", "title": "Wyoming"}
|
||||
];
|
||||
@ -1,7 +1,7 @@
|
||||
// Label StoreMAX
|
||||
//
|
||||
// Created by Anthony Gordon.
|
||||
// Copyright © 2019 WooSignal. All rights reserved.
|
||||
// Copyright © 2020 WooSignal. All rights reserved.
|
||||
//
|
||||
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
@ -14,6 +14,8 @@ import 'dart:convert';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
|
||||
import '../labelconfig.dart';
|
||||
|
||||
class AppLocalizations {
|
||||
final Locale locale;
|
||||
|
||||
@ -48,7 +50,8 @@ class _AppLocalizationsDelegate
|
||||
const _AppLocalizationsDelegate();
|
||||
|
||||
@override
|
||||
bool isSupported(Locale locale) => ['en', 'es'].contains(locale.languageCode);
|
||||
bool isSupported(Locale locale) =>
|
||||
app_locales_supported.contains(locale.languageCode);
|
||||
|
||||
@override
|
||||
bool shouldReload(_AppLocalizationsDelegate old) => false;
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
// Label StoreMAX
|
||||
//
|
||||
// Created by Anthony Gordon.
|
||||
// Copyright © 2019 WooSignal. All rights reserved.
|
||||
// Copyright © 2020 WooSignal. All rights reserved.
|
||||
//
|
||||
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
|
||||
100
LabelStoreMax/lib/helpers/data/order_wc.dart
Normal file
100
LabelStoreMax/lib/helpers/data/order_wc.dart
Normal file
@ -0,0 +1,100 @@
|
||||
// Label StoreMAX
|
||||
//
|
||||
// Created by Anthony Gordon.
|
||||
// Copyright © 2020 WooSignal. All rights reserved.
|
||||
//
|
||||
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
|
||||
import 'dart:io';
|
||||
|
||||
import 'package:label_storemax/labelconfig.dart';
|
||||
import 'package:label_storemax/models/billing_details.dart';
|
||||
import 'package:label_storemax/models/cart.dart';
|
||||
import 'package:label_storemax/models/cart_line_item.dart';
|
||||
import 'package:label_storemax/models/checkout_session.dart';
|
||||
import 'package:woosignal/models/payload/order_wc.dart';
|
||||
import 'package:woosignal/models/response/tax_rate.dart';
|
||||
|
||||
Future<OrderWC> buildOrderWC({TaxRate taxRate}) async {
|
||||
OrderWC orderWC = OrderWC();
|
||||
|
||||
String paymentMethodName = CheckoutSession.getInstance.paymentType.name ?? "";
|
||||
|
||||
orderWC.paymentMethod = Platform.isAndroid
|
||||
? "$paymentMethodName - Android App"
|
||||
: "$paymentMethodName - IOS App";
|
||||
|
||||
orderWC.paymentMethodTitle = paymentMethodName.toLowerCase();
|
||||
|
||||
orderWC.setPaid = true;
|
||||
orderWC.status = "pending";
|
||||
orderWC.currency = app_currency_iso.toUpperCase();
|
||||
|
||||
List<LineItems> lineItems = [];
|
||||
List<CartLineItem> cartItems = await Cart.getInstance.getCart();
|
||||
cartItems.forEach((cartItem) {
|
||||
LineItems tmpLineItem = LineItems();
|
||||
tmpLineItem.quantity = cartItem.quantity;
|
||||
tmpLineItem.name = cartItem.name;
|
||||
tmpLineItem.productId = cartItem.productId;
|
||||
if (cartItem.variationId != null && cartItem.variationId != 0) {
|
||||
tmpLineItem.variationId = cartItem.variationId;
|
||||
}
|
||||
|
||||
tmpLineItem.total = cartItem.total;
|
||||
tmpLineItem.subtotal = cartItem.subtotal;
|
||||
|
||||
lineItems.add(tmpLineItem);
|
||||
});
|
||||
|
||||
orderWC.lineItems = lineItems;
|
||||
|
||||
BillingDetails billingDetails = CheckoutSession.getInstance.billingDetails;
|
||||
|
||||
Billing billing = Billing();
|
||||
billing.firstName = billingDetails.billingAddress.firstName;
|
||||
billing.lastName = billingDetails.billingAddress.lastName;
|
||||
billing.address1 = billingDetails.billingAddress.addressLine;
|
||||
billing.city = billingDetails.billingAddress.city;
|
||||
billing.postcode = billingDetails.billingAddress.postalCode;
|
||||
billing.country = billingDetails.billingAddress.country;
|
||||
billing.email = billingDetails.billingAddress.emailAddress;
|
||||
|
||||
orderWC.billing = billing;
|
||||
|
||||
Shipping shipping = Shipping();
|
||||
shipping.firstName = billingDetails.shippingAddress.firstName;
|
||||
shipping.lastName = billingDetails.shippingAddress.lastName;
|
||||
shipping.address1 = billingDetails.shippingAddress.addressLine;
|
||||
shipping.city = billingDetails.shippingAddress.city;
|
||||
shipping.postcode = billingDetails.shippingAddress.postalCode;
|
||||
shipping.country = billingDetails.shippingAddress.country;
|
||||
|
||||
orderWC.shipping = shipping;
|
||||
|
||||
orderWC.shippingLines = [];
|
||||
Map<String, dynamic> shippingLineFeeObj =
|
||||
CheckoutSession.getInstance.shippingType.toShippingLineFee();
|
||||
if (shippingLineFeeObj != null) {
|
||||
ShippingLines shippingLine = ShippingLines();
|
||||
shippingLine.methodId = shippingLineFeeObj['method_id'];
|
||||
shippingLine.methodTitle = shippingLineFeeObj['method_title'];
|
||||
shippingLine.total = shippingLineFeeObj['total'];
|
||||
orderWC.shippingLines.add(shippingLine);
|
||||
}
|
||||
|
||||
if (taxRate != null) {
|
||||
orderWC.feeLines = [];
|
||||
FeeLines feeLines = FeeLines();
|
||||
feeLines.name = taxRate.name;
|
||||
feeLines.total = await Cart.getInstance.taxAmount(taxRate);
|
||||
feeLines.taxClass = "";
|
||||
feeLines.taxStatus = "taxable";
|
||||
orderWC.feeLines.add(feeLines);
|
||||
}
|
||||
|
||||
return orderWC;
|
||||
}
|
||||
28
LabelStoreMax/lib/helpers/shared_pref.dart
Normal file
28
LabelStoreMax/lib/helpers/shared_pref.dart
Normal file
@ -0,0 +1,28 @@
|
||||
// Label StoreMAX
|
||||
//
|
||||
// Created by Anthony Gordon.
|
||||
// Copyright © 2020 WooSignal. All rights reserved.
|
||||
//
|
||||
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
|
||||
import 'package:shared_preferences/shared_preferences.dart';
|
||||
|
||||
class SharedPref {
|
||||
read(String key) async {
|
||||
final prefs = await SharedPreferences.getInstance();
|
||||
return prefs.getString(key);
|
||||
}
|
||||
|
||||
save(String key, value) async {
|
||||
final prefs = await SharedPreferences.getInstance();
|
||||
prefs.setString(key, value);
|
||||
}
|
||||
|
||||
remove(String key) async {
|
||||
final prefs = await SharedPreferences.getInstance();
|
||||
prefs.remove(key);
|
||||
}
|
||||
}
|
||||
@ -1,50 +1,42 @@
|
||||
// Label StoreMAX
|
||||
//
|
||||
// Created by Anthony Gordon.
|
||||
// Copyright © 2019 WooSignal. All rights reserved.
|
||||
// Copyright © 2020 WooSignal. All rights reserved.
|
||||
//
|
||||
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
|
||||
import 'package:label_storemax/app_payment_methods.dart';
|
||||
import 'package:label_storemax/helpers/app_localizations.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:fluttertoast/fluttertoast.dart';
|
||||
import 'package:label_storemax/labelconfig.dart';
|
||||
import 'package:edge_alert/edge_alert.dart';
|
||||
import 'package:flutter_spinkit/flutter_spinkit.dart';
|
||||
import 'package:shared_preferences/shared_preferences.dart';
|
||||
import 'package:label_storemax/models/billing_details.dart';
|
||||
import 'package:label_storemax/models/cart.dart';
|
||||
import 'package:label_storemax/models/checkout_session.dart';
|
||||
import 'package:label_storemax/models/payment_type.dart';
|
||||
import 'package:html/parser.dart';
|
||||
import 'package:flutter_web_browser/flutter_web_browser.dart';
|
||||
import 'dart:convert';
|
||||
import 'package:flutter_money_formatter/flutter_money_formatter.dart';
|
||||
import 'package:woosignal/models/response/shipping_method.dart';
|
||||
import 'package:status_alert/status_alert.dart';
|
||||
import 'package:woosignal/models/response/tax_rate.dart';
|
||||
import 'package:woosignal/woosignal.dart';
|
||||
|
||||
// CONFIG FOR WOOSIGNAL API
|
||||
var wsConfig = {"appKey": app_key, "debugMode": app_debug};
|
||||
|
||||
// MARK: PaymentMethodType
|
||||
class PaymentType {
|
||||
int id;
|
||||
String name;
|
||||
String assetImage;
|
||||
|
||||
PaymentType({this.id, this.name, this.assetImage});
|
||||
appWooSignal(Function(WooSignal) api) async {
|
||||
WooSignal wooSignal = await WooSignal.getInstance(
|
||||
config: {"appKey": app_key, "debugMode": app_debug});
|
||||
return await api(wooSignal);
|
||||
}
|
||||
|
||||
List<PaymentType> arrPaymentMethods = [
|
||||
(paymentMethods.contains("Stripe")
|
||||
? (PaymentType(
|
||||
id: 1,
|
||||
name: "Debit or Credit Card",
|
||||
assetImage: "dark_powered_by_stripe.png"))
|
||||
: null)
|
||||
];
|
||||
|
||||
List<PaymentType> getPaymentTypes() {
|
||||
return arrPaymentMethods;
|
||||
return arrPaymentMethods.where((v) => v != null).toList();
|
||||
}
|
||||
|
||||
PaymentType addPayment(PaymentType paymentType) {
|
||||
return app_payment_methods.contains(paymentType.name) ? paymentType : null;
|
||||
}
|
||||
|
||||
class HexColor extends Color {
|
||||
@ -65,29 +57,12 @@ String truncateWithEllipsis(int cutoff, String myString) {
|
||||
: '${myString.substring(0, cutoff)}...';
|
||||
}
|
||||
|
||||
class TextFieldMaker extends TextField {
|
||||
static TextField makeWith(labelTitle) {
|
||||
return TextField(
|
||||
decoration: InputDecoration(
|
||||
labelText: labelTitle,
|
||||
labelStyle: TextStyle(
|
||||
fontFamily: 'Overpass',
|
||||
fontWeight: FontWeight.bold,
|
||||
color: Colors.grey),
|
||||
focusedBorder: UnderlineInputBorder(
|
||||
borderSide: BorderSide(color: Colors.green))),
|
||||
keyboardAppearance: Brightness.light,
|
||||
keyboardType: TextInputType.emailAddress,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
void showToastWith({String message, String statusType}) {
|
||||
Fluttertoast.showToast(
|
||||
msg: message,
|
||||
toastLength: Toast.LENGTH_SHORT,
|
||||
gravity: ToastGravity.CENTER,
|
||||
timeInSecForIos: 3,
|
||||
timeInSecForIosWeb: 3,
|
||||
backgroundColor:
|
||||
(statusType == "error" ? HexColor("#b5123a") : Colors.grey),
|
||||
textColor: (statusType == "error" ? Colors.white : Colors.black),
|
||||
@ -98,26 +73,15 @@ void showToastNetworkError() {
|
||||
showToastWith(message: "Oops, something went wrong");
|
||||
}
|
||||
|
||||
bool isEmail(String em) {
|
||||
String p =
|
||||
r'^(([^<>()[\]\\.,;:\s@\"]+(\.[^<>()[\]\\.,;:\s@\"]+)*)|(\".+\"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$';
|
||||
RegExp regExp = new RegExp(p);
|
||||
return regExp.hasMatch(em);
|
||||
}
|
||||
|
||||
// 6 LENGTH, 1 DIGIT
|
||||
bool validPassword(String pw) {
|
||||
String p = r'^(?=.*[A-Za-z])(?=.*\d)[A-Za-z\d]{6,}$';
|
||||
RegExp regExp = new RegExp(p);
|
||||
return regExp.hasMatch(pw);
|
||||
}
|
||||
|
||||
Widget showAppLoader() {
|
||||
return SpinKitDoubleBounce(color: HexColor("#393318"));
|
||||
}
|
||||
|
||||
Future delayFunction(void Function() action) {
|
||||
return Future.delayed(const Duration(milliseconds: 300), action);
|
||||
showStatusAlert(context,
|
||||
{@required String title, String subtitle, IconData icon, int duration}) {
|
||||
StatusAlert.show(
|
||||
context,
|
||||
duration: Duration(seconds: duration ?? 2),
|
||||
title: title,
|
||||
subtitle: subtitle,
|
||||
configuration: IconConfiguration(icon: icon ?? Icons.done, size: 50),
|
||||
);
|
||||
}
|
||||
|
||||
class PaymentMethodType {
|
||||
@ -176,218 +140,19 @@ void showEdgeAlertWith(context,
|
||||
}
|
||||
}
|
||||
|
||||
void errorWithNetworkDefault(BuildContext context) {
|
||||
showEdgeAlertWith(context,
|
||||
title: trans(context, "Oops"),
|
||||
desc: trans(context, "Something went wrong"),
|
||||
style: EdgeAlertStyle.DANGER);
|
||||
}
|
||||
|
||||
String parseHtmlString(String htmlString) {
|
||||
var document = parse(htmlString);
|
||||
String parsedString = parse(document.body.text).documentElement.text;
|
||||
return parsedString;
|
||||
}
|
||||
|
||||
class CartLineItem {
|
||||
String name;
|
||||
int productId;
|
||||
int variationId;
|
||||
int quantity;
|
||||
bool isManagedStock;
|
||||
int stockQuantity;
|
||||
String shippingClassId;
|
||||
String taxStatus;
|
||||
String taxClass;
|
||||
bool shippingIsTaxable;
|
||||
String subtotal;
|
||||
String total;
|
||||
String imageSrc;
|
||||
String variationOptions;
|
||||
String stockStatus;
|
||||
Object metaData = {};
|
||||
|
||||
CartLineItem(
|
||||
{this.name,
|
||||
this.productId,
|
||||
this.variationId,
|
||||
this.isManagedStock,
|
||||
this.stockQuantity,
|
||||
this.quantity,
|
||||
this.stockStatus,
|
||||
this.shippingClassId,
|
||||
this.taxStatus,
|
||||
this.taxClass,
|
||||
this.shippingIsTaxable,
|
||||
this.variationOptions,
|
||||
this.imageSrc,
|
||||
this.subtotal,
|
||||
this.total,
|
||||
this.metaData});
|
||||
|
||||
CartLineItem.fromJson(Map<String, dynamic> json)
|
||||
: name = json['name'],
|
||||
productId = json['product_id'],
|
||||
variationId = json['variation_id'],
|
||||
quantity = json['quantity'],
|
||||
shippingClassId = json['shipping_class_id'].toString(),
|
||||
taxStatus = json['tax_status'],
|
||||
stockQuantity = json['stock_quantity'],
|
||||
isManagedStock = json['is_managed_stock'],
|
||||
shippingIsTaxable = json['shipping_is_taxable'],
|
||||
subtotal = json['subtotal'],
|
||||
total = json['total'],
|
||||
taxClass = json['tax_class'],
|
||||
stockStatus = json['stock_status'],
|
||||
imageSrc = json['image_src'],
|
||||
variationOptions = json['variation_options'],
|
||||
metaData = json['metaData'];
|
||||
|
||||
Map<String, dynamic> toJson() => {
|
||||
'name': name,
|
||||
'product_id': productId,
|
||||
'variation_id': variationId,
|
||||
'quantity': quantity,
|
||||
'shipping_class_id': shippingClassId,
|
||||
'tax_status': taxStatus,
|
||||
'tax_class': taxClass,
|
||||
'stock_status': stockStatus,
|
||||
'is_managed_stock': isManagedStock,
|
||||
'stock_quantity': stockQuantity,
|
||||
'shipping_is_taxable': shippingIsTaxable,
|
||||
'image_src': imageSrc,
|
||||
'variation_options': variationOptions,
|
||||
'subtotal': subtotal,
|
||||
'total': total,
|
||||
'meta_data': metaData,
|
||||
};
|
||||
}
|
||||
|
||||
class SharedPref {
|
||||
read(String key) async {
|
||||
final prefs = await SharedPreferences.getInstance();
|
||||
return prefs.getString(key);
|
||||
}
|
||||
|
||||
save(String key, value) async {
|
||||
final prefs = await SharedPreferences.getInstance();
|
||||
prefs.setString(key, value);
|
||||
}
|
||||
|
||||
remove(String key) async {
|
||||
final prefs = await SharedPreferences.getInstance();
|
||||
prefs.remove(key);
|
||||
}
|
||||
}
|
||||
|
||||
class CustomerAddress {
|
||||
String firstName;
|
||||
String lastName;
|
||||
String addressLine;
|
||||
String city;
|
||||
String postalCode;
|
||||
String country;
|
||||
String emailAddress;
|
||||
|
||||
CustomerAddress(
|
||||
{this.firstName,
|
||||
this.lastName,
|
||||
this.addressLine,
|
||||
this.city,
|
||||
this.postalCode,
|
||||
this.country,
|
||||
this.emailAddress});
|
||||
|
||||
void initAddress() {
|
||||
firstName = "";
|
||||
lastName = "";
|
||||
addressLine = "";
|
||||
city = "";
|
||||
postalCode = "";
|
||||
country = "";
|
||||
emailAddress = "";
|
||||
}
|
||||
|
||||
bool hasMissingFields() {
|
||||
return (this.firstName.isEmpty ||
|
||||
this.lastName.isEmpty ||
|
||||
this.addressLine.isEmpty ||
|
||||
this.city.isEmpty ||
|
||||
this.postalCode.isEmpty);
|
||||
}
|
||||
|
||||
String addressFull() {
|
||||
List<String> tmpArrAddress = new List<String>();
|
||||
if (addressLine != "") {
|
||||
tmpArrAddress.add(addressLine);
|
||||
}
|
||||
if (city != "") {
|
||||
tmpArrAddress.add(city);
|
||||
}
|
||||
if (postalCode != "") {
|
||||
tmpArrAddress.add(postalCode);
|
||||
}
|
||||
if (country != "") {
|
||||
tmpArrAddress.add(country);
|
||||
}
|
||||
return tmpArrAddress.join(", ");
|
||||
}
|
||||
|
||||
String nameFull() {
|
||||
List<String> tmpArrName = new List<String>();
|
||||
if (firstName != "") {
|
||||
tmpArrName.add(firstName);
|
||||
}
|
||||
if (lastName != "") {
|
||||
tmpArrName.add(lastName);
|
||||
}
|
||||
return tmpArrName.join(", ");
|
||||
}
|
||||
|
||||
CustomerAddress.fromJson(Map<String, dynamic> json) {
|
||||
firstName = json['first_name'];
|
||||
lastName = json['last_name'];
|
||||
addressLine = json['address_line'];
|
||||
city = json['city'];
|
||||
postalCode = json['postal_code'];
|
||||
country = json['country'];
|
||||
emailAddress = json['email_address'];
|
||||
}
|
||||
|
||||
Map<String, dynamic> toJson() {
|
||||
final Map<String, dynamic> data = new Map<String, dynamic>();
|
||||
data['first_name'] = this.firstName;
|
||||
data['last_name'] = this.lastName;
|
||||
data['address_line'] = this.addressLine;
|
||||
data['city'] = this.city;
|
||||
data['postal_code'] = this.postalCode;
|
||||
data['country'] = this.country;
|
||||
data['email_address'] = this.emailAddress;
|
||||
return data;
|
||||
}
|
||||
}
|
||||
|
||||
class BillingDetails {
|
||||
CustomerAddress billingAddress;
|
||||
CustomerAddress shippingAddress;
|
||||
bool rememberDetails;
|
||||
|
||||
void initSession() {
|
||||
billingAddress = CustomerAddress();
|
||||
shippingAddress = CustomerAddress();
|
||||
}
|
||||
}
|
||||
|
||||
class PaymentDetails {
|
||||
String method;
|
||||
}
|
||||
|
||||
String formatDoubleCurrency({double total}) {
|
||||
FlutterMoneyFormatter fmf = FlutterMoneyFormatter(
|
||||
amount: total,
|
||||
settings: MoneyFormatterSettings(
|
||||
symbol: app_currency_symbol,
|
||||
));
|
||||
amount: total,
|
||||
settings: MoneyFormatterSettings(
|
||||
symbol: app_currency_symbol,
|
||||
),
|
||||
);
|
||||
return fmf.output.symbolOnLeft;
|
||||
}
|
||||
|
||||
@ -399,338 +164,15 @@ String formatStringCurrency({String total}) {
|
||||
tmpVal = double.parse(total);
|
||||
}
|
||||
FlutterMoneyFormatter fmf = FlutterMoneyFormatter(
|
||||
amount: tmpVal,
|
||||
settings: MoneyFormatterSettings(
|
||||
symbol: app_currency_symbol,
|
||||
));
|
||||
amount: tmpVal,
|
||||
settings: MoneyFormatterSettings(
|
||||
symbol: app_currency_symbol,
|
||||
),
|
||||
);
|
||||
return fmf.output.symbolOnLeft;
|
||||
}
|
||||
|
||||
class ShippingType {
|
||||
String methodId;
|
||||
String cost;
|
||||
dynamic object;
|
||||
|
||||
ShippingType({this.methodId, this.object, this.cost});
|
||||
|
||||
Map<String, dynamic> toJson() =>
|
||||
{'methodId': methodId, 'object': object, 'cost': cost};
|
||||
|
||||
String getTotal({bool withFormatting}) {
|
||||
if (this.methodId != null && this.object != null) {
|
||||
switch (this.methodId) {
|
||||
case "flat_rate":
|
||||
FlatRate flatRate = (this.object as FlatRate);
|
||||
return (withFormatting == true
|
||||
? formatStringCurrency(total: cost)
|
||||
: flatRate.cost);
|
||||
case "free_shipping":
|
||||
FreeShipping freeShipping = (this.object as FreeShipping);
|
||||
return (withFormatting == true
|
||||
? formatStringCurrency(total: cost)
|
||||
: freeShipping.cost);
|
||||
case "local_pickup":
|
||||
LocalPickup localPickup = (this.object as LocalPickup);
|
||||
return (withFormatting == true
|
||||
? formatStringCurrency(total: cost)
|
||||
: localPickup.cost);
|
||||
default:
|
||||
return "0";
|
||||
break;
|
||||
}
|
||||
}
|
||||
return "0";
|
||||
}
|
||||
|
||||
String getTitle() {
|
||||
if (this.methodId != null && this.object != null) {
|
||||
switch (this.methodId) {
|
||||
case "flat_rate":
|
||||
FlatRate flatRate = (this.object as FlatRate);
|
||||
return flatRate.title;
|
||||
case "free_shipping":
|
||||
FreeShipping freeShipping = (this.object as FreeShipping);
|
||||
return freeShipping.title;
|
||||
case "local_pickup":
|
||||
LocalPickup localPickup = (this.object as LocalPickup);
|
||||
return localPickup.title;
|
||||
default:
|
||||
return "";
|
||||
break;
|
||||
}
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
Map<String, dynamic> toShippingLineFee() {
|
||||
if (this.methodId != null && this.object != null) {
|
||||
Map<String, dynamic> tmpShippingLinesObj = {};
|
||||
|
||||
switch (this.methodId) {
|
||||
case "flat_rate":
|
||||
FlatRate flatRate = (this.object as FlatRate);
|
||||
tmpShippingLinesObj["method_title"] = flatRate.title;
|
||||
tmpShippingLinesObj["method_id"] = flatRate.methodId;
|
||||
tmpShippingLinesObj["total"] = this.cost;
|
||||
break;
|
||||
case "free_shipping":
|
||||
FreeShipping freeShipping = (this.object as FreeShipping);
|
||||
tmpShippingLinesObj["method_title"] = freeShipping.title;
|
||||
tmpShippingLinesObj["method_id"] = freeShipping.methodId;
|
||||
tmpShippingLinesObj["total"] = this.cost;
|
||||
break;
|
||||
case "local_pickup":
|
||||
LocalPickup localPickup = (this.object as LocalPickup);
|
||||
tmpShippingLinesObj["method_title"] = localPickup.title;
|
||||
tmpShippingLinesObj["method_id"] = localPickup.methodId;
|
||||
tmpShippingLinesObj["total"] = this.cost;
|
||||
break;
|
||||
default:
|
||||
return null;
|
||||
break;
|
||||
}
|
||||
return tmpShippingLinesObj;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
class CheckoutSession {
|
||||
String sfKeyCheckout = "CS_BILLING_DETAILS";
|
||||
CheckoutSession._privateConstructor();
|
||||
static final CheckoutSession getInstance =
|
||||
CheckoutSession._privateConstructor();
|
||||
|
||||
BillingDetails billingDetails;
|
||||
ShippingType shippingType;
|
||||
PaymentType paymentType;
|
||||
|
||||
void initSession() {
|
||||
billingDetails = BillingDetails();
|
||||
shippingType = null;
|
||||
}
|
||||
|
||||
void saveBillingAddress() {
|
||||
SharedPref sharedPref = SharedPref();
|
||||
CustomerAddress customerAddress =
|
||||
CheckoutSession.getInstance.billingDetails.billingAddress;
|
||||
|
||||
String billingAddress = jsonEncode(customerAddress.toJson());
|
||||
sharedPref.save(sfKeyCheckout, billingAddress);
|
||||
}
|
||||
|
||||
Future<CustomerAddress> getBillingAddress() async {
|
||||
SharedPref sharedPref = SharedPref();
|
||||
|
||||
String strCheckoutDetails = await sharedPref.read(sfKeyCheckout);
|
||||
|
||||
if (strCheckoutDetails != null && strCheckoutDetails != "") {
|
||||
return CustomerAddress.fromJson(jsonDecode(strCheckoutDetails));
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
void clearBillingAddress() {
|
||||
SharedPref sharedPref = SharedPref();
|
||||
sharedPref.remove(sfKeyCheckout);
|
||||
}
|
||||
|
||||
Future<String> total({bool withFormat, TaxRate taxRate}) async {
|
||||
double totalCart = double.parse(await Cart.getInstance.getTotal());
|
||||
double totalShipping = 0;
|
||||
if (shippingType != null && shippingType.object != null) {
|
||||
switch (shippingType.methodId) {
|
||||
case "flat_rate":
|
||||
totalShipping = double.parse(shippingType.cost);
|
||||
break;
|
||||
case "free_shipping":
|
||||
totalShipping = double.parse(shippingType.cost);
|
||||
break;
|
||||
case "local_pickup":
|
||||
totalShipping = double.parse(shippingType.cost);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
double total = totalCart + totalShipping;
|
||||
|
||||
if (taxRate != null) {
|
||||
String taxAmount = await Cart.getInstance.taxAmount(taxRate);
|
||||
total += double.parse(taxAmount);
|
||||
}
|
||||
|
||||
if (withFormat != null && withFormat == true) {
|
||||
return formatDoubleCurrency(total: total);
|
||||
}
|
||||
return total.toString();
|
||||
}
|
||||
}
|
||||
|
||||
class Cart {
|
||||
String _keyCart = "CART_SESSION";
|
||||
|
||||
Cart._privateConstructor();
|
||||
static final Cart getInstance = Cart._privateConstructor();
|
||||
|
||||
Future<List<CartLineItem>> getCart() async {
|
||||
List<CartLineItem> cartLineItems = [];
|
||||
SharedPref sharedPref = SharedPref();
|
||||
String currentCartArrJSON = (await sharedPref.read(_keyCart) as String);
|
||||
if (currentCartArrJSON == null) {
|
||||
cartLineItems = List<CartLineItem>();
|
||||
} else {
|
||||
cartLineItems = (jsonDecode(currentCartArrJSON) as List<dynamic>)
|
||||
.map((i) => CartLineItem.fromJson(i))
|
||||
.toList();
|
||||
}
|
||||
return cartLineItems;
|
||||
}
|
||||
|
||||
void addToCart({CartLineItem cartLineItem}) async {
|
||||
List<CartLineItem> cartLineItems = await getCart();
|
||||
var firstCartItem = cartLineItems.firstWhere(
|
||||
(i) =>
|
||||
i.productId == cartLineItem.productId ||
|
||||
i.productId == cartLineItem.productId &&
|
||||
i.variationId == cartLineItem.variationId, orElse: () {
|
||||
return null;
|
||||
});
|
||||
if (firstCartItem != null) {
|
||||
return;
|
||||
}
|
||||
cartLineItems.add(cartLineItem);
|
||||
|
||||
saveCartToPref(cartLineItems: cartLineItems);
|
||||
}
|
||||
|
||||
Future<String> getTotal({bool withFormat}) async {
|
||||
List<CartLineItem> cartLineItems = await getCart();
|
||||
double total = 0;
|
||||
cartLineItems.forEach((cartItem) {
|
||||
total += (double.parse(cartItem.total) * cartItem.quantity);
|
||||
});
|
||||
|
||||
if (withFormat != null && withFormat == true) {
|
||||
return formatDoubleCurrency(total: total);
|
||||
}
|
||||
return total.toString();
|
||||
}
|
||||
|
||||
Future<String> getSubtotal({bool withFormat}) async {
|
||||
List<CartLineItem> cartLineItems = await getCart();
|
||||
double subtotal = 0;
|
||||
cartLineItems.forEach((cartItem) {
|
||||
subtotal += (double.parse(cartItem.subtotal) * cartItem.quantity);
|
||||
});
|
||||
if (withFormat != null && withFormat == true) {
|
||||
return formatDoubleCurrency(total: subtotal);
|
||||
}
|
||||
return subtotal.toString();
|
||||
}
|
||||
|
||||
void updateQuantity(
|
||||
{CartLineItem cartLineItem, int incrementQuantity}) async {
|
||||
List<CartLineItem> cartLineItems = await getCart();
|
||||
List<CartLineItem> tmpCartItem = new List<CartLineItem>();
|
||||
cartLineItems.forEach((cartItem) {
|
||||
if (cartItem.variationId == cartLineItem.variationId &&
|
||||
cartItem.productId == cartLineItem.productId) {
|
||||
if ((cartItem.quantity + incrementQuantity) > 0) {
|
||||
cartItem.quantity += incrementQuantity;
|
||||
}
|
||||
}
|
||||
tmpCartItem.add(cartItem);
|
||||
});
|
||||
saveCartToPref(cartLineItems: tmpCartItem);
|
||||
}
|
||||
|
||||
Future<String> cartShortDesc() async {
|
||||
List<CartLineItem> cartLineItems = await getCart();
|
||||
var tmpShortItemDesc = [];
|
||||
cartLineItems.forEach((cartItem) {
|
||||
tmpShortItemDesc
|
||||
.add(cartItem.quantity.toString() + " x | " + cartItem.name);
|
||||
});
|
||||
return tmpShortItemDesc.join(",");
|
||||
}
|
||||
|
||||
void removeCartItemForIndex({int index}) async {
|
||||
List<CartLineItem> cartLineItems = await getCart();
|
||||
cartLineItems.removeAt(index);
|
||||
saveCartToPref(cartLineItems: cartLineItems);
|
||||
}
|
||||
|
||||
void clear() {
|
||||
SharedPref sharedPref = SharedPref();
|
||||
List<CartLineItem> cartLineItems = new List<CartLineItem>();
|
||||
String jsonArrCartItems =
|
||||
jsonEncode(cartLineItems.map((i) => i.toJson()).toList());
|
||||
sharedPref.save(_keyCart, jsonArrCartItems);
|
||||
}
|
||||
|
||||
void saveCartToPref({List<CartLineItem> cartLineItems}) {
|
||||
SharedPref sharedPref = SharedPref();
|
||||
String jsonArrCartItems =
|
||||
jsonEncode(cartLineItems.map((i) => i.toJson()).toList());
|
||||
sharedPref.save(_keyCart, jsonArrCartItems);
|
||||
}
|
||||
|
||||
Future<String> taxAmount(TaxRate taxRate) async {
|
||||
double subtotal = 0;
|
||||
double shippingTotal = 0;
|
||||
|
||||
List<CartLineItem> cartItems = await Cart.getInstance.getCart();
|
||||
if (cartItems.every((c) => c.taxStatus == 'none')) {
|
||||
return "0";
|
||||
}
|
||||
List<CartLineItem> taxableCartLines =
|
||||
cartItems.where((c) => c.taxStatus == 'taxable').toList();
|
||||
double cartSubtotal = 0;
|
||||
|
||||
if (taxableCartLines.length > 0) {
|
||||
cartSubtotal = taxableCartLines
|
||||
.map<double>((m) => double.parse(m.subtotal))
|
||||
.reduce((a, b) => a + b);
|
||||
}
|
||||
|
||||
subtotal = cartSubtotal;
|
||||
|
||||
ShippingType shippingType = CheckoutSession.getInstance.shippingType;
|
||||
|
||||
if (shippingType != null) {
|
||||
switch (shippingType.methodId) {
|
||||
case "flat_rate":
|
||||
FlatRate flatRate = (shippingType.object as FlatRate);
|
||||
if (flatRate.taxable != null && flatRate.taxable) {
|
||||
shippingTotal += double.parse(shippingType.cost);
|
||||
}
|
||||
break;
|
||||
case "local_pickup":
|
||||
LocalPickup localPickup = (shippingType.object as LocalPickup);
|
||||
if (localPickup.taxable != null && localPickup.taxable) {
|
||||
shippingTotal += double.parse(localPickup.cost);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
double total = 0;
|
||||
if (subtotal != 0) {
|
||||
total += ((double.parse(taxRate.rate) * subtotal) / 100);
|
||||
}
|
||||
if (shippingTotal != 0) {
|
||||
total += ((double.parse(taxRate.rate) * shippingTotal) / 100);
|
||||
}
|
||||
return (total).toString();
|
||||
}
|
||||
}
|
||||
|
||||
openBrowserTab({String url}) async {
|
||||
openBrowserTab({@required String url}) async {
|
||||
await FlutterWebBrowser.openWebPage(
|
||||
url: url, androidToolbarColor: Colors.white70);
|
||||
}
|
||||
@ -739,26 +181,21 @@ EdgeInsets safeAreaDefault() {
|
||||
return EdgeInsets.only(left: 16, right: 16, bottom: 8);
|
||||
}
|
||||
|
||||
class SlideRightRoute extends PageRouteBuilder {
|
||||
final Widget widget;
|
||||
SlideRightRoute({this.widget})
|
||||
: super(pageBuilder: (BuildContext context, Animation<double> animation,
|
||||
Animation<double> secondaryAnimation) {
|
||||
return widget;
|
||||
}, transitionsBuilder: (BuildContext context,
|
||||
Animation<double> animation,
|
||||
Animation<double> secondaryAnimation,
|
||||
Widget child) {
|
||||
return new SlideTransition(
|
||||
position: new Tween<Offset>(
|
||||
begin: const Offset(-1.0, 0.0),
|
||||
end: Offset.zero,
|
||||
).animate(animation),
|
||||
child: child,
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
String trans(BuildContext context, String key) {
|
||||
return AppLocalizations.of(context).trans(key);
|
||||
}
|
||||
|
||||
bool isNumeric(String str) {
|
||||
if (str == null) {
|
||||
return false;
|
||||
}
|
||||
return double.tryParse(str) != null;
|
||||
}
|
||||
|
||||
checkout(TaxRate taxRate, Function(String total, BillingDetails billingDetails, Cart cart) completeCheckout) async {
|
||||
String cartTotal = await CheckoutSession.getInstance
|
||||
.total(withFormat: false, taxRate: taxRate);
|
||||
BillingDetails billingDetails = CheckoutSession.getInstance.billingDetails;
|
||||
Cart cart = Cart.getInstance;
|
||||
return await completeCheckout(cartTotal, billingDetails, cart);
|
||||
}
|
||||
|
||||
@ -3,7 +3,7 @@
|
||||
// Label StoreMAX
|
||||
//
|
||||
// Created by Anthony Gordon.
|
||||
// Copyright © 2019 WooSignal. All rights reserved.
|
||||
// Copyright © 2020 WooSignal. All rights reserved.
|
||||
//
|
||||
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
@ -14,7 +14,7 @@
|
||||
Developer Notes
|
||||
|
||||
SUPPORT EMAIL - support@woosignal.com
|
||||
VERSION - 1.0
|
||||
VERSION - 2.0
|
||||
https://woosignal.com
|
||||
*/
|
||||
|
||||
@ -22,7 +22,8 @@
|
||||
|
||||
const app_name = "MyApp";
|
||||
|
||||
const app_key = "your app key";
|
||||
const app_key =
|
||||
"app_affb6434339b34443a297c2e40a3edab7102137e6d67de9abfe612b749bd";
|
||||
|
||||
const app_logo_url = "https://woosignal.com/images/120x120_woosignal.png";
|
||||
|
||||
@ -31,7 +32,9 @@ const app_privacy_url = "https://yourdomain.com/privacy";
|
||||
|
||||
/*<! ------ STRIPE (OPTIONAL) ------!>*/
|
||||
|
||||
const app_stripe_account = "your StripeAccount key"; // Your StripeAccount key from WooSignal
|
||||
const app_stripe_account =
|
||||
"acct_1DNNUgADlQ9NE89O"; // Your StripeAccount key from WooSignal
|
||||
|
||||
const app_stripe_live_mode = false; // SET true for live payments
|
||||
|
||||
/*<! ------ APP CURRENCY ------!>*/
|
||||
@ -40,7 +43,7 @@ const app_currency_symbol = "\£";
|
||||
const app_currency_iso = "gbp";
|
||||
const app_locales_supported = ['en'];
|
||||
|
||||
const paymentMethods = ["Stripe"];
|
||||
const app_payment_methods = ["Stripe", "RazorPay"];
|
||||
|
||||
/*<! ------ DEBUGGER ENABLED ------!>*/
|
||||
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
// Label StoreMAX
|
||||
//
|
||||
// Created by Anthony Gordon.
|
||||
// Copyright © 2019 WooSignal. All rights reserved.
|
||||
// Copyright © 2020 WooSignal. All rights reserved.
|
||||
//
|
||||
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
@ -10,6 +10,10 @@
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_localizations/flutter_localizations.dart';
|
||||
import 'package:label_storemax/pages/error_page.dart';
|
||||
import 'package:woosignal/models/response/order.dart';
|
||||
import 'package:woosignal/models/response/product_category.dart';
|
||||
import 'package:woosignal/models/response/products.dart';
|
||||
import 'labelconfig.dart';
|
||||
import 'package:label_storemax/pages/checkout_details.dart';
|
||||
import 'package:label_storemax/pages/home.dart';
|
||||
@ -46,43 +50,106 @@ void main() async {
|
||||
routes: <String, WidgetBuilder>{
|
||||
'/home': (BuildContext context) => new HomePage(),
|
||||
'/cart': (BuildContext context) => new CartPage(),
|
||||
'/browse-category': (BuildContext context) => new BrowseCategoryPage(),
|
||||
'/product-search': (BuildContext context) => new BrowseSearchPage(),
|
||||
'/product-detail': (BuildContext context) => new ProductDetailPage(),
|
||||
'/error': (BuildContext context) => new ErrorPage(),
|
||||
'/checkout': (BuildContext context) => new CheckoutConfirmationPage(),
|
||||
'/checkout-status': (BuildContext context) => new CheckoutStatusPage(),
|
||||
},
|
||||
onGenerateRoute: (settings) {
|
||||
switch (settings.name) {
|
||||
case '/browse-category':
|
||||
if (settings.arguments != null) {
|
||||
final ProductCategory category =
|
||||
settings.arguments as ProductCategory;
|
||||
return PageTransition(
|
||||
child: BrowseCategoryPage(productCategory: category),
|
||||
type: PageTransitionType.fade,
|
||||
);
|
||||
}
|
||||
return PageTransition(
|
||||
child: ErrorPage(),
|
||||
type: PageTransitionType.fade,
|
||||
);
|
||||
|
||||
case '/product-search':
|
||||
if (settings.arguments != null) {
|
||||
final String search = settings.arguments as String;
|
||||
return PageTransition(
|
||||
child: BrowseSearchPage(search: search),
|
||||
type: PageTransitionType.fade,
|
||||
);
|
||||
}
|
||||
return PageTransition(
|
||||
child: ErrorPage(),
|
||||
type: PageTransitionType.fade,
|
||||
);
|
||||
|
||||
case '/product-detail':
|
||||
if (settings.arguments != null) {
|
||||
final Product product = settings.arguments as Product;
|
||||
return PageTransition(
|
||||
child: ProductDetailPage(product: product),
|
||||
type: PageTransitionType.rightToLeftWithFade,
|
||||
);
|
||||
}
|
||||
return PageTransition(
|
||||
child: ErrorPage(),
|
||||
type: PageTransitionType.fade,
|
||||
);
|
||||
|
||||
case '/checkout-status':
|
||||
if (settings.arguments != null) {
|
||||
final Order order = settings.arguments as Order;
|
||||
return PageTransition(
|
||||
child: CheckoutStatusPage(order: order),
|
||||
type: PageTransitionType.rightToLeftWithFade,
|
||||
);
|
||||
}
|
||||
return PageTransition(
|
||||
child: ErrorPage(),
|
||||
type: PageTransitionType.fade,
|
||||
);
|
||||
|
||||
case '/home-menu':
|
||||
return PageTransition(
|
||||
child: HomeMenuPage(), type: PageTransitionType.leftToRight);
|
||||
child: HomeMenuPage(),
|
||||
type: PageTransitionType.leftToRightWithFade,
|
||||
);
|
||||
|
||||
case '/checkout-details':
|
||||
return PageTransition(
|
||||
child: CheckoutDetailsPage(),
|
||||
type: PageTransitionType.downToUp);
|
||||
child: CheckoutDetailsPage(),
|
||||
type: PageTransitionType.downToUp,
|
||||
);
|
||||
|
||||
case '/about':
|
||||
return PageTransition(
|
||||
child: AboutPage(), type: PageTransitionType.leftToRight);
|
||||
child: AboutPage(),
|
||||
type: PageTransitionType.leftToRightWithFade,
|
||||
);
|
||||
|
||||
case '/checkout-payment-type':
|
||||
return PageTransition(
|
||||
child: CheckoutPaymentTypePage(),
|
||||
type: PageTransitionType.downToUp);
|
||||
child: CheckoutPaymentTypePage(),
|
||||
type: PageTransitionType.downToUp,
|
||||
);
|
||||
|
||||
case '/checkout-shipping-type':
|
||||
return PageTransition(
|
||||
child: CheckoutShippingTypePage(),
|
||||
type: PageTransitionType.downToUp);
|
||||
child: CheckoutShippingTypePage(),
|
||||
type: PageTransitionType.downToUp,
|
||||
);
|
||||
|
||||
case '/home-search':
|
||||
return PageTransition(
|
||||
child: HomeSearchPage(), type: PageTransitionType.downToUp);
|
||||
child: HomeSearchPage(),
|
||||
type: PageTransitionType.downToUp,
|
||||
);
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
},
|
||||
supportedLocales: [Locale('en')],
|
||||
supportedLocales: [
|
||||
Locale('en'),
|
||||
],
|
||||
localizationsDelegates: [
|
||||
AppLocalizations.delegate,
|
||||
GlobalWidgetsLocalizations.delegate,
|
||||
@ -106,14 +173,15 @@ void main() async {
|
||||
),
|
||||
),
|
||||
appBarTheme: AppBarTheme(
|
||||
color: Colors.white,
|
||||
textTheme: textThemeAppBar(),
|
||||
elevation: 0.0,
|
||||
brightness: Brightness.light,
|
||||
iconTheme: IconThemeData(color: Colors.black),
|
||||
actionsIconTheme: IconThemeData(
|
||||
color: Colors.black,
|
||||
)),
|
||||
color: Colors.white,
|
||||
textTheme: textThemeAppBar(),
|
||||
elevation: 0.0,
|
||||
brightness: Brightness.light,
|
||||
iconTheme: IconThemeData(color: Colors.black),
|
||||
actionsIconTheme: IconThemeData(
|
||||
color: Colors.black,
|
||||
),
|
||||
),
|
||||
accentColor: Colors.black,
|
||||
accentTextTheme: textThemeAccent(),
|
||||
textTheme: textThemeMain(),
|
||||
|
||||
22
LabelStoreMax/lib/models/billing_details.dart
Normal file
22
LabelStoreMax/lib/models/billing_details.dart
Normal file
@ -0,0 +1,22 @@
|
||||
// Label StoreMAX
|
||||
//
|
||||
// Created by Anthony Gordon.
|
||||
// Copyright © 2020 WooSignal. All rights reserved.
|
||||
//
|
||||
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
|
||||
import 'package:label_storemax/models/customer_address.dart';
|
||||
|
||||
class BillingDetails {
|
||||
CustomerAddress billingAddress;
|
||||
CustomerAddress shippingAddress;
|
||||
bool rememberDetails;
|
||||
|
||||
void initSession() {
|
||||
billingAddress = CustomerAddress();
|
||||
shippingAddress = CustomerAddress();
|
||||
}
|
||||
}
|
||||
181
LabelStoreMax/lib/models/cart.dart
Normal file
181
LabelStoreMax/lib/models/cart.dart
Normal file
@ -0,0 +1,181 @@
|
||||
// Label StoreMAX
|
||||
//
|
||||
// Created by Anthony Gordon.
|
||||
// Copyright © 2020 WooSignal. All rights reserved.
|
||||
//
|
||||
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
|
||||
import 'dart:convert';
|
||||
|
||||
import 'package:label_storemax/helpers/shared_pref.dart';
|
||||
import 'package:label_storemax/models/cart_line_item.dart';
|
||||
import 'package:label_storemax/models/checkout_session.dart';
|
||||
import 'package:label_storemax/models/shipping_type.dart';
|
||||
import 'package:woosignal/models/response/shipping_method.dart';
|
||||
import 'package:woosignal/models/response/tax_rate.dart';
|
||||
|
||||
import '../helpers/tools.dart';
|
||||
|
||||
class Cart {
|
||||
String _keyCart = "CART_SESSION";
|
||||
|
||||
Cart._privateConstructor();
|
||||
static final Cart getInstance = Cart._privateConstructor();
|
||||
|
||||
Future<List<CartLineItem>> getCart() async {
|
||||
List<CartLineItem> cartLineItems = [];
|
||||
SharedPref sharedPref = SharedPref();
|
||||
String currentCartArrJSON = (await sharedPref.read(_keyCart) as String);
|
||||
if (currentCartArrJSON == null) {
|
||||
cartLineItems = List<CartLineItem>();
|
||||
} else {
|
||||
cartLineItems = (jsonDecode(currentCartArrJSON) as List<dynamic>)
|
||||
.map((i) => CartLineItem.fromJson(i))
|
||||
.toList();
|
||||
}
|
||||
return cartLineItems;
|
||||
}
|
||||
|
||||
void addToCart({CartLineItem cartLineItem}) async {
|
||||
List<CartLineItem> cartLineItems = await getCart();
|
||||
var firstCartItem = cartLineItems.firstWhere(
|
||||
(i) =>
|
||||
i.productId == cartLineItem.productId ||
|
||||
i.productId == cartLineItem.productId &&
|
||||
i.variationId == cartLineItem.variationId, orElse: () {
|
||||
return null;
|
||||
});
|
||||
if (firstCartItem != null) {
|
||||
return;
|
||||
}
|
||||
cartLineItems.add(cartLineItem);
|
||||
|
||||
saveCartToPref(cartLineItems: cartLineItems);
|
||||
}
|
||||
|
||||
Future<String> getTotal({bool withFormat}) async {
|
||||
List<CartLineItem> cartLineItems = await getCart();
|
||||
double total = 0;
|
||||
cartLineItems.forEach((cartItem) {
|
||||
total += (double.parse(cartItem.total) * cartItem.quantity);
|
||||
});
|
||||
|
||||
if (withFormat != null && withFormat == true) {
|
||||
return formatDoubleCurrency(total: total);
|
||||
}
|
||||
return total.toString();
|
||||
}
|
||||
|
||||
Future<String> getSubtotal({bool withFormat}) async {
|
||||
List<CartLineItem> cartLineItems = await getCart();
|
||||
double subtotal = 0;
|
||||
cartLineItems.forEach((cartItem) {
|
||||
subtotal += (double.parse(cartItem.subtotal) * cartItem.quantity);
|
||||
});
|
||||
if (withFormat != null && withFormat == true) {
|
||||
return formatDoubleCurrency(total: subtotal);
|
||||
}
|
||||
return subtotal.toString();
|
||||
}
|
||||
|
||||
void updateQuantity(
|
||||
{CartLineItem cartLineItem, int incrementQuantity}) async {
|
||||
List<CartLineItem> cartLineItems = await getCart();
|
||||
List<CartLineItem> tmpCartItem = new List<CartLineItem>();
|
||||
cartLineItems.forEach((cartItem) {
|
||||
if (cartItem.variationId == cartLineItem.variationId &&
|
||||
cartItem.productId == cartLineItem.productId) {
|
||||
if ((cartItem.quantity + incrementQuantity) > 0) {
|
||||
cartItem.quantity += incrementQuantity;
|
||||
}
|
||||
}
|
||||
tmpCartItem.add(cartItem);
|
||||
});
|
||||
saveCartToPref(cartLineItems: tmpCartItem);
|
||||
}
|
||||
|
||||
Future<String> cartShortDesc() async {
|
||||
List<CartLineItem> cartLineItems = await getCart();
|
||||
var tmpShortItemDesc = [];
|
||||
cartLineItems.forEach((cartItem) {
|
||||
tmpShortItemDesc
|
||||
.add(cartItem.quantity.toString() + " x | " + cartItem.name);
|
||||
});
|
||||
return tmpShortItemDesc.join(",");
|
||||
}
|
||||
|
||||
void removeCartItemForIndex({int index}) async {
|
||||
List<CartLineItem> cartLineItems = await getCart();
|
||||
cartLineItems.removeAt(index);
|
||||
saveCartToPref(cartLineItems: cartLineItems);
|
||||
}
|
||||
|
||||
void clear() {
|
||||
SharedPref sharedPref = SharedPref();
|
||||
List<CartLineItem> cartLineItems = new List<CartLineItem>();
|
||||
String jsonArrCartItems =
|
||||
jsonEncode(cartLineItems.map((i) => i.toJson()).toList());
|
||||
sharedPref.save(_keyCart, jsonArrCartItems);
|
||||
}
|
||||
|
||||
void saveCartToPref({List<CartLineItem> cartLineItems}) {
|
||||
SharedPref sharedPref = SharedPref();
|
||||
String jsonArrCartItems =
|
||||
jsonEncode(cartLineItems.map((i) => i.toJson()).toList());
|
||||
sharedPref.save(_keyCart, jsonArrCartItems);
|
||||
}
|
||||
|
||||
Future<String> taxAmount(TaxRate taxRate) async {
|
||||
double subtotal = 0;
|
||||
double shippingTotal = 0;
|
||||
|
||||
List<CartLineItem> cartItems = await Cart.getInstance.getCart();
|
||||
if (cartItems.every((c) => c.taxStatus == 'none')) {
|
||||
return "0";
|
||||
}
|
||||
List<CartLineItem> taxableCartLines =
|
||||
cartItems.where((c) => c.taxStatus == 'taxable').toList();
|
||||
double cartSubtotal = 0;
|
||||
|
||||
if (taxableCartLines.length > 0) {
|
||||
cartSubtotal = taxableCartLines
|
||||
.map<double>((m) => double.parse(m.subtotal))
|
||||
.reduce((a, b) => a + b);
|
||||
}
|
||||
|
||||
subtotal = cartSubtotal;
|
||||
|
||||
ShippingType shippingType = CheckoutSession.getInstance.shippingType;
|
||||
|
||||
if (shippingType != null) {
|
||||
switch (shippingType.methodId) {
|
||||
case "flat_rate":
|
||||
FlatRate flatRate = (shippingType.object as FlatRate);
|
||||
if (flatRate.taxable != null && flatRate.taxable) {
|
||||
shippingTotal += double.parse(shippingType.cost);
|
||||
}
|
||||
break;
|
||||
case "local_pickup":
|
||||
LocalPickup localPickup = (shippingType.object as LocalPickup);
|
||||
if (localPickup.taxable != null && localPickup.taxable) {
|
||||
shippingTotal += double.parse(localPickup.cost);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
double total = 0;
|
||||
if (subtotal != 0) {
|
||||
total += ((double.parse(taxRate.rate) * subtotal) / 100);
|
||||
}
|
||||
if (shippingTotal != 0) {
|
||||
total += ((double.parse(taxRate.rate) * shippingTotal) / 100);
|
||||
}
|
||||
return (total).toString();
|
||||
}
|
||||
}
|
||||
83
LabelStoreMax/lib/models/cart_line_item.dart
Normal file
83
LabelStoreMax/lib/models/cart_line_item.dart
Normal file
@ -0,0 +1,83 @@
|
||||
// Label StoreMAX
|
||||
//
|
||||
// Created by Anthony Gordon.
|
||||
// Copyright © 2020 WooSignal. All rights reserved.
|
||||
//
|
||||
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
|
||||
class CartLineItem {
|
||||
String name;
|
||||
int productId;
|
||||
int variationId;
|
||||
int quantity;
|
||||
bool isManagedStock;
|
||||
int stockQuantity;
|
||||
String shippingClassId;
|
||||
String taxStatus;
|
||||
String taxClass;
|
||||
bool shippingIsTaxable;
|
||||
String subtotal;
|
||||
String total;
|
||||
String imageSrc;
|
||||
String variationOptions;
|
||||
String stockStatus;
|
||||
Object metaData = {};
|
||||
|
||||
CartLineItem(
|
||||
{this.name,
|
||||
this.productId,
|
||||
this.variationId,
|
||||
this.isManagedStock,
|
||||
this.stockQuantity,
|
||||
this.quantity,
|
||||
this.stockStatus,
|
||||
this.shippingClassId,
|
||||
this.taxStatus,
|
||||
this.taxClass,
|
||||
this.shippingIsTaxable,
|
||||
this.variationOptions,
|
||||
this.imageSrc,
|
||||
this.subtotal,
|
||||
this.total,
|
||||
this.metaData});
|
||||
|
||||
CartLineItem.fromJson(Map<String, dynamic> json)
|
||||
: name = json['name'],
|
||||
productId = json['product_id'],
|
||||
variationId = json['variation_id'],
|
||||
quantity = json['quantity'],
|
||||
shippingClassId = json['shipping_class_id'].toString(),
|
||||
taxStatus = json['tax_status'],
|
||||
stockQuantity = json['stock_quantity'],
|
||||
isManagedStock = json['is_managed_stock'],
|
||||
shippingIsTaxable = json['shipping_is_taxable'],
|
||||
subtotal = json['subtotal'],
|
||||
total = json['total'],
|
||||
taxClass = json['tax_class'],
|
||||
stockStatus = json['stock_status'],
|
||||
imageSrc = json['image_src'],
|
||||
variationOptions = json['variation_options'],
|
||||
metaData = json['metaData'];
|
||||
|
||||
Map<String, dynamic> toJson() => {
|
||||
'name': name,
|
||||
'product_id': productId,
|
||||
'variation_id': variationId,
|
||||
'quantity': quantity,
|
||||
'shipping_class_id': shippingClassId,
|
||||
'tax_status': taxStatus,
|
||||
'tax_class': taxClass,
|
||||
'stock_status': stockStatus,
|
||||
'is_managed_stock': isManagedStock,
|
||||
'stock_quantity': stockQuantity,
|
||||
'shipping_is_taxable': shippingIsTaxable,
|
||||
'image_src': imageSrc,
|
||||
'variation_options': variationOptions,
|
||||
'subtotal': subtotal,
|
||||
'total': total,
|
||||
'meta_data': metaData,
|
||||
};
|
||||
}
|
||||
94
LabelStoreMax/lib/models/checkout_session.dart
Normal file
94
LabelStoreMax/lib/models/checkout_session.dart
Normal file
@ -0,0 +1,94 @@
|
||||
// Label StoreMAX
|
||||
//
|
||||
// Created by Anthony Gordon.
|
||||
// Copyright © 2020 WooSignal. All rights reserved.
|
||||
//
|
||||
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
|
||||
import 'dart:convert';
|
||||
|
||||
import 'package:label_storemax/helpers/shared_pref.dart';
|
||||
import 'package:label_storemax/models/billing_details.dart';
|
||||
import 'package:label_storemax/models/cart.dart';
|
||||
import 'package:label_storemax/models/customer_address.dart';
|
||||
import 'package:label_storemax/models/payment_type.dart';
|
||||
import 'package:label_storemax/models/shipping_type.dart';
|
||||
import 'package:woosignal/models/response/tax_rate.dart';
|
||||
|
||||
import '../helpers/tools.dart';
|
||||
|
||||
class CheckoutSession {
|
||||
String sfKeyCheckout = "CS_BILLING_DETAILS";
|
||||
CheckoutSession._privateConstructor();
|
||||
static final CheckoutSession getInstance =
|
||||
CheckoutSession._privateConstructor();
|
||||
|
||||
BillingDetails billingDetails;
|
||||
ShippingType shippingType;
|
||||
PaymentType paymentType;
|
||||
|
||||
void initSession() {
|
||||
billingDetails = BillingDetails();
|
||||
shippingType = null;
|
||||
}
|
||||
|
||||
void saveBillingAddress() {
|
||||
SharedPref sharedPref = SharedPref();
|
||||
CustomerAddress customerAddress =
|
||||
CheckoutSession.getInstance.billingDetails.billingAddress;
|
||||
|
||||
String billingAddress = jsonEncode(customerAddress.toJson());
|
||||
sharedPref.save(sfKeyCheckout, billingAddress);
|
||||
}
|
||||
|
||||
Future<CustomerAddress> getBillingAddress() async {
|
||||
SharedPref sharedPref = SharedPref();
|
||||
|
||||
String strCheckoutDetails = await sharedPref.read(sfKeyCheckout);
|
||||
|
||||
if (strCheckoutDetails != null && strCheckoutDetails != "") {
|
||||
return CustomerAddress.fromJson(jsonDecode(strCheckoutDetails));
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
void clearBillingAddress() {
|
||||
SharedPref sharedPref = SharedPref();
|
||||
sharedPref.remove(sfKeyCheckout);
|
||||
}
|
||||
|
||||
Future<String> total({bool withFormat, TaxRate taxRate}) async {
|
||||
double totalCart = double.parse(await Cart.getInstance.getTotal());
|
||||
double totalShipping = 0;
|
||||
if (shippingType != null && shippingType.object != null) {
|
||||
switch (shippingType.methodId) {
|
||||
case "flat_rate":
|
||||
totalShipping = double.parse(shippingType.cost);
|
||||
break;
|
||||
case "free_shipping":
|
||||
totalShipping = double.parse(shippingType.cost);
|
||||
break;
|
||||
case "local_pickup":
|
||||
totalShipping = double.parse(shippingType.cost);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
double total = totalCart + totalShipping;
|
||||
|
||||
if (taxRate != null) {
|
||||
String taxAmount = await Cart.getInstance.taxAmount(taxRate);
|
||||
total += double.parse(taxAmount);
|
||||
}
|
||||
|
||||
if (withFormat != null && withFormat == true) {
|
||||
return formatDoubleCurrency(total: total);
|
||||
}
|
||||
return total.toString();
|
||||
}
|
||||
}
|
||||
96
LabelStoreMax/lib/models/customer_address.dart
Normal file
96
LabelStoreMax/lib/models/customer_address.dart
Normal file
@ -0,0 +1,96 @@
|
||||
// Label StoreMAX
|
||||
//
|
||||
// Created by Anthony Gordon.
|
||||
// Copyright © 2020 WooSignal. All rights reserved.
|
||||
//
|
||||
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
|
||||
class CustomerAddress {
|
||||
String firstName;
|
||||
String lastName;
|
||||
String addressLine;
|
||||
String city;
|
||||
String postalCode;
|
||||
String country;
|
||||
String emailAddress;
|
||||
|
||||
CustomerAddress(
|
||||
{this.firstName,
|
||||
this.lastName,
|
||||
this.addressLine,
|
||||
this.city,
|
||||
this.postalCode,
|
||||
this.country,
|
||||
this.emailAddress});
|
||||
|
||||
void initAddress() {
|
||||
firstName = "";
|
||||
lastName = "";
|
||||
addressLine = "";
|
||||
city = "";
|
||||
postalCode = "";
|
||||
country = "";
|
||||
emailAddress = "";
|
||||
}
|
||||
|
||||
bool hasMissingFields() {
|
||||
return (this.firstName.isEmpty ||
|
||||
this.lastName.isEmpty ||
|
||||
this.addressLine.isEmpty ||
|
||||
this.city.isEmpty ||
|
||||
this.postalCode.isEmpty);
|
||||
}
|
||||
|
||||
String addressFull() {
|
||||
List<String> tmpArrAddress = new List<String>();
|
||||
if (addressLine != "") {
|
||||
tmpArrAddress.add(addressLine);
|
||||
}
|
||||
if (city != "") {
|
||||
tmpArrAddress.add(city);
|
||||
}
|
||||
if (postalCode != "") {
|
||||
tmpArrAddress.add(postalCode);
|
||||
}
|
||||
if (country != "") {
|
||||
tmpArrAddress.add(country);
|
||||
}
|
||||
return tmpArrAddress.join(", ");
|
||||
}
|
||||
|
||||
String nameFull() {
|
||||
List<String> tmpArrName = new List<String>();
|
||||
if (firstName != "") {
|
||||
tmpArrName.add(firstName);
|
||||
}
|
||||
if (lastName != "") {
|
||||
tmpArrName.add(lastName);
|
||||
}
|
||||
return tmpArrName.join(", ");
|
||||
}
|
||||
|
||||
CustomerAddress.fromJson(Map<String, dynamic> json) {
|
||||
firstName = json['first_name'];
|
||||
lastName = json['last_name'];
|
||||
addressLine = json['address_line'];
|
||||
city = json['city'];
|
||||
postalCode = json['postal_code'];
|
||||
country = json['country'];
|
||||
emailAddress = json['email_address'];
|
||||
}
|
||||
|
||||
Map<String, dynamic> toJson() {
|
||||
final Map<String, dynamic> data = new Map<String, dynamic>();
|
||||
data['first_name'] = this.firstName;
|
||||
data['last_name'] = this.lastName;
|
||||
data['address_line'] = this.addressLine;
|
||||
data['city'] = this.city;
|
||||
data['postal_code'] = this.postalCode;
|
||||
data['country'] = this.country;
|
||||
data['email_address'] = this.emailAddress;
|
||||
return data;
|
||||
}
|
||||
}
|
||||
19
LabelStoreMax/lib/models/payment_type.dart
Normal file
19
LabelStoreMax/lib/models/payment_type.dart
Normal file
@ -0,0 +1,19 @@
|
||||
// Label StoreMAX
|
||||
//
|
||||
// Created by Anthony Gordon.
|
||||
// Copyright © 2020 WooSignal. All rights reserved.
|
||||
//
|
||||
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
|
||||
class PaymentType {
|
||||
int id;
|
||||
String name;
|
||||
String desc;
|
||||
String assetImage;
|
||||
Function pay;
|
||||
|
||||
PaymentType({this.id, this.name, this.desc, this.assetImage, this.pay});
|
||||
}
|
||||
103
LabelStoreMax/lib/models/shipping_type.dart
Normal file
103
LabelStoreMax/lib/models/shipping_type.dart
Normal file
@ -0,0 +1,103 @@
|
||||
// Label StoreMAX
|
||||
//
|
||||
// Created by Anthony Gordon.
|
||||
// Copyright © 2020 WooSignal. All rights reserved.
|
||||
//
|
||||
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
|
||||
import 'package:woosignal/models/response/shipping_method.dart';
|
||||
|
||||
import '../helpers/tools.dart';
|
||||
|
||||
class ShippingType {
|
||||
String methodId;
|
||||
String cost;
|
||||
dynamic object;
|
||||
|
||||
ShippingType({this.methodId, this.object, this.cost});
|
||||
|
||||
Map<String, dynamic> toJson() =>
|
||||
{'methodId': methodId, 'object': object, 'cost': cost};
|
||||
|
||||
String getTotal({bool withFormatting}) {
|
||||
if (this.methodId != null && this.object != null) {
|
||||
switch (this.methodId) {
|
||||
case "flat_rate":
|
||||
FlatRate flatRate = (this.object as FlatRate);
|
||||
return (withFormatting == true
|
||||
? formatStringCurrency(total: cost)
|
||||
: flatRate.cost);
|
||||
case "free_shipping":
|
||||
FreeShipping freeShipping = (this.object as FreeShipping);
|
||||
return (withFormatting == true
|
||||
? formatStringCurrency(total: cost)
|
||||
: freeShipping.cost);
|
||||
case "local_pickup":
|
||||
LocalPickup localPickup = (this.object as LocalPickup);
|
||||
return (withFormatting == true
|
||||
? formatStringCurrency(total: cost)
|
||||
: localPickup.cost);
|
||||
default:
|
||||
return "0";
|
||||
break;
|
||||
}
|
||||
}
|
||||
return "0";
|
||||
}
|
||||
|
||||
String getTitle() {
|
||||
if (this.methodId != null && this.object != null) {
|
||||
switch (this.methodId) {
|
||||
case "flat_rate":
|
||||
FlatRate flatRate = (this.object as FlatRate);
|
||||
return flatRate.title;
|
||||
case "free_shipping":
|
||||
FreeShipping freeShipping = (this.object as FreeShipping);
|
||||
return freeShipping.title;
|
||||
case "local_pickup":
|
||||
LocalPickup localPickup = (this.object as LocalPickup);
|
||||
return localPickup.title;
|
||||
default:
|
||||
return "";
|
||||
break;
|
||||
}
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
Map<String, dynamic> toShippingLineFee() {
|
||||
if (this.methodId != null && this.object != null) {
|
||||
Map<String, dynamic> tmpShippingLinesObj = {};
|
||||
|
||||
switch (this.methodId) {
|
||||
case "flat_rate":
|
||||
FlatRate flatRate = (this.object as FlatRate);
|
||||
tmpShippingLinesObj["method_title"] = flatRate.title;
|
||||
tmpShippingLinesObj["method_id"] = flatRate.methodId;
|
||||
tmpShippingLinesObj["total"] = this.cost;
|
||||
break;
|
||||
case "free_shipping":
|
||||
FreeShipping freeShipping = (this.object as FreeShipping);
|
||||
tmpShippingLinesObj["method_title"] = freeShipping.title;
|
||||
tmpShippingLinesObj["method_id"] = freeShipping.methodId;
|
||||
tmpShippingLinesObj["total"] = this.cost;
|
||||
break;
|
||||
case "local_pickup":
|
||||
LocalPickup localPickup = (this.object as LocalPickup);
|
||||
tmpShippingLinesObj["method_title"] = localPickup.title;
|
||||
tmpShippingLinesObj["method_id"] = localPickup.methodId;
|
||||
tmpShippingLinesObj["total"] = this.cost;
|
||||
break;
|
||||
default:
|
||||
return null;
|
||||
break;
|
||||
}
|
||||
return tmpShippingLinesObj;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@ -1,7 +1,7 @@
|
||||
// Label StoreMAX
|
||||
//
|
||||
// Created by Anthony Gordon.
|
||||
// Copyright © 2019 WooSignal. All rights reserved.
|
||||
// Copyright © 2020 WooSignal. All rights reserved.
|
||||
//
|
||||
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
@ -11,6 +11,7 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:label_storemax/helpers/tools.dart';
|
||||
import 'package:label_storemax/labelconfig.dart';
|
||||
import 'package:label_storemax/widgets/menu_item.dart';
|
||||
import 'package:label_storemax/widgets/woosignal_ui.dart';
|
||||
import 'package:package_info/package_info.dart';
|
||||
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
// Label StoreMAX
|
||||
//
|
||||
// Created by Anthony Gordon.
|
||||
// Copyright © 2019 WooSignal. All rights reserved.
|
||||
// Copyright © 2020 WooSignal. All rights reserved.
|
||||
//
|
||||
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
@ -10,20 +10,23 @@
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:label_storemax/helpers/tools.dart';
|
||||
import 'package:label_storemax/widgets/app_loader.dart';
|
||||
import 'package:woosignal/models/response/product_category.dart';
|
||||
import 'package:woosignal/models/response/products.dart' as WS;
|
||||
import 'package:woosignal/woosignal.dart';
|
||||
import 'package:label_storemax/widgets/woosignal_ui.dart';
|
||||
|
||||
class BrowseCategoryPage extends StatefulWidget {
|
||||
BrowseCategoryPage();
|
||||
final ProductCategory productCategory;
|
||||
const BrowseCategoryPage({Key key, @required this.productCategory})
|
||||
: super(key: key);
|
||||
|
||||
@override
|
||||
_BrowseCategoryPageState createState() => _BrowseCategoryPageState();
|
||||
_BrowseCategoryPageState createState() =>
|
||||
_BrowseCategoryPageState(productCategory);
|
||||
}
|
||||
|
||||
class _BrowseCategoryPageState extends State<BrowseCategoryPage> {
|
||||
_BrowseCategoryPageState();
|
||||
_BrowseCategoryPageState(this._selectedCategory);
|
||||
|
||||
List<WS.Product> _products = [];
|
||||
var _productsController = ScrollController();
|
||||
@ -44,6 +47,11 @@ class _BrowseCategoryPageState extends State<BrowseCategoryPage> {
|
||||
_shouldStopRequests = false;
|
||||
waitForNextRequest = false;
|
||||
|
||||
_fetchProductsForCategory();
|
||||
_addScrollListener();
|
||||
}
|
||||
|
||||
_addScrollListener() async {
|
||||
_productsController.addListener(() {
|
||||
double maxScroll = _productsController.position.maxScrollExtent;
|
||||
double currentScroll = _productsController.position.pixels;
|
||||
@ -55,44 +63,35 @@ class _BrowseCategoryPageState extends State<BrowseCategoryPage> {
|
||||
if (waitForNextRequest) {
|
||||
return;
|
||||
}
|
||||
WooSignal.getInstance(config: wsConfig).then((wcStore) {
|
||||
waitForNextRequest = true;
|
||||
_page = _page + 1;
|
||||
wcStore
|
||||
.getProducts(perPage: 50, page: _page, status: "publish")
|
||||
.then((products) {
|
||||
waitForNextRequest = false;
|
||||
if (products.length == 0) {
|
||||
_shouldStopRequests = true;
|
||||
}
|
||||
_products.addAll(products.toList());
|
||||
setState(() {});
|
||||
});
|
||||
});
|
||||
|
||||
_fetchMoreProducts();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
_fetchProductsForCategory() {
|
||||
WooSignal.getInstance(config: wsConfig).then((wcStore) {
|
||||
wcStore
|
||||
.getProducts(category: _selectedCategory.id.toString(), perPage: 50)
|
||||
.then((products) {
|
||||
_products = products;
|
||||
setState(() {
|
||||
_isLoading = false;
|
||||
});
|
||||
});
|
||||
_fetchMoreProducts() async {
|
||||
waitForNextRequest = true;
|
||||
List<WS.Product> products = await appWooSignal((api) {
|
||||
return api.getProducts(perPage: 50, page: _page, status: "publish");
|
||||
});
|
||||
_products.addAll(products);
|
||||
waitForNextRequest = false;
|
||||
_page = _page + 1;
|
||||
|
||||
waitForNextRequest = false;
|
||||
if (products.length == 0) {
|
||||
_shouldStopRequests = true;
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
void didChangeDependencies() {
|
||||
super.didChangeDependencies();
|
||||
if (_isLoading) {
|
||||
_selectedCategory = ModalRoute.of(context).settings.arguments;
|
||||
_fetchProductsForCategory();
|
||||
}
|
||||
_fetchProductsForCategory() async {
|
||||
_products = await appWooSignal((api) {
|
||||
return api.getProducts(
|
||||
category: _selectedCategory.id.toString(), perPage: 50);
|
||||
});
|
||||
setState(() {
|
||||
_isLoading = false;
|
||||
});
|
||||
}
|
||||
|
||||
@override
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
// Label StoreMAX
|
||||
//
|
||||
// Created by Anthony Gordon.
|
||||
// Copyright © 2019 WooSignal. All rights reserved.
|
||||
// Copyright © 2020 WooSignal. All rights reserved.
|
||||
//
|
||||
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
@ -10,19 +10,20 @@
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:label_storemax/helpers/tools.dart';
|
||||
import 'package:label_storemax/widgets/app_loader.dart';
|
||||
import 'package:woosignal/models/response/products.dart' as WS;
|
||||
import 'package:woosignal/woosignal.dart';
|
||||
import 'package:label_storemax/widgets/woosignal_ui.dart';
|
||||
|
||||
class BrowseSearchPage extends StatefulWidget {
|
||||
BrowseSearchPage();
|
||||
final String search;
|
||||
BrowseSearchPage({Key key, @required this.search}) : super(key: key);
|
||||
|
||||
@override
|
||||
_BrowseSearchState createState() => _BrowseSearchState();
|
||||
_BrowseSearchState createState() => _BrowseSearchState(search);
|
||||
}
|
||||
|
||||
class _BrowseSearchState extends State<BrowseSearchPage> {
|
||||
_BrowseSearchState();
|
||||
_BrowseSearchState(this._search);
|
||||
|
||||
var _productsController = ScrollController();
|
||||
List<WS.Product> _products = [];
|
||||
@ -41,6 +42,11 @@ class _BrowseSearchState extends State<BrowseSearchPage> {
|
||||
_shouldStopRequests = false;
|
||||
waitForNextRequest = false;
|
||||
|
||||
_fetchProductsForSearch(_page);
|
||||
_addScrollListener();
|
||||
}
|
||||
|
||||
_addScrollListener() async {
|
||||
_productsController.addListener(() {
|
||||
double maxScroll = _productsController.position.maxScrollExtent;
|
||||
double currentScroll = _productsController.position.pixels;
|
||||
@ -57,33 +63,20 @@ class _BrowseSearchState extends State<BrowseSearchPage> {
|
||||
});
|
||||
}
|
||||
|
||||
_fetchProductsForSearch(int page) {
|
||||
WooSignal.getInstance(config: wsConfig).then((wcStore) {
|
||||
waitForNextRequest = true;
|
||||
_fetchProductsForSearch(int page) async {
|
||||
waitForNextRequest = true;
|
||||
List<WS.Product> products = await appWooSignal((api) {
|
||||
_page = _page + 1;
|
||||
wcStore
|
||||
.getProducts(
|
||||
search: _search, perPage: 100, page: page, status: "publish")
|
||||
.then((products) {
|
||||
waitForNextRequest = false;
|
||||
if (products.length == 0) {
|
||||
_shouldStopRequests = true;
|
||||
}
|
||||
_products.addAll(products.toList());
|
||||
setState(() {
|
||||
_isLoading = false;
|
||||
});
|
||||
});
|
||||
return api.getProducts(
|
||||
search: _search, perPage: 100, page: page, status: "publish");
|
||||
});
|
||||
}
|
||||
|
||||
@override
|
||||
void didChangeDependencies() {
|
||||
super.didChangeDependencies();
|
||||
if (_isLoading) {
|
||||
_search = ModalRoute.of(context).settings.arguments;
|
||||
_fetchProductsForSearch(_page);
|
||||
if (products.length == 0) {
|
||||
_shouldStopRequests = true;
|
||||
}
|
||||
setState(() {
|
||||
_products.addAll(products.toList());
|
||||
_isLoading = false;
|
||||
});
|
||||
}
|
||||
|
||||
@override
|
||||
@ -122,10 +115,14 @@ class _BrowseSearchState extends State<BrowseSearchPage> {
|
||||
? GridView.count(
|
||||
crossAxisCount: 2,
|
||||
controller: _productsController,
|
||||
children: List.generate(_products.length, (index) {
|
||||
return wsCardProductItem(context,
|
||||
index: index, product: _products[index]);
|
||||
}))
|
||||
children: List.generate(
|
||||
_products.length,
|
||||
(index) {
|
||||
return wsCardProductItem(context,
|
||||
index: index, product: _products[index]);
|
||||
},
|
||||
),
|
||||
)
|
||||
: wsNoResults(context)),
|
||||
flex: 1,
|
||||
),
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
// Label StoreMAX
|
||||
//
|
||||
// Created by Anthony Gordon.
|
||||
// Copyright © 2019 WooSignal. All rights reserved.
|
||||
// Copyright © 2020 WooSignal. All rights reserved.
|
||||
//
|
||||
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
@ -11,8 +11,13 @@
|
||||
import 'package:flutter/cupertino.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:label_storemax/helpers/tools.dart';
|
||||
import 'package:label_storemax/models/cart.dart';
|
||||
import 'package:label_storemax/models/cart_line_item.dart';
|
||||
import 'package:label_storemax/models/checkout_session.dart';
|
||||
import 'package:label_storemax/models/customer_address.dart';
|
||||
import 'package:label_storemax/widgets/app_loader.dart';
|
||||
import 'package:label_storemax/widgets/buttons.dart';
|
||||
import 'package:label_storemax/widgets/woosignal_ui.dart';
|
||||
import 'package:woosignal/woosignal.dart';
|
||||
|
||||
class CartPage extends StatefulWidget {
|
||||
CartPage();
|
||||
@ -45,10 +50,12 @@ class _CartPageState extends State<CartPage> {
|
||||
});
|
||||
return [];
|
||||
}
|
||||
WooSignal wooSignal = await WooSignal.getInstance(config: wsConfig);
|
||||
|
||||
List<Map<String, dynamic>> cartJSON = cart.map((c) => c.toJson()).toList();
|
||||
|
||||
List<dynamic> cartRes = await wooSignal.cartCheck(cartJSON);
|
||||
List<dynamic> cartRes = await appWooSignal((api) {
|
||||
return api.cartCheck(cartJSON);
|
||||
});
|
||||
_cartLines = cartRes.map((json) => CartLineItem.fromJson(json)).toList();
|
||||
if (_cartLines.length > 0) {
|
||||
Cart.getInstance.saveCartToPref(cartLineItems: _cartLines);
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
// Label StoreMAX
|
||||
//
|
||||
// Created by Anthony Gordon.
|
||||
// Copyright © 2019 WooSignal. All rights reserved.
|
||||
// Copyright © 2020 WooSignal. All rights reserved.
|
||||
//
|
||||
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
@ -9,27 +9,28 @@
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:label_storemax/app_payment_methods.dart';
|
||||
import 'package:label_storemax/helpers/tools.dart';
|
||||
import 'package:label_storemax/labelconfig.dart';
|
||||
import 'package:label_storemax/models/checkout_session.dart';
|
||||
import 'package:label_storemax/models/customer_address.dart';
|
||||
import 'package:label_storemax/widgets/app_loader.dart';
|
||||
import 'package:label_storemax/widgets/buttons.dart';
|
||||
import 'package:label_storemax/widgets/woosignal_ui.dart';
|
||||
import 'package:woosignal/models/response/tax_rate.dart';
|
||||
import 'package:woosignal_stripe/woosignal_stripe.dart';
|
||||
import 'package:woosignal/models/payload/order_wc.dart';
|
||||
import 'package:woosignal/models/response/order.dart' as WS;
|
||||
import 'package:woosignal/woosignal.dart';
|
||||
import 'dart:io';
|
||||
import 'package:label_storemax/app_country_options.dart';
|
||||
|
||||
class CheckoutConfirmationPage extends StatefulWidget {
|
||||
CheckoutConfirmationPage();
|
||||
CheckoutConfirmationPage({Key key}) : super(key: key);
|
||||
|
||||
@override
|
||||
_CheckoutConfirmationPageState createState() =>
|
||||
_CheckoutConfirmationPageState();
|
||||
CheckoutConfirmationPageState createState() =>
|
||||
CheckoutConfirmationPageState();
|
||||
}
|
||||
|
||||
class _CheckoutConfirmationPageState extends State<CheckoutConfirmationPage> {
|
||||
_CheckoutConfirmationPageState();
|
||||
class CheckoutConfirmationPageState extends State<CheckoutConfirmationPage> {
|
||||
CheckoutConfirmationPageState();
|
||||
|
||||
GlobalKey<CheckoutConfirmationPageState> _key = GlobalKey<CheckoutConfirmationPageState>();
|
||||
|
||||
bool _showFullLoader;
|
||||
|
||||
@ -48,9 +49,17 @@ class _CheckoutConfirmationPageState extends State<CheckoutConfirmationPage> {
|
||||
_getTaxes();
|
||||
}
|
||||
|
||||
void reloadState({bool showLoader}) {
|
||||
setState(() {
|
||||
_showFullLoader = showLoader ?? false;
|
||||
});
|
||||
}
|
||||
|
||||
_getTaxes() async {
|
||||
WooSignal wooSignal = await WooSignal.getInstance(config: wsConfig);
|
||||
_taxRates = await wooSignal.getTaxRates(page: 1, perPage: 100);
|
||||
_taxRates = await appWooSignal((api) {
|
||||
return api.getTaxRates(page: 1, perPage: 100);
|
||||
});
|
||||
|
||||
if (CheckoutSession.getInstance.billingDetails.shippingAddress == null) {
|
||||
setState(() {
|
||||
_showFullLoader = false;
|
||||
@ -150,7 +159,8 @@ class _CheckoutConfirmationPageState extends State<CheckoutConfirmationPage> {
|
||||
30,
|
||||
CheckoutSession.getInstance
|
||||
.billingDetails.billingAddress
|
||||
.addressFull())),
|
||||
.addressFull(),
|
||||
)),
|
||||
action: _actionCheckoutDetails,
|
||||
showBorderBottom: true)
|
||||
: wsCheckoutRow(context,
|
||||
@ -170,7 +180,7 @@ class _CheckoutConfirmationPageState extends State<CheckoutConfirmationPage> {
|
||||
.paymentType.assetImage),
|
||||
width: 70),
|
||||
leadTitle: CheckoutSession
|
||||
.getInstance.paymentType.name,
|
||||
.getInstance.paymentType.desc,
|
||||
action: _actionPayWith,
|
||||
showBorderBottom: true)
|
||||
: wsCheckoutRow(context,
|
||||
@ -236,8 +246,13 @@ class _CheckoutConfirmationPageState extends State<CheckoutConfirmationPage> {
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: <Widget>[
|
||||
showAppLoader(),
|
||||
Text(trans(context, "One moment") + "...",
|
||||
style: Theme.of(context).primaryTextTheme.subhead)
|
||||
Padding(
|
||||
padding: const EdgeInsets.only(top: 15),
|
||||
child: Text(
|
||||
trans(context, "One moment") + "...",
|
||||
style: Theme.of(context).primaryTextTheme.subhead,
|
||||
),
|
||||
)
|
||||
],
|
||||
),
|
||||
),
|
||||
@ -284,168 +299,7 @@ class _CheckoutConfirmationPageState extends State<CheckoutConfirmationPage> {
|
||||
return;
|
||||
}
|
||||
|
||||
_pay();
|
||||
}
|
||||
|
||||
Future<OrderWC> _buildOrderWC() async {
|
||||
OrderWC orderWC = OrderWC();
|
||||
if (Platform.isAndroid) {
|
||||
orderWC.paymentMethod = "Stripe - Android App";
|
||||
orderWC.paymentMethodTitle = "stripe";
|
||||
} else if (Platform.isIOS) {
|
||||
orderWC.paymentMethod = "Stripe - IOS App";
|
||||
orderWC.paymentMethodTitle = "stripe";
|
||||
}
|
||||
|
||||
orderWC.setPaid = true;
|
||||
orderWC.status = "pending";
|
||||
orderWC.currency = app_currency_iso.toUpperCase();
|
||||
|
||||
List<LineItems> lineItems = [];
|
||||
List<CartLineItem> cartItems = await Cart.getInstance.getCart();
|
||||
cartItems.forEach((cartItem) {
|
||||
LineItems tmpLineItem = LineItems();
|
||||
tmpLineItem.quantity = cartItem.quantity;
|
||||
tmpLineItem.name = cartItem.name;
|
||||
tmpLineItem.productId = cartItem.productId;
|
||||
if (cartItem.variationId != null && cartItem.variationId != 0) {
|
||||
tmpLineItem.variationId = cartItem.variationId;
|
||||
}
|
||||
|
||||
tmpLineItem.total = cartItem.total;
|
||||
tmpLineItem.subtotal = cartItem.subtotal;
|
||||
|
||||
lineItems.add(tmpLineItem);
|
||||
});
|
||||
|
||||
orderWC.lineItems = lineItems;
|
||||
|
||||
BillingDetails billingDetails = CheckoutSession.getInstance.billingDetails;
|
||||
|
||||
Billing billing = Billing();
|
||||
billing.firstName = billingDetails.billingAddress.firstName;
|
||||
billing.lastName = billingDetails.billingAddress.lastName;
|
||||
billing.address1 = billingDetails.billingAddress.addressLine;
|
||||
billing.city = billingDetails.billingAddress.city;
|
||||
billing.postcode = billingDetails.billingAddress.postalCode;
|
||||
billing.country = billingDetails.billingAddress.country;
|
||||
billing.email = billingDetails.billingAddress.emailAddress;
|
||||
|
||||
orderWC.billing = billing;
|
||||
|
||||
Shipping shipping = Shipping();
|
||||
shipping.firstName = billingDetails.shippingAddress.firstName;
|
||||
shipping.lastName = billingDetails.shippingAddress.lastName;
|
||||
shipping.address1 = billingDetails.shippingAddress.addressLine;
|
||||
shipping.city = billingDetails.shippingAddress.city;
|
||||
shipping.postcode = billingDetails.shippingAddress.postalCode;
|
||||
shipping.country = billingDetails.shippingAddress.country;
|
||||
|
||||
orderWC.shipping = shipping;
|
||||
|
||||
orderWC.shippingLines = [];
|
||||
Map<String, dynamic> shippingLineFeeObj =
|
||||
CheckoutSession.getInstance.shippingType.toShippingLineFee();
|
||||
if (shippingLineFeeObj != null) {
|
||||
ShippingLines shippingLine = ShippingLines();
|
||||
shippingLine.methodId = shippingLineFeeObj['method_id'];
|
||||
shippingLine.methodTitle = shippingLineFeeObj['method_title'];
|
||||
shippingLine.total = shippingLineFeeObj['total'];
|
||||
orderWC.shippingLines.add(shippingLine);
|
||||
}
|
||||
|
||||
if (_taxRate != null) {
|
||||
orderWC.feeLines = [];
|
||||
FeeLines feeLines = FeeLines();
|
||||
feeLines.name = _taxRate.name;
|
||||
feeLines.total = await Cart.getInstance.taxAmount(_taxRate);
|
||||
feeLines.taxClass = "";
|
||||
feeLines.taxStatus = "taxable";
|
||||
orderWC.feeLines.add(feeLines);
|
||||
}
|
||||
|
||||
return orderWC;
|
||||
}
|
||||
|
||||
_pay() async {
|
||||
WooSignal wsStore = await WooSignal.getInstance(config: wsConfig);
|
||||
|
||||
String cartTotal = await CheckoutSession.getInstance
|
||||
.total(withFormat: false, taxRate: _taxRate);
|
||||
|
||||
FlutterStripePayment.setStripeSettings(
|
||||
stripeAccount: app_stripe_account, liveMode: app_stripe_live_mode);
|
||||
|
||||
var paymentResponse = await FlutterStripePayment.addPaymentMethod();
|
||||
|
||||
if (paymentResponse.status == PaymentResponseStatus.succeeded) {
|
||||
setState(() {
|
||||
_showFullLoader = true;
|
||||
});
|
||||
|
||||
BillingDetails checkoutDetails =
|
||||
CheckoutSession.getInstance.billingDetails;
|
||||
|
||||
Map<String, dynamic> address = {
|
||||
"name": checkoutDetails.billingAddress.nameFull(),
|
||||
"line1": checkoutDetails.shippingAddress.addressLine,
|
||||
"city": checkoutDetails.shippingAddress.city,
|
||||
"postal_code": checkoutDetails.shippingAddress.postalCode,
|
||||
"country": checkoutDetails.shippingAddress.country
|
||||
};
|
||||
|
||||
String cartShortDesc = await Cart.getInstance.cartShortDesc();
|
||||
|
||||
dynamic rsp = await wsStore.stripePaymentIntent(
|
||||
amount: cartTotal,
|
||||
email: checkoutDetails.billingAddress.emailAddress,
|
||||
desc: cartShortDesc,
|
||||
shipping: address);
|
||||
|
||||
if (rsp == null) {
|
||||
showToastNetworkError();
|
||||
setState(() {
|
||||
_showFullLoader = false;
|
||||
});
|
||||
return false;
|
||||
}
|
||||
|
||||
String clientSecret = rsp["client_secret"];
|
||||
var intentResponse = await FlutterStripePayment.confirmPaymentIntent(
|
||||
clientSecret,
|
||||
paymentResponse.paymentMethodId,
|
||||
(double.parse(cartTotal) * 100));
|
||||
|
||||
if (intentResponse.status == PaymentResponseStatus.succeeded) {
|
||||
OrderWC orderWC = await _buildOrderWC();
|
||||
WS.Order order = await wsStore.createOrder(orderWC);
|
||||
|
||||
if (order != null) {
|
||||
Cart.getInstance.clear();
|
||||
Navigator.pushNamed(context, "/checkout-status", arguments: order);
|
||||
} else {
|
||||
showEdgeAlertWith(context,
|
||||
title: trans(context, "Error"),
|
||||
desc: trans(
|
||||
context, "Something went wrong, please contact our store"));
|
||||
setState(() {
|
||||
_showFullLoader = false;
|
||||
});
|
||||
}
|
||||
} else if (intentResponse.status == PaymentResponseStatus.failed) {
|
||||
if (app_debug) {
|
||||
print(intentResponse.errorMessage);
|
||||
}
|
||||
showEdgeAlertWith(context,
|
||||
title: trans(context, "Error"), desc: intentResponse.errorMessage);
|
||||
setState(() {
|
||||
_showFullLoader = false;
|
||||
});
|
||||
} else {
|
||||
setState(() {
|
||||
_showFullLoader = false;
|
||||
});
|
||||
}
|
||||
}
|
||||
CheckoutSession.getInstance.paymentType
|
||||
.pay(context, state: this, taxRate: _taxRate);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
// Label StoreMAX
|
||||
//
|
||||
// Created by Anthony Gordon.
|
||||
// Copyright © 2019 WooSignal. All rights reserved.
|
||||
// Copyright © 2020 WooSignal. All rights reserved.
|
||||
//
|
||||
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
@ -10,6 +10,10 @@
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:label_storemax/helpers/tools.dart';
|
||||
import 'package:label_storemax/models/billing_details.dart';
|
||||
import 'package:label_storemax/models/checkout_session.dart';
|
||||
import 'package:label_storemax/models/customer_address.dart';
|
||||
import 'package:label_storemax/widgets/buttons.dart';
|
||||
import 'package:label_storemax/widgets/woosignal_ui.dart';
|
||||
import 'package:label_storemax/app_country_options.dart';
|
||||
|
||||
@ -82,27 +86,34 @@ class _CheckoutDetailsPageState extends State<CheckoutDetailsPage> {
|
||||
wsModalBottom(context,
|
||||
title: trans(context, "Select a country"),
|
||||
bodyWidget: Expanded(
|
||||
child: ListView.builder(
|
||||
itemCount: appCountryOptions.length,
|
||||
itemBuilder: (BuildContext context, int index) {
|
||||
Map<String, String> strName = appCountryOptions[index];
|
||||
child: ListView.separated(
|
||||
itemCount: appCountryOptions.length,
|
||||
itemBuilder: (BuildContext context, int index) {
|
||||
Map<String, String> strName = appCountryOptions[index];
|
||||
|
||||
return InkWell(
|
||||
child: Container(
|
||||
child: Text(strName["name"],
|
||||
style: Theme.of(context).primaryTextTheme.body2),
|
||||
padding: EdgeInsets.only(top: 25, bottom: 25),
|
||||
),
|
||||
splashColor: Colors.grey,
|
||||
highlightColor: Colors.black12,
|
||||
onTap: () {
|
||||
setState(() {
|
||||
_strBillingCountry = strName["name"];
|
||||
Navigator.of(context).pop();
|
||||
});
|
||||
},
|
||||
);
|
||||
}),
|
||||
return InkWell(
|
||||
child: Container(
|
||||
child: Text(strName["name"],
|
||||
style: Theme.of(context).primaryTextTheme.body2),
|
||||
padding: EdgeInsets.only(top: 25, bottom: 25),
|
||||
),
|
||||
splashColor: Colors.grey,
|
||||
highlightColor: Colors.black12,
|
||||
onTap: () {
|
||||
setState(() {
|
||||
_strBillingCountry = strName["name"];
|
||||
Navigator.of(context).pop();
|
||||
});
|
||||
},
|
||||
);
|
||||
},
|
||||
separatorBuilder: (cxt, i) {
|
||||
return Divider(
|
||||
height: 0,
|
||||
color: Colors.black12,
|
||||
);
|
||||
},
|
||||
),
|
||||
));
|
||||
}
|
||||
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
// Label StoreMAX
|
||||
//
|
||||
// Created by Anthony Gordon.
|
||||
// Copyright © 2019 WooSignal. All rights reserved.
|
||||
// Copyright © 2020 WooSignal. All rights reserved.
|
||||
//
|
||||
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
@ -10,6 +10,8 @@
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:label_storemax/helpers/tools.dart';
|
||||
import 'package:label_storemax/models/checkout_session.dart';
|
||||
import 'package:label_storemax/widgets/buttons.dart';
|
||||
import 'package:label_storemax/widgets/woosignal_ui.dart';
|
||||
|
||||
class CheckoutPaymentTypePage extends StatefulWidget {
|
||||
@ -26,6 +28,12 @@ class _CheckoutPaymentTypePageState extends State<CheckoutPaymentTypePage> {
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
|
||||
if (CheckoutSession.getInstance.paymentType == null) {
|
||||
if (getPaymentTypes() != null && getPaymentTypes().length > 0) {
|
||||
CheckoutSession.getInstance.paymentType = getPaymentTypes().first;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
@ -78,12 +86,16 @@ class _CheckoutPaymentTypePageState extends State<CheckoutPaymentTypePage> {
|
||||
width: 60,
|
||||
fit: BoxFit.fitHeight,
|
||||
alignment: Alignment.center),
|
||||
title: Text(getPaymentTypes()[index].name,
|
||||
title: Text(getPaymentTypes()[index].desc,
|
||||
style: Theme.of(context)
|
||||
.primaryTextTheme
|
||||
.subhead),
|
||||
selected: true,
|
||||
trailing: Icon(Icons.check),
|
||||
trailing: (CheckoutSession
|
||||
.getInstance.paymentType ==
|
||||
getPaymentTypes()[index]
|
||||
? Icon(Icons.check)
|
||||
: null),
|
||||
onTap: () {
|
||||
CheckoutSession.getInstance.paymentType =
|
||||
getPaymentTypes()[index];
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
// Label StoreMAX
|
||||
//
|
||||
// Created by Anthony Gordon.
|
||||
// Copyright © 2019 WooSignal. All rights reserved.
|
||||
// Copyright © 2020 WooSignal. All rights reserved.
|
||||
//
|
||||
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
@ -10,9 +10,14 @@
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:label_storemax/helpers/tools.dart';
|
||||
import 'package:label_storemax/models/cart.dart';
|
||||
import 'package:label_storemax/models/cart_line_item.dart';
|
||||
import 'package:label_storemax/models/checkout_session.dart';
|
||||
import 'package:label_storemax/models/customer_address.dart';
|
||||
import 'package:label_storemax/models/shipping_type.dart';
|
||||
import 'package:label_storemax/widgets/app_loader.dart';
|
||||
import 'package:label_storemax/widgets/buttons.dart';
|
||||
import 'package:woosignal/models/response/shipping_method.dart';
|
||||
import 'package:label_storemax/widgets/woosignal_ui.dart';
|
||||
import 'package:woosignal/woosignal.dart';
|
||||
import 'package:label_storemax/app_country_options.dart';
|
||||
|
||||
class CheckoutShippingTypePage extends StatefulWidget {
|
||||
@ -43,8 +48,9 @@ class _CheckoutShippingTypePageState extends State<CheckoutShippingTypePage> {
|
||||
}
|
||||
|
||||
_getShippingMethods() async {
|
||||
WooSignal wooSignal = await WooSignal.getInstance(config: wsConfig);
|
||||
List<WSShipping> wsShipping = await wooSignal.getShippingMethods();
|
||||
List<WSShipping> wsShipping = await appWooSignal((api) {
|
||||
return api.getShippingMethods();
|
||||
});
|
||||
CustomerAddress customerAddress =
|
||||
CheckoutSession.getInstance.billingDetails.shippingAddress;
|
||||
String postalCode = customerAddress.postalCode;
|
||||
@ -96,7 +102,7 @@ class _CheckoutShippingTypePageState extends State<CheckoutShippingTypePage> {
|
||||
|
||||
if (_shipping.methods.freeShipping != null) {
|
||||
_shipping.methods.freeShipping.forEach((freeShipping) {
|
||||
if (_isNumeric(freeShipping.cost)) {
|
||||
if (isNumeric(freeShipping.cost)) {
|
||||
Map<String, dynamic> tmpShippingOption = {};
|
||||
tmpShippingOption = {
|
||||
"id": freeShipping.id,
|
||||
@ -120,13 +126,6 @@ class _CheckoutShippingTypePageState extends State<CheckoutShippingTypePage> {
|
||||
});
|
||||
}
|
||||
|
||||
bool _isNumeric(String str) {
|
||||
if(str == null) {
|
||||
return false;
|
||||
}
|
||||
return double.tryParse(str) != null;
|
||||
}
|
||||
|
||||
Future<String> _getShippingPrice(int index) async {
|
||||
double total = 0;
|
||||
List<CartLineItem> cartLineItem = await Cart.getInstance.getCart();
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
// Label StoreMAX
|
||||
//
|
||||
// Created by Anthony Gordon.
|
||||
// Copyright © 2019 WooSignal. All rights reserved.
|
||||
// Copyright © 2020 WooSignal. All rights reserved.
|
||||
//
|
||||
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
@ -10,19 +10,21 @@
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:label_storemax/helpers/tools.dart';
|
||||
import 'package:label_storemax/labelconfig.dart';
|
||||
import 'package:woosignal/models/response/products.dart' as WS;
|
||||
import 'package:woosignal/models/response/order.dart' as WS;
|
||||
|
||||
import '../widgets/woosignal_ui.dart';
|
||||
|
||||
class CheckoutStatusPage extends StatefulWidget {
|
||||
CheckoutStatusPage();
|
||||
final WS.Order order;
|
||||
CheckoutStatusPage({Key key, @required this.order}) : super(key: key);
|
||||
|
||||
@override
|
||||
_CheckoutStatusState createState() => _CheckoutStatusState();
|
||||
_CheckoutStatusState createState() => _CheckoutStatusState(this.order);
|
||||
}
|
||||
|
||||
class _CheckoutStatusState extends State<CheckoutStatusPage> {
|
||||
_CheckoutStatusState();
|
||||
_CheckoutStatusState(this._order);
|
||||
|
||||
WS.Order _order;
|
||||
|
||||
@ -31,19 +33,13 @@ class _CheckoutStatusState extends State<CheckoutStatusPage> {
|
||||
super.initState();
|
||||
}
|
||||
|
||||
@override
|
||||
void didChangeDependencies() {
|
||||
super.didChangeDependencies();
|
||||
_order = ModalRoute.of(context).settings.arguments;
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Scaffold(
|
||||
appBar: AppBar(
|
||||
backgroundColor: Colors.white,
|
||||
elevation: 0.0,
|
||||
title: Image.network(app_logo_url, height: 100),
|
||||
title: storeLogo(height: 60),
|
||||
automaticallyImplyLeading: false,
|
||||
centerTitle: true,
|
||||
),
|
||||
|
||||
62
LabelStoreMax/lib/pages/error_page.dart
Normal file
62
LabelStoreMax/lib/pages/error_page.dart
Normal file
@ -0,0 +1,62 @@
|
||||
// Label StoreMAX
|
||||
//
|
||||
// Created by Anthony Gordon.
|
||||
// Copyright © 2020 WooSignal. All rights reserved.
|
||||
//
|
||||
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:label_storemax/helpers/tools.dart';
|
||||
import 'package:label_storemax/widgets/buttons.dart';
|
||||
|
||||
class ErrorPage extends StatefulWidget {
|
||||
ErrorPage();
|
||||
|
||||
@override
|
||||
_ErrorPageState createState() => _ErrorPageState();
|
||||
}
|
||||
|
||||
class _ErrorPageState extends State<ErrorPage> {
|
||||
_ErrorPageState();
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Scaffold(
|
||||
body: SafeArea(
|
||||
minimum: safeAreaDefault(),
|
||||
child: Center(
|
||||
child: Column(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
crossAxisAlignment: CrossAxisAlignment.center,
|
||||
children: <Widget>[
|
||||
Icon(
|
||||
Icons.error_outline,
|
||||
size: 100,
|
||||
color: Colors.black54,
|
||||
),
|
||||
Padding(
|
||||
padding: const EdgeInsets.all(16.0),
|
||||
child: Text(
|
||||
trans(context, "Sorry, something went wrong"),
|
||||
style: Theme.of(context).primaryTextTheme.body1,
|
||||
textAlign: TextAlign.center,
|
||||
),
|
||||
),
|
||||
wsLinkButton(context, title: trans(context, "Back"), action: () {
|
||||
Navigator.pop(context);
|
||||
}),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
@ -1,7 +1,7 @@
|
||||
// Label StoreMAX
|
||||
//
|
||||
// Created by Anthony Gordon.
|
||||
// Copyright © 2019 WooSignal. All rights reserved.
|
||||
// Copyright © 2020 WooSignal. All rights reserved.
|
||||
//
|
||||
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
@ -10,9 +10,10 @@
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:label_storemax/helpers/tools.dart';
|
||||
import 'package:label_storemax/widgets/app_loader.dart';
|
||||
import 'package:label_storemax/widgets/cart_icon.dart';
|
||||
import 'package:woosignal/models/response/product_category.dart' as WS;
|
||||
import 'package:woosignal/models/response/products.dart' as WS;
|
||||
import 'package:woosignal/woosignal.dart';
|
||||
import 'package:label_storemax/widgets/woosignal_ui.dart';
|
||||
|
||||
class HomePage extends StatefulWidget {
|
||||
@ -42,9 +43,33 @@ class _HomePageState extends State<HomePage> {
|
||||
_isLoading = true;
|
||||
|
||||
_page = 1;
|
||||
_home();
|
||||
_addScrollListener();
|
||||
}
|
||||
|
||||
_home() async {
|
||||
await _fetchProducts();
|
||||
await _fetchCategories();
|
||||
_shouldStopRequests = false;
|
||||
waitForNextRequest = false;
|
||||
setState(() {
|
||||
_isLoading = false;
|
||||
});
|
||||
}
|
||||
|
||||
_fetchProducts() async {
|
||||
_products = await appWooSignal((api) {
|
||||
return api.getProducts(perPage: 50, page: _page, status: "publish");
|
||||
});
|
||||
}
|
||||
|
||||
_fetchCategories() async {
|
||||
_categories = await appWooSignal((api) {
|
||||
return api.getProductCategories();
|
||||
});
|
||||
}
|
||||
|
||||
_addScrollListener() async {
|
||||
_productsController.addListener(() {
|
||||
double maxScroll = _productsController.position.maxScrollExtent;
|
||||
double currentScroll = _productsController.position.pixels;
|
||||
@ -56,86 +81,75 @@ class _HomePageState extends State<HomePage> {
|
||||
if (waitForNextRequest) {
|
||||
return;
|
||||
}
|
||||
WooSignal.getInstance(config: wsConfig).then((wcStore) {
|
||||
waitForNextRequest = true;
|
||||
_page = _page + 1;
|
||||
wcStore
|
||||
.getProducts(perPage: 50, page: _page, status: "publish")
|
||||
.then((products) {
|
||||
waitForNextRequest = false;
|
||||
if (products.length == 0) {
|
||||
_shouldStopRequests = true;
|
||||
}
|
||||
_products.addAll(products.toList());
|
||||
setState(() {});
|
||||
});
|
||||
});
|
||||
_fetchMoreProducts();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
WooSignal.getInstance(config: wsConfig).then((wcStore) {
|
||||
wcStore
|
||||
.getProducts(perPage: 50, page: _page, status: "publish")
|
||||
.then((products) {
|
||||
_products = products;
|
||||
setState(() {
|
||||
_isLoading = false;
|
||||
});
|
||||
});
|
||||
|
||||
wcStore.getProductCategories().then((categories) {
|
||||
_categories = categories;
|
||||
setState(() {});
|
||||
});
|
||||
_fetchMoreProducts() async {
|
||||
waitForNextRequest = true;
|
||||
List<WS.Product> products = await appWooSignal((api) {
|
||||
_page = _page + 1;
|
||||
return api.getProducts(perPage: 50, page: _page, status: "publish");
|
||||
});
|
||||
if (products.length == 0) {
|
||||
_shouldStopRequests = true;
|
||||
}
|
||||
setState(() {
|
||||
_products.addAll(products.toList());
|
||||
});
|
||||
}
|
||||
|
||||
void _modalBottomSheetMenu() {
|
||||
showModalBottomSheet(
|
||||
context: context,
|
||||
backgroundColor: Colors.transparent,
|
||||
builder: (builder) {
|
||||
return new Container(
|
||||
height: double.infinity,
|
||||
width: double.infinity - 10,
|
||||
color: Colors.transparent,
|
||||
child: new Container(
|
||||
padding: EdgeInsets.only(top: 25, left: 18, right: 18),
|
||||
decoration: new BoxDecoration(
|
||||
color: Colors.white,
|
||||
borderRadius: new BorderRadius.only(
|
||||
topLeft: const Radius.circular(10.0),
|
||||
topRight: const Radius.circular(10.0))),
|
||||
child: Column(
|
||||
children: <Widget>[
|
||||
Text(trans(context, "Categories"),
|
||||
style: Theme.of(context).primaryTextTheme.display1,
|
||||
textAlign: TextAlign.left),
|
||||
Expanded(
|
||||
child: new ListView.builder(
|
||||
itemCount: _categories.length,
|
||||
itemBuilder: (BuildContext context, int index) {
|
||||
return InkWell(
|
||||
child: Container(
|
||||
child: Text(_categories[index].name),
|
||||
padding: EdgeInsets.all(15),
|
||||
decoration: BoxDecoration(
|
||||
border: Border(
|
||||
bottom: BorderSide(
|
||||
color: HexColor("#f2f2f2"),
|
||||
width: 2))),
|
||||
),
|
||||
onTap: () {
|
||||
Navigator.pushNamed(context, "/browse-category",
|
||||
arguments: _categories[index]);
|
||||
},
|
||||
);
|
||||
}))
|
||||
],
|
||||
),
|
||||
context: context,
|
||||
backgroundColor: Colors.transparent,
|
||||
builder: (builder) {
|
||||
return new Container(
|
||||
height: double.infinity,
|
||||
width: double.infinity - 10,
|
||||
color: Colors.transparent,
|
||||
child: new Container(
|
||||
padding: EdgeInsets.only(top: 25, left: 18, right: 18),
|
||||
decoration: new BoxDecoration(
|
||||
color: Colors.white,
|
||||
borderRadius: new BorderRadius.only(
|
||||
topLeft: const Radius.circular(10.0),
|
||||
topRight: const Radius.circular(10.0)),
|
||||
),
|
||||
);
|
||||
});
|
||||
child: Column(
|
||||
children: <Widget>[
|
||||
Text(trans(context, "Categories"),
|
||||
style: Theme.of(context).primaryTextTheme.display1,
|
||||
textAlign: TextAlign.left),
|
||||
Expanded(
|
||||
child: new ListView.builder(
|
||||
itemCount: _categories.length,
|
||||
itemBuilder: (BuildContext context, int index) {
|
||||
return InkWell(
|
||||
child: Container(
|
||||
child: Text(_categories[index].name),
|
||||
padding: EdgeInsets.all(15),
|
||||
decoration: BoxDecoration(
|
||||
border: Border(
|
||||
bottom: BorderSide(
|
||||
color: HexColor("#f2f2f2"), width: 2),
|
||||
),
|
||||
),
|
||||
),
|
||||
onTap: () {
|
||||
Navigator.pushNamed(context, "/browse-category",
|
||||
arguments: _categories[index]);
|
||||
},
|
||||
);
|
||||
}),
|
||||
)
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
@ -207,12 +221,13 @@ class _HomePageState extends State<HomePage> {
|
||||
? Expanded(child: showAppLoader())
|
||||
: Expanded(
|
||||
child: GridView.count(
|
||||
controller: _productsController,
|
||||
crossAxisCount: 2,
|
||||
children: List.generate(_products.length, (index) {
|
||||
return wsCardProductItem(context,
|
||||
index: index, product: _products[index]);
|
||||
})),
|
||||
controller: _productsController,
|
||||
crossAxisCount: 2,
|
||||
children: List.generate(_products.length, (index) {
|
||||
return wsCardProductItem(context,
|
||||
index: index, product: _products[index]);
|
||||
}),
|
||||
),
|
||||
flex: 1,
|
||||
)),
|
||||
],
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
// Label StoreMAX
|
||||
//
|
||||
// Created by Anthony Gordon.
|
||||
// Copyright © 2019 WooSignal. All rights reserved.
|
||||
// Copyright © 2020 WooSignal. All rights reserved.
|
||||
//
|
||||
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
@ -9,10 +9,11 @@
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:label_storemax/labelconfig.dart';
|
||||
import 'package:label_storemax/widgets/woosignal_ui.dart';
|
||||
import 'package:label_storemax/widgets/menu_item.dart';
|
||||
import 'package:label_storemax/helpers/tools.dart';
|
||||
|
||||
import '../widgets/woosignal_ui.dart';
|
||||
|
||||
class HomeMenuPage extends StatefulWidget {
|
||||
HomeMenuPage();
|
||||
|
||||
@ -50,7 +51,7 @@ class _HomeMenuPageState extends State<HomeMenuPage> {
|
||||
mainAxisAlignment: MainAxisAlignment.start,
|
||||
crossAxisAlignment: CrossAxisAlignment.center,
|
||||
children: <Widget>[
|
||||
Image.network(app_logo_url, height: 100),
|
||||
storeLogo(height: 100),
|
||||
Expanded(
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.center,
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
// Label StoreMAX
|
||||
//
|
||||
// Created by Anthony Gordon.
|
||||
// Copyright © 2019 WooSignal. All rights reserved.
|
||||
// Copyright © 2020 WooSignal. All rights reserved.
|
||||
//
|
||||
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
@ -10,8 +10,9 @@
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:label_storemax/helpers/tools.dart';
|
||||
import 'package:label_storemax/labelconfig.dart';
|
||||
import 'package:label_storemax/widgets/woosignal_ui.dart';
|
||||
import 'package:label_storemax/widgets/buttons.dart';
|
||||
|
||||
import '../widgets/woosignal_ui.dart';
|
||||
|
||||
class HomeSearchPage extends StatefulWidget {
|
||||
HomeSearchPage();
|
||||
@ -45,8 +46,7 @@ class _HomeSearchPageState extends State<HomeSearchPage> {
|
||||
return Scaffold(
|
||||
appBar: AppBar(
|
||||
backgroundColor: Colors.transparent,
|
||||
title: Image.network(app_logo_url,
|
||||
height: 60, alignment: Alignment.center),
|
||||
title: storeLogo(height: 60),
|
||||
centerTitle: true,
|
||||
),
|
||||
body: SafeArea(
|
||||
@ -60,14 +60,21 @@ class _HomeSearchPageState extends State<HomeSearchPage> {
|
||||
margin: EdgeInsets.only(bottom: 20),
|
||||
),
|
||||
TextField(
|
||||
controller: _txtSearchController,
|
||||
style: Theme.of(context).primaryTextTheme.display2,
|
||||
keyboardType: TextInputType.text,
|
||||
autocorrect: false,
|
||||
autofocus: true,
|
||||
textCapitalization: TextCapitalization.sentences),
|
||||
wsPrimaryButton(context,
|
||||
title: trans(context, "Search"), action: _actionSearch)
|
||||
controller: _txtSearchController,
|
||||
style: Theme.of(context).primaryTextTheme.display2,
|
||||
keyboardType: TextInputType.text,
|
||||
autocorrect: false,
|
||||
autofocus: true,
|
||||
textCapitalization: TextCapitalization.sentences,
|
||||
),
|
||||
Padding(
|
||||
padding: const EdgeInsets.only(top: 10),
|
||||
child: wsPrimaryButton(
|
||||
context,
|
||||
title: trans(context, "Search"),
|
||||
action: _actionSearch,
|
||||
),
|
||||
)
|
||||
],
|
||||
),
|
||||
),
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
// Label StoreMAX
|
||||
//
|
||||
// Created by Anthony Gordon.
|
||||
// Copyright © 2019 WooSignal. All rights reserved.
|
||||
// Copyright © 2020 WooSignal. All rights reserved.
|
||||
//
|
||||
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
@ -9,27 +9,53 @@
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/painting.dart';
|
||||
import 'package:label_storemax/helpers/tools.dart';
|
||||
import 'package:label_storemax/labelconfig.dart';
|
||||
import 'package:label_storemax/models/cart.dart';
|
||||
import 'package:label_storemax/models/cart_line_item.dart';
|
||||
import 'package:label_storemax/widgets/app_loader.dart';
|
||||
import 'package:label_storemax/widgets/buttons.dart';
|
||||
import 'package:label_storemax/widgets/cart_icon.dart';
|
||||
import 'package:woosignal/models/response/product_variation.dart' as WS;
|
||||
import 'package:woosignal/models/response/products.dart' as WS;
|
||||
import 'package:woosignal/woosignal.dart';
|
||||
import 'package:flutter_swiper/flutter_swiper.dart';
|
||||
import 'package:label_storemax/widgets/woosignal_ui.dart';
|
||||
import 'package:cached_network_image/cached_network_image.dart';
|
||||
|
||||
class ProductDetailPage extends StatefulWidget {
|
||||
final WS.Product product;
|
||||
const ProductDetailPage({Key key, @required this.product}) : super(key: key);
|
||||
|
||||
@override
|
||||
_ProductDetailState createState() => _ProductDetailState(this.product);
|
||||
}
|
||||
|
||||
class _ProductDetailState extends State<ProductDetailPage> {
|
||||
_ProductDetailState();
|
||||
_ProductDetailState(this._product);
|
||||
|
||||
bool _isLoading;
|
||||
WS.Product _product;
|
||||
int _quantityIndicator = 1;
|
||||
List<WS.ProductVariation> _productVariations = [];
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
if (_product.type == "variable") {
|
||||
_isLoading = true;
|
||||
_fetchProductVariations();
|
||||
} else {
|
||||
_isLoading = false;
|
||||
}
|
||||
}
|
||||
|
||||
_isLoading = true;
|
||||
_fetchProductVariations() async {
|
||||
_productVariations = await appWooSignal((api) {
|
||||
return api.getProductVariations(_product.id);
|
||||
});
|
||||
setState(() {
|
||||
_isLoading = false;
|
||||
});
|
||||
}
|
||||
|
||||
Map<int, dynamic> _tmpAttributeObj = {};
|
||||
@ -94,159 +120,146 @@ class _ProductDetailState extends State<ProductDetailPage> {
|
||||
|
||||
_itemAddToCart({CartLineItem cartLineItem}) {
|
||||
Cart.getInstance.addToCart(cartLineItem: cartLineItem);
|
||||
showToastWith(message: trans(context, "Added to cart"), statusType: "");
|
||||
showStatusAlert(context,
|
||||
title: "Success",
|
||||
subtitle: trans(context, "Added to cart"),
|
||||
duration: 1,
|
||||
icon: Icons.add_shopping_cart);
|
||||
setState(() {});
|
||||
}
|
||||
|
||||
void _modalBottomSheetAttributes() {
|
||||
wsModalBottom(context,
|
||||
title: trans(context, "Options"),
|
||||
bodyWidget: Expanded(
|
||||
child: ListView.separated(
|
||||
itemCount: _product.attributes.length,
|
||||
separatorBuilder: (BuildContext context, int index) => Divider(
|
||||
color: Colors.black12,
|
||||
thickness: 1,
|
||||
),
|
||||
itemBuilder: (BuildContext context, int index) {
|
||||
return ListTile(
|
||||
title: Text(_product.attributes[index].name,
|
||||
style: Theme.of(context).primaryTextTheme.subhead),
|
||||
subtitle: (_tmpAttributeObj.isNotEmpty &&
|
||||
_tmpAttributeObj.containsKey(index))
|
||||
? Text(_tmpAttributeObj[index]["value"],
|
||||
style: Theme.of(context).primaryTextTheme.body2)
|
||||
: Text(trans(context, "Select a") +
|
||||
" " +
|
||||
_product.attributes[index].name),
|
||||
trailing: (_tmpAttributeObj.isNotEmpty &&
|
||||
_tmpAttributeObj.containsKey(index))
|
||||
? Icon(Icons.check, color: Colors.blueAccent)
|
||||
: null,
|
||||
onTap: () {
|
||||
_modalBottomSheetOptionsForAttribute(index);
|
||||
},
|
||||
);
|
||||
},
|
||||
)),
|
||||
extraWidget: Container(
|
||||
decoration: BoxDecoration(
|
||||
border: Border(top: BorderSide(color: Colors.black12, width: 1))),
|
||||
padding: EdgeInsets.only(top: 10),
|
||||
child: Column(
|
||||
children: <Widget>[
|
||||
Text(
|
||||
(findProductVariation() != null
|
||||
? trans(context, "Price") +
|
||||
": " +
|
||||
formatStringCurrency(
|
||||
total: findProductVariation().price)
|
||||
: (((_product.attributes.length ==
|
||||
_tmpAttributeObj.values.length) &&
|
||||
findProductVariation() == null)
|
||||
? trans(context, "This variation is unavailable")
|
||||
: trans(context, "Choose your options"))),
|
||||
style: Theme.of(context).primaryTextTheme.subhead),
|
||||
Text(
|
||||
wsModalBottom(
|
||||
context,
|
||||
title: trans(context, "Options"),
|
||||
bodyWidget: Expanded(
|
||||
child: ListView.separated(
|
||||
itemCount: _product.attributes.length,
|
||||
separatorBuilder: (BuildContext context, int index) => Divider(
|
||||
color: Colors.black12,
|
||||
thickness: 1,
|
||||
),
|
||||
itemBuilder: (BuildContext context, int index) {
|
||||
return ListTile(
|
||||
title: Text(_product.attributes[index].name,
|
||||
style: Theme.of(context).primaryTextTheme.subhead),
|
||||
subtitle: (_tmpAttributeObj.isNotEmpty &&
|
||||
_tmpAttributeObj.containsKey(index))
|
||||
? Text(_tmpAttributeObj[index]["value"],
|
||||
style: Theme.of(context).primaryTextTheme.body2)
|
||||
: Text(trans(context, "Select a") +
|
||||
" " +
|
||||
_product.attributes[index].name),
|
||||
trailing: (_tmpAttributeObj.isNotEmpty &&
|
||||
_tmpAttributeObj.containsKey(index))
|
||||
? Icon(Icons.check, color: Colors.blueAccent)
|
||||
: null,
|
||||
onTap: () {
|
||||
_modalBottomSheetOptionsForAttribute(index);
|
||||
},
|
||||
);
|
||||
},
|
||||
)),
|
||||
extraWidget: Container(
|
||||
decoration: BoxDecoration(
|
||||
border: Border(top: BorderSide(color: Colors.black12, width: 1))),
|
||||
padding: EdgeInsets.only(top: 10),
|
||||
child: Column(
|
||||
children: <Widget>[
|
||||
Text(
|
||||
(findProductVariation() != null
|
||||
? findProductVariation().stockStatus != "instock"
|
||||
? trans(context, "Out of stock")
|
||||
: ""
|
||||
: ""),
|
||||
style: Theme.of(context).primaryTextTheme.subhead,
|
||||
),
|
||||
wsPrimaryButton(context, title: trans(context, "Add to cart"),
|
||||
action: () {
|
||||
if (_product.attributes.length !=
|
||||
_tmpAttributeObj.values.length) {
|
||||
? trans(context, "Price") +
|
||||
": " +
|
||||
formatStringCurrency(
|
||||
total: findProductVariation().price)
|
||||
: (((_product.attributes.length ==
|
||||
_tmpAttributeObj.values.length) &&
|
||||
findProductVariation() == null)
|
||||
? trans(context, "This variation is unavailable")
|
||||
: trans(context, "Choose your options"))),
|
||||
style: Theme.of(context).primaryTextTheme.subhead),
|
||||
Text(
|
||||
(findProductVariation() != null
|
||||
? findProductVariation().stockStatus != "instock"
|
||||
? trans(context, "Out of stock")
|
||||
: ""
|
||||
: ""),
|
||||
style: Theme.of(context).primaryTextTheme.subhead,
|
||||
),
|
||||
wsPrimaryButton(context, title: trans(context, "Add to cart"),
|
||||
action: () {
|
||||
if (_product.attributes.length !=
|
||||
_tmpAttributeObj.values.length) {
|
||||
showEdgeAlertWith(context,
|
||||
title: trans(context, "Oops"),
|
||||
desc: trans(context, "Please select valid options first"),
|
||||
style: EdgeAlertStyle.WARNING);
|
||||
return;
|
||||
}
|
||||
|
||||
if (findProductVariation() == null) {
|
||||
showEdgeAlertWith(context,
|
||||
title: trans(context, "Oops"),
|
||||
desc: trans(context, "Product variation does not exist"),
|
||||
style: EdgeAlertStyle.WARNING);
|
||||
return;
|
||||
}
|
||||
|
||||
if (findProductVariation() != null) {
|
||||
if (findProductVariation().stockStatus != "instock") {
|
||||
showEdgeAlertWith(context,
|
||||
title: trans(context, "Oops"),
|
||||
desc: trans(context, "Please select valid options first"),
|
||||
title: trans(context, "Sorry"),
|
||||
desc: trans(context, "This item is not in stock"),
|
||||
style: EdgeAlertStyle.WARNING);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (findProductVariation() == null) {
|
||||
showEdgeAlertWith(context,
|
||||
title: trans(context, "Oops"),
|
||||
desc: trans(context, "Product variation does not exist"),
|
||||
style: EdgeAlertStyle.WARNING);
|
||||
return;
|
||||
}
|
||||
List<String> options = [];
|
||||
_tmpAttributeObj.forEach((k, v) {
|
||||
options.add(v["name"] + ": " + v["value"]);
|
||||
});
|
||||
|
||||
if (findProductVariation() != null) {
|
||||
if (findProductVariation().stockStatus != "instock") {
|
||||
showEdgeAlertWith(context,
|
||||
title: trans(context, "Sorry"),
|
||||
desc: trans(context, "This item is not in stock"),
|
||||
style: EdgeAlertStyle.WARNING);
|
||||
return;
|
||||
}
|
||||
}
|
||||
CartLineItem cartLineItem = CartLineItem(
|
||||
name: _product.name,
|
||||
productId: _product.id,
|
||||
variationId: findProductVariation().id,
|
||||
quantity: 1,
|
||||
taxStatus: findProductVariation().taxStatus,
|
||||
shippingClassId:
|
||||
findProductVariation().shippingClassId.toString(),
|
||||
subtotal: findProductVariation().price,
|
||||
stockQuantity: findProductVariation().stockQuantity,
|
||||
isManagedStock: findProductVariation().manageStock,
|
||||
taxClass: findProductVariation().taxClass,
|
||||
imageSrc: (findProductVariation().image != null
|
||||
? findProductVariation().image.src
|
||||
: _product.images.first.src),
|
||||
shippingIsTaxable: _product.shippingTaxable,
|
||||
variationOptions: options.join(", "),
|
||||
total: findProductVariation().price);
|
||||
|
||||
List<String> options = [];
|
||||
_tmpAttributeObj.forEach((k, v) {
|
||||
options.add(v["name"] + ": " + v["value"]);
|
||||
});
|
||||
|
||||
CartLineItem cartLineItem = CartLineItem(
|
||||
name: _product.name,
|
||||
productId: _product.id,
|
||||
variationId: findProductVariation().id,
|
||||
quantity: 1,
|
||||
taxStatus: findProductVariation().taxStatus,
|
||||
shippingClassId:
|
||||
findProductVariation().shippingClassId.toString(),
|
||||
subtotal: findProductVariation().price,
|
||||
stockQuantity: findProductVariation().stockQuantity,
|
||||
isManagedStock: findProductVariation().manageStock,
|
||||
taxClass: findProductVariation().taxClass,
|
||||
imageSrc: (findProductVariation().image != null
|
||||
? findProductVariation().image.src
|
||||
: _product.images.first.src),
|
||||
shippingIsTaxable: _product.shippingTaxable,
|
||||
variationOptions: options.join(", "),
|
||||
total: findProductVariation().price);
|
||||
|
||||
_itemAddToCart(cartLineItem: cartLineItem);
|
||||
Navigator.of(context).pop();
|
||||
}),
|
||||
],
|
||||
),
|
||||
margin: EdgeInsets.only(bottom: 10),
|
||||
));
|
||||
_itemAddToCart(cartLineItem: cartLineItem);
|
||||
Navigator.of(context).pop();
|
||||
}),
|
||||
],
|
||||
),
|
||||
margin: EdgeInsets.only(bottom: 10),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
void _modalBottomSheetMenu() {
|
||||
wsModalBottom(context,
|
||||
title: trans(context, "Description"),
|
||||
bodyWidget: Expanded(
|
||||
child: SingleChildScrollView(
|
||||
child: Text(parseHtmlString(_product.description)),
|
||||
),
|
||||
flex: 1,
|
||||
));
|
||||
}
|
||||
|
||||
@override
|
||||
void didChangeDependencies() {
|
||||
super.didChangeDependencies();
|
||||
if (_isLoading) {
|
||||
_product = ModalRoute.of(context).settings.arguments;
|
||||
|
||||
if (_product.type == "variable") {
|
||||
WooSignal.getInstance(config: wsConfig).then((wcStore) {
|
||||
wcStore.getProductVariations(_product.id).then((productVariations) {
|
||||
_productVariations = productVariations;
|
||||
_isLoading = false;
|
||||
setState(() {});
|
||||
});
|
||||
});
|
||||
} else {
|
||||
_isLoading = false;
|
||||
setState(() {});
|
||||
}
|
||||
}
|
||||
wsModalBottom(
|
||||
context,
|
||||
title: trans(context, "Description"),
|
||||
bodyWidget: Expanded(
|
||||
child: SingleChildScrollView(
|
||||
child: Text(parseHtmlString(_product.description)),
|
||||
),
|
||||
flex: 1,
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
@ -254,170 +267,276 @@ class _ProductDetailState extends State<ProductDetailPage> {
|
||||
return Scaffold(
|
||||
appBar: AppBar(
|
||||
backgroundColor: Colors.transparent,
|
||||
actions: <Widget>[wsCartIcon(context)],
|
||||
title: storeLogo(height: 50),
|
||||
actions: <Widget>[
|
||||
wsCartIcon(context),
|
||||
],
|
||||
title: storeLogo(height: 55),
|
||||
centerTitle: true,
|
||||
),
|
||||
body: SafeArea(
|
||||
minimum: safeAreaDefault(),
|
||||
child: _isLoading
|
||||
? showAppLoader()
|
||||
: Column(
|
||||
mainAxisAlignment: MainAxisAlignment.start,
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
crossAxisAlignment: CrossAxisAlignment.center,
|
||||
children: <Widget>[
|
||||
Flexible(
|
||||
flex: 3,
|
||||
child: SizedBox(
|
||||
child: new Swiper(
|
||||
itemBuilder: (BuildContext context, int index) {
|
||||
return CachedNetworkImage(
|
||||
imageUrl: _product.images[index].src,
|
||||
placeholder: (context, url) =>
|
||||
new CircularProgressIndicator(
|
||||
strokeWidth: 2,
|
||||
backgroundColor: Colors.black12),
|
||||
errorWidget: (context, url, error) =>
|
||||
new Icon(Icons.error),
|
||||
fit: BoxFit.contain);
|
||||
},
|
||||
itemCount: _product.images.length,
|
||||
viewportFraction: 0.8,
|
||||
scale: 0.9,
|
||||
onTap: (i) {
|
||||
setState(() {});
|
||||
},
|
||||
),
|
||||
),
|
||||
),
|
||||
Padding(
|
||||
padding: EdgeInsets.only(top: 10),
|
||||
child: Row(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
Expanded(
|
||||
child: ListView(
|
||||
children: <Widget>[
|
||||
Flexible(
|
||||
child: Text(
|
||||
_product.name,
|
||||
style: Theme.of(context).primaryTextTheme.body2,
|
||||
textAlign: TextAlign.left,
|
||||
SizedBox(
|
||||
height: MediaQuery.of(context).size.height * 0.40,
|
||||
child: SizedBox(
|
||||
child: new Swiper(
|
||||
itemBuilder: (BuildContext context, int index) {
|
||||
return CachedNetworkImage(
|
||||
imageUrl: _product.images[index].src,
|
||||
placeholder: (context, url) =>
|
||||
new CircularProgressIndicator(
|
||||
strokeWidth: 2,
|
||||
backgroundColor: Colors.black12,
|
||||
),
|
||||
errorWidget: (context, url, error) =>
|
||||
new Icon(Icons.error),
|
||||
fit: BoxFit.contain,
|
||||
);
|
||||
},
|
||||
itemCount: _product.images.length,
|
||||
viewportFraction: 0.85,
|
||||
scale: 0.9,
|
||||
onTap: (i) {
|
||||
setState(() {});
|
||||
},
|
||||
),
|
||||
),
|
||||
flex: 4,
|
||||
),
|
||||
Flexible(
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.end,
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
Container(
|
||||
height: 100,
|
||||
padding: EdgeInsets.symmetric(
|
||||
vertical: 10, horizontal: 16),
|
||||
child: Row(
|
||||
crossAxisAlignment: CrossAxisAlignment.center,
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: <Widget>[
|
||||
Text(
|
||||
formatStringCurrency(total: _product.price),
|
||||
style:
|
||||
Theme.of(context).primaryTextTheme.subhead,
|
||||
textAlign: TextAlign.right,
|
||||
Flexible(
|
||||
child: Text(
|
||||
_product.name,
|
||||
style:
|
||||
Theme.of(context).primaryTextTheme.body2,
|
||||
textAlign: TextAlign.left,
|
||||
overflow: TextOverflow.ellipsis,
|
||||
maxLines: 2,
|
||||
),
|
||||
flex: 4,
|
||||
),
|
||||
Text(
|
||||
((_product.stockStatus != "instock"
|
||||
? trans(context, "Out of stock")
|
||||
: trans(context, "In Stock"))),
|
||||
style: Theme.of(context).primaryTextTheme.body1,
|
||||
textAlign: TextAlign.right,
|
||||
Flexible(
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.end,
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: <Widget>[
|
||||
Text(
|
||||
formatStringCurrency(
|
||||
total: _product.price),
|
||||
style: Theme.of(context)
|
||||
.primaryTextTheme
|
||||
.display1
|
||||
.copyWith(
|
||||
fontSize: 20,
|
||||
),
|
||||
textAlign: TextAlign.right,
|
||||
),
|
||||
],
|
||||
),
|
||||
flex: 2,
|
||||
)
|
||||
],
|
||||
),
|
||||
),
|
||||
Container(
|
||||
color: Colors.white,
|
||||
padding:
|
||||
EdgeInsets.symmetric(vertical: 4, horizontal: 16),
|
||||
height: 180,
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
mainAxisAlignment: MainAxisAlignment.spaceAround,
|
||||
children: <Widget>[
|
||||
Row(
|
||||
mainAxisAlignment:
|
||||
MainAxisAlignment.spaceBetween,
|
||||
crossAxisAlignment: CrossAxisAlignment.center,
|
||||
children: <Widget>[
|
||||
Text(
|
||||
trans(context, "Description"),
|
||||
style: Theme.of(context)
|
||||
.primaryTextTheme
|
||||
.caption
|
||||
.copyWith(fontSize: 18),
|
||||
textAlign: TextAlign.left,
|
||||
),
|
||||
MaterialButton(
|
||||
child: Text(
|
||||
trans(context, "Full description"),
|
||||
style: Theme.of(context)
|
||||
.primaryTextTheme
|
||||
.body1
|
||||
.copyWith(fontSize: 14),
|
||||
textAlign: TextAlign.right,
|
||||
),
|
||||
height: 50,
|
||||
minWidth: 60,
|
||||
onPressed: () {
|
||||
_modalBottomSheetMenu();
|
||||
},
|
||||
),
|
||||
],
|
||||
),
|
||||
Flexible(
|
||||
child: Text(
|
||||
(_product.shortDescription != null &&
|
||||
_product.shortDescription != ""
|
||||
? parseHtmlString(
|
||||
_product.shortDescription)
|
||||
: parseHtmlString(_product.description)),
|
||||
),
|
||||
flex: 3,
|
||||
),
|
||||
],
|
||||
),
|
||||
flex: 2,
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
Container(
|
||||
padding: EdgeInsets.symmetric(horizontal: 16),
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.white,
|
||||
boxShadow: [
|
||||
BoxShadow(
|
||||
color: Colors.black12,
|
||||
blurRadius: 15.0,
|
||||
spreadRadius: -17,
|
||||
offset: Offset(
|
||||
0,
|
||||
-10,
|
||||
),
|
||||
)
|
||||
],
|
||||
),
|
||||
),
|
||||
Divider(
|
||||
color: Colors.black12,
|
||||
thickness: 1,
|
||||
),
|
||||
Expanded(
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
mainAxisAlignment: MainAxisAlignment.spaceAround,
|
||||
crossAxisAlignment: CrossAxisAlignment.center,
|
||||
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
|
||||
children: <Widget>[
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
crossAxisAlignment: CrossAxisAlignment.center,
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: <Widget>[
|
||||
Text(
|
||||
trans(context, "Description"),
|
||||
style: Theme.of(context).primaryTextTheme.body1,
|
||||
textAlign: TextAlign.left,
|
||||
"Quantity",
|
||||
style: Theme.of(context).primaryTextTheme.body2,
|
||||
),
|
||||
MaterialButton(
|
||||
Row(
|
||||
children: <Widget>[
|
||||
IconButton(
|
||||
icon: Icon(
|
||||
Icons.remove_circle_outline,
|
||||
size: 28,
|
||||
),
|
||||
onPressed: () {
|
||||
if ((_quantityIndicator - 1) >= 1) {
|
||||
setState(() {
|
||||
_quantityIndicator--;
|
||||
});
|
||||
}
|
||||
},
|
||||
),
|
||||
Text(
|
||||
_quantityIndicator.toString(),
|
||||
style:
|
||||
Theme.of(context).primaryTextTheme.body2,
|
||||
),
|
||||
IconButton(
|
||||
icon: Icon(
|
||||
Icons.add_circle_outline,
|
||||
size: 28,
|
||||
),
|
||||
onPressed: () {
|
||||
if (_quantityIndicator != 0) {
|
||||
setState(() {
|
||||
_quantityIndicator++;
|
||||
});
|
||||
}
|
||||
},
|
||||
),
|
||||
],
|
||||
)
|
||||
],
|
||||
),
|
||||
Row(
|
||||
crossAxisAlignment: CrossAxisAlignment.center,
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: <Widget>[
|
||||
Flexible(
|
||||
child: Align(
|
||||
child: Text(
|
||||
trans(context, "Full description"),
|
||||
formatStringCurrency(
|
||||
total: (double.parse(_product.price) *
|
||||
_quantityIndicator)
|
||||
.toString()),
|
||||
style:
|
||||
Theme.of(context).primaryTextTheme.caption,
|
||||
textAlign: TextAlign.right,
|
||||
Theme.of(context).primaryTextTheme.display1,
|
||||
textAlign: TextAlign.center,
|
||||
),
|
||||
alignment: Alignment.centerLeft,
|
||||
)),
|
||||
Flexible(
|
||||
child: wsPrimaryButton(
|
||||
context,
|
||||
title: trans(context, "Add to cart"),
|
||||
action: () {
|
||||
_addItemToCart();
|
||||
},
|
||||
),
|
||||
height: 50,
|
||||
minWidth: 60,
|
||||
onPressed: () {
|
||||
_modalBottomSheetMenu();
|
||||
},
|
||||
),
|
||||
],
|
||||
),
|
||||
Flexible(
|
||||
child: Text(
|
||||
(_product.shortDescription != null &&
|
||||
_product.shortDescription != ""
|
||||
? parseHtmlString(_product.shortDescription)
|
||||
: parseHtmlString(_product.description)),
|
||||
),
|
||||
flex: 3,
|
||||
),
|
||||
],
|
||||
),
|
||||
flex: 1,
|
||||
),
|
||||
wsPrimaryButton(
|
||||
context,
|
||||
title: trans(context, "ADD TO CART"),
|
||||
action: () {
|
||||
CartLineItem cartLineItem = CartLineItem(
|
||||
name: _product.name,
|
||||
productId: _product.id,
|
||||
quantity: 1,
|
||||
taxStatus: _product.taxStatus,
|
||||
shippingClassId: _product.shippingClassId.toString(),
|
||||
subtotal: _product.price,
|
||||
taxClass: _product.taxClass,
|
||||
isManagedStock: _product.manageStock,
|
||||
stockQuantity: _product.stockQuantity,
|
||||
shippingIsTaxable: _product.shippingTaxable,
|
||||
imageSrc: _product.images.length == 0 ? "" : _product.images.first.src,
|
||||
total: _product.price);
|
||||
|
||||
if (_product.type != "simple") {
|
||||
_modalBottomSheetAttributes();
|
||||
return;
|
||||
}
|
||||
if (_product.stockStatus == "instock") {
|
||||
_itemAddToCart(cartLineItem: cartLineItem);
|
||||
} else {
|
||||
showEdgeAlertWith(context,
|
||||
title: trans(context, "Sorry"),
|
||||
desc: trans(context, "This item is out of stock"),
|
||||
style: EdgeAlertStyle.WARNING,
|
||||
icon: Icons.local_shipping);
|
||||
}
|
||||
},
|
||||
height: 140,
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class ProductDetailPage extends StatefulWidget {
|
||||
ProductDetailPage();
|
||||
_addItemToCart() {
|
||||
CartLineItem cartLineItem = CartLineItem(
|
||||
name: _product.name,
|
||||
productId: _product.id,
|
||||
quantity: _quantityIndicator,
|
||||
taxStatus: _product.taxStatus,
|
||||
shippingClassId: _product.shippingClassId.toString(),
|
||||
subtotal: _product.price,
|
||||
taxClass: _product.taxClass,
|
||||
isManagedStock: _product.manageStock,
|
||||
stockQuantity: _product.stockQuantity,
|
||||
shippingIsTaxable: _product.shippingTaxable,
|
||||
imageSrc: _product.images.first.src,
|
||||
total: _product.price,
|
||||
);
|
||||
|
||||
@override
|
||||
_ProductDetailState createState() => _ProductDetailState();
|
||||
if (_product.type != "simple") {
|
||||
_modalBottomSheetAttributes();
|
||||
return;
|
||||
}
|
||||
if (_product.stockStatus == "instock") {
|
||||
_itemAddToCart(cartLineItem: cartLineItem);
|
||||
} else {
|
||||
showEdgeAlertWith(context,
|
||||
title: trans(context, "Sorry"),
|
||||
desc: trans(context, "This item is out of stock"),
|
||||
style: EdgeAlertStyle.WARNING,
|
||||
icon: Icons.local_shipping);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
106
LabelStoreMax/lib/providers/stripe_pay.dart
Normal file
106
LabelStoreMax/lib/providers/stripe_pay.dart
Normal file
@ -0,0 +1,106 @@
|
||||
//
|
||||
// LabelCore
|
||||
// Label StoreMAX
|
||||
//
|
||||
// Created by Anthony Gordon.
|
||||
// Copyright © 2020 WooSignal. All rights reserved.
|
||||
//
|
||||
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
|
||||
import 'package:flutter/cupertino.dart';
|
||||
import 'package:label_storemax/helpers/data/order_wc.dart';
|
||||
import 'package:label_storemax/helpers/tools.dart';
|
||||
import 'package:label_storemax/labelconfig.dart';
|
||||
import 'package:label_storemax/models/cart.dart';
|
||||
import 'package:label_storemax/pages/checkout_confirmation.dart';
|
||||
import 'package:woosignal/models/payload/order_wc.dart';
|
||||
import 'package:woosignal/models/response/order.dart';
|
||||
import 'package:woosignal/models/response/tax_rate.dart';
|
||||
import 'package:woosignal_stripe/woosignal_stripe.dart';
|
||||
|
||||
stripePay(context,
|
||||
{@required CheckoutConfirmationPageState state,
|
||||
TaxRate taxRate}) async {
|
||||
|
||||
// CONFIGURE STRIPE
|
||||
FlutterStripePayment.setStripeSettings(
|
||||
stripeAccount: app_stripe_account, liveMode: app_stripe_live_mode);
|
||||
|
||||
var paymentResponse = await FlutterStripePayment.addPaymentMethod();
|
||||
|
||||
// CHECK STATUS FROM STRIPE
|
||||
if (paymentResponse.status == PaymentResponseStatus.succeeded) {
|
||||
state.reloadState(showLoader: true);
|
||||
|
||||
// CHECKOUT HELPER
|
||||
await checkout(taxRate, (total, billingDetails, cart) async {
|
||||
|
||||
Map<String, dynamic> address = {
|
||||
"name": billingDetails.billingAddress.nameFull(),
|
||||
"line1": billingDetails.shippingAddress.addressLine,
|
||||
"city": billingDetails.shippingAddress.city,
|
||||
"postal_code": billingDetails.shippingAddress.postalCode,
|
||||
"country": billingDetails.shippingAddress.country
|
||||
};
|
||||
|
||||
String cartShortDesc = await cart.cartShortDesc();
|
||||
|
||||
dynamic rsp = await appWooSignal((api) {
|
||||
return api.stripePaymentIntent(
|
||||
amount: total,
|
||||
email: billingDetails.billingAddress.emailAddress,
|
||||
desc: cartShortDesc,
|
||||
shipping: address,
|
||||
);
|
||||
});
|
||||
|
||||
if (rsp == null) {
|
||||
showToastNetworkError();
|
||||
state.reloadState(showLoader: false);
|
||||
return;
|
||||
}
|
||||
|
||||
String clientSecret = rsp["client_secret"];
|
||||
var intentResponse = await FlutterStripePayment.confirmPaymentIntent(
|
||||
clientSecret,
|
||||
paymentResponse.paymentMethodId,
|
||||
(double.parse(total) * 100),
|
||||
);
|
||||
|
||||
if (intentResponse.status == PaymentResponseStatus.succeeded) {
|
||||
OrderWC orderWC = await buildOrderWC(taxRate: taxRate);
|
||||
Order order = await appWooSignal((api) {
|
||||
return api.createOrder(orderWC);
|
||||
});
|
||||
|
||||
if (order != null) {
|
||||
Cart.getInstance.clear();
|
||||
Navigator.pushNamed(context, "/checkout-status", arguments: order);
|
||||
} else {
|
||||
showEdgeAlertWith(
|
||||
context,
|
||||
title: trans(context, "Error"),
|
||||
desc:
|
||||
trans(context, "Something went wrong, please contact our store"),
|
||||
);
|
||||
state.reloadState(showLoader: false);
|
||||
}
|
||||
} else if (intentResponse.status == PaymentResponseStatus.failed) {
|
||||
if (app_debug) {
|
||||
print(intentResponse.errorMessage);
|
||||
}
|
||||
showEdgeAlertWith(
|
||||
context,
|
||||
title: trans(context, "Error"),
|
||||
desc: intentResponse.errorMessage,
|
||||
);
|
||||
state.reloadState(showLoader: false);
|
||||
} else {
|
||||
state.reloadState(showLoader: false);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
7
LabelStoreMax/lib/widgets/app_loader.dart
Normal file
7
LabelStoreMax/lib/widgets/app_loader.dart
Normal file
@ -0,0 +1,7 @@
|
||||
import 'package:flutter/widgets.dart';
|
||||
import 'package:flutter_spinkit/flutter_spinkit.dart';
|
||||
import '../helpers/tools.dart';
|
||||
|
||||
Widget showAppLoader() {
|
||||
return SpinKitDoubleBounce(color: HexColor("#393318"));
|
||||
}
|
||||
52
LabelStoreMax/lib/widgets/buttons.dart
Normal file
52
LabelStoreMax/lib/widgets/buttons.dart
Normal file
@ -0,0 +1,52 @@
|
||||
import 'package:flutter/cupertino.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
import '../helpers/tools.dart';
|
||||
|
||||
Widget wsPrimaryButton(BuildContext context,
|
||||
{@required String title, void Function() action}) {
|
||||
return Container(
|
||||
height: 55,
|
||||
child: RaisedButton(
|
||||
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(12.0)),
|
||||
padding: EdgeInsets.all(8),
|
||||
child: Text(
|
||||
title,
|
||||
style: Theme.of(context).primaryTextTheme.button.copyWith(fontSize: 16),
|
||||
),
|
||||
onPressed: action ?? null,
|
||||
elevation: 0,
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Widget wsSecondaryButton(BuildContext context,
|
||||
{String title, void Function() action}) {
|
||||
return Container(
|
||||
height: 60,
|
||||
margin: EdgeInsets.only(top: 10),
|
||||
child: RaisedButton(
|
||||
padding: EdgeInsets.all(10),
|
||||
child: Text(title,
|
||||
style: Theme.of(context).primaryTextTheme.body2,
|
||||
textAlign: TextAlign.center),
|
||||
onPressed: action,
|
||||
color: HexColor("#f6f6f9"),
|
||||
elevation: 0),
|
||||
);
|
||||
}
|
||||
|
||||
Widget wsLinkButton(BuildContext context,
|
||||
{String title, void Function() action}) {
|
||||
return Container(
|
||||
height: 60,
|
||||
margin: EdgeInsets.only(top: 10),
|
||||
child: MaterialButton(
|
||||
padding: EdgeInsets.all(10),
|
||||
child: Text(title,
|
||||
style: Theme.of(context).primaryTextTheme.body2,
|
||||
textAlign: TextAlign.left),
|
||||
onPressed: action,
|
||||
elevation: 0),
|
||||
);
|
||||
}
|
||||
45
LabelStoreMax/lib/widgets/cart_icon.dart
Normal file
45
LabelStoreMax/lib/widgets/cart_icon.dart
Normal file
@ -0,0 +1,45 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:label_storemax/models/cart.dart';
|
||||
import 'package:label_storemax/models/cart_line_item.dart';
|
||||
|
||||
Widget wsCartIcon(BuildContext context) {
|
||||
return IconButton(
|
||||
icon: Stack(
|
||||
children: <Widget>[
|
||||
Positioned.fill(
|
||||
child: Align(
|
||||
child: Icon(Icons.shopping_cart, size: 20, color: Colors.black87),
|
||||
alignment: Alignment.bottomCenter,
|
||||
),
|
||||
bottom: 0),
|
||||
Positioned.fill(
|
||||
child: Align(
|
||||
child: FutureBuilder<List<CartLineItem>>(
|
||||
future: Cart.getInstance.getCart(),
|
||||
builder: (BuildContext context,
|
||||
AsyncSnapshot<List<CartLineItem>> snapshot) {
|
||||
switch (snapshot.connectionState) {
|
||||
case ConnectionState.waiting:
|
||||
return Text("");
|
||||
default:
|
||||
if (snapshot.hasError)
|
||||
return Text("");
|
||||
else
|
||||
return new Text(
|
||||
snapshot.data.length.toString(),
|
||||
style: Theme.of(context).primaryTextTheme.body2,
|
||||
textAlign: TextAlign.center,
|
||||
);
|
||||
}
|
||||
},
|
||||
),
|
||||
alignment: Alignment.topCenter,
|
||||
),
|
||||
top: 0)
|
||||
],
|
||||
),
|
||||
onPressed: () {
|
||||
Navigator.pushNamed(context, "/cart");
|
||||
},
|
||||
);
|
||||
}
|
||||
27
LabelStoreMax/lib/widgets/menu_item.dart
Normal file
27
LabelStoreMax/lib/widgets/menu_item.dart
Normal file
@ -0,0 +1,27 @@
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
Widget wsMenuItem(BuildContext context,
|
||||
{String title, Widget leading, void Function() action}) {
|
||||
return Flexible(
|
||||
child: InkWell(
|
||||
child: Card(
|
||||
child: Container(
|
||||
width: double.infinity,
|
||||
padding: EdgeInsets.only(top: 15, bottom: 15),
|
||||
child: Column(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
crossAxisAlignment: CrossAxisAlignment.center,
|
||||
children: <Widget>[
|
||||
leading,
|
||||
Text(" " + title,
|
||||
style: Theme.of(context).primaryTextTheme.body1),
|
||||
],
|
||||
),
|
||||
),
|
||||
elevation: 1,
|
||||
margin: EdgeInsets.only(top: 8, bottom: 8, left: 8, right: 8),
|
||||
),
|
||||
onTap: action,
|
||||
),
|
||||
);
|
||||
}
|
||||
@ -1,7 +1,7 @@
|
||||
// Label StoreMAX
|
||||
//
|
||||
// Created by Anthony Gordon.
|
||||
// Copyright © 2019 WooSignal. All rights reserved.
|
||||
// Copyright © 2020 WooSignal. All rights reserved.
|
||||
//
|
||||
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
@ -10,6 +10,10 @@
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:label_storemax/labelconfig.dart';
|
||||
import 'package:label_storemax/models/cart.dart';
|
||||
import 'package:label_storemax/models/cart_line_item.dart';
|
||||
import 'package:label_storemax/models/checkout_session.dart';
|
||||
import 'package:label_storemax/widgets/app_loader.dart';
|
||||
import 'package:woosignal/models/response/products.dart';
|
||||
import 'package:label_storemax/helpers/tools.dart';
|
||||
import 'package:cached_network_image/cached_network_image.dart';
|
||||
@ -17,118 +21,6 @@ import 'package:woosignal/models/response/tax_rate.dart';
|
||||
|
||||
const appFontFamily = "Overpass";
|
||||
|
||||
Widget wsCartIcon(BuildContext context) {
|
||||
return IconButton(
|
||||
icon: Stack(
|
||||
children: <Widget>[
|
||||
Positioned.fill(
|
||||
child: Align(
|
||||
child: Icon(Icons.shopping_cart, size: 20, color: Colors.black87),
|
||||
alignment: Alignment.bottomCenter,
|
||||
),
|
||||
bottom: 0),
|
||||
Positioned.fill(
|
||||
child: Align(
|
||||
child: FutureBuilder<List<CartLineItem>>(
|
||||
future: Cart.getInstance.getCart(),
|
||||
builder: (BuildContext context,
|
||||
AsyncSnapshot<List<CartLineItem>> snapshot) {
|
||||
switch (snapshot.connectionState) {
|
||||
case ConnectionState.waiting:
|
||||
return Text("");
|
||||
default:
|
||||
if (snapshot.hasError)
|
||||
return Text("");
|
||||
else
|
||||
return new Text(
|
||||
snapshot.data.length.toString(),
|
||||
style: Theme.of(context).primaryTextTheme.body2,
|
||||
textAlign: TextAlign.center,
|
||||
);
|
||||
}
|
||||
},
|
||||
),
|
||||
alignment: Alignment.topCenter,
|
||||
),
|
||||
top: 0)
|
||||
],
|
||||
),
|
||||
onPressed: () {
|
||||
Navigator.pushNamed(context, "/cart");
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
Widget wsMenuItem(BuildContext context,
|
||||
{String title, Widget leading, void Function() action}) {
|
||||
return Flexible(
|
||||
child: InkWell(
|
||||
child: Card(
|
||||
child: Container(
|
||||
width: double.infinity,
|
||||
padding: EdgeInsets.only(top: 15, bottom: 15),
|
||||
child: Column(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
crossAxisAlignment: CrossAxisAlignment.center,
|
||||
children: <Widget>[
|
||||
leading,
|
||||
Text(" " + title,
|
||||
style: Theme.of(context).primaryTextTheme.body1),
|
||||
],
|
||||
),
|
||||
),
|
||||
elevation: 1,
|
||||
margin: EdgeInsets.only(top: 8, bottom: 8, left: 8, right: 8),
|
||||
),
|
||||
onTap: action,
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Widget wsPrimaryButton(BuildContext context,
|
||||
{String title, void Function() action}) {
|
||||
return Container(
|
||||
height: 60,
|
||||
margin: EdgeInsets.only(top: 10),
|
||||
child: RaisedButton(
|
||||
padding: EdgeInsets.all(10),
|
||||
child: Text(title, style: Theme.of(context).primaryTextTheme.button),
|
||||
onPressed: action,
|
||||
elevation: 0),
|
||||
);
|
||||
}
|
||||
|
||||
Widget wsSecondaryButton(BuildContext context,
|
||||
{String title, void Function() action}) {
|
||||
return Container(
|
||||
height: 60,
|
||||
margin: EdgeInsets.only(top: 10),
|
||||
child: RaisedButton(
|
||||
padding: EdgeInsets.all(10),
|
||||
child: Text(title,
|
||||
style: Theme.of(context).primaryTextTheme.body2,
|
||||
textAlign: TextAlign.center),
|
||||
onPressed: action,
|
||||
color: HexColor("#f6f6f9"),
|
||||
elevation: 0),
|
||||
);
|
||||
}
|
||||
|
||||
Widget wsLinkButton(BuildContext context,
|
||||
{String title, void Function() action}) {
|
||||
return Container(
|
||||
height: 60,
|
||||
margin: EdgeInsets.only(top: 10),
|
||||
child: MaterialButton(
|
||||
padding: EdgeInsets.all(10),
|
||||
child: Text(title,
|
||||
style: Theme.of(context).primaryTextTheme.body2,
|
||||
textAlign: TextAlign.left),
|
||||
onPressed: action,
|
||||
elevation: 0),
|
||||
);
|
||||
}
|
||||
|
||||
Widget wsRow2Text(BuildContext context, {String text1, String text2}) {
|
||||
return Row(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
@ -142,7 +34,11 @@ Widget wsRow2Text(BuildContext context, {String text1, String text2}) {
|
||||
),
|
||||
Flexible(
|
||||
child: Container(
|
||||
child: Text(text2, style: Theme.of(context).primaryTextTheme.body2),
|
||||
child: Text(text2,
|
||||
style: Theme.of(context)
|
||||
.primaryTextTheme
|
||||
.body2
|
||||
.copyWith(fontSize: 16, color: Colors.black87)),
|
||||
),
|
||||
flex: 3,
|
||||
)
|
||||
@ -168,45 +64,46 @@ Widget wsCheckoutRow(BuildContext context,
|
||||
return Flexible(
|
||||
child: InkWell(
|
||||
child: Container(
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: <Widget>[
|
||||
Padding(
|
||||
child: Text(heading,
|
||||
style: Theme.of(context).primaryTextTheme.body1),
|
||||
padding: EdgeInsets.only(bottom: 8),
|
||||
),
|
||||
Row(
|
||||
crossAxisAlignment: CrossAxisAlignment.center,
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: <Widget>[
|
||||
Row(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: <Widget>[
|
||||
leadImage,
|
||||
Container(
|
||||
child: Text(leadTitle,
|
||||
style: Theme.of(context).primaryTextTheme.subhead,
|
||||
maxLines: 2,
|
||||
overflow: TextOverflow.ellipsis,
|
||||
softWrap: false),
|
||||
padding: EdgeInsets.only(left: 15),
|
||||
)
|
||||
],
|
||||
),
|
||||
Icon(Icons.arrow_forward_ios)
|
||||
],
|
||||
)
|
||||
],
|
||||
),
|
||||
padding: EdgeInsets.all(8),
|
||||
decoration: showBorderBottom == true
|
||||
? BoxDecoration(
|
||||
border: Border(
|
||||
bottom: BorderSide(color: Colors.black12, width: 1)))
|
||||
: BoxDecoration()),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: <Widget>[
|
||||
Padding(
|
||||
child: Text(heading,
|
||||
style: Theme.of(context).primaryTextTheme.body1),
|
||||
padding: EdgeInsets.only(bottom: 8),
|
||||
),
|
||||
Row(
|
||||
crossAxisAlignment: CrossAxisAlignment.center,
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: <Widget>[
|
||||
Row(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: <Widget>[
|
||||
leadImage,
|
||||
Container(
|
||||
child: Text(leadTitle,
|
||||
style: Theme.of(context).primaryTextTheme.subhead,
|
||||
maxLines: 2,
|
||||
overflow: TextOverflow.ellipsis,
|
||||
softWrap: false),
|
||||
padding: EdgeInsets.only(left: 15),
|
||||
)
|
||||
],
|
||||
),
|
||||
Icon(Icons.arrow_forward_ios)
|
||||
],
|
||||
)
|
||||
],
|
||||
),
|
||||
padding: EdgeInsets.all(8),
|
||||
decoration: showBorderBottom == true
|
||||
? BoxDecoration(
|
||||
border:
|
||||
Border(bottom: BorderSide(color: Colors.black12, width: 1)))
|
||||
: BoxDecoration(),
|
||||
),
|
||||
onTap: action,
|
||||
borderRadius: BorderRadius.circular(8),
|
||||
),
|
||||
@ -335,14 +232,18 @@ void wsModalBottom(BuildContext context,
|
||||
child: new Container(
|
||||
padding: EdgeInsets.only(top: 25, left: 18, right: 18),
|
||||
decoration: new BoxDecoration(
|
||||
color: Colors.white,
|
||||
borderRadius: new BorderRadius.only(
|
||||
topLeft: const Radius.circular(10.0),
|
||||
topRight: const Radius.circular(10.0))),
|
||||
color: Colors.white,
|
||||
borderRadius: new BorderRadius.only(
|
||||
topLeft: const Radius.circular(10.0),
|
||||
topRight: const Radius.circular(10.0)),
|
||||
),
|
||||
child: Column(
|
||||
children: <Widget>[
|
||||
Text(title,
|
||||
style: Theme.of(context).primaryTextTheme.display1,
|
||||
style: Theme.of(context)
|
||||
.primaryTextTheme
|
||||
.display1
|
||||
.copyWith(fontSize: 20),
|
||||
textAlign: TextAlign.left),
|
||||
bodyWidget,
|
||||
extraWidget ?? Container()
|
||||
@ -481,12 +382,13 @@ Widget wsCardCartItem(BuildContext context,
|
||||
void Function() actionRemoveItem}) {
|
||||
return Container(
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.white,
|
||||
border: Border(
|
||||
bottom: BorderSide(
|
||||
color: Colors.black12,
|
||||
width: 1,
|
||||
))),
|
||||
padding: EdgeInsets.all(8),
|
||||
color: Colors.black12,
|
||||
width: 1,
|
||||
))),
|
||||
padding: EdgeInsets.symmetric(vertical: 8, horizontal: 8),
|
||||
child: Column(
|
||||
children: <Widget>[
|
||||
Row(
|
||||
@ -508,8 +410,12 @@ Widget wsCardCartItem(BuildContext context,
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: <Widget>[
|
||||
Text(cartLineItem.name,
|
||||
style: Theme.of(context).primaryTextTheme.subhead),
|
||||
Text(
|
||||
cartLineItem.name,
|
||||
style: Theme.of(context).primaryTextTheme.subhead,
|
||||
overflow: TextOverflow.ellipsis,
|
||||
maxLines: 3,
|
||||
),
|
||||
(cartLineItem.variationOptions != null
|
||||
? Text(cartLineItem.variationOptions,
|
||||
style: Theme.of(context).primaryTextTheme.body2)
|
||||
@ -575,9 +481,10 @@ Widget wsCardCartItem(BuildContext context,
|
||||
));
|
||||
}
|
||||
|
||||
Widget storeLogo({double height}) {
|
||||
Widget storeLogo({double height, double width}) {
|
||||
return cachedImage(app_logo_url,
|
||||
height: height, placeholder: Container(height: height, width: height));
|
||||
height: height,
|
||||
placeholder: Container(height: height ?? 100, width: width ?? 100));
|
||||
}
|
||||
|
||||
Widget cachedImage(image, {double height, Widget placeholder, BoxFit fit}) {
|
||||
|
||||
@ -7,7 +7,7 @@ packages:
|
||||
name: archive
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "2.0.10"
|
||||
version: "2.0.11"
|
||||
args:
|
||||
dependency: transitive
|
||||
description:
|
||||
@ -21,7 +21,7 @@ packages:
|
||||
name: async
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "2.3.0"
|
||||
version: "2.4.0"
|
||||
boolean_selector:
|
||||
dependency: transitive
|
||||
description:
|
||||
@ -35,7 +35,7 @@ packages:
|
||||
name: cached_network_image
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.1.1"
|
||||
version: "2.0.0"
|
||||
charcode:
|
||||
dependency: transitive
|
||||
description:
|
||||
@ -50,13 +50,6 @@ packages:
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.14.11"
|
||||
connectivity:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: connectivity
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "0.4.4"
|
||||
convert:
|
||||
dependency: transitive
|
||||
description:
|
||||
@ -98,7 +91,7 @@ packages:
|
||||
name: dio
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "3.0.4"
|
||||
version: "3.0.9"
|
||||
edge_alert:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
@ -106,6 +99,20 @@ packages:
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "0.0.1"
|
||||
flare_dart:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: flare_dart
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "2.3.3"
|
||||
flare_flutter:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: flare_flutter
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.8.3"
|
||||
flutter:
|
||||
dependency: "direct main"
|
||||
description: flutter
|
||||
@ -117,14 +124,14 @@ packages:
|
||||
name: flutter_cache_manager
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.1.1"
|
||||
version: "1.1.3"
|
||||
flutter_launcher_icons:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: flutter_launcher_icons
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "0.7.3"
|
||||
version: "0.7.4"
|
||||
flutter_localizations:
|
||||
dependency: "direct main"
|
||||
description: flutter
|
||||
@ -150,7 +157,7 @@ packages:
|
||||
name: flutter_spinkit
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "4.0.0"
|
||||
version: "4.1.2+1"
|
||||
flutter_swiper:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
@ -170,13 +177,18 @@ packages:
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "0.11.0"
|
||||
flutter_web_plugins:
|
||||
dependency: transitive
|
||||
description: flutter
|
||||
source: sdk
|
||||
version: "0.0.0"
|
||||
fluttertoast:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: fluttertoast
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "3.1.3"
|
||||
version: "4.0.1"
|
||||
html:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
@ -204,49 +216,42 @@ packages:
|
||||
name: image
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "2.1.5"
|
||||
version: "2.1.4"
|
||||
intl:
|
||||
dependency: transitive
|
||||
dependency: "direct overridden"
|
||||
description:
|
||||
name: intl
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "0.15.8"
|
||||
json_annotation:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: json_annotation
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "3.0.0"
|
||||
matcher:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: matcher
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "0.12.5"
|
||||
version: "0.12.6"
|
||||
meta:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: meta
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.1.7"
|
||||
version: "1.1.8"
|
||||
package_info:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: package_info
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "0.4.0+6"
|
||||
version: "0.4.0+16"
|
||||
page_transition:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: page_transition
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.1.4"
|
||||
version: "1.1.5"
|
||||
path:
|
||||
dependency: transitive
|
||||
description:
|
||||
@ -282,13 +287,6 @@ packages:
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "2.2.1"
|
||||
pref_dessert:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: pref_dessert
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "0.4.0+1"
|
||||
quiver:
|
||||
dependency: transitive
|
||||
description:
|
||||
@ -302,7 +300,28 @@ packages:
|
||||
name: shared_preferences
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "0.5.4+3"
|
||||
version: "0.5.6+3"
|
||||
shared_preferences_macos:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: shared_preferences_macos
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "0.0.1+6"
|
||||
shared_preferences_platform_interface:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: shared_preferences_platform_interface
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.0.3"
|
||||
shared_preferences_web:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: shared_preferences_web
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "0.1.2+4"
|
||||
sky_engine:
|
||||
dependency: transitive
|
||||
description: flutter
|
||||
@ -329,6 +348,13 @@ packages:
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.9.3"
|
||||
status_alert:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: status_alert
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "0.1.1"
|
||||
stream_channel:
|
||||
dependency: transitive
|
||||
description:
|
||||
@ -363,7 +389,7 @@ packages:
|
||||
name: test_api
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "0.2.5"
|
||||
version: "0.2.11"
|
||||
transformer_page_view:
|
||||
dependency: transitive
|
||||
description:
|
||||
@ -405,7 +431,7 @@ packages:
|
||||
name: woosignal_stripe
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "0.0.2"
|
||||
version: "0.0.4"
|
||||
xml:
|
||||
dependency: transitive
|
||||
description:
|
||||
@ -421,5 +447,5 @@ packages:
|
||||
source: hosted
|
||||
version: "2.2.0"
|
||||
sdks:
|
||||
dart: ">2.4.0 <3.0.0"
|
||||
flutter: ">=1.6.7 <2.0.0"
|
||||
dart: ">=2.5.0 <3.0.0"
|
||||
flutter: ">=1.12.13+hotfix.4 <2.0.0"
|
||||
|
||||
@ -24,21 +24,20 @@ environment:
|
||||
|
||||
dependencies:
|
||||
woosignal: ^1.0.2
|
||||
woosignal_stripe: ^0.0.2
|
||||
connectivity: ^0.4.4
|
||||
shared_preferences: ^0.5.3+4
|
||||
woosignal_stripe: ^0.0.4
|
||||
shared_preferences: ^0.5.6+3
|
||||
cached_network_image: ^2.0.0
|
||||
page_transition: ^1.1.4
|
||||
package_info: ^0.4.0+6
|
||||
flutter_money_formatter: ^0.8.2
|
||||
page_transition: ^1.1.5
|
||||
package_info: ^0.4.0+16
|
||||
flutter_money_formatter: ^0.8.3
|
||||
flutter_web_browser: ^0.11.0
|
||||
dio: ^3.0.2
|
||||
dio: ^3.0.9
|
||||
flutter_swiper: ^1.1.6
|
||||
edge_alert: ^0.0.1
|
||||
fluttertoast: ^3.1.3
|
||||
flutter_spinkit: ^4.0.0
|
||||
pref_dessert: ^0.4.0+1
|
||||
flutter_launcher_icons: ^0.7.3
|
||||
status_alert: ^0.1.1
|
||||
fluttertoast: ^4.0.1
|
||||
flutter_spinkit: ^4.1.2+1
|
||||
flutter_launcher_icons: ^0.7.4
|
||||
html: ^0.14.0+3
|
||||
flutter:
|
||||
sdk: flutter
|
||||
|
||||
Loading…
Reference in New Issue
Block a user