瀏覽代碼

fix the most details

gdias 1 周之前
父節點
當前提交
871727c891

+ 53 - 2
src/lib/components/trading/BoletaVenda.svelte

@@ -55,9 +55,12 @@
   }) ?? null;
 
   $: tokenLockedState = selectedToken?.token_uf ?? '';
+  const SACK_PACKAGING_LABEL = 'saca (60 kg)';
+  const SACK_WEIGHT_KG = 60;
+
   $: displayCommodityName = selectedToken?.cpr_product_name ?? commodity ?? '';
-  $: displayCommodityValue = selectedToken?.token_commodities_value ?? null;
-  $: displayCommodityAmount = selectedToken?.token_commodities_amount ?? null;
+  $: displayCommodityValue = deriveDisplayCommodityValue(selectedToken);
+  $: displayCommodityAmount = deriveDisplayCommodityAmount(selectedToken);
   $: quantidade = displayCommodityAmount != null ? String(displayCommodityAmount) : '';
   $: referencia = selectedToken ? formatBRL(displayCommodityValue ?? 0) : 'BRL : 12';
   $: if (tokenLockedState) {
@@ -119,6 +122,54 @@
       currency: 'BRL'
     }).format(Number(n || 0));
   }
+
+  function normalizePackaging(value = '') {
+    return value
+      ?.toString?.()
+      ?.normalize?.('NFD')
+      ?.replace?.(/\p{Diacritic}/gu, '')
+      ?.trim()
+      ?.toLowerCase?.();
+  }
+
+  function isSackPackaging(value = '') {
+    const normalized = normalizePackaging(value);
+    if (!normalized) return false;
+    if (normalized === SACK_PACKAGING_LABEL) return true;
+    return normalized.includes('saca') && normalized.includes('60');
+  }
+
+  function deriveDisplayCommodityAmount(token) {
+    if (!token) return null;
+    const rawAmount = token?.token_commodities_amount;
+    if (rawAmount == null) return null;
+    const numericAmount = Number(rawAmount);
+    if (!Number.isFinite(numericAmount)) {
+      return null;
+    }
+    if (isSackPackaging(token?.cpr_packaging_way_name)) {
+      return numericAmount / SACK_WEIGHT_KG;
+    }
+    return numericAmount;
+  }
+
+  function deriveDisplayCommodityValue(token) {
+    if (!token) return null;
+    const rawValue = token?.token_commodities_value;
+    if (rawValue == null) return null;
+    const numericValue = Number(rawValue);
+    if (!Number.isFinite(numericValue)) {
+      return null;
+    }
+    if (isSackPackaging(token?.cpr_packaging_way_name)) {
+      const rawAmount = Number(token?.token_commodities_amount ?? 0);
+      const adjustedQuantity = rawAmount ? rawAmount / SACK_WEIGHT_KG : 0;
+      if (adjustedQuantity) {
+        return numericValue / adjustedQuantity;
+      }
+    }
+    return numericValue;
+  }
 </script>
 <ModalBase title="Boleta de Venda" {visible} {onClose}>
   <div class="space-y-4">

+ 3 - 1
src/lib/components/trading/TabelaOrdens.svelte

@@ -40,6 +40,7 @@
   let tooltipPrice = 0;
   let tooltipQty = 0;
   let tooltipStyle = 'top:0px;left:0px;';
+  let tooltipTotal = 0;
 
   function scheduleTooltip(event, order) {
     if (hoverTimer) clearTimeout(hoverTimer);
@@ -51,6 +52,7 @@
       tooltipCity = order?.cityName || order?.city || '';
       tooltipPrice = Number(order?.valor ?? 0);
       tooltipQty = Number(order?.quantidade ?? 0);
+      tooltipTotal = Number(order?.total ?? order?.raw?.token_commodities_value ?? (tooltipPrice * tooltipQty));
       tooltipStyle = `top:${top}px;left:${left}px;`;
       tooltipVisible = true;
     }, 300);
@@ -178,7 +180,7 @@
         </div>
         <div class="text-sm pt-1 border-t border-gray-100 dark:border-gray-700">
           <div class="text-[11px] uppercase tracking-wide text-gray-400 dark:text-gray-500">Valor total</div>
-          <div class="text-gray-900 dark:text-gray-100 font-semibold">{formatBRL(tooltipPrice * tooltipQty)}</div>
+          <div class="text-gray-900 dark:text-gray-100 font-semibold">{formatBRL(tooltipTotal)}</div>
         </div>
       </div>
     </div>

+ 33 - 2
src/routes/trading/+page.svelte

@@ -17,6 +17,7 @@
   const ORDERBOOK_PAYMENT_STORAGE_PREFIX = 'tooeasy_orderbook_payment_';
   const CIDADES_ESTADOS_SRC = 'https://cdn.jsdelivr.net/npm/cidades-estados@1.4.1/cidades-estados.js';
   const DEFAULT_STATE_OPTIONS = ['AC','AL','AP','AM','BA','CE','DF','ES','GO','MA','MT','MS','MG','PA','PB','PR','PE','PI','RJ','RN','RS','RO','RR','SC','SP','SE','TO'];
+  const PACKAGING_SACK_LABEL = 'saca (60 kg)';
 
   const orders = writable([]);
 
@@ -75,6 +76,32 @@
     return raw ? JSON.parse(raw) : null;
   }
 
+  function resolvePackagingValue(source = {}) {
+    return pickNonEmptyString(source, [
+      'packagingName',
+      'packaging_name',
+      'packagingname',
+      'Packagingname',
+      'PACKAGINGNAME'
+    ]);
+  }
+
+  function normalizePackaging(value = '') {
+    return value
+      ?.toString?.()
+      ?.normalize?.('NFD')
+      ?.replace?.(/\p{Diacritic}/gu, '')
+      ?.trim()
+      ?.toLowerCase?.();
+  }
+
+  function isSackPackaging(value = '') {
+    const normalized = normalizePackaging(value);
+    if (!normalized) return false;
+    if (normalized === PACKAGING_SACK_LABEL) return true;
+    return normalized.includes('saca') && normalized.includes('60');
+  }
+
   function pickNonEmptyString(source = {}, keys = []) {
     if (!source || typeof source !== 'object') return '';
     for (const key of keys) {
@@ -316,7 +343,11 @@
   function mapOrderResponse(item = {}) {
     const totalValue = Number(item?.token_commodities_value ?? item?.valor ?? 0);
     const quantidade = Number(item?.orderbook_amount ?? item?.token_commodities_amount ?? item?.quantidade ?? 0);
-    const valorPorSaca = quantidade ? totalValue / quantidade : totalValue;
+    const packagingName = resolvePackagingValue(item) || resolvePackagingValue(item?.raw ?? {});
+    const adjustedQuantity = isSackPackaging(packagingName) && quantidade
+      ? quantidade / 60
+      : quantidade;
+    const valorPorSaca = adjustedQuantity ? totalValue / adjustedQuantity : totalValue;
     const resolvedCity = resolveCityValue(item);
     const resolvedMeasureUnit = resolveMeasureUnitValue(item);
     return {
@@ -1072,7 +1103,7 @@
         token_external_id: tokenExternalId
       };
 
-      const res = await fetch(`${apiUrl}  `, {
+      const res = await fetch(`${apiUrl}/token/orderbook`, {
         method: 'POST',
         headers: {
           'content-type': 'application/json',