New-Thanasoft/thanas
2025-10-31 15:19:04 +03:00

259 lines
7.3 KiB
Plaintext

import { defineStore } from "pinia";
import ProductService from "@/services/product";
export const useProductStore = defineStore("product", {
state: () => ({
products: [],
currentProduct: null,
loading: false,
isLoading: false,
error: null,
meta: {
current_page: 1,
last_page: 1,
per_page: 15,
total: 0,
from: 1,
to: 0,
},
}),
getters: {
lowStockProducts: (state) =>
state.products.filter((product) => product.is_low_stock),
expiringProducts: (state) =>
state.products.filter((product) =>
product.date_expiration &&
new Date(product.date_expiration) <= new Date(Date.now() + 30 * 24 * 60 * 60 * 1000)
),
categories: (state) => {
const categorySet = new Set(state.products.map(product => product.categorie).filter(Boolean));
return Array.from(categorySet).sort();
},
totalProducts: (state) => state.meta.total,
totalValue: (state) =>
state.products.reduce((total, product) =>
total + (product.stock_actuel * product.prix_unitaire), 0
),
},
actions: {
async fetchProducts(params = {}) {
this.loading = true;
this.error = null;
try {
const response = await ProductService.getAllProducts(params);
this.products = response.data;
this.meta = {
current_page: response.pagination.current_page,
last_page: response.pagination.last_page,
per_page: response.pagination.per_page,
total: response.pagination.total,
from: response.pagination.from,
to: response.pagination.to,
};
return response;
} catch (error: any) {
this.error = error?.message || "Erreur lors du chargement des produits";
throw error;
} finally {
this.loading = false;
}
},
async createProduct(productData: any) {
this.isLoading = true;
this.error = null;
try {
const response = await ProductService.createProduct(productData);
const product = response.data;
// Add the new product to the beginning of the list
this.products.unshift(product);
this.meta.total += 1;
return product;
} catch (error: any) {
this.error = error?.message || "Erreur lors de la création du produit";
throw error;
} finally {
this.isLoading = false;
}
},
async updateProduct(id: number, productData: any) {
this.isLoading = true;
this.error = null;
try {
const response = await ProductService.updateProduct(id, productData);
const updatedProduct = response.data;
// Update the product in the list
const index = this.products.findIndex((p) => p.id === id);
if (index !== -1) {
this.products[index] = updatedProduct;
}
// Update current product if it matches
if (this.currentProduct?.id === id) {
this.currentProduct = updatedProduct;
}
return updatedProduct;
} catch (error: any) {
this.error = error?.message || "Erreur lors de la mise à jour du produit";
throw error;
} finally {
this.isLoading = false;
}
},
async deleteProduct(id: number) {
this.isLoading = true;
this.error = null;
try {
await ProductService.deleteProduct(id);
// Remove the product from the list
this.products = this.products.filter((p) => p.id !== id);
this.meta.total -= 1;
// Clear current product if it was deleted
if (this.currentProduct?.id === id) {
this.currentProduct = null;
}
return true;
} catch (error: any) {
this.error = error?.message || "Erreur lors de la suppression du produit";
throw error;
} finally {
this.isLoading = false;
}
},
async fetchProduct(id: number) {
this.loading = true;
this.error = null;
try {
const response = await ProductService.getProduct(id);
this.currentProduct = response.data;
return response.data;
} catch (error: any) {
this.error = error?.message || "Erreur lors du chargement du produit";
throw error;
} finally {
this.loading = false;
}
},
async searchProducts(searchTerm: string, exact = false) {
this.loading = true;
this.error = null;
try {
const response = await ProductService.searchProducts(searchTerm, exact);
// Update current products list with search results
this.products = response.data;
return response.data;
} catch (error: any) {
this.error = error?.message || "Erreur lors de la recherche";
throw error;
} finally {
this.loading = false;
}
},
async fetchLowStockProducts() {
this.loading = true;
this.error = null;
try {
const response = await ProductService.getLowStockProducts();
return response;
} catch (error: any) {
this.error = error?.message || "Erreur lors du chargement des produits à stock faible";
throw error;
} finally {
this.loading = false;
}
},
async fetchProductsByCategory(category: string) {
this.loading = true;
this.error = null;
try {
const response = await ProductService.getProductsByCategory(category);
return response;
} catch (error: any) {
this.error = error?.message || "Erreur lors du chargement des produits par catégorie";
throw error;
} finally {
this.loading = false;
}
},
async getProductStatistics() {
try {
const response = await ProductService.getProductStatistics();
return response.data;
} catch (error: any) {
this.error = error?.message || "Erreur lors du chargement des statistiques";
throw error;
}
},
async updateStock(productId: number, newStock: number) {
try {
const response = await ProductService.updateStock(productId, newStock);
// Update the product in the list
const index = this.products.findIndex((p) => p.id === productId);
if (index !== -1) {
this.products[index] = response.data;
}
return response.data;
} catch (error: any) {
this.error = error?.message || "Erreur lors de la mise à jour du stock";
throw error;
}
},
resetState() {
this.products = [];
this.currentProduct = null;
this.error = null;
this.loading = false;
this.isLoading = false;
},
// Local filtering functions
filterByCategory(category: string) {
if (!category) return this.products;
return this.products.filter((product: any) => product.categorie === category);
},
filterByLowStock() {
return this.products.filter((product: any) => product.is_low_stock);
},
filterByExpiration(days = 30) {
const cutoffDate = new Date(Date.now() + days * 24 * 60 * 60 * 1000);
return this.products.filter((product: any) =>
product.date_expiration &&
new Date(product.date_expiration) <= cutoffDate
);
},
},
});