mirror of
https://github.com/frappe/books.git
synced 2024-11-09 23:30:56 +00:00
fix: remove valuation selection
- book COGS according to FIFO valuation on Shipment
This commit is contained in:
parent
18be2b5106
commit
034d612d29
@ -1,12 +1,10 @@
|
|||||||
import { Doc } from 'fyo/model/doc';
|
import { Doc } from 'fyo/model/doc';
|
||||||
import { FiltersMap, ReadOnlyMap } from 'fyo/model/types';
|
import { FiltersMap, ReadOnlyMap } from 'fyo/model/types';
|
||||||
import { AccountTypeEnum } from 'models/baseModels/Account/types';
|
import { AccountTypeEnum } from 'models/baseModels/Account/types';
|
||||||
import { ValuationMethod } from './types';
|
|
||||||
|
|
||||||
export class InventorySettings extends Doc {
|
export class InventorySettings extends Doc {
|
||||||
defaultLocation?: string;
|
defaultLocation?: string;
|
||||||
stockInHand?: string;
|
stockInHand?: string;
|
||||||
valuationMethod?: ValuationMethod;
|
|
||||||
stockReceivedButNotBilled?: string;
|
stockReceivedButNotBilled?: string;
|
||||||
costOfGoodsSold?: string;
|
costOfGoodsSold?: string;
|
||||||
enableBarcodes?: boolean;
|
enableBarcodes?: boolean;
|
||||||
|
@ -27,6 +27,7 @@ import {
|
|||||||
validateSerialNumber,
|
validateSerialNumber,
|
||||||
} from './helpers';
|
} from './helpers';
|
||||||
import { ReturnDocItem } from './types';
|
import { ReturnDocItem } from './types';
|
||||||
|
import { getShipmentCOGSAmountFromSLEs } from 'reports/inventory/helpers';
|
||||||
|
|
||||||
export abstract class StockTransfer extends Transfer {
|
export abstract class StockTransfer extends Transfer {
|
||||||
name?: string;
|
name?: string;
|
||||||
@ -128,7 +129,7 @@ export abstract class StockTransfer extends Transfer {
|
|||||||
'stockInHand'
|
'stockInHand'
|
||||||
)) as string;
|
)) as string;
|
||||||
|
|
||||||
const amount = this.grandTotal ?? this.fyo.pesa(0);
|
const amount = await this.getPostingAmount();
|
||||||
const posting = new LedgerPosting(this, this.fyo);
|
const posting = new LedgerPosting(this, this.fyo);
|
||||||
|
|
||||||
if (this.isSales) {
|
if (this.isSales) {
|
||||||
@ -163,6 +164,14 @@ export abstract class StockTransfer extends Transfer {
|
|||||||
return posting;
|
return posting;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async getPostingAmount(): Promise<Money> {
|
||||||
|
if (!this.isSales) {
|
||||||
|
return this.grandTotal ?? this.fyo.pesa(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
return await getShipmentCOGSAmountFromSLEs(this);
|
||||||
|
}
|
||||||
|
|
||||||
async validateAccounts() {
|
async validateAccounts() {
|
||||||
const settings: string[] = ['stockInHand'];
|
const settings: string[] = ['stockInHand'];
|
||||||
if (this.isSales) {
|
if (this.isSales) {
|
||||||
|
@ -90,9 +90,7 @@ export class StockLedger extends Report {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async _setRawData() {
|
async _setRawData() {
|
||||||
const valuationMethod =
|
const valuationMethod = ValuationMethod.FIFO;
|
||||||
this.fyo.singles.InventorySettings?.valuationMethod ??
|
|
||||||
ValuationMethod.FIFO;
|
|
||||||
|
|
||||||
const rawSLEs = await getRawStockLedgerEntries(this.fyo);
|
const rawSLEs = await getRawStockLedgerEntries(this.fyo);
|
||||||
this._rawData = getStockLedgerEntries(rawSLEs, valuationMethod);
|
this._rawData = getStockLedgerEntries(rawSLEs, valuationMethod);
|
||||||
|
@ -3,17 +3,22 @@ import { StockQueue } from 'models/inventory/stockQueue';
|
|||||||
import { ValuationMethod } from 'models/inventory/types';
|
import { ValuationMethod } from 'models/inventory/types';
|
||||||
import { ModelNameEnum } from 'models/types';
|
import { ModelNameEnum } from 'models/types';
|
||||||
import { safeParseFloat, safeParseInt } from 'utils/index';
|
import { safeParseFloat, safeParseInt } from 'utils/index';
|
||||||
import {
|
import type {
|
||||||
ComputedStockLedgerEntry,
|
ComputedStockLedgerEntry,
|
||||||
RawStockLedgerEntry,
|
RawStockLedgerEntry,
|
||||||
StockBalanceEntry,
|
StockBalanceEntry,
|
||||||
} from './types';
|
} from './types';
|
||||||
|
import type { QueryFilter } from 'utils/db/types';
|
||||||
|
import type { StockTransfer } from 'models/inventory/StockTransfer';
|
||||||
|
|
||||||
type Item = string;
|
type Item = string;
|
||||||
type Location = string;
|
type Location = string;
|
||||||
type Batch = string;
|
type Batch = string;
|
||||||
|
|
||||||
export async function getRawStockLedgerEntries(fyo: Fyo) {
|
export async function getRawStockLedgerEntries(
|
||||||
|
fyo: Fyo,
|
||||||
|
filters: QueryFilter = {}
|
||||||
|
) {
|
||||||
const fieldnames = [
|
const fieldnames = [
|
||||||
'name',
|
'name',
|
||||||
'date',
|
'date',
|
||||||
@ -29,11 +34,73 @@ export async function getRawStockLedgerEntries(fyo: Fyo) {
|
|||||||
|
|
||||||
return (await fyo.db.getAllRaw(ModelNameEnum.StockLedgerEntry, {
|
return (await fyo.db.getAllRaw(ModelNameEnum.StockLedgerEntry, {
|
||||||
fields: fieldnames,
|
fields: fieldnames,
|
||||||
|
filters,
|
||||||
orderBy: ['date', 'created', 'name'],
|
orderBy: ['date', 'created', 'name'],
|
||||||
order: 'asc',
|
order: 'asc',
|
||||||
})) as RawStockLedgerEntry[];
|
})) as RawStockLedgerEntry[];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export async function getShipmentCOGSAmountFromSLEs(
|
||||||
|
stockTransfer: StockTransfer
|
||||||
|
) {
|
||||||
|
const fyo = stockTransfer.fyo;
|
||||||
|
const date = stockTransfer.date ?? new Date();
|
||||||
|
const items = (stockTransfer.items ?? []).filter((i) => i.item);
|
||||||
|
const itemNames = Array.from(new Set(items.map((i) => i.item))) as string[];
|
||||||
|
|
||||||
|
type Item = string;
|
||||||
|
type Batch = string;
|
||||||
|
type Location = string;
|
||||||
|
type Queues = Record<Item, Record<Location, Record<Batch, StockQueue>>>;
|
||||||
|
|
||||||
|
const rawSles = await getRawStockLedgerEntries(fyo, {
|
||||||
|
item: ['in', itemNames],
|
||||||
|
date: ['<=', date.toISOString()],
|
||||||
|
});
|
||||||
|
|
||||||
|
const q: Queues = {};
|
||||||
|
for (const sle of rawSles) {
|
||||||
|
const i = sle.item;
|
||||||
|
const l = sle.location;
|
||||||
|
const b = sle.batch ?? '-';
|
||||||
|
|
||||||
|
q[i] ??= {};
|
||||||
|
q[i][l] ??= {};
|
||||||
|
q[i][l][b] ??= new StockQueue();
|
||||||
|
|
||||||
|
const sq = q[i][l][b];
|
||||||
|
if (sle.quantity > 0) {
|
||||||
|
const rate = fyo.pesa(sle.rate);
|
||||||
|
sq.inward(rate.float, sle.quantity);
|
||||||
|
} else {
|
||||||
|
sq.outward(-sle.quantity);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let total = fyo.pesa(0);
|
||||||
|
for (const item of items) {
|
||||||
|
const i = item.item ?? '-';
|
||||||
|
const l = item.location ?? '-';
|
||||||
|
const b = item.batch ?? '-';
|
||||||
|
|
||||||
|
const sq = q[i][l][b];
|
||||||
|
const stAmount = item.amount ?? 0;
|
||||||
|
if (!sq) {
|
||||||
|
total = total.add(stAmount);
|
||||||
|
}
|
||||||
|
|
||||||
|
const stRate = item.rate?.float ?? 0;
|
||||||
|
const stQuantity = item.quantity ?? 0;
|
||||||
|
|
||||||
|
const rate = sq.outward(stQuantity) ?? stRate;
|
||||||
|
const amount = rate * stQuantity;
|
||||||
|
|
||||||
|
total = total.add(amount);
|
||||||
|
}
|
||||||
|
|
||||||
|
return total;
|
||||||
|
}
|
||||||
|
|
||||||
export function getStockLedgerEntries(
|
export function getStockLedgerEntries(
|
||||||
rawSLEs: RawStockLedgerEntry[],
|
rawSLEs: RawStockLedgerEntry[],
|
||||||
valuationMethod: ValuationMethod
|
valuationMethod: ValuationMethod
|
||||||
|
@ -4,24 +4,6 @@
|
|||||||
"isSingle": true,
|
"isSingle": true,
|
||||||
"isChild": false,
|
"isChild": false,
|
||||||
"fields": [
|
"fields": [
|
||||||
{
|
|
||||||
"fieldname": "valuationMethod",
|
|
||||||
"label": "Valuation Method",
|
|
||||||
"fieldtype": "Select",
|
|
||||||
"options": [
|
|
||||||
{
|
|
||||||
"value": "FIFO",
|
|
||||||
"label": "FIFO"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"value": "MovingAverage",
|
|
||||||
"label": "Moving Average"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"default": "FIFO",
|
|
||||||
"required": true,
|
|
||||||
"section": "Default"
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"fieldname": "defaultLocation",
|
"fieldname": "defaultLocation",
|
||||||
"label": "Default Location",
|
"label": "Default Location",
|
||||||
|
Loading…
Reference in New Issue
Block a user