feat: Enhance pricing and sales API with free goods and discount scheme support
This commit is contained in:
@@ -4,6 +4,7 @@ import type {
|
|||||||
PriceResolution,
|
PriceResolution,
|
||||||
SchemeResponse,
|
SchemeResponse,
|
||||||
SchemeRuleType,
|
SchemeRuleType,
|
||||||
|
SchemeSuggestion,
|
||||||
} from '@/types/api'
|
} from '@/types/api'
|
||||||
|
|
||||||
// ─── Price Lists ──────────────────────────────────────────────────────────────
|
// ─── Price Lists ──────────────────────────────────────────────────────────────
|
||||||
@@ -89,4 +90,17 @@ export const schemes = {
|
|||||||
|
|
||||||
remove: (id: string) =>
|
remove: (id: string) =>
|
||||||
api.delete(`/schemes/${id}`),
|
api.delete(`/schemes/${id}`),
|
||||||
|
|
||||||
|
setFreeGoodsRule: (id: string, body: { triggerItemId?: string | null; triggerQty?: number | null; freeItemId: string; freeQty: number }) =>
|
||||||
|
api.put<SchemeResponse>(`/schemes/${id}/free-goods-rule`, body).then(r => r.data),
|
||||||
|
|
||||||
|
upsertBundleComponent: (id: string, itemId: string, qty: number) =>
|
||||||
|
api.put<SchemeResponse>(`/schemes/${id}/bundle-components/${itemId}`, { qty }).then(r => r.data),
|
||||||
|
|
||||||
|
removeBundleComponent: (id: string, itemId: string) =>
|
||||||
|
api.delete<SchemeResponse>(`/schemes/${id}/bundle-components/${itemId}`).then(r => r.data),
|
||||||
|
|
||||||
|
/** Schemes the lines of a not-yet-saved Shop PO qualify for (or are close to). */
|
||||||
|
suggest: (body: { storeId: string; items: { itemId: string; quantity: number; unitPrice?: number | null }[] }) =>
|
||||||
|
api.post<SchemeSuggestion[]>('/schemes/suggest', body).then(r => r.data),
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -21,16 +21,22 @@ export interface ShopPOItemBody {
|
|||||||
itemId: string
|
itemId: string
|
||||||
quantity: number
|
quantity: number
|
||||||
unitPrice?: number | null
|
unitPrice?: number | null
|
||||||
|
/** Free issue accepted from a scheme suggestion; priced 0 by the server. */
|
||||||
|
isFree?: boolean
|
||||||
|
schemeId?: string | null
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface CreateShopPOBody {
|
export interface CreateShopPOBody {
|
||||||
storeId: string
|
storeId: string
|
||||||
items: ShopPOItemBody[]
|
items: ShopPOItemBody[]
|
||||||
raisedByUserId?: string | null
|
raisedByUserId?: string | null
|
||||||
|
/** The one flat/slab discount scheme the user accepted. */
|
||||||
|
discountSchemeIds?: string[]
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface UpdateShopPOItemsBody {
|
export interface UpdateShopPOItemsBody {
|
||||||
items: ShopPOItemBody[]
|
items: ShopPOItemBody[]
|
||||||
|
discountSchemeIds?: string[]
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface ShopPOListParams extends PageParams {
|
export interface ShopPOListParams extends PageParams {
|
||||||
@@ -97,8 +103,12 @@ export const invoices = {
|
|||||||
finalize: (id: string, finalizedByUserId?: string | null, adjustments?: { invoiceItemId: string; adjustedQuantity: number; isRemoved?: boolean }[]) =>
|
finalize: (id: string, finalizedByUserId?: string | null, adjustments?: { invoiceItemId: string; adjustedQuantity: number; isRemoved?: boolean }[]) =>
|
||||||
api.post<InvoiceResponse>(`/invoices/${id}/finalize`, { finalizedByUserId, adjustments }).then(r => r.data),
|
api.post<InvoiceResponse>(`/invoices/${id}/finalize`, { finalizedByUserId, adjustments }).then(r => r.data),
|
||||||
|
|
||||||
updateItems: (id: string, items: { invoiceItemId?: string; itemId?: string; quantity: number; unitPrice?: number | null; isRemoved?: boolean }[], editedByUserId?: string | null) =>
|
updateItems: (id: string, items: { invoiceItemId?: string; itemId?: string; quantity: number; unitPrice?: number | null; isRemoved?: boolean }[], editedByUserId?: string | null, discountSchemeIds?: string[]) =>
|
||||||
api.put<InvoiceResponse>(`/invoices/${id}/items`, { items, editedByUserId }).then(r => r.data),
|
api.put<InvoiceResponse>(`/invoices/${id}/items`, { items, editedByUserId, discountSchemeIds }).then(r => r.data),
|
||||||
|
|
||||||
|
/** What the discount and total would be for these unsaved lines (draft editor preview). */
|
||||||
|
previewTotals: (id: string, items: { itemId: string; quantity: number; unitPrice: number; isFree?: boolean; isRemoved?: boolean; schemeId?: string | null }[], discountSchemeIds?: string[]) =>
|
||||||
|
api.post<{ discountAmount: number; totalAmount: number; freeEntitlements: { schemeId: string; quantity: number }[] }>(`/invoices/${id}/preview-totals`, { items, discountSchemeIds }).then(r => r.data),
|
||||||
|
|
||||||
versions: (id: string) =>
|
versions: (id: string) =>
|
||||||
api.get<InvoiceVersionResponse[]>(`/invoices/${id}/versions`).then(r => r.data),
|
api.get<InvoiceVersionResponse[]>(`/invoices/${id}/versions`).then(r => r.data),
|
||||||
|
|||||||
Reference in New Issue
Block a user