PageSourceSearch

https://lhkgo.com/assets/AdminBusinessCosts-3jVe3AUc.js

js lhkgo.com collected 2026-10-07 16:11:06 UTC 13,070 bytes, 7 lines download raw bytes

1import{c as z,u as H,k as U,r as u,j as e,B as I,L as M,D as V,g as W,h as G,i as Q,ab as J,w as L,Q as X,s as b,_ as B,x as Y,y as Z,af as ee,z as te,E as re,T as se,O as ne}from"./index-XV4mQklL.js";import{a as ae,e as T}from"./businessRates-Ct5Ap4n3.js";/**
2 * @license lucide-react v0.462.0 - ISC
3 *
4 * This source code is licensed under the ISC license.
5 * See the LICENSE file in the root directory of this source tree.
6 */const ie=z("FileScan",[["path",{d:"M20 10V7l-5-5H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h4",key:"1rdf37"}],["path",{d:"M14 2v4a2 2 0 0 0 2 2h4",key:"tnqrlb"}],["path",{d:"M16 14a2 2 0 0 0-2 2",key:"ceaadl"}],["path",{d:"M20 14a2 2 0 0 1 2 2",key:"1ny6zw"}],["path",{d:"M20 22a2 2 0 0 0 2-2",key:"1l9q4k"}],["path",{d:"M16 22a2 2 0 0 1-2-2",key:"1wqh5n"}]]),R=m=>m.replace(/\s+/g,"").toUpperCase(),ce=m=>{const l=[];m.tracking_number&&l.push(R(m.tracking_number));const g=m.tracking_numbers;if(Array.isArray(g)){for(const o of g)if(typeof o=="string")l.push(R(o));else if(o&&typeof o=="object"){const _=o.tracking_number??o.number??o.trackingNumber;_&&l.push(R(String(_)))}}return l};async function oe(m){const l=await B(()=>import("./pdf-ftNvnhDM.js"),[]),g=await B(()=>import("./pdf.worker.min-ocdtAcA3.js"),[]);l.GlobalWorkerOptions.workerSrc=g.default;const o=await l.getDocument({data:await m.arrayBuffer()}).promise,_=[];for(let v=1;v<=o.numPages;v++){const S=await(await o.getPage(v)).getTextContent();_.push(S.items.map(y=>"str"in y?y.str:"").join(" "))}return _.join(`
7`)}const le=({orders:m,onDone:l})=>{const{user:g}=H(),{toast:o}=U(),_=u.useRef(null),[v,F]=u.useState(!1),[S,y]=u.useState(!1),[f,P]=u.useState(null),[D,A]=u.useState([]),[N,K]=u.useState({}),$=async n=>{F(!0);try{const t=await oe(n);if(!t.trim())throw new Error("No readable text in this PDF (scanned image PDFs are not supported)");const{data:i,error:h}=await b.functions.invoke("scan-shipping-pdf",{body:{text:t}});if(h||i!=null&&i.error)throw new Error((i==null?void 0:i.error)||(h==null?void 0:h.message));const r=i.entries||[],a=Array.from(new Set(m.map(s=>s.userId).filter(Boolean))),{data:d}=a.length?await b.from("business_route_rates").select("id, user_id, origin_country, destination_country, per_kg_rate, min_charge, currency").in("user_id",a).range(0,999):{data:[]},k=d||[],x=[],j=[];for(const s of r){const p=m.find(C=>ce(C).includes(s.tracking_number));if(!p){j.push(`${s.tracking_number} (${s.weight_kg} kg)`);continue}const w={tracking_number:s.tracking_number,billed_weight_kg:s.weight_kg,audited_weight_kg:s.audited_weight_kg??null,length_cm:s.length_cm??null,width_cm:s.width_cm??null,height_cm:s.height_cm??null},c=x.find(C=>C.order.id===p.id);if(c&&c.parcels.push(w),c){c.newKg=Math.round((c.newKg+s.weight_kg)*100)/100,c.tracking+=`, ${s.tracking_number}`;continue}x.push({order:p,tracking:s.tracking_number,newKg:s.weight_kg,oldKg:Number(p.chargeable_weight??p.weight??0),oldPrice:p.estimated_price,newPrice:null,currency:"USD",parcels:[w]})}for(const s of x){const p=s.parcels.reduce((w,c)=>w+Number(c.audited_weight_kg??c.billed_weight_kg??0),0);s.newKg=Math.round(p*100)/100}for(const s of x){const p=k.filter(q=>q.user_id===s.order.userId),w=ae(p,s.order.origin_country,s.order.country_code);if(!w){s.note="No route rate for this customer";continue}s.currency=w.currency;const c=T(w,s.oldKg)??0,C=s.oldPrice!=null?Math.max(0,Number(s.oldPrice)-c):0,O=T(w,s.newKg);s.newPrice=O==null?null:Math.round((O+C)*100)/100}P(x),A(j),K(Object.fromEntries(x.filter(s=>s.newPrice!=null).map(s=>[s.order.id,!0]))),r.length===0&&o({title:"No tracking numbers found in the PDF",variant:"destructive"})}catch(t){o({title:t instanceof Error?t.message:"Scan failed",variant:"destructive"})}finally{F(!1),_.current&&(_.current.value="")}},E=async()=>{if(!f)return;y(!0);let n=0;for(const t of f){if(!N[t.order.id]||t.newPrice==null)continue;const i={chargeable_weight:t.newKg,estimated_price:t.newPrice,audited_parcels:t.parcels,actual_shipping_cost:t.newPrice,actual_cost_currency:t.currency||"HKD",actual_cost_charged_at:new Date().toISOString()},h=t.parcels[0];if(t.parcels.length===1&&h.length_cm&&h.width_cm&&h.height_cm){const a=t.order;a.original_length==null&&a.length!=null&&(i.original_length=a.length,i.original_width=a.width,i.original_height=a.height),i.length=h.length_cm,i.width=h.width_cm,i.height=h.height_cm}t.order.original_estimated_price==null&&t.oldPrice!=null&&(i.original_estimated_price=t.oldPrice);const{error:r}=await b.from("orders").update(i).eq("id",t.order.id);if(r){o({title:`${t.order.order_number}: ${r.message}`,variant:"destructive"});continue}if(await b.from("order_price_history").insert({order_id:t.order.id,old_price:t.oldPrice,new_price:t.newPrice,old_chargeable_weight:t.oldKg,new_chargeable_weight:t.newKg,reason:`PDF scan (tracking ${t.tracking})`,changed_by:(g==null?void 0:g.id)??null}),t.order.userId&&t.newPrice>0){const{error:a}=await b.from("business_wallet_transactions").insert({user_id:t.order.userId,amount:t.newPrice,currency:t.currency||"HKD",entry_type:"debit",note:"Actual shipping cost",order_number:t.order.order_number,created_by:(g==null?void 0:g.id)??null});a&&o({title:`${t.order.order_number}: ${a.message}`,variant:"destructive"})}n++}y(!1),o({title:`Updated ${n} order(s)`}),P(null),l()};return e.jsxs(e.Fragment,{children:[e.jsx("input",{ref:_,type:"file",accept:"application/pdf",className:"hidden",onChange:n=>{var t;return((t=n.target.files)==null?void 0:t[0])&&$(n.target.files[0])}}),e.jsxs(I,{size:"sm",variant:"outline",disabled:v,onClick:()=>{var n;return(n=_.current)==null?void 0:n.click()},children:[v?e.jsx(M,{className:"h-4 w-4 animate-spin mr-1"}):e.jsx(ie,{className:"h-4 w-4 mr-1"}),v?"Scanning PDF…":"Scan PDF weights"]}),e.jsx(V,{open:!!f,onOpenChange:n=>!n&&P(null),children:e.jsxs(W,{className:"max-w-3xl max-h-[85vh] overflow-y-auto",children:[e.jsx(G,{children:e.jsx(Q,{children:"Review PDF matches"})}),f&&f.length===0&&e.jsx("p",{className:"text-sm text-muted-foreground",children:"No tracking numbers in the PDF matched a business order."}),e.jsx("div",{className:"space-y-2",children:f==null?void 0:f.map(n=>e.jsxs("label",{className:"flex items-start gap-3 border rounded-lg p-3 text-sm cursor-pointer",children:[e.jsx(J,{className:"mt-1",disabled:n.newPrice==null,checked:!!N[n.order.id],onCheckedChange:t=>K(i=>({...i,[n.order.id]:!!t}))}),e.jsxs("div",{className:"flex-1 min-w-0",children:[e.jsx("div",{className:"font-mono text-xs",children:n.order.order_number}),e.jsx("div",{className:"font-mono text-xs text-muted-foreground truncate",children:n.tracking}),n.parcels.map(t=>e.jsxs("div",{className:"text-xs text-muted-foreground",children:[e.jsx("span",{className:"font-mono",children:t.tracking_number}
7),": 核實重量 Audited weight ",t.audited_weight_kg??"-"," kg · 核實尺寸 Audited dims ",t.length_cm&&t.width_cm&&t.height_cm?`${t.length_cm}×${t.width_cm}×${t.height_cm} cm`:"-"]},t.tracking_number)),n.note&&e.jsx(L,{variant:"destructive",className:"mt-1",children:n.note})]}),e.jsxs("div",{className:"text-right text-xs",children:[e.jsxs("div",{children:[n.oldKg," kg → ",e.jsxs("span",{className:"font-semibold",children:[n.newKg," kg"]})]}),e.jsxs("div",{children:[n.oldPrice!=null?Number(n.oldPrice).toFixed(2):"-"," → ",e.jsx("span",{className:"font-semibold text-primary",children:n.newPrice!=null?`${n.currency} ${n.newPrice.toFixed(2)}`:"-"})]})]})]},n.order.id))}),D.length>0&&e.jsxs("div",{className:"text-xs text-muted-foreground",children:[e.jsxs("div",{className:"font-medium mb-1",children:["Not matched (",D.length,"):"]}),e.jsx("div",{className:"font-mono break-all",children:D.join(" · ")})]}),e.jsxs(X,{children:[e.jsx(I,{variant:"outline",onClick:()=>P(null),children:"Cancel"}),e.jsxs(I,{disabled:S||!Object.values(N).some(Boolean),onClick:E,children:[S&&e.jsx(M,{className:"h-4 w-4 animate-spin mr-1"}),"Confirm & charge selected"]})]})]})})]})},me=()=>{const{user:m}=H(),{toast:l}=U(),[g,o]=u.useState(!0),[_,v]=u.useState([]),[F,S]=u.useState([]),[y,f]=u.useState([]),[P,D]=u.useState({}),[A,N]=u.useState(null),K=u.useRef(new Map),$=async()=>{o(!0);const[r,a]=await Promise.all([b.from("business_users").select("user_id, company_name").range(0,999),b.from("business_applications").select("user_id, email").range(0,999)]),d=r.data||[],k=a.data||[];v(d),S(k);const{data:x}=await b.rpc("get_business_user_emails"),j=x||[];K.current=new Map(j.map(c=>[(c.email||"").toLowerCase().trim(),c.user_id]));const s=Array.from(new Set([...k.filter(c=>d.some(C=>C.user_id===c.user_id)).map(c=>(c.email||"").toLowerCase().trim()),...j.map(c=>(c.email||"").toLowerCase().trim())].filter(Boolean)));if(s.length===0){f([]),o(!1);return}const{data:p}=await b.from("orders").select("id, order_number, sender_email, status, weight, chargeable_weight, length, width, height, original_length, original_estimated_price, tracking_numbers, country_code, origin_country, estimated_price, actual_shipping_cost, actual_cost_charged_at, created_at, tracking_number, tracking_last_status, tracking_last_event, tracking_updated_at").eq("status","delivered").order("created_at",{ascending:!1}).range(0,999),w=(p||[]).filter(c=>c.sender_email&&s.includes(c.sender_email.toLowerCase().trim()));f(w),o(!1)};u.useEffect(()=>{$()},[]);const E=r=>{var d;const a=(r.sender_email||"").toLowerCase().trim();return K.current.get(a)||((d=F.find(k=>(k.email||"").toLowerCase().trim()===a))==null?void 0:d.user_id)||null},n=r=>{var d;const a=E(r);return((d=_.find(k=>k.user_id===a))==null?void 0:d.company_name)||r.sender_email||"-"},t=({o:r})=>{if(!r.tracking_number)return e.jsx("div",{className:"text-xs text-muted-foreground",children:"No 17track tracking number yet"});const a=r.tracking_last_status||"Registered";return e.jsxs("div",{className:"text-xs text-muted-foreground",children:[e.jsxs("div",{className:"flex items-center gap-1.5 flex-wrap",children:[e.jsx("span",{children:"17track:"}),e.jsx("a",{href:`https://www.17track.net/en/track#nums=${encodeURIComponent(r.tracking_number)}`,target:"_blank",rel:"noopener noreferrer",className:"font-mono text-primary hover:underline",children:r.tracking_number}),e.jsx(L,{variant:"secondary",className:"text-[10px] px-1.5 py-0",children:a})]}),r.tracking_last_event&&e.jsx("div",{className:"truncate max-w-md",children:r.tracking_last_event})]})},i=u.useMemo(()=>y.filter(r=>r.actual_shipping_cost==null),[y]),h=async r=>{const a=Number(P[r.id]);if(!(a>=0)||Number.isNaN(a)){l({title:"Enter a valid amount",variant:"destructive"});return}const d=E(r);if(!d){l({title:"No business account matched for this order",variant:"destructive"});return}N(r.id);const k=new Date().toISOString(),{error:x}=await b.from("orders").update({actual_shipping_cost:a,actual_cost_currency:"HKD",actual_cost_charged_at:k}).eq("id",r.id);if(x){N(null),l({title:x.message,variant:"destructive"});return}if(a>0){const{error:j}=await b.from("business_wallet_transactions").insert({user_id:d,amount:a,currency:"HKD",entry_type:"debit",note:"Actual shipping cost",order_number:r.order_number,created_by:(m==null?void 0:m.id)??null});if(j){N(null),l({title:j.message,variant:"destructive"});return}}N(null),l({title:`Charged HKD ${a.toFixed(2)} to ${n(r)}`}),D(j=>({...j,[r.id]:""})),$()};return e.jsxs(Y,{children:[e.jsxs(Z,{className:"flex flex-row items-center gap-2",children:[e.jsx(ee,{className:"h-5 w-5"}),e.jsx(te,{children:"Business Actual Shipping Costs"}),i.length>0&&e.jsxs(L,{variant:"destructive",children:[i.length," pending"]}),e.jsx("div",{className:"ml-auto",children:e.jsx(le,{orders:y.map(r=>({...r,userId:E(r)})),onDone:$})})]}),e.jsx(re,{className:"space-y-6",children:g?e.jsx("div",{className:"flex justify-center py-8",children:e.jsx(M,{className:"h-5 w-5 animate-spin"})}):e.jsx(e.Fragment,{children:e.jsxs("div",{className:"space-y-3",children:[e.jsxs("div",{className:"text-sm font-medium flex items-center gap-2",children:[e.jsx(se,{className:"h-4 w-4 text-destructive"}),"Delivered orders awaiting actual cost"]}),i.length===0&&e.jsx("p",{className:"text-sm text-muted-foreground",children:"Nothing pending."}),i.map(r=>e.jsxs("div",{className:"flex flex-col md:flex-row md:items-center gap-3 border rounded-lg p-3",children:[e.jsxs("div",{className:"flex-1 min-w-0",children:[e.jsx("div",{className:"font-mono text-xs",children:r.order_number}),e.jsx("div",{className:"text-sm truncate",children:n(r)}),e.jsxs("div",{className:"text-xs text-muted-foreground",children:[r.origin_country||"-"," → ",r.country_code||"-"," · ",r.weight??"-"," kg",r.estimated_price!=null&&` · est. ${Number(r.estimated_price).toFixed(2)}`]}),e.jsx(t,{o:r})]}),e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx("span",{className:"text-xs text-muted-foreground",children:"HKD"}),e.jsx(ne,{type:"number",step:"0.01",className:"w-32",placeholder:"Actual cost",value:P[r.id]??"",onChange:a=>D(d=>({...d,[r.id]:a.target.value}))}
7),e.jsx(I,{size:"sm",disabled:A===r.id,onClick:()=>h(r),children:A===r.id?e.jsx(M,{className:"h-4 w-4 animate-spin"}):"Charge wallet"})]})]},r.id))]})})})]})};export{me as default};

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.