mirror of
https://github.com/frappe/books.git
synced 2025-02-02 12:08:27 +00:00
Merge pull request #1079 from AbleKSaju/feat-return-invoice
feat: return invoice functionality in POS
This commit is contained in:
commit
0e120bf315
@ -50,6 +50,7 @@ import { CouponCode } from '../CouponCode/CouponCode';
|
||||
import { SalesInvoice } from '../SalesInvoice/SalesInvoice';
|
||||
import { SalesInvoiceItem } from '../SalesInvoiceItem/SalesInvoiceItem';
|
||||
import { PricingRuleItem } from '../PricingRuleItem/PricingRuleItem';
|
||||
import { getLinkedEntries } from 'src/utils/doc';
|
||||
|
||||
export type TaxDetail = {
|
||||
account: string;
|
||||
@ -982,6 +983,17 @@ export abstract class Invoice extends Transactional {
|
||||
return null;
|
||||
}
|
||||
|
||||
let linkedEntries;
|
||||
|
||||
if (this.returnAgainst) {
|
||||
const sinvDoc = (await this.fyo.doc.getDoc(
|
||||
ModelNameEnum.SalesInvoice,
|
||||
this.returnAgainst
|
||||
)) as SalesInvoice;
|
||||
|
||||
linkedEntries = await getLinkedEntries(sinvDoc);
|
||||
}
|
||||
|
||||
if (!this.stockNotTransferred) {
|
||||
return null;
|
||||
}
|
||||
@ -1005,6 +1017,7 @@ export abstract class Invoice extends Transactional {
|
||||
terms,
|
||||
numberSeries,
|
||||
backReference: this.name,
|
||||
returnAgainst: linkedEntries ? linkedEntries.Shipment![0] : '',
|
||||
};
|
||||
|
||||
let location = this.autoStockTransferLocation;
|
||||
|
@ -55,8 +55,7 @@
|
||||
"label": "Is POS Shift Open",
|
||||
"fieldtype": "Check",
|
||||
"default": false,
|
||||
"hidden": true,
|
||||
"section": "Default"
|
||||
"hidden": true
|
||||
},
|
||||
{
|
||||
"fieldname": "weightEnabledBarcode",
|
||||
|
@ -17,6 +17,7 @@ export const modalNames = [
|
||||
'Alert',
|
||||
'CouponCode',
|
||||
'PriceList',
|
||||
'ReturnSalesInvoice',
|
||||
] as const;
|
||||
|
||||
export type ModalName = typeof modalNames[number];
|
||||
@ -35,6 +36,7 @@ export type PosEmits =
|
||||
| 'setTransferAmount'
|
||||
| 'createTransaction'
|
||||
| 'selectedInvoiceName'
|
||||
| 'selectedReturnInvoice'
|
||||
| 'setTransferClearanceDate';
|
||||
|
||||
export interface POSItem {
|
||||
|
@ -56,6 +56,13 @@
|
||||
"
|
||||
/>
|
||||
|
||||
<ReturnSalesInvoiceModal
|
||||
:open-modal="openReturnSalesInvoiceModal"
|
||||
:modal-status="openReturnSalesInvoiceModal"
|
||||
@selected-return-invoice="(value:any) => emitEvent('selectedReturnInvoice', value)"
|
||||
@toggle-modal="emitEvent('toggleModal', 'ReturnSalesInvoice')"
|
||||
/>
|
||||
|
||||
<AlertModal
|
||||
:open-modal="openAlertModal"
|
||||
@toggle-modal="emitEvent('toggleModal', 'Alert')"
|
||||
@ -180,7 +187,7 @@
|
||||
|
||||
<div
|
||||
class="
|
||||
p-4
|
||||
p-3
|
||||
bg-white
|
||||
border
|
||||
rounded-md
|
||||
@ -188,7 +195,7 @@
|
||||
"
|
||||
>
|
||||
<div class="w-full grid grid-cols-2 gap-y-2 gap-x-3">
|
||||
<div class="">
|
||||
<div class="flex flex-col justify-end">
|
||||
<div class="grid grid-cols-2 gap-2">
|
||||
<FloatingLabelFloatInput
|
||||
:df="{
|
||||
@ -242,10 +249,11 @@
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex w-full gap-2">
|
||||
<div class="w-full">
|
||||
<div class="w-full">
|
||||
<div class="w-full flex gap-2">
|
||||
<Button
|
||||
class="w-full bg-violet-500 dark:bg-violet-700 py-6"
|
||||
class="w-full bg-violet-500 dark:bg-violet-700"
|
||||
:class="`${isReturnInvoiceEnabledReturn ? 'py-5' : 'py-6'}`"
|
||||
:disabled="!sinvDoc?.party || !sinvDoc?.items?.length"
|
||||
@click="$emit('saveInvoiceAction')"
|
||||
>
|
||||
@ -255,21 +263,9 @@
|
||||
</p>
|
||||
</slot>
|
||||
</Button>
|
||||
|
||||
<Button
|
||||
class="w-full mt-4 bg-blue-500 dark:bg-blue-700 py-6"
|
||||
@click="emitEvent('toggleModal', 'SavedInvoice', true)"
|
||||
>
|
||||
<slot>
|
||||
<p class="uppercase text-lg text-white font-semibold">
|
||||
{{ t`held` }}
|
||||
</p>
|
||||
</slot>
|
||||
</Button>
|
||||
</div>
|
||||
<div class="w-full">
|
||||
<Button
|
||||
class="w-full bg-red-500 dark:bg-red-700 py-6"
|
||||
class="w-full bg-red-500 dark:bg-red-700"
|
||||
:class="`${isReturnInvoiceEnabledReturn ? 'py-5' : 'py-6'}`"
|
||||
:disabled="!sinvDoc?.items?.length"
|
||||
@click="() => $emit('clearValues')"
|
||||
>
|
||||
@ -279,19 +275,62 @@
|
||||
</p>
|
||||
</slot>
|
||||
</Button>
|
||||
</div>
|
||||
<div
|
||||
class="w-full flex gap-2"
|
||||
:class="`${isReturnInvoiceEnabledReturn ? 'mt-2' : 'mt-4'}`"
|
||||
>
|
||||
<Button
|
||||
class="w-full bg-blue-500 dark:bg-blue-700"
|
||||
:class="`${isReturnInvoiceEnabledReturn ? 'py-5' : 'py-6'}`"
|
||||
@click="emitEvent('toggleModal', 'SavedInvoice', true)"
|
||||
>
|
||||
<slot>
|
||||
<p class="uppercase text-lg text-white font-semibold">
|
||||
{{ t`held` }}
|
||||
</p>
|
||||
</slot>
|
||||
</Button>
|
||||
|
||||
<Button
|
||||
class="mt-4 w-full bg-green-500 dark:bg-green-700 py-6"
|
||||
v-if="isReturnInvoiceEnabledReturn"
|
||||
class="w-full bg-orange-500 dark:bg-orange-700 py-5"
|
||||
@click="
|
||||
emitEvent('toggleModal', 'ReturnSalesInvoice', true)
|
||||
"
|
||||
>
|
||||
<slot>
|
||||
<p class="uppercase text-lg text-white font-semibold">
|
||||
{{ t`Return` }}
|
||||
</p>
|
||||
</slot>
|
||||
</Button>
|
||||
<Button
|
||||
v-else
|
||||
class="w-full bg-green-500 dark:bg-green-700"
|
||||
:class="`${isReturnInvoiceEnabledReturn ? 'py-5' : 'py-6'}`"
|
||||
:disabled="disablePayButton"
|
||||
@click="emitEvent('toggleModal', 'Payment', true)"
|
||||
>
|
||||
<slot>
|
||||
<p class="uppercase text-lg text-white font-semibold">
|
||||
{{ t`Buy` }}
|
||||
{{ t`Pay` }}
|
||||
</p>
|
||||
</slot>
|
||||
</Button>
|
||||
</div>
|
||||
<Button
|
||||
v-if="isReturnInvoiceEnabledReturn"
|
||||
class="w-full bg-green-500 mt-2 dark:bg-green-700 py-5"
|
||||
:disabled="disablePayButton"
|
||||
@click="emitEvent('toggleModal', 'Payment', true)"
|
||||
>
|
||||
<slot>
|
||||
<p class="uppercase text-lg text-white font-semibold">
|
||||
{{ t`Pay` }}
|
||||
</p>
|
||||
</slot>
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@ -323,6 +362,7 @@ import LoyaltyProgramModal from './LoyaltyProgramModal.vue';
|
||||
import { POSItem, ItemQtyMap } from 'src/components/POS/types';
|
||||
import ItemsGrid from 'src/components/POS/Classic/ItemsGrid.vue';
|
||||
import ItemsTable from 'src/components/POS/Classic/ItemsTable.vue';
|
||||
import ReturnSalesInvoiceModal from './ReturnSalesInvoiceModal.vue';
|
||||
import MultiLabelLink from 'src/components/Controls/MultiLabelLink.vue';
|
||||
import { SalesInvoice } from 'models/baseModels/SalesInvoice/SalesInvoice';
|
||||
import SelectedItemTable from 'src/components/POS/Classic/SelectedItemTable.vue';
|
||||
@ -352,6 +392,7 @@ export default defineComponent({
|
||||
LoyaltyProgramModal,
|
||||
WeightEnabledBarcode,
|
||||
FloatingLabelFloatInput,
|
||||
ReturnSalesInvoiceModal,
|
||||
FloatingLabelCurrencyInput,
|
||||
},
|
||||
props: {
|
||||
@ -368,6 +409,7 @@ export default defineComponent({
|
||||
openSavedInvoiceModal: Boolean,
|
||||
openLoyaltyProgramModal: Boolean,
|
||||
openAppliedCouponsModal: Boolean,
|
||||
openReturnSalesInvoiceModal: Boolean,
|
||||
totalQuantity: {
|
||||
type: Number,
|
||||
default: 0,
|
||||
@ -418,6 +460,7 @@ export default defineComponent({
|
||||
'createTransaction',
|
||||
'setTransferAmount',
|
||||
'selectedInvoiceName',
|
||||
'selectedReturnInvoice',
|
||||
'setTransferClearanceDate',
|
||||
],
|
||||
data() {
|
||||
@ -426,6 +469,10 @@ export default defineComponent({
|
||||
itemSearchTerm: '',
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
isReturnInvoiceEnabledReturn: () =>
|
||||
fyo.singles.AccountingSettings?.enableInvoiceReturns ?? undefined,
|
||||
},
|
||||
methods: {
|
||||
emitEvent(
|
||||
eventName: PosEmits,
|
||||
|
@ -56,6 +56,13 @@
|
||||
"
|
||||
/>
|
||||
|
||||
<ReturnSalesInvoiceModal
|
||||
:open-modal="openReturnSalesInvoiceModal"
|
||||
:modal-status="openReturnSalesInvoiceModal"
|
||||
@selected-return-invoice="(value:any) => emitEvent('selectedReturnInvoice', value)"
|
||||
@toggle-modal="emitEvent('toggleModal', 'ReturnSalesInvoice')"
|
||||
/>
|
||||
|
||||
<AlertModal
|
||||
:open-modal="openAlertModal"
|
||||
@toggle-modal="emitEvent('toggleModal', 'Alert')"
|
||||
@ -185,7 +192,7 @@
|
||||
>
|
||||
<slot>
|
||||
<p class="uppercase text-lg text-white font-semibold">
|
||||
{{ t`held` }}
|
||||
{{ t`Held` }}
|
||||
</p>
|
||||
</slot>
|
||||
</Button>
|
||||
@ -202,8 +209,19 @@
|
||||
</p>
|
||||
</slot>
|
||||
</Button>
|
||||
|
||||
<Button
|
||||
v-if="isReturnInvoiceEnabledReturn"
|
||||
class="mt-2 w-full bg-orange-500 dark:bg-orange-700 py-5"
|
||||
@click="emitEvent('toggleModal', 'ReturnSalesInvoice', true)"
|
||||
>
|
||||
<slot>
|
||||
<p class="uppercase text-lg text-white font-semibold">
|
||||
{{ t`Return` }}
|
||||
</p>
|
||||
</slot>
|
||||
</Button>
|
||||
<Button
|
||||
v-else
|
||||
class="mt-2 w-full bg-green-500 dark:bg-green-700 py-5"
|
||||
:disabled="disablePayButton"
|
||||
@click="emitEvent('toggleModal', 'Payment', true)"
|
||||
@ -216,6 +234,18 @@
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
<Button
|
||||
v-if="isReturnInvoiceEnabledReturn"
|
||||
class="mt-2 w-full bg-green-500 dark:bg-green-700 py-5"
|
||||
:disabled="disablePayButton"
|
||||
@click="emitEvent('toggleModal', 'Payment', true)"
|
||||
>
|
||||
<slot>
|
||||
<p class="uppercase text-lg text-white font-semibold">
|
||||
{{ t`Buy` }}
|
||||
</p>
|
||||
</slot>
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@ -329,6 +359,7 @@ import SavedInvoiceModal from './SavedInvoiceModal.vue';
|
||||
import Barcode from 'src/components/Controls/Barcode.vue';
|
||||
import ClosePOSShiftModal from './ClosePOSShiftModal.vue';
|
||||
import LoyaltyProgramModal from './LoyaltyProgramModal.vue';
|
||||
import ReturnSalesInvoiceModal from './ReturnSalesInvoiceModal.vue';
|
||||
import MultiLabelLink from 'src/components/Controls/MultiLabelLink.vue';
|
||||
import { POSItem, PosEmits, ItemQtyMap } from 'src/components/POS/types';
|
||||
import { SalesInvoice } from 'models/baseModels/SalesInvoice/SalesInvoice';
|
||||
@ -362,6 +393,7 @@ export default defineComponent({
|
||||
ModernPOSItemsTable,
|
||||
WeightEnabledBarcode,
|
||||
FloatingLabelFloatInput,
|
||||
ReturnSalesInvoiceModal,
|
||||
FloatingLabelCurrencyInput,
|
||||
ModernPOSSelectedItemTable,
|
||||
},
|
||||
@ -380,6 +412,7 @@ export default defineComponent({
|
||||
openSavedInvoiceModal: Boolean,
|
||||
openLoyaltyProgramModal: Boolean,
|
||||
openAppliedCouponsModal: Boolean,
|
||||
openReturnSalesInvoiceModal: Boolean,
|
||||
totalQuantity: {
|
||||
type: Number,
|
||||
default: 0,
|
||||
@ -430,6 +463,7 @@ export default defineComponent({
|
||||
'createTransaction',
|
||||
'setTransferAmount',
|
||||
'selectedInvoiceName',
|
||||
'selectedReturnInvoice',
|
||||
'setTransferClearanceDate',
|
||||
],
|
||||
data() {
|
||||
@ -442,6 +476,10 @@ export default defineComponent({
|
||||
itemSearchTerm: '',
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
isReturnInvoiceEnabledReturn: () =>
|
||||
fyo.singles.AccountingSettings?.enableInvoiceReturns ?? undefined,
|
||||
},
|
||||
methods: {
|
||||
emitEvent(
|
||||
eventName: PosEmits,
|
||||
|
@ -32,6 +32,7 @@
|
||||
:open-saved-invoice-modal="openSavedInvoiceModal"
|
||||
:open-loyalty-program-modal="openLoyaltyProgramModal"
|
||||
:open-applied-coupons-modal="openAppliedCouponsModal"
|
||||
:open-return-sales-invoice-modal="openReturnSalesInvoiceModal"
|
||||
@add-item="addItem"
|
||||
@toggle-view="toggleView"
|
||||
@set-sinv-doc="setSinvDoc"
|
||||
@ -49,6 +50,7 @@
|
||||
@save-invoice-action="saveInvoiceAction"
|
||||
@set-transfer-amount="setTransferAmount"
|
||||
@selected-invoice-name="selectedInvoiceName"
|
||||
@selected-return-invoice="selectedReturnInvoice"
|
||||
@set-transfer-clearance-date="setTransferClearanceDate"
|
||||
/>
|
||||
<ModernPOS
|
||||
@ -74,6 +76,7 @@
|
||||
:open-saved-invoice-modal="openSavedInvoiceModal"
|
||||
:open-loyalty-program-modal="openLoyaltyProgramModal"
|
||||
:open-applied-coupons-modal="openAppliedCouponsModal"
|
||||
:open-return-sales-invoice-modal="openReturnSalesInvoiceModal"
|
||||
@add-item="addItem"
|
||||
@toggle-view="toggleView"
|
||||
@set-sinv-doc="setSinvDoc"
|
||||
@ -91,6 +94,7 @@
|
||||
@save-invoice-action="saveInvoiceAction"
|
||||
@set-transfer-amount="setTransferAmount"
|
||||
@selected-invoice-name="selectedInvoiceName"
|
||||
@selected-return-invoice="selectedReturnInvoice"
|
||||
@set-transfer-clearance-date="setTransferClearanceDate"
|
||||
/>
|
||||
</div>
|
||||
@ -188,6 +192,7 @@ export default defineComponent({
|
||||
openSavedInvoiceModal: false,
|
||||
openLoyaltyProgramModal: false,
|
||||
openAppliedCouponsModal: false,
|
||||
openReturnSalesInvoiceModal: false,
|
||||
|
||||
totalQuantity: 0,
|
||||
paidAmount: fyo.pesa(0),
|
||||
@ -396,6 +401,20 @@ export default defineComponent({
|
||||
});
|
||||
}
|
||||
},
|
||||
async selectedReturnInvoice(invoiceName: string) {
|
||||
const salesInvoiceDoc = (await this.fyo.doc.getDoc(
|
||||
ModelNameEnum.SalesInvoice,
|
||||
invoiceName
|
||||
)) as SalesInvoice;
|
||||
|
||||
let returnDoc = (await salesInvoiceDoc.getReturnDoc()) as SalesInvoice;
|
||||
|
||||
if (!returnDoc || !returnDoc.name) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.sinvDoc = returnDoc;
|
||||
},
|
||||
toggleView() {
|
||||
this.tableView = !this.tableView;
|
||||
},
|
||||
@ -481,16 +500,23 @@ export default defineComponent({
|
||||
setTransferRefNo(ref: string) {
|
||||
this.transferRefNo = ref;
|
||||
},
|
||||
validateInvoice() {
|
||||
if (this.sinvDoc.isSubmitted) {
|
||||
throw new ValidationError(
|
||||
t`Cannot add an item to a submitted invoice.`
|
||||
);
|
||||
}
|
||||
|
||||
if (this.sinvDoc.returnAgainst) {
|
||||
throw new ValidationError(
|
||||
t`Unable to add an item to the return invoice.`
|
||||
);
|
||||
}
|
||||
},
|
||||
async addItem(item: POSItem | Item | undefined, quantity?: number) {
|
||||
try {
|
||||
await this.sinvDoc.runFormulas();
|
||||
|
||||
if (this.sinvDoc.isSubmitted) {
|
||||
throw new ValidationError(
|
||||
t`Cannot add an item to a submitted invoice.`
|
||||
);
|
||||
}
|
||||
this.validateInvoice();
|
||||
|
||||
if (!item) {
|
||||
return;
|
||||
@ -626,7 +652,7 @@ export default defineComponent({
|
||||
|
||||
if (paymentMethodDoc?.type !== 'Cash') {
|
||||
await this.paymentDoc.setMultiple({
|
||||
amount: this.paidAmount as Money,
|
||||
amount: this.fyo.pesa(this.paidAmount as unknown as number).abs(),
|
||||
referenceId: this.transferRefNo,
|
||||
clearanceDate: this.transferClearanceDate,
|
||||
});
|
||||
@ -635,7 +661,7 @@ export default defineComponent({
|
||||
if (paymentMethodDoc?.type === 'Cash') {
|
||||
await this.paymentDoc.setMultiple({
|
||||
paymentAccount: this.defaultPOSCashAccount,
|
||||
amount: this.paidAmount as Money,
|
||||
amount: this.fyo.pesa(this.paidAmount as unknown as number).abs(),
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -318,7 +318,8 @@ export default defineComponent({
|
||||
|
||||
if (
|
||||
(this.sinvDoc.grandTotal?.float as number) < 1 &&
|
||||
this.fyo.pesa(this.paidAmount.float).isZero()
|
||||
this.fyo.pesa(this.paidAmount.float).isZero() &&
|
||||
!this.sinvDoc.returnAgainst
|
||||
) {
|
||||
return true;
|
||||
}
|
||||
@ -334,7 +335,8 @@ export default defineComponent({
|
||||
disablePayButton(): boolean {
|
||||
if (
|
||||
(this.sinvDoc.grandTotal?.float as number) < 1 &&
|
||||
this.fyo.pesa(this.paidAmount.float).isZero()
|
||||
this.fyo.pesa(this.paidAmount.float).isZero() &&
|
||||
!this.sinvDoc.returnAgainst
|
||||
) {
|
||||
return true;
|
||||
}
|
||||
@ -345,6 +347,7 @@ export default defineComponent({
|
||||
) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
},
|
||||
},
|
||||
|
179
src/pages/POS/ReturnSalesInvoiceModal.vue
Normal file
179
src/pages/POS/ReturnSalesInvoiceModal.vue
Normal file
@ -0,0 +1,179 @@
|
||||
<template>
|
||||
<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" />
|
||||
|
||||
<Row
|
||||
:ratio="ratio"
|
||||
class="
|
||||
border
|
||||
flex
|
||||
items-center
|
||||
mt-2
|
||||
px-2
|
||||
w-full
|
||||
rounded-t-md
|
||||
text-gray-600
|
||||
dark:border-gray-800 dark:text-gray-400
|
||||
"
|
||||
>
|
||||
<div
|
||||
v-for="df in tableFields"
|
||||
:key="df.fieldname"
|
||||
class="flex items-center px-2 py-2 text-lg"
|
||||
>
|
||||
{{ df.label }}
|
||||
</div>
|
||||
</Row>
|
||||
|
||||
<div
|
||||
class="overflow-y-auto custom-scroll custom-scroll-thumb2"
|
||||
style="height: 65vh; width: 60vh"
|
||||
>
|
||||
<Row
|
||||
v-for="row in returnedInvoices"
|
||||
:key="row.name"
|
||||
:ratio="ratio"
|
||||
:border="true"
|
||||
class="
|
||||
border-b border-l border-r
|
||||
dark:border-gray-800 dark:bg-gray-890
|
||||
flex
|
||||
group
|
||||
h-row-mid
|
||||
hover:bg-gray-25
|
||||
items-center
|
||||
justify-center
|
||||
px-2
|
||||
w-full
|
||||
"
|
||||
@click="returnInvoice(row as SalesInvoice)"
|
||||
>
|
||||
<FormControl
|
||||
v-for="df in tableFields"
|
||||
:key="df.fieldname"
|
||||
size="large"
|
||||
:df="df"
|
||||
:value="row[df.fieldname]"
|
||||
:read-only="true"
|
||||
/>
|
||||
</Row>
|
||||
</div>
|
||||
|
||||
<div class="row-start-6 grid grid-cols-2 gap-4 mt-4">
|
||||
<div class="col-span-2">
|
||||
<Button
|
||||
class="w-full p-5 bg-red-500 dark:bg-red-700"
|
||||
@click="$emit('toggleModal', 'SavedInvoice')"
|
||||
>
|
||||
<slot>
|
||||
<p class="uppercase text-lg text-white font-semibold">
|
||||
{{ t`Cancel` }}
|
||||
</p>
|
||||
</slot>
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
</Modal>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import Button from 'src/components/Button.vue';
|
||||
import Modal from 'src/components/Modal.vue';
|
||||
import Row from 'src/components/Row.vue';
|
||||
import FormControl from 'src/components/Controls/FormControl.vue';
|
||||
import { SalesInvoice } from 'models/baseModels/SalesInvoice/SalesInvoice';
|
||||
import { defineComponent, inject } from 'vue';
|
||||
import { ModelNameEnum } from 'models/types';
|
||||
import { Field } from 'schemas/types';
|
||||
|
||||
export default defineComponent({
|
||||
name: 'ReturnSalesInvoice',
|
||||
components: {
|
||||
Modal,
|
||||
Button,
|
||||
FormControl,
|
||||
Row,
|
||||
},
|
||||
props: {
|
||||
modalStatus: Boolean,
|
||||
},
|
||||
emits: ['toggleModal', 'selectedReturnInvoice'],
|
||||
setup() {
|
||||
return {
|
||||
sinvDoc: inject('sinvDoc') as SalesInvoice,
|
||||
};
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
returnedInvoices: [] as SalesInvoice[],
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
ratio() {
|
||||
return [1, 1, 1, 0.8];
|
||||
},
|
||||
tableFields() {
|
||||
return [
|
||||
{
|
||||
fieldname: 'name',
|
||||
label: 'Name',
|
||||
fieldtype: 'Link',
|
||||
target: 'SalesInvoice',
|
||||
readOnly: true,
|
||||
},
|
||||
{
|
||||
fieldname: 'party',
|
||||
fieldtype: 'Link',
|
||||
label: 'Customer',
|
||||
target: 'Party',
|
||||
placeholder: 'Customer',
|
||||
readOnly: true,
|
||||
},
|
||||
{
|
||||
fieldname: 'date',
|
||||
label: 'Date',
|
||||
fieldtype: 'Date',
|
||||
readOnly: true,
|
||||
},
|
||||
{
|
||||
fieldname: 'grandTotal',
|
||||
label: 'Grand Total',
|
||||
fieldtype: 'Currency',
|
||||
readOnly: true,
|
||||
},
|
||||
] as Field[];
|
||||
},
|
||||
},
|
||||
watch: {
|
||||
async modalStatus(newVal) {
|
||||
if (newVal) {
|
||||
await this.setReturnedInvoices();
|
||||
}
|
||||
},
|
||||
},
|
||||
async mounted() {
|
||||
await this.setReturnedInvoices();
|
||||
},
|
||||
async activated() {
|
||||
await this.setReturnedInvoices();
|
||||
},
|
||||
|
||||
methods: {
|
||||
returnInvoice(row: SalesInvoice) {
|
||||
this.$emit('selectedReturnInvoice', row.name);
|
||||
this.$emit('toggleModal', 'ReturnSalesInvoice');
|
||||
},
|
||||
async setReturnedInvoices() {
|
||||
this.returnedInvoices = (await this.fyo.db.getAll(
|
||||
ModelNameEnum.SalesInvoice,
|
||||
{
|
||||
fields: [],
|
||||
filters: { isPOS: true, submitted: true, returnAgainst: null },
|
||||
}
|
||||
)) as SalesInvoice[];
|
||||
},
|
||||
},
|
||||
});
|
||||
</script>
|
@ -129,7 +129,6 @@ export default defineComponent({
|
||||
savedInvoiceList: true,
|
||||
savedInvoices: [] as SalesInvoice[],
|
||||
submittedInvoices: [] as SalesInvoice[],
|
||||
isModalVisible: false,
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
|
@ -81,15 +81,20 @@ export function validateSinv(sinvDoc: SalesInvoice, itemQtyMap: ItemQtyMap) {
|
||||
return;
|
||||
}
|
||||
|
||||
validateSinvItems(sinvDoc.items as SalesInvoiceItem[], itemQtyMap);
|
||||
validateSinvItems(
|
||||
sinvDoc.items as SalesInvoiceItem[],
|
||||
itemQtyMap,
|
||||
sinvDoc.returnAgainst as string
|
||||
);
|
||||
}
|
||||
|
||||
function validateSinvItems(
|
||||
sinvItems: SalesInvoiceItem[],
|
||||
itemQtyMap: ItemQtyMap
|
||||
itemQtyMap: ItemQtyMap,
|
||||
isReturn?: string
|
||||
) {
|
||||
for (const item of sinvItems) {
|
||||
if (!item.quantity || item.quantity < 1) {
|
||||
if (!item.quantity || (item.quantity < 1 && !isReturn)) {
|
||||
throw new ValidationError(
|
||||
t`Invalid Quantity for Item ${item.item as string}`
|
||||
);
|
||||
|
Loading…
x
Reference in New Issue
Block a user