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
Quoteto CartOrigin. - [API] Added DirectDiscount and DirectDiscountDraft to Carts API.
- [API] Added
directDiscountsfield to Cart and Order. - [API] Added
setDirectDiscountsupdate action to Carts and Orders via OrderEdit. - [API] Added OrderFromQuoteDraft and Create Order from Quote endpoint to Orders API.
- [API] Added
quotefield 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
Querytype:- Added the
quoteRequestfield to theQuerytype. - Added the
quotesfield to theQuerytype. - Added the
stagedQuotesfield to theQuerytype. - Added the
quotefield to theQuerytype. - Added the
quoteRequestsfield to theQuerytype. - Added the
stagedQuotefield to theQuerytype.
- Added the
- [GraphQL API] Changed the
Metype:- Added the
quoteRequestsfield to theMetype. - Added the
quoteRequestfield to theMetype. - Added the
quotefield to theMetype. - Added the
quotesfield to theMetype.
- Added the
- [GraphQL API] Changed the
Mutationtype:- Added the
createQuoteRequestfield to theMutationtype. - Added the
updateQuoteRequestfield to theMutationtype. - Added the
updateMyQuoteRequestfield to theMutationtype. - Added the
createOrderFromQuotefield to theMutationtype. - Added the
updateQuotefield to theMutationtype. - Added the
deleteQuoteRequestfield to theMutationtype. - Added the
createStagedQuotefield to theMutationtype. - Added the
updateMyQuotefield to theMutationtype. - Added the
deleteStagedQuotefield to theMutationtype. - Added the
createQuotefield to theMutationtype. - Added the
updateStagedQuotefield to theMutationtype. - Added the
createMyQuoteRequestfield to theMutationtype. - Added the
createMyOrderFromQuotefield to theMutationtype. - Added the
deleteQuotefield to theMutationtype.
- 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
}