import { HttpClient } from '@angular/common/http'; import { Injectable } from '@angular/core'; import { BehaviorSubject, map } from 'rxjs'; import { environment } from 'src/environments/environment'; import { Basket, IBasket, IBasketItem, IBasketTotals } from '../shared/models/baskset'; import { IProduct } from '../shared/models/product'; @Injectable({ providedIn: 'root' }) export class BasketService { baseUrl = environment.apiUrl; private basketSource = new BehaviorSubject(null); basket$ = this.basketSource.asObservable(); private basketTotalSource = new BehaviorSubject(null); basketTotal$ = this.basketTotalSource.asObservable(); constructor(private http: HttpClient) { } getBasket(id: string){ return this.http.get(this.baseUrl + 'basket?id=' + id).pipe( map((basket: IBasket) => { this.basketSource.next(basket); this.calculateTotals(); }) ); } setBasket(basket: IBasket){ return this.http.post(this.baseUrl + 'basket', basket).subscribe({ next: (response: IBasket) => { this.basketSource.next(response); this.calculateTotals(); }, error: (e: any) => { console.log(e); }, complete: () => { console.log('complete'); } }); } getCurrentBasketValue(){ return this.basketSource.value; } addItemToBasket(item: IProduct, quantity = 1){ const itemToAdd: IBasketItem = this.mapProductItemToBasketItem(item, quantity); const basket = this.getCurrentBasketValue() ?? this.createBasket(); basket.items = this.addOrUpdateItem(basket.items, itemToAdd, quantity); this.setBasket(basket); } private calculateTotals(){ const basket = this.getCurrentBasketValue(); const shipping = 0; const subtotal = basket.items.reduce((a, b) => (b.price * b.quantity) + a, 0); const total = subtotal + shipping; this.basketTotalSource.next({ shipping, total, subtotal }); } private addOrUpdateItem(items: IBasketItem[], itemToAdd: IBasketItem, quantity: number): IBasketItem[] { const index = items.findIndex(i => i.id === itemToAdd.id); if(index === -1){ itemToAdd.quantity = quantity; items.push(itemToAdd); } else { items[index].quantity += quantity; } return items; } private createBasket(): IBasket { const basket = new Basket(); localStorage.setItem('basket_id', basket.id); return basket; } private mapProductItemToBasketItem(item: IProduct, quantity: number): IBasketItem { return { id: item.id, productName: item.name, price: item.price, pictureUrl: item.pictureUrl, quantity, brand: item.productBrand, type: item.productType } } }