Quote Management Data & Events
The Quote Management drop-in uses the event bus to emit and listen to events for communication between drop-ins and external integrations.
Events reference
| Event | Direction | Description |
|---|---|---|
| quote-management/file-upload-error | Emits | Emitted when a specific condition or state change occurs. |
| quote-management/line-item-note-set | Emits | Emitted when a specific condition or state change occurs. |
| quote-management/negotiable-quote-delete-error | Emits | Emitted when a specific condition or state change occurs. |
| quote-management/negotiable-quote-deleted | Emits | Emitted when a specific condition or state change occurs. |
| quote-management/negotiable-quote-requested | Emits | Emitted when a specific condition or state change occurs. |
| quote-management/quote-data/error | Emits | Emitted when an error occurs. |
| quote-management/quote-data/initialized | Emits | Emitted when the component completes initialization. |
| quote-management/quote-template-data/error | Emits | Emitted when an error occurs. |
| quote-management/quote-template-deleted | Emits | Emitted when a specific condition or state change occurs. |
| quote-management/quote-template-generated | Emits | Emitted when a specific condition or state change occurs. |
| quote-management/quote-templates-data | Emits | Emitted when a specific condition or state change occurs. |
| auth/permissions | Listens | Fired by Auth (auth) when permissions are updated. |
| checkout/updated | Listens | Fired by Checkout (checkout) when the component state is updated. |
| quote-management/initialized | Emits and listens | Triggered when the component completes initialization. |
| quote-management/negotiable-quote-close-error | Emits and listens | Emitted and consumed for internal and external communication. |
| quote-management/negotiable-quote-closed | Emits and listens | Emitted and consumed for internal and external communication. |
| quote-management/permissions | Emits and listens | Triggered when permissions are updated. |
| quote-management/quantities-updated | Emits and listens | Emitted and consumed for internal and external communication. |
| quote-management/quote-data | Emits and listens | Emitted and consumed for internal and external communication. |
| quote-management/quote-duplicated | Emits and listens | Emitted and consumed for internal and external communication. |
| quote-management/quote-items-removed | Emits and listens | Emitted and consumed for internal and external communication. |
| quote-management/quote-renamed | Emits and listens | Emitted and consumed for internal and external communication. |
| quote-management/quote-sent-for-review | Emits and listens | Emitted and consumed for internal and external communication. |
| quote-management/quote-template-data | Emits and listens | Emitted and consumed for internal and external communication. |
| quote-management/shipping-address-set | Emits and listens | Emitted and consumed for internal and external communication. |
Event details
The following sections provide detailed information about each event, including its direction, event payload, and usage examples.
auth/permissions (listens)
Fired by Auth (auth) when permissions are updated.
Event payload
AuthPermissionsPayloadExample
import { events } from '@dropins/tools/event-bus.js';
events.on('auth/permissions', (payload) => { console.log('auth/permissions event received:', payload); // Add your custom logic here});checkout/updated (listens)
Fired by Checkout (checkout) when the component state is updated.
Event payload
Cart | NegotiableQuote | nullSee Cart, NegotiableQuote for full type definitions.
Example
import { events } from '@dropins/tools/event-bus.js';
events.on('checkout/updated', (payload) => { console.log('checkout/updated event received:', payload); // Add your custom logic here});quote-management/file-upload-error (emits)
Emitted when a specific condition or state change occurs.
Event payload
{ error: string; fileName?: string;}Example
import { events } from '@dropins/tools/event-bus.js';
events.on('quote-management/file-upload-error', (payload) => { console.log('quote-management/file-upload-error event received:', payload); // Add your custom logic here});quote-management/initialized (emits and listens)
Triggered when the component completes initialization.
Event payload
{ config: StoreConfigModel;}See StoreConfigModel for full type definition.
When triggered
- After
initialize()function completes - On drop-in first load
Example: Example
import { events } from '@dropins/tools/event-bus.js';
events.on('quote-management/initialized', () => { console.log('Quote Management ready'); loadQuotesList();});quote-management/line-item-note-set (emits)
Emitted when a specific condition or state change occurs.
Event payload
{ quote: NegotiableQuoteModel; input: { quoteUid: string; itemUid: string; note: string; quantity?: number;}}See NegotiableQuoteModel for full type definition.
When triggered
- After calling
setLineItemNote() - When merchant or buyer adds/updates item notes
Example: Example
events.on('quote-management/line-item-note-set', (payload) => { console.log(`Note set on item ${payload.data.itemId}:`, payload.data.note); refreshQuoteItemsList();});quote-management/negotiable-quote-close-error (emits and listens)
Emitted and consumed for internal and external communication.
Event payload
{ error: Error; attemptedQuoteUids: string[];}Example
import { events } from '@dropins/tools/event-bus.js';
events.on('quote-management/negotiable-quote-close-error', (payload) => { console.log('quote-management/negotiable-quote-close-error event received:', payload); // Add your custom logic here});quote-management/negotiable-quote-closed (emits and listens)
Emitted and consumed for internal and external communication.
Event payload
{ closedQuoteUids: string[]; resultStatus: string;}When triggered
- After calling
closeNegotiableQuote() - When quote reaches final state
Example: Example
events.on('quote-management/negotiable-quote-closed', (payload) => { console.log(`Quote ${payload.data.quoteId} closed`); redirectToQuotesList();});quote-management/negotiable-quote-delete-error (emits)
Emitted when a specific condition or state change occurs.
Event payload
{ error: Error; attemptedQuoteUids: string[];}Example
import { events } from '@dropins/tools/event-bus.js';
events.on('quote-management/negotiable-quote-delete-error', (payload) => { console.log('quote-management/negotiable-quote-delete-error event received:', payload); // Add your custom logic here});quote-management/negotiable-quote-deleted (emits)
Emitted when a specific condition or state change occurs.
Event payload
{ deletedQuoteUids: string[]; resultStatus: string;}When triggered
- After calling
deleteQuote() - After successful quote deletion
Example: Example
events.on('quote-management/negotiable-quote-deleted', (payload) => { console.log(`Quote ${payload.data.quoteId} deleted`); removeQuoteFromList(payload.data.quoteId);});quote-management/negotiable-quote-requested (emits)
Emitted when a specific condition or state change occurs.
Event payload
{ quote: NegotiableQuoteModel | null; input: { cartId: string; quoteName: string; comment?: string; attachments?: { key: string }[]; isDraft?: boolean;}}See NegotiableQuoteModel for full type definition.
When triggered
- After calling
requestNegotiableQuote() - When buyer submits quote request
Example: Example
events.on('quote-management/negotiable-quote-requested', (payload) => { console.log(`Quote ${payload.data.quoteName} requested`); showSuccessMessage('Quote request submitted'); redirectToQuoteDetails(payload.data.quoteId);});quote-management/permissions (emits and listens)
Triggered when permissions are updated.
Event payload
typeof state.permissionsWhen triggered
- After permission changes
- On user role updates
- After company context switches
Example: Example
events.on('quote-management/permissions', (payload) => { const canRequestQuote = payload.data.permissions.includes('request_quote'); updateQuoteActions(canRequestQuote);});quote-management/quantities-updated (emits and listens)
Emitted and consumed for internal and external communication.
Event payload
{ quote: NegotiableQuoteModel; input: { quoteUid: string; items: Array<{ quoteItemUid: string; quantity: number }>;}}See NegotiableQuoteModel for full type definition.
When triggered
- After calling
updateQuantities() - When buyer or merchant updates quantities
Example: Example
events.on('quote-management/quantities-updated', (payload) => { console.log(`Quantities updated for quote ${payload.data.quoteId}`); refreshQuoteTotals();});quote-management/quote-data (emits and listens)
Emitted and consumed for internal and external communication.
Event payload
{ quote: NegotiableQuoteModel; permissions: typeof state.permissions;}See NegotiableQuoteModel for full type definition.
When triggered
- After loading quote details
- After any quote modification
- After status changes
Example: Example
events.on('quote-management/quote-data', (payload) => { console.log('Quote data updated:', payload.data); updateQuoteDisplay(payload.data);});quote-management/quote-data/error (emits)
Emitted when an error occurs.
Event payload
{ error: Error;}Example
import { events } from '@dropins/tools/event-bus.js';
events.on('quote-management/quote-data/error', (payload) => { console.log('quote-management/quote-data/error event received:', payload); // Add your custom logic here});quote-management/quote-data/initialized (emits)
Emitted when the component completes initialization.
Event payload
{ quote: NegotiableQuoteModel; permissions: typeof state.permissions;}See NegotiableQuoteModel for full type definition.
When triggered
- On first load of quote details
- After quote context is established
Example: Example
events.on('quote-management/quote-data/initialized', (payload) => { console.log('Quote initialized:', payload.data.number); setupQuoteWorkflow(payload.data);});quote-management/quote-duplicated (emits and listens)
Emitted and consumed for internal and external communication.
Event payload
{ quote: NegotiableQuoteModel; input: { quoteUid: string; duplicatedQuoteUid: string;} hasOutOfStockItems?: boolean;}See NegotiableQuoteModel for full type definition.
When triggered
- After calling
duplicateQuote() - When creating copy of existing quote
Example: Example
events.on('quote-management/quote-duplicated', (payload) => { console.log(`Quote duplicated: ${payload.data.originalQuoteId} -> ${payload.data.newQuoteId}`); redirectToQuote(payload.data.newQuoteId);});quote-management/quote-items-removed (emits and listens)
Emitted and consumed for internal and external communication.
Event payload
{ quote: NegotiableQuoteModel; removedItemUids: string[]; input: RemoveNegotiableQuoteItemsInput;}See NegotiableQuoteModel for full type definition.
When triggered
- After calling
removeNegotiableQuoteItems() - When items are deleted from quote
Example: Example
events.on('quote-management/quote-items-removed', (payload) => { console.log(`Removed ${payload.data.removedItemIds.length} items`); refreshQuoteItemsList();});quote-management/quote-renamed (emits and listens)
Emitted and consumed for internal and external communication.
Event payload
{ quote: NegotiableQuoteModel; input: { quoteUid: string; quoteName: string; quoteComment?: string;}}See NegotiableQuoteModel for full type definition.
When triggered
- After calling
renameNegotiableQuote() - When quote name is updated
Example: Example
events.on('quote-management/quote-renamed', (payload) => { console.log(`Quote renamed to: ${payload.data.newName}`); updateQuoteHeader(payload.data.newName);});quote-management/quote-sent-for-review (emits and listens)
Emitted and consumed for internal and external communication.
Event payload
{ quote: NegotiableQuoteModel; input: { quoteUid: string; comment?: string; attachments?: { key: string }[];}}See NegotiableQuoteModel for full type definition.
When triggered
- After calling
sendForReview() - When buyer submits quote for negotiation
Example: Example
events.on('quote-management/quote-sent-for-review', (payload) => { console.log(`Quote ${payload.data.quoteId} sent for review`); showSuccessMessage('Quote submitted for merchant review'); updateQuoteStatus('pending');});quote-management/quote-template-data (emits and listens)
Emitted and consumed for internal and external communication.
Event payload
{ quoteTemplate: NegotiableQuoteTemplateModel; permissions: typeof state.permissions;}See NegotiableQuoteTemplateModel for full type definition.
When triggered
- After loading template details
- After template modifications
- After template status changes
Example: Example
events.on('quote-management/quote-template-data', (payload) => { console.log('Template data updated:', payload.data); updateTemplateDisplay(payload.data);});quote-management/quote-template-data/error (emits)
Emitted when an error occurs.
Event payload
{ error: Error;}Example
import { events } from '@dropins/tools/event-bus.js';
events.on('quote-management/quote-template-data/error', (payload) => { console.log('quote-management/quote-template-data/error event received:', payload); // Add your custom logic here});quote-management/quote-template-deleted (emits)
Emitted when a specific condition or state change occurs.
Event payload
{ templateId: string;}When triggered
- After calling
deleteQuoteTemplate() - After successful template deletion
Example: Example
events.on('quote-management/quote-template-deleted', (payload) => { console.log(`Template ${payload.data.templateId} deleted`); removeTemplateFromList(payload.data.templateId);});quote-management/quote-template-generated (emits)
Emitted when a specific condition or state change occurs.
Event payload
{ quoteId: string;}When triggered
- After calling
generateQuoteFromTemplate() - When creating quote from template
Example 1: Basic template generation
events.on('quote-management/quote-template-generated', (payload) => { console.log(`Quote ${payload.data.quoteId} generated from template ${payload.data.templateId}`); redirectToQuote(payload.data.quoteId);});Example 2: Template catalog with quick-quote generation
import { events } from '@dropins/tools/event-bus.js';import { generateQuoteFromTemplate, getQuoteTemplates } from '@dropins/storefront-quote-management/api.js';
class QuoteTemplateCatalog { constructor(containerElement) { this.container = containerElement; this.templates = [];
// Listen for template generation events.on('quote-management/quote-template-generated', this.handleQuoteGenerated.bind(this));
this.init(); }
async init() { try { // Load all available templates const response = await getQuoteTemplates({ currentPage: 1, pageSize: 50, sort: { field: 'name', direction: 'ASC' } });
this.templates = response.items; this.render();
} catch (error) { this.showError('Failed to load quote templates'); console.error(error); } }
render() { this.container.innerHTML = ` <div class="template-catalog"> <h2>Quote Templates</h2> <div class="template-grid"> ${this.templates.map(template => this.renderTemplateCard(template)).join('')} </div> </div> `;
// Attach event listeners this.container.querySelectorAll('.generate-quote-btn').forEach(btn => { btn.addEventListener('click', (e) => { const templateUid = e.target.dataset.templateUid; this.generateQuote(templateUid); }); }); }
renderTemplateCard(template) { return ` <div class="template-card" data-template-uid="${template.uid}"> <div class="template-header"> <h3>${template.name}</h3> <span class="item-count">${template.items.length} items</span> </div> <div class="template-meta"> <span class="total">Total: ${template.prices.grandTotal.value}</span> <span class="date">Created: ${formatDate(template.createdAt)}</span> </div> <div class="template-actions"> <button class="generate-quote-btn" data-template-uid="${template.uid}"> Generate Quote </button> <button class="view-template-btn" onclick="viewTemplate('${template.uid}')"> View Details </button> </div> </div> `; }
async generateQuote(templateUid) { const template = this.templates.find(t => t.uid === templateUid); if (!template) return;
try { // Show loading state this.showLoadingOverlay(`Generating quote from "${template.name}"...`);
// Generate quote from template await generateQuoteFromTemplate(templateUid);
// Event handler will redirect when complete
} catch (error) { this.hideLoadingOverlay(); this.showError('Failed to generate quote: ' + error.message); console.error(error); } }
handleQuoteGenerated(payload) { const { templateId, quoteId } = payload.data;
this.hideLoadingOverlay();
// Get template name for notification const template = this.templates.find(t => t.uid === templateId); const templateName = template ? template.name : 'template';
// Show success notification this.showSuccess(`Quote generated from "${templateName}"`);
// Track analytics trackAnalytics('quote_generated_from_template', { templateId, quoteId, templateName });
// Redirect to the new quote for editing setTimeout(() => { window.location.href = `/quotes/${quoteId}`; }, 1500); }
showLoadingOverlay(message) { const overlay = document.createElement('div'); overlay.id = 'loading-overlay'; overlay.innerHTML = ` <div class="loading-spinner"></div> <div class="loading-message">${message}</div> `; document.body.appendChild(overlay); }
hideLoadingOverlay() { const overlay = document.getElementById('loading-overlay'); if (overlay) overlay.remove(); }
showSuccess(message) { this.showToast(message, 'success'); }
showError(message) { this.showToast(message, 'error'); }
showToast(message, type) { const toast = document.createElement('div'); toast.className = `toast toast-${type}`; toast.textContent = message; document.body.appendChild(toast); setTimeout(() => toast.remove(), 3000); }}
// Initialize template catalogconst catalog = new QuoteTemplateCatalog(document.querySelector('#template-catalog'));Example 3: Recurring order workflow using templates
import { events } from '@dropins/tools/event-bus.js';import { generateQuoteFromTemplate, submitNegotiableQuote } from '@dropins/storefront-quote-management/api.js';
/** * Automated recurring order system using quote templates * Useful for customers who regularly order the same items */class RecurringOrderManager { constructor() { this.activeOrders = [];
events.on('quote-management/quote-template-generated', this.handleGeneration.bind(this)); events.on('quote-management/quote-sent-for-review', this.handleSubmission.bind(this)); }
/** * Set up a recurring order schedule */ async scheduleRecurringOrder(templateUid, schedule) { const recurringOrder = { templateUid, schedule, // e.g., { frequency: 'monthly', dayOfMonth: 1 } status: 'active', lastGenerated: null, nextGeneration: this.calculateNextDate(schedule) };
// Save to user preferences await this.saveRecurringOrder(recurringOrder);
// Set up next execution this.scheduleNextGeneration(recurringOrder);
return recurringOrder; }
/** * Generate quote from template on schedule */ async generateScheduledQuote(templateUid, autoSubmit = true) { try { console.log(`Generating scheduled quote from template ${templateUid}`);
// Generate the quote await generateQuoteFromTemplate(templateUid);
// Store auto-submit preference if (autoSubmit) { this.pendingAutoSubmits.add(templateUid); }
} catch (error) { console.error('Failed to generate scheduled quote:', error);
// Notify user of failure this.notifyGenerationFailure(templateUid, error); } }
/** * Handle successful quote generation */ async handleGeneration(payload) { const { templateId, quoteId } = payload.data;
console.log(`Quote ${quoteId} generated from template ${templateId}`);
// Check if this was an automated generation if (this.pendingAutoSubmits.has(templateId)) { // Automatically submit for review try { await submitNegotiableQuote(quoteId); console.log(`Auto-submitted quote ${quoteId} for review`);
this.pendingAutoSubmits.delete(templateId);
} catch (error) { console.error('Failed to auto-submit quote:', error);
// Notify user to manually submit this.notifyManualSubmissionNeeded(quoteId); } }
// Update recurring order record await this.updateRecurringOrderHistory(templateId, quoteId); }
/** * Handle quote submission */ handleSubmission(payload) { const { quoteId } = payload.data;
// Send confirmation email this.sendSubmissionConfirmation(quoteId);
// Update dashboard this.updateDashboard(); }
calculateNextDate(schedule) { const now = new Date(); switch (schedule.frequency) { case 'weekly': return new Date(now.setDate(now.getDate() + 7)); case 'monthly': return new Date(now.setMonth(now.getMonth() + 1, schedule.dayOfMonth)); case 'quarterly': return new Date(now.setMonth(now.getMonth() + 3, schedule.dayOfMonth)); default: return null; } }
scheduleNextGeneration(recurringOrder) { const delay = recurringOrder.nextGeneration - new Date(); setTimeout(() => { this.generateScheduledQuote(recurringOrder.templateUid, true); }, delay); }
// Helper methods pendingAutoSubmits = new Set();
async saveRecurringOrder(order) { /* Save to backend */ } async updateRecurringOrderHistory(templateId, quoteId) { /* Update history */ } notifyGenerationFailure(templateId, error) { /* Send notification */ } notifyManualSubmissionNeeded(quoteId) { /* Send notification */ } sendSubmissionConfirmation(quoteId) { /* Send email */ } updateDashboard() { /* Refresh UI */ }}
// Initialize recurring order systemconst recurringOrders = new RecurringOrderManager();
// Example: Set up monthly recurring orderrecurringOrders.scheduleRecurringOrder('template-uid-123', { frequency: 'monthly', dayOfMonth: 1});Usage scenarios
- One-click quote generation from commonly used templates.
- Streamline repeat ordering workflows for regular customers.
- Implement recurring order systems based on templates.
- Quick quote creation for standard product bundles.
- Template-based ordering for seasonal or periodic purchases.
- Automated quote generation for subscription-like B2B orders.
quote-management/quote-templates-data (emits)
Emitted when a specific condition or state change occurs.
Event payload
{ quoteTemplates: NegotiableQuoteTemplatesListModel; permissions: typeof state.permissions;}See NegotiableQuoteTemplatesListModel for full type definition.
When triggered
- After loading templates list
- After template creation/deletion
- After template status changes
Example: Example
events.on('quote-management/quote-templates-data', (payload) => { console.log(`${payload.data.totalCount} templates loaded`); updateTemplatesList(payload.data.templates);});quote-management/shipping-address-set (emits and listens)
Emitted and consumed for internal and external communication.
Event payload
{ quote: NegotiableQuoteModel; input: { quoteUid: string; addressId?: number; addressData?: AddressInput;}}See NegotiableQuoteModel for full type definition.
When triggered
- After calling
setShippingAddress() - When shipping address is updated
Example: Example
events.on('quote-management/shipping-address-set', (payload) => { console.log('Shipping address set:', payload.data.address); refreshShippingMethods(); recalculateQuoteTotals();});Listening to events
All Quote Management events are emitted through the centralized event bus:
import { events } from '@dropins/tools/event-bus.js';
// Listen to quote lifecycle eventsevents.on('quote-management/negotiable-quote-requested', handleQuoteRequest);events.on('quote-management/quote-sent-for-review', handleQuoteReview);events.on('quote-management/quote-duplicated', handleQuoteDuplicate);
// Listen to quote data changesevents.on('quote-management/quote-data', handleQuoteUpdate);events.on('quote-management/quantities-updated', handleQuantityChange);
// Listen to template eventsevents.on('quote-management/quote-template-generated', handleTemplateGeneration);events.on('quote-management/quote-templates-data', handleTemplatesLoad);
// Clean up listenersevents.off('quote-management/quote-data', handleQuoteUpdate);Event flow examples
Data Models
The following data models are used in event payloads for this drop-in.
NegotiableQuoteModel
Used in: quote-management/line-item-note-set, quote-management/negotiable-quote-requested, quote-management/quantities-updated, quote-management/quote-data, quote-management/quote-data/initialized, quote-management/quote-duplicated, quote-management/quote-items-removed, quote-management/quote-renamed, quote-management/quote-sent-for-review, quote-management/shipping-address-set.
interface NegotiableQuoteModel { uid: string; name: string; createdAt: string; salesRepName: string; expirationDate: string; updatedAt: string; status: NegotiableQuoteStatus; isVirtual: boolean; buyer: { firstname: string; lastname: string; }; templateName?: string; totalQuantity: number; comments?: { uid: string; createdAt: string; author: { firstname: string; lastname: string; }; text: string; attachments?: { name: string; url: string; }[]; }[]; history?: NegotiableQuoteHistoryEntry[]; prices: { appliedDiscounts?: Discount[]; appliedTaxes?: Tax[]; discount?: Currency; grandTotal?: Currency; grandTotalExcludingTax?: Currency; shippingExcludingTax?: Currency; shippingIncludingTax?: Currency; subtotalExcludingTax?: Currency; subtotalIncludingTax?: Currency; subtotalWithDiscountExcludingTax?: Currency; totalTax?: Currency; }; items: CartItemModel[]; shippingAddresses?: ShippingAddress[]; canCheckout: boolean; canSendForReview: boolean; lockedForEditing?: boolean; canDelete: boolean; canClose: boolean; canUpdateQuote: boolean; readOnly: boolean;}NegotiableQuoteTemplateModel
Used in: quote-management/quote-template-data.
interface NegotiableQuoteTemplateModel { id: string; uid: string; name: string; createdAt: string; updatedAt: string; expirationDate?: string; status: NegotiableQuoteTemplateStatus; salesRepName: string; buyer: { firstname: string; lastname: string; }; comments?: QuoteTemplateComment[]; history?: NegotiableQuoteHistoryEntry[]; prices: { subtotalExcludingTax?: Currency; subtotalIncludingTax?: Currency; subtotalWithDiscountExcludingTax?: Currency; grandTotal?: Currency; appliedTaxes?: { amount: Currency; label: string; }[]; }; items: CartItemModel[]; shippingAddresses?: ShippingAddress[]; referenceDocuments?: { uid: string; name: string; identifier?: string; url: string; }[]; // Template-specific fields quantityThresholds?: { min?: number; max?: number; }; canAccept: boolean; canDelete: boolean; canReopen: boolean; canCancel: boolean; canSendForReview: boolean; canGenerateQuoteFromTemplate: boolean; canEditTemplateItems: boolean;}NegotiableQuoteTemplatesListModel
Used in: quote-management/quote-templates-data.
interface NegotiableQuoteTemplatesListModel { items: NegotiableQuoteTemplateListEntry[]; pageInfo: { currentPage: number; pageSize: number; totalPages: number; }; totalCount: number; paginationInfo?: PaginationInfo; sortFields?: { default: string; options: Array<{ label: string; value: string; }>; };}StoreConfigModel
Used in: quote-management/initialized.
interface StoreConfigModel { quoteSummaryDisplayTotal: number; quoteSummaryMaxItems: number; quoteDisplaySettings: { zeroTax: boolean; subtotal: QuoteDisplayAmount; price: QuoteDisplayAmount; shipping: QuoteDisplayAmount; fullSummary: boolean; grandTotal: boolean; }; useConfigurableParentThumbnail: boolean; quoteMinimumAmount: number | null; quoteMinimumAmountMessage: string | null;}