PackCost AI
packaging cost intelligence · ERP-agnostic core · SAP-first

For SAP implementation partners

One number per package.
Fully traced to your SAP.

PackCost AI is a read-only layer over SAP that turns BOM, vendor, price and transactional data into a deterministic cost for every empty bottle or package — and shows the exact path it took through the ERP to get there.

₹ 2.105289 / bottle
500 ml PET bottle BOM B2 actual landed as of 2025-08-15 CALC-EDCF4D610276 partial — 2 landed-cost gaps flagged

Every figure is reproducible from stored inputs, business rules, source references and timestamps. Nothing is estimated. Where landed-cost or conversion data is missing, the result is marked partial and the gap is listed — never filled with a zero.

Architecture

Four layers. The ERP sits behind one interface.

The separation is what lets the same product serve S/4HANA, ECC and non-SAP ERPs without touching the costing engine or the user experience.

SAP S/4HANA · OData/CDS ECC 6.0 · RFC/BAPI ERP connector read-only · config-driven Canonical model ERP-neutral schema + snapshot cache Engines cost · vendor variance · scenario ₹ 2.105289 / bottle extract (read-only) normalise + cache deterministic calc answer + evidence + retrieval path
SAP is the system of record. PackCost reads it once into an ERP-neutral model and calculates from that copy — so routine questions return in seconds — while every stored value still records the SAP object it came from and when it was extracted.

Where your team plugs in

Implement one interface. Nothing above it changes.

The mock connector implements every operation today, against a deterministic seed. On a REST/OData ERP your work is the mapping pack — the connector itself, the canonical model, the cost engine, the API and the web UI are all shared and untouched.

The connector interface ERPConnector

  • resolve_part
  • get_fx_rates
  • get_plants
  • get_purchase_history
  • get_material
  • get_receipts
  • get_bom
  • get_invoices
  • get_vendors
  • get_landed_costs
  • get_vendor_materials
  • get_production_orders
  • get_prices
  • get_consumption
  • get_qualifications
  • get_conversion_cost

Each returns canonical DTOs plus source metadata — never raw SAP objects.

The mapping pack config/{sap,rest}/<customer>.yaml

# connection picks the dialect; bindings map the fields
connection:
  route: rest
  dialect: odata_v2
get_bom:
  object: API_BILL_OF_MATERIAL_SRV/MaterialBOM
  status: partial
  field_map:
    version:    BillOfMaterialVariantUsage
    valid_from: BOMHeaderValidityStartDate
  # TODO: component scrap % field
mappedget_material  API_PRODUCT_SRV
partialget_bom  API_BILL_OF_MATERIAL_SRV
todoget_landed_costs  PO pricing conditions
todoget_conversion_cost  Material Ledger / CO

Your deliverable: turn python -m packcost.connectors.sap check green.

One connector, many ERPs

Config picks the dialect. The interface never changes.

The live connector is config-driven. A dialect handles how one family of HTTP + JSON ERPs shapes a query — the URL, where the filter goes, the response envelope, pagination — and the customer’s YAML mapping pack does the field-by-field mapping. SAP S/4HANA is one dialect among several; adding Dynamics or Oracle is configuration, not new connector code.

odata_v2SAP S/4HANA — released OData APIs / CDS views  verified end‑to‑end
odata_v4Dynamics 365 F&SCM / Business Central · SAP OData v4  verified end‑to‑end
suiteqlOracle NetSuite — one joined SuiteQL SELECT per concept, OAuth 1.0a  verified end‑to‑end
oracle_fusionOracle Fusion Cloud ERP / SCM — q= query, expanded children, offset paging  verified end‑to‑end
rest_jsonSage X3 and bespoke REST — configurable filter param + rows key

SAP S/4HANA odata_v2

Released OData APIs & CDS views; Integration Suite. Material Ledger for actual cost where activated.

  • API_BILL_OF_MATERIAL_SRV
  • API_PRODUCT_SRV
  • API_PURCHASINGINFORECORD_PROCESS_SRV
  • API_SUPPLIERINVOICE_PROCESS_SRV
  • API_EXCHANGE_RATE_SRV

Oracle NetSuite suiteql

One joined SELECT per operation against the whole data model — the concept, not the tables. Flat component rows are grouped back into BOM headers.

  • bomassignment → bomrevision
  • bomrevisioncomponent
  • item / itemvendor
  • vendor / currencyrate
  • transaction / transactionline

SAP ECC 6.0 rfc / bapi

A separate RFC / BAPI adapter behind the same interface (needs the NW RFC SDK). Actual cost reconstructed from PO / GR / IR / freight history.

  • CS_BOM_EXPL_MAT_V2
  • BAPI_MATERIAL_GET_DETAIL
  • EINA / EINE / KONP / A017
  • RBKP / RSEG
  • TCURR
-- NetSuite get_bom: "BOM components with quantities and scrap" as one query
SELECT br.name, brc.item, brc.quantity,
       (100 - COALESCE(brc.componentyield, 100)) AS scrap_pct
FROM   bomassignment ba
JOIN   bomrevision br  ON br.billofmaterials = ba.billofmaterials
JOIN   bomrevisioncomponent brc ON brc.bomrevision = br.id
WHERE  ba.item =  AND ba.location = 

No API in the POC? file / staging_db

Same interface, same mapping pack — rows come from CSV / Parquet / JSON extracts in a directory, or a read-only staging schema the customer replicates a few tables into. Unblocks the engagement while API access is still in approvals; the extract can be swapped for a live dialect later with no change above the connector.

Shipped feature

Every figure shows its retrieval path.

For any BOM or cost, PackCost renders the exact sequence of ERP reads — object, filter, fields, rows returned. On SAP the steps name the real objects, so a client’s auditors can point at where each number came from.

  1. Retrieve the BOM version(s) for the package & plant, valid on the date. SAP  API_BILL_OF_MATERIAL_SRV/MaterialBOM  $filter=Material eq 'BOT-500' and Plant eq 'LKO' → selected B2 (valid 2025-07-01…)
  2. For each component — the purchasing price valid on the date, per supplier. SAP  API_PURCHASINGINFORECORD_PROCESS_SRV/A_PurInfoRecdPrcgCndn  material='PRE-22' → V-PRE-B 1.40 INR
  3. Foreign-currency component → the exchange rate to the reporting currency. SAP  API_EXCHANGE_RATE_SRV/A_ExchangeRate  USD→INR → 83.00

Status

Everything above the connector is built and tested.

154 automated tests · deterministic seed · reproducible via docker compose up

The engagement

What a partner delivers.

  1. Confirm the environment — ERP profile and release, the approved integration route and dialect, and a read-only least-privilege service account.
  2. Complete the mapping pack — with the customer’s ERP team, fill the field maps for each operation until python -m packcost.connectors.sap check reports the cost path ready.
  3. Wire it up and reconcile — for a REST/OData ERP, select the dialect and resolve secrets through the secret manager; for ECC, complete the RFC client behind EccRfcConnector. Then reconcile PackCost’s output against an existing ERP cost report.