65.9K
CodeProject 正在变化。 阅读更多。
Home

使用简单的 JavaScript 进行简单的财务计算(第 1 部分)- 库存估值方法

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.50/5 (4投票s)

2017 年 8 月 21 日

CPOL

5分钟阅读

viewsIcon

16150

downloadIcon

266

使用简单的 JavaScript 进行一系列财务计算的简单可视化的开端。

引言

本文及整个项目的目标是双重的:提供一个简单且交互式的图形界面,深入了解选定的财务计算,并通过阅读简单的代码来理解这些计算。这两个目标本身都很难实现,并且带有自己固有的复杂性,足以填充两个库。尽管如此,我将尝试直接应对这些问题,并为您——消费者——提供尽可能深刻的见解。

背景

对于本文,您只需要具备 Javascript、库存估值方法的基本知识,以及中等的街头智慧(可选)。

基本要求

本项目的主要目标是直观地展示三种主要库存估值方法(先进先出法 (FIFO)、后进先出法 (LIFO) 和加权平均成本法 (WAC))的特征。

因此,衍生出的要求是:

  • 给定估值方法,正确计算库存价值
  • 提供一个比较不同估值方法的平台
  • 允许用户操作库存 - 不同的输入提供不同的结果
  • 以最简单有效的方式呈现估值

既然我们的要求已经比较具体地设定好了,我们就可以开始。

库存计算

我将库存价值的计算分为三个部分:首先,我们将设置一个Warehouse,然后我们将与这个Warehouse进行交易,最后,显示这些交易的结果。

设置仓库

在我们开始计算库存价值之前,我们需要一个地方来存储它。这就是Warehouse对象的作用。我已经这样设置了Warehouse。本质上,Warehouse对象包含三个TransactionTables(每种估值方法一个),一个TransactionTable将包含一个TransactionItems列表以及特定于估值方法的其他值。

        function Warehouse(initialItems) {

        //... some other properties

            this.LIFOTransactionTable = new TransactionTable();
            this.FIFOTransactionTable = new TransactionTable();
            this.WACTransactionTable = new TransactionTable();

        //... some methods to be discussed later
        
        }
        
        function TransactionTable(){
                
            this.ItemsList = [];
            this.Total = 0;
            this.BeginningTotal = 0;
            this.EndingTotal = 0;
            this.COGSTotal = 0;
            this.TotalSell = 0;
            this.GrossProfit = 0;
            
        //ratios
            this.GrossMargin = 0;
            this.InventoryTurnover = 0;
            this.DaysOnHand = 0;
        }
        
        function TransactionItem(txType, quantity, price){

            this.Timestamp = ticker;
            this.TxType = txType;

            if(txType == TransactionType.IMPORT)
            {
                this.Price = price;	
            }

            this.Quantity = quantity;

            ticker++;	
        }

引入仓库交易

现在我们已经设置好了仓库,我们可以开始进出口商品了。最终,我们一次只想向仓库添加一个TransactionItem。然后,该项目将复制到三个TransactionTables中。让我们从导入TransactionItem开始。

在导入TransactionItem时,我们只需要回答两个问题:我们想要多少数量,价格是多少,以及我们是否真的要添加该商品(TransactionType)。正如下面的截图所示,我们可以轻松地将这些信息归类到一个标题下。

此处输入的任何价格/数量都将创建一个TransactionItem并将其添加到相应的TransactionTables中。商品将按顺序添加,从 t0 开始,每次添加新商品时都会递增。当我们并排查看 LIFO、FIFO 和 WAC 表时,Timestamp非常重要。加权平均成本表的 Timestamp 始终是 t_avg

