1// Copyright 2018-present the Flutter authors. All Rights Reserved. 2// 3// Licensed under the Apache License, Version 2.0 (the "License"); 4// you may not use this file except in compliance with the License. 5// You may obtain a copy of the License at 6// 7// http://www.apache.org/licenses/LICENSE-2.0 8// 9// Unless required by applicable law or agreed to in writing, software 10// distributed under the License is distributed on an "AS IS" BASIS, 11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12// See the License for the specific language governing permissions and 13// limitations under the License. 14 15import 'package:scoped_model/scoped_model.dart'; 16 17import 'package:flutter_gallery/demo/shrine/model/product.dart'; 18import 'package:flutter_gallery/demo/shrine/model/products_repository.dart'; 19 20double _salesTaxRate = 0.06; 21double _shippingCostPerItem = 7.0; 22 23class AppStateModel extends Model { 24 // All the available products. 25 List<Product> _availableProducts; 26 27 // The currently selected category of products. 28 Category _selectedCategory = Category.all; 29 30 // The IDs and quantities of products currently in the cart. 31 final Map<int, int> _productsInCart = <int, int>{}; 32 33 Map<int, int> get productsInCart => Map<int, int>.from(_productsInCart); 34 35 // Total number of items in the cart. 36 int get totalCartQuantity => _productsInCart.values.fold(0, (int v, int e) => v + e); 37 38 Category get selectedCategory => _selectedCategory; 39 40 // Totaled prices of the items in the cart. 41 double get subtotalCost { 42 return _productsInCart.keys 43 .map((int id) => _availableProducts[id].price * _productsInCart[id]) 44 .fold(0.0, (double sum, int e) => sum + e); 45 } 46 47 // Total shipping cost for the items in the cart. 48 double get shippingCost { 49 return _shippingCostPerItem * _productsInCart.values.fold(0.0, (num sum, int e) => sum + e); 50 } 51 52 // Sales tax for the items in the cart 53 double get tax => subtotalCost * _salesTaxRate; 54 55 // Total cost to order everything in the cart. 56 double get totalCost => subtotalCost + shippingCost + tax; 57 58 // Returns a copy of the list of available products, filtered by category. 59 List<Product> getProducts() { 60 if (_availableProducts == null) { 61 return <Product>[]; 62 } 63 64 if (_selectedCategory == Category.all) { 65 return List<Product>.from(_availableProducts); 66 } else { 67 return _availableProducts 68 .where((Product p) => p.category == _selectedCategory) 69 .toList(); 70 } 71 } 72 73 // Adds a product to the cart. 74 void addProductToCart(int productId) { 75 if (!_productsInCart.containsKey(productId)) { 76 _productsInCart[productId] = 1; 77 } else { 78 _productsInCart[productId]++; 79 } 80 81 notifyListeners(); 82 } 83 84 // Removes an item from the cart. 85 void removeItemFromCart(int productId) { 86 if (_productsInCart.containsKey(productId)) { 87 if (_productsInCart[productId] == 1) { 88 _productsInCart.remove(productId); 89 } else { 90 _productsInCart[productId]--; 91 } 92 } 93 94 notifyListeners(); 95 } 96 97 // Returns the Product instance matching the provided id. 98 Product getProductById(int id) { 99 return _availableProducts.firstWhere((Product p) => p.id == id); 100 } 101 102 // Removes everything from the cart. 103 void clearCart() { 104 _productsInCart.clear(); 105 notifyListeners(); 106 } 107 108 // Loads the list of available products from the repo. 109 void loadProducts() { 110 _availableProducts = ProductsRepository.loadProducts(Category.all); 111 notifyListeners(); 112 } 113 114 void setCategory(Category newCategory) { 115 _selectedCategory = newCategory; 116 notifyListeners(); 117 } 118 119 @override 120 String toString() { 121 return 'AppStateModel(totalCost: $totalCost)'; 122 } 123} 124