diff --git a/fyo/model/doc.ts b/fyo/model/doc.ts
index 14965ceb..50f7bb7b 100644
--- a/fyo/model/doc.ts
+++ b/fyo/model/doc.ts
@@ -920,6 +920,35 @@ export class Doc extends Observable {
return this;
}
+ async _hasERPSyncableItems(): Promise {
+ const isSalesInvoice = this.schemaName === ModelNameEnum.SalesInvoice;
+ if (!isSalesInvoice) {
+ return true;
+ }
+
+ const items = (this.get('items') as Doc[]) ?? [];
+
+ for (const item of items) {
+ const itemName = item.get('item') as string;
+ if (!itemName) {
+ continue;
+ }
+
+ try {
+ const itemDoc = await this.fyo.doc.getDoc('Item', itemName);
+ const isInventoryItem = !!itemDoc.get('trackItem');
+ const isFromERP = !!itemDoc.get('datafromErp');
+
+ if (!isInventoryItem && isFromERP) {
+ return true;
+ }
+ } catch (err) {
+ continue;
+ }
+ }
+
+ return false;
+ }
async sync(): Promise {
this._syncing = true;
@@ -936,10 +965,12 @@ export class Doc extends Observable {
if (this._addDocToSyncQueue && !!this.shouldDocSyncToERPNext) {
const isSalesInvoice = this.schemaName === ModelNameEnum.SalesInvoice;
+ const hasERPSyncableItems = await this._hasERPSyncableItems();
if (
- !(isSalesInvoice && this.isSyncedWithErp) ||
- (isSalesInvoice && !!this.isReturn)
+ hasERPSyncableItems &&
+ (!(isSalesInvoice && this.isSyncedWithErp) ||
+ (isSalesInvoice && !!this.isReturn))
) {
if (isSalesInvoice && !this.isReturn) {
await this.setAndSync('isSyncedWithErp', true);
diff --git a/models/baseModels/ERPNextSyncSettings/ERPNextSyncSettings.ts b/models/baseModels/ERPNextSyncSettings/ERPNextSyncSettings.ts
index b163e153..ee17eebc 100644
--- a/models/baseModels/ERPNextSyncSettings/ERPNextSyncSettings.ts
+++ b/models/baseModels/ERPNextSyncSettings/ERPNextSyncSettings.ts
@@ -40,6 +40,9 @@ export class ERPNextSyncSettings extends Doc {
batchSyncType: () => {
return !this.fyo.singles.InventorySettings?.enableBatches;
},
+ // syncDataFromServer: () => {
+ // return !this.deviceID;
+ // },
};
async change(ch: ChangeArg) {
diff --git a/models/baseModels/InvoiceItem/InvoiceItem.ts b/models/baseModels/InvoiceItem/InvoiceItem.ts
index 590702d2..14ed7ef0 100644
--- a/models/baseModels/InvoiceItem/InvoiceItem.ts
+++ b/models/baseModels/InvoiceItem/InvoiceItem.ts
@@ -19,8 +19,13 @@ import { Item } from '../Item/Item';
import { StockTransfer } from 'models/inventory/StockTransfer';
import { isPesa } from 'fyo/utils';
import { PricingRule } from '../PricingRule/PricingRule';
-import { getItemRateFromPriceList, getPricingRule } from 'models/helpers';
+import {
+ getItemRateFromPriceList,
+ getPricingRule,
+ getItemVisibility,
+} from 'models/helpers';
import { SalesInvoice } from '../SalesInvoice/SalesInvoice';
+import { QueryFilter } from 'utils/db/types';
export abstract class InvoiceItem extends Doc {
item?: string;
@@ -646,13 +651,28 @@ export abstract class InvoiceItem extends Doc {
};
static filters: FiltersMap = {
- item: (doc: Doc) => {
+ item: async (doc: Doc): Promise => {
let itemNotFor = 'Sales';
if (doc.isSales) {
itemNotFor = 'Purchases';
}
- return { for: ['not in', [itemNotFor]] };
+ const filters: QueryFilter = {
+ for: ['not in', [itemNotFor]],
+ };
+
+ const enableERPNextSync =
+ doc.fyo.singles.AccountingSettings?.enableERPNextSync;
+
+ if (enableERPNextSync) {
+ const itemVisibility = await getItemVisibility(doc.fyo);
+
+ if (itemVisibility === 'ERP Sync Items') {
+ filters.datafromErp = true;
+ }
+ }
+
+ return filters;
},
batch: async (doc: Doc) => {
const batches = await doc.fyo.db.getAll(ModelNameEnum.Batch, {
diff --git a/models/baseModels/Item/Item.ts b/models/baseModels/Item/Item.ts
index 9971a1ba..5f349386 100644
--- a/models/baseModels/Item/Item.ts
+++ b/models/baseModels/Item/Item.ts
@@ -30,6 +30,7 @@ export class Item extends Doc {
hsnCode?: number;
hasSerialNumber?: boolean;
serialNumberSeries?: string;
+ datafromErp?: boolean;
uomConversions: UOMConversionItem[] = [];
formulas: FormulaMap = {
@@ -237,5 +238,6 @@ export class Item extends Doc {
trackItem: () => this.inserted,
hasBatch: () => this.inserted,
hasSerialNumber: () => this.inserted,
+ datafromErp: () => true,
};
}
diff --git a/models/helpers.ts b/models/helpers.ts
index 07e13435..37e8744c 100644
--- a/models/helpers.ts
+++ b/models/helpers.ts
@@ -116,6 +116,12 @@ export async function getItemQtyMap(doc: SalesInvoice): Promise {
export async function getItemVisibility(fyo: Fyo): Promise {
const posProfileName = fyo.singles.POSSettings?.posProfile as string;
+ const enableERPNextSync = fyo.singles.AccountingSettings?.enableERPNextSync;
+
+ if (enableERPNextSync) {
+ // When ERP sync is enabled, use itemVisibilityERP from POSSettings
+ return fyo.singles.POSSettings?.itemVisibilityERP as ItemVisibility;
+ }
if (posProfileName) {
const posProfile = await fyo.doc.getDoc(
diff --git a/models/inventory/Point of Sale/POSSettings.ts b/models/inventory/Point of Sale/POSSettings.ts
index 5fbcc9e6..2a70b60a 100644
--- a/models/inventory/Point of Sale/POSSettings.ts
+++ b/models/inventory/Point of Sale/POSSettings.ts
@@ -16,6 +16,7 @@ export class POSSettings extends Doc {
itemWeightDigits?: number;
defaultAccount?: string;
itemVisibility?: string;
+ itemVisibilityERP?: 'ERP Sync Items';
posUI?: 'Classic' | 'Modern';
canChangeRate?: boolean;
canEditDiscount?: boolean;
@@ -46,6 +47,8 @@ export class POSSettings extends Doc {
!this.fyo.singles.InventorySettings?.enableBarcodes ||
!this.weightEnabledBarcode,
itemVisibility: () =>
- !this.fyo.singles.AccountingSettings?.enablePointOfSaleWithOutInventory,
+ !!this.fyo.singles.AccountingSettings?.enableERPNextSync,
+ itemVisibilityERP: () =>
+ !this.fyo.singles.AccountingSettings?.enableERPNextSync,
};
}
diff --git a/schemas/app/Item.json b/schemas/app/Item.json
index 02a483fa..d97b7677 100644
--- a/schemas/app/Item.json
+++ b/schemas/app/Item.json
@@ -172,6 +172,13 @@
"fieldtype": "Table",
"target": "UOMConversionItem",
"section": "Inventory"
+ },
+ {
+ "fieldname": "datafromErp",
+ "fieldtype": "Check",
+ "hidden": false,
+ "default": false,
+ "section": "Default"
}
],
"quickEditFields": [
diff --git a/schemas/app/inventory/Point of Sale/POSSettings.json b/schemas/app/inventory/Point of Sale/POSSettings.json
index 0d2887bb..657a28eb 100644
--- a/schemas/app/inventory/Point of Sale/POSSettings.json
+++ b/schemas/app/inventory/Point of Sale/POSSettings.json
@@ -121,6 +121,28 @@
"required": true,
"section": "Default"
},
+ {
+ "fieldname": "itemVisibilityERP",
+ "label": "Item Visibility",
+ "fieldtype": "Select",
+ "options": [
+ {
+ "value": "ERP Sync Items",
+ "label": "ERP Sync Items"
+ },
+ {
+ "value": "Inventory Items",
+ "label": "Inventory Items"
+ },
+ {
+ "value": "Non-Inventory Items",
+ "label": "Non-Inventory Items"
+ }
+ ],
+ "default": "ERP Sync Items",
+ "required": true,
+ "section": "Default"
+ },
{
"fieldname": "canChangeRate",
"label": "Can Change Rate",
diff --git a/src/components/POS/Classic/ItemsGrid.vue b/src/components/POS/Classic/ItemsGrid.vue
index 08c289a2..0081f134 100644
--- a/src/components/POS/Classic/ItemsGrid.vue
+++ b/src/components/POS/Classic/ItemsGrid.vue
@@ -63,6 +63,7 @@