Skip to main content
The SCM application has a multi-model approach to represent external business relationships:

Party

Transaction Entity Low-level entity for POs, Invoices, Shipments. OpenBoxes-style.

Partner

Operational Management SCM-native partner with addresses, contacts, and locations.

Partnership

Cross-Organization Formal B2B relationships between separate Organizations.

OrganizationRelation

Hierarchy Structural relationships (Subsidiary, Division, Partner).

1. Party Model (Transaction Entities)

Purpose: Low-level transactional entity for Purchase Orders, Invoices, Shipments.
model Party {
  id              String
  organizationId  String
  partyTypeId     String    // Links to PartyType (Supplier, Customer, etc.)
  class           String    // ORGANIZATION or PERSON
  name            String
  roles           PartyRole[]    // Used in transactions
  supplierPurchaseOrders  PurchaseOrder[]  @relation("POSupplier")
  invoicesFrom            Invoice[]
  invoicesTo              Invoice[]
}

Key Usage

  • PurchaseOrder.supplierPartyId → references a Party
  • ProductSupplier.supplierId → links products to their suppliers
  • Invoice.partyId → billing party

Party Roles

RoleDescription
SUPPLIERVendor you buy from
CUSTOMEROrganization you sell to
MANUFACTURERProduct manufacturer
DISTRIBUTORDistribution partner
THIRD_PARTY_LOGISTICS3PL provider

2. Partner Model (Operational Management)

Purpose: SCM-native partner management with addresses, contacts, locations.
model Partner {
  id              String
  organizationId  String    // Your org owns this partner record
  name            String
  type            PartnerType   // SUPPLIER, CUSTOMER, CARRIER, etc.
  status          PartnerStatus // ACTIVE, INACTIVE, SUSPENDED
  
  // Operational settings
  taxId           String?
  paymentTerms    String?
  incoterm        String?
  centralPurchasing Boolean
  poPrefix        String?       // For PO numbering
  
  // Related data
  addresses       PartnerAddress[]
  contacts        PartnerContact[]
  locations       PartnerLocation[]   // Links to shared locations
}

Partner Types

  • SUPPLIER: Vendors you purchase from
  • CUSTOMER: Organizations you sell to
  • CARRIER: Shipping/logistics providers
  • MANUFACTURER: Product manufacturers
  • DISTRIBUTOR: Distribution partners
  • INTERNAL: Internal divisions
  • OTHER: Misc partners

Key Features

  • Addresses: Billing, shipping, returns addresses per partner
  • Contacts: Named contacts with roles (Sales, Support, Accounting)
  • Locations: Link partners to shared Location records (warehouses, stores)
  • Central Purchasing: Allow parent to purchase on behalf of children

3. Partnership Model (Cross-Organization)

Purpose: Formal B2B relationships between separate Organizations.
model Partnership {
  id                    String
  organizationId        String    // Requesting org
  partnerOrganizationId String    // Partner org
  status                PartnershipStatus  // REQUESTED, ACCEPTED, DENIED
  partyRole             PartyRoleType      // Role they play for you
  relationshipType      RelationshipType   // BUYER_SELLER, LOGISTICS, etc.
  
  // Invitation workflow
  invitationToken       String?
  invitationEmail       String?
  invitationSentAt      DateTime?
  invitationAcceptedAt  DateTime?
}

Partnership Workflow

Relationship Types

  • BUYER_SELLER: Standard procurement relationship
  • LOGISTICS: 3PL/shipping partnership
  • MANUFACTURING: Contract manufacturing
  • DISTRIBUTION: Distribution agreement
  • FRANCHISE: Franchise relationship

4. OrganizationRelation (Org Hierarchy)

Purpose: Define structural relationships between organizations (including PARTNER role).
model OrganizationRelation {
  parentOrgId  String
  childOrgId   String
  role         String    // SUBSIDIARY, DIVISION, PARTNER, AFFILIATE
  isActive     Boolean
}

Relation Roles

RoleDescriptionBilling Included
SUBSIDIARYOwned subsidiary✅ Yes
DIVISIONBusiness division✅ Yes
BRANCHBranch office✅ Yes
PARTNERExternal partner❌ No
AFFILIATEAffiliate org❌ No
FRANCHISEFranchise❌ No

How They Work Together

Scenario: Creating a Purchase Order

  1. User selects SupplierParty record (type: SUPPLIER)
  2. System loads → Partner record (for payment terms, addresses)
  3. PO is created → supplierPartyId = Party.id
  4. Supplier org may have → Partnership (if cross-org visibility needed)

API Flow (/api/partners)

The partners API aggregates from 3 sources:
// 1. Partner model (owned by your org)
const partnersFromModel = await database.partner.findMany({
  where: { organizationId, type: 'SUPPLIER' }
});

// 2. OrganizationRelation (PARTNER role)
const partnersFromRelations = await database.organizationRelation.findMany({
  where: { parentOrgId: organizationId, role: 'PARTNER' }
});

// 3. Partnership model (accepted partnerships)
const partnersFromPartnerships = await database.partnership.findMany({
  where: { organizationId, status: 'ACCEPTED' }
});

Key Flags on Organization

model Organization {
  isCustomer       Boolean   // Can be sold to
  isSupplier       Boolean   // Can be purchased from
  partnershipTier  PartnershipTier?  // PARTNER_ONLY, BASIC, FULL
}
These flags determine:
  • isSupplier=true → Appears in supplier dropdowns for POs
  • isCustomer=true → Appears in customer dropdowns for Sales Orders
  • partnershipTier → Controls what partnership features are available

Summary Table

ModelPurposeScopeUsed For
PartyTransaction entityPer-orgPOs, Invoices, Shipments
PartnerOperational configPer-orgAddresses, contacts, terms
PartnershipCross-org linkMulti-orgVisibility, collaboration
OrganizationRelationOrg hierarchyMulti-orgSubsidiaries, partners, billing