diff --git a/content/applications/finance/accounting.rst b/content/applications/finance/accounting.rst index 7a5388595b..c3fb01e516 100644 --- a/content/applications/finance/accounting.rst +++ b/content/applications/finance/accounting.rst @@ -282,7 +282,7 @@ available methods are standard price, average price, :abbr:`LIFO (Last-In, First :abbr:`FIFO (First-In, First-Out).` .. seealso:: - :doc:`../inventory_and_mrp/inventory/product_management/inventory_valuation/inventory_valuation_config` + :doc:`../inventory_and_mrp/inventory/inventory_valuation/cheat_sheet` .. _accounting/retained-earnings: diff --git a/content/applications/finance/accounting/get_started/avg_price_valuation.rst b/content/applications/finance/accounting/get_started/avg_price_valuation.rst index ebadf3ff00..6eb4f7b290 100644 --- a/content/applications/finance/accounting/get_started/avg_price_valuation.rst +++ b/content/applications/finance/accounting/get_started/avg_price_valuation.rst @@ -25,14 +25,8 @@ valuation `. .. note:: This document addresses a specific use case for theoretical purposes. For instructions on how to - set up and use |AVCO|, refer to the :doc:`inventory valuation configuration - <../../../inventory_and_mrp/inventory/product_management/inventory_valuation/inventory_valuation_config>` - doc. - -.. seealso:: - - :doc:`Using inventory valuation - <../../../inventory_and_mrp/inventory/product_management/inventory_valuation/using_inventory_valuation>` - - :ref:`Other inventory valuation methods ` + set up and use |AVCO|, refer to the :doc:`inventory valuation cheat sheet + <../../../inventory_and_mrp/inventory/inventory_valuation/cheat_sheet>`. Configuration ============= @@ -43,8 +37,8 @@ product category page, set :guilabel:`Costing Method` to `Average Cost (AVCO)` a :guilabel:`Inventory Valuation` to `Automated`. .. seealso:: - :doc:`Inventory valuation configuration - <../../../inventory_and_mrp/inventory/product_management/inventory_valuation/inventory_valuation_config>` + :doc:`Inventory valuation cheat sheet + <../../../inventory_and_mrp/inventory/inventory_valuation/cheat_sheet>` Using average cost valuation ============================ @@ -70,7 +64,7 @@ When new products arrive, the new average cost for each product is recomputed us - **Purchase Price**: estimated price of products at the reception of products (since vendor bills may arrive later). The amount includes not only the price for the products, but also added costs, such as shipping, taxes, and :doc:`landed costs - <../../../inventory_and_mrp/inventory/product_management/inventory_valuation/landed_costs>`. At + <../../../inventory_and_mrp/inventory/inventory_valuation/landed_costs>`. At reception of the vendor bill, this price is adjusted; - **Final Qty**: quantity of on-hand stock after the stock move. @@ -263,9 +257,6 @@ account that tracks the amount to be paid to vendors. Once a vendor delivers an value** increases based on the vendor price of the products that have entered the stock. The holding account (called **stock input**) is credited and only reconciled once the vendor bill is received. -.. seealso:: - - :ref:`Anglo-Saxon vs. Continental ` - The table below reflects journal entries and accounts. The *stock input* account stores the money intended to pay vendors when the vendor bill has not yet been received. To balance accounts when returning products that have a price difference between the price the product is **valued at** and diff --git a/content/applications/finance/fiscal_localizations/mexico.rst b/content/applications/finance/fiscal_localizations/mexico.rst index 9591a8f504..49a2b61859 100644 --- a/content/applications/finance/fiscal_localizations/mexico.rst +++ b/content/applications/finance/fiscal_localizations/mexico.rst @@ -1553,7 +1553,7 @@ Configuration ~~~~~~~~~~~~~ In order to track the correct customs number for a specific invoice, Odoo uses :doc:`landed costs -<../../inventory_and_mrp/inventory/product_management/inventory_valuation/landed_costs>`. Go to +<../../inventory_and_mrp/inventory/inventory_valuation/landed_costs>`. Go to :menuselection:`Inventory --> Configuration --> Settings`, and in the :guilabel:`Valuation` section, make sure that :guilabel:`Landed Costs` is activated. @@ -1569,8 +1569,7 @@ and complete these three requirements: Number` but **not** :guilabel:`By Quantity`. - :guilabel:`Invoicing Policy` **must** be set to :guilabel:`Delivered quantities`. - :doc:`Valuation by lots/serial numbers - <../../inventory_and_mrp/inventory/product_management/inventory_valuation/valuation_by_lots>` - **must** be enabled. + <../../inventory_and_mrp/inventory/inventory_valuation/valuation_by_lots>` **must** be enabled. This will make the field :guilabel:`Customs invoicing` available on the :guilabel:`Accounting` tab. Enable the field to use customs numbers with this product. @@ -1583,8 +1582,8 @@ configuration: .. note:: The feature works regardless of whether the :doc:`inventory valuation - <../../inventory_and_mrp/inventory/product_management/inventory_valuation/using_inventory_valuation>` - is set to either :guilabel:`Periodic (at closing)` or :guilabel:`Perpetual (at invoicing)`. + <../../inventory_and_mrp/inventory/inventory_valuation/cheat_sheet>` is set to either + :guilabel:`Periodic (at closing)` or :guilabel:`Perpetual (at invoicing)`. .. image:: mexico/mx-landing-configuration.png :alt: Storable products general configuration. @@ -1610,7 +1609,7 @@ number`. While it is possible to add costs related to the customs number at this stage of the process, it is highly recommended to create a landed cost from a vendor bill from your customs agent. Learn more about :doc:`Landed Costs here - <../../inventory_and_mrp/inventory/product_management/inventory_valuation/landed_costs>`. + <../../inventory_and_mrp/inventory/inventory_valuation/landed_costs>`. .. warning:: The :guilabel:`Customs number` field is not editable once it is set, and cannot be repeated, diff --git a/content/applications/finance/fiscal_localizations/peru.rst b/content/applications/finance/fiscal_localizations/peru.rst index 4709d753f4..141d61d50a 100644 --- a/content/applications/finance/fiscal_localizations/peru.rst +++ b/content/applications/finance/fiscal_localizations/peru.rst @@ -1003,12 +1003,11 @@ Several configurations related to the product or product category are necessary - **Automatic inventory valuation**: For storable goods (:dfn:`products with tracked inventory`), use :doc:`automatic inventory valuation - <../../inventory_and_mrp/inventory/product_management/inventory_valuation/inventory_valuation_config>`. - Once automatic inventory valuation is enabled, this valuation method can be enabled for - a product's :ref:`product category `. + <../../inventory_and_mrp/inventory/inventory_valuation/cheat_sheet>`. Once automatic inventory + valuation is enabled, this valuation method can be enabled for a product's product category. - **Costing method:** Storable goods must use a :doc:`costing method - <../../inventory_and_mrp/inventory/product_management/inventory_valuation/inventory_valuation_config>` + <../../inventory_and_mrp/inventory/inventory_valuation/cheat_sheet>` **other** than :guilabel:`Standard Price`, as the journal entries generated from stock moves are used to populate the |PLE| reports. @@ -1041,7 +1040,7 @@ Generate a .txt file for permanent inventory Kardex reports |PLE| 12.1 and 13.1 come as two separate books. The books need to be downloaded in `.txt` file format from Odoo, and then they should be submitted to the |SUNAT| |PLE| software. -On the :ref:`Inventory Valuation Report `, click +On the :ref:`Inventory Valuation Report `, click the :guilabel:`PLE Reports` button. Then, select the :guilabel:`Period` and choose a report to export: either the :guilabel:`PLE 12.1` or :guilabel:`PLE 13.1`. Odoo generates a `.txt` file for the chosen report. diff --git a/content/applications/inventory_and_mrp/inventory.rst b/content/applications/inventory_and_mrp/inventory.rst index 825a6b30b4..f93bd9d27c 100644 --- a/content/applications/inventory_and_mrp/inventory.rst +++ b/content/applications/inventory_and_mrp/inventory.rst @@ -19,3 +19,4 @@ users to easily manage lead times, automate replenishment, configure advanced ro inventory/product_management inventory/warehouses_storage inventory/shipping_receiving + inventory/inventory_valuation diff --git a/content/applications/inventory_and_mrp/inventory/product_management/inventory_valuation.rst b/content/applications/inventory_and_mrp/inventory/inventory_valuation.rst similarity index 64% rename from content/applications/inventory_and_mrp/inventory/product_management/inventory_valuation.rst rename to content/applications/inventory_and_mrp/inventory/inventory_valuation.rst index 05704a93f9..be88ed46f8 100644 --- a/content/applications/inventory_and_mrp/inventory/product_management/inventory_valuation.rst +++ b/content/applications/inventory_and_mrp/inventory/inventory_valuation.rst @@ -7,8 +7,7 @@ Inventory valuation .. toctree:: :titlesonly: - inventory_valuation/inventory_valuation_config - inventory_valuation/using_inventory_valuation + inventory_valuation/cheat_sheet inventory_valuation/landed_costs inventory_valuation/valuation_by_lots diff --git a/content/applications/inventory_and_mrp/inventory/inventory_valuation/cheat_sheet.rst b/content/applications/inventory_and_mrp/inventory/inventory_valuation/cheat_sheet.rst new file mode 100644 index 0000000000..0766033b3e --- /dev/null +++ b/content/applications/inventory_and_mrp/inventory/inventory_valuation/cheat_sheet.rst @@ -0,0 +1,408 @@ +:code-column: +:custom-css: valuation.css +:custom-js: misc.js,valuation-data.js,valuation-journal.js,valuation-accounting.js + +===================== +Valuation cheat sheet +===================== + +.. rst-class:: full-width + + +Costing Methods +=============== + +Odoo supports 3 costing methods configured in accounting's settings and, optionally, +the product's category. + +.. rst-class:: alternatives doc-aside + +Standard Cost: fixed unit cost, updated manually + .. list-table:: + :widths: 28 18 18 18 18 + :header-rows: 1 + :stub-columns: 1 + :class: values-table + + * - Operation + - Unit Cost + - Qty On Hand + - Delta Value + - Inventory Value + * - + - $10 + - 0 + - + - $0 + * - Receive 8 @$10 + - $10 + - 8 + - +8×$10 + - $80 + * - Receive 4 @$16 + - $10 + - 12 + - +4×$10 + - $120 + * - Deliver 10 + - $10 + - 2 + - | -10×$10 + | + - $20 + * - Receive 2 @$9 + - $10 + - 4 + - +2×$10 + - $40 + +Average Cost: weighted average of all units + .. list-table:: + :widths: 28 18 18 18 18 + :header-rows: 1 + :stub-columns: 1 + :class: values-table + + * - Operation + - Unit Cost + - Qty On Hand + - Delta Value + - Inventory Value + * - + - $0 + - 0 + - + - $0 + * - Receive 8 @$10 + - $10 + - 8 + - +8×$10 + - $80 + * - Receive 4 @$16 + - $12 + - 12 + - +4×$16 + - $144 + * - Deliver 10 + - $12 + - 2 + - | -10×$12 + | + - $24 + * - Receive 2 @$6 + - $9 + - 4 + - +2×$6 + - $36 + +FIFO: first in, first out + .. list-table:: + :widths: 28 18 18 18 18 + :header-rows: 1 + :stub-columns: 1 + :class: values-table + + * - Operation + - Unit Cost + - Qty On Hand + - Delta Value + - Inventory Value + * - + - $0 + - 0 + - + - $0 + * - Receive 8 @$10 + - $10 + - 8 + - +8×$10 + - $80 + * - Receive 4 @$16 + - $12 + - 12 + - +4×$16 + - $144 + * - Deliver 10 + - $16 + - 2 + - | -8×$10 + | -2×$16 + - $32 + * - Receive 2 @$6 + - $11 + - 4 + - +2×$6 + - $44 + + +.. rst-class:: alternatives-note + + .. note:: Removal strategies also support :abbr:`LIFO (last in, first out)` and :abbr:`FEFO + (first expiry, first out)`, but they only impact which product is first picked, not the + valuation method. For example, you can pick using LIFO, but using average cost for valuation, + as LIFO is not allowed by :abbr:`IFRS (International Financial Reporting Standards)`. + + +Inventory vs Accounting +======================= + +.. rst-class:: inventory-app-paragraph + + The :doc:`Inventory app ` keeps track of the inventory + value in real time as you **receive and deliver goods**. The reporting menu lets you analyze + inventory quantities and values by company, location, product, and more. + +.. rst-class:: accounting-app-paragraph + + The :doc:`Accounting app ` updates accounts when you receive + **invoices or bills**. Even though receipts and invoices differ, it’s not practical for + accountants to post journal entries for every inventory movement. So, they post a closing entry + to account for the difference between what has been invoiced and received/delivered. This closing + process happens usually once a year for SMEs, or once a month for larger companies. + +.. role:: good +.. role:: meh +.. role:: bad + +.. h:div:: feature-table doc-aside + + +------------------+------------+-----------+ + | | Accounting | Inventory | + +==================+============+===========+ + | Purchase Order | :meh:`/` | :meh:`/` | + +------------------+------------+-----------+ + | Receipt | :meh:`/` | :good:`✓` | + +------------------+------------+-----------+ + | Vendor Bill | :good:`✓` | :meh:`/` | + +------------------+------------+-----------+ + | Sales Order | :meh:`/` | :meh:`/` | + +------------------+------------+-----------+ + | Customer Invoice | :good:`✓` | :meh:`/` | + +------------------+------------+-----------+ + | Delivery | :meh:`/` | :good:`✓` | + +------------------+------------+-----------+ + | Closing Entry | :good:`✓` | :meh:`/` | + +------------------+------------+-----------+ + + +Accounting Methods +================== + +There are two accounting practices on how to maintain your accounts: + +**Periodic:** Post vendor bills as expenses by nature, and update stock valuation in the closing +entry by reducing expenses (stock variation). This is the best practice in Europe. + +**Perpetual:** Post vendor bills as assets (stock valuation), report expenses when goods are sold +(cost of goods sold). This is the best practice in countries that follow Anglo-Saxon accounting, +like the USA and India. + +.. role:: yellow +.. role:: green +.. role:: blue +.. role:: darkblue +.. role:: purple +.. role:: washed +.. role:: washed-green + :class: washed green +.. role:: washed-darkblue + :class: washed darkblue +.. role:: washed-purple + :class: washed purple + +* :purple:`Stock Account` on the product's category +* :yellow:`Stock Variation` on the stock account +* :blue:`Expense/Cost of Goods Sold` on the product/category +* :green:`Inventory Adjustment` on the Inventory Loss location + (optional, recommended for Anglo-Saxon accounting) +* :darkblue:`Expense` on the stock account + (for perpetual Continental accounting only) + +.. h:div:: doc-aside + + .. list-table:: + :stub-columns: 1 + :header-rows: 1 + :class: config-table + + * - + - EU Periodic + - EU Perpetual + - US Periodic + - US Perpetual + * - ADJUSTMENT + - + - :purple:`Stock` + - + - :purple:`Stock` + * - + - + - :green:`LOSS` + - + - :green:`Shrinkage` + * - + - + - + - + - + * - BILL + - :blue:`Expense` + - :purple:`Stock` + - :blue:`COGS` + - :purple:`Stock` + * - + - :washed:`Payable` + - :washed:`Payable` + - :washed:`Payable` + - :washed:`Payable` + * - + - + - + - + - + * - INVOICE + - + - :blue:`Expense` + - + - :blue:`COGS` + * - + - + - :purple:`Stock` + - + - :purple:`Stock` + * - + - :washed:`Income` + - :washed:`Income` + - :washed:`Income` + - :washed:`Income` + * - + - :washed:`Receivable` + - :washed:`Receivable` + - :washed:`Receivable` + - :washed:`Receivable` + * - + - + - + - + - + * - Closing + - :purple:`Stock` + - :washed-purple:`Stock` + - :purple:`Stock` + - :washed-purple:`Stock` + * - [1] + - :yellow:`Variation` + - :washed-darkblue:`Expense` + - :yellow:`Variation` + - :yellow:`Variation` + * - [2] + - :washed-green:`LOSS` + - + - :washed-green:`Shrinkage` + - + * - [3] + - + - :yellow:`Variation` + - + - + * - + - + - :darkblue:`Expense` + - + - + + 1. Inventory valuation - Accounting valuation + 2. Inventory valuation lost, + only if an account is set on the loss location + 3. Accounting valuation end of period - + Valuation beginning of period + + +.. _accounting-entries: + +Accounting Entries +================== + +.. h:div:: accounting-entries doc-aside + + .. placeholder + + +.. _journal-entries: + +Journal Entries Configuration +============================= + + +.. h:div:: journal-entries doc-aside + + .. placeholder + + +Reporting +========= + +In Inventory +------------ + +Open :menuselection:`Inventory -- > Reporting --> Stock` to view your current inventory level and +valuation for each product, or to review historical data as of a previous date. + +.. h:div:: doc-aside + + .. image:: cheat_sheet/valuation-stock.png + + +Unit cost +~~~~~~~~~ + +To check a product's existing unit price updates and their origins, click on the product's +:guilabel:`Unit Cost`. In :abbr:`AVCO (average cost)` this allows you to understand how the +currently used value was calculated. + +.. h:div:: doc-aside + + .. image:: cheat_sheet/unit-cost.png + + +Total value +~~~~~~~~~~~ + +To see all incoming quantities for which you still have a remaining quantity and the value used for +their valuation, click on a product's :guilabel:`Total Value`. + +- In AVCO or standard cost, the used value is always the current average unit cost. +- In FIFO, remaining units from each previous incoming move retain their own individual valuation. + +In FIFO or AVCO, remaining quantities from a previous incoming move can have their value adjusted if +necessary: Select the incoming moves to be adjusted, click :icon:`fa-cog` :guilabel:`Actions`, and +then click :guilabel:`Adjust Valuation`. Enter the new :guilabel:`Value` and, optionally, a +:guilabel:`Description`. + +.. h:div:: doc-aside + + .. image:: cheat_sheet/total-value.png + + +In Accounting +------------- + +To view the difference between the accounting stock value and the current inventory value recorded +thanks to the incoming moves with a remaining quantity, go to :menuselection:`Accounting --> Review +--> Inventory Valuation`. + +To generate a new accounting entry to review and post, click :guilabel:`Generate Entry`. + +To view a list of sales and purchase orders for which accrual entries should be encoded, go to +:menuselection:`Accounting --> Review` and select the relevant menu item (:guilabel:`Invoices not +received`, :guilabel:`Invoices to be issued`, :guilabel:`Prepaid expenses`, or :guilabel:`Deferred +Revenues`). + +With Anglo-Saxon perpetual accounting, this will also help to distribute recorded inventory +variations to accounts such as Bills to Receive/:abbr:`GRNI (goods received not invoiced)` or +:abbr:`COGS (cost of goods sold)` as shown in the :ref:`Accounting Entries ` +and :ref:`Journal Entries Configuration ` sections. + +.. h:div:: doc-aside + + .. image:: cheat_sheet/valuation-accounting.png diff --git a/content/applications/inventory_and_mrp/inventory/inventory_valuation/cheat_sheet/total-value.png b/content/applications/inventory_and_mrp/inventory/inventory_valuation/cheat_sheet/total-value.png new file mode 100644 index 0000000000..bfeeb84ec2 Binary files /dev/null and b/content/applications/inventory_and_mrp/inventory/inventory_valuation/cheat_sheet/total-value.png differ diff --git a/content/applications/inventory_and_mrp/inventory/inventory_valuation/cheat_sheet/unit-cost.png b/content/applications/inventory_and_mrp/inventory/inventory_valuation/cheat_sheet/unit-cost.png new file mode 100644 index 0000000000..aa80ff2952 Binary files /dev/null and b/content/applications/inventory_and_mrp/inventory/inventory_valuation/cheat_sheet/unit-cost.png differ diff --git a/content/applications/inventory_and_mrp/inventory/inventory_valuation/cheat_sheet/valuation-accounting.png b/content/applications/inventory_and_mrp/inventory/inventory_valuation/cheat_sheet/valuation-accounting.png new file mode 100644 index 0000000000..db2b1bd5d2 Binary files /dev/null and b/content/applications/inventory_and_mrp/inventory/inventory_valuation/cheat_sheet/valuation-accounting.png differ diff --git a/content/applications/inventory_and_mrp/inventory/inventory_valuation/cheat_sheet/valuation-stock.png b/content/applications/inventory_and_mrp/inventory/inventory_valuation/cheat_sheet/valuation-stock.png new file mode 100644 index 0000000000..f09260594c Binary files /dev/null and b/content/applications/inventory_and_mrp/inventory/inventory_valuation/cheat_sheet/valuation-stock.png differ diff --git a/content/applications/inventory_and_mrp/inventory/product_management/inventory_valuation/landed_costs.rst b/content/applications/inventory_and_mrp/inventory/inventory_valuation/landed_costs.rst similarity index 98% rename from content/applications/inventory_and_mrp/inventory/product_management/inventory_valuation/landed_costs.rst rename to content/applications/inventory_and_mrp/inventory/inventory_valuation/landed_costs.rst index 72b9d09c33..171dac4393 100644 --- a/content/applications/inventory_and_mrp/inventory/product_management/inventory_valuation/landed_costs.rst +++ b/content/applications/inventory_and_mrp/inventory/inventory_valuation/landed_costs.rst @@ -69,9 +69,7 @@ When creating new vendor bills, this product can be added as an invoice line as .. important:: To apply a landed cost on a vendor bill, products in the original |PO| **must** belong to a - *Product Category* with a *Costing Method* of either |AVCO| or |FIFO|, and the valuation method - can be :doc:`manual ` or :doc:`automatic - `. + *Product Category* with a *Costing Method* of either |AVCO| or |FIFO|. Create purchase order ===================== diff --git a/content/applications/inventory_and_mrp/inventory/product_management/inventory_valuation/landed_costs/integrating-landed-costs-checkboxes.png b/content/applications/inventory_and_mrp/inventory/inventory_valuation/landed_costs/integrating-landed-costs-checkboxes.png similarity index 100% rename from content/applications/inventory_and_mrp/inventory/product_management/inventory_valuation/landed_costs/integrating-landed-costs-checkboxes.png rename to content/applications/inventory_and_mrp/inventory/inventory_valuation/landed_costs/integrating-landed-costs-checkboxes.png diff --git a/content/applications/inventory_and_mrp/inventory/product_management/inventory_valuation/landed_costs/integrating-landed-costs-create-button.png b/content/applications/inventory_and_mrp/inventory/inventory_valuation/landed_costs/integrating-landed-costs-create-button.png similarity index 100% rename from content/applications/inventory_and_mrp/inventory/product_management/inventory_valuation/landed_costs/integrating-landed-costs-create-button.png rename to content/applications/inventory_and_mrp/inventory/inventory_valuation/landed_costs/integrating-landed-costs-create-button.png diff --git a/content/applications/inventory_and_mrp/inventory/product_management/inventory_valuation/landed_costs/integrating-landed-costs-enabled-setting.png b/content/applications/inventory_and_mrp/inventory/inventory_valuation/landed_costs/integrating-landed-costs-enabled-setting.png similarity index 100% rename from content/applications/inventory_and_mrp/inventory/product_management/inventory_valuation/landed_costs/integrating-landed-costs-enabled-setting.png rename to content/applications/inventory_and_mrp/inventory/inventory_valuation/landed_costs/integrating-landed-costs-enabled-setting.png diff --git a/content/applications/inventory_and_mrp/inventory/product_management/inventory_valuation/landed_costs/integrating-landed-costs-journal-entry.png b/content/applications/inventory_and_mrp/inventory/inventory_valuation/landed_costs/integrating-landed-costs-journal-entry.png similarity index 100% rename from content/applications/inventory_and_mrp/inventory/product_management/inventory_valuation/landed_costs/integrating-landed-costs-journal-entry.png rename to content/applications/inventory_and_mrp/inventory/inventory_valuation/landed_costs/integrating-landed-costs-journal-entry.png diff --git a/content/applications/inventory_and_mrp/inventory/product_management/inventory_valuation/landed_costs/integrating-landed-costs-landed-cost-product.png b/content/applications/inventory_and_mrp/inventory/inventory_valuation/landed_costs/integrating-landed-costs-landed-cost-product.png similarity index 100% rename from content/applications/inventory_and_mrp/inventory/product_management/inventory_valuation/landed_costs/integrating-landed-costs-landed-cost-product.png rename to content/applications/inventory_and_mrp/inventory/inventory_valuation/landed_costs/integrating-landed-costs-landed-cost-product.png diff --git a/content/applications/inventory_and_mrp/inventory/product_management/inventory_valuation/landed_costs/integrating-landed-costs-transfers-menu.png b/content/applications/inventory_and_mrp/inventory/inventory_valuation/landed_costs/integrating-landed-costs-transfers-menu.png similarity index 100% rename from content/applications/inventory_and_mrp/inventory/product_management/inventory_valuation/landed_costs/integrating-landed-costs-transfers-menu.png rename to content/applications/inventory_and_mrp/inventory/inventory_valuation/landed_costs/integrating-landed-costs-transfers-menu.png diff --git a/content/applications/inventory_and_mrp/inventory/product_management/inventory_valuation/valuation_by_lots.rst b/content/applications/inventory_and_mrp/inventory/inventory_valuation/valuation_by_lots.rst similarity index 90% rename from content/applications/inventory_and_mrp/inventory/product_management/inventory_valuation/valuation_by_lots.rst rename to content/applications/inventory_and_mrp/inventory/inventory_valuation/valuation_by_lots.rst index cbf3319693..c945b0ac00 100644 --- a/content/applications/inventory_and_mrp/inventory/product_management/inventory_valuation/valuation_by_lots.rst +++ b/content/applications/inventory_and_mrp/inventory/inventory_valuation/valuation_by_lots.rst @@ -2,19 +2,19 @@ Valuation by lots/serial numbers ================================ -Track :doc:`inventory valuation ` by :doc:`lots or serial numbers -<../../product_management/product_tracking>` to: +Track :doc:`inventory valuation ` by :doc:`lots or serial numbers +<../product_management/product_tracking>` to: #. :ref:`Compare and differentiate purchasing cost `, based on lot or serial numbers. #. Track the actual cost of manufactured products, based on the real cost of each tracked component used. #. Depreciate specific lot or serial numbers when they :doc:`sit in stock for too long - <../../warehouses_storage/reporting/aging>`. + <../warehouses_storage/reporting/aging>`. .. important:: - Please read this :doc:`introduction to inventory valuation ` before - setting up valuation by lot/serial numbers. + Please read this :doc:`introduction to inventory valuation ` before setting up + valuation by lot/serial numbers. Configuration ============= @@ -25,16 +25,13 @@ feature `. After that, go to a new product, by clicking :guilabel:`New`. On the product form, in the :guilabel:`Category` field, choose a product category. Ensure the -product category's :ref:`Costing Method ` is set to -*First In First Out (FIFO)* or *Average Cost (AVCO)*. +product category's :guilabel:`Costing Method` is set to *First In First Out (FIFO)* or +*Average Cost (AVCO)*. .. tip:: To check the costing method set on the product category, hover over the :guilabel:`Category` field, and click the :icon:`oi-arrow-right` :guilabel:`(Internal Link)` icon. -.. seealso:: - :ref:`Costing methods ` - Next, activate the product to be tracked by lots or serial numbers by ticking the :guilabel:`Track Inventory` checkbox. Then, click the adjacent field that appears, and choose either :guilabel:`By Lots` or :guilabel:`By Unique Serial Number` from the resulting drop-down menu. @@ -109,7 +106,7 @@ Create new lot/serial number ---------------------------- Creating a new lot/serial number through an :doc:`inventory adjustment -<../../warehouses_storage/inventory_management/count_products>` assigns the same value as the cost +<../warehouses_storage/inventory_management/count_products>` assigns the same value as the cost on the product form. To make an inventory adjustment, and assign a lot number, go to :menuselection:`Inventory app --> @@ -187,7 +184,7 @@ On the resulting :guilabel:`Stock Valuation` report, click the search bar, and i .. tip:: Click the :icon:`fa-plus` :guilabel:`(plus)` icon to the right of a collapsed lot number line to - :ref:`manually modify the cost `. + manually modify the cost. This is useful for adjusting individual lot prices when a purchase order or bill includes multiple lots/serial numbers, as initial prices are identical upon reception. diff --git a/content/applications/inventory_and_mrp/inventory/product_management/inventory_valuation/valuation_by_lots/create-new.png b/content/applications/inventory_and_mrp/inventory/inventory_valuation/valuation_by_lots/create-new.png similarity index 100% rename from content/applications/inventory_and_mrp/inventory/product_management/inventory_valuation/valuation_by_lots/create-new.png rename to content/applications/inventory_and_mrp/inventory/inventory_valuation/valuation_by_lots/create-new.png diff --git a/content/applications/inventory_and_mrp/inventory/product_management/inventory_valuation/valuation_by_lots/existing.png b/content/applications/inventory_and_mrp/inventory/inventory_valuation/valuation_by_lots/existing.png similarity index 100% rename from content/applications/inventory_and_mrp/inventory/product_management/inventory_valuation/valuation_by_lots/existing.png rename to content/applications/inventory_and_mrp/inventory/inventory_valuation/valuation_by_lots/existing.png diff --git a/content/applications/inventory_and_mrp/inventory/product_management/inventory_valuation/valuation_by_lots/lip-gloss.png b/content/applications/inventory_and_mrp/inventory/inventory_valuation/valuation_by_lots/lip-gloss.png similarity index 100% rename from content/applications/inventory_and_mrp/inventory/product_management/inventory_valuation/valuation_by_lots/lip-gloss.png rename to content/applications/inventory_and_mrp/inventory/inventory_valuation/valuation_by_lots/lip-gloss.png diff --git a/content/applications/inventory_and_mrp/inventory/product_management/inventory_valuation/valuation_by_lots/lot-stock-valuation.png b/content/applications/inventory_and_mrp/inventory/inventory_valuation/valuation_by_lots/lot-stock-valuation.png similarity index 100% rename from content/applications/inventory_and_mrp/inventory/product_management/inventory_valuation/valuation_by_lots/lot-stock-valuation.png rename to content/applications/inventory_and_mrp/inventory/inventory_valuation/valuation_by_lots/lot-stock-valuation.png diff --git a/content/applications/inventory_and_mrp/inventory/product_management/inventory_valuation/valuation_by_lots/lot.png b/content/applications/inventory_and_mrp/inventory/inventory_valuation/valuation_by_lots/lot.png similarity index 100% rename from content/applications/inventory_and_mrp/inventory/product_management/inventory_valuation/valuation_by_lots/lot.png rename to content/applications/inventory_and_mrp/inventory/inventory_valuation/valuation_by_lots/lot.png diff --git a/content/applications/inventory_and_mrp/inventory/product_management/inventory_valuation/valuation_by_lots/product-form.png b/content/applications/inventory_and_mrp/inventory/inventory_valuation/valuation_by_lots/product-form.png similarity index 100% rename from content/applications/inventory_and_mrp/inventory/product_management/inventory_valuation/valuation_by_lots/product-form.png rename to content/applications/inventory_and_mrp/inventory/inventory_valuation/valuation_by_lots/product-form.png diff --git a/content/applications/inventory_and_mrp/inventory/product_management/inventory_valuation/valuation_by_lots/stock-valuation.png b/content/applications/inventory_and_mrp/inventory/inventory_valuation/valuation_by_lots/stock-valuation.png similarity index 100% rename from content/applications/inventory_and_mrp/inventory/product_management/inventory_valuation/valuation_by_lots/stock-valuation.png rename to content/applications/inventory_and_mrp/inventory/inventory_valuation/valuation_by_lots/stock-valuation.png diff --git a/content/applications/inventory_and_mrp/inventory/product_management.rst b/content/applications/inventory_and_mrp/inventory/product_management.rst index a8b32e652c..b58fc9df47 100644 --- a/content/applications/inventory_and_mrp/inventory/product_management.rst +++ b/content/applications/inventory_and_mrp/inventory/product_management.rst @@ -9,4 +9,3 @@ Product management product_management/configure product_management/product_tracking - product_management/inventory_valuation diff --git a/content/applications/inventory_and_mrp/inventory/product_management/configure/type.rst b/content/applications/inventory_and_mrp/inventory/product_management/configure/type.rst index 50cae18401..513e974a1c 100644 --- a/content/applications/inventory_and_mrp/inventory/product_management/configure/type.rst +++ b/content/applications/inventory_and_mrp/inventory/product_management/configure/type.rst @@ -164,7 +164,7 @@ documents. * - :doc:`Use inventory adjustments <../../warehouses_storage/inventory_management/count_products>` - Yes - No - * - :doc:`Use inventory valuation <../inventory_valuation/using_inventory_valuation>` + * - :doc:`Use inventory valuation <../../inventory_valuation/cheat_sheet>` - Yes - No * - :ref:`Create transfer ` @@ -344,6 +344,6 @@ Inventory reports on that product's specific moves history. - :guilabel:`Moves Analysis`: This report provides a pivot table view of inventory transfers by operation type. -- :ref:`Stock Valuation report `: A detailed record - of the monetary value of all tracked inventory. +- :ref:`Stock Valuation report `: A + detailed record of the monetary value of all tracked inventory. diff --git a/content/applications/inventory_and_mrp/inventory/product_management/inventory_valuation/inventory_valuation_config.rst b/content/applications/inventory_and_mrp/inventory/product_management/inventory_valuation/inventory_valuation_config.rst deleted file mode 100644 index d67611e347..0000000000 --- a/content/applications/inventory_and_mrp/inventory/product_management/inventory_valuation/inventory_valuation_config.rst +++ /dev/null @@ -1,488 +0,0 @@ -============================= -Automatic inventory valuation -============================= - -.. |right arrow| replace:: :icon:`fa-arrow-right` :guilabel:`(right arrow)` - -All of a company's stock on-hand contributes to the valuation of its inventory. That value should -be reflected in the company's accounting records to accurately show the value of the company and -all of its assets. - -By default, Odoo uses a periodic inventory valuation (also known as manual inventory valuation). -This method implies that the accounting team manually posts journal entries, based on the physical -inventory of the company, and warehouse employees take the time to count the stock. In Odoo, each -product category reflects this, with the :guilabel:`Costing Method` set to :guilabel:`Standard -Price`, and the :guilabel:`Inventory Valuation` (not visible by default) set to :guilabel:`Manual`. - -.. image:: inventory_valuation_config/inventory-valuation-fields.png - :align: center - :alt: The Costing Method field is located on the Product Categories form. - -Alternatively, perpetual (automatic) inventory valuation creates real-time *journal entries* in the -*Accounting* app whenever stock enters or leaves the company's warehouse. - -This document is focused on the proper setup of automatic inventory valuation, which is an -integrated valuation method that ensures journal entries in the *Accounting* app match stock -valuation updates in the *Inventory* app. For an introduction of inventory valuation in Odoo, refer -to the :doc:`using_inventory_valuation` documentation. - -.. warning:: - Switching from manual to automatic inventory valuation may cause discrepancies between stock - valuation and accounting journals. - - One `successful strategy `_ for switching to automated valuation: - - #. Clear existing stock (possibly with an :doc:`inventory adjustment - <../../warehouses_storage/inventory_management/count_products>`) - #. Change the inventory valuation method to *Automatic* - #. Return the existing stock, with the original monetary value (using an inventory adjustment) - - Once the existing stock is recovered, the Odoo *Accounting* app automatically generates the - journal entries to corresponding stock valuation records. - -Configuration -============= - -To properly set up automatic inventory valuation, follow these steps in Odoo: - -#. :ref:`Install Accounting app and enable specific settings - ` -#. :ref:`Set Automatic inventory valuation on product categories - ` -#. :ref:`Set costing method ` - -.. _inventory/warehouses_storage/accounting-setup: - -Accounting setup ----------------- - -To use automatic inventory valuation, install the *Accounting* app. Next, go to -:menuselection:`Accounting app --> Configuration --> Settings`, and in the :guilabel:`Stock -Valuation` section, tick the :guilabel:`Automatic Accounting` checkbox. Then, click -:guilabel:`Save`. - -.. note:: - Enabling :guilabel:`Automatic Accounting` shows the previously invisible *Inventory Valuation* - field on a product category. - -.. image:: inventory_valuation_config/auto-accounting.png - :align: center - :alt: Automatic Accounting feature in Stock Valuation section of Settings page. - -Refer to the :ref:`Expense ` and :ref:`Stock -input/output ` sections of documentation for details on -configuring the accounting journals shown. - -.. _inventory/warehouses_storage/valuation-on-product-category: - -Product category setup ----------------------- - -After :ref:`enabling inventory valuation `, the next -step is to set the product category to use automatic inventory valuation. - -Go to :menuselection:`Inventory app --> Configuration --> Product Categories`, and select the -desired product category. In the :guilabel:`Inventory Valuation` section, set the -:guilabel:`Inventory Valuation` field to :guilabel:`Automated`. Repeat this step for every product -category intending to use automatic inventory valuation. - -.. note:: - After enabling automatic accounting, each new stock move layer (SVL), that is created during - inventory valuation updates, generates a journal entry. - -.. image:: inventory_valuation_config/automated-inventory-valuation.png - :align: center - :alt: Inventory Valuation field on the product category, with its various stock accounts. - -.. _inventory/warehouses_storage/costing_methods: - -Costing method -============== - -After :ref:`enabling inventory valuation `, the -*costing method* for calculating and recording inventory costs is defined on the product category in -Odoo. - -Go to :menuselection:`Inventory app --> Configuration --> Product Categories` and select the desired -product category. In the :guilabel:`Inventory Valuation` section, select the appropriate -:guilabel:`Costing Method`: - - -.. tabs:: - - .. tab:: Standard Price - - The default costing method in Odoo. The cost of the product is manually defined on the product - form, and this cost is used to compute the valuation. Even if the purchase price on a purchase - order differs, the valuation is the cost defined on the product form. - - .. list-table:: - :header-rows: 1 - :stub-columns: 1 - - * - Operation - - Unit Cost - - Qty On Hand - - Incoming Value - - Inventory Value - * - - - $10 - - 0 - - - - $0 - * - Receive 8 products for $10/unit - - $10 - - 8 - - 8 * $10 - - $80 - * - Receive 4 products for $16/unit - - $10 - - 12 - - 4 * $10 - - $120 - * - Deliver 10 products - - $10 - - 2 - - -10 * $10 - - $20 - * - Receive 2 products for $9/unit - - $10 - - 4 - - 2 * $10 - - $40 - - .. tab:: Average Cost (AVCO) - - Calculates the valuation of a product based on the average cost of that product, divided by - the total number of available stock on-hand. With this costing method, inventory valuation is - *dynamic*, and constantly adjusts based on the purchase price of products. - - .. list-table:: - :header-rows: 1 - :stub-columns: 1 - - * - Operation - - Unit Cost - - Qty On Hand - - Incoming Value - - Inventory Value - * - - - $0 - - 0 - - - - $0 - * - Receive 8 products for $10/unit - - $10 - - 8 - - 8 * $10 - - $80 - * - Receive 4 products for $16/unit - - $12 - - 12 - - 4 * $16 - - $144 - * - Deliver 10 products - - $12 - - 2 - - -10 * $12 - - $24 - * - Receive 2 products for $6/unit - - $9 - - 4 - - 2 * $6 - - $36 - - How are unit cost and inventory value calculated at each step? - - - When receiving four products for $16 each: - - - Inventory value is calculated by adding the previous inventory value with the incoming - value: :math:`$80 + (4 * $16) = $144`. - - Unit cost is calculated by dividing the inventory value by the quantity on-hand: - :math:`$144 / 12 = $12`. - - - When delivering ten products, the average unit cost is used to calculate the inventory - value, regardless of the purchase price of the product. Therefore, inventory value is - :math:`$144 + (-10 * $12) = $24`. - - - Receive two products for $6 each: - - - Inventory value: :math:`$24 + (2 * $6) = $36` - - Unit cost: :math:`$36 / 4 = $9` - - .. note:: - When choosing :guilabel:`Average Cost (AVCO)` as the :guilabel:`Costing Method`, changing - the numerical value in the *Cost* field for products in the respective product category - creates a new record in the *Inventory Valuation* report to adjust the value of the - product. The *Cost* amount is then automatically updated, based on the average purchase - price of both the inventory on-hand and the costs accumulated from validated purchase - orders. - - .. tab:: First In First Out (FIFO) - - Tracks the costs of incoming and outgoing items in real-time, and uses the real price of the - products to change the valuation. The oldest purchase price is used as the cost for the next - good sold, until an entire lot of that product is sold. When the next inventory lot moves up - in the queue, an updated product cost is used based on the valuation of that specific lot. - - This method is arguably the most accurate inventory valuation method for a variety of reasons, - but it is highly sensitive to input data and human error. - - .. list-table:: - :header-rows: 1 - :stub-columns: 1 - - * - Operation - - Unit Cost - - Qty On Hand - - Incoming Value - - Inventory Value - * - - - $0 - - 0 - - - - $0 - * - Receive 8 products for $10/unit - - $10 - - 8 - - 8 * $10 - - $80 - * - Receive 4 products for $16/unit - - $12 - - 12 - - 4 * $16 - - $144 - * - Deliver 10 products - - $16 - - 2 - - | -8 * $10 - | -2 * $16 - - $32 - * - Receive 2 products for $6/unit - - $11 - - 4 - - 2 * $6 - - $44 - - How are unit cost and inventory value calculated at each step? - - - When receiving four products for $16 each: - - - Inventory value is calculated by adding the previous inventory value to the incoming - value: :math:`$80 + (4 * $16) = $144`. - - Unit cost is calculated by dividing the inventory value by the quantity on-hand: - :math:`$144 / 12 = $12`. - - - When delivering ten products, eight units were purchased for $10, and two units were - purchased for $16. - - - First, the incoming value is calculated by multiplying the on-hand quantity by the - purchased price: :math:`(-8 * $10) + (-2 * $16) = -112`. - - The inventory value is calculated by subtracting the incoming value from the previous - inventory value: :math:`$144 - $112 = $32`. - - Unit cost is calculated by dividing the inventory value by the remaining quantity: - :math:`$32 / 2 = $16`. - - - When receiving two products for $6, inventory value is :math:`$32 + $12 = $44`. Unit cost is - :math:`$44 / 4 = $11`. - -.. warning:: - Changing the costing method greatly impacts inventory valuation. It is highly recommended to - consult an accountant first before making any adjustments here. - -.. seealso:: - :doc:`using_inventory_valuation` - -When the :guilabel:`Costing Method` is changed, products already in stock that were using the -:guilabel:`Standard` costing method **do not** change value; rather, the existing units keep their -value, and any product moves from then on affect the average cost, and the cost of the product will -change. If the value in the :guilabel:`Cost` field on a product form is changed manually, Odoo -generates a corresponding record in the *Inventory Valuation* report. - -.. note:: - It is possible to use different valuation settings for different product categories. - -.. _inventory/warehouses_storage/accounting-types: - -Types of accounting -=================== - -With automated inventory valuation set up, the generated journal entries depend on the chosen -accounting mode: *Continental* or *Anglo-Saxon*. - -.. tip:: - Verify the accounting mode by activating the :ref:`developer-mode`, and navigating to - :menuselection:`Accounting app --> Configuration --> Settings`. - - Then, in the :guilabel:`Search...` bar, look for `Anglo-Saxon Accounting`, to see if the feature - is enabled. If it is **not** enabled, *Continental* accounting mode is in use. - - .. image:: inventory_valuation_config/anglo-saxon.png - :align: center - :alt: Show the Anglo-Saxon accounting mode feature. - -In *Anglo-Saxon* accounting, the costs of goods sold (COGS) are reported when products are sold or -delivered. This means the cost of a good is only recorded as an expense when a customer is invoiced -for a product. - -So, for **manual** valuation method, set the *Expense Account* to *Stock Valuation* for the current -asset type; for **automatic** valuation method, set the *Expense Account* to an *Expenses* or a -*Cost of Revenue* type (e.g. *Cost of Production*, *Cost of Goods Sold*, etc.). - -In *Continental* accounting, the cost of a good is reported as soon as a product is received into -stock. Because of this, the *Expense Account* can be set to **either** *Expenses* or a *Cost of -Revenue* type, however, it is more commonly set to an *Expenses* account. - -Refer to the :ref:`Expense ` and :ref:`Stock -input/output ` sections for details on configuring each -account type. - -.. _inventory/warehouses_storage/expense-account: - -Expense account ---------------- - -To configure the *expense account*, which is used in both manual and automatic inventory valuation, -go to the :guilabel:`Account Properties` section of the intended product category -(:menuselection:`Inventory app --> Configuration --> Product Categories`). Then, choose an existing -account from the :guilabel:`Expense Account` drop-down menu. - -To ensure the chosen account is the correct :guilabel:`Type,` click the |right arrow| icon to the -right of the account. Then, set the account type based on the information below. - -.. tabs:: - - .. group-tab:: Anglo-Saxon - - .. tabs:: - - .. group-tab:: Automated - - In Anglo-Saxon accounting for automated inventory valuation, set the :guilabel:`Expense - Account` to the `Expenses` account. Then, click the |right arrow| icon to the right of - the account. - - In the pop-up window, choose :guilabel:`Expenses` or :guilabel:`Cost of Revenue` from - the :guilabel:`Type` drop-down menu. - - .. image:: inventory_valuation_config/external-link.png - :align: center - :alt: Show **Expense Account** field, and external link icon. - - .. group-tab:: Manual - - To configure the :guilabel:`Expense Account`, choose :guilabel:`Stock Valuation` from - the field's drop-down menu. Verify the account's type by clicking the |right arrow| - icon, and then ensure the :guilabel:`Type` is :guilabel:`Current Assets`. - - .. image:: inventory_valuation_config/manual-anglo-saxon-expense.png - :align: center - :alt: Show the **Expense Account** field. - - .. group-tab:: Continental - - .. tabs:: - - .. group-tab:: Automated - - Set the :guilabel:`Expense Account` to the :guilabel:`Expenses` or :guilabel:`Cost of - Revenue` account type. - - .. group-tab:: Manual - - Set the :guilabel:`Expense Account` to the :guilabel:`Expenses` or :guilabel:`Cost of - Revenue` account type. - -.. _inventory/warehouses_storage/stock-account: - -Stock input/output (automated only) -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -To configure the :guilabel:`Stock Input Account` and :guilabel:`Stock Output Account`, go to -:menuselection:`Inventory app --> Configuration --> Product Categories` and select the desired -product category. - -In the :guilabel:`Inventory Valuation` field, select :guilabel:`Automated`. Doing so makes the -:guilabel:`Account Stock Properties` section appear. These accounts are defined as follows: - -- :guilabel:`Stock Valuation Account`: when automated inventory valuation is enabled on a product, - this account will hold the current value of the products. -- :guilabel:`Stock Journal`: accounting journal where entries are automatically posted when a - product's inventory valuation changes. -- :guilabel:`Stock Input Account`: counterpart journal items for all incoming stock moves will be - posted in this account, unless there is a specific valuation account set on the source location. - This is the default value for all products in a given category, and can also be set directly on - each product. -- :guilabel:`Stock Output Account`: counterpart journal items for all outgoing stock moves will be - posted in this account, unless there is a specific valuation account set on the destination - location. This is the default value for all products in a given category, and can also be set - directly on each product. - -.. tabs:: - - .. group-tab:: Anglo-Saxon - - In Anglo-Saxon accounting, the :guilabel:`Stock Input Account` and :guilabel:`Stock Output - Account` are set to *different* :guilabel:`Current Assets` accounts. This way, delivering - products and invoicing the customer balance the *Stock Output* account, while receiving - products and billing vendors balance the *Stock Input* account. - - To modify the account type, go to the click the |right arrow| icon to the right of the stock - input/output account. In the pop-up window, choose :guilabel:`Current Assets` from the - :guilabel:`Type` drop-down menu. - - .. figure:: inventory_valuation_config/account-type.png - :align: center - :alt: Display account setup page, highlighting the **Type** field. - - The *Stock Input* account is set to `Stock Interim (Received)`, a *Current Asset* account - type. - - .. group-tab:: Continental - - In Continental accounting, the :guilabel:`Stock Input Account` and :guilabel:`Stock Output - Account` are set to **the same** :guilabel:`Current Assets` account. That way, one account can - be balanced when items are bought and sold. - - .. example:: - The stock input and output accounts are both set to `Stock Interim (Received)`, a - :guilabel:`Current Assets` account type. They can also be set to the `Stock Interim - (Delivered)`, as long as the input and output accounts are assigned to the **same** - account. - - .. image:: inventory_valuation_config/continental-stock-account.png - :align: center - :alt: Show the Stock Input and Output accounts. - -Inventory valuation reporting -============================= - -To start, go to :menuselection:`Accounting app --> Reporting --> Balance Sheet`. Click the -:guilabel:`Current Assets` line item to unfold the drop-down menu, and look for the nested -:guilabel:`Stock Valuation`, :guilabel:`Stock Interim (Received)`, and :guilabel:`Stock Interim -(Delivered)` lines. - -.. tip:: - At the top of the dashboard, click the :guilabel:`As of [date]` button to display accounting - records up to a specified date. - -.. seealso:: - - :ref:`Stock accounts and what they do ` - - :doc:`../../../../finance/accounting/get_started/cheat_sheet` - -.. image:: inventory_valuation_config/stock-balance-sheet.png - :align: center - :alt: See the full inventory valuation breakdown in Odoo Accounting app. - -Access more specific information by clicking the :icon:`fa-ellipsis-v` :guilabel:`(ellipsis)` icon -to the right of the desired journal. Select :guilabel:`General Ledger` to see a list of all of the -journal entries, where each line item's :icon:`fa-ellipsis-v` :guilabel:`(ellipsis)` icon can be -clicked to reveal the :guilabel:`View Journal Entry` option to open the individualized journal -entry. - -Additionally, annotations to the :guilabel:`Balance Sheet` can be added by choosing -:guilabel:`Annotate`, filling in the text box, and clicking :guilabel:`Save`. - -.. image:: inventory_valuation_config/journals.png - :align: center - :alt: Show Stock Valuation journals in a list. diff --git a/content/applications/inventory_and_mrp/inventory/product_management/inventory_valuation/inventory_valuation_config/account-type.png b/content/applications/inventory_and_mrp/inventory/product_management/inventory_valuation/inventory_valuation_config/account-type.png deleted file mode 100644 index f1e18d637b..0000000000 Binary files a/content/applications/inventory_and_mrp/inventory/product_management/inventory_valuation/inventory_valuation_config/account-type.png and /dev/null differ diff --git a/content/applications/inventory_and_mrp/inventory/product_management/inventory_valuation/inventory_valuation_config/anglo-saxon.png b/content/applications/inventory_and_mrp/inventory/product_management/inventory_valuation/inventory_valuation_config/anglo-saxon.png deleted file mode 100644 index e9317885a3..0000000000 Binary files a/content/applications/inventory_and_mrp/inventory/product_management/inventory_valuation/inventory_valuation_config/anglo-saxon.png and /dev/null differ diff --git a/content/applications/inventory_and_mrp/inventory/product_management/inventory_valuation/inventory_valuation_config/auto-accounting.png b/content/applications/inventory_and_mrp/inventory/product_management/inventory_valuation/inventory_valuation_config/auto-accounting.png deleted file mode 100644 index ced02e4ef3..0000000000 Binary files a/content/applications/inventory_and_mrp/inventory/product_management/inventory_valuation/inventory_valuation_config/auto-accounting.png and /dev/null differ diff --git a/content/applications/inventory_and_mrp/inventory/product_management/inventory_valuation/inventory_valuation_config/automated-inventory-valuation.png b/content/applications/inventory_and_mrp/inventory/product_management/inventory_valuation/inventory_valuation_config/automated-inventory-valuation.png deleted file mode 100644 index 43e3f8a9a2..0000000000 Binary files a/content/applications/inventory_and_mrp/inventory/product_management/inventory_valuation/inventory_valuation_config/automated-inventory-valuation.png and /dev/null differ diff --git a/content/applications/inventory_and_mrp/inventory/product_management/inventory_valuation/inventory_valuation_config/continental-stock-account.png b/content/applications/inventory_and_mrp/inventory/product_management/inventory_valuation/inventory_valuation_config/continental-stock-account.png deleted file mode 100644 index 152660e9d3..0000000000 Binary files a/content/applications/inventory_and_mrp/inventory/product_management/inventory_valuation/inventory_valuation_config/continental-stock-account.png and /dev/null differ diff --git a/content/applications/inventory_and_mrp/inventory/product_management/inventory_valuation/inventory_valuation_config/external-link.png b/content/applications/inventory_and_mrp/inventory/product_management/inventory_valuation/inventory_valuation_config/external-link.png deleted file mode 100644 index 9acc040dcf..0000000000 Binary files a/content/applications/inventory_and_mrp/inventory/product_management/inventory_valuation/inventory_valuation_config/external-link.png and /dev/null differ diff --git a/content/applications/inventory_and_mrp/inventory/product_management/inventory_valuation/inventory_valuation_config/inventory-valuation-fields.png b/content/applications/inventory_and_mrp/inventory/product_management/inventory_valuation/inventory_valuation_config/inventory-valuation-fields.png deleted file mode 100644 index 1d196bb1fd..0000000000 Binary files a/content/applications/inventory_and_mrp/inventory/product_management/inventory_valuation/inventory_valuation_config/inventory-valuation-fields.png and /dev/null differ diff --git a/content/applications/inventory_and_mrp/inventory/product_management/inventory_valuation/inventory_valuation_config/journals.png b/content/applications/inventory_and_mrp/inventory/product_management/inventory_valuation/inventory_valuation_config/journals.png deleted file mode 100644 index 697bd9a013..0000000000 Binary files a/content/applications/inventory_and_mrp/inventory/product_management/inventory_valuation/inventory_valuation_config/journals.png and /dev/null differ diff --git a/content/applications/inventory_and_mrp/inventory/product_management/inventory_valuation/inventory_valuation_config/manual-anglo-saxon-expense.png b/content/applications/inventory_and_mrp/inventory/product_management/inventory_valuation/inventory_valuation_config/manual-anglo-saxon-expense.png deleted file mode 100644 index 3a95c3d4b0..0000000000 Binary files a/content/applications/inventory_and_mrp/inventory/product_management/inventory_valuation/inventory_valuation_config/manual-anglo-saxon-expense.png and /dev/null differ diff --git a/content/applications/inventory_and_mrp/inventory/product_management/inventory_valuation/inventory_valuation_config/stock-balance-sheet.png b/content/applications/inventory_and_mrp/inventory/product_management/inventory_valuation/inventory_valuation_config/stock-balance-sheet.png deleted file mode 100644 index 5877c34e9a..0000000000 Binary files a/content/applications/inventory_and_mrp/inventory/product_management/inventory_valuation/inventory_valuation_config/stock-balance-sheet.png and /dev/null differ diff --git a/content/applications/inventory_and_mrp/inventory/product_management/inventory_valuation/using_inventory_valuation.rst b/content/applications/inventory_and_mrp/inventory/product_management/inventory_valuation/using_inventory_valuation.rst deleted file mode 100644 index c0e7f920c2..0000000000 --- a/content/applications/inventory_and_mrp/inventory/product_management/inventory_valuation/using_inventory_valuation.rst +++ /dev/null @@ -1,178 +0,0 @@ -========================= -Using inventory valuation -========================= - -.. _inventory/reporting/using_inventory_val: - -*Inventory valuation* is a quintessential accounting procedure that calculates the value of on-hand -stock. Once determined, the inventory valuation amount is then incorporated into a company's overall -value. - -In Odoo, this process can be conducted manually— by warehouse employees physically counting the -products— or automatically through the database. - -Automatic inventory valuation -============================= - -To use Odoo to automatically generate a trail of inventory valuation entries, first navigate to the -:menuselection:`Product Categories` list by going to :menuselection:`Inventory app --> Configuration ---> Product Categories` and select the desired product category. On the form, set the -:guilabel:`Inventory Valuation` as :guilabel:`Automated` and the :guilabel:`Costing Method` to any -of the three options. - -.. seealso:: - :doc:`Set up inventory valuation ` - -In order to understand how moving products in and out of stock affects the company's overall value, -consider the following product and stock moves scenario below. - -Receive a product ------------------ - -To track the value of incoming products, such as a simple *table*, configure the product category on -the the product itself. To get there, navigate to :menuselection:`Inventory app --> Products --> -Products` and click the desired product. On the product form, click the :guilabel:`➡️ (right arrow)` -icon beside the :guilabel:`Product Category` field, which opens an internal link to edit the product -category. Next, set the :guilabel:`Costing Method` as :guilabel:`First In First Out (FIFO)` and -:guilabel:`Inventory Valuation` as :guilabel:`Automated`. - -.. tip:: - Alternatively access the :guilabel:`Product Categories` dashboard by navigating to - :menuselection:`Inventory app --> Configuration --> Product Categories` and select the desired - product category. - -Next, assume 10 tables are purchased at a price of $10.00, each. The :abbr:`PO (Purchase Order)` for -those tables will show the subtotal of the purchase as $100, plus any additional costs or taxes. - -.. image:: using_inventory_valuation/purchase-order.png - :align: center - :alt: Purchase order with 10 tables products valued at $10.00 each. - -After selecting :guilabel:`Validate` on the :abbr:`PO (Purchase Order)`, the :guilabel:`Valuation` -smart button is enabled. Clicking on this button displays a report showing how the inventory -valuation for the table was affected by this purchase. - -.. important:: - :ref:`Developer mode ` **must** be turned on to see the :guilabel:`Valuation` - smart button. - -.. tip:: - The :doc:`consignment <../../shipping_receiving/daily_operations/owned_stock>` feature allows - ownership to items in stock. Thus, products owned by other companies are not accounted for in the - host company's inventory valuation. - -.. image:: using_inventory_valuation/valuation-smart-button.png - :align: center - :alt: See Valuation smart button on a receipt, with Developer mode enabled. - -For a comprehensive dashboard that includes the inventory valuation of all product shipments, -inventory adjustments, and warehouse operations, refer to the :ref:`stock valuation report -`. - -Deliver a product ------------------ - -In the same logic, when a table is shipped to a customer and leaves the warehouse, the stock -valuation decreases. The :guilabel:`Valuation` smart button on the :abbr:`DO (Delivery Order)`, -likewise, displays the stock valuation record as it does on a :abbr:`PO (Purchase Order)`. - -.. image:: using_inventory_valuation/decreased-stock-valuation.png - :align: center - :alt: Decreased stock valuation after a product is shipped. - -.. _inventory/management/reporting/valuation-report: - -Inventory valuation report -========================== - -To view the current value of all products in the warehouse, first turn on :ref:`Developer mode -` and navigate to :menuselection:`Inventory app --> Reporting --> Valuation`. The -:guilabel:`Stock Valuation` dashboard displays detailed records of products with the -:guilabel:`Date`, :guilabel:`Quantity`, :guilabel:`Unit Value`, and :guilabel:`Total Value` of the -inventory. - -.. important:: - :ref:`Developer mode ` **must** be enabled to see the :guilabel:`Valuation` - option under :guilabel:`Reporting`. - -.. image:: using_inventory_valuation/inventory-valuation-products.png - :align: center - :alt: Inventory valuation report showing multiple products. - -The :guilabel:`Valuation At Date` button, located in the top-left corner of the :guilabel:`Stock -Valuation` page, reveals a pop-up window. In this pop-up, the inventory valuation of products -available during a prior specified date can be seen and selected. - -.. tip:: - View a detailed record of a product's inventory value, stock move, and on-hand stock by selecting - the teal :guilabel:`➡️ (right arrow)` button to the right of the :guilabel:`Reference` column - value. - -.. _inventory/product_management/update-unit-price: - -Update product unit price -------------------------- - -For any company: lead times, supply chain failures, and other risk factors can contribute to -invisible costs. Although Odoo attempts to accurately represent the stock value, *manual valuation* -serves as an additional tool to update the unit price of products. - -.. important:: - Manual valuation is intended for products that can be purchased and received for a cost greater - than 0, or have product categories set with :guilabel:`Costing Method` set as either - :guilabel:`Average Cost (AVCO)` or :guilabel:`First In First Out (FIFO)`. - -.. image:: using_inventory_valuation/add-manual-valuation.png - :align: center - :alt: Add manual valuation of stock value to a product. - -Create manual valuation entries on the :guilabel:`Stock Valuation` dashboard by first navigating to -:menuselection:`Inventory app --> Reporting --> Valuation`. Next, to enable the *product -revaluation* feature, select :menuselection:`Group by --> Product` to organize all the records by -product. Click on the gray :guilabel:`▶️ (drop-down triangle)` icon to reveal stock valuation line -items below, as well as a teal :guilabel:`➕ (plus)` button on the right. - -Click the teal :guilabel:`+ (plus)` button to open up the :guilabel:`Product Revaluation` form. -Here, the inventory valuation for a product can be recalculated, by increasing or decreasing the -unit price of each product. - -.. note:: - The :guilabel:`▶️ (drop-down triangle)` and :guilabel:`➕ (plus)` buttons are only visible after - grouping entries by product. - -.. image:: using_inventory_valuation/product-revaluation.png - :align: center - :alt: Product revaluation form adding a value of $1.00 with the reason being inflation. - -Inventory valuation journal entries ------------------------------------ - -In Odoo, automatic inventory valuation records are also recorded in the :menuselection:`Accounting -app --> Accounting --> Journal Entries` dashboard. On this comprehensive list of accounting entries, -inventory valuation records are identified by checking values in the :guilabel:`Journal` column, or -looking for the :guilabel:`Reference` column value which matches the warehouse operation reference -(e.g. `WH/IN/00014` for receipts). - -Clicking on an inventory valuation journal entry opens a *double-entry accounting* record. These -records are generated by Odoo to track the change of value in inventory valuation as products are -moved in and out of the warehouse. - -.. example:: - To view the inventory valuation of 10 *tables*, costing $10.00 each, upon reception from the - vendor, go to the :menuselection:`Journal Entries` page found in :menuselection:`Accounting app - --> Accounting --> Journal Entries`. Here, click the journal line where the :guilabel:`Reference` - column value matches the reference on the receipt, `WH/IN/00014`. - - .. image:: using_inventory_valuation/stock-valuation-product.png - :align: center - :alt: Stock valuation page depicting the products within a shipment. - - `Stock interim` is a holding account for money intended to pay vendors for the product. The - `stock valuation` account stores the value of all on-hand stock. - - .. image:: using_inventory_valuation/inventory-valuation-entry.png - :align: center - :alt: Accounting entry for the inventory valuation of 10 tables. - -.. seealso:: - `Odoo Tutorial: Inventory Valuation `_ diff --git a/content/applications/inventory_and_mrp/inventory/product_management/inventory_valuation/using_inventory_valuation/add-manual-valuation.png b/content/applications/inventory_and_mrp/inventory/product_management/inventory_valuation/using_inventory_valuation/add-manual-valuation.png deleted file mode 100644 index 1ad0eb8df9..0000000000 Binary files a/content/applications/inventory_and_mrp/inventory/product_management/inventory_valuation/using_inventory_valuation/add-manual-valuation.png and /dev/null differ diff --git a/content/applications/inventory_and_mrp/inventory/product_management/inventory_valuation/using_inventory_valuation/decreased-stock-valuation.png b/content/applications/inventory_and_mrp/inventory/product_management/inventory_valuation/using_inventory_valuation/decreased-stock-valuation.png deleted file mode 100644 index e5230b7386..0000000000 Binary files a/content/applications/inventory_and_mrp/inventory/product_management/inventory_valuation/using_inventory_valuation/decreased-stock-valuation.png and /dev/null differ diff --git a/content/applications/inventory_and_mrp/inventory/product_management/inventory_valuation/using_inventory_valuation/inventory-valuation-entry.png b/content/applications/inventory_and_mrp/inventory/product_management/inventory_valuation/using_inventory_valuation/inventory-valuation-entry.png deleted file mode 100644 index c5e5ddb074..0000000000 Binary files a/content/applications/inventory_and_mrp/inventory/product_management/inventory_valuation/using_inventory_valuation/inventory-valuation-entry.png and /dev/null differ diff --git a/content/applications/inventory_and_mrp/inventory/product_management/inventory_valuation/using_inventory_valuation/inventory-valuation-products.png b/content/applications/inventory_and_mrp/inventory/product_management/inventory_valuation/using_inventory_valuation/inventory-valuation-products.png deleted file mode 100644 index 8123e1ccea..0000000000 Binary files a/content/applications/inventory_and_mrp/inventory/product_management/inventory_valuation/using_inventory_valuation/inventory-valuation-products.png and /dev/null differ diff --git a/content/applications/inventory_and_mrp/inventory/product_management/inventory_valuation/using_inventory_valuation/product-revaluation.png b/content/applications/inventory_and_mrp/inventory/product_management/inventory_valuation/using_inventory_valuation/product-revaluation.png deleted file mode 100644 index 26d6bf7815..0000000000 Binary files a/content/applications/inventory_and_mrp/inventory/product_management/inventory_valuation/using_inventory_valuation/product-revaluation.png and /dev/null differ diff --git a/content/applications/inventory_and_mrp/inventory/product_management/inventory_valuation/using_inventory_valuation/purchase-order.png b/content/applications/inventory_and_mrp/inventory/product_management/inventory_valuation/using_inventory_valuation/purchase-order.png deleted file mode 100644 index ba1579c6e6..0000000000 Binary files a/content/applications/inventory_and_mrp/inventory/product_management/inventory_valuation/using_inventory_valuation/purchase-order.png and /dev/null differ diff --git a/content/applications/inventory_and_mrp/inventory/product_management/inventory_valuation/using_inventory_valuation/stock-valuation-product.png b/content/applications/inventory_and_mrp/inventory/product_management/inventory_valuation/using_inventory_valuation/stock-valuation-product.png deleted file mode 100644 index 46bd6017fd..0000000000 Binary files a/content/applications/inventory_and_mrp/inventory/product_management/inventory_valuation/using_inventory_valuation/stock-valuation-product.png and /dev/null differ diff --git a/content/applications/inventory_and_mrp/inventory/product_management/inventory_valuation/using_inventory_valuation/valuation-smart-button.png b/content/applications/inventory_and_mrp/inventory/product_management/inventory_valuation/using_inventory_valuation/valuation-smart-button.png deleted file mode 100644 index 90dea63caa..0000000000 Binary files a/content/applications/inventory_and_mrp/inventory/product_management/inventory_valuation/using_inventory_valuation/valuation-smart-button.png and /dev/null differ diff --git a/content/applications/inventory_and_mrp/inventory/warehouses_storage/inventory_management.rst b/content/applications/inventory_and_mrp/inventory/warehouses_storage/inventory_management.rst index 71a5bc35e9..ac5ef70f4b 100644 --- a/content/applications/inventory_and_mrp/inventory/warehouses_storage/inventory_management.rst +++ b/content/applications/inventory_and_mrp/inventory/warehouses_storage/inventory_management.rst @@ -64,8 +64,7 @@ field, there are: View locations should **not** contain products, but it is possible to move them there. - :guilabel:`Internal Location`: storage locations within the warehouse. Items stored in these - locations are accounted for in :doc:`inventory valuation - <../product_management/inventory_valuation/using_inventory_valuation>`. + locations are accounted for in :doc:`inventory valuation <../inventory_valuation/cheat_sheet>`. - :guilabel:`Customer Location`: where sold products are tracked; items here are no longer in stock. @@ -110,10 +109,9 @@ Odoo databases include preconfigured view locations to organize the hierarchy of provide helpful context, and distinguish between internal and external locations. - *Physical locations* group internal locations—such as secondary warehouses and subcontractor - sites. Because :doc:`inventory valuation - <../product_management/inventory_valuation/inventory_valuation_config>` changes only when goods - move from internal to external locations, Odoo uses physical locations to track stock that is - off-site or in transit without affecting valuation. + sites. Because :doc:`inventory valuation <../inventory_valuation/cheat_sheet>` changes only when + goods move from internal to external locations, Odoo uses physical locations to track stock that + is off-site or in transit without affecting valuation. .. _inventory/warehouses_storage/interwarehouse-transit: diff --git a/content/applications/inventory_and_mrp/inventory/warehouses_storage/replenishment/reordering_rules.rst b/content/applications/inventory_and_mrp/inventory/warehouses_storage/replenishment/reordering_rules.rst index 70ba3edcfc..f25947b51c 100644 --- a/content/applications/inventory_and_mrp/inventory/warehouses_storage/replenishment/reordering_rules.rst +++ b/content/applications/inventory_and_mrp/inventory/warehouses_storage/replenishment/reordering_rules.rst @@ -422,7 +422,7 @@ Example where visibility days is triggered ------------------------------------------ A product shipped from Asia has a combined vendor lead time of 30 days and a shipping cost of $100 -(including :doc:`landed costs <../../product_management/inventory_valuation/landed_costs>` and +(including :doc:`landed costs <../../inventory_valuation/landed_costs>` and tariffs). - November 4: Current date. The forecasted date is December 4 (30 days later). diff --git a/content/applications/inventory_and_mrp/inventory/warehouses_storage/reporting/aging.rst b/content/applications/inventory_and_mrp/inventory/warehouses_storage/reporting/aging.rst index 07f35adafb..989f4afce8 100644 --- a/content/applications/inventory_and_mrp/inventory/warehouses_storage/reporting/aging.rst +++ b/content/applications/inventory_and_mrp/inventory/warehouses_storage/reporting/aging.rst @@ -11,8 +11,8 @@ assigning a monetary value to account for inventory is known as *stock valuation This value is often reported for accounting purposes. For instance, an insurance company may want to know the value of goods stored in a warehouse, in the event of a flood or fire. -:doc:`Stock valuation <../../product_management/inventory_valuation/using_inventory_valuation>` -typically utilizes one of two accounting systems: +:doc:`Stock valuation <../../inventory_valuation/cheat_sheet>` typically utilizes one of two +accounting systems: - **Perpetual**: The inventory is constantly (perpetually) being updated, and the value is constantly changing. @@ -21,11 +21,10 @@ typically utilizes one of two accounting systems: Using :ref:`tracked inventory ` in Odoo necessitates a *perpetual* inventory accounting system because of the need to know when and where -inventory exists, and how much of it is available or forecasted. There are a few common :ref:`stock -valuation methods ` used in Odoo: *standard price*, -*average cost* (AVCO), and *first in, first out* (FIFO) accounting. It is important to know that the -valuation method chosen for a product impacts the calculation of several fields in the stock -valuation reports. +inventory exists, and how much of it is available or forecasted. There are a few common valuation +methods used in Odoo: *standard price*, *average cost* (AVCO), and *first in, first out* (FIFO) +accounting. It is important to know that the valuation method chosen for a product impacts the +calculation of several fields in the stock valuation reports. Open the dashboard ================== diff --git a/content/applications/inventory_and_mrp/inventory/warehouses_storage/reporting/stock.rst b/content/applications/inventory_and_mrp/inventory/warehouses_storage/reporting/stock.rst index ab05ea58cd..e5533a5c4e 100644 --- a/content/applications/inventory_and_mrp/inventory/warehouses_storage/reporting/stock.rst +++ b/content/applications/inventory_and_mrp/inventory/warehouses_storage/reporting/stock.rst @@ -36,8 +36,7 @@ In the report itself, the columns represent: .. seealso:: - :ref:`Compute average cost inventory valuation per unit ` - - :doc:`Inventory valuation methods - <../../product_management/inventory_valuation/inventory_valuation_config>` + - :doc:`Inventory valuation methods <../../inventory_valuation/cheat_sheet>` - :guilabel:`On Hand`: current quantity of products. Click the :icon:`fa-pencil` :guilabel:`(pencil)` icon to :doc:`modify the on-hand quantity diff --git a/redirects/19.0.txt b/redirects/19.0.txt index 61abb8765d..8083b183b9 100644 --- a/redirects/19.0.txt +++ b/redirects/19.0.txt @@ -1,3 +1,10 @@ # applications/websites applications/websites/ecommerce/payments.rst applications/websites/ecommerce/checkout.rst + +# applications/inventory_and_mrp + +applications/inventory_and_mrp/inventory/product_management/inventory_valuation/landed_costs.rst applications/inventory_and_mrp/inventory/inventory_valuation/landed_costs.rst +applications/inventory_and_mrp/inventory/product_management/inventory_valuation/inventory_valuation_config.rst applications/inventory_and_mrp/inventory/inventory_valuation/cheat_sheet.rst +applications/inventory_and_mrp/inventory/product_management/inventory_valuation/using_inventory_valuation.rst applications/inventory_and_mrp/inventory/inventory_valuation/cheat_sheet.rst +applications/inventory_and_mrp/inventory/product_management/inventory_valuation/valuation_by_lots.rst applications/inventory_and_mrp/inventory/inventory_valuation/valuation_by_lots.rst diff --git a/static/css/accounting.css b/static/css/accounting.css index 0d1f188118..142b814ca8 100644 --- a/static/css/accounting.css +++ b/static/css/accounting.css @@ -106,13 +106,6 @@ label:hover, font-style: normal; } -.values-table tr > * { - text-align: right; -} -.values-table tr > :first-child { - text-align: left; -} - /* 3-column (thing, debit, credit) tables */ /* 2nd and 3rd th & td of each row right-aligned and 1/4th width */ .d-c-table tr > :nth-child(2), @@ -139,21 +132,7 @@ label:hover, background-color: #eee !important; color: #7A436B !important; } - - .chart-of-accounts .highlight-op, - .valuation-chart .highlight-op { - background-color: #030035; - border-bottom: 1px solid #000000 !important; - } - - .chart-of-accounts .highlight-op, - .valuation-chart-continental .highlight-op { - background-color: #030035; - border-bottom: 1px solid #000000 !important; - } - - .chart-of-accounts .highlight-op, - .valuation-chart-anglo-saxon .highlight-op { + .chart-of-accounts .highlight-op { background-color: #030035; border-bottom: 1px solid #000000 !important; } @@ -217,17 +196,3 @@ blockquote.highlights, blockquote.highlights p{ margin-bottom: 1rem; text-align: center; } - -/* - lists of alternatives -*/ -.alternatives-controls label { - display: block; -} -dl.alternatives > dt, -dl.alternatives > dd { - display: none; -} -dl.alternatives > dd { - margin-left: 0; -} diff --git a/static/css/valuation.css b/static/css/valuation.css new file mode 100644 index 0000000000..8ebbd064d1 --- /dev/null +++ b/static/css/valuation.css @@ -0,0 +1,128 @@ +/* Used in valuation cheat_sheet.rst */ + +/* Prevent titles from wrapping upwards */ +h3 { clear: both !important; } + +.full-width { width: 100% !important; } + +.accounting-entries, .journal-entries, .values-table { + border: 1px solid #d5d5d5; + background-color: #f8f8f8; + margin: 0px auto; +} + +/* Costing methods table - see misc.js */ +.alternatives-controls { + padding-bottom: 24px; + label { + display: block; + } +} +dl.alternatives > dt { + display: none; +} +dl.alternatives > dd { + display: none; + margin-left: 0; +} +.values-table { + text-align: right; + tr > th:first-of-type { + text-align: left; + } +} + +/* Accounting methods table - see valuation-accounting.js */ +.accounting-entries { + th, td { + padding-top: 0px !important; + padding-bottom: 0px !important; + } + thead th, tr > td { + padding-left: 48px; + } + tbody th { + font-weight: normal; + } + .parent-line { background-color: #fafafa; } + .child-line { background-color: #f0f0f0; } +} +.entries-listing { + padding: .5rem; +} +#accounting-entries-controls label, +#journaling-entries-controls label { + display: block; +} + +/* Highlighting of selected options - see misc.js */ +label:hover, .highlighter-list li:hover { + background-color: hsl(0, 0%, 94%); + cursor: pointer; +} +.related { + background-color: hsl(317deg 16% 90%) !important; + border: 1px solid #000000 !important; + transition: .3s; +} +.secondary { + background-color: hsl(180deg 67% 94%) !important; + transition: .3s; +} +.highlight-op { + background-color: hsl(317deg 16% 90%) !important; + transition: .3s; +} +.highlighter-target { + th { + font-weight: 400; + } + .related { + /*background-color: #eee !important;*/ + color: #7A436B !important; + } + .secondary { + background-color: #eee !important; + color: #7A436B !important; + } +} + +/* Static tables */ +.feature-table, .config-table { + table { + /* width: unset; */ + margin: auto; + white-space: nowrap; + text-align: center; + } + tbody td:first-child { + text-align: left; + } +} +.config-table { + font-size: 90%; +} + +.accounting-app-paragraph:hover ~ .feature-table tr > td:first-child:has(+ td .good), +.inventory-app-paragraph:hover ~ .feature-table tr > td:first-child:has(+ td + td .good) +{ font-weight: bold; } + +.feature-table { + td { width: 32px; } + td:has(.good) { background-color: #d9ead3 !important; } + td:has(.meh) { background-color: #fce5cd !important; } + td:has(.bad) { background-color: #f4cccc !important; } +} +.config-table { + th, td { + padding-top: 0px !important; + padding-bottom: 0px !important; + } + td:has(.washed) { color: var(--bs-gray); } +} + +.yellow, td:has(.yellow), th:has(.yellow) { background-color: #fff2cc !important; } +.green, td:has(.green), th:has(.green) { background-color: #d9ead3 !important; } +.blue, td:has(.blue), th:has(.blue) { background-color: #cfe2f3 !important; } +.darkblue, td:has(.darkblue), th:has(.darkblue) { background-color: #6d9eeb !important; } +.purple, td:has(.purple), th:has(.purple) { background-color: #d9d2e9 !important; } diff --git a/static/js/accounts.js b/static/js/accounts.js index f7ba5c7763..744cb3073e 100644 --- a/static/js/accounts.js +++ b/static/js/accounts.js @@ -1,6 +1,6 @@ /* global Immutable, React */ (function () { - // NOTE: used by cheat_sheet.rst + // NOTE: used by accounting cheat_sheet.rst 'use strict'; function highlight(primary, secondary) { diff --git a/static/js/chart-of-accounts.js b/static/js/chart-of-accounts.js index 960e8af53e..462bf5fdda 100644 --- a/static/js/chart-of-accounts.js +++ b/static/js/chart-of-accounts.js @@ -1,7 +1,7 @@ /* global Immutable, React */ /* global createAtom */ (function () { - // NOTE: used by cheat_sheet.rst + // NOTE: used by accounting cheat_sheet.rst 'use strict'; var data = createAtom(); diff --git a/static/js/entries.js b/static/js/entries.js index f6bbf20978..f30fdffb9d 100644 --- a/static/js/entries.js +++ b/static/js/entries.js @@ -2,7 +2,7 @@ /* global createAtom, findAncestor */ (function () { 'use strict'; - // NOTE: cheat_sheet.rst + // NOTE: used by accounting cheat_sheet.rst var data = createAtom(); data.addWatch('chart', function (k, m, prev, next) { diff --git a/static/js/misc.js b/static/js/misc.js index 1bc7cd3e3e..3966344502 100644 --- a/static/js/misc.js +++ b/static/js/misc.js @@ -6,7 +6,7 @@ }); function highlight() { - // NOTE: used by double-entry.rst + // NOTE: used by valuation cheat_sheet.rst $('.highlighter-list').each(function () { var $this = $(this), $target = $($this.data('target')); @@ -34,7 +34,7 @@ * - automatically select first control on startup */ function alternatives() { - // NOTE: used by double-entry.rst & valuation_methods pages + // NOTE: used by valuation cheat_sheet.rst $('dl.alternatives').each(function (index) { var $list = $(this), $contents = $list.children('dd'); @@ -51,7 +51,18 @@ label.appendChild(input); label.appendChild(document.createTextNode(' ')); - label.appendChild(document.createTextNode(this.textContent)); + + // Hack to bold the definition since we have to strip rST formatting + const [headText, tailText] = this.textContent.split(':', 2); + if (tailText) { + const bold = document.createElement('b'), + defined = document.createTextNode(`${headText}:`); + bold.appendChild(defined); + label.appendChild(bold); + } + + label.appendChild(document.createTextNode(tailText || headText)); + label.normalize(); return label; })) @@ -65,9 +76,10 @@ }) .find('input:first').click(); }); + $('.alternatives-note').insertAfter($('.alternatives-controls')); } function checks_handling() { - // NOTE: used by cheat_sheet.rst + // NOTE: used by accounting cheat_sheet.rst var $section = $('.checks-handling'); if (!$section.length) { return; } diff --git a/static/js/reconciliation.js b/static/js/reconciliation.js index 84c4ee07df..8925f95c0d 100644 --- a/static/js/reconciliation.js +++ b/static/js/reconciliation.js @@ -1,5 +1,5 @@ (function () { - // NOTE: cheat_sheet.rst + // NOTE: used by accounting cheat_sheet.rst document.addEventListener('DOMContentLoaded', function () { var $rec = $('#reconciliation .reconciliation-example'); if (!$rec.length) { return; } diff --git a/static/js/valuation-accounting.js b/static/js/valuation-accounting.js new file mode 100644 index 0000000000..98bc6db0d2 --- /dev/null +++ b/static/js/valuation-accounting.js @@ -0,0 +1,262 @@ +/* global Immutable, React */ +/* global createAtom */ +/* global VALUATION_{STANDARDS,METHODS,JOURNALS,ENTRIES,REVIEWS} */ +(function () { + 'use strict'; + // NOTE: used by valuation cheat_sheet.rst + + const selectedMode = createAtom(['continental', 'periodic']); + const selectedOps = createAtom(); + + function watch (next) { + React.render( + React.createElement(Controls, { p: next }), + document.getElementById('accounting-entries-controls')); + React.render( + React.createElement(Chart, { p: next }), + document.querySelector('.accounting-entries')); + } + + selectedOps.addWatch('chart', (k, m, prev, next) => watch(next)); + selectedMode.addWatch('chart', (k, m, prev, next) => watch(selectedOps.deref())); + + document.addEventListener('DOMContentLoaded', function () { + const chart = document.querySelector('.accounting-entries'); + if (!chart) { return; } + + const controls = document.createElement('div'); + controls.setAttribute('id', 'accounting-entries-controls'); + chart.parentNode.insertBefore(controls, chart); + + selectedOps.reset(Immutable.Map({ + // last-selected operation + active: null, + // set of all currently enabled operations + operations: Immutable.OrderedSet() + })); + }); + + function toKey(s, postfix) { + if (postfix) { + s += ' ' + postfix; + } + return s.replace(/[^0-9a-z ]/gi, '').toLowerCase().split(/\s+/).join('-'); + } + + const Controls = React.createClass({ + render: function () { + const state = this.props.p; + return React.DOM.div( + null, + React.DOM.b(null, "Choose a standard:"), + VALUATION_STANDARDS.map(function (item, index) { + return React.DOM.label( + { key: index }, + React.DOM.input({ + type: 'radio', + checked: item.get('name') === selectedMode.deref()[0], + onChange: function (e) { + const newValue = item.get('name'); + selectedMode.reset([newValue, newValue === 'continental' ? 'periodic' : 'perpetual']); + } + }), + ' ', + item.get('text') + ); + }), + React.DOM.br(), + React.DOM.b(null, "Choose an accounting method:"), + VALUATION_METHODS.map(function (item, index) { + return React.DOM.label( + { key: index }, + React.DOM.input({ + type: 'radio', + checked: item.get('name') === selectedMode.deref()[1], + onChange: e => selectedMode.swap(vals => [vals[0], item.get('name')]), + }), + ' ', + item.get('text') + ); + }), + React.DOM.br(), + React.DOM.b(null, "Activate operations to see the impact:"), + VALUATION_ENTRIES.map(function (item, key) { + return React.DOM.label( + { + key: key, + style: { display: 'block' }, + className: (key === state.get('active') ? 'highlight-op' : void 0) + }, + React.DOM.input({ + type: 'checkbox', + checked: state.get('operations').contains(key), + onChange: function (e) { + if (e.target.checked) { + selectedOps.swap(d => d.set('active', key) + .update('operations', ops => ops.add(key))); + } else { + selectedOps.swap(d => d.set('active', null) + .update('operations', ops => ops.remove(key))); + } + } + }), + ' ', + item.get('title') + ); + }), + React.DOM.br(), + "Closing", + VALUATION_REVIEWS.map(function (item, key) { + // We bold the text if any of the operations in this review is + // relevant to the currently selected operations. + const boldable = item.getIn([...selectedMode.deref(), 'operations']) + .some(function (op) { + if (!op.has('entries') && !op.has('except')) + return true; + const opset = state.get('operations').toSet(); + if (opset.isSuperset(op.get('entries', [])) + && opset.intersect(op.get('except', [])).isEmpty()) + return true; + }); + return React.DOM.label( + { + key: key, + style: { display: 'block' }, + className: (key === state.get('active') ? 'highlight-op' : void 0) + }, + React.DOM.input({ + type: 'checkbox', + checked: state.get('operations').contains(key), + onChange: function (e) { + if (e.target.checked) { + selectedOps.swap(d => d.set('active', key) + .update('operations', ops => ops.add(key))); + } else { + selectedOps.swap(d => d.set('active', null) + .update('operations', ops => ops.remove(key))); + } + } + }), + ' ', + boldable ? React.DOM.b(null, item.get('title')) : item.get('title'), + ); + }), + React.DOM.br(), + ); + } + }); + + const Chart = React.createClass({ + render: function () { + // Only used for highlighting cells. + const lastop = Immutable.Map( + this.props.p.get('active') + ? (VALUATION_ENTRIES.concat(VALUATION_REVIEWS) + .getIn([this.props.p.get('active'), ...selectedMode.deref(), 'operations'], Immutable.List())) + .map(op => [VALUATION_JOURNALS.getIn([selectedMode.deref()[0], ...op.get('account'), 'code']), + op.has('credit') ? 'credit' : 'debit']) + : Immutable.Map()); + return React.DOM.div( + null, + React.DOM.table( + { className: 'table table-condensed' }, + React.DOM.thead( + null, + React.DOM.tr( + null, + React.DOM.th(), + React.DOM.th({ className: 'text-right' }, "Debit"), + React.DOM.th({ className: 'text-right' }, "Credit"), + React.DOM.th({ className: 'text-right' }, "Balance")) + ), + React.DOM.tbody( + null, + this.accounts().map(function (data) { + // Don't highlight the cell if it's going to be empty. + const highlight = lastop.get(data.get('code')), + debit = format(data.get('debit')), + credit = format(data.get('credit')); + return React.DOM.tr( + { + key: data.get('code'), + className: data.get('level') ? 'parent-line' : 'child-line', + }, + React.DOM.th( + null, + data.get('level') ? '\u2001 ' : '', + data.get('code') || '', ' ', data.get('title') + ), + React.DOM.td( + { className: React.addons.classSet({ + 'text-right': true, + 'highlight-op': debit ? highlight === 'debit' : void 0 }) }, + debit), + React.DOM.td( + { className: React.addons.classSet({ + 'text-right': true, + 'highlight-op': credit ? highlight === 'credit' : void 0 }) }, + credit), + React.DOM.td( + { className: 'text-right' }, + ((data.get('debit') || data.get('credit')) + ? format(data.get('debit') - data.get('credit'), 0) + : ''), + ) + ); + }) + ) + ) + ); + }, + accounts: function() { + const currentOperations = this.props.p.get('operations'); + if (!currentOperations) + return null; + const totals = VALUATION_ENTRIES.concat(VALUATION_REVIEWS) + .filter((val, key) => currentOperations.includes(key)) + .valueSeq() + .flatMap(entry => entry.getIn([...selectedMode.deref(), 'operations'])) + .reduce(function (acc, op) { + // `entries' and `except' fields are explained in valuation-data.js (quod vide) + if (op.has('entries') || op.has('except')) { + const opset = currentOperations.toSet(); + if (!(opset.isSuperset(op.get('entries', [])) + && opset.intersect(op.get('except', [])).isEmpty())) { + return acc; + } + } + const code = VALUATION_JOURNALS.getIn([selectedMode.deref()[0], ...op.get('account'), 'code']); + return acc + .updateIn([code, 'debit'], + d => (d || 0) + op.get('debit', 0)) + .updateIn([code, 'credit'], + c => (c || 0) + op.get('credit', 0)); + }, Immutable.Map()); + return accounts.get(selectedMode.deref()[0]).map(account => + account.merge(account.get('accounts') + .map(code => totals.get(code, NULL)) + .reduce((acc, it) => acc.mergeWith((a, b) => a + b, it, NULL)))); + } + }); + + const NULL = Immutable.Map({ debit: 0, credit: 0 }); + const accounts = VALUATION_JOURNALS.map(method => method.toList().flatMap(function (cat) { + return Immutable.Seq.of(cat.set('level', 0)).concat(cat.filter(function (v, k) { + return k.toUpperCase() === k; + }).toIndexedSeq().map(function (acc) { return acc.set('level', 1) })); + }).map(function (account) { // add accounts: Seq to each account + return account.set( + 'accounts', + Immutable.Seq.of(account.get('code')).concat( + account.toIndexedSeq().map(function (val) { + return Immutable.Map.isMap(val) && val.get('code'); + }).filter(function (val) { return !!val; }) + ) + ); + })); + function format(val, def) { + if (!val) { return def === undefined ? '' : def; } + if (val % 1 === 0) { return val; } + return val.toFixed(2); + } +})(); diff --git a/static/js/valuation-data.js b/static/js/valuation-data.js new file mode 100644 index 0000000000..c8975b5787 --- /dev/null +++ b/static/js/valuation-data.js @@ -0,0 +1,1343 @@ +/* global Immutable */ +// NOTE: used by valuation-journal.js & valuation-accounting.js + +// Deep conversion with OrderedMap as default +Immutable.fromJSButOrdered = code => Immutable.fromJS(code, (key, value) => + Immutable.Iterable.isKeyed(value) ? value.toOrderedMap() : value.toList()); + +const VALUATION_STANDARDS = Immutable.fromJS([ + { name: 'continental', text: "Continental (Expenses = Purchase Expenses)" }, + { name: 'anglo_saxon', text: "Anglo-Saxon (Expenses = Cost of Goods Sold)" }, +]); + +const VALUATION_METHODS = Immutable.fromJS([ + { name: 'periodic', text: "Periodic: focuses on expenses by nature" }, + { name: 'perpetual', text: "Perpetual: focuses on inventory value" }, +]); + +const VALUATION_JOURNALS = Immutable.fromJSButOrdered({ + continental: { + EQUITY: { code: 1, title: "Equity and Liabilities" }, + ASSETS: { code: 2, title: "Fixed Assets" }, + STOCK: { + code: 3, title: "Stock (Current Assets)", + RAW: { code: 300000, title: "Inventory Raw Materials" }, + WIP: { code: 320000, title: "Work in Progress" }, + FINISHED_GOODS: { code: 330000, title: "Inventory Finished Goods" }, + GOODS_FOR_RESALE: { code: 340000, title: "Inventory Goods Purchase for Resale" }, + }, + LIABILITIES: { + code: 4, title: "Receivables and Payables", + CUSTOMERS: { code: 400000, title: "Customers" }, + VAT_RECOVERABLE: { code: 411000, title: "VAT Recoverable" }, + RECEIVABLE: { code: 414000, title: "Income Receivable" }, + SUPPLIERS: { code: 440000, title: "Suppliers" }, + INVOICES_UNRECEIVED: { code: 444000, title: "Invoices to Be Received" }, + VAT_PAYABLE: { code: 451000, title: "VAT Payable" }, + DEFERRED_CHARGES: { code: 490000, title: "Deferred Charges" }, + DEFERRED_INCOME: { code: 493000, title: "Deferred Income" }, + }, + CASH: { code: 5, title: "Financial Accounts and Cash" }, + EXPENSES: { + code: 6, title: "Expenses", + RAW: { code: 600000, title: "Raw Materials" }, + FINISHED: { code: 600200, title: "Cost of Finished Goods" }, + GOODS_FOR_RESALE: { code: 604000, title: "Goods for Resale" }, + CHANGE_IN_RAW: { code: 609000, title: "Decrease (Increase) in Stocks of Raw Materials" }, + CHANGE_IN_GOODS_FOR_RESALE: { code: 609400, title: "Decrease (Increase) in Stocks of Goods Purchased for Resale" }, + }, + REVENUES: { + code: 7, title: "Revenues", + SALES: { code: 700000, title: "Sales" }, + CHANGE_IN_WIP: { code: 712000, title: "Increase (Decrease) in Stocks of Work in Progress" }, + CHANGE_IN_FINISHED_GOODS: { code: 713000, title: "Increase (Decrease) in Stocks of Finished Goods" }, + }, + INITIAL_BALANCE: { code: 0, title: "General Balance for Inventory Initial Value" }, + }, + anglo_saxon: { + ASSETS: { + code: 1, title: "Assets", + BANK: { code: 101401, title: "Bank" }, + INVENTORY: { code: 110100, title: "Inventory" }, + RAW: { code: 110101, title: "Raw Materials Inventory" }, + MANUFACTURED: { code: 110102, title: "Manufactured Products Inventory" }, + COST: { code: 110400, title: "Cost of Production" }, + VARIATIONS: { code: 110600, title: "Inventory Variations" }, + RECEIVABLE: { code: 121000, title: "Accounts Receivable" }, + UNINVOICED: { code: 121200, title: "Uninvoiced Receivable" }, + PREPAID: { code: 128000, title: "Prepaid Expenses" }, + TAX_PAID: { code: 131000, title: "Tax Paid" }, + }, + LIABILITIES: { + code: 2, title: "Liabilities", + PAYABLE: { code: 211000, title: "Accounts Payable" }, + UNINVOICED: { + code: 211100, + title: "Bills to Receive/Goods Received Not Invoiced", + }, + DEFERRED: { code: 212000, title: "Deferred Revenue" }, + TAX_RECEIVED: { code: 251000, title: "Tax Received" }, + }, + EQUITY: { + code: 3, title: "Equity", + COMMON: { code: 303000, title: "Common Stock" }, + }, + REVENUES: { + code: 4, title: "Revenue", + SALES: { code: 400000, title: "Product Sales" }, + }, + EXPENSES: { + code: 5, title: "Expenses", + COST: { code: 500000, title: "Cost of Goods Sold" }, + PRICE_DIFFERENCE: { code: 530000, title: "Price Difference" }, + INVENTORY_LOSS: { code: 609100, title: "Inventory Loss Expense" }, + MISC: { code: 609000, title: "Miscellanous Expenses" }, + }, + INITIAL_BALANCE: { code: 0, title: "General Balance for Inventory Initial Value" }, + }, +}); + +/* Entry and review operations follow the following schema: + { name: { + title: "...", + continental: { + periodic: { + operations: [{ account: [...], // corresponds to the above table + debit OR credit: n, // mutually exclusive + entries: [...], // reviews only, optional [accounting only] + except: [...], // reviews only, optional [accounting only] + }, ...], + journal_operations: [...], // `closing' reviews only [journaling only] + explanation: [...], // [journaling only] + configuration: [...], // [journaling only] + }, + perpetual: { ditto }, + }, + anglo_saxon: { + periodic: { ditto }, + perpetual: { ditto }, + }, + }, + }, ... + See below for more on review operations. + */ +const VALUATION_ENTRIES = Immutable.fromJSButOrdered({ + initial_inventory: { + title: "Initial Inventory (Goods for Resale $50)", + continental: { + periodic: { + operations: [ + { account: ['STOCK', 'GOODS_FOR_RESALE'], debit: 50 }, + { account: ['INITIAL_BALANCE'], credit: 50 }, + ], + explanation: [], + configuration: [ + "Stock Account: defined on the product category", + ], + }, + perpetual: { + operations: [ + { account: ['STOCK', 'GOODS_FOR_RESALE'], debit: 50 }, + { account: ['INITIAL_BALANCE'], credit: 50 }, + ], + explanation: [], + configuration: [ + "Stock Account: defined on the product category", + ], + }, + }, + anglo_saxon: { + periodic: { + operations: [ + { account: ['ASSETS', 'INVENTORY'], debit: 50 }, + { account: ['INITIAL_BALANCE'], credit: 50 }, + ], + explanation: [], + configuration: [ + "Stock Account: defined on the product category", + ], + }, + perpetual: { + operations: [ + { account: ['ASSETS', 'INVENTORY'], debit: 50 }, + { account: ['INITIAL_BALANCE'], credit: 50 }, + ], + explanation: [], + configuration: [ + "Stock Account: defined on the product category", + ], + }, + }, + }, + supplier_reception: { + title: "Supplier Goods Reception (PO $50, Bill $50)", + continental: { + periodic: { + operations: [], + explanation: [ + "In a periodic inventory valuation, goods' receipts are not directly posted in the accounting.", + "The inventory value is updated when entries are generated from stock valuation report at closing.", + ], + configuration: [], + }, + perpetual: { + operations: [], + explanation: [ + "In a perpetual inventory valuation, goods receipts are not directly posted in the accounting.", + "The inventory value is updated:", + "- when the invoice/bill is posted", + "- when entries are generated from stock valuation report at closing", + ], + configuration: [], + }, + }, + anglo_saxon: { + periodic: { + operations: [], + explanation: [ + "In a periodic inventory valuation, goods' receipts are not directly posted in the accounting.", + "The inventory value is updated when entries are generated from stock valuation report at closing.", + ], + configuration: [], + }, + perpetual: { + operations: [], + explanation: [ + "In a perpetual inventory valuation, goods receipts are not directly posted in the accounting.", + "The inventory value is updated:", + "- when the invoice/bill is posted", + "- when entries are generated from stock valuation report at closing", + ], + configuration: [], + }, + }, + }, + supplier_bill: { + title: "Supplier Bill (PO $50, Bill $50)", + continental: { + periodic: { + operations: [ + { account: ['EXPENSES', 'GOODS_FOR_RESALE'], debit: 50 }, + { account: ['LIABILITIES', 'SUPPLIERS'], credit: 54.5 }, + { account: ['LIABILITIES', 'VAT_RECOVERABLE'], debit: 4.5 }, + ], + explanation: [], + configuration: [ + "Account Payable: defined on the supplier contact", + "Tax Account: defined on the account from the Purchase Taxes set on the product", + "Expense Account: defined on the product/product category", + ], + }, + perpetual: { + operations: [ + { account: ['STOCK', 'GOODS_FOR_RESALE'], debit: 50 }, + { account: ['LIABILITIES', 'SUPPLIERS'], credit: 54.5 }, + { account: ['LIABILITIES', 'VAT_RECOVERABLE'], debit: 4.5 }, + ], + explanation: [], + configuration: [ + "Stock Account: defined on the product category", + "Account Payable Account: defined on the supplier contact", + "Tax Account: defined on the account from the Purchase Taxes set on the product", + ], + }, + }, + anglo_saxon: { + periodic: { + operations: [ + { account: ['EXPENSES', 'COST'], debit: 50 }, + { account: ['LIABILITIES', 'PAYABLE'], credit: 54.5 }, + { account: ['ASSETS', 'TAX_PAID'], debit: 4.5 }, + ], + explanation: [], + configuration: [ + "Account Payable: defined on the supplier contact", + "Tax Account: defined on the account from the Purchase Taxes set on the product", + "Expense Account: defined on the product/product category", + ], + }, + perpetual: { + operations: [ + { account: ['ASSETS', 'INVENTORY'], debit: 50 }, + { account: ['LIABILITIES', 'PAYABLE'], credit: 54.5 }, + { account: ['ASSETS', 'TAX_PAID'], debit: 4.5 }, + ], + explanation: [], + configuration: [ + "Account Payable: defined on the supplier contact", + "Tax Account: defined on the account from the Purchase Taxes set on the product", + "Expense Account: defined on the product/product category", + ], + }, + }, + }, + supplier_reception_extra: { + title: "Supplier Goods Reception (PO $48, Bill $50)", + continental: { + periodic: { + operations: [], + explanation: [ + "In a periodic inventory valuation, goods' receipts are not directly posted in the accounting.", + "The inventory value is updated when entries are generated from stock valuation report at closing.", + ], + configuration: [], + }, + perpetual: { + operations: [], + explanation: [ + "In a perpetual inventory valuation, goods receipts are not directly posted in the accounting.", + "The inventory value is updated:", + "- when the invoice/bill is posted", + "- when entries are generated from stock valuation report at closing", + ], + configuration: [], + }, + }, + anglo_saxon: { + periodic: { + operations: [], + explanation: [ + "In a periodic inventory valuation, goods' receipts are not directly posted in the accounting.", + "The inventory value is updated when entries are generated from stock valuation report at closing.", + ], + configuration: [], + }, + perpetual: { + operations: [], + explanation: [ + "In a perpetual inventory valuation, goods receipts are not directly posted in the accounting.", + "The inventory value is updated:", + "- when the invoice/bill is posted", + "- when entries are generated from stock valuation report at closing", + ], + configuration: [], + }, + }, + }, + supplier_bill_extra: { + title: "Supplier Bill (PO $48, Bill $50)", + continental: { + periodic: { + operations: [ + { account: ['EXPENSES', 'GOODS_FOR_RESALE'], debit: 50 }, + { account: ['LIABILITIES', 'SUPPLIERS'], credit: 54.5 }, + { account: ['LIABILITIES', 'VAT_RECOVERABLE'], debit: 4.5 }, + ], + explanation: [], + configuration: [ + "Account Payable: defined on the supplier contact", + "Tax Account: defined on the account from the Purchase Taxes set on the product", + "Expense Account: defined on the product/product category", + ], + }, + perpetual: { + operations: [ + { account: ['STOCK', 'GOODS_FOR_RESALE'], debit: 50 }, + { account: ['LIABILITIES', 'SUPPLIERS'], credit: 54.5 }, + { account: ['LIABILITIES', 'VAT_RECOVERABLE'], debit: 4.5 }, + ], + explanation: [], + configuration: [ + "Stock Account: defined on the product category", + "Account Payable Account: defined on the supplier contact", + "Tax Account: defined on the account from the Purchase Taxes set on the product", + ], + }, + }, + anglo_saxon: { + periodic: { + operations: [ + { account: ['EXPENSES', 'COST'], debit: 50 }, + { account: ['LIABILITIES', 'PAYABLE'], credit: 54.5 }, + { account: ['ASSETS', 'TAX_PAID'], debit: 4.5 }, + ], + explanation: [], + configuration: [ + "Account Payable: defined on the supplier contact", + "Tax Account: defined on the account from the Purchase Taxes set on the product", + "Expense Account: defined on the product/product category", + ], + }, + perpetual: { + operations: [ + { account: ['ASSETS', 'INVENTORY'], debit: 50 }, + { account: ['LIABILITIES', 'PAYABLE'], credit: 54.5 }, + { account: ['ASSETS', 'TAX_PAID'], debit: 4.5 }, + ], + explanation: [], + configuration: [ + "Account Payable: defined on the supplier contact", + "Tax Account: defined on the account from the Purchase Taxes set on the product", + "Expense Account: defined on the product/product category", + ], + }, + }, + }, + customer_shipping: { + title: "Customer Shipping (SO $100, Invoice $100, Good Value $50)", + continental: { + periodic: { + operations: [], + explanation: [ + "In a periodic inventory valuation, goods shipments are not directly posted in the accounting.", + "The inventory value is updated when entries are generated from stock valuation report at closing.", + ], + configuration: [], + }, + perpetual: { + operations: [], + explanation: [ + "In a perpetual inventory valuation, goods shipments are not directly posted in the accounting.", + "The inventory value is updated:", + "- when the invoice/bill is posted", + "- when entries are generated from stock valuation report at closing", + ], + configuration: [], + }, + }, + anglo_saxon: { + periodic: { + operations: [], + explanation: [ + "In a periodic inventory valuation, goods shipments are not directly posted in the accounting.", + "The inventory value is updated when entries are generated from stock valuation report at closing.", + ], + configuration: [], + }, + perpetual: { + operations: [], + explanation: [ + "In a perpetual inventory valuation, goods shipments are not directly posted in the accounting.", + "The inventory value is updated:", + "- when the invoice/bill is posted", + "- when entries are generated from stock valuation report at closing", + ], + configuration: [], + }, + }, + }, + customer_invoice: { + title: "Customer Invoice (SO $100, Invoice $100, Good Value $50)", + continental: { + periodic: { + operations: [ + { account: ['LIABILITIES', 'CUSTOMERS'], debit: 109 }, + { account: ['LIABILITIES', 'VAT_PAYABLE'], credit: 9 }, + { account: ['REVENUES', 'SALES'], credit: 100 }, + ], + explanation: [], + configuration: [ + "Account Receivable Account: defined on the customer contact", + "Tax Account: defined on the account from the Sales Taxes set on the product", + "Income Account: defined on the product/product category", + ], + }, + perpetual: { + operations: [ + { account: ['STOCK', 'GOODS_FOR_RESALE'], credit: 50 }, + { account: ['EXPENSES', 'GOODS_FOR_RESALE'], debit: 50 }, + { account: ['LIABILITIES', 'CUSTOMERS'], debit: 109 }, + { account: ['LIABILITIES', 'VAT_PAYABLE'], credit: 9 }, + { account: ['REVENUES', 'SALES'], credit: 100 }, + ], + explanation: [], + configuration: [ + "Stock Account: defined on the product category", + "Expense/COGS Account: defined on the product/product category", + "Account Receivable Account: defined on the customer contact", + "Tax Account: defined on the account from the Sales Taxes set on the product", + "Income Account: defined on the product/product category", + ], + }, + }, + anglo_saxon: { + periodic: { + operations: [ + { account: ['ASSETS', 'RECEIVABLE'], debit: 109 }, + { account: ['LIABILITIES', 'TAX_RECEIVED'], credit: 9 }, + { account: ['REVENUES', 'SALES'], credit: 100 }, + ], + explanation: [], + configuration: [ + "Account Receivable Account: defined on the customer contact", + "Tax Account: defined on the account from the Sales Taxes set on the product", + "Income Account: defined on the product/product category", + ], + }, + perpetual: { + operations: [ + { account: ['ASSETS', 'INVENTORY'], credit: 50 }, + { account: ['EXPENSES', 'COST'], debit: 50 }, + { account: ['ASSETS', 'RECEIVABLE'], debit: 109 }, + { account: ['LIABILITIES', 'TAX_RECEIVED'], credit: 9 }, + { account: ['REVENUES', 'SALES'], credit: 100 }, + ], + explanation: [], + configuration: [ + "Stock Account: defined on the product category", + "Expense/COGS Account: defined on the product/product category", + "Account Receivable Account: defined on the customer contact", + "Tax Account: defined on the account from the Sales Taxes set on the product", + "Income Account: defined on the product/product category", + ], + }, + }, + }, + manufacturing_order: { + title: "Manufacturing Order (Finished Product at $52, Component at $50)", + continental: { + periodic: { + operations: [], + explanation: [ + "In a periodic inventory valuation manufacturing orders are not directly posted in the accounting.", + "The inventory value is updated when entries are genarted from stock valuation report at closing.", + ], + configuration: [], + }, + perpetual: { + operations: [], + explanation: [ + "No 'Cost of Production' account is set on the production location, therefore variations in" + + " inventories of manufactured goods and components will be recorded at closing.", + ], + configuration: [], + }, + }, + anglo_saxon: { + periodic: { + operations: [], + explanation: [ + "In a periodic inventory valuation manufacturing orders are not directly posted in the accounting.", + "The inventory value is updated when entries are genarted from stock valuation report at closing.", + ], + configuration: [], + }, + perpetual: { + operations: [ + { account: ['ASSETS', 'MANUFACTURED'], debit: 52 }, + { account: ['ASSETS', 'COST'], credit: 52 }, + { account: ['ASSETS', 'RAW'], credit: 50 }, + { account: ['ASSETS', 'COST'], debit: 50 }, + ], + explanation: [], + configuration: [ + "Stock Account for manufactured product: defined on the product category", + "Stock Account for component: defined on the product category", + "Cost of Production Account: defined on the production location", + ], + }, + }, + }, + inventory_loss: { + title: "Inventory Loss (Scrap $30)", + continental: { + periodic: { + operations: [], + explanation: [ + "In a periodic inventory valuation, inventory adjustments are not directly posted in the accounting.", + "The inventory value is updated when entries are generated from stock valuation report at closing.", + ], + configuration: [], + }, + perpetual: { + operations: [], + explanation: [ + "No 'Inventory Loss' account is set on the inventory loss location, therefore variations in" + + " inventories coming from inventory adjustments will be recorded at closing.", + ], + configuration: [], + }, + }, + anglo_saxon: { + periodic: { + operations: [], + explanation: [ + "In a periodic inventory valuation, inventory adjustments are not directly posted in the accounting.", + "The inventory value is updated when entries are generated from stock valuation report at closing.", + ], + configuration: [], + }, + perpetual: { + operations: [ + { account: ['ASSETS', 'INVENTORY'], credit: 30 }, + { account: ['EXPENSES', 'INVENTORY_LOSS'], debit: 30 }, + ], + explanation: [], + configuration: [ + "Stock Account: defined on the product category", + "Inventory Adjustment Account: defined on the inventory loss location", + ], + }, + }, + }, +}); + +/* >Hic sunt dracones< + * + * Reviews are treated almost identically to entry operations in both scripts, + * except for the following difference in behaviour. + * + * [valuation-journal.js] + * The journal chart will use `journal_operations' (unique to `closing') if it + * exists, falling back to `operations' as normal otherwise. It will ignore the + * `entries' and `except' fields. + * + * [valuation-accounting.js] + * The accounting chart will ignore `journal_operations'. If an `entries' or + * `except' field is defined, it will only use that operation if said fields + * match the currently active operations (see above for keys). It must match + * ALL in `entries' and NONE in `except' in order to be used. The commented out + * parts in the `explanation' field (otherwise unused here) are relevant only + * for this chart. + */ +const VALUATION_REVIEWS = Immutable.fromJSButOrdered({ + unreceived: { + title: "Invoices not received", + continental: { + periodic: { + operations: [ + { account: ['LIABILITIES', 'INVOICES_UNRECEIVED'], credit: 50, + entries: ['supplier_reception'], + except: ['supplier_bill'] }, + { account: ['EXPENSES', 'GOODS_FOR_RESALE'], debit: 50, + entries: ['supplier_reception'], + except: ['supplier_bill'] }, + { account: ['LIABILITIES', 'INVOICES_UNRECEIVED'], credit: 48, + entries: ['supplier_reception_extra'], + except: ['supplier_bill_extra'] }, + { account: ['EXPENSES', 'GOODS_FOR_RESALE'], debit: 48, + entries: ['supplier_reception_extra'], + except: ['supplier_bill_extra'] }, + ], + explanation: [ + "These accrual entries are adjusting journal entries made at the end of an accounting period to ensure" + + " that expenses are recognized in the period in which they are incurred, regardless of when cash is paid.", + "Related operations:", + "1) Supplier Goods Reception (PO $50, Bill $50) is done but no bill is received yet", + "2) Supplier Goods Reception (PO $48, Bill $50) is done but no bill is received yet", + ], + configuration: [ + "Expense Account: defined on the product/product category", + "GRNI Account: defined when generating accrual entries from 'Invoices not received'", + ], + }, + perpetual: { + operations: [ + { account: ['LIABILITIES', 'INVOICES_UNRECEIVED'], credit: 50, + entries: ['supplier_reception'], + except: ['supplier_bill'] }, + { account: ['EXPENSES', 'GOODS_FOR_RESALE'], debit: 50, + entries: ['supplier_reception'], + except: ['supplier_bill'] }, + { account: ['LIABILITIES', 'INVOICES_UNRECEIVED'], credit: 48, + entries: ['supplier_reception_extra'], + except: ['supplier_bill_extra'] }, + { account: ['EXPENSES', 'GOODS_FOR_RESALE'], debit: 48, + entries: ['supplier_reception_extra'], + except: ['supplier_bill_extra'] }, + ], + explanation: [ + "These accrual entries are adjusting journal entries made at the end of an accounting period to ensure" + + " that expenses are recognized in the period in which they are incurred, regardless of when cash is paid.", + "They are reverted after the period we are closing.", + "Related operations:", + "1) Supplier Goods Reception (PO $50, Bill $50) is done but no bill is received yet", + "2) Supplier Goods Reception (PO $48, Bill $50) is done but no bill is received yet", + ], + configuration: [ + "Expense Account: defined on the product/product category", + "GRNI Account: defined when generating accrual entries from 'Invoices not received'", + ], + }, + }, + anglo_saxon: { + periodic: { + operations: [ + { account: ['LIABILITIES', 'UNINVOICED'], credit: 50, + entries: ['supplier_reception'], + except: ['supplier_bill'] }, + { account: ['EXPENSES', 'COST'], debit: 50, + entries: ['supplier_reception'], + except: ['supplier_bill'] }, + { account: ['LIABILITIES', 'UNINVOICED'], credit: 48, + entries: ['supplier_reception_extra'], + except: ['supplier_bill_extra'] }, + { account: ['EXPENSES', 'COST'], debit: 48, + entries: ['supplier_reception_extra'], + except: ['supplier_bill_extra'] }, + ], + explanation: [ + "These accrual entries are adjusting journal entries made at the end of an accounting period to ensure" + + " that expenses are recognized in the period in which they are incurred, regardless of when cash is paid.", + "Related operations:", + "1) Supplier Goods Reception (PO $50, Bill $50) is done but no bill is received yet", + "2) Supplier Goods Reception (PO $48, Bill $50) is done but no bill is received yet", + ], + configuration: [ + "Expense Account: defined on the product/product category", + "GRNI Account: defined when generating accrual entries from 'Invoices not received'", + ], + }, + perpetual: { + operations: [ + { account: ['LIABILITIES', 'UNINVOICED'], credit: 50, + entries: ['supplier_reception'], + except: ['supplier_bill'] }, + { account: ['ASSETS', 'VARIATIONS'], debit: 50, + entries: ['supplier_reception'], + except: ['supplier_bill'] }, + { account: ['LIABILITIES', 'UNINVOICED'], credit: 48, + entries: ['supplier_reception_extra'], + except: ['supplier_bill_extra'] }, + { account: ['ASSETS', 'VARIATIONS'], debit: 48, + entries: ['supplier_reception_extra'], + except: ['supplier_bill_extra'] }, + ], + explanation: [ + "Accrual entries are adjusting journal entries made at the end of an accounting period to ensure" + + " that revenues/expenses are recognized in the period in which they are earned/incurred, regardless of" + + " when cash is received / paid.", + "They are reverted after the period we are closing.", + "From a stock point of view, it also enables us to specify a part of the origin of stock variations (between" + + " Accounting Stock and Inventory Stock) recorded from the stock valuation report.", + "Related operations:", + "1) Supplier Goods Reception (PO $50, Bill $50) is done but no bill is received yet", + "2) Supplier Goods Reception (PO $48, Bill $50) is done but no bill is received yet", + ], + configuration: [ + "Inventory Variation Account: defined on the used Stock Account for the product category", + "GRNI Account: defined when generating accrual entries from 'Invoices not received'", + ], + }, + }, + }, + uninvoiced: { + title: "Invoices to be issued", + continental: { + periodic: { + operations: [ + { account: ['LIABILITIES', 'RECEIVABLE'], debit: 100, + entries: ['customer_shipping'], + except: ['customer_invoice'] }, + { account: ['REVENUES', 'SALES'], credit: 100, + entries: ['customer_shipping'], + except: ['customer_invoice'] }, + ], + explanation: [ + "These accrual entries are adjusting journal entries made at the end of an accounting period to ensure" + + " that revenues are recognized in the period in which they are earned, regardless of when cash is received.", + "Related operation:", + "Customer Shipping (SO $100, Invoice $100, Good Value $50) is done but no invoice is sent yet", + ], + configuration: [ + "Revenue Account: defined on the product/product category", + "Uninvoiced Receivable Account: defined when generating accrual entries from 'Invoices to be issued'", + ], + }, + perpetual: { + operations: [ + { account: ['LIABILITIES', 'RECEIVABLE'], debit: 100, + entries: ['customer_shipping'], + except: ['customer_invoice'] }, + { account: ['REVENUES', 'SALES'], credit: 100, + entries: ['customer_shipping'], + except: ['customer_invoice'] }, + ], + explanation: [ + "These accrual entries are adjusting journal entries made at the end of an accounting period to ensure" + + " that revenues are recognized in the period in which they are earned, regardless of when cash is received.", + "They are reverted after the period we are closing.", + "Related operation:", + "Customer Shipping (SO $100, Invoice $100, Good Value $50) is done but no invoice is sent yet", + ], + configuration: [ + "Revenue Account: defined on the product/product category", + "Uninvoiced Receivable Account: defined when generating accrual entries from 'Invoices to be issued'", + ], + }, + }, + anglo_saxon: { + periodic: { + operations: [ + { account: ['ASSETS', 'UNINVOICED'], debit: 100, + entries: ['customer_shipping'], + except: ['customer_invoice'] }, + { account: ['REVENUES', 'SALES' ], credit: 100, + entries: ['customer_shipping'], + except: ['customer_invoice'] }, + ], + explanation: [ + "These accrual entries are adjusting journal entries made at the end of an accounting period to ensure" + + " that revenues are recognized in the period in which they are earned, regardless of" + + " when cash is received.", + "Related operation:", + "Customer Shipping (SO $100, Invoice $100, Good Value $50) is done but no invoice is sent yet", + ], + configuration: [ + "Revenue Account: defined on the product/product category", + "Uninvoiced Receivable Account: defined when generating accrual entries from 'Invoices to be issued'", + ], + }, + perpetual: { + operations: [ + { account: ['ASSETS', 'UNINVOICED'], debit: 100, + entries: ['customer_shipping'], + except: ['customer_invoice'] }, + { account: ['REVENUES', 'SALES'], credit: 100, + entries: ['customer_shipping'], + except: ['customer_invoice'] }, + { account: ['ASSETS', 'VARIATIONS'], credit: 50, + entries: ['customer_shipping'], + except: ['customer_invoice'] }, + { account: ['EXPENSES', 'COST'], debit: 50, + entries: ['customer_shipping'], + except: ['customer_invoice'] }, + ], + explanation: [ + "These accrual entries are adjusting journal entries made at the end of an accounting period to ensure" + + " that revenues/expenses are recognized in the period in which they are earned/incurred, regardless of" + + " when cash is received/paid.", + "From a stock point of view, it also enables us to specify a part of the origin of stock variations (between" + + " Accounting Stock and Inventory Stock) recorded from the stock valuation report.", + "They are reverted after the period we are closing.", + "Related operation:", + "Customer Shipping (SO $100, Invoice $100, Good Value $50) is done but no invoice is sent yet", + ], + configuration: [ + "Inventory Variation Account: defined on the used Stock Account for the product category", + "Uninvoiced Receivable Account: defined when generating accrual entries from 'Invoices to be issued'", + "Revenue Account: defined on the product/product category", + "Expense/COGS Account: defined on the product/product category", + ], + }, + }, + }, + prepaid: { + title: "Prepaid Expenses", + continental: { + periodic: { + operations: [ + { account: ['LIABILITIES', 'DEFERRED_CHARGES'], debit: 50, + entries: ['supplier_bill'], + except: ['supplier_reception'] }, + { account: ['EXPENSES', 'GOODS_FOR_RESALE'], credit: 50, + entries: ['supplier_bill'], + except: ['supplier_reception'] }, + { account: ['LIABILITIES', 'DEFERRED_CHARGES'], debit: 50, + entries: ['supplier_bill_extra'], + except: ['supplier_reception_extra'] }, + { account: ['EXPENSES', 'GOODS_FOR_RESALE'], credit: 50, + entries: ['supplier_bill_extra'], + except: ['supplier_reception_extra'] }, + ], + explanation: [ + "Prepaid expenses are journal entries made during closing when a supplier bill is received before goods" + + " or services are received, so the amount is recorded as an asset until the expense is recognized.", + "Related operations:", + "1) Supplier Goods Reception (PO $50, Bill $50) is not done but the bill is received", + "2) Supplier Goods Reception (PO $48, Bill $50) is not done but the bill is received", + ], + configuration: [ + "Expense Account: defined on the product/product category", + "Prepaid Expense Account: defined when generating entries from 'Prepaid Expenses'", + ], + }, + perpetual: { + operations: [ + { account: ['LIABILITIES', 'DEFERRED_CHARGES'], debit: 50, + entries: ['supplier_bill'], + except: ['supplier_reception'] }, + { account: ['EXPENSES', 'GOODS_FOR_RESALE'], credit: 50, + entries: ['supplier_bill'], + except: ['supplier_reception'] }, + { account: ['LIABILITIES', 'DEFERRED_CHARGES'], debit: 50, + entries: ['supplier_bill_extra'], + except: ['supplier_reception_extra'] }, + { account: ['EXPENSES', 'GOODS_FOR_RESALE'], credit: 50, + entries: ['supplier_bill_extra'], + except: ['supplier_reception_extra'] }, + ], + explanation: [ + "Prepaid expenses are journal entries made during closing when a supplier bill is received before goods" + + " or services are received, so the amount is recorded as an asset until the expense is recognized.", + "Related operations:", + "1) Supplier Goods Reception (PO $50, Bill $50) is not done but the bill is received", + "2) Supplier Goods Reception (PO $48, Bill $50) is not done but the bill is received", + ], + configuration: [ + "Expense Account: defined on the product/product category", + "Prepaid Expense Account: defined when generating entries from 'Prepaid Expenses'", + ], + }, + }, + anglo_saxon: { + periodic: { + operations: [ + { account: ['ASSETS', 'PREPAID'], debit: 50, + entries: ['supplier_bill'], + except: ['supplier_reception'] }, + { account: ['EXPENSES', 'COST'], credit: 50, + entries: ['supplier_bill'], + except: ['supplier_reception'] }, + { account: ['ASSETS', 'PREPAID'], debit: 50, + entries: ['supplier_bill_extra'], + except: ['supplier_reception_extra'] }, + { account: ['EXPENSES', 'COST'], credit: 50, + entries: ['supplier_bill_extra'], + except: ['supplier_reception_extra'] }, + ], + explanation: [ + "Prepaid expenses are journal entries made during closing when a supplier bill is received before goods" + + " or services are received, so the amount is recorded as an asset until the expense is recognized.", + "Related operations:", + "1) Supplier Goods Reception (PO $50, Bill $50) is not done but the bill is received", + "2) Supplier Goods Reception (PO $48, Bill $50) is not done but the bill is received", + ], + configuration: [ + "Expense Account: defined on the product/product category", + "Prepaid Expense Account: defined when generating entries from 'Prepaid Expenses'", + ], + }, + perpetual: { + operations: [ + { account: ['ASSETS', 'PREPAID'], debit: 50, + entries: ['supplier_bill'], + except: ['supplier_reception'] }, + { account: ['ASSETS', 'VARIATIONS'], credit: 50, + entries: ['supplier_bill'], + except: ['supplier_reception'] }, + { account: ['ASSETS', 'PREPAID'], debit: 50, + entries: ['supplier_bill_extra'], + except: ['supplier_reception_extra'] }, + { account: ['ASSETS', 'VARIATIONS'], credit: 50, + entries: ['supplier_bill_extra'], + except: ['supplier_reception_extra'] }, + ], + explanation: [ + "Prepaid expenses are journal entries made during closing when a supplier bill is received before goods" + + " or services are received, so the amount is recorded as an asset until the expense is recognized.", + "From a stock point of view, it also enables us to specify a part of the origin of stock variations (between" + + " Accounting Stock and Inventory Stock) recorded from the stock valuation report.", + "Related operations:", + "1) Supplier Goods Reception (PO $50, Bill $50) is not done but the bill is received", + "2) Supplier Goods Reception (PO $48, Bill $50) is not done but the bill is received", + ], + configuration: [ + "Inventory Variation Account: defined on the used Stock Account for the product category", + "Prepaid Expense Account: defined when generating entries from 'Prepaid Expenses'", + ], + }, + }, + }, + deferred: { + title: "Deferred Revenues", + continental: { + periodic: { + operations: [ + { account: ['LIABILITIES', 'DEFERRED_INCOME'], credit: 100, + entries: ['customer_invoice'], + except: ['customer_shipping'] }, + { account: ['REVENUES', 'SALES'], debit: 100, + entries: ['customer_invoice'], + except: ['customer_shipping'] }, + ], + explanation: [ + "Deferred revenues are journal entries made during closing when an invoice has been issued but goods or" + + " services are not delivered yet, so the amount has to be recorded as a liability until the revenue is earned.", + "They are reverted after the period we are closing.", + "Related operation:", + "Customer Shipping (SO $100, Invoice $100, Good Value $50) is not done but the invoice is sent", + ], + configuration: [ + "Revenue Account: defined on the product/product category", + "Deferred Revenue Account: defined when generating accrual entries from 'Deferred Revenues'", + ], + }, + perpetual: { + operations: [ + { account: ['LIABILITIES', 'DEFERRED_INCOME'], credit: 100, + entries: ['customer_invoice'], + except: ['customer_shipping'] }, + { account: ['REVENUES', 'SALES'], debit: 100, + entries: ['customer_invoice'], + except: ['customer_shipping'] }, + ], + explanation: [ + "Deferred revenues are journal entries made during closing when an invoice has been issued but goods or" + + " services are not delivered yet, so the amount has to be recorded as a liability until the revenue is earned.", + "They are reverted after the period we are closing.", + "Related operation:", + "Customer Shipping (SO $100, Invoice $100, Good Value $50) is not done but the invoice is sent", + ], + configuration: [ + "Revenue Account: defined on the product/product category", + "Deferred Revenue Account: defined when generating accrual entries from 'Deferred Revenues'", + ], + }, + }, + anglo_saxon: { + periodic: { + operations: [ + { account: ['LIABILITIES', 'DEFERRED'], credit: 100, + entries: ['customer_invoice'], + except: ['customer_shipping'] }, + { account: ['REVENUES', 'SALES'], debit: 100, + entries: ['customer_invoice'], + except: ['customer_shipping'] }, + ], + explanation: [ + "Deferred revenues are journal entries made during closing when an invoice has been issued but goods or" + + " services are not delivered yet, so the amount has to be recorded as a liability until the revenue is earned.", + "They are reverted after the period we are closing.", + "Related operation:", + "Customer Shipping (SO $100, Invoice $100, Good Value $50) is not done but the invoice is sent", + ], + configuration: [ + "Revenue Account: defined on the product/product category", + "Deferred Revenue Account: defined when generating accrual entries from 'Deferred Revenues'", + ], + }, + perpetual: { + operations: [ + { account: ['LIABILITIES', 'DEFERRED'], credit: 100, + entries: ['customer_invoice'], + except: ['customer_shipping'] }, + { account: ['REVENUES', 'SALES'], debit: 100, + entries: ['customer_invoice'], + except: ['customer_shipping'] }, + { account: ['ASSETS', 'VARIATIONS'], debit: 50, + entries: ['customer_invoice'], + except: ['customer_shipping'] }, + { account: ['EXPENSES', 'COST'], credit: 50, + entries: ['customer_invoice'], + except: ['customer_shipping'] }, + ], + explanation: [ + "Deferred revenues are journal entries made during closing when an invoice has been issued but goods or" + + " services are not delivered yet, so the amount has to be recorded as a liability until the revenue is earned.", + "From a stock point of view, it also enables us to specify a part of the origin of stock variations (between" + + " Accounting Stock and Inventory Stock) recorded from the stock valuation report.", + "They are reverted after the period we are closing.", + "Related operation:", + "Customer Shipping (SO $100, Invoice $100, Good Value $50) is not done but the invoice is sent", + ], + configuration: [ + "Inventory Variation Account: defined on the used Stock Account for the product category", + "Deferred Revenue Account: defined when generating accrual entries from 'Deferred Revenues'", + "Revenue Account: defined on the product/product category", + "Expense/COGS Account : defined on the product/product category", + ], + }, + }, + }, + closing: { + title: "Stock Valuation", + continental: { + periodic: { + journal_operations: [ + { account: ['STOCK', 'GOODS_FOR_RESALE'], debit: 20 }, + { account: ['EXPENSES', 'CHANGE_IN_GOODS_FOR_RESALE'], credit: 20 }, + { account: ['STOCK', 'FINISHED_GOODS'], debit: 52 }, + { account: ['STOCK', 'RAW'], credit: 50 }, + { account: ['REVENUES', 'CHANGE_IN_FINISHED_GOODS'], credit: 52 }, + { account: ['EXPENSES', 'CHANGE_IN_RAW'], debit: 50 }, + ], + operations: [ + { account: ['STOCK', 'GOODS_FOR_RESALE'], debit: 50, + entries: ['supplier_reception'] }, + { account: ['EXPENSES', 'CHANGE_IN_GOODS_FOR_RESALE'], credit: 50, + entries: ['supplier_reception'] }, + { account: ['STOCK', 'GOODS_FOR_RESALE'], debit: 50, + entries: ['supplier_reception_extra', 'supplier_bill_extra'] }, + { account: ['EXPENSES', 'CHANGE_IN_GOODS_FOR_RESALE'], credit: 50, + entries: ['supplier_reception_extra', 'supplier_bill_extra'] }, + { account: ['STOCK', 'GOODS_FOR_RESALE'], debit: 48, + entries: ['supplier_reception_extra'], + except: ['supplier_bill_extra'] }, + { account: ['EXPENSES', 'CHANGE_IN_GOODS_FOR_RESALE'], credit: 48, + entries: ['supplier_reception_extra'], + except: ['supplier_bill_extra'] }, + { account: ['STOCK', 'GOODS_FOR_RESALE'], credit: 50, + entries: ['customer_shipping'] }, + { account: ['EXPENSES', 'CHANGE_IN_GOODS_FOR_RESALE'], debit: 50, + entries: ['customer_shipping'] }, + { account: ['STOCK', 'GOODS_FOR_RESALE'], credit: 30, + entries: ['inventory_loss'] }, + { account: ['EXPENSES', 'CHANGE_IN_GOODS_FOR_RESALE'], debit: 30, + entries: ['inventory_loss'] }, + { account: ['STOCK', 'FINISHED_GOODS'], debit: 52, + entries: ['manufacturing_order'] }, + { account: ['STOCK', 'RAW'], credit: 50, + entries: ['manufacturing_order'] }, + { account: ['REVENUES', 'CHANGE_IN_FINISHED_GOODS'], credit: 52, + entries: ['manufacturing_order'] }, + { account: ['EXPENSES', 'CHANGE_IN_RAW'], debit: 50, + entries: ['manufacturing_order'] }, + ], + explanation: [ + "At closing, Stock Valuation must be updated to reflect reality. This will be done by generating entries from" + + " the Stock Valuation Report. This will recognize value coming from operations such as the following ones:", + "1) Supplier Goods Reception (PO $50, Bill $50)", + "2) Supplier Goods Reception (PO $48, Bill $50)", + "3) Customer Shipping (SO $100, Invoice $100, Good Value $50)", + "4) Inventory Loss (Scrap $30)", + "5) Manufacturing Order (Finished Product at $52, Component at $50)", + ], + configuration: [ + "Stock Account: defined on the product category", + "Inventory Variation Account: defined on the used Stock Account", + ], + }, + perpetual: { + journal_operations: [ + { account: ['STOCK', 'GOODS_FOR_RESALE'], debit: 18 }, + { account: ['EXPENSES', 'GOODS_FOR_RESALE'], credit: 18 }, + { account: ['STOCK', 'FINISHED_GOODS'], debit: 52 }, + { account: ['EXPENSES', 'FINISHED'], credit: 52 }, + { account: ['STOCK', 'RAW'], credit: 50 }, + { account: ['EXPENSES', 'RAW'], debit: 50 }, + { account: ['EXPENSES', 'CHANGE_IN_GOODS_FOR_RESALE'], credit: 18 }, + { account: ['EXPENSES', 'GOODS_FOR_RESALE'], debit: 18 }, + { account: ['EXPENSES', 'RAW'], credit: 50 }, + { account: ['EXPENSES', 'CHANGE_IN_RAW'], debit: 50 }, + { account: ['EXPENSES', 'FINISHED'], debit: 52 }, + { account: ['REVENUES', 'CHANGE_IN_FINISHED_GOODS'], credit: 52 }, + ], + operations: [ + { account: ['STOCK', 'GOODS_FOR_RESALE'], debit: 50, + entries: ['supplier_reception'], + except: ['supplier_bill'] }, + { account: ['EXPENSES', 'GOODS_FOR_RESALE'], credit: 50, + entries: ['supplier_reception'], + except: ['supplier_bill'] }, + { account: ['STOCK', 'GOODS_FOR_RESALE'], debit: 48, + entries: ['supplier_reception_extra'], + except: ['supplier_bill_extra'] }, + { account: ['EXPENSES', 'GOODS_FOR_RESALE'], credit: 48, + entries: ['supplier_reception_extra'], + except: ['supplier_bill_extra'] }, + { account: ['STOCK', 'GOODS_FOR_RESALE'], credit: 50, + entries: ['customer_shipping'], + except: ['customer_invoice'] }, + { account: ['EXPENSES', 'GOODS_FOR_RESALE'], debit: 50, + entries: ['customer_shipping'], + except: ['customer_invoice'] }, + { account: ['STOCK', 'GOODS_FOR_RESALE'], credit: 30, + entries: ['inventory_loss'] }, + { account: ['EXPENSES', 'GOODS_FOR_RESALE'], debit: 30, + entries: ['inventory_loss'] }, + { account: ['STOCK', 'FINISHED_GOODS'], debit: 52, + entries: ['manufacturing_order'] }, + { account: ['EXPENSES', 'FINISHED'], credit: 52, + entries: ['manufacturing_order'] }, + { account: ['STOCK', 'RAW'], credit: 50, + entries: ['manufacturing_order'] }, + { account: ['EXPENSES', 'RAW'], debit: 50, + entries: ['manufacturing_order'] }, + // Adjustment + // a) Purchased good for resale + { account: ['EXPENSES', 'CHANGE_IN_GOODS_FOR_RESALE'], credit: 50, + entries: ['supplier_reception'] }, + { account: ['EXPENSES', 'GOODS_FOR_RESALE'], debit: 50, + entries: ['supplier_reception'] }, + { account: ['EXPENSES', 'CHANGE_IN_GOODS_FOR_RESALE'], credit: 48, + entries: ['supplier_reception_extra'], + except: ['supplier_bill_extra'] }, + { account: ['EXPENSES', 'GOODS_FOR_RESALE'], debit: 48, + entries: ['supplier_reception_extra'], + except: ['supplier_bill_extra'] }, + { account: ['EXPENSES', 'CHANGE_IN_GOODS_FOR_RESALE'], credit: 50, + entries: ['supplier_reception_extra', 'supplier_bill_extra'] }, + { account: ['EXPENSES', 'GOODS_FOR_RESALE'], debit: 50, + entries: ['supplier_reception_extra', 'supplier_bill_extra'] }, + { account: ['EXPENSES', 'CHANGE_IN_GOODS_FOR_RESALE'], debit: 50, + entries: ['customer_shipping'] }, + { account: ['EXPENSES', 'GOODS_FOR_RESALE'], credit: 50, + entries: ['customer_shipping'] }, + { account: ['EXPENSES', 'CHANGE_IN_GOODS_FOR_RESALE'], debit: 30, + entries: ['inventory_loss'] }, + { account: ['EXPENSES', 'GOODS_FOR_RESALE'], credit: 30, + entries: ['inventory_loss'] }, + // b) Component + { account: ['EXPENSES', 'RAW'], credit: 50, + entries: ['manufacturing_order'] }, + { account: ['EXPENSES', 'CHANGE_IN_RAW'], debit: 50, + entries: ['manufacturing_order'] }, + // c) Finished product + { account: ['EXPENSES', 'FINISHED'], debit: 52, + entries: ['manufacturing_order'] }, + { account: ['REVENUES', 'CHANGE_IN_FINISHED_GOODS'], credit: 52, + entries: ['manufacturing_order'] }, + // Second half, excluded from journal chart + { account: ['STOCK', 'GOODS_FOR_RESALE'], credit: 50, + entries: ['supplier_bill'], + except: ['supplier_reception'] }, + { account: ['EXPENSES', 'GOODS_FOR_RESALE'], debit: 50, + entries: ['supplier_bill'], + except: ['supplier_reception'] }, + { account: ['STOCK', 'GOODS_FOR_RESALE'], credit: 50, + entries: ['supplier_bill_extra'], + except: ['supplier_reception_extra'] }, + { account: ['EXPENSES', 'GOODS_FOR_RESALE'], debit: 50, + entries: ['supplier_bill_extra'], + except: ['supplier_reception_extra'] }, + { account: ['STOCK', 'GOODS_FOR_RESALE'], debit: 50, + entries: ['customer_invoice'], + except: ['customer_shipping'] }, + { account: ['EXPENSES', 'GOODS_FOR_RESALE'], credit: 50, + entries: ['customer_invoice'], + except: ['customer_shipping'] }, + ], + explanation: [ + "At closing Accounting Stock and Inventory Stock must have the same value.", + "A difference could come from cases such as the ones listed below and this will be corrected thanks to" + + " the Stock Valuation Report closing entry.", + "1) Supplier Goods Reception (PO $50, Bill $50) is done but no bill is received yet", + "2) Supplier Goods Reception (PO $48, Bill $50) is done but no bill is received yet", + "3) Customer Shipping (SO $100, Invoice $100, Good Value $50) is done but no invoice is sent yet", + "4) Inventory Loss (Scrap $30)", + "5) Manufacturing Order (Finished Product at $52, Component at $50)", + "At closing, an adjusting entry is created to ensure that the values are correctly recorded in the" + + " variation and expenses accounts according to continental accounting logic. Indeed, even though" + + " expenses are recorded according to the COGS logic of Anglo-Saxon accounting during the period," + + " at closing the expenses recorded should represent what was actually purchased during this period.", + "The variation is known thanks to the calculation (Stock Account y - Stock Account y-1) for each of" + + " the following categories:", + "a. Purchased good for resale", + "b. Component", + "c. Finished product", + // "6) Supplier Goods Reception (PO $50, Bill $50) is not done but the bill is received", + // "7) Supplier Goods Reception (PO $48, Bill $50) is not done but the bill is received", + // "8) Customer Shipping (SO $100, Invoice $100, Good Value $50) is not done but the invoice is sent", + ], + configuration: [ + "Expense Account: defined on the product/product category", + "Stock Account: defined on the product category", + "Inventory Variation Account: defined on the used Stock Account", + "Expense Account for adjusting entry: defined on the used Stock Account", + ], + }, + }, + anglo_saxon: { + periodic: { + journal_operations: [ + { account: ['ASSETS', 'INVENTORY'], debit: 50 }, + { account: ['EXPENSES', 'COST'], credit: 50 }, + { account: ['ASSETS', 'INVENTORY'], credit: 30 }, + { account: ['EXPENSES', 'INVENTORY_LOSS'], debit: 30 }, + { account: ['ASSETS', 'MANUFACTURED'], debit: 52 }, + { account: ['ASSETS', 'COST'], credit: 52 }, + { account: ['ASSETS', 'RAW'], credit: 50 }, + { account: ['ASSETS', 'COST'], debit: 50 }, + ], + operations: [ + { account: ['ASSETS', 'INVENTORY'], debit: 50, + entries: ['supplier_reception'] }, + { account: ['EXPENSES', 'COST'], credit: 50, + entries: ['supplier_reception'] }, + { account: ['ASSETS', 'INVENTORY'], debit: 50, + entries: ['supplier_reception_extra', 'supplier_bill_extra'] }, + { account: ['EXPENSES', 'COST'], credit: 50, + entries: ['supplier_reception_extra', 'supplier_bill_extra'] }, + { account: ['ASSETS', 'INVENTORY'], debit: 48, + entries: ['supplier_reception_extra'], + except: ['supplier_bill_extra'] }, + { account: ['EXPENSES', 'COST'], credit: 48, + entries: ['supplier_reception_extra'], + except: ['supplier_bill_extra'] }, + { account: ['ASSETS', 'INVENTORY'], credit: 50, + entries: ['customer_shipping'] }, + { account: ['EXPENSES', 'COST'], debit: 50, + entries: ['customer_shipping'] }, + { account: ['ASSETS', 'INVENTORY'], credit: 30, + entries: ['inventory_loss'] }, + { account: ['EXPENSES', 'INVENTORY_LOSS'], debit: 30, + entries: ['inventory_loss'] }, + { account: ['ASSETS', 'MANUFACTURED'], debit: 52, + entries: ['manufacturing_order'] }, + { account: ['ASSETS', 'COST'], credit: 52, + entries: ['manufacturing_order'] }, + { account: ['ASSETS', 'RAW'], credit: 50, + entries: ['manufacturing_order'] }, + { account: ['ASSETS', 'COST'], debit: 50, + entries: ['manufacturing_order'] }, + ], + explanation: [ + "At closing, Stock Valuation must be updated to reflect reality. This will be done by generating entries from" + + " the Stock Valuation Report. This will recognize value coming from operations such as the following ones:", + "1) Supplier Goods Reception (PO $50, Bill $50)", + "2) Supplier Goods Reception (PO $48, Bill $50)", + "3) Customer Shipping (SO $100, Invoice $100, Good Value $50)", + "4) Inventory Loss (Scrap $30)", + "5) Manufacturing Order (Finished Product at $52, Component at $50)", + ], + configuration: [ + "Stock Account: defined on the product category", + "Inventory Variation Account: defined on the used Stock Account", + "Inventory Adjustment Account: defined on the Inventory Loss location", + "Cost of Production Account: defined on the Production location", + ], + }, + perpetual: { + journal_operations: [ + { account: ['ASSETS', 'INVENTORY'], debit: 48 }, + { account: ['ASSETS', 'VARIATIONS'], credit: 48 }, + ], + operations: [ + { account: ['ASSETS', 'INVENTORY'], debit: 50, + entries: ['supplier_reception'], + except: ['supplier_bill'] }, + { account: ['ASSETS', 'VARIATIONS'], credit: 50, + entries: ['supplier_reception'], + except: ['supplier_bill'] }, + { account: ['ASSETS', 'INVENTORY'], debit: 48, + entries: ['supplier_reception_extra'], + except: ['supplier_bill_extra'] }, + { account: ['ASSETS', 'VARIATIONS'], credit: 48, + entries: ['supplier_reception_extra'], + except: ['supplier_bill_extra'] }, + { account: ['ASSETS', 'INVENTORY'], credit: 50, + entries: ['customer_shipping'], + except: ['customer_invoice'] }, + { account: ['ASSETS', 'VARIATIONS'], debit: 50, + entries: ['customer_shipping'], + except: ['customer_invoice'] }, + { account: ['ASSETS', 'INVENTORY'], credit: 50, + entries: ['supplier_bill'], + except: ['supplier_reception'] }, + { account: ['ASSETS', 'VARIATIONS'], debit: 50, + entries: ['supplier_bill'], + except: ['supplier_reception'] }, + { account: ['ASSETS', 'INVENTORY'], credit: 50, + entries: ['supplier_bill_extra'], + except: ['supplier_reception_extra'] }, + { account: ['ASSETS', 'VARIATIONS'], debit: 50, + entries: ['supplier_bill_extra'], + except: ['supplier_reception_extra'] }, + { account: ['ASSETS', 'INVENTORY'], debit: 50, + entries: ['customer_invoice'], + except: ['customer_shipping'] }, + { account: ['ASSETS', 'VARIATIONS'], credit: 50, + entries: ['customer_invoice'], + except: ['customer_shipping'] }, + ], + explanation: [ + "At closing, Accounting Stock and Inventory Stock must have the same value.", + "A difference could come from cases such as the ones listed below and this will be corrected thanks to" + + " the Stock Valuation Report closing entry.", + "Related operations:", + "1) Supplier Goods Reception (PO $50, Bill $50) is done but no bill is received yet", + "2) Supplier Goods Reception (PO $48, Bill $50) is done but no bill is received yet", + "3) Customer Shipping (SO $100, Invoice $100, Good Value $50) is done but no invoice is sent yet", + // "4) Supplier Goods Reception (PO $50, Bill $50) is not done but the bill is received", + // "5) Supplier Goods Reception (PO $48, Bill $50) is not done but the bill is received", + // "6) Customer Shipping (SO $100, Invoice $100, Good Value $50) is not done but the invoice is sent", + ], + configuration: [ + "Stock Account: defined on the product category", + "Inventory Variation Account: defined on the used Stock Account", + ], + }, + }, + }, +}); diff --git a/static/js/valuation-journal.js b/static/js/valuation-journal.js new file mode 100644 index 0000000000..6e9e222cb5 --- /dev/null +++ b/static/js/valuation-journal.js @@ -0,0 +1,176 @@ +/* global Immutable, React */ +/* global createAtom, findAncestor */ +/* global VALUATION_{STANDARDS,METHODS,JOURNALS,ENTRIES,REVIEWS} */ +(function () { + 'use strict'; + // NOTE: used by valuation cheat_sheet.rst + + const selectedMode = createAtom() + const selectedOp = createAtom(); + + const entries = VALUATION_ENTRIES.concat(VALUATION_REVIEWS); + + function watch (next) { + React.render( + React.createElement(Controls, { entryKey: next }), + document.getElementById('journaling-entries-controls')); + React.render( + React.createElement(FormatEntry, { entryKey: next }), + document.querySelector('.journal-entries')); + } + + selectedOp.addWatch('chart', (k, m, prev, next) => watch([next, ...selectedMode.deref()])); + selectedMode.addWatch('chart', (k, m, prev, next) => watch([selectedOp.deref(), ...next])); + + document.addEventListener('DOMContentLoaded', function () { + const entriesSection = findAncestor(document.querySelector('.journal-entries'), 'section'); + if (!entriesSection) { return; } + + const controls = document.createElement('div'); + controls.setAttribute('id', 'journaling-entries-controls'); + entriesSection.insertBefore(controls, entriesSection.lastElementChild); + + selectedMode.reset(['continental', 'periodic']); + selectedOp.reset('initial_inventory'); + }); + + const Controls = React.createClass({ + render: function () { + const key = this.props.entryKey; + return React.DOM.div( + null, + React.DOM.b(null, "Choose a standard:"), + VALUATION_STANDARDS.map(function (item, index) { + return React.DOM.label( + { key: index }, + React.DOM.input({ + type: 'radio', + checked: item.get('name') === key[1], + onChange: function (e) { + const newValue = item.get('name'); + selectedMode.reset([newValue, newValue === 'continental' ? 'periodic' : 'perpetual']); + } + }), + ' ', + item.get('text') + ); + }), + React.DOM.br(), + React.DOM.b(null, "Choose an accounting method:"), + VALUATION_METHODS.map(function (item, index) { + return React.DOM.label( + { key: index }, + React.DOM.input({ + type: 'radio', + checked: item.get('name') === key[2], + onChange: e => selectedMode.swap(vals => [vals[0], item.get('name')]), + }), + ' ', + item.get('text') + ); + }), + React.DOM.br(), + React.DOM.b(null, "Activate operations to see the impact:"), + VALUATION_ENTRIES.map(function (item, index) { + return React.DOM.label( + { key: index }, + React.DOM.input({ + type: 'radio', + checked: index === key[0], + onChange: e => selectedOp.reset(index), + }), + ' ', + item.get('title') + ); + }), + React.DOM.br(), + "Closing", + VALUATION_REVIEWS.map(function (item, index) { + return React.DOM.label( + { key: index }, + React.DOM.input({ + type: 'radio', + checked: index === key[0], + onChange: e => selectedOp.reset(index), + }), + ' ', + item.get('title') + ); + }), + React.DOM.br(), + ); + } + }); + const FormatEntry = React.createClass({ + render: function () { + const entry = entries.getIn(this.props.entryKey); + return React.DOM.div( + null, + React.DOM.table( + { className: 'table table-sm d-c-table' }, + React.DOM.thead( + null, + React.DOM.tr( + null, + React.DOM.th(), + React.DOM.th(null, "Debit"), + React.DOM.th(null, "Credit"), + ) + ), + React.DOM.tbody( + null, + // Use `journal_operations' if it's a review. See `valuation-data.js'. + entry && entry.get('journal_operations', entry.get('operations', [])).map(this.renderRow) + ) + ), + React.createElement(Listing, { + heading: "Explanation", + items: entry && entry.get('explanation'), + }), + React.createElement(Listing, { + heading: "Configuration", + items: entry && entry.get('configuration'), + }) + ); + }, + renderRow: function (entry, index) { + const standard = this.props.entryKey[1]; + if (!entry) { + return React.DOM.tr( + { key: 'spacer-' + index }, + React.DOM.td({ colSpan: 3 }, "\u00A0") + ); + } + const journalEntry = VALUATION_JOURNALS.getIn([standard, ...entry.get('account')]); + const title = journalEntry.get('title'); + // Don't display 0 for 'General Balance for Inventory Initial Value' + const code = journalEntry.get('code') || ''; + return React.DOM.tr( + { key: index }, + React.DOM.td(null, `${code} ${title}`), + React.DOM.td(null, entry.get('debit')), + React.DOM.td(null, entry.get('credit')) + ); + } + }); + const Listing = React.createClass({ + render: function () { + if (!this.props.items || this.props.items.isEmpty()) { + return React.DOM.div(); + } + const items = this.props.items; + const idx = items.indexOf(null); + if (idx !== -1) { + // console.log(items.slice(idx + 1).deref()); + items = items.take(idx); + } + return React.DOM.div( + { className: 'entries-listing' }, + React.DOM.h4(null, this.props.heading, ':'), + items.map(function (item, index) { + return React.DOM.p({ key: index }, item); + }) + ); + } + }); +}());