mirror of
https://github.com/frappe/books.git
synced 2025-01-10 18:24:40 +00:00
Merge pull request #652 from frappe/auto-stock-transfer
feat: auto stock transfer
This commit is contained in:
commit
25b230b9a2
@ -1,10 +1,14 @@
|
|||||||
import { Fyo } from 'fyo';
|
import { Fyo } from 'fyo';
|
||||||
import { DocValue, DocValueMap } from 'fyo/core/types';
|
import { DocValue, DocValueMap } from 'fyo/core/types';
|
||||||
import SystemSettings from 'fyo/models/SystemSettings';
|
import type SystemSettings from 'fyo/models/SystemSettings';
|
||||||
import { FieldType, Schema, SelectOption } from 'schemas/types';
|
import { FieldType, Schema, SelectOption } from 'schemas/types';
|
||||||
import { QueryFilter } from 'utils/db/types';
|
import { QueryFilter } from 'utils/db/types';
|
||||||
import { RouteLocationRaw, Router } from 'vue-router';
|
import { RouteLocationRaw, Router } from 'vue-router';
|
||||||
import { Doc } from './doc';
|
import { Doc } from './doc';
|
||||||
|
import type { AccountingSettings } from 'models/baseModels/AccountingSettings/AccountingSettings';
|
||||||
|
import type { Defaults } from 'models/baseModels/Defaults/Defaults';
|
||||||
|
import type { PrintSettings } from 'models/baseModels/PrintSettings/PrintSettings';
|
||||||
|
import type { InventorySettings } from 'models/inventory/InventorySettings';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The functions below are used for dynamic evaluation
|
* The functions below are used for dynamic evaluation
|
||||||
@ -47,6 +51,10 @@ export type DocMap = Record<string, Doc | undefined>;
|
|||||||
|
|
||||||
export interface SinglesMap {
|
export interface SinglesMap {
|
||||||
SystemSettings?: SystemSettings;
|
SystemSettings?: SystemSettings;
|
||||||
|
AccountingSettings?: AccountingSettings;
|
||||||
|
InventorySettings?: InventorySettings;
|
||||||
|
PrintSettings?: PrintSettings;
|
||||||
|
Defaults?: Defaults;
|
||||||
[key: string]: Doc | undefined;
|
[key: string]: Doc | undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -7,6 +7,10 @@ export class Defaults extends Doc {
|
|||||||
salesPaymentAccount?: string;
|
salesPaymentAccount?: string;
|
||||||
purchasePaymentAccount?: string;
|
purchasePaymentAccount?: string;
|
||||||
|
|
||||||
|
// Auto Stock Transfer
|
||||||
|
shipmentLocation?: string;
|
||||||
|
purchaseReceiptLocation?: string;
|
||||||
|
|
||||||
// Number Series
|
// Number Series
|
||||||
salesInvoiceNumberSeries?: string;
|
salesInvoiceNumberSeries?: string;
|
||||||
purchaseInvoiceNumberSeries?: string;
|
purchaseInvoiceNumberSeries?: string;
|
||||||
|
@ -50,6 +50,7 @@ export abstract class Invoice extends Transactional {
|
|||||||
submitted?: boolean;
|
submitted?: boolean;
|
||||||
cancelled?: boolean;
|
cancelled?: boolean;
|
||||||
makeAutoPayment?: boolean;
|
makeAutoPayment?: boolean;
|
||||||
|
makeAutoStockTransfer?: boolean;
|
||||||
|
|
||||||
get isSales() {
|
get isSales() {
|
||||||
return this.schemaName === 'SalesInvoice';
|
return this.schemaName === 'SalesInvoice';
|
||||||
@ -105,6 +106,18 @@ export abstract class Invoice extends Transactional {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
get autoStockTransferLocation(): string | null {
|
||||||
|
const fieldname = this.isSales
|
||||||
|
? 'shipmentLocation'
|
||||||
|
: 'purchaseReceiptLocation';
|
||||||
|
const value = this.fyo.singles.Defaults?.[fieldname];
|
||||||
|
if (typeof value === 'string' && value.length) {
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
constructor(schema: Schema, data: DocValueMap, fyo: Fyo) {
|
constructor(schema: Schema, data: DocValueMap, fyo: Fyo) {
|
||||||
super(schema, data, fyo);
|
super(schema, data, fyo);
|
||||||
this._setGetCurrencies();
|
this._setGetCurrencies();
|
||||||
@ -139,6 +152,13 @@ export abstract class Invoice extends Transactional {
|
|||||||
await payment?.submit();
|
await payment?.submit();
|
||||||
await this.load();
|
await this.load();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (this.makeAutoStockTransfer && this.autoStockTransferLocation) {
|
||||||
|
const stockTransfer = await this.getStockTransfer(true);
|
||||||
|
await stockTransfer?.sync();
|
||||||
|
await stockTransfer?.submit();
|
||||||
|
await this.load();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async afterCancel() {
|
async afterCancel() {
|
||||||
@ -418,6 +438,12 @@ export abstract class Invoice extends Transactional {
|
|||||||
formula: () => !!this.autoPaymentAccount,
|
formula: () => !!this.autoPaymentAccount,
|
||||||
dependsOn: [],
|
dependsOn: [],
|
||||||
},
|
},
|
||||||
|
makeAutoStockTransfer: {
|
||||||
|
formula: () =>
|
||||||
|
!!this.fyo.singles.AccountingSettings?.enableInventory &&
|
||||||
|
!!this.autoStockTransferLocation,
|
||||||
|
dependsOn: [],
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
getStockTransferred() {
|
getStockTransferred() {
|
||||||
@ -458,11 +484,18 @@ export abstract class Invoice extends Transactional {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!this.autoPaymentAccount) {
|
return !this.autoPaymentAccount;
|
||||||
|
},
|
||||||
|
makeAutoStockTransfer: () => {
|
||||||
|
if (this.submitted) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
if (!this.fyo.singles.AccountingSettings?.enableInventory) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return !this.autoStockTransferLocation;
|
||||||
},
|
},
|
||||||
setDiscountAmount: () => true || !this.enableDiscounting,
|
setDiscountAmount: () => true || !this.enableDiscounting,
|
||||||
discountAmount: () =>
|
discountAmount: () =>
|
||||||
@ -486,6 +519,10 @@ export abstract class Invoice extends Transactional {
|
|||||||
static defaults: DefaultMap = {
|
static defaults: DefaultMap = {
|
||||||
makeAutoPayment: (doc) =>
|
makeAutoPayment: (doc) =>
|
||||||
doc instanceof Invoice && !!doc.autoPaymentAccount,
|
doc instanceof Invoice && !!doc.autoPaymentAccount,
|
||||||
|
makeAutoStockTransfer: (doc) =>
|
||||||
|
!!doc.fyo.singles.AccountingSettings?.enableInventory &&
|
||||||
|
doc instanceof Invoice &&
|
||||||
|
!!doc.autoStockTransferLocation,
|
||||||
numberSeries: (doc) => getNumberSeries(doc.schemaName, doc.fyo),
|
numberSeries: (doc) => getNumberSeries(doc.schemaName, doc.fyo),
|
||||||
terms: (doc) => {
|
terms: (doc) => {
|
||||||
const defaults = doc.fyo.singles.Defaults as Defaults | undefined;
|
const defaults = doc.fyo.singles.Defaults as Defaults | undefined;
|
||||||
@ -574,7 +611,9 @@ export abstract class Invoice extends Transactional {
|
|||||||
return this.fyo.doc.getNewDoc(ModelNameEnum.Payment, data) as Payment;
|
return this.fyo.doc.getNewDoc(ModelNameEnum.Payment, data) as Payment;
|
||||||
}
|
}
|
||||||
|
|
||||||
async getStockTransfer(): Promise<StockTransfer | null> {
|
async getStockTransfer(
|
||||||
|
isAuto: boolean = false
|
||||||
|
): Promise<StockTransfer | null> {
|
||||||
if (!this.isSubmitted) {
|
if (!this.isSubmitted) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
@ -604,9 +643,14 @@ export abstract class Invoice extends Transactional {
|
|||||||
backReference: this.name,
|
backReference: this.name,
|
||||||
};
|
};
|
||||||
|
|
||||||
const location =
|
let location = this.autoStockTransferLocation;
|
||||||
(this.fyo.singles.InventorySettings as InventorySettings)
|
if (!location) {
|
||||||
.defaultLocation ?? null;
|
location = this.fyo.singles.InventorySettings?.defaultLocation ?? null;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isAuto && !location) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
const transfer = this.fyo.doc.getNewDoc(schemaName, data) as StockTransfer;
|
const transfer = this.fyo.doc.getNewDoc(schemaName, data) as StockTransfer;
|
||||||
for (const row of this.items ?? []) {
|
for (const row of this.items ?? []) {
|
||||||
@ -615,6 +659,10 @@ export abstract class Invoice extends Transactional {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const itemDoc = (await row.loadAndGetLink('item')) as Item;
|
const itemDoc = (await row.loadAndGetLink('item')) as Item;
|
||||||
|
if (isAuto && (itemDoc.hasBatch || itemDoc.hasSerialNumber)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
const item = row.item;
|
const item = row.item;
|
||||||
const quantity = row.stockNotTransferred;
|
const quantity = row.stockNotTransferred;
|
||||||
const trackItem = itemDoc.trackItem;
|
const trackItem = itemDoc.trackItem;
|
||||||
@ -631,6 +679,21 @@ export abstract class Invoice extends Transactional {
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (isAuto) {
|
||||||
|
const stock =
|
||||||
|
(await this.fyo.db.getStockQuantity(
|
||||||
|
item,
|
||||||
|
location!,
|
||||||
|
undefined,
|
||||||
|
data.date
|
||||||
|
)) ?? 0;
|
||||||
|
console.log(quantity, stock);
|
||||||
|
|
||||||
|
if (stock < quantity) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
await transfer.append('items', {
|
await transfer.append('items', {
|
||||||
item,
|
item,
|
||||||
quantity,
|
quantity,
|
||||||
|
@ -20,6 +20,22 @@
|
|||||||
"create": true,
|
"create": true,
|
||||||
"section": "Auto Payments"
|
"section": "Auto Payments"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"fieldname": "shipmentLocation",
|
||||||
|
"label": "Shipment Location",
|
||||||
|
"fieldtype": "Link",
|
||||||
|
"target": "Location",
|
||||||
|
"create": true,
|
||||||
|
"section": "Auto Stock Transfer"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fieldname": "purchaseReceiptLocation",
|
||||||
|
"label": "Purchase Receipt Location",
|
||||||
|
"fieldtype": "Link",
|
||||||
|
"target": "Location",
|
||||||
|
"create": true,
|
||||||
|
"section": "Auto Stock Transfer"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"fieldname": "salesInvoiceNumberSeries",
|
"fieldname": "salesInvoiceNumberSeries",
|
||||||
"label": "Sales Invoice Number Series",
|
"label": "Sales Invoice Number Series",
|
||||||
|
@ -147,6 +147,11 @@
|
|||||||
"readOnly": false,
|
"readOnly": false,
|
||||||
"tab": "Settings"
|
"tab": "Settings"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"abstract": true,
|
||||||
|
"fieldname": "makeAutoStockTransfer",
|
||||||
|
"tab": "Settings"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"fieldname": "outstandingAmount",
|
"fieldname": "outstandingAmount",
|
||||||
"label": "Outstanding Amount",
|
"label": "Outstanding Amount",
|
||||||
|
@ -22,6 +22,14 @@
|
|||||||
"target": "PurchaseReceipt",
|
"target": "PurchaseReceipt",
|
||||||
"section": "References"
|
"section": "References"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"fieldname": "makeAutoStockTransfer",
|
||||||
|
"label": "Make Purchase Receipt On Submit",
|
||||||
|
"fieldtype": "Check",
|
||||||
|
"default": false,
|
||||||
|
"readOnly": false,
|
||||||
|
"tab": "Settings"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"fieldname": "items",
|
"fieldname": "items",
|
||||||
"label": "Items",
|
"label": "Items",
|
||||||
|
@ -22,6 +22,14 @@
|
|||||||
"target": "Shipment",
|
"target": "Shipment",
|
||||||
"section": "References"
|
"section": "References"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"fieldname": "makeAutoStockTransfer",
|
||||||
|
"label": "Make Shipment On Submit",
|
||||||
|
"fieldtype": "Check",
|
||||||
|
"default": false,
|
||||||
|
"readOnly": false,
|
||||||
|
"tab": "Settings"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"fieldname": "items",
|
"fieldname": "items",
|
||||||
"label": "Items",
|
"label": "Items",
|
||||||
|
Loading…
Reference in New Issue
Block a user