HEX
Server: Microsoft-IIS/10.0
System: Windows NT ITPWINWEBSVR22 10.0 build 20348 (Windows Server 2022) AMD64
User: www.conferencesearch.co.uk (0)
PHP: 8.3.30
Disabled: NONE
Upload Files
File: D:/web/hyperflight/apps/inxpress/app/templates/shipments_parsed - Copy (4).html
{% extends "base.html" %}
{% block title %}InXpress — Shipments{% endblock %}

{% block content %}


{% macro sort_link(label, col, tip=None) -%}
  {%- set newdir = 'asc' if sort != col or direction == 'desc' else 'desc' -%}
  <a class="link-body-emphasis text-decoration-none"
     href="{{ url_for('shipments_parsed',
                      q=q,
                      carrier=carrier,
                      country=country,
                      from=date_from,
                      to=date_to,
                      pagesize=pagesize_raw,
                      duponly=1 if duponly else None,
                      noorder=1 if noorder else None,
                      details=1 if show_details else None,
                      page=1,
                      sort=col,
                      dir=newdir) }}"
     {% if tip %}
       data-bs-toggle="tooltip"
       data-bs-placement="top"
       title="{{ tip }}"
     {% endif %}>
    {{ label }}
    {% if sort == col %}
      <span class="small">{{ '▲' if direction == 'asc' else '▼' }}</span>
    {% endif %}
  </a>
{%- endmacro %}




{% macro ref_badge(val) -%}
  {% set raw = (val or '') %}
  {% set key = raw|norm_ref %}
  {% if key and duplicates.get(key, 0) > 1 %}
    <span class="badge bg-warning-subtle text-warning-emphasis"
          title="Duplicate reference ({{ duplicates[key] }} occurrences)">
      {{ raw }}
    </span>
  {% else %}
    {{ raw }}
  {% endif %}
{%- endmacro %}

{% if not show_details %}
<style>
  /* hide detailed columns in simple view */
  .detail-col {
    display: none;
  }
</style>
{% endif %}


<!--
<div class="d-flex align-items-center justify-content-between mb-3">
  <h1 class="h4 mb-0">Shipments</h1>
  <div class="text-muted small">Total: {{ total }}</div>
</div>
-->

