Files
BarangaySystem/resources/js/composables/Market/usePosSession.js
2026-06-06 18:43:00 +08:00

163 lines
5.9 KiB
JavaScript

import { ref, onMounted, watch } from 'vue';
import { usePosStore } from '../../stores/pos';
import { useUIStore } from '../../stores/ui';
import { useOfflineStore } from '../useOfflineStore';
import { useNetworkStore } from '../../stores/network';
export function usePosSession(props) {
const posStore = usePosStore();
const uiStore = useUIStore();
const offlineStore = useOfflineStore();
const networkStore = useNetworkStore();
const storeHash = ref(null);
const showSuccessAnimation = ref(false);
const isOfflineMode = ref(false);
// Helper: Access key from URL or LocalStorage
const getStoredAccessKey = () => {
try {
return localStorage.getItem('pos_access_key');
} catch {
return null;
}
};
const initialize = async () => {
// Check for existing session in URL or Storage
const urlParams = new URLSearchParams(window.location.search);
const accessKey = props.access_key || urlParams.get('key') || getStoredAccessKey();
const hashkey = props.target;
if (accessKey) {
localStorage.setItem('pos_access_key', accessKey);
}
// 1. Load Session or treat as Store Hash
if (hashkey) {
// Try loading as session
await posStore.loadSession(hashkey, accessKey);
if (!posStore.activeSession) {
// Not a session? Treat it as a direct link to a store terminal
storeHash.value = hashkey;
posStore.error = null;
} else if (posStore.activeSession?.store?.hashkey) {
storeHash.value = posStore.activeSession.store.hashkey;
}
}
// 2. Fetch products (Always synchronized with access key/store hash)
await posStore.fetchProducts(accessKey, storeHash.value);
// 3. Fallback: If no direct session yet, try to load one by access key
if (!posStore.activeSession && accessKey) {
await posStore.loadSession(null, accessKey);
}
// 4. Synchronization: ensure products are loaded if session was found later
if (posStore.activeSession && posStore.products.length === 0) {
await posStore.fetchProducts(accessKey, storeHash.value);
}
// 5. Restore offline cart if no server session was found
if (!posStore.activeSession) {
try {
const savedRaw = localStorage.getItem('pos_cart_session')
const saved = savedRaw ? JSON.parse(savedRaw) : null
if (saved?.offline && saved.cart?.length > 0) {
posStore.activeSession = { hashkey: saved.sessionHashkey, offline: true, transactions: [] }
posStore.cart = saved.cart
posStore.isOfflineMode = true
isOfflineMode.value = true
}
} catch {}
}
// 6. Load terminal stats
await posStore.fetchTodayStats(storeHash.value);
};
const completeTransaction = async (customerName) => {
const currentStoreHash = storeHash.value || posStore.activeSession?.store?.hashkey;
// Try Online First (skip if session is a local offline-only session)
let success = false;
const isOfflineSession = posStore.activeSession?.offline === true;
if (networkStore.isOnline && !isOfflineSession) {
success = await posStore.completeTransaction(customerName);
}
if (!success) {
// Offline Fallback
const txnData = {
store_hash: currentStoreHash,
customer_name: customerName,
items: posStore.cart.map(item => ({
product_hashkey: item.product?.hashkey,
quantity: item.quantity,
price_at_sale: item.price_at_sale
})),
total: posStore.totalAmount,
received: posStore.receivedAmount,
change: posStore.changeAmount,
method: posStore.paymentMethod
};
const id = await offlineStore.storeTransactionOffline(txnData);
if (id) {
success = true;
isOfflineMode.value = true;
}
}
if (success) {
showSuccessAnimation.value = true;
// Clean up state
posStore.resetSession();
// Delayed re-initialization (gives time for animation)
setTimeout(async () => {
showSuccessAnimation.value = false;
if (networkStore.isOnline) {
await posStore.startNewSession(currentStoreHash, '', getStoredAccessKey());
await Promise.all([
posStore.fetchTodayStats(currentStoreHash),
posStore.fetchPosSessions(currentStoreHash, 1)
]);
isOfflineMode.value = false;
}
}, 2500);
return true;
}
return false;
};
const startNewSessionSilently = async () => {
const accessKey = getStoredAccessKey();
if (!storeHash.value && !accessKey) {
posStore.error = 'No store selected. Open the POS from a store page or use an access key.';
return false;
}
return await posStore.startNewSession(storeHash.value, '', accessKey);
};
// Keep storeHash in sync with active session if it changes
watch(() => posStore.activeSession, (session) => {
if (session?.store?.hashkey) {
storeHash.value = session.store.hashkey;
}
}, { immediate: true });
return {
storeHash,
showSuccessAnimation,
initialize,
completeTransaction,
startNewSessionSilently,
getStoredAccessKey,
isOfflineMode
};
}