fix: filter returned invoices

This commit is contained in:
AbleKSaju
2025-06-17 15:09:01 +05:30
parent 593b1112c7
commit 5fcc5eb267
10 changed files with 67 additions and 40 deletions
@@ -26,6 +26,7 @@ export class AccountingSettings extends Doc {
enableERPNextSync?: boolean;
enablePointOfSaleWithOutInventory?: boolean;
enablePartialPayment?: boolean;
enableitemGroup?: boolean;
static filters: FiltersMap = {
writeOffAccount: () => ({
+16 -2
View File
@@ -339,6 +339,10 @@ export abstract class Invoice extends Transactional {
for (const details of (tax.details ?? []) as TaxDetail[]) {
let amount = item.amount!;
if (this.isReturn && amount.isPositive()) {
amount = amount.neg();
}
if (!this.discountAfterTax) {
let itemDiscountAmount = this.getDiscountAmount(item);
@@ -895,11 +899,21 @@ export abstract class Invoice extends Transactional {
this.returnAgainst
)) as Invoice;
if (sinvreturnedDoc.outstandingAmount?.isZero()) {
return this.grandTotal;
return this.grandTotal?.abs();
} else {
return this.grandTotal
const totalPaid = this.grandTotal
?.abs()
.sub(sinvreturnedDoc.outstandingAmount as Money);
if (!sinvreturnedDoc.isReturn) {
return totalPaid?.abs();
}
if (!this.grandTotal?.isNegative()) {
this.grandTotal = this.grandTotal?.neg();
}
return this.grandTotal?.add(totalPaid as Money).abs();
}
}
+12 -16
View File
@@ -459,6 +459,16 @@ export class Payment extends Transactional {
row.referenceName
);
const previousOutstandingAmount = referenceDoc.outstandingAmount as Money;
const outstandingAmount = previousOutstandingAmount.sub(row.amount!);
await referenceDoc.setAndSync({ outstandingAmount });
}
}
async beforeSync(): Promise<void> {
await super.beforeSync();
for (const row of this.for ?? []) {
if (!this.fyo.singles.AccountingSettings?.enablePartialPayment) {
const amount = !(this.amountPaid as Money).isZero()
? (this.amountPaid as Money)
@@ -466,7 +476,7 @@ export class Payment extends Transactional {
const initialAmount = this.initialAmount as Money;
if (amount.lt(initialAmount) && !amount.eq(initialAmount)) {
if (this.writeoff?.isZero()) {
row.amount = this.initialAmount;
this.amount = this.initialAmount;
row.amountPaid = this.fyo.pesa(0);
throw new ValidationError(
this.fyo.t`Enable Partial payment to pay partial amount`
@@ -474,10 +484,6 @@ export class Payment extends Transactional {
}
}
}
const previousOutstandingAmount = referenceDoc.outstandingAmount as Money;
const outstandingAmount = previousOutstandingAmount.sub(row.amount!);
await referenceDoc.setAndSync({ outstandingAmount });
}
}
@@ -648,23 +654,13 @@ export class Payment extends Transactional {
}
const reference = this?.for?.[0];
if (!reference) {
return null;
}
const refDoc = (await reference.loadAndGetLink(
const refDoc = (await reference?.loadAndGetLink(
'referenceName'
)) as Invoice | null;
const partyDoc = (await this.loadAndGetLink('party')) as Party;
const outstanding = partyDoc.outstandingAmount as Money;
if (outstanding.isNegative()) {
if (this.referenceType === ModelNameEnum.PurchaseInvoice) {
return 'Pay';
}
return 'Receive';
}
if (partyDoc.role === 'Supplier') {
if (refDoc?.isReturn) {
return 'Receive';
+1 -1
View File
@@ -180,7 +180,7 @@ test('create SINV return for balance qty', async (t) => {
t.equals(
returnDoc.outstandingAmount?.float,
-itemData.rate,
itemData.rate,
'return doc outstanding amount matches'
);
});
@@ -57,13 +57,6 @@
"fieldtype": "Check",
"section": "Features"
},
{
"fieldname": "enableStockReturns",
"label": "Enable Stock Returns",
"fieldtype": "Check",
"default": false,
"section": "Features"
},
{
"fieldname": "enablePointOfSale",
"label": "Enable Point of Sale",
+1
View File
@@ -105,6 +105,7 @@
/>
<Link
v-if="fyo.singles.AccountingSettings?.enableitemGroup"
:df="{
label: t`Filter by Group`,
fieldtype: 'Link',
+5 -5
View File
@@ -466,7 +466,7 @@ export default defineComponent({
await this.setItems();
},
async setItems() {
const filters: Record<string, boolean> = {};
const filters: Record<string, boolean | string> = {};
const itemVisibility = this.fyo.singles.POSSettings?.itemVisibility;
const hideUnavailable =
this.fyo.singles.POSSettings?.hideUnavailableItems;
@@ -477,13 +477,13 @@ export default defineComponent({
filters.trackItem = false;
}
const itemGroupfilter = this.selectedItemGroup
? { itemGroup: this.selectedItemGroup }
: undefined;
if (this.selectedItemGroup) {
filters.itemGroup = this.selectedItemGroup;
}
const items = (await fyo.db.getAll(ModelNameEnum.Item, {
fields: [],
filters: itemGroupfilter,
filters: filters,
})) as Item[];
this.items = [] as POSItem[];
+6
View File
@@ -31,6 +31,7 @@
:show-label="true"
:border="true"
:required="!transferAmount.isZero()"
:read-only="false"
:value="transferRefNo"
@change="(value:string) => $emit('setTransferRefNo', value)"
/>
@@ -41,6 +42,7 @@
:show-label="true"
:border="true"
:required="!transferAmount.isZero()"
:read-only="false"
:value="transferClearanceDate"
@change="(value:Date) => $emit('setTransferClearanceDate', value)"
/>
@@ -306,6 +308,10 @@ export default defineComponent({
return true;
},
showPaidChange(): boolean {
if (this.sinvDoc.isReturn) {
return false;
}
if (
this.fyo.pesa(this.paidAmount.float).eq(fyo.pesa(0)) &&
this.transferAmount.eq(fyo.pesa(0))
+23 -5
View File
@@ -108,6 +108,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: 'ReturnSalesInvoice',
@@ -169,7 +170,7 @@ export default defineComponent({
},
filteredInvoices() {
return this.returnedInvoices.filter((invoice) =>
invoice.name
(invoice.name as string)
.toLowerCase()
.includes(this.invoiceSearchTerm.toLowerCase())
);
@@ -210,11 +211,28 @@ export default defineComponent({
});
const returnedInvoiceNames = allInvoices
.filter((inv) => inv.returnAgainst)
.map((inv) => inv.returnAgainst);
.filter((inv) => {
if (inv.isReturned) {
return false;
}
this.returnedInvoices = allInvoices.filter(
(inv) => !inv.returnAgainst && !returnedInvoiceNames.includes(inv.name)
if (inv.isReturned && !(inv.outstandingAmount as Money).isZero()) {
return true;
}
if (!inv.isReturned && !inv.returnAgainst) {
return true;
}
if (!inv.isReturned && !(inv.outstandingAmount as Money).isZero()) {
return true;
}
return false;
})
.map((inv) => inv.name);
this.returnedInvoices = allInvoices.filter((inv) =>
returnedInvoiceNames.includes(inv.name)
) as SalesInvoice[];
},
},
+2 -4
View File
@@ -186,7 +186,7 @@ export async function syncDocumentsFromERPNext(fyo: Fyo) {
}
}
} catch (error) {
return await fyo.doc
await fyo.doc
.getNewDoc(ErrorLogEnum.IntegrationErrorLog, {
error: error as string,
data: JSON.stringify({ instance: deviceID, records: docsToSync }),
@@ -220,9 +220,7 @@ export async function syncDocumentsFromERPNext(fyo: Fyo) {
(doc.erpnextDocName as string) || (doc.name as string),
newDoc.name as string
);
} catch (error) {
return error;
}
} catch (error) {}
}
}