Skip to content

Search is only available in production builds. Try building and previewing the site to test it out locally.

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.

Version: 1.0.0-beta5

Events reference

EventDirectionDescription
quote-management/file-upload-errorEmitsEmitted when a specific condition or state change occurs.
quote-management/line-item-note-setEmitsEmitted when a specific condition or state change occurs.
quote-management/negotiable-quote-delete-errorEmitsEmitted when a specific condition or state change occurs.
quote-management/negotiable-quote-deletedEmitsEmitted when a specific condition or state change occurs.
quote-management/negotiable-quote-requestedEmitsEmitted when a specific condition or state change occurs.
quote-management/quote-data/errorEmitsEmitted when an error occurs.
quote-management/quote-data/initializedEmitsEmitted when the component completes initialization.
quote-management/quote-template-data/errorEmitsEmitted when an error occurs.
quote-management/quote-template-deletedEmitsEmitted when a specific condition or state change occurs.
quote-management/quote-template-generatedEmitsEmitted when a specific condition or state change occurs.
quote-management/quote-templates-dataEmitsEmitted when a specific condition or state change occurs.
auth/permissionsListensFired by Auth (auth) when permissions are updated.
checkout/updatedListensFired by Checkout (checkout) when the component state is updated.
quote-management/initializedEmits and listensTriggered when the component completes initialization.
quote-management/negotiable-quote-close-errorEmits and listensEmitted and consumed for internal and external communication.
quote-management/negotiable-quote-closedEmits and listensEmitted and consumed for internal and external communication.
quote-management/permissionsEmits and listensTriggered when permissions are updated.
quote-management/quantities-updatedEmits and listensEmitted and consumed for internal and external communication.
quote-management/quote-dataEmits and listensEmitted and consumed for internal and external communication.
quote-management/quote-duplicatedEmits and listensEmitted and consumed for internal and external communication.
quote-management/quote-items-removedEmits and listensEmitted and consumed for internal and external communication.
quote-management/quote-renamedEmits and listensEmitted and consumed for internal and external communication.
quote-management/quote-sent-for-reviewEmits and listensEmitted and consumed for internal and external communication.
quote-management/quote-template-dataEmits and listensEmitted and consumed for internal and external communication.
quote-management/shipping-address-setEmits and listensEmitted 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

AuthPermissionsPayload

Example

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 | null

See 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.permissions

When 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 catalog
const 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 system
const recurringOrders = new RecurringOrderManager();
// Example: Set up monthly recurring order
recurringOrders.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 events
events.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 changes
events.on('quote-management/quote-data', handleQuoteUpdate);
events.on('quote-management/quantities-updated', handleQuantityChange);
// Listen to template events
events.on('quote-management/quote-template-generated', handleTemplateGeneration);
events.on('quote-management/quote-templates-data', handleTemplatesLoad);
// Clean up listeners
events.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;
}