2
0
mirror of https://github.com/frappe/books.git synced 2024-12-23 03:19:01 +00:00

feat: warn about insufficient quantity

This commit is contained in:
18alantom 2023-06-30 09:43:45 +05:30
parent 4013303196
commit 4321a5f60e
3 changed files with 86 additions and 4 deletions

View File

@ -26,7 +26,16 @@
:class="config.iconColor" :class="config.iconColor"
/> />
</div> </div>
<p v-if="detail" class="text-base">{{ detail }}</p>
<template v-if="detail">
<p v-if="typeof detail === 'string'" class="text-base">
{{ detail }}
</p>
<div v-else v-for="d of detail">
<p class="text-base">{{ d }}</p>
</div>
</template>
<div class="flex justify-end gap-4 mt-4"> <div class="flex justify-end gap-4 mt-4">
<Button <Button
v-for="(b, index) of buttons" v-for="(b, index) of buttons"
@ -57,7 +66,7 @@ export default defineComponent({
type: { type: String as PropType<ToastType>, default: 'info' }, type: { type: String as PropType<ToastType>, default: 'info' },
title: { type: String, required: true }, title: { type: String, required: true },
detail: { detail: {
type: String, type: [String, Array] as PropType<string | string[]>,
required: false, required: false,
}, },
buttons: { buttons: {

View File

@ -108,7 +108,7 @@ export type PrintValues = {
export interface DialogOptions { export interface DialogOptions {
title: string; title: string;
type?: ToastType; type?: ToastType;
detail?: string; detail?: string | string[];
buttons?: DialogButton[]; buttons?: DialogButton[];
} }

View File

@ -544,7 +544,19 @@ async function syncWithoutDialog(doc: Doc): Promise<boolean> {
} }
export async function commonDocSubmit(doc: Doc): Promise<boolean> { export async function commonDocSubmit(doc: Doc): Promise<boolean> {
const success = await showSubmitOrSyncDialog(doc, 'submit'); let success = true;
if (
doc instanceof SalesInvoice &&
fyo.singles.AccountingSettings?.enableInventory
) {
success = await showInsufficientInventoryDialog(doc);
}
if (!success) {
return false;
}
success = await showSubmitOrSyncDialog(doc, 'submit');
if (!success) { if (!success) {
return false; return false;
} }
@ -553,6 +565,67 @@ export async function commonDocSubmit(doc: Doc): Promise<boolean> {
return true; return true;
} }
async function showInsufficientInventoryDialog(doc: SalesInvoice) {
const insufficient: { item: string; quantity: number }[] = [];
for (const { item, quantity, batch } of doc.items ?? []) {
if (!item || typeof quantity !== 'number') {
continue;
}
const isTracked = await fyo.getValue(ModelNameEnum.Item, item, 'trackItem');
if (!isTracked) {
continue;
}
const stockQuantity =
(await fyo.db.getStockQuantity(
item,
undefined,
undefined,
doc.date!.toISOString(),
batch
)) ?? 0;
if (stockQuantity > quantity) {
continue;
}
insufficient.push({ item, quantity: quantity - stockQuantity });
}
if (insufficient.length) {
const buttons = [
{
label: t`Yes`,
action: () => true,
isPrimary: true,
},
{
label: t`No`,
action: () => false,
isEscape: true,
},
];
const list = insufficient
.map(({ item, quantity }) => `${item} (${quantity})`)
.join(', ');
const detail = [
t`The following items have insufficient quantities to create a Shipment: ${list}`,
t`Continue submitting Sales Invoice?`,
];
return (await showDialog({
title: t`Insufficient Quantity`,
type: 'warning',
detail,
buttons,
})) as boolean;
}
return true;
}
async function showSubmitOrSyncDialog(doc: Doc, type: 'submit' | 'sync') { async function showSubmitOrSyncDialog(doc: Doc, type: 'submit' | 'sync') {
const label = getDocReferenceLabel(doc); const label = getDocReferenceLabel(doc);
let title = t`Save ${label}?`; let title = t`Save ${label}?`;