• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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