Purchase orders and invoice linkage (payableId)

Analyzes purchase orders and their link to invoices via payableId. Explains why payableId=null does not necessarily mean no invoice exists.

↓ Download skill (.md)
79/100·🔍 Ad hoc·ExpertProcurementAP Manager
Budget & POsReconciliationget_purchase_orders

🎯 Skill purpose

Analyzes purchase orders and their link to invoices via payableId. Explains why payableId=null does not necessarily mean no invoice exists.

📊 What it produces

POs with invoice linkage status, committed amount, and explanation of cases without payableId.

Benefit

Before

Incorrect interpretation of payableId=null caused false missing invoice reports.

After

Correct understanding of PO-invoice linkage, zero false missing invoice detection.



# Instructions — Purchase Orders (POs)

## ⚠️ payableId=null ≠ "no invoice"

Each PO can have an `invoices[]` array with related invoices.
Each invoice has a `payableId` which can be:
- **UUID** → direct link to the payable (use `get_payable_by_id` for details)
- **null** → the invoice exists but cannot be resolved from its `requestId`

```json
// Invoice with payableId null — the invoice exists but is not linked:
{
  "invoiceRequestId": "abc123",
  "invoiceNumber": "INV-001",
  "amount": { "amount": 150000, "currency": "EUR", "precision": 2 },
  "status": "paid",
  "payableId": null   ← DO NOT conclude "no invoice"
}
```

→ In case of `payableId=null`, use `invoiceRequestId` or `invoiceNumber` for manual reconciliation.

## ⚠️ Multi-currency POs: do not sum across currencies

POs can be denominated in EUR, USD, GBP, etc. The `amount`, `billedAmount`, `deliveredAmount` fields are in the PO's currency.
→ Never add up POs in different currencies without conversion.
→ Display separately by currency or convert explicitly.

Live example: FullStory PO in USD ($21,267.89), Oracle PO in EUR (30,000 EUR).

## Step 1 — Active POs (status=open)

```json
{ "companyId": "...", "status": ["open"], "pageSize": 100 }
```

→ Returns ongoing POs that can still accept invoices.
→ `billingStatus: "lateInvoice"` → PO open but no invoice received recently.
→ `billingStatus: "partiallyBilled"` → invoices received but budget not exhausted.

## Step 2 — POs expiring soon

```json
{
  "companyId": "...",
  "endDateFrom": "YYYY-MM-DD",
  "endDateTo": "YYYY-MM-DD",
  "status": ["open"]
}
```

Example: POs expiring in the next 30 days = endDateFrom=today, endDateTo=today+30d.

## Step 3 — Calculating consumed budget

For each PO:
```
approved_budget = amount (in PO currency)
invoiced = billedAmount
delivered = deliveredAmount
net = billedAmount - creditNotes (= netAmount field)

consumption_rate = billedAmount / amount × 100
remaining_budget = amount - billedAmount
```

⚠️ A PO with `billedAmount > amount` is over budget.

## Step 4 — Accessing invoice details

For each PO with `invoices[]`:
1. If `payableId != null` → call `get_payable_by_id(payableId)` for full details
2. If `payableId == null` → note `invoiceNumber` + `invoiceRequestId` for manual reconciliation

## Live example (real data)

| PO | Description | Status | Amount | Invoiced |
|----|-------------|--------|--------|---------|
| Coworking Lyon | Coworking space | open | 26,026 EUR | 20,185 EUR (78%) |
| FullStory | SaaS subscription | open | $21,267 USD | $10,633 USD (50%) |
| Oracle | Annual subscription | open | 30,000 EUR | 0 EUR (0%) — lateInvoice |
| Coworking Lyon 2 | Extension | open | 35,424 EUR | 5,904 EUR (17%) |

Note: `payableId=null` not visible in this demo dataset — the risk is documented in the MCP spec but not testable here.

## Example prompt

- "Which POs expire in the next 30 days?" → endDateFrom/endDateTo + status=open
- "What is the consumption rate of our active POs?" → status=open + billedAmount/amount calculation
- "Find the invoices linked to the Oracle PO" → invoices[].payableId → get_payable_by_id

How to install this skill

/
  1. 1
    Download the file s28-purchase-orders-payable-id.md using the button above.
  2. 2
    Place the file in the .claude/ directory of your project (or ~/.claude/ for a global install).
    cp s28-purchase-orders-payable-id.md .claude/s28-purchase-orders-payable-id.md
  3. 3
    Use in Claude Codethe skill is automatically discovered. Describe your need in natural language and Claude will apply the skill instructions.
💡 Make sure the Spendesk MCP is configured in your .claude/settings.json with the tools get_purchase_orders.

Similar skills

★ Top
95/100·🔍 Ad hoc·Expert

MCP coverage audit & gap analysis

Probes all available MCP tools, re-evaluates coverage of 50 persona use cases, detects new fields or tools, and regenerates the gap analysis report.

CFOControllerAP Manager
★ Top
89/100·🔍 Ad hoc·Intermediate

Skill Builder

Aide un client à transformer un besoin métier précis (contexte, contraintes, format de sortie souhaité) en un nouveau skill Claude sur mesure, prêt à l'emploi sur le MCP Spendesk

CFOControllerAP Manager
★ Top
88/100·🔍 Ad hoc·Beginner

MCP Product Tour

Visite guidée conversationnelle du MCP Spendesk — appels réels sur les données de l'utilisateur, adaptée à sa persona, puis recommandation des prochains skills à installer

CFOControllerAP Manager