Kaynağa Gözat

add the function on report screen

gdias 4 ay önce
ebeveyn
işleme
f1e9ec1369

+ 1 - 1
src/lib/component/Commands.svelte

@@ -105,7 +105,7 @@
 
 	function handleAddProduct(order_id) {
 		localStorage.setItem('order', order_id);
-		goto('/dashboard/endcommands');
+		goto('/dashboard/endcommand');
 	}
 
 	onMount(() => {

+ 57 - 150
src/lib/component/EndCommand.svelte

@@ -22,44 +22,25 @@
 	}
 
 	let selectedCategory = null;
-	let isPaymentModalOpen = false;
-	let selectedPaymentMethod = null;
 
-	let orderItems = [];
+	let localOrderItems = [];
 	let products = [];
 	let categories = [];
 
-	$: totalAmount = orderItems.reduce(
+	if (browser) {
+		const storedItems = localStorage.getItem(`orderItems_${orderId}`);
+		if (storedItems) {
+			localOrderItems = JSON.parse(storedItems);
+		}
+	}
+
+	$: totalAmount = localOrderItems.reduce(
 		(sum, item) => sum + Number(item.product_details?.product_price ?? 0) * (item.quantity ?? 1),
 		0
 	);
 
-	async function fetchOrderItems() {
-		try {
-			const myHeaders = new Headers();
-			myHeaders.append('Authorization', `Bearer ${token}`);
-			myHeaders.append('Content-Type', 'application/json');
-
-			if (orderId) {
-				const rawItems = JSON.stringify({
-					order_id: orderId,
-					company_id: company
-				});
-
-				const resItems = await fetch('https://dev2.mixtech.dev.br/order_item/get', {
-					method: 'POST',
-					headers: myHeaders,
-					body: rawItems
-				});
-				const itemsResult = await resItems.json();
-				orderItems = itemsResult.data || [];
-				orderItems = orderItems.map((item) => ({ ...item, quantity: item.quantity ?? 1 }));
-			} else {
-				orderItems = [];
-			}
-		} catch (error) {
-			console.error('Erro ao buscar itens do pedido:', error);
-		}
+	$: if (browser && localOrderItems) {
+		localStorage.setItem(`orderItems_${orderId}`, JSON.stringify(localOrderItems));
 	}
 
 	async function fetchProductsAndCategories() {
@@ -92,7 +73,6 @@
 	}
 
 	onMount(async () => {
-		await fetchOrderItems();
 		await fetchProductsAndCategories();
 	});
 
@@ -107,57 +87,54 @@
 			})
 		: products;
 
-	async function handleAddItem(product) {
-		const myHeaders = new Headers();
-		myHeaders.append('Authorization', `Bearer ${token}`);
-		myHeaders.append('Content-Type', 'application/json');
-		const payload = {
-			company_id: company,
-			order_id: orderId,
-			product_id: product.product_id
+	function handleAddItem(product) {
+		const newItem = {
+			order_item_id: Date.now(), // Temporary ID for local use
+			product_details: product,
+			quantity: 1
 		};
-		await fetch('https://dev2.mixtech.dev.br/order_item/create', {
-			method: 'POST',
-			headers: myHeaders,
-			body: JSON.stringify(payload)
-		});
-		await fetchOrderItems();
+		localOrderItems = [...localOrderItems, newItem]; // Update localOrderItems
 	}
 
-	async function removeItemFromOrder(tableId, itemId) {
-		const myHeaders = new Headers();
-		myHeaders.append('Authorization', `Bearer ${token}`);
-		myHeaders.append('Content-Type', 'application/json');
-		await fetch('https://dev2.mixtech.dev.br/order_item/delete', {
-			method: 'DELETE',
-			headers: myHeaders,
-			body: JSON.stringify({
-				company_id: company,
-				item_id: itemId
-			})
-		});
-		await fetchOrderItems();
+	function removeItemFromOrder(itemId) {
+		localOrderItems = localOrderItems.filter((item) => item.order_item_id !== itemId); // Update localOrderItems
 	}
 
-	async function handlePaymentConfirm() {
-		if (!selectedPaymentMethod) {
-			console.warn('Selecione uma forma de pagamento');
-			return;
-		}
+	async function handleSendToKitchen() {
+		if (localOrderItems.length === 0) return;
+
 		const myHeaders = new Headers();
 		myHeaders.append('Authorization', `Bearer ${token}`);
 		myHeaders.append('Content-Type', 'application/json');
-		await fetch('https://dev2.mixtech.dev.br/order/close', {
-			method: 'POST',
-			headers: myHeaders,
-			body: JSON.stringify({
-				company_id: company,
-				order_id: orderId,
-				payment_method: selectedPaymentMethod
-			})
-		});
-		isPaymentModalOpen = false;
-		goto('/tables');
+
+		try {
+			let success = true;
+			for (const item of localOrderItems) {
+				const payload = {
+					company_id: company,
+					order_id: orderId,
+					product_id: item.product_details.product_id
+				};
+				const response = await fetch('https://dev2.mixtech.dev.br/order_item/create', {
+					method: 'POST',
+					headers: myHeaders,
+					body: JSON.stringify(payload)
+				});
+				if (!response.ok) {
+					success = false;
+					console.error('Erro ao enviar item para cozinha:', response.statusText);
+					break;
+				}
+			}
+			if (success) {
+				localOrderItems = [];
+				if (browser) {
+					localStorage.removeItem(`orderItems_${orderId}`);
+				}
+			}
+		} catch (error) {
+			console.error('Erro ao enviar para cozinha:', error);
+		}
 	}
 </script>
 
@@ -229,13 +206,13 @@
 			</div>
 
 			<div class="flex-1 overflow-y-auto p-4">
-				{#if orderItems.length === 0}
+				{#if localOrderItems.length === 0}
 					<div class="py-6 text-center text-gray-400">
 						<img src={cart_icon} class="mx-auto mb-2 h-10 w-10 opacity-50" alt="Nenhum item" />
 						<p>Nenhum item adicionado</p>
 					</div>
 				{:else}
-					{#each orderItems as item, index}
+					{#each localOrderItems as item, index}
 						<div class="bg-gray-750 flex items-center justify-between rounded-lg p-3">
 							<div class="flex-1">
 								<h3 class="font-medium">
@@ -248,7 +225,7 @@
 							</div>
 							<div class="flex items-center space-x-2">
 								<button
-									on:click={() => removeItemFromOrder(tableIdNum, item.order_item_id)}
+									on:click={() => removeItemFromOrder(item.order_item_id)}
 									class="ml-2 rounded bg-red-700 p-1 hover:bg-red-600"
 								>
 									<img src={trash_icon} class="h-4 w-4" alt="Remover" />
@@ -266,83 +243,13 @@
 				</div>
 
 				<button
-					on:click={() => (isPaymentModalOpen = true)}
-					disabled={orderItems.length === 0}
+					on:click={handleSendToKitchen}
+					disabled={localOrderItems.length === 0}
 					class="flex w-full items-center justify-center rounded-lg bg-emerald-600 py-3 font-medium hover:bg-emerald-700 disabled:cursor-not-allowed disabled:opacity-50"
 				>
-					Fechar Atendimento
+					Enviar para Cozinha
 				</button>
 			</div>
 		</div>
 	</div>
-
-	{#if isPaymentModalOpen}
-		<div class="fixed inset-0 z-50 flex items-center justify-center bg-black/70 p-4">
-			<div class="w-full max-w-lg rounded-lg bg-gray-800 p-6 shadow-xl">
-				<h2 class="mb-4 text-xl font-bold">Finalizar Pedido</h2>
-
-				<div class="mb-6">
-					<h3 class="mb-3 text-lg font-medium">Resumo do Pedido</h3>
-					<div class="mb-4 max-h-60 overflow-y-auto sm:max-h-80">
-						{#each orderItems as item}
-							<div class="flex justify-between border-b border-gray-700 py-2">
-								<span
-									>{item.quantity ?? 1}x {item.product_details?.product_name ??
-										'Nome Indisponível'}</span
-								>
-								<span
-									>R$ {(
-										Number(item.product_details?.product_price ?? 0) * (item.quantity ?? 1)
-									).toFixed(2)}</span
-								>
-							</div>
-						{/each}
-					</div>
-					<div class="flex justify-between text-lg font-semibold">
-						<span>Total:</span>
-						<span>R$ {totalAmount.toFixed(2)}</span>
-					</div>
-				</div>
-
-				<h3 class="mb-3 text-lg font-medium">Forma de Pagamento</h3>
-				<div class="mb-6 grid grid-cols-1 gap-3 sm:grid-cols-2">
-					{#each ['CASH', 'PIX', 'DEBIT', 'CREDIT'] as method}
-						<button
-							class="flex flex-col items-center justify-center rounded-lg border-2 p-4 transition-colors {selectedPaymentMethod ===
-							method
-								? 'border-emerald-500 bg-emerald-900/20'
-								: 'border-gray-700 hover:border-gray-600'}"
-							on:click={() => (selectedPaymentMethod = method)}
-						>
-							<span
-								>{method === 'CASH'
-									? 'Dinheiro'
-									: method === 'PIX'
-										? 'Pix'
-										: method === 'DEBIT'
-											? 'Cart\u00e3o de D\u00e9bito'
-											: 'Cart\u00e3o de Cr\u00e9dito'}</span
-							>
-						</button>
-					{/each}
-				</div>
-
-				<div class="flex space-x-3">
-					<button
-						on:click={() => (isPaymentModalOpen = false)}
-						class="flex-1 rounded-lg bg-gray-700 py-3 font-medium hover:bg-gray-600"
-					>
-						Cancelar
-					</button>
-					<button
-						on:click={handlePaymentConfirm}
-						disabled={!selectedPaymentMethod}
-						class="flex-1 rounded-lg bg-emerald-600 py-3 font-medium hover:bg-emerald-700 disabled:cursor-not-allowed disabled:opacity-50"
-					>
-						Confirmar Pagamento
-					</button>
-				</div>
-			</div>
-		</div>
-	{/if}
 </div>

+ 63 - 37
src/lib/component/Report.svelte

@@ -1,17 +1,8 @@
 <script>
 	import { onMount } from 'svelte';
-	// import calendar_icon from '$lib/assets/calendar.svg';
-	// import creditcard_icon from '$lib/assets/creditcard.svg';
-	// import search_icon from '$lib/assets/search.svg';
-	// import filter_icon from '$lib/assets/filter.svg';
-	// import download_icon from '$lib/assets/download.svg';
-	// import dollar_icon from '$lib/assets/dollar.svg';
-	// import trash_icon from '$lib/assets/trash.svg';
-	// import x_icon from '$lib/assets/x.svg';
-	// import arrow_icon from '$lib/assets/arrow.svg';
+	import { browser } from '$app/environment';
 
 	let sales = [];
-
 	let dateFilter = '';
 	let paymentMethodFilter = '';
 	let searchTerm = '';
@@ -20,10 +11,66 @@
 	let selectedSale = null;
 	let isDayClosingModalOpen = false;
 
+	let token = null;
+	let company = null;
+	let orderId = null;
+
+	if (browser) {
+		token = localStorage.getItem('token');
+		company = Number(localStorage.getItem('company'));
+		orderId = Number(localStorage.getItem('order'));
+	}
+
 	onMount(async () => {
-		const res = await fetch('/api/sales'); // trocar as api e rever a logica
+		const myHeaders = new Headers();
+		myHeaders.append('Authorization', `Bearer ${token}`);
+		myHeaders.append('Content-Type', 'application/json');
+
+		const raw = JSON.stringify({
+			company_id: company
+		});
+
+		const requestOptions = {
+			method: 'POST',
+			headers: myHeaders,
+			body: raw,
+			redirect: 'follow'
+		};
+
+		try {
+			const response = await fetch('https://dev2.mixtech.dev.br/order_item/get', requestOptions);
+			const result = await response.json();
+
+			if (result.status === 'ok' && result.data) {
+				// Agrupar itens por order_id e transformar em formato de sales
+				const itemsByOrder = result.data.reduce((acc, item) => {
+					const orderId = item.order_id;
+					if (!acc[orderId]) {
+						acc[orderId] = [];
+					}
+					acc[orderId].push({
+						productName: item.product_details.product_name,
+						quantity: 1, // Suposição: quantidade fixa de 1
+						priceAtSale: parseFloat(item.product_details.product_price)
+					});
+					return acc;
+				}, {});
 
-		sales = await res.json();
+				// Converter para o formato de sales
+				sales = Object.entries(itemsByOrder).map(([orderId, items], index) => ({
+					id: parseInt(orderId),
+					timestamp: new Date().toISOString(), // Data atual como padrão
+					tableId: 1, // Valor fixo como padrão
+					items,
+					totalAmount: items.reduce((sum, item) => sum + item.priceAtSale * item.quantity, 0),
+					paymentMethod: 'CASH' // Valor padrão
+				}));
+			} else {
+				console.error('Erro na resposta da API:', result.msg);
+			}
+		} catch (error) {
+			console.error('Erro ao buscar dados:', error);
+		}
 	});
 
 	function formatDate(dateStr) {
@@ -147,7 +194,6 @@
 					on:click={() => (isDayClosingModalOpen = true)}
 					class="flex w-full items-center justify-center rounded-lg bg-[#D4AF37] px-4 py-2 text-[#1C1C1E] transition-colors hover:bg-[#D4AF37]/90 sm:w-auto"
 				>
-					<!-- <img src={dollar_icon} alt="Fechamento do dia" class="mr-2 h-5 w-5" /> -->
 					Fechamento do Dia
 				</button>
 				<button
@@ -155,7 +201,6 @@
 					disabled={filteredSales.length === 0}
 					class="flex w-full items-center justify-center rounded-lg bg-[#2C2C2E] px-4 py-2 transition-colors hover:bg-[#3C3C3E] disabled:cursor-not-allowed disabled:opacity-50 sm:w-auto"
 				>
-					<!-- <img src={download_icon} alt="Exportar CSV" class="mr-2 h-5 w-5" /> -->
 					Exportar CSV
 				</button>
 			</div>
@@ -187,9 +232,7 @@
 					<div class="relative">
 						<div
 							class="pointer-events-none absolute inset-y-0 left-0 flex items-center pl-3 text-[#A0A0A0]"
-						>
-							<!-- <img src={calendar_icon} alt="" class="h-5 w-5" /> -->
-						</div>
+						></div>
 						<input
 							type="date"
 							id="dateFilter"
@@ -206,9 +249,7 @@
 					<div class="relative">
 						<div
 							class="pointer-events-none absolute inset-y-0 left-0 flex items-center pl-3 text-[#A0A0A0]"
-						>
-							<!-- <img src={creditcard_icon} alt="" class="h-5 w-5" /> -->
-						</div>
+						></div>
 						<select
 							id="paymentMethodFilter"
 							bind:value={paymentMethodFilter}
@@ -230,9 +271,7 @@
 					<div class="relative">
 						<div
 							class="pointer-events-none absolute inset-y-0 left-0 flex items-center pl-3 text-[#A0A0A0]"
-						>
-							<!-- <img src={search_icon} alt="" class="h-5 w-5" /> -->
-						</div>
+						></div>
 						<input
 							type="text"
 							id="searchTerm"
@@ -252,7 +291,6 @@
 						}}
 						class="flex w-full items-center justify-center rounded-lg bg-[#1C1C1E] px-4 py-2 transition-colors hover:bg-[#2C2C2E]"
 					>
-						<!-- <img src={filter_icon} alt="" class="mr-2 h-5 w-5" /> -->
 						Limpar Filtros
 					</button>
 				</div>
@@ -268,11 +306,6 @@
 						>
 							<button on:click={() => toggleSort('date')} class="flex items-center">
 								Data/Hora
-								<!-- <img
-									src={arrow_icon}
-									class="ml-1 h-4 w-4 {sortBy === 'date' ? 'text-gold' : 'text-gray'}"
-									alt=""
-								/> -->
 							</button>
 						</th>
 						<th>Mesa</th>
@@ -280,11 +313,6 @@
 						<th>
 							<button on:click={() => toggleSort('amount')} class="flex items-center">
 								Total
-								<!-- <img
-									src={arrow_icon}
-									class="ml-1 h-4 w-4 {sortBy === 'amount' ? 'text-gold' : 'text-gray'}"
-									alt=""
-								/> -->
 							</button>
 						</th>
 						<th>Pagamento</th>
@@ -322,7 +350,6 @@
 										on:click|stopPropagation={() => handleCancelSale(sale.id)}
 										class="rounded-lg p-1.5 text-[#FF3B30] hover:bg-[#FF3B30]/20"
 									>
-										<!-- <img src={trash_icon} alt="Cancelar" class="h-4 w-4" /> -->
 									</button>
 								</td>
 							</tr>
@@ -353,7 +380,7 @@
 							<div class="text-xs text-[#A0A0A0]">
 								Itens: <span class="line-clamp-1 text-white"
 									>{sale.items
-										.map((item) => `${item.quantity}x ${item.productName}`)
+										.map((item) => `${item.quantity}x ${item.productName}`)
 										.join(', ')}</span
 								>
 							</div>
@@ -366,7 +393,6 @@
 									on:click|stopPropagation={() => handleCancelSale(sale.id)}
 									class="rounded-lg p-1.5 text-[#FF3B30] hover:bg-[#FF3B30]/20"
 								>
-									<!-- <img src={trash_icon} alt="Cancelar" class="h-4 w-4" /> -->
 								</button>
 							</div>
 						</div>