Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: submit and hold invoice for later use in POS #1065

Merged
merged 11 commits into from
Jan 3, 2025
1 change: 1 addition & 0 deletions models/inventory/Point of Sale/POSSettings.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ export class POSSettings extends Doc {
itemWeightDigits?: number;

posUI?: 'Classic' | 'Modern';
submitInvoice?: string;

static filters: FiltersMap = {
cashAccount: () => ({
Expand Down
8 changes: 8 additions & 0 deletions schemas/app/inventory/Point of Sale/POSSettings.json
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,14 @@
"required": true,
"section": "Default"
},
{
"fieldname": "submitInvoice",
"label": "Post Payment",
"fieldtype": "Check",
"default": false,
"description": "create invoice and shipment with payment option later.",
"section": "Default"
},
{
"fieldname": "weightEnabledBarcode",
"label": "Weigth Enabled Barcode",
Expand Down
4 changes: 2 additions & 2 deletions src/pages/POS/ClassicPOS.vue
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@
(date) => emitEvent('setTransferClearanceDate', date)
"
@create-transaction="
(createTransaction) => emitEvent('createTransaction', createTransaction)
(print, status) => emitEvent('createTransaction', print, status)
"
/>

Expand Down Expand Up @@ -287,7 +287,7 @@
>
<slot>
<p class="uppercase text-lg text-white font-semibold">
{{ t`Pay` }}
{{ t`Submit` }}
</p>
</slot>
</Button>
Expand Down
4 changes: 2 additions & 2 deletions src/pages/POS/ModernPOS.vue
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@
(date) => emitEvent('setTransferClearanceDate', date)
"
@create-transaction="
(createTransaction) => emitEvent('createTransaction', createTransaction)
(print, status) => emitEvent('createTransaction', print, status)
"
/>

Expand Down Expand Up @@ -210,7 +210,7 @@
>
<slot>
<p class="uppercase text-lg text-white font-semibold">
{{ t`Pay` }}
{{ t`Submit` }}
</p>
</slot>
</Button>
Expand Down
52 changes: 38 additions & 14 deletions src/pages/POS/POS.vue
Original file line number Diff line number Diff line change
Expand Up @@ -138,6 +138,7 @@ import {
ItemQtyMap,
ItemSerialNumbers,
} from 'src/components/POS/types';
import { ValidationError } from 'fyo/utils/errors';

const COMPONENT_NAME = 'POS';

Expand Down Expand Up @@ -466,6 +467,10 @@ export default defineComponent({

this.sinvDoc = salesInvoiceDoc;
this.toggleModal('SavedInvoice', false);

if (doc.submitted) {
this.toggleModal('Payment');
}
},
setTransferAmount(amount: Money = fyo.pesa(0)) {
this.transferAmount = amount;
Expand All @@ -478,19 +483,25 @@ export default defineComponent({
},

async addItem(item: POSItem | Item | undefined, quantity?: number) {
await this.sinvDoc.runFormulas();
try {
await this.sinvDoc.runFormulas();

if (!item) {
return;
}
if (this.sinvDoc.isSubmitted) {
throw new ValidationError(
t`Cannot add an item to a submitted invoice.`
);
}

if (!item) {
return;
}

const existingItems =
this.sinvDoc.items?.filter(
(invoiceItem) =>
invoiceItem.item === item.name && !invoiceItem.isFreeItem
) ?? [];
const existingItems =
this.sinvDoc.items?.filter(
(invoiceItem) =>
invoiceItem.item === item.name && !invoiceItem.isFreeItem
) ?? [];

try {
if (item.hasBatch) {
for (const invItem of existingItems) {
const itemQty = invItem.quantity ?? 0;
Expand Down Expand Up @@ -571,13 +582,26 @@ export default defineComponent({
await this.applyPricingRule();
await this.sinvDoc.runFormulas();
},

async createTransaction(shouldPrint = false) {
async createTransaction(shouldPrint = false, isPay = false) {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

isPay should be renamed to makePayment or createPayment or something else that suits the action that's performed.

try {
await this.validate();
await this.submitSinvDoc();
await this.makePayment(shouldPrint);
await this.makeStockTransfer();

if (this.sinvDoc.stockNotTransferred) {
await this.makeStockTransfer();
}

if (isPay) {
await this.makePayment(shouldPrint);
}

if (shouldPrint) {
await routeTo(
// eslint-disable-next-line @typescript-eslint/restrict-template-expressions
`/print/${this.sinvDoc.schemaName}/${this.sinvDoc.name}`
);
}

await this.afterTransaction();
await this.setItems();
} catch (error) {
Expand Down
69 changes: 60 additions & 9 deletions src/pages/POS/PaymentModal.vue
Original file line number Diff line number Diff line change
Expand Up @@ -130,12 +130,36 @@
/>
</div>

<div class="grid grid-cols-2 gap-4 fixed bottom-8" style="width: 25rem">
<div class="col-span-2">
<div class="grid grid-cols-2 gap-4 bottom-8">
<div v-if="fyo.singles.POSSettings?.submitInvoice" class="col-span-1">
<Button
class="w-full bg-violet-500 dark:bg-violet-700"
style="padding: 1.35rem"
:disabled="disableSubmitButton"
@click="submitTransaction()"
>
<slot>
<p
class="uppercase text-lg text-white font-semibold"
:disabled="sinvDoc.submitted"
>
{{ t`Submit` }}
</p>
</slot>
</Button>
</div>

<div
:class="
!fyo.singles.POSSettings?.submitInvoice
? 'col-span-2'
: 'col-span-1'
"
>
<Button
class="w-full bg-red-500 dark:bg-red-700"
style="padding: 1.35rem"
@click="$emit('toggleModal', 'Payment')"
@click="cancelTransaction()"
>
<slot>
<p class="uppercase text-lg text-white font-semibold">
Expand All @@ -149,26 +173,27 @@
<Button
class="w-full bg-blue-500 dark:bg-blue-700"
style="padding: 1.35rem"
:disabled="disableSubmitButton"
@click="submitTransaction()"
:disabled="disablePayButton"
@click="payTransaction()"
>
<slot>
<p class="uppercase text-lg text-white font-semibold">
{{ t`Submit` }}
{{ t`Pay` }}
</p>
</slot>
</Button>
</div>

<div class="col-span-1">
<Button
class="w-full bg-green-500 dark:bg-green-700"
style="padding: 1.35rem"
:disabled="disableSubmitButton"
@click="$emit('createTransaction', true)"
:disabled="disablePayButton"
@click="$emit('createTransaction', true, true)"
>
<slot>
<p class="uppercase text-lg text-white font-semibold">
{{ t`Submit & Print` }}
{{ t`Pay & Print` }}
</p>
</slot>
</Button>
Expand Down Expand Up @@ -293,6 +318,26 @@ export default defineComponent({
return false;
},
disableSubmitButton(): boolean {
if (this.sinvDoc.submitted) {
return true;
}

if (
(this.sinvDoc.grandTotal?.float as number) < 1 &&
this.fyo.pesa(this.paidAmount.float).isZero()
) {
return true;
}

if (
this.paymentMethod !== 'Cash' &&
(!this.transferRefNo || !this.transferClearanceDate)
) {
return true;
}
return false;
},
disablePayButton(): boolean {
if (
(this.sinvDoc.grandTotal?.float as number) < 1 &&
this.fyo.pesa(this.paidAmount.float).isZero()
Expand Down Expand Up @@ -332,6 +377,12 @@ export default defineComponent({
submitTransaction() {
this.$emit('createTransaction');
},
payTransaction() {
this.$emit('createTransaction', false, true);
},
cancelTransaction() {
this.$emit('toggleModal', 'Payment');
},
},
});
</script>
43 changes: 38 additions & 5 deletions src/pages/POS/SavedInvoiceModal.vue
Original file line number Diff line number Diff line change
@@ -1,16 +1,33 @@
<template>
<Modal class="h-auto w-auto p-6" :set-close-listener="false">
<p class="text-center font-semibold">{{ t`Saved Invoices` }}</p>
<Modal class="h-auto w-auto p-5" :set-close-listener="false">
<p class="text-center font-semibold">{{ t`Invoices` }}</p>

<hr class="mt-2 dark:border-gray-800" />

<div class="flex justify-around items-center">
<Button
:background="false"
class="w-full h-full p-2 mt-2"
:class="{ 'dark:bg-gray-890 underline': savedInvoiceList }"
@click="savedInvoiceList = true"
>Saved</Button
>

<Button
:background="false"
class="w-full h-full p-2 mt-2"
:class="{ 'dark:bg-gray-890 underline': !savedInvoiceList }"
@click="savedInvoiceList = false"
>Submitted</Button
>
</div>
<Row
:ratio="ratio"
class="
border
flex
items-center
mt-4
mt-2
px-2
w-full
rounded-t-md
Expand All @@ -28,12 +45,12 @@
</Row>

<div
v-if="savedInvoices.length"
v-if="savedInvoiceList ? savedInvoices.length : submittedInvoices.length"
class="overflow-y-auto custom-scroll custom-scroll-thumb2"
style="height: 65vh; width: 60vh"
>
<Row
v-for="row in savedInvoices as SalesInvoice[]"
v-for="row in savedInvoiceList ? savedInvoices : submittedInvoices"
:key="row.name"
:ratio="ratio"
:border="true"
Expand Down Expand Up @@ -88,6 +105,7 @@ import { SalesInvoice } from 'models/baseModels/SalesInvoice/SalesInvoice';
import { defineComponent, inject } from 'vue';
import { ModelNameEnum } from 'models/types';
import { Field } from 'schemas/types';
import { Money } from 'pesa';

export default defineComponent({
name: 'SavedInvoiceModal',
Expand All @@ -108,7 +126,9 @@ export default defineComponent({
},
data() {
return {
savedInvoiceList: true,
savedInvoices: [] as SalesInvoice[],
submittedInvoices: [] as SalesInvoice[],
isModalVisible: false,
};
},
Expand Down Expand Up @@ -152,14 +172,17 @@ export default defineComponent({
async modalStatus(newVal) {
if (newVal) {
await this.setSavedInvoices();
await this.setSubmittedInvoices();
}
},
},
async mounted() {
await this.setSavedInvoices();
await this.setSubmittedInvoices();
},
async activated() {
await this.setSavedInvoices();
await this.setSubmittedInvoices();
},

methods: {
Expand All @@ -172,6 +195,16 @@ export default defineComponent({
}
)) as SalesInvoice[];
},
async setSubmittedInvoices() {
const invoices = (await this.fyo.db.getAll(ModelNameEnum.SalesInvoice, {
fields: [],
filters: { isPOS: true, submitted: true, returnAgainst: null },
})) as SalesInvoice[];

this.submittedInvoices = invoices.filter(
(invoice) => !(invoice.outstandingAmount as Money).isZero()
);
},
async selectedInvoice(row: SalesInvoice) {
let selectedInvoiceDoc = (await this.fyo.doc.getDoc(
ModelNameEnum.SalesInvoice,
Expand Down