<form method="get" id="filterForm" 
      action="{{ url_for('shipments_parsed') }}"
      class="row row-cols-1 row-cols-lg-auto g-2 align-items-end mb-3">
      
  {# Keep current sort & direction when applying filters #}
  <input type="hidden" name="sort" value="{{ sort }}">
  <input type="hidden" name="dir" value="{{ dir }}">
  <input type="hidden" name="page" value="1">

  <div class="col-auto">
    <label for="q" class="form-label mb-0">Search</label>
    <input id="q" name="q" type="text"
           class="form-control search-narrow"
           value="{{ q or '' }}"
           placeholder="Ref / name / airbill"
           onkeydown="if(event.key==='Enter'){ this.form.page.value=1; }">
  </div>



  <div class="col">
    <label class="form-label">Invoice</label>
    <select name="invoice" class="form-select"
            onchange="this.form.page.value=1; this.form.submit()">
      <option value="">All invoices</option>
      {% for inv in invoices %}
        <option value="{{ inv }}" {{ 'selected' if invoice==inv else '' }}>{{ inv }}</option>
      {% endfor %}
    </select>
  </div>

  <div class="col">
    <label class="form-label">Carrier</label>
    <select name="carrier" class="form-select"
            onchange="this.form.page.value=1; this.form.submit()">
      <option value="">All carriers</option>
      {% for c in carriers %}
        <option value="{{ c }}" {{ 'selected' if carrier==c else '' }}>{{ c }}</option>
      {% endfor %}
    </select>
  </div>

  <div class="col">
    <label class="form-label">Country</label>
    <select name="country" class="form-select" style="width:14rem"
            onchange="this.form.page.value=1; this.form.submit()">
      <option value="">All countries</option>
      {% for c in countries %}
        <option value="{{ c.cc }}" {{ 'selected' if country==c.cc else '' }}>
          {{ c.name }} ({{ c.cc }})
        </option>
      {% endfor %}
    </select>
  </div>

  <div class="col">
    <label class="form-label">From</label>
    <input type="date" name="from" class="form-control" lang="en-GB"
           value="{{ date_from_iso or '' }}"
           onchange="this.form.page.value=1; this.form.submit()">
  </div>
  <div class="col">
    <label class="form-label">To</label>
    <input type="date" name="to" class="form-control" lang="en-GB"
           value="{{ date_to_iso or '' }}"
           onchange="this.form.page.value=1; this.form.submit()">
  </div>


  <div class="col">
    <label class="form-label">Page size</label>
      <select name="pagesize" class="form-select" style="width:8rem"
            onchange="this.form.page.value=1; this.form.submit()">
      <option value="25"  {{ 'selected' if pagesize_raw=='25' else '' }}>25</option>
      <option value="50"  {{ 'selected' if pagesize_raw=='50' else '' }}>50</option>
      <option value="100" {{ 'selected' if pagesize_raw=='100' else '' }}>100</option>
      <option value="200" {{ 'selected' if pagesize_raw in ['200',''] else '' }}>200</option>
      <option value="all" {{ 'selected' if pagesize_raw=='all' else '' }}>All records</option>
    </select>
  </div>
  
  <!-- Duplicates + No matching order stacked -->
  <div class="col-auto">
    <div class="d-flex flex-column">
      <div class="form-check">
        <input class="form-check-input" type="checkbox" id="duponly" name="duponly"
               value="1" {{ 'checked' if duponly else '' }}
               onchange="this.form.page.value=1; this.form.submit()">
        <label class="form-check-label" for="duponly">Duplicates only</label>
      </div>

      <div class="form-check">
        <input class="form-check-input" type="checkbox" id="noorder" name="noorder"
               value="1" {{ 'checked' if noorder else '' }}
               onchange="this.form.page.value=1; this.form.submit()">
        <label class="form-check-label" for="noorder">No matching order</label>
      </div>

      <div class="form-check">
        <input class="form-check-input"
               type="checkbox"
               id="details"
               name="details"
               value="1"
               {% if show_details %}checked{% endif %}
               onchange="this.form.page.value=1; this.form.submit();">
        <label class="form-check-label" for="details">
          More details
        </label>
      </div>      
      
    </div>
  </div>
  

  <div class="col">
    <button type="submit" class="btn btn-primary">Apply</button>
    {% if q or invoice or carrier or country or date_from_iso or date_to_iso
          or (pagesize_raw and pagesize_raw != '50') %}
      <a class="btn btn-outline-secondary ms-1" href="{{ url_for('shipments_parsed') }}">Clear</a>
    {% endif %}
  </div>

</form>




<div class="table-sticky-wrap">
  <table class="table table-sm align-middle mb-0">
    <thead class="table-light">
      <tr>
        <th class="text-end">{{ sort_link('ID','shipment_id') }}</th>
        <th>{{ sort_link('Date','ShipDate') }}</th>
        <th>{{ sort_link('Carrier','Carrier') }}</th>
        <th class="detail-col">{{ sort_link('Service','ServiceType') }}</th>        
        <th>{{ sort_link('Country','DestCountry') }}</th>  {# still sorts by destination #}
        <th class="detail-col text-center">{{ sort_link('Zone','Zone') }}</th>   <!-- centered -->
        <th>{{ sort_link('Refs','Reference') }}</th>                   <!-- moved here -->
        <th>{{ sort_link('Receiver','ReceiverName') }}</th>            <!-- moved here -->
        <th class="text-end">{{ sort_link('Pcs','Pieces') }}</th>
        <th class="text-end">{{ sort_link('Weight','WeightKg') }}</th>
        <th class="text-end">{{ sort_link('L × W × H','Length') }}</th>
        <th class="detail-col text-end">{{ sort_link('Base (£)','BaseCharge') }}</th>
        <th class="detail-col text-end">{{ sort_link('Fuel (£)','FuelSurcharge') }}</th>
        <th class="detail-col text-end">Other (£)</th>
        <th class="detail-col text-end">{{ sort_link('VAT (£)','VATAmount') }}</th>
        <th class="detail-col text-end">{{ sort_link('Total (£)','Total') }}</th>
        
        <th class="text-end col-money">{{ sort_link('Charge (£)',   'Charge',       'Delivery charged to the customer from order Delivery field, with VAT removed') }}</th>
        <th class="text-end col-money">{{ sort_link('Calc (£)',     'Calculated',   'Calculated delivery cost (before markup) from the website (DeliveryCalculatedCost)') }}</th>        
        <th class="text-end col-money">{{ sort_link('Quote (£)',    'Cost',         'Quote from Webship stored in order DeliveryAgentCost field') }}</th>          
        <th class="text-end col-money">{{ sort_link('Invoice (£)',  'NetAmount',    'Net shipment charge from Inxpress invoice, with VAT removed') }}</th>                
        
        <th class="text-end col-costdelta">{{ sort_link('Cost Δ',   'DiffCost',     'Invoice − Quote. Positive (red) = shipment more expensive than Webship quote.') }}</th>        
        <th class="text-end col-costdelta">{{ sort_link('Cost Δ %', 'DiffCostPct',  '(Invoice − Quote) ÷ Quote × 100%') }}</th>
        
        <th class="text-end col-calcdelta">{{ sort_link('Calc Δ',   'DiffCalc',     'Invoice − Calc. Difference between Inxpress invoice and website calculation (before markup).') }}</th>
        <th class="text-end col-calcdelta">{{ sort_link('Calc Δ %', 'DiffCalcPct',  '(Invoice − Calc) ÷ Calc × 100%') }}</th>

        
      </tr>
    </thead>

    <tbody>
      {% for r in rows %}
      <tr>       
        <td class="text-end">
          <a
            href="{{ url_for('shipment_detail', shipment_id=r.shipment_id) }}"
            class="open-shipment"
            data-id="{{ r.shipment_id }}"
            data-invoice="{{ r.invoice_number or '' }}"
            onclick="return openShipmentModal(this);" 
          >{{ r.shipment_id }}</a>
        </td>



        <td class="text-nowrap">{{ r.ShipDate|fmt_date }}</td>
        <td class="text-nowrap">{{ r.Carrier }}</td>
        <!--<td class="text-truncate" style="max-width: 240px;">{{ r.ServiceType }}</td>-->
        <td class="detail-col align-middle"><div class="small text-tiny">{{ r.ServiceType }}</div></td>

        {# Country cell: default DEST; if ORIGIN != GB, show ORIGIN with small back arrow #}
        {% set oc = (r.OriginCountry or '')|upper %}
        {% set dc = (r.DestCountry  or '')|upper %}
        {% set use_origin = oc and oc != 'GB' %}

        <td class="text-nowrap align-middle">
          {% if use_origin %}
            <span class="me-1 text-muted small" title="Origin country shown">↩︎</span>
            <img src="{{ url_for('static', filename='flags/' ~ (oc|lower if oc else 'globe') ~ '.svg') }}"
                 width="24" height="18" alt="{{ oc or 'globe' }}" class="flag-img">
            <span class="cc">{{ oc }}</span>
          {% else %}
            <img src="{{ url_for('static', filename='flags/' ~ (dc|lower if dc else 'globe') ~ '.svg') }}"
                 width="24" height="18" alt="{{ dc or 'globe' }}" class="flag-img">
            <span class="cc">{{ dc }}</span>
          {% endif %}
        </td>


        <td class="detail-col text-center">{{ r.Zone }}</td>  <!-- centered -->

        <td class="text-truncate" style="max-width: 300px;">
          {% if r.Reference %}
            <a href="#" class="open-order" data-ref="{{ r.Reference }}" data-shipment-id="{{ r.shipment_id }}">{{ ref_badge(r.Reference) }}</a>
          {% endif %}
          {% if r.Reference2 %} · {{ ref_badge(r.Reference2) }}{% endif %}{% if r.Reference3 %} · {{ ref_badge(r.Reference3) }}{% endif %}
        </td>

        <!--<td class="text-truncate" style="max-width: 260px;">{{ r.ReceiverName }}</td>-->
        <td class="align-middle"><div class="small text-tiny">{{ r.ReceiverName }}</div></td>

        <td class="text-end">{{ r.Pieces }}</td>
        <td class="text-end">{{ r.WeightKg|trim2 }}</td>
        <td class="text-end">
          {% set dims = [r.Length, r.Width, r.Height] %}
          {% if dims[0] or dims[1] or dims[2] %}
            {{ dims[0]|trim2 }}×{{ dims[1]|trim2 }}×{{ dims[2]|trim2 }}
          {% endif %}
        </td>

        <td class="detail-col text-end">{{ r.BaseCharge|blank_if_zero }}</td>
        <td class="detail-col text-end">{{ r.FuelSurcharge|blank_if_zero }}</td>
        <td class="detail-col text-end">{{ r.Other|blank_if_zero }}</td>

        <td class="detail-col text-end">{{ r.VATAmount|fmt }}</td>
        <td class="detail-col text-end fw-semibold">{{ r.Total|fmt }}</td>
        

        {% macro diff_val(v) -%}
          {% if v is not none %}
            {# v > 0 => Net higher than Cost/Calc => bad => red #}
            {% set cls = 'text-danger' if v > 0 else ('text-success' if v < 0 else 'text-body') %}
            <span class="{{ cls }}">{{ '%.2f'|format(v) }}</span>
          {% endif %}
        {%- endmacro %}


        {% macro diff_pct(p) -%}
          {% if p is not none %}
            {# p > 0 => Net higher than Cost/Calc => bad => red #}
            {% set cls = 'text-danger' if p > 0 else ('text-success' if p < 0 else 'text-body') %}
            <span class="{{ cls }}">{{ '%+0.1f%%'|format(p) }}</span>
          {% endif %}
        {%- endmacro %}


        {# values #}
        <td class="text-end col-money">{{ r.Charge|blank_if_zero }}</td>
        <td class="text-end col-money">{{ r.Calculated|blank_if_zero }}</td>        
        <td class="text-end col-money">{{ r.Cost|blank_if_zero }}</td>        
        <td class="text-end col-money">{{ r.NetAmount|fmt }}</td>        

        {# deltas: value + percent #}
        <td class="text-end col-costdelta">{{ diff_val(r.DiffCost) }}</td>
        <td class="text-end col-costdelta">{{ diff_pct(r.DiffCostPct) }}</td>
        
        <td class="text-end col-calcdelta">{{ diff_val(r.DiffCalc) }}</td>
        <td class="text-end col-calcdelta">{{ diff_pct(r.DiffCalcPct) }}</td>


        
      </tr>
      {% endfor %}
    </tbody>

    <tfoot>
      <tr class="table-secondary">
        <!--<td colspan="{{ 11 if show_details else 9 }}" class="text-end fw-semibold">Page totals:</td>-->

        
        <td colspan="{{ 11 if show_details else 9 }}" class="text-muted">
          <div class="d-flex justify-content-between">
            <span class="text-muted small">
              Showing {{ rows|length }} of {{ total }} shipments
            </span>
            <span class="fw-semibold">
              Totals:
            </span>
          </div>
        </td>
        
        <td class="detail-col text-end">{{ sums.BaseCharge|blank_if_zero }}</td>
        <td class="detail-col text-end">{{ sums.FuelSurcharge|blank_if_zero }}</td>
        <td class="detail-col text-end">{{ sums.Other|blank_if_zero }}</td>
        <td class="detail-col text-end">{{ sums.VATAmount|fmt }}</td>
        <td class="detail-col text-end fw-semibold">{{ sums.Total|fmt }}</td>
        
        {# …existing footer cells for other totals… #}

        {# Charge / Cost / Calculated totals #}
        <td class="text-end fw-semibold col-money">{{ sums.Charge     | fmt }}</td>
        <td class="text-end fw-semibold col-money">{{ sums.Calculated | fmt }}</td>
        <td class="text-end fw-semibold col-money">{{ sums.Cost       | fmt }}</td>        
        <td class="text-end fw-semibold col-money">{{ sums.NetAmount|fmt }}</td>        

        {# Δ vs Net (value + %) – value uses same coloring rule as rows #}
        {% set dc = sums.DiffCostTotal %}
        <td class="text-end col-costdelta fw-semibold">
          {% if dc is not none %}
            {% set cls = 'text-danger' if dc > 0 else ('text-success' if dc < 0 else 'text-body') %}
            <span class="{{ cls }}">{{ '%.2f'|format(dc) }}</span>
          {% endif %}
        </td>

        {% set dcp = sums.DiffCostPct %}
        <td class="text-end col-costdelta fw-semibold">
          {% if dcp is not none %}
            {% set cls = 'text-danger' if dcp > 0 else ('text-success' if dcp < 0 else 'text-body') %}
            <span class="{{ cls }}">{{ '%+0.1f%%'|format(dcp) }}</span>
          {% endif %}
        </td>

        {% set dl = sums.DiffCalcTotal %}
        <td class="text-end col-calcdelta fw-semibold">
          {% if dl is not none %}
            {% set cls = 'text-danger' if dl > 0 else ('text-success' if dl < 0 else 'text-body') %}
            <span class="{{ cls }}">{{ '%.2f'|format(dl) }}</span>
          {% endif %}
        </td>

        {% set dlp = sums.DiffCalcPct %}
        <td class="text-end col-calcdelta fw-semibold">
          {% if dlp is not none %}
            {% set cls = 'text-danger' if dlp > 0 else ('text-success' if dlp < 0 else 'text-body') %}
            <span class="{{ cls }}">{{ '%+0.1f%%'|format(dlp) }}</span>
          {% endif %}
        </td>

        </td>

        
      </tr>
    </tfoot>

  </table>
</div>

<!-- Modal -->
<div class="modal fade" id="shipmentModal" tabindex="-1" aria-hidden="true">
  <div class="modal-dialog modal-lg modal-dialog-centered modal-dialog-scrollable">
    <div class="modal-content">
<div class="modal-header">
  <h5 class="modal-title">Shipment details</h5>
  <button type="button"
          class="btn btn-outline-secondary btn-sm"
          data-bs-dismiss="modal"
          aria-label="Close"
          title="Close (Esc)">
    Close
  </button>
</div>


      <div class="modal-body">
        <div class="text-center py-5" id="shipmentModalLoading">
          <div class="spinner-border" role="status" aria-hidden="true"></div>
          <div class="mt-2 small text-muted">Loading…</div>
        </div>
        <div id="shipmentModalBody" class="d-none"></div>
      </div>
    </div>
  </div>
</div>



<script>
function openShipmentModal(anchor){
  try {
    const modalEl = document.getElementById('shipmentModal');
    const bodyEl  = document.getElementById('shipmentModalBody');
    const loadEl  = document.getElementById('shipmentModalLoading');
    if (!modalEl || !bodyEl || !loadEl || !window.bootstrap) return true; // fall back to navigation

    const id  = anchor.getAttribute('data-id') || '';
    const inv = anchor.getAttribute('data-invoice') || '';
    const url = anchor.getAttribute('href');

    // Title + reset UI
    modalEl.querySelector('.modal-title').textContent =
      'Shipment #' + id + (inv ? ' · ' + inv : '');
    loadEl.classList.remove('d-none');
    bodyEl.classList.add('d-none');
    bodyEl.innerHTML = '';

    // Show modal
    new bootstrap.Modal(modalEl).show();

    // Load content
    fetch(url, { cache: 'no-store', headers: { 'X-Requested-With': 'XMLHttpRequest' } })
      .then(r => { if (!r.ok) throw new Error('HTTP ' + r.status); return r.text(); })
      .then(html => { bodyEl.innerHTML = html; loadEl.classList.add('d-none'); bodyEl.classList.remove('d-none'); })
      .catch(err => { bodyEl.innerHTML = '<div class="alert alert-danger small mb-0">Could not load shipment ' + id + ': ' + err.message + '</div>'; loadEl.classList.add('d-none'); bodyEl.classList.remove('d-none'); });

    return false; // PREVENT NAVIGATION
  } catch(e) {
    console.error(e);
    return true; // fallback to opening the link normally
  }
}
</script>

<div class="modal fade" id="orderModal" tabindex="-1" aria-hidden="true">
  <div class="modal-dialog modal-dialog-scrollable modal-dialog-centered">
    <div class="modal-content">
      <div class="modal-header py-2">
        <h5 class="modal-title">Order</h5>
        <button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
      </div>
      <div class="modal-body">
        Loading…
      </div>
    </div>
  </div>
</div>


<script>

let linkedShipmentId = null;  // remembers which shipment this order belongs to

document.addEventListener('click', function (e) {

  // 1) Open Order modal
  const orderLink = e.target.closest('.open-order');
  if (orderLink) {
    e.preventDefault();

    const ref = orderLink.dataset.ref;
    // new: remember the shipment id (may be undefined)
    linkedShipmentId = orderLink.dataset.shipmentId || null;

    const modalEl = document.getElementById('orderModal');
    const body = modalEl.querySelector('.modal-body');
    body.textContent = 'Loading…';

    const url = '{{ url_for("order_by_ref", ref="__REF__") }}'
                  .replace('__REF__', encodeURIComponent(ref));

    fetch(url, { headers: { 'X-Requested-With': 'fetch' } })
      .then(r => r.text())
      .then(html => {
        body.innerHTML = html;

        // NEW: show/hide "View shipment…" button depending on whether we have a linkedShipmentId
        const backBtn = body.querySelector('.open-linked-shipment');
        if (backBtn) {
          if (linkedShipmentId) {
            backBtn.classList.remove('d-none');
          } else {
            backBtn.classList.add('d-none');
          }
        }

        bootstrap.Modal.getOrCreateInstance(modalEl).show();
      })
      .catch(() => {
        body.innerHTML = '<div class="text-danger">Error loading order.</div>';
      });

    return;
  }
  
  
  // 1b) Click "View shipment…" inside Order modal
  const backToShipment = e.target.closest('.open-linked-shipment');
  if (backToShipment) {
    e.preventDefault();
    if (!linkedShipmentId) return;

    const shipmentModalEl = document.getElementById('shipmentModal');
    const shipmentBody    = shipmentModalEl.querySelector('.modal-body');
    shipmentBody.textContent = 'Loading…';

    // Build base URL with dummy 0, then replace it client-side
    const baseUrl = '{{ url_for("shipment_detail", shipment_id=0) }}'.replace(/0$/, '');
    const url = baseUrl + encodeURIComponent(linkedShipmentId);

    fetch(url, { headers: { 'X-Requested-With': 'fetch' } })
      .then(r => r.text())
      .then(html => {
        shipmentBody.innerHTML = html;

        // hide the order modal first
        const orderModalEl = document.getElementById('orderModal');
        const orderModal   = bootstrap.Modal.getInstance(orderModalEl);
        if (orderModal) {
          orderModal.hide();
        }

        // then show the shipment modal on top
        bootstrap.Modal.getOrCreateInstance(shipmentModalEl).show();
      })
      .catch(() => {
        shipmentBody.innerHTML = '<div class="text-danger">Error loading shipment.</div>';
      });

    return;
  }

 
  

  // 2) Open Order Items modal
  const itemsBtn = e.target.closest('.open-order-items');
  if (itemsBtn) {
    e.preventDefault();
    const orderNo = itemsBtn.dataset.order;
    const modalEl = document.getElementById('orderItemsModal');
    const body = modalEl.querySelector('.modal-body');
    body.textContent = 'Loading…';

    const urlItems = '{{ url_for("order_details", order_no=0) }}'
                     .replace('0', encodeURIComponent(orderNo));

    fetch(urlItems, { headers: { 'X-Requested-With': 'fetch' } })
      .then(r => r.text())
      .then(html => {
        body.innerHTML = html;
        bootstrap.Modal.getOrCreateInstance(modalEl).show();
      })
      .catch(() => {
        body.innerHTML = '<div class="text-danger">Error loading items.</div>';
      });

    return;
  }

  // 3) Open Product modal
  const prodLink = e.target.closest('.open-product');
  if (prodLink) {
    e.preventDefault();
    const url = prodLink.dataset.url;
    const modalEl = document.getElementById('productModal');
    const frame = document.getElementById('productFrame');

    frame.src = url;
    bootstrap.Modal.getOrCreateInstance(modalEl).show();
    return;
  }

  // Restore items to basket
  const restoreBtn = e.target.closest('.open-restore-basket');
  if (restoreBtn) {
    e.preventDefault();

    const orderNo = restoreBtn.dataset.order;
    const sid     = restoreBtn.dataset.session;
    const ip      = restoreBtn.dataset.ip;

    if (!orderNo || !sid || !ip) {
      console.warn('Missing data for restore basket link', { orderNo, sid, ip });
      return;
    }

    const origin = window.location.origin ||
                   (window.location.protocol + '//' + window.location.host);

    const url = origin
      + '/products.asp?cmd=restorebasketorder'
      + '&orderno=' + encodeURIComponent(orderNo)
      + '&sid='     + encodeURIComponent(sid)
      + '&ip='      + encodeURIComponent(ip);

    window.open(url, '_blank', 'noopener');
    return;
  }


});
</script>

<script>
let currentPdfUrl = null;
let currentPdfRef = null;

document.addEventListener('click', function (e) {
  // Open PDF modal
  const pdfLink = e.target.closest('.open-pdf');
  if (pdfLink) {
    e.preventDefault();

    const url = pdfLink.dataset.url || pdfLink.getAttribute('href');
    if (!url) return;

    currentPdfUrl = url;
    currentPdfRef = pdfLink.dataset.ref || '';

    const modalEl   = document.getElementById('pdfModal');
    const frame     = document.getElementById('pdfFrame');
    const refWrap   = document.getElementById('pdfRefWrapper');
    const refText   = document.getElementById('pdfRefText');
    const refCopied = document.getElementById('pdfRefCopied');

    // Update reference display
    if (currentPdfRef) {
      refText.textContent = currentPdfRef;
      refWrap.style.display = '';
      refCopied.style.display = 'none';
    } else {
      refWrap.style.display = 'none';
    }

    frame.src = url;
    bootstrap.Modal.getOrCreateInstance(modalEl).show();
    return;
  }

  // Open PDF in new tab
  const openNewBtn = e.target.closest('.pdf-open-new');
  if (openNewBtn) {
    e.preventDefault();
    if (currentPdfUrl) {
      window.open(currentPdfUrl, '_blank', 'noopener');
    }
    return;
  }

  // Copy Ref to clipboard
  const copyBtn = e.target.closest('.pdf-copy-ref');
  if (copyBtn) {
    e.preventDefault();
    if (!currentPdfRef) return;

    const refCopied = document.getElementById('pdfRefCopied');

    // Try modern clipboard API first
    if (navigator.clipboard && navigator.clipboard.writeText) {
      navigator.clipboard.writeText(currentPdfRef)
        .then(() => {
          refCopied.style.display = '';
          setTimeout(() => { refCopied.style.display = 'none'; }, 1500);
        })
        .catch(() => {
          const ta = document.createElement('textarea');
          ta.value = currentPdfRef;
          ta.style.position = 'fixed';
          ta.style.left = '-9999px';
          document.body.appendChild(ta);
          ta.select();
          try { document.execCommand('copy'); } catch (e) {}
          document.body.removeChild(ta);
          refCopied.style.display = '';
          setTimeout(() => { refCopied.style.display = 'none'; }, 1500);
        });
    } else {
      // fallback only
      const ta = document.createElement('textarea');
      ta.value = currentPdfRef;
      ta.style.position = 'fixed';
      ta.style.left = '-9999px';
      document.body.appendChild(ta);
      ta.select();
      try { document.execCommand('copy'); } catch (e) {}
      document.body.removeChild(ta);
      refCopied.style.display = '';
      setTimeout(() => { refCopied.style.display = 'none'; }, 1500);
    }

    return;
  }
});
</script>



<div class="modal fade" id="orderItemsModal" tabindex="-1" aria-hidden="true">
  <div class="modal-dialog modal-dialog-scrollable modal-dialog-centered">
    <div class="modal-content order-items-modal">
      <div class="modal-header py-2">
        <h5 class="modal-title">Order items</h5>
        <button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
      </div>
      <div class="modal-body">
        Loading…
      </div>
    </div>
  </div>
</div>

<div class="modal fade" id="productModal" tabindex="-1" aria-hidden="true">
  <div class="modal-dialog modal-dialog-centered modal-xl">
    <div class="modal-content product-modal">
      <div class="modal-header py-2">
        <h5 class="modal-title">Product</h5>
        <button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
      </div>
      <div class="modal-body p-0">
        <iframe id="productFrame"
                src="about:blank"
                style="border:0; width:100%; height:80vh;"></iframe>
      </div>
    </div>
  </div>
</div>

<div class="modal fade" id="pdfModal" tabindex="-1" aria-hidden="true">
  <div class="modal-dialog modal-dialog-centered modal-xl">
    <div class="modal-content pdf-modal">
      <div class="modal-header py-2">
        <h5 class="modal-title mb-0">Source PDF</h5>

        <div class="d-flex align-items-center gap-2">
          <div class="small me-3" id="pdfRefWrapper" style="display:none;">
            Ref:
            <code id="pdfRefText"></code>
            <button type="button"
                    class="btn btn-sm btn-light ms-1 pdf-copy-ref"
                    title="Copy order no">
              Copy
            </button>
            <span class="small text-success ms-1" id="pdfRefCopied" style="display:none;">
              Copied
            </span>
          </div>

          <button type="button"
                  class="btn btn-sm btn-outline-light pdf-open-new"
                  title="Open in new tab">
            Open in new tab
          </button>

          <button type="button"
                  class="btn-close ms-2"
                  data-bs-dismiss="modal"
                  aria-label="Close"></button>
        </div>
      </div>



      <div class="modal-body p-0">
        <div class="pdf-frame-container">
          <div id="pdfFrameInner" class="pdf-frame-inner">
            <iframe id="pdfFrame"
                    src="about:blank"
                    style="border:0; width:100%; height:80vh;"></iframe>
          </div>
        </div>
      </div>
    </div>
  </div>
</div>




{% if last_page > 1 %}
<nav class="mt-3" aria-label="Shipments pagination">
  {% set prevp = 1 if page<=1 else page-1 %}
  {% set nextp = last_page if page>=last_page else page+1 %}
  <ul class="pagination pagination-sm mb-0">
    <li class="page-item {{ 'disabled' if page==1 }}">
      <a class="page-link" href="{{ url_for('shipments_parsed', q=q, carrier=carrier, from=date_from, to=date_to, pagesize=pagesize, duponly=1 if duponly else None, noorder=1 if noorder else None, page=1) }}">« First</a>
    </li>
    <li class="page-item {{ 'disabled' if page==1 }}">
      <a class="page-link" href="{{ url_for('shipments_parsed', q=q, carrier=carrier, from=date_from, to=date_to, pagesize=pagesize, duponly=1 if duponly else None, noorder=1 if noorder else None, page=prevp) }}">‹ Prev</a>
    </li>
    <li class="page-item disabled"><span class="page-link">Page {{ page }} / {{ last_page }}</span></li>
    <li class="page-item {{ 'disabled' if page==last_page }}">
      <a class="page-link" href="{{ url_for('shipments_parsed', q=q, carrier=carrier, from=date_from, to=date_to, pagesize=pagesize,duponly=1 if duponly else None, noorder=1 if noorder else None, page=nextp) }}">Next ›</a>
    </li>
    <li class="page-item {{ 'disabled' if page==last_page }}">
      <a class="page-link" href="{{ url_for('shipments_parsed', q=q, carrier=carrier, from=date_from, to=date_to, pagesize=pagesize, duponly=1 if duponly else None, noorder=1 if noorder else None, page=last_page) }}">Last »</a>
    </li>
  </ul>
</nav>
{% endif %}

{% endblock %}