Переглянути джерело

add the cancel order on the frontend

gdias 1 місяць тому
батько
коміт
7c6e0fc434
1 змінених файлів з 91 додано та 9 видалено
  1. 91 9
      src/routes/trading/+page.svelte

+ 91 - 9
src/routes/trading/+page.svelte

@@ -49,6 +49,8 @@
   let orderDetailModalVisible = false;
   let orderDetailSelected = null;
   let orderDetailEntries = [];
+  let orderCancelLoading = false;
+  let orderCancelError = '';
   let orderPaymentId = null;
   let orderPaymentCode = '';
   let orderPaymentExternalId = '';
@@ -179,9 +181,32 @@
     'currencyId',
     'Currency_id',
     'CurrencyId',
-    'CURRENCY_ID'
+    'CURRENCY_ID',
+    'editable',
+    'Editable',
+    'EDITABLE'
   ]);
 
+  function normalizeBoolean(value) {
+    if (value === true || value === false) return value;
+    if (typeof value === 'number') return value === 1;
+    if (typeof value === 'string') {
+      const normalized = value.trim().toLowerCase();
+      if (normalized === 'true') return true;
+      if (normalized === 'false') return false;
+    }
+    return false;
+  }
+
+  function resolveOrderEditable(order = {}) {
+    const raw = order?.raw && typeof order.raw === 'object' ? order.raw : order;
+    return normalizeBoolean(raw?.editable);
+  }
+
+  function resolveOrderbookId(order = {}) {
+    return order?.orderbookId ?? order?.orderbook_id ?? order?.raw?.orderbook_id ?? order?.raw?.orderbookId ?? null;
+  }
+
   const orderDetailFieldConfig = [
     {
       keys: ['orderbook_flag', 'orderbookFlag'],
@@ -316,10 +341,13 @@
       city: resolvedCity,
       cityName: resolvedCity,
       measureUnitName: resolvedMeasureUnit,
-      orderbookId: order?.orderbookId ?? order?.orderbook_id ?? order?.raw?.orderbook_id ?? null,
+      orderbookId: resolveOrderbookId(order),
       tokenExternalId: order?.tokenExternalId ?? order?.token_external_id ?? order?.raw?.token_external_id ?? '',
+      editable: resolveOrderEditable(order),
       raw: order?.raw ?? order
     };
+    orderCancelError = '';
+    orderCancelLoading = false;
     orderDetailEntries = buildOrderDetailEntries(orderDetailSelected);
     orderDetailModalVisible = true;
   }
@@ -328,6 +356,51 @@
     orderDetailModalVisible = false;
     orderDetailEntries = [];
     orderDetailSelected = null;
+    orderCancelError = '';
+    orderCancelLoading = false;
+  }
+
+  async function cancelOrderbookOrder() {
+    if (orderCancelLoading) return;
+    orderCancelError = '';
+
+    const orderbookIdRaw = resolveOrderbookId(orderDetailSelected);
+    const orderbookId = Number(orderbookIdRaw);
+    if (!Number.isInteger(orderbookId) || orderbookId <= 0) {
+      orderCancelError = 'Ordem inválida para cancelamento.';
+      return;
+    }
+
+    const token = get(authToken);
+    if (!token) {
+      orderCancelError = 'Sessão expirada. Faça login novamente.';
+      return;
+    }
+
+    orderCancelLoading = true;
+    try {
+      const res = await fetch(`${apiUrl}/orderbook/cancel`, {
+        method: 'POST',
+        headers: {
+          'content-type': 'application/json',
+          Authorization: `Bearer ${token}`
+        },
+        body: JSON.stringify({ orderbook_id: orderbookId })
+      });
+      const body = await parseResponse(res);
+      const isSuccess = res.ok && body?.status === 'ok' && body?.code === 'S_ORDERBOOK_STATUS_UPDATED';
+      if (!isSuccess) {
+        throw new Error(body?.msg ?? body?.message ?? 'Falha ao cancelar ordem.');
+      }
+      orderbookSuccessMessage = body?.msg ?? 'Ordem cancelada com sucesso.';
+      closeOrderDetailModal();
+      await fetchOrderbook(selectedState, selectedCommodity);
+    } catch (err) {
+      console.error('[Trading] Falha ao cancelar ordem do orderbook:', err);
+      orderCancelError = err?.message ?? 'Não foi possível cancelar a ordem.';
+    } finally {
+      orderCancelLoading = false;
+    }
   }
 
   function handleOrderDetailPurchase() {
@@ -1364,6 +1437,12 @@ $: displayPendingSells = pendingSells.map((o) => ({
           {/if}
         </div>
 
+        {#if orderCancelError}
+          <div class="rounded border border-red-200 dark:border-red-700 bg-red-50 dark:bg-red-900/30 text-red-700 dark:text-red-200 px-3 py-2 text-sm">
+            {orderCancelError}
+          </div>
+        {/if}
+
         <div class="flex flex-col gap-2">
           <button
             class="w-full rounded bg-green-600 hover:bg-green-700 text-white font-semibold py-2 disabled:opacity-60"
@@ -1372,13 +1451,16 @@ $: displayPendingSells = pendingSells.map((o) => ({
           >
             Comprar esta ordem
           </button>
-          <button
-            type="button"
-            class="w-full rounded border border-gray-300 dark:border-gray-600 py-2 text-gray-700 dark:text-gray-200 hover:bg-gray-50 dark:hover:bg-gray-800"
-            on:click={closeOrderDetailModal}
-          >
-            Cancelar
-          </button>
+          {#if orderDetailSelected?.editable}
+            <button
+              type="button"
+              class="w-full rounded border border-gray-300 dark:border-gray-600 py-2 text-gray-700 dark:text-gray-200 hover:bg-gray-50 dark:hover:bg-gray-800 disabled:opacity-60"
+              on:click={cancelOrderbookOrder}
+              disabled={orderCancelLoading}
+            >
+              {orderCancelLoading ? 'Cancelando...' : 'Cancelar'}
+            </button>
+          {/if}
         </div>
       </div>
     {:else}