通过其性质,库存商品的导入很容易处理,因为它们总是会同时添加,而与库存估值方法无关。当销售商品时,差异就开始显现。对于本项目而言,这被归类为出口。当我们出口商品时,在 FIFO 的情况下,我们将移除先添加的商品(从 t0 开始)。在 LIFO 中,我们将移除最后添加的商品。这导致三个交易表中销货成本 (COGS) 存在差异。下面的代码片段显示了 FIFO 中 COGS 计算的示例。我们需要检查当前要耗尽的TransactionItemCurrentTx)中还剩多少数量。FIFO 计算的CurrentTx始终是列表中的第一个项目(currentIndex = 0),而在 LIFO 的情况下,第一个要销售的项目是列表中的最后一个项目(currentIndex = Warehouse.LIFOTransactionTable.ItemsList.length - 1;)。

        function CalculateCOGSFIFO_Perpetual(sellQuantity){
        var neededItems = sellQuantity;
        var itemsCalculated = 0;
        var currentIndex = 0; 
        var COGS_total = 0;
        var alterList = [];


        while(neededItems != itemsCalculated){

            var currentTx = new TransactionItem(TransactionType.IMPORT, Warehouse.FIFOTransactionTable.ItemsList[currentIndex].Quantity, Warehouse.FIFOTransactionTable.ItemsList[currentIndex].Price);

            currentTx.Timestamp = Warehouse.FIFOTransactionTable.ItemsList[currentIndex].Timestamp;

            if(currentTx.Quantity == 0){

            }
            else if(currentTx.Quantity > (neededItems - itemsCalculated)){
                var used = (neededItems - itemsCalculated);
                COGS_total = COGS_total + used * currentTx.Price;                
                currentTx.Quantity = currentTx.Quantity - used;
                itemsCalculated = itemsCalculated + used;
            }
            else if(currentTx.Quantity == (neededItems - itemsCalculated)){
                COGS_total = COGS_total + currentTx.Quantity * currentTx.Price;
                itemsCalculated += currentTx.Quantity;
                currentTx.Quantity = 0;
            }
            else if(currentTx.Quantity < (neededItems - itemsCalculated)){
                COGS_total = COGS_total + currentTx.Quantity * currentTx.Price;
                itemsCalculated += currentTx.Quantity;
                currentTx.Quantity = 0;
            }

            alterList.push(currentTx);
            currentIndex++;
        }

        Warehouse.FIFOTransactionTable.COGSTotal += COGS_total;
        AlterTransactionTable(CostMethod.FIFO, alterList);
    }

为了获得 WAC 的 COGS,计算很简单,因为 WAC 表始终只包含一个TransactionItem。这在下面的代码片段中可以看到。

    function CalculateCOGSWeightedAverage_Perpetual(sellQuantity){
        var WACItem = Warehouse.WACTransactionTable.ItemsList[0];
        Warehouse.WACTransactionTable.COGSTotal += (WACItem.Price * sellQuantity);
        WACItem.Quantity -= sellQuantity;
    }

以视觉友好的方式将所有内容整合在一起

现在我们有了一个Warehouse,并且可以进出口商品以实现盈利/亏损。我们现在将通过在添加/移除商品时构建这些表格来展示这种交互。希望这能很好地描绘出Warehouse在其三种形式下的当前状态。

获得比较视图的一个通用好方法是并排显示结果,因此决定将三个交易表放在一起。通过这种方式,可以获得良好的库存横截面视图。正如下面的图像所示,相同的 timestamps 在同一行上可见。

现在我们想看看销售商品时会发生什么。由于 FIFO/LIFO 的性质,这需要有效地表示出来,以便理解两种方法之间的差异。这是通过更改完全耗尽的商品(数量 = 0)的颜色来实现的。比喻地说,结果很清楚,表明一个事件正在仓库的不同末端发生。下面可以看到这一点。

此视图以以下方式在代码中构建:首先,当前库存将从视图中删除。然后,对于Warehouse中的每个TransactionTables,将使用下面的代码片段添加商品。如果一个TransactionItem已被耗尽,它将被赋予不同的颜色(我选择了 bootstrap 的“danger”类)。之后,将显示总值。

    Warehouse.FIFOTransactionTable.ItemsList.forEach(function(addItem){
                     
        var time = "t" + tick++;  
        
        if(addItem.TxType == TransactionType.IMPORT)			
        {
            var desc1 = addItem.Quantity + " items @ R " + addItem.Price; 
            
            if(addItem.Quantity == 0)
               var addRow = new String(`<tr id="FIFOItemRow" class="danger">`);
            else
                var addRow = new String(`<tr id="FIFOItemRow">`);
            
            addRow = addRow + tdText + time + endtd;
            addRow = addRow + tdText + desc1 + endtd;	

            $("#FIFOTable").append(addRow);			

            addRow = "";			
        }	
    });

关于模拟的一点说明

“在我那个年代,我们不得不手动添加库存商品,”一位几个月前使用过这个应用程序的人说道。有一个漂亮的“模拟”部分,用户可以设置他是否想在通货膨胀/通货紧缩的环境中添加库存商品。只需按一下按钮,就会以恒定的价格变动率向库存中添加五件随机数量的商品。变动率也随机设置为 1% 到 10% 之间。下面可以看到这个部分。

结论

库存估值方法有时是一个难以完全理解的棘手概念,有时直观的表示可以帮助更容易地获得直觉。本项目旨在通过易于开发的技术提供这种表示,以便通过使用 Web 界面或阅读代码来衡量理解程度。我希望您在阅读本文的过程中有所收获,并感谢任何和所有反馈。

历史

2017 年 8 月 20 日:初始版本

© . All rights reserved.