30 June 2022
Feature
CartsOrdersPricingCustomizationGraphQL

We have released Quotes in public beta. This new feature allows you to negotiate quote requests for your products with your customers. The negotiation process involves utilizing several APIs that we introduced with this feature, allowing you to control each step of the intended workflow of the negotiation. All the introduced resources, such as Quote Request, Staged Quote, and Quote can be extended with Custom Fields. The discounts applied on a specific Quote, can be utilized by the newly added DirectDiscount. After successful negotiation, the Order can be created right from the Quote.

Changes:

  • [API] Added Quote Requests and My Quote Requests APIs.
  • [API] Added Staged Quotes API.
  • [API] Added Quotes API.
  • [API] Added QuoteRequestCreated, QuoteRequestStateChanged, and QuoteRequestDeleted Messages.
  • [API] Added StagedQuoteCreated, StagedQuoteStateChanged, StagedQuoteValidToSet, StagedQuoteSellerCommentSet, and StagedQuoteDeleted Messages.
  • [API] Added QuoteCreated, QuoteStateChanged, and QuoteDeleted Messages.
  • [API] Added Quote to CartOrigin.
  • [API] Added DirectDiscount and DirectDiscountDraft to Carts API.
  • [API] Added directDiscounts field to Cart and Order.
  • [API] Added setDirectDiscounts update action to Carts and Orders via OrderEdit.
  • [API] Added OrderFromQuoteDraft and Create Order from Quote endpoint to Orders API.
  • [API] Added quote field to Order.
  • [API] Added OAuth scopes manage_quote_requests, view_quote_requests, manage_my_quote_requests, manage_staged_quotes, view_staged_quotes, manage_quotes, and view_quotes.
  • [GraphQL API] Added the following types to the GraphQL schema: CancelQuoteRequest, ChangeMyQuoteMyQuoteState, ChangeQuoteRequestState, ChangeQuoteState, ChangeStagedQuoteState, MyQuoteRequestDraft, MyQuoteRequestUpdateAction, MyQuoteState, MyQuoteUpdateAction, OrderMyQuoteCommand, OrderQuoteCommand, Quote, QuoteDraft, QuoteQueryResult, QuoteRequest, QuoteRequestDraft, QuoteRequestQueryResult, QuoteRequestState, QuoteRequestUpdateAction, QuoteState, QuoteUpdateAction, SetMyQuoteRequestCustomField, SetMyQuoteRequestCustomType, SetQuoteCustomField, SetQuoteCustomType, SetQuoteRequestCustomField, SetQuoteRequestCustomType, SetStagedQuoteCustomField, SetStagedQuoteCustomType, SetStagedQuoteSellerComment, SetStagedQuoteValidTo, StagedQuote, StagedQuoteDraft, StagedQuoteQueryResult, StagedQuoteState, StagedQuoteUpdateAction.
  • [GraphQL API] Changed the Query type:
    • Added the quoteRequest field to the Query type.
    • Added the quotes field to the Query type.
    • Added the stagedQuotes field to the Query type.
    • Added the quote field to the Query type.
    • Added the quoteRequests field to the Query type.
    • Added the stagedQuote field to the Query type.
  • [GraphQL API] Changed the Me type:
    • Added the quoteRequests field to the Me type.
    • Added the quoteRequest field to the Me type.
    • Added the quote field to the Me type.
    • Added the quotes field to the Me type.
  • [GraphQL API] Changed the Mutation type:
    • Added the createQuoteRequest field to the Mutation type.
    • Added the updateQuoteRequest field to the Mutation type.
    • Added the updateMyQuoteRequest field to the Mutation type.
    • Added the createOrderFromQuote field to the Mutation type.
    • Added the updateQuote field to the Mutation type.
    • Added the deleteQuoteRequest field to the Mutation type.
    • Added the createStagedQuote field to the Mutation type.
    • Added the updateMyQuote field to the Mutation type.
    • Added the deleteStagedQuote field to the Mutation type.
    • Added the createQuote field to the Mutation type.
    • Added the updateStagedQuote field to the Mutation type.
    • Added the createMyQuoteRequest field to the Mutation type.
    • Added the createMyOrderFromQuote field to the Mutation type.
    • Added the deleteQuote field to the Mutation type.

The following changes were introduced in terms of GraphQL SDL:

