Export production orders with missing data
All checks were successful
Build and Deploy / build-and-deploy (push) Successful in 1m2s
All checks were successful
Build and Deploy / build-and-deploy (push) Successful in 1m2s
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
import { useCallback, useEffect, useMemo, useState } from 'react';
|
||||
import { AlertTriangle, CheckCircle2, CloudDownload, Database, FileUp, Link2, Loader2, RefreshCw, ScrollText, Square, Timer, X, XCircle } from 'lucide-react';
|
||||
import { fetchOlistRunDetails, fetchOlistStatus, fetchProductionOrderImportData, getOlistAuthorizationUrl, importFinalizedProductionOrderCsv, startOlistCompositionSync, stopOlistCompositionSync } from '../dataService';
|
||||
import { AlertTriangle, CheckCircle2, CloudDownload, Database, Download, FileUp, Link2, Loader2, RefreshCw, ScrollText, Square, Timer, X, XCircle } from 'lucide-react';
|
||||
import { exportMissingProductionOrderDataCsv, fetchOlistRunDetails, fetchOlistStatus, fetchProductionOrderImportData, getOlistAuthorizationUrl, importFinalizedProductionOrderCsv, startOlistCompositionSync, stopOlistCompositionSync } from '../dataService';
|
||||
import type { OlistRunDetails, OlistStatus, OlistSyncRun, ProductionOrderImportData } from '../types';
|
||||
|
||||
const formatDateTime = (value: string | null) => {
|
||||
@@ -50,6 +50,7 @@ const OlistSync = () => {
|
||||
const [isDetailsLoading, setIsDetailsLoading] = useState(false);
|
||||
const [importData, setImportData] = useState<ProductionOrderImportData | null>(null);
|
||||
const [isImportingOrders, setIsImportingOrders] = useState(false);
|
||||
const [isExportingPendingOrders, setIsExportingPendingOrders] = useState(false);
|
||||
const [importMessage, setImportMessage] = useState('');
|
||||
|
||||
const loadStatus = useCallback(async (initial = false) => {
|
||||
@@ -167,6 +168,19 @@ const OlistSync = () => {
|
||||
}
|
||||
};
|
||||
|
||||
const exportPendingOrders = async () => {
|
||||
setIsExportingPendingOrders(true);
|
||||
setImportMessage('');
|
||||
try {
|
||||
const totalRows = await exportMissingProductionOrderDataCsv();
|
||||
setImportMessage(totalRows ? `${totalRows.toLocaleString('pt-BR')} OPs com pendências exportadas para completar.` : 'Nenhuma OP finalizada possui pendências de dados.');
|
||||
} catch (actionError) {
|
||||
setError(actionError instanceof Error ? actionError.message : 'Não foi possível exportar as pendências das OPs.');
|
||||
} finally {
|
||||
setIsExportingPendingOrders(false);
|
||||
}
|
||||
};
|
||||
|
||||
const openRunDetails = (runId: number) => {
|
||||
const initialPages = { events: 1, products: 1 };
|
||||
setDetailsPages(initialPages);
|
||||
@@ -189,6 +203,9 @@ const OlistSync = () => {
|
||||
<button type="button" onClick={() => void loadStatus()} className="inline-flex h-10 items-center gap-2 rounded-xl border border-dark-border bg-dark-card px-4 text-sm font-bold text-dark-text transition-colors hover:border-brand-primary cursor-pointer">
|
||||
<RefreshCw className="h-4 w-4" /> Atualizar
|
||||
</button>
|
||||
<button type="button" onClick={() => void exportPendingOrders()} disabled={isExportingPendingOrders} className="inline-flex h-10 items-center gap-2 rounded-xl border border-dark-border bg-dark-card px-4 text-sm font-bold text-dark-text transition-colors hover:border-brand-primary disabled:cursor-not-allowed disabled:opacity-60 cursor-pointer">
|
||||
{isExportingPendingOrders ? <Loader2 className="h-4 w-4 animate-spin" /> : <Download className="h-4 w-4 text-brand-primary" />} Exportar pendências
|
||||
</button>
|
||||
<label className={`inline-flex h-10 items-center gap-2 rounded-xl border border-dark-border bg-dark-card px-4 text-sm font-bold text-dark-text transition-colors hover:border-brand-primary ${isImportingOrders ? 'cursor-wait opacity-60' : 'cursor-pointer'}`}>
|
||||
{isImportingOrders ? <Loader2 className="h-4 w-4 animate-spin" /> : <FileUp className="h-4 w-4 text-brand-primary" />} Importar OPs finalizadas
|
||||
<input type="file" accept=".csv,text/csv" className="sr-only" disabled={isImportingOrders} onChange={(event) => { void importOrders(event.target.files?.[0] || null); event.currentTarget.value = ''; }} />
|
||||
@@ -216,7 +233,7 @@ const OlistSync = () => {
|
||||
</div>
|
||||
|
||||
{error && <div className="rounded-2xl border border-red-400/30 bg-red-400/10 px-4 py-3 text-sm font-bold text-red-300">{error}</div>}
|
||||
{importMessage && <div className="rounded-2xl border border-emerald-400/30 bg-emerald-400/10 px-4 py-3 text-sm font-bold text-emerald-300">Importação concluída: {importMessage}</div>}
|
||||
{importMessage && <div className="rounded-2xl border border-emerald-400/30 bg-emerald-400/10 px-4 py-3 text-sm font-bold text-emerald-300">{importMessage.startsWith('Nenhuma') || importMessage.includes('exportadas') ? 'Exportação pronta: ' : 'Importação concluída: '}{importMessage}</div>}
|
||||
{!status?.configured && <div className="rounded-2xl border border-amber-400/30 bg-amber-400/10 px-4 py-3 text-sm font-bold text-amber-200">Configure as credenciais Olist V3 no ambiente antes de conectar.</div>}
|
||||
|
||||
<div className="grid grid-cols-1 gap-4 md:grid-cols-3">
|
||||
|
||||
Reference in New Issue
Block a user