Orders and Commerce
Overview
The commerce domain in CoCore manages the business side of print production, connecting customer orders to production jobs. Unlike traditional JDF which focuses on production, CoCore provides comprehensive order management, customer relationships, and financial tracking.
Domain Structure
Customer
├── Contacts (multiple contact persons)
├── Addresses (billing, shipping, etc.)
└── Orders
├── OrderLines (line items)
│ └── Job (production link)
└── OrderShippingInstructions
└── OrderLineShippingInstructions (override per line)Order Lifecycle
Order States
graphql
enum OrderStateEnum {
DRAFT # Initial creation, not submitted
PENDING # Submitted, awaiting confirmation
CONFIRMED # Accepted and ready for production
IN_PRODUCTION # Being manufactured
READY_FOR_PICKUP # Complete, awaiting collection
DELIVERED # Shipped/collected by customer
CANCELLED # Order cancelled
}Order Flow
DRAFT → PENDING → CONFIRMED → IN_PRODUCTION → READY_FOR_PICKUP → DELIVERED
↓ ↓ ↓ ↓
CANCELLED CANCELLED CANCELLED CANCELLEDCustomer Management
Creating Customers
graphql
mutation CreateCustomer {
createCustomer(input: {
# Basic Information
businessName: "ACME Printing Co."
contactName: "John Smith"
contactEmail: "john@acmeprinting.com"
phone: "+1-555-0100"
# Customer Type
customerType: BUSINESS # or INDIVIDUAL
# Financial
taxId: "12-3456789"
paymentTerms: 30 # Net 30 days
creditLimit: { amount: 50000, currency: "USD" }
# Status
status: ACTIVE # ACTIVE, INACTIVE, SUSPENDED, PROSPECT
# External Reference
externalId: "CRM-CUST-001"
}) {
result {
id
businessName
status
creditLimit {
amount
currency
}
}
errors {
field
message
}
}
}Adding Customer Addresses
graphql
mutation AddCustomerAddress {
createAddress(input: {
customerId: "customer-123"
# Address Type
addressType: BILLING # BILLING, SHIPPING, BOTH
# Address Details
name: "ACME Headquarters"
line1: "123 Main Street"
line2: "Suite 400"
city: "Springfield"
state: "IL"
postalCode: "62701"
country: "US"
# Flags
isDefault: true
isActive: true
}) {
result {
id
addressType
isDefault
}
}
}Adding Customer Contacts
graphql
mutation AddCustomerContact {
createContact(input: {
customerId: "customer-123"
# Contact Information
firstName: "Jane"
lastName: "Doe"
title: "Production Manager"
email: "jane.doe@acmeprinting.com"
phone: "+1-555-0101"
mobile: "+1-555-0102"
# Preferences
isPrimary: true
receiveOrderUpdates: true
receiveInvoices: false
receiveProofs: true
}) {
result {
id
firstName
lastName
email
isPrimary
}
}
}Creating Orders
Basic Order Creation
graphql
mutation CreateBasicOrder {
createOrder(input: {
# Required Fields
orderNumber: "ORD-2024-001"
orderDate: "2024-02-15"
customerId: "customer-123"
# Delivery Dates
requestedDeliveryDate: "2024-03-01"
promisedDeliveryDate: "2024-02-28"
# Order Type
rushOrder: false
# Initial State
state: DRAFT
}) {
result {
id
orderNumber
state
orderDate
customer {
businessName
}
}
errors {
field
message
}
}
}Complete Order with Financial Details
graphql
mutation CreateCompleteOrder {
createOrder(input: {
orderNumber: "ORD-2024-002"
orderDate: "2024-02-15"
customerId: "customer-456"
contactId: "contact-789" # Specific contact person
# Dates
requestedDeliveryDate: "2024-02-25"
promisedDeliveryDate: "2024-02-24"
# Financial (Money type includes amount and currency)
subtotal: { amount: 1500.00, currency: "USD" }
taxAmount: { amount: 120.00, currency: "USD" }
shippingAmount: { amount: 50.00, currency: "USD" }
discountAmount: { amount: 75.00, currency: "USD" }
totalAmount: { amount: 1595.00, currency: "USD" }
# Payment
paymentStatus: PENDING # PENDING, PARTIAL, PAID, OVERDUE, REFUNDED
paymentMethod: CREDIT_CARD # CASH, CHECK, CREDIT_CARD, WIRE_TRANSFER, TERMS
# Rush Order
rushOrder: true
rushFee: { amount: 200.00, currency: "USD" }
# Instructions
specialInstructions: "Call before delivery. Use loading dock entrance."
state: PENDING
}) {
result {
id
orderNumber
totalAmount {
amount
currency
}
paymentStatus
}
}
}Order Lines
Adding Order Lines
graphql
mutation AddOrderLines {
# Line 1: Business Cards
line1: createOrderLine(input: {
orderId: "order-123"
lineNumber: 1
# Product Information
productName: "Business Cards - Premium"
productSku: "BC-PREM-001"
description: "Full color, double-sided, UV coating"
# Quantities
quantity: 1000
minDeliverableQuantity: 950 # Allow 5% under
maxDeliverableQuantity: 1100 # Allow 10% over
# Pricing
unitPrice: { amount: 0.15, currency: "USD" }
lineTotal: { amount: 150.00, currency: "USD" }
# Tax and Fees
taxRate: 0.08 # 8% tax
taxAmount: { amount: 12.00, currency: "USD" }
discountAmount: { amount: 0.00, currency: "USD" }
shippingAmount: { amount: 5.00, currency: "USD" }
# Proofing
proofRequired: HARD_COPY # NONE, SOFT_COPY, HARD_COPY
proofApproved: false
# State
state: PENDING # PENDING, CONFIRMED, IN_PRODUCTION, COMPLETE, CANCELLED
# Link to production (optional at creation)
jobId: null # Will link when job is created
}) {
result {
id
lineNumber
productName
quantity
lineTotal {
amount
currency
}
}
}
# Line 2: Brochures
line2: createOrderLine(input: {
orderId: "order-123"
lineNumber: 2
productName: "Tri-fold Brochures"
productSku: "BR-TRI-001"
quantity: 5000
unitPrice: { amount: 0.25, currency: "USD" }
lineTotal: { amount: 1250.00, currency: "USD" }
taxRate: 0.08
taxAmount: { amount: 100.00, currency: "USD" }
proofRequired: SOFT_COPY
state: PENDING
}) {
result {
id
lineNumber
productName
}
}
}Linking Order Lines to Jobs
graphql
mutation LinkOrderLineToJob {
updateOrderLine(
id: "order-line-123"
input: {
jobId: "job-456"
state: IN_PRODUCTION
}
) {
result {
id
job {
id
jobNumber
name
}
state
}
}
}Shipping Instructions
Order-Level Shipping
graphql
mutation AddOrderShipping {
createOrderShippingInstruction(input: {
orderId: "order-123"
instructionNumber: 1
# Shipping Details
shippingMethod: "FedEx Ground"
shippingCost: { amount: 50.00, currency: "USD" }
# Delivery
deliveryDate: "2024-02-28"
deliveryTime: "09:00-17:00"
# Address (can override customer default)
addressId: "address-456"
# Special Instructions
specialInstructions: "Leave at reception desk"
signatureRequired: true
# Package Details
numberOfPackages: 2
packageWeight: { value: 10.5, unit: "KG" }
packageDimensions: "40x30x20 cm"
}) {
result {
id
shippingMethod
deliveryDate
trackingNumber # Added when shipped
}
}
}Line-Item Specific Shipping
graphql
mutation AddLineItemShipping {
createOrderLineShippingInstruction(input: {
orderLineId: "order-line-456"
instructionNumber: 1
# Override order-level shipping for this line
shippingMethod: "Next Day Air"
shippingCost: { amount: 125.00, currency: "USD" }
# Different delivery address
addressId: "address-789"
deliveryDate: "2024-02-20" # Earlier than rest of order
specialInstructions: "Urgent - deliver to warehouse"
}) {
result {
id
orderLine {
productName
}
shippingMethod
deliveryDate
}
}
}Querying Orders
Get Order with Full Details
graphql
query GetOrderComplete {
getOrder(id: "order-123") {
id
orderNumber
state
# Dates
orderDate
requestedDeliveryDate
promisedDeliveryDate
actualDeliveryDate
# Financial Summary
subtotal { amount, currency }
taxAmount { amount, currency }
shippingAmount { amount, currency }
discountAmount { amount, currency }
totalAmount { amount, currency }
# Payment
paymentStatus
paymentMethod
# Rush Order
rushOrder
rushFee { amount, currency }
# Special Instructions
specialInstructions
# Delivery
deliveryStatus # PENDING, SHIPPED, DELIVERED, RETURNED
# Customer
customer {
id
businessName
contactEmail
paymentTerms
creditLimit { amount, currency }
status
}
# Contact Person
contact {
firstName
lastName
email
phone
}
# Order Lines
lines {
id
lineNumber
productName
productSku
description
quantity
minDeliverableQuantity
maxDeliverableQuantity
unitPrice { amount, currency }
lineTotal { amount, currency }
taxAmount { amount, currency }
proofRequired
proofApproved
proofApprovedAt
state
# Linked Job
job {
id
jobNumber
name
status
}
# Line-specific shipping
shippingInstructions {
shippingMethod
deliveryDate
trackingNumber
}
}
# Addresses
addresses {
id
addressType
line1
line2
city
state
postalCode
country
}
# Order-level shipping
shippingInstructions {
instructionNumber
shippingMethod
shippingCost { amount, currency }
deliveryDate
trackingNumber
specialInstructions
}
}
}Search Orders
graphql
query SearchOrders {
listOrders(
filter: {
# By customer
customer: {
businessName: { ilike: "%acme%" }
}
# By state
state: { in: [PENDING, CONFIRMED, IN_PRODUCTION] }
# By dates
orderDate: {
greaterThanOrEqual: "2024-01-01"
lessThan: "2024-02-01"
}
# By payment
paymentStatus: { in: [PENDING, OVERDUE] }
# Rush orders only
rushOrder: { eq: true }
# By amount
totalAmount: {
amount: { greaterThanOrEqual: 1000 }
}
}
sort: [
{ field: ORDER_DATE, order: DESC }
]
first: 20
) {
count
results {
id
orderNumber
customer { businessName }
orderDate
totalAmount { amount, currency }
paymentStatus
state
}
endKeyset
}
}Common Workflows
Quote to Order Conversion
graphql
mutation ConvertQuoteToOrder {
# Step 1: Create order from quote/estimate
createOrder(input: {
orderNumber: "ORD-2024-100"
customerId: $customerId
orderDate: $today
state: PENDING
# Copy financial details from quote
subtotal: $quoteSubtotal
taxAmount: $quoteTax
totalAmount: $quoteTotal
requestedDeliveryDate: $requestedDate
}) {
result {
id
orderNumber
}
}
}
# Step 2: Copy estimate items to order lines
mutation CopyEstimateItems {
createOrderLine(input: {
orderId: $orderId
lineNumber: $lineNumber
productName: $estimateItemName
quantity: $estimateQuantity
unitPrice: $estimateUnitPrice
lineTotal: $estimateLineTotal
state: PENDING
}) {
result { id }
}
}Order Confirmation Workflow
graphql
# Step 1: Validate credit
query CheckCustomerCredit {
getCustomer(id: $customerId) {
creditLimit { amount }
# Check current outstanding balance
orders(filter: {
paymentStatus: { in: [PENDING, PARTIAL, OVERDUE] }
}) {
results {
totalAmount { amount }
}
}
}
}
# Step 2: Confirm order
mutation ConfirmOrder {
updateOrder(
id: $orderId
input: {
state: CONFIRMED
promisedDeliveryDate: $calculatedDeliveryDate
}
) {
result {
state
promisedDeliveryDate
}
}
}
# Step 3: Create production jobs
mutation CreateJobsForOrder {
createJob(input: {
name: $orderLineProductName
externalId: $orderNumber
orderedQuantity: $orderLineQuantity
maxDeliverableQuantity: $orderLineMaxQuantity
billingCustomerId: $customerId
deliveryCustomerId: $customerId
orderLineId: $orderLineId
}) {
result {
id
jobNumber
}
}
}Payment Processing
graphql
mutation RecordPayment {
# Update order payment status
updateOrder(
id: "order-123"
input: {
paymentStatus: PAID
paymentMethod: CREDIT_CARD
# Record payment reference
metadata: {
paymentReference: "STRIPE-ch_1234567890"
paymentDate: "2024-02-15T10:30:00Z"
}
}
) {
result {
id
paymentStatus
}
}
# Create payment record (if separate payment tracking exists)
createPayment(input: {
orderId: "order-123"
amount: { amount: 1595.00, currency: "USD" }
method: CREDIT_CARD
reference: "STRIPE-ch_1234567890"
status: COMPLETED
}) {
result {
id
reference
}
}
}Shipping and Fulfillment
graphql
mutation ShipOrder {
# Update shipping instruction with tracking
updateOrderShippingInstruction(
id: "shipping-instruction-123"
input: {
trackingNumber: "1Z999AA10123456784"
actualShippingDate: "2024-02-28T14:30:00Z"
carrier: "UPS"
}
) {
result {
trackingNumber
}
}
# Update order delivery status
updateOrder(
id: "order-123"
input: {
deliveryStatus: SHIPPED
state: DELIVERED
actualDeliveryDate: "2024-03-01"
}
) {
result {
state
deliveryStatus
}
}
# Send shipping notification
sendShippingNotification(input: {
orderId: "order-123"
recipientEmail: $customerEmail
trackingNumbers: ["1Z999AA10123456784"]
}) {
result {
sentAt
}
}
}Pricing and Billing
Dynamic Pricing Calculation
graphql
query CalculateOrderPricing {
calculatePricing(input: {
customerId: "customer-123"
items: [
{
productSku: "BC-PREM-001"
quantity: 1000
options: {
coating: "UV"
sides: "double"
rushOrder: true
}
}
]
}) {
subtotal { amount, currency }
rushFee { amount, currency }
volumeDiscount { amount, currency }
taxAmount { amount, currency }
shippingAmount { amount, currency }
totalAmount { amount, currency }
# Breakdown per item
itemPricing {
productSku
basePrice { amount, currency }
optionsPrice { amount, currency }
quantity
lineTotal { amount, currency }
}
}
}Invoice Generation
graphql
mutation GenerateInvoice {
createInvoice(input: {
orderId: "order-123"
invoiceNumber: "INV-2024-001"
invoiceDate: "2024-03-01"
dueDate: "2024-03-31" # Net 30
# Can override order amounts if needed
subtotal: { amount: 1500.00, currency: "USD" }
taxAmount: { amount: 120.00, currency: "USD" }
totalAmount: { amount: 1620.00, currency: "USD" }
# Billing address
billingAddressId: "address-billing-123"
# Terms
paymentTerms: "Net 30"
notes: "Thank you for your business!"
}) {
result {
id
invoiceNumber
totalAmount { amount, currency }
dueDate
}
}
}Best Practices
1. Order Number Generation
Use a consistent format for order numbers:
ORD-YYYY-NNNN (e.g., ORD-2024-0001)2. Payment Terms Management
Always check credit limits before confirming orders:
graphql
paymentTerms: 30 # Days
creditLimit: { amount: 50000, currency: "USD" }3. Quantity Tolerance
Set realistic min/max quantities for print production:
graphql
quantity: 1000
minDeliverableQuantity: 950 # -5%
maxDeliverableQuantity: 1100 # +10%4. Proof Management
Track proof requirements and approvals:
graphql
proofRequired: HARD_COPY
proofApproved: true
proofApprovedAt: "2024-02-20T10:30:00Z"5. State Transitions
Follow proper order state flow:
- Only confirm orders after credit check
- Link to jobs before moving to IN_PRODUCTION
- Verify shipping details before READY_FOR_PICKUP
6. Financial Accuracy
Always use Money type with currency:
graphql
unitPrice: { amount: 0.15, currency: "USD" }Dashboard Queries
Orders Dashboard
graphql
query OrdersDashboard {
# Today's orders
todaysOrders: listOrders(
filter: {
orderDate: {
greaterThanOrEqual: $todayStart
lessThan: $todayEnd
}
}
) {
count
results {
orderNumber
customer { businessName }
totalAmount { amount }
}
}
# Pending payments
pendingPayments: listOrders(
filter: {
paymentStatus: { in: [PENDING, OVERDUE] }
}
) {
count
results {
orderNumber
totalAmount { amount }
paymentStatus
customer { businessName }
}
}
# Orders awaiting production
awaitingProduction: listOrders(
filter: {
state: { eq: CONFIRMED }
}
) {
count
results {
orderNumber
promisedDeliveryDate
}
}
# Rush orders
rushOrders: listOrders(
filter: {
rushOrder: { eq: true }