· 4 years ago · May 26, 2021, 03:40 PM
1class CartManager {
2
3 /**
4 * Set all cart listeners when these buttons are pressed do a specific function.
5 * Since these listeners need to be refreshed every time a new element comes in we call it multiple times.
6 * So we need to unbind the function before we add them again, else the function will be called multiple times.
7 */
8 static addListeners() {
9
10 $('.addToCart').unbind();
11 $('.removeFromCart').unbind();
12 $('.amount').unbind();
13 $('.delete').unbind();
14 $('#check-cart').unbind();
15
16 $('.addToCart').on('click', function () {
17 const id = $(this).parents('.col-4').data('id');
18 CartManager.addToCart(id);
19 });
20
21 $('.removeFromCart').on('click', function (event) {
22 event.preventDefault();
23 const id = $(this).data('id');
24 CartManager.removeFromCart(id);
25 });
26
27 $('.amount').on('change', function() {
28 const id = $(this).parents('tr').data('id');
29 const amount = $(this).val();
30 CartManager.changeAmount(id, amount);
31 });
32
33 $('.delete').on('click', function () {
34 CartManager.discardCart();
35 });
36
37 $('#check-cart').on('click', async function () {
38 await CartManager.checkCart();
39 });
40 }
41
42 /**
43 * Add a item to the cart, we save the cart in the session so when the page is leaved the cart is still there.
44 * When the product exists the amount is increased by one.
45 * @param id
46 */
47 static addToCart(id) {
48 let items = CartManager.getItems();
49
50 const element = $('div[data-id=' + id + ']');
51
52 const item = {
53 id: id,
54 title: element.find('.title').html(),
55 price: element.find('.price').html(),
56 amount: parseInt(element.find('select').val())
57 };
58
59 if(items != null) {
60
61 for (let i = 0; i < items.length; i++) {
62 if(items[i].id == id) {
63 items[i].amount = parseInt(items[i].amount) + parseInt(element.find('select').val());
64 return CartManager.setCartItems(items);
65 }
66 }
67 items.push(item);
68 } else {
69 items = [item];
70 }
71
72 return CartManager.setCartItems(items);
73 }
74
75 /**
76 * Check how many items are in the cart if there is only 1 item, we can remove the whole cart.
77 * Since I could not found a way to remove a specific item from an array
78 * We create a new array and add te items to it, except for the one that the user would like to remove.
79 *
80 * @param id
81 * @returns {void|undefined}
82 */
83 static removeFromCart(id) {
84 const items = CartManager.getItems();
85
86 if(items.length === 1) {
87 sessionManager.remove('items');
88 return CartManager.updateShoppingCart();
89 }
90
91 let newItems = [];
92 for (let i = 0; i < items.length; i++) {
93 if(items[i].id !== id) {
94 newItems.push(items[i]);
95 return CartManager.setCartItems(newItems);
96 }
97 }
98 }
99
100 /**
101 * discard the whole shopping cart.
102 */
103 static discardCart() {
104 const check = confirm('Weet u zeker dat u het winkelmandje leeg wilt halen?');
105 if(check) {
106 sessionManager.remove('items');
107 return CartManager.updateShoppingCart();
108 }
109 }
110
111 /**
112 * Calculate the total price of all the products in the shopping cart.
113 * The price is stored with a comma instead of a dot so before we parse it we have to change the comma to a dot
114 * If we dont do that "4,50" will ben 4 and not 4.50
115 * We format the total price to a format where there will always be 2 trailing zero's
116 * We also return it with a comma since we do that everywhere
117 */
118 static calculateTotalPrice() {
119 const items = CartManager.getItems();
120
121 if(items == null) { return 0; }
122
123 let total_price = 0;
124
125 for (let i = 0; i < items.length; i++) {
126 let item = items[i];
127 total_price += parseFloat(item.price.replace(',', '.')) * item.amount;
128 }
129
130 return total_price.toFixed(2).replace('.', ',');
131 }
132
133 /**
134 * Return all items that are currently in the shopping cart.
135 * @returns {*}
136 */
137 static getItems() {
138 return sessionManager.get('items');
139 }
140
141 /**
142 * Set a cart item in the session, after that is done update the shopping cart so the changes show on the screen.
143 * @param items
144 */
145 static setCartItems(items) {
146 sessionManager.set('items', items);
147 CartManager.updateShoppingCart();
148 }
149
150 /**
151 * Update the shopping cart the user sees on the screen.
152 */
153 static updateShoppingCart() {
154 const items = CartManager.getItems();
155
156 $('#items').empty();
157
158 CartManager.setTotalPrice();
159
160 if(items == null) { return; } else if(items.length == 0) { return; }
161
162 for (let i = 0; i < items.length; i++) {
163 let item = items[i];
164
165 $.get('partials/cart/item.html')
166 .done((data) => CartManager.fillPartial(data , item))
167 .fail(() => CartManager.error());
168 }
169 }
170
171 /**
172 * Set total price underneath the table that holds the item.
173 */
174 static setTotalPrice() {
175 const total_price = CartManager.calculateTotalPrice();
176
177 const checkoutElement = $('.checkout');
178
179 if(total_price != 0) {
180 checkoutElement.removeClass('d-none');
181 checkoutElement.find('#total_price').text(total_price);
182 } else {
183 checkoutElement.addClass('d-none');
184 }
185 };
186
187 /**
188 * Fill in partial
189 */
190 static fillPartial(data, item, element) {
191 const partial = $(data);
192
193 partial.attr('data-id', item.id);
194 partial.find('.price').html('€' + item.price);
195 partial.find('.title').html(item.title);
196 partial.find('.amount').val(item.amount);
197 partial.find('.removeFromCart').data('id', item.id);
198
199 if(element == null) {
200 $('#items').append(partial);
201 return CartManager.addListeners();
202 } else {
203 return element.find('#checkout-table').append(partial)
204 }
205 }
206
207 /**
208 * Changes the amount of a product in the cart.
209 *
210 * @param id
211 * @param amount
212 */
213 static changeAmount(id, amount) {
214 const items = CartManager.getItems();
215
216 for (let i = 0; i < items.length; i++) {
217 if(items[i].id === id) {
218 items[i].amount = amount;
219 return CartManager.setCartItems(items);
220 }
221 }
222 }
223
224 /**
225 * Gives the user a overview of all selected product and the option to order them.
226 * @returns {Promise<*>}
227 */
228 static async checkCart() {
229 const items = CartManager.getItems();
230 const price = CartManager.calculateTotalPrice();
231
232 const modal = $(await CartManager.getModal());
233
234 for (let i = 0; i < items.length; i++) {
235 let item = items[i];
236
237 $.get('partials/cart/item.html')
238 .done((data) => CartManager.fillPartial(data, item, modal))
239 .fail(() => CartManager.error());
240 }
241
242 modal.find('#checkout_price').text(price);
243 modal.find('#checkout-button').on('click', () => CartManager.createOrder());
244
245 $('body').append(modal);
246 return modal.modal('show');
247 }
248
249 /**
250 * Get modal for the popup that lets the user check his order.
251 *
252 * @returns {Promise<*>}
253 */
254 static async getModal() {
255 return await $.get('partials/cart/checkout.html');
256 }
257
258 /**
259 * Create the order,
260 * If the order is created remove the shipping cart and close the modal.
261 * When failed keep the modal open and show an alert that it failed.
262 *
263 * @returns {Promise<void>}
264 */
265 static async createOrder() {
266 const data = {
267 items: sessionManager.get('items'),
268 seat: $('#seat').val(),
269 }
270
271 const order = await BestellingRepository.createOrder(data);
272
273 if(order.status === 'success') {
274 sessionManager.remove('items');
275 CartManager.updateShoppingCart();
276 const alert = $(await $.get('partials/alert/alert.html'));
277 alert.addClass('alert-success');
278 alert.prepend('Uw order is succesvol aangekomen, een steward zal zo snel mogelijk langskomen om u verder te helpen!');
279
280 $('.modal').modal('hide');
281 $('.alert-box').prepend(alert);
282 } else {
283 alert("Er is iets fout gegaan, probeer het opnieuw.");
284 }
285 return true;
286 }
287
288 /**
289 * Display error when an error occurs using the shopping cart.
290 */
291 static error() {
292 alert('Er is iets fout gegaan met de shopping cart, probeer het opnieuw.');
293 }
294