← back to Govarbitrage

src/engines/freight.ts

48 lines

import { round2 } from "@/lib/utils";
import { FREIGHT_THRESHOLD_LBS } from "./constants";

export interface FreightEstimate {
  parcelShipping: number;
  freight: number;
  isFreight: boolean;
  basis: string;
}

/**
 * Estimate outbound logistics cost from total lot weight. Light items ship as
 * parcel (USPS/UPS ground tiers); heavy items move as LTL freight with a base
 * charge plus per-hundredweight (CWT) rate. Deliberately simple + explainable.
 */
export function estimateFreight(totalWeightLbs: number): FreightEstimate {
  const w = Math.max(0, totalWeightLbs || 0);

  if (w <= FREIGHT_THRESHOLD_LBS) {
    // Parcel tiers.
    let parcel: number;
    if (w <= 1) parcel = 6;
    else if (w <= 5) parcel = 12;
    else if (w <= 20) parcel = 22;
    else if (w <= 50) parcel = 45;
    else if (w <= 100) parcel = 85;
    else parcel = 130;
    return {
      parcelShipping: round2(parcel),
      freight: 0,
      isFreight: false,
      basis: `parcel @ ${w} lb`,
    };
  }

  // LTL freight: base handling + per-CWT (hundredweight) rate.
  const base = 95;
  const perCwt = 28;
  const cwt = w / 100;
  const freight = round2(base + perCwt * cwt);
  return {
    parcelShipping: 0,
    freight,
    isFreight: true,
    basis: `LTL: $${base} base + $${perCwt}/cwt × ${cwt.toFixed(2)}cwt`,
  };
}