30 June 2022
CartsOrdersPricing and DiscountsExtensibilityGraphQL
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
, andview_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 theQuery
type. - Added the
quotes
field to theQuery
type. - Added the
stagedQuotes
field to theQuery
type. - Added the
quote
field to theQuery
type. - Added the
quoteRequests
field to theQuery
type. - Added the
stagedQuote
field to theQuery
type.
- Added the
- [GraphQL API] Changed the
Me
type:- Added the
quoteRequests
field to theMe
type. - Added the
quoteRequest
field to theMe
type. - Added the
quote
field to theMe
type. - Added the
quotes
field to theMe
type.
- Added the
- [GraphQL API] Changed the
Mutation
type:- Added the
createQuoteRequest
field to theMutation
type. - Added the
updateQuoteRequest
field to theMutation
type. - Added the
updateMyQuoteRequest
field to theMutation
type. - Added the
createOrderFromQuote
field to theMutation
type. - Added the
updateQuote
field to theMutation
type. - Added the
deleteQuoteRequest
field to theMutation
type. - Added the
createStagedQuote
field to theMutation
type. - Added the
updateMyQuote
field to theMutation
type. - Added the
deleteStagedQuote
field to theMutation
type. - Added the
createQuote
field to theMutation
type. - Added the
updateStagedQuote
field to theMutation
type. - Added the
createMyQuoteRequest
field to theMutation
type. - Added the
createMyOrderFromQuote
field to theMutation
type. - Added the
deleteQuote
field to theMutation
type.
- Added the
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
}