extend type Query {
quote(
"Queries with specified ID"
id: String,
"Queries with specified key"
key: String): Quote
quoteRequest(
"Queries with specified ID"
id: String,
"Queries with specified key"
key: String): QuoteRequest
quoteRequests(where: String, sort: [String!], limit: Int, offset: Int): QuoteRequestQueryResult!
quotes(where: String, sort: [String!], limit: Int, offset: Int): QuoteQueryResult!
stagedQuote(
"Queries with specified ID"
id: String,
"Queries with specified key"
key: String): StagedQuote
stagedQuotes(where: String, sort: [String!], limit: Int, offset: Int): StagedQuoteQueryResult!
}
extend type Me {
"BETA: This feature can be subject to change and should be used carefully in production. https://docs.commercetools.com/api/contract#public-beta"
quote(
"Queries with specified ID"
id: String,
"Queries with specified key"
key: String): Quote
"BETA: This feature can be subject to change and should be used carefully in production. https://docs.commercetools.com/api/contract#public-beta"
quoteRequest(
"Queries with specified ID"
id: String,
"Queries with specified key"
key: String): QuoteRequest
"BETA: This feature can be subject to change and should be used carefully in production. https://docs.commercetools.com/api/contract#public-beta"
quoteRequests(where: String, sort: [String!], limit: Int, offset: Int): QuoteRequestQueryResult!
"BETA: This feature can be subject to change and should be used carefully in production. https://docs.commercetools.com/api/contract#public-beta"
quotes(where: String, sort: [String!], limit: Int, offset: Int): QuoteQueryResult!
}
extend type Mutation {
"BETA: This feature can be subject to change and should be used carefully in production. https://docs.commercetools.com/api/contract#public-beta"
createMyOrderFromQuote(draft: OrderMyQuoteCommand!): Order
createMyQuoteRequest(draft: MyQuoteRequestDraft!): QuoteRequest
createOrderFromQuote(draft: OrderQuoteCommand!): Order
createQuote(draft: QuoteDraft!): Quote
createQuoteRequest(draft: QuoteRequestDraft!): QuoteRequest
createStagedQuote(draft: StagedQuoteDraft!): StagedQuote
deleteQuote(version: Long!, personalDataErasure: Boolean = false,
"Queries with specified ID"
id: String,
"Queries with specified key"
key: String): Quote
deleteQuoteRequest(version: Long!, personalDataErasure: Boolean = false,
"Queries with specified ID"
id: String,
"Queries with specified key"
key: String): QuoteRequest
deleteStagedQuote(version: Long!, personalDataErasure: Boolean = false,
"Queries with specified ID"
id: String,
"Queries with specified key"
key: String): StagedQuote
updateMyQuote(version: Long!, actions: [MyQuoteUpdateAction!]!,
"Queries with specified ID"
id: String,
"Queries with specified key"
key: String): Quote
updateMyQuoteRequest(version: Long!, actions: [MyQuoteRequestUpdateAction!]!,
"Queries with specified ID"
id: String,
"Queries with specified key"
key: String): QuoteRequest
updateQuote(version: Long!, actions: [QuoteUpdateAction!]!,
"Queries with specified ID"
id: String,
"Queries with specified key"
key: String): Quote
updateQuoteRequest(version: Long!, actions: [QuoteRequestUpdateAction!]!,
"Queries with specified ID"
id: String,
"Queries with specified key"
key: String): QuoteRequest
updateStagedQuote(version: Long!, actions: [StagedQuoteUpdateAction!]!,
"Queries with specified ID"
id: String,
"Queries with specified key"
key: String): StagedQuote
}
input CancelQuoteRequest {
dummy: String
}
input ChangeMyQuoteMyQuoteState {
quoteState: MyQuoteState!
}
input ChangeQuoteRequestState {
quoteRequestState: QuoteRequestState!
}
input ChangeQuoteState {
quoteState: MyQuoteState!
}
input ChangeStagedQuoteState {
stagedQuoteState: StagedQuoteState!
}
input MyQuoteRequestDraft {
cartId: String!
comment: String
cartVersion: Long!
}
input MyQuoteRequestUpdateAction {
cancelQuoteRequest: CancelQuoteRequest
setCustomField: SetMyQuoteRequestCustomField
setCustomType: SetMyQuoteRequestCustomType
}
enum MyQuoteState {
Accepted
Declined
Failed
}
input MyQuoteUpdateAction {
changeMyQuoteState: ChangeMyQuoteMyQuoteState
setCustomField: SetQuoteCustomField
setCustomType: SetQuoteCustomType
}
input OrderMyQuoteCommand {
id: String!
version: Long!
}
input OrderQuoteCommand {
quote: ResourceIdentifierInput
version: Long!
paymentState: PaymentState
orderState: OrderState
state: ReferenceInput
shipmentState: ShipmentState
orderNumber: String
custom: CustomFieldsDraft
}
type Quote implements Versioned {
customerRef: Reference
customer: Customer
lineItems(
"Queries with specified ID"
id: String): [LineItem!]!
customLineItems: [CustomLineItem!]!
totalPrice: Money!
taxedPrice: TaxedPrice
shippingAddress: Address
billingAddress: Address
itemShippingAddresses: [Address!]!
inventoryMode: InventoryMode!
taxMode: TaxMode!
taxRoundingMode: RoundingMode!
taxCalculationMode: TaxCalculationMode!
country: Country
shippingInfo: ShippingInfo
paymentInfo: PaymentInfo
shippingRateInput: ShippingRateInput
storeRef: KeyReference
store: Store
key: String
quoteState: QuoteState!
stagedQuoteRef: Reference!
stagedQuote: StagedQuote
quoteRequestRef: Reference!
quoteRequest: QuoteRequest
validTo: DateTime
custom: CustomFieldsType
id: String!
version: Long!
createdAt: DateTime!
lastModifiedAt: DateTime!
createdBy: Initiator
lastModifiedBy: Initiator
}
input QuoteDraft {
key: String
stagedQuote: ResourceIdentifierInput
stagedQuoteVersion: Long
custom: CustomFieldsDraft
}
type QuoteQueryResult {
offset: Int!
count: Int!
total: Long!
"BETA: This feature can be subject to change and should be used carefully in production. https://docs.commercetools.com/api/contract#public-beta"
exists: Boolean!
results: [Quote!]!
}
type QuoteRequest implements Versioned {
customerRef: Reference
customer: Customer
lineItems(
"Queries with specified ID"
id: String): [LineItem!]!
customLineItems: [CustomLineItem!]!
totalPrice: Money!
taxedPrice: TaxedPrice
shippingAddress: Address
billingAddress: Address
itemShippingAddresses: [Address!]!
inventoryMode: InventoryMode!
taxMode: TaxMode!
taxRoundingMode: RoundingMode!
taxCalculationMode: TaxCalculationMode!
country: Country
shippingInfo: ShippingInfo
paymentInfo: PaymentInfo
shippingRateInput: ShippingRateInput
storeRef: KeyReference
store: Store
key: String
quoteRequestState: QuoteRequestState!
comment: String
custom: CustomFieldsType
id: String!
version: Long!
createdAt: DateTime!
lastModifiedAt: DateTime!
createdBy: Initiator
lastModifiedBy: Initiator
}
input QuoteRequestDraft {
key: String
cart: ResourceIdentifierInput
comment: String
cartVersion: Long
custom: CustomFieldsDraft
}
type QuoteRequestQueryResult {
offset: Int!
count: Int!
total: Long!
"BETA: This feature can be subject to change and should be used carefully in production. https://docs.commercetools.com/api/contract#public-beta"
exists: Boolean!
results: [QuoteRequest!]!
}
enum QuoteRequestState {
Closed
UnderReview
Submitted
Cancelled
Accepted
Rejected
}
input QuoteRequestUpdateAction {
changeQuoteRequestState: ChangeQuoteRequestState
setCustomField: SetQuoteRequestCustomField
setCustomType: SetQuoteRequestCustomType
}
enum QuoteState {
Accepted
Declined
Failed
Pending
Withdrawn
}
input QuoteUpdateAction {
changeQuoteState: ChangeQuoteState
setCustomField: SetQuoteCustomField
setCustomType: SetQuoteCustomType
}
input SetMyQuoteRequestCustomField {
name: String!
value: String
}
input SetMyQuoteRequestCustomType {
fields: [CustomFieldInput!]
type: ResourceIdentifierInput
typeKey: String
typeId: String
}
input SetQuoteCustomField {
name: String!
value: String
}
input SetQuoteCustomType {
fields: [CustomFieldInput!]
type: ResourceIdentifierInput
typeKey: String
typeId: String
}
input SetQuoteRequestCustomField {
name: String!
value: String
}
input SetQuoteRequestCustomType {
fields: [CustomFieldInput!]
type: ResourceIdentifierInput
typeKey: String
typeId: String
}
input SetStagedQuoteCustomField {
name: String!
value: String
}
input SetStagedQuoteCustomType {
fields: [CustomFieldInput!]
type: ResourceIdentifierInput
typeKey: String
typeId: String
}
input SetStagedQuoteSellerComment {
sellerComment: String
}
input SetStagedQuoteValidTo {
validTo: DateTime
}
type StagedQuote implements Versioned {
key: String
stagedQuoteState: StagedQuoteState!
quoteRequestRef: Reference!
quoteRequest: QuoteRequest
quotationCartRef: Reference!
quotationCart: Cart
customerRef: Reference
customer: Customer
validTo: DateTime
custom: CustomFieldsType
id: String!
version: Long!
createdAt: DateTime!
lastModifiedAt: DateTime!
createdBy: Initiator
lastModifiedBy: Initiator
}
input StagedQuoteDraft {
key: String
quoteRequest: ResourceIdentifierInput
quoteRequestVersion: Long
custom: CustomFieldsDraft
}
type StagedQuoteQueryResult {
offset: Int!
count: Int!
total: Long!
"BETA: This feature can be subject to change and should be used carefully in production. https://docs.commercetools.com/api/contract#public-beta"
exists: Boolean!
results: [StagedQuote!]!
}
enum StagedQuoteState {
Closed
InProgress
Sent
}
input StagedQuoteUpdateAction {
changeStagedQuoteState: ChangeStagedQuoteState
setSellerComment: SetStagedQuoteSellerComment
setCustomField: SetStagedQuoteCustomField
setCustomType: SetStagedQuoteCustomType
setValidTo: SetStagedQuoteValidTo
}