File: /var/www/vhost/disk-apps/pwa.sports-crowd.com/src/app/services/cart.service.ts
import { Injectable } from "@angular/core";
import { TranslateService } from "@ngx-translate/core";
import { AlertController } from "@ionic/angular";
import { StorageService } from './storage.service';
import { UtilsService } from "./utils.service";
import { ApiService } from "./api.service";
import { UserService } from "./user.service";
import { AnalyticsFacebookService } from "./analytics-facebook.service";
@Injectable({
providedIn: "root",
})
export class CartService {
storeType: any;
productsCartDiscount: any = [];
productsCart: any = [];
priceToDiscount: any = [];
_priceDomicile: any;
_paymentTypes: any;
_subtotal: any;
_total: any;
_discount: any;
_discountDelivery: any;
_statusMinimumOrderPrice: boolean = false;
_minimumOrderPrice: any;
_activeDiscount: boolean = false;
_discountsApplied: any = [];
_listShowToast: any = [];
_serviceChargeEnabled: boolean = false;
_serviceCharge: number = 0;
priceDomicileDefault = 0;
domicile_by_coverage: boolean = false;
current_ticket: any;
currentAcademyUserId: any;
constructor(
private storage: StorageService,
public api: ApiService,
public alertController: AlertController,
public translateService: TranslateService,
private utilsService: UtilsService,
private userService: UserService,
private analyticsFacebookService: AnalyticsFacebookService
) { }
getProductsCart() {
this.storage.get("productsCart").then((productsCart) => {
if (productsCart) {
this.productsCart = productsCart;
}
});
}
priceDomicileByCoverage() {
return new Promise((resolve, reject) => {
this.userService
.getlastAddressUser()
.then((resp: any) => {
if (resp && resp.coverage) {
this._priceDomicile = resp.coverage.cost_delivery;
} else {
this._priceDomicile = this.priceDomicileDefault;
}
resolve(true);
})
.catch((error) => {
reject(false);
this._priceDomicile = this.priceDomicileDefault;
console.log("error getlastAddressUser: ", error);
});
});
}
getPriceDomicile() {
this.storage.get("token").then(async (token) => {
if (token) {
this._priceDomicile = "";
this._minimumOrderPrice = "";
let seq = await this.api.get("parameters/info", token.access_token);
seq.subscribe(
(res: any) => {
if (res.status == "success") {
this.storage.set("parameters", res.parameters);
this.domicile_by_coverage = res.parameters.cost_delivery_by_coverage;
this.priceDomicileDefault = res.parameters.cost_delivery;
this._minimumOrderPrice = res.parameters.minimum_order_price;
if (res.parameters.cost_delivery_by_coverage == 1) {
this.priceDomicileByCoverage()
.then(() => {
this.calculatePrice();
})
.catch((error) => {
console.log("error");
});
} else {
this._priceDomicile = res.parameters.cost_delivery;
this.calculatePrice();
}
}
},
(err) => {
console.error("Error provider cart getPriceDomicile", err);
}
);
}
});
}
getPaymentTypesDomicile() {
this.storage.get("token").then(async (token) => {
if (token) {
this._paymentTypes = [];
let seq = await this.api.get("cart/paymentTypes/list", token.access_token);
seq.subscribe(
(res: any) => {
if (res.status == "success") {
this.storage.set("paymentTypes", res.paymentTypes);
this._paymentTypes = res.paymentTypes;
}
},
(err) => {
console.error("Error provider cart getPriceDomicile", err);
}
);
}
});
}
async presentVALIDATEAGE(product, quantity, origin) {
const alert = await this.alertController.create({
header: this.translateService.instant("TITLE_VALIDATE_AGE"),
message: this.translateService.instant("TEXT_VALIDATE_AGE"),
buttons: [
{
text: "No",
role: "cancel",
cssClass: "secondary",
handler: (blah) => { },
},
{
text: "Si",
handler: () => {
this.addProduct(product, quantity, origin, false);
},
},
],
});
await alert.present();
}
async presentAlertUNITSORDER() {
const alert = await this.alertController.create({
header: this.translateService.instant("TITLE_MAX_UNITS_ORDER"),
message: this.translateService.instant("TEXT_MAX_UNITS_ORDER"),
buttons: ["Ok"],
});
await alert.present();
}
async presentAlertAvailableUnits() {
const alert = await this.alertController.create({
header: this.translateService.instant("TITLE_AVAILABLE_UNITS_ORDER"),
message: this.translateService.instant("TEXT_AVAILABLE_UNITS_ORDER"),
buttons: ["Ok"],
});
await alert.present();
}
async presentAlertAvailableUnitsItems(attribute, value) {
const alert = await this.alertController.create({
header: this.translateService.instant("TITLE_AVAILABLE_UNITS_ORDER"),
message: this.translateService.instant("ATTRIBUTE_REQUIRED_ITEMS", { attribute, value }),
buttons: ["Ok"],
});
await alert.present();
}
validateItemsProduct(product, quantity, origin, valid_age?) {
// Search by product id on Cart and sum quantity.
let quantityCart = 0;
let quantityCartPerProduct = 0;
if (origin != "remove") {
// Comportamiento diferente cuando viene de detail-product, ya que aquí se envian todas las unidades no de 1 en 1.
if (origin != "detail_product") {
quantity = 1;
}
for (let i = 0; i < this.productsCart.length; i++) {
let p = this.productsCart[i];
if (p.id == product.id) {
if (product.product_attributes_selected && product.product_attributes_selected[0]) {
if (p.product_attributes_selected && p.product_attributes_selected[0]) {
quantityCartPerProduct += p.quantity;
if (p.product_attributes_selected[0].value == product.product_attributes_selected[0].value) {
quantityCart = quantityCart + p.quantity
}
}
} else {
quantityCartPerProduct += p.quantity;
quantityCart = quantityCart + p.quantity;
}
}
}
}
if (product.max_units_per_product && quantity + quantityCartPerProduct > product.max_units_per_product) {
this.presentAlertUNITSORDER();
return false;
}
if (product.max_units_per_order && quantity + quantityCart > product.max_units_per_order) {
this.presentAlertUNITSORDER();
return false;
}
if (quantity + quantityCart > product.available_units) {
this.presentAlertAvailableUnits();
return false;
}
if (product.product_attributes_selected) {
for (let i = 0; i < product.product_attributes_selected.length; i++) {
let item = product.product_attributes_selected[i];
if (quantity + quantityCart > item.available_units) {
this.presentAlertAvailableUnitsItems(item.attribute.display_name, item.value);
return false;
}
}
}
if (product.validate_age && !product.addCart && valid_age) {
this.presentVALIDATEAGE(product, quantity, origin);
return false;
}
return true;
}
deepCopy(obj) {
var copy;
// Handle the 3 simple types, and null or undefined
if (null == obj || "object" != typeof obj) return obj;
// Handle Date
if (obj instanceof Date) {
copy = new Date();
copy.setTime(obj.getTime());
return copy;
}
// Handle Array
if (obj instanceof Array) {
copy = [];
for (var i = 0, len = obj.length; i < len; i++) {
copy[i] = this.deepCopy(obj[i]);
}
return copy;
}
// Handle Object
if (obj instanceof Object) {
copy = {};
for (var attr in obj) {
if (obj.hasOwnProperty(attr)) copy[attr] = this.deepCopy(obj[attr]);
}
return copy;
}
throw new Error("Unable to copy obj! Its type isn't supported.");
}
addProduct(product, quantity, origin?, validate_age = true) {
if (this.validateItemsProduct(product, quantity, origin, validate_age)) {
var params = {};
params["CONTENT"] = product.name;
params["CONTENT_ID"] = product.id;
params["CONTENT_TYPE"] = product.category.name;
params["CURRENCY"] = "COP";
this.analyticsFacebookService.createLogEvent("EVENT_NAME_ADDED_TO_CART", params, product.price);
var clone = this.deepCopy(product);
clone.addCart = true;
clone.quantity = quantity;
clone.indexCart = this.productsCart.length;
clone.priceToDiscount = 0;
this.productsCart.push(clone);
this.storage.set("productsCart", this.productsCart);
this.calculatePrice();
}
}
updateQuantity(product, quantity, origin?) {
if (quantity > 0) {
if (this.validateItemsProduct(product, quantity, origin)) {
this.productsCart[product.indexCart].quantity = quantity;
this.storage.set("productsCart", this.productsCart);
this.calculatePrice();
}
} else {
if (product.priceToDiscount > 0) {
this.showConfirmDeleteProductGift(product);
} else {
this.deleteProduct(product);
}
}
}
showConfirmDeleteProductGift(product) {
this.alertController.create({
header: 'Producto obsequio',
message: 'Quieres eliminar el producto obsequio: ' + product.name + '?',
buttons: [
{
text: 'Cancelar',
handler: () => {
}
},
{
text: 'Eliminar!',
handler: () => {
if (this.productsCart && this.productsCart.length) {
let isSameProductRemoved = this.productsCart.find((element) => element.id != product.id);
if ((typeof (isSameProductRemoved) == "undefined")) {
for (let i = 0; i < this.productsCart.length; i++) {
this.productsCart[i].priceToDiscount = product.priceToDiscount;
}
}
this.storage.set("productsCart", this.productsCart);
}
this.deleteProduct(product);
}
}
]
}).then(res => {
res.present();
});
}
updateProduct(product, origin?) {
if (this.validateItemsProduct(product, product.quantity, origin)) {
let clone = this.deepCopy(product);
this.productsCart[product.indexCart] = clone;
this.storage.set("productsCart", this.productsCart);
this.calculatePrice();
}
}
deleteProduct(product) {
this.productsCart.splice(product.indexCart, 1);
this.updateIndexProductsInCart();
this.calculatePrice();
}
updateIndexProductsInCart() {
if (this.productsCart && this.productsCart.length) {
for (let i = 0; i < this.productsCart.length; i++) {
this.productsCart[i].indexCart = i;
}
this.storage.set("productsCart", this.productsCart);
}
}
deleteAllProductsCart() {
this.productsCart = [];
this.storage.remove("productsCart");
this.storage.remove("productsCartCombo");
this.calculatePrice();
}
updateComments(product, comments) {
this.productsCart[product.indexCart].comments = comments;
this.storage.set("productsCart", this.productsCart);
}
typeAttribute(object) {
let attributeText = true;
if (object && object != "") {
let item = Object.entries(object);
for (let i = 0; i < item.length; i++) {
let attributes: any = item[i][1];
for (let j = 0; j < attributes.length; j++) {
let element = attributes[j];
if (element.attribute.attribute_type_id != 1) {
attributeText = false;
}
}
}
}
return attributeText;
}
itemProductTour(product) {
product.attributeText = this.typeAttribute(product.product_attributes);
product.priceAfterFlash = 0;
product.priceAfterDiscount = 0;
product.priceAfterSpecialPriceTag = 0;
let quantity = 0;
let quantityGlobal = 0;
let statusInCart = false;
for (let i = 0; i < this.productsCart.length; i++) {
const element = this.productsCart[i];
if (product.id == element.id) {
product.indexCart = i;
quantity = element.quantity;
quantityGlobal += quantity;
statusInCart = true;
}
}
if (statusInCart) {
product.addCart = true;
product.quantity = quantity;
product.quantityGlobal = quantityGlobal;
} else {
product.addCart = false;
product.quantity = 0;
product.quantityGlobal = 0;
}
return product;
}
calculatePrice() {
this._subtotal = 0;
this._discount = 0;
this._total = 0;
if (this.productsCart && this.productsCart.length) {
for (let i = 0; i < this.productsCart.length; i++) {
let quantity = this.productsCart[i].quantity;
let price = this.productsCart[i].price;
let currentDiscount = 0;
let priceTotal = 0;
let priceWithDiscount = 0;
let aditionalPrice = 0;
let savePriceWithDiscount = 0;
if (this.productsCart[i].priceAfterDiscount > 0) {
currentDiscount = quantity * (price - this.productsCart[i].priceAfterDiscount);
this._discount += currentDiscount;
priceWithDiscount = this.productsCart[i].priceAfterDiscount;
} else if (this.productsCart[i].priceAfterFlash > 0) {
currentDiscount = quantity * (price - this.productsCart[i].priceAfterFlash);
this._discount += currentDiscount;
priceWithDiscount = this.productsCart[i].priceAfterFlash;
} else if (this.productsCart[i].priceAfterSpecialPriceTag > 0) {
currentDiscount = quantity * (price - this.productsCart[i].priceAfterSpecialPriceTag);
this._discount += currentDiscount;
priceWithDiscount = this.productsCart[i].priceAfterSpecialPriceTag;
} else if (typeof (this.productsCart[i].priceToDiscount) !== "undefined" && this.productsCart[i].priceToDiscount !== 0) {
let priceToDiscount = this.productsCart[i].priceToDiscount;
if (this.productsCart.find(element => element.priceToDiscount == this.productsCart[i].priceToDiscount)) {
if (this.productsCart[i].quantity == 1 && this.productsCart.length > 1) {
priceWithDiscount = 0;
this._discount += priceToDiscount;
} else if (this.productsCart[i].quantity == 2 && this.productsCart.length > 1) {
let testProduct = this.productsCart.find(element => element.priceToDiscount == priceToDiscount);
let test = this.productsCart.findIndex((element) => element.product_id == testProduct.product_id);
if (this.productsCart[test].priceWithDiscount !== 0) {
savePriceWithDiscount += (this.productsCart[test].price - priceToDiscount) * quantity;
} else {
savePriceWithDiscount += priceToDiscount;
}
priceWithDiscount = savePriceWithDiscount;
this._discount += priceToDiscount;
} else {
priceWithDiscount = price;
}
} else {
priceWithDiscount = price;
}
} else if (typeof (this.productsCart[i].discountpercentageCombo) !== "undefined" && this.productsCart[i].discountpercentageCombo !== 0) {
if (this.productsCart.find(element => element.pivotProduct == 1)) {
let temporal = this.productsCart.map((element, index) => element.discountpercentageCombo && element.quantity == 1);
this.getProductsCombos();
const testBoolean = this.productsCart.every(m => {
if (m.discountpercentageCombo && m.quantity == 1) {
return true;
}
return false;
});
if (testBoolean == true || testBoolean == false) {
if (!this.productsCart[i].pivotProduct) {
let filterNotPivotCombo = this.productsCartDiscount.filter(element => (element.discountpercentageCombo) && !element.pivotProduct);
let filterNotPivotProduct = this.productsCart.filter((element) => (element.discountpercentageCombo) && !element.pivotProduct);
let filterBoth = filterNotPivotCombo.filter(element2 =>
!filterNotPivotProduct.some(element =>
element2.product_id == element.product_id
)
);
if (filterBoth.length == 0) {
currentDiscount = (this.productsCart[i].price * this.productsCart[i].discountpercentageCombo) / 100;
priceWithDiscount = price - currentDiscount;
this._discount += currentDiscount;
} else {
priceWithDiscount = price;
}
} else {
priceWithDiscount = price;
}
} else {
priceWithDiscount = price;
}
} else {
priceWithDiscount = price;
}
} else {
priceWithDiscount = price;
}
if (this.productsCart[i].product_attributes_selected && this.productsCart[i].product_attributes_selected.length) {
for (let v = 0; v < this.productsCart[i].product_attributes_selected.length; v++) {
let itemQuantity = 1;
const element = this.productsCart[i].product_attributes_selected[v];
if (element.quantity) {
itemQuantity = element.quantity;
}
aditionalPrice += element.price_additional * itemQuantity;
}
}
priceTotal = priceWithDiscount + aditionalPrice;
this.productsCart[i].priceTotal = priceTotal;
this.productsCart[i].priceWithDiscount = priceWithDiscount;
let testProduct2 = this.productsCart.find(element => element.priceToDiscount == price);
if (testProduct2 && testProduct2.quantity == 2 && testProduct2.priceToDiscount == price) {
this._subtotal += priceTotal;
} else {
this._subtotal += quantity * priceTotal;
}
}
if (typeof (this._priceDomicile) == 'string') {
if (this._priceDomicile != '')
this._priceDomicile = parseFloat(this._priceDomicile);
else
this._priceDomicile = this.priceDomicileDefault;
}
this._total = this._subtotal + this._priceDomicile + this._serviceCharge;
this.storage.get("parameters").then((parameters) => {
if (parameters) {
if (parameters.minimum_order_price > this._subtotal) {
this._statusMinimumOrderPrice = true;
} else {
this._statusMinimumOrderPrice = false;
}
} else {
this._statusMinimumOrderPrice = false;
}
});
}
}
generateOrder(orderInfo, access_token) {
return this.api.post("cart/userCreateOrder", orderInfo, access_token);
}
copyProductsToOrder(products) {
for (let i = 0; i < products.length; i++) {
let product_attributes_selected = [];
if (products[i].order_product_attributes && products[i].order_product_attributes.length) {
for (let j = 0; j < products[i].order_product_attributes.length; j++) {
let attribute = products[i].order_product_attributes[j];
for (let k = 0; k < products[i].products.product_attributes.length; k++) {
let current_attribute = products[i].products.product_attributes[k];
if (
current_attribute.product_id == products[i].product_id &&
current_attribute.attribute_id == attribute.attribute_id &&
current_attribute.value == attribute.value
) {
product_attributes_selected.push(current_attribute);
}
}
}
if (products[i].products.active) {
products[i].products.product_attributes_selected = product_attributes_selected;
}
}
this.addProduct(products[i].products, products[i].quantity);
}
}
getDiscounts(access_token) {
return this.api.get("cart/discount/list", access_token);
}
applyDiscount(discount) {
if (!discount.is_cumulative_another_discounts && this._activeDiscount) {
this.utilsService.presentToast(4000, "warning", "top", this.translateService.instant("TEXT_TOAST_DISCOUNT") + discount.name);
} else {
if (this.validateDateDiscount(discount)) {
if (this.validateDiscountRedeemed(discount.id)) {
if (this.validateUserDiscount(discount)) {
this._activeDiscount = true;
let newDiscount = {
discount_id: discount.id,
discount_type_id: discount.discount_type_id,
};
this._discountsApplied.push(newDiscount);
if (discount.price_discount) {
this._discount += discount.price_discount;
this._total -= discount.price_discount;
} else {
let currentDiscount = (this._total * discount.percentage_discount) / 100;
this._discount += currentDiscount;
this._total -= currentDiscount;
}
if (discount.discount_type_id === 4) {
this.utilsService.presentToast(4000, "warning", "top", discount.message_to_user);
} else {
this.toatDiscountApply(discount.message_to_user);
}
}
} else {
this.toatDiscountApply(this.translateService.instant("TEXT2_TOAST_DISCOUNT"));
}
} else {
if (discount.discount_type_id === 4) {
this.toatDiscountApply("El descuento cupón: " + discount.name + " no está vigente");
}
}
}
}
validateDiscountRedeemed(discount_id) {
let status = false;
let existsDiscount = false;
if (this._discountsApplied.length) {
for (let i = 0; i < this._discountsApplied.length; i++) {
if (this._discountsApplied[i].discount_id == discount_id) {
existsDiscount = true;
}
}
if (existsDiscount) {
status = false;
} else {
status = true;
}
} else {
status = true;
}
return status;
}
validateUserDiscount(discount) {
let status = true;
if (discount.discountOrderUsers && !discount.is_multiple_redeem) {
status = false;
}
return status;
}
validateDateDiscount(discount) {
let status = true;
let currentDate = new Date();
let startDiscount = new Date(discount.when_start.replace(/\s+/g, "T").concat(".000-05:00"));
let finishDiscount = new Date(discount.when_finish.replace(/\s+/g, "T").concat(".000-05:00"));
if (startDiscount.getTime() < currentDate.getTime() && finishDiscount.getTime() > currentDate.getTime()) {
status = true;
} else {
status = false;
}
return status;
}
toatDiscountApply(message) {
let toast = {
message: message,
};
this._listShowToast.push(toast);
}
showListToast() {
let listShowToast = this._listShowToast;
let t = this.utilsService;
if (listShowToast && listShowToast.length) {
for (let i = 0; i < listShowToast.length; i++) {
setTimeout(
function () {
t.presentToast(4000, "warning", "top", listShowToast[i].message);
}.bind(i, listShowToast[i], t),
i * 4000
);
}
}
}
getProductsCombos() {
this.storage.get("productsCartCombo").then((productsCartDiscountt) => {
if (productsCartDiscountt) {
this.productsCartDiscount = productsCartDiscountt;
}
});
}
productValidationCart(data, access_token) {
return this.api.post("cart/productValidationCart", data, access_token);
}
validationOrderForPayment(orderId, access_token) {
return this.api.post("cart/validationOrderForPayment", orderId, access_token);
}
updateAddressPrice(address?) {
if (this.domicile_by_coverage) {
if (!address) {
this.priceDomicileByCoverage()
.then(() => {
this.calculatePrice();
})
.catch((error) => {
console.log("error");
});
} else {
if (address.coverage) {
this._priceDomicile = address.coverage.cost_delivery;
} else {
this._priceDomicile = this.priceDomicileDefault;
}
this.calculatePrice();
}
} else {
this.calculatePrice();
}
}
}