diff --git a/_static/atom.js b/_static/atom.js index 49642ee41..1589afee1 100644 --- a/_static/atom.js +++ b/_static/atom.js @@ -1,3 +1,11 @@ +function findAncestor(element, name) { + name = name.toUpperCase(); + while(element && element.nodeName.toUpperCase() !== name) { + element = element.parentElement; + }; + return element; +} + function createAtom(val, options) { var watchers = {}; var validator = options && options.validator || function () { return true; }; diff --git a/_static/chart-of-accounts.js b/_static/chart-of-accounts.js index c29ba430d..e8cf343d7 100644 --- a/_static/chart-of-accounts.js +++ b/_static/chart-of-accounts.js @@ -133,7 +133,7 @@ }); document.addEventListener('DOMContentLoaded', function () { - var chart = document.getElementById('chart-of-accounts'); + var chart = findAncestor(document.querySelector('.chart-of-accounts'), 'section'); if (!chart) { return; } var controls = document.createElement('div'); diff --git a/_static/coa-valuation.js b/_static/coa-valuation.js deleted file mode 100644 index 1413b4af0..000000000 --- a/_static/coa-valuation.js +++ /dev/null @@ -1,270 +0,0 @@ -(function () { - 'use strict'; - - var data = createAtom(); - - function toKey(s, postfix) { - if (postfix) { - s += ' ' + postfix; - } - return s.replace(/[^0-9a-z ]/gi, '').toLowerCase().split(/\s+/).join('-'); - - } - var Controls = React.createClass({ - render: function () { - var state = this.props.p; - return React.DOM.div(null, operations.map(function (op) { - var label = op.get('label'), operations = op.get('operations'); - return React.DOM.label( - { - key: toKey(label), - style: {display: 'block'}, - className: (operations === state.get('active') ? 'highlight-op' : void 0) - }, - React.DOM.input({ - type: 'checkbox', - checked: state.get('operations').contains(operations), - onChange: function (e) { - if (e.target.checked) { - data.swap(function (d) { - return d.set('active', operations) - .update('operations', function (ops) { - return ops.add(operations) - }); - }); - } else { - data.swap(function (d) { - return d.set('active', null) // keep visible in state map - .update('operations', function (ops) { - return ops.remove(operations); - }) - }); - } - } - }), - " ", - label - ); - })); - } - }); - - var Chart = React.createClass({ - render: function () { - var lastop = Immutable.Map( - (this.props.p.get('active') || Immutable.List()).map(function (op) { - return [op.get('account'), op.has('credit') ? 'credit' : 'debit']; - }) - ); - 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) { - var highlight = lastop.get(data.get('code')); - return React.DOM.tr( - {key: data.get('code')}, - React.DOM.th(null, - data.get('level') ? '\u2001 ' : '', - data.get('code'), ' ', data.get('label')), - React.DOM.td({className: React.addons.classSet({ - 'text-right': true, - 'highlight-op': highlight === 'debit' - })}, format(data.get('debit'))), - React.DOM.td({className: React.addons.classSet({ - 'text-right': true, - 'highlight-op': highlight === 'credit' - })}, format(data.get('credit'))), - React.DOM.td( - {className: 'text-right'}, - ((data.get('debit') || data.get('credit')) - ? format(data.get('debit') - data.get('credit'), 0) - : '') - ) - ); - }) - ) - ) - ); - }, - accounts: function() { - var data = this.props.p.get('operations'); - - var totals = data.toIndexedSeq().flatten(true).reduce(function (acc, op) { - return acc - .updateIn([op.get('account'), 'debit'], function (d) { - return (d || 0) + op.get('debit', zero)(data); - }) - .updateIn([op.get('account'), 'credit'], function (c) { - return (c || 0) + op.get('credit', zero)(data); - }); - }, Immutable.Map()); - - return accounts.map(function (account) { - // for each account, add sum - return account.merge( - account.get('accounts').map(function (code) { - return totals.get(code, NULL); - }).reduce(function (acc, it) { - return acc.mergeWith(function (a, b) { return a + b; }, it, NULL); - }) - ); - }); - } - }); - data.addWatch('chart', function (k, m, prev, next) { - React.render( - React.createElement(Controls, {p: next}), - document.getElementById('chart-controls')); - React.render( - React.createElement(Chart, {p: next}), - document.querySelector('.valuation-chart')); - }); - - document.addEventListener('DOMContentLoaded', function () { - var chart = document.querySelector('.valuation-chart'); - if (!chart) { return; } - - var controls = document.createElement('div'); - controls.setAttribute('id', 'chart-controls'); - chart.parentNode.insertBefore(controls, chart); - - data.reset(Immutable.Map({ - // last-selected operation - active: null, - // set of all currently enabled operations - operations: Immutable.OrderedSet() - })); - }); - - var NULL = Immutable.Map({debit: 0, credit: 0}); - var ASSETS = { - code: 1, - label: "Assets", - BANK: { code: 11000, label: "Cash" }, - ACCOUNTS_RECEIVABLE: { code: 13100, label: "Accounts Receivable" }, - STOCK: { code: 14000, label: "Inventory" }, - RAW_MATERIALS: { code: 14100, label: "Raw Materials Inventory" }, - STOCK_OUT: { code: 14600, label: "Goods Issued Not Invoiced" }, - TAXES_PAID: { code: 19000, label: "Deferred Tax Assets" } - }; - var LIABILITIES = { - code: 2, - label: "Liabilities", - ACCOUNTS_PAYABLE: { code: 21000, label: "Accounts Payable" }, - STOCK_IN: { code: 23000, label: "Goods Received Not Purchased" }, - TAXES_PAYABLE: { code: 26200, label: "Deferred Tax Liabilities" } - }; - var EQUITY = { - code: 3, - label: "Equity", - CAPITAL: { code: 31000, label: "Common Stock" } - }; - var REVENUE = { - code: 4, - label: "Revenue", - SALES: { code: 41000, label: "Goods" }, - }; - var EXPENSES = { - code: 5, - label: "Expenses", - GOODS_SOLD: { code: 51100, label: "Cost of Goods Sold" }, - MANUFACTURING_OVERHEAD: { code: 52000, label: "Manufacturing Overhead" }, - PRICE_DIFFERENCE: { code: 53000, label: "Price Difference" } - }; - var categories = Immutable.fromJS([ASSETS, LIABILITIES, EQUITY, REVENUE, EXPENSES], function (k, v) { - return Immutable.Iterable.isIndexed(v) - ? v.toList() - : v.toOrderedMap(); - }); - var accounts = categories.toSeq().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; }) - ) - ); - }); - - var sale = 100, - cor = 50, - cor_tax = cor * 0.09, - tax = sale * 0.09, - total = sale + tax, - purchase = 52, - purchase_tax = 52 * 0.09; - var operations = Immutable.fromJS([{ - label: "Vendor Bill (PO $50, Invoice $40)", - operations: [ - {account: LIABILITIES.STOCK_IN.code, debit: constant(50)}, - {account: ASSETS.TAXES_PAID.code, debit: constant(50 * 0.09)}, - {account: LIABILITIES.ACCOUNTS_PAYABLE.code, credit: constant(50 * 1.09)}, - ] - }, { - label: "Vendor Goods Reception (PO $50, Invoice $50)", - operations: [ - {account: LIABILITIES.STOCK_IN.code, credit: constant(50)}, - {account: ASSETS.STOCK.code, debit: constant(50)}, - ] - }, { - label: "Vendor Bill (PO $48, Invoice $50)", - operations: [ - {account: EXPENSES.PRICE_DIFFERENCE.code, debit: constant(2)}, - {account: LIABILITIES.STOCK_IN.code, debit: constant(48)}, - {account: ASSETS.TAXES_PAID.code, debit: constant(50 * 0.09)}, - {account: LIABILITIES.ACCOUNTS_PAYABLE.code, credit: constant(50 * 1.09)}, - ] - }, { - label: "Vendor Goods Reception (PO $48, Invoice $50)", - operations: [ - {account: LIABILITIES.STOCK_IN.code, credit: constant(48)}, - {account: ASSETS.STOCK.code, debit: constant(48)}, - ] - }, { - label: "Customer Invoice", - operations: [ - {account: ASSETS.ACCOUNTS_RECEIVABLE.code, debit: constant(total)}, - {account: EXPENSES.GOODS_SOLD.code, debit: constant(cor)}, - {account: REVENUE.SALES.code, credit: constant(sale)}, - {account: ASSETS.STOCK_OUT.code, credit: constant(cor)}, - {account: LIABILITIES.TAXES_PAYABLE.code, credit: constant(tax)} - ] - }, { - label: "Customer Shipping", - operations: [ - {account: ASSETS.STOCK_OUT.code, debit: constant(cor)}, - {account: ASSETS.STOCK.code, credit: constant(cor)} - ] - }, { - label: "Production Order", - operations: [ - {account: ASSETS.STOCK.code, debit: constant(50)}, - {account: EXPENSES.MANUFACTURING_OVERHEAD.code, debit: constant(2)}, - {account: ASSETS.RAW_MATERIALS.code, credit: constant(52)} - ] - }]); - function constant(val) {return function () { return val; };} - var zero = constant(0); - function format(val, def) { - if (!val) { return def === undefined ? '' : def; } - if (val % 1 === 0) { return val; } - return val.toFixed(2); - } -})(); diff --git a/_static/entries.js b/_static/entries.js index 4a2ec52fe..2da8c6275 100644 --- a/_static/entries.js +++ b/_static/entries.js @@ -11,12 +11,12 @@ document.querySelector('.journal-entries')); }); document.addEventListener('DOMContentLoaded', function () { - var entries_node = document.getElementById('journal-entries'); - if (!entries_node) { return; } + var entries_section = findAncestor(document.querySelector('.journal-entries'), 'section'); + if (!entries_section) { return; } var controls = document.createElement('div'); controls.setAttribute('id', 'entries-control'); - entries_node.insertBefore(controls, entries_node.lastElementChild); + entries_section.insertBefore(controls, entries_section.lastElementChild); data.reset(entries.first()); }); @@ -151,7 +151,7 @@ explanation: [ "Revenues increase by $100", "A tax to pay at the end of the month of $9", - "The customer owns you $109", + "The customer owes $109", "The inventory is decreased by $50 (shipping of the goods)", "The cost of goods sold decreases the gross profit by $50" ], @@ -172,7 +172,7 @@ ], explanation: [ "The company receives $109 in cash", - "The customer owns you $109 less" + "The customer owes $109 less" ], configuration: [ "Cash: defined on the journal used when registering the payment, fields Default Credit Account and Default Debit Account", diff --git a/conf.py b/conf.py index a0628a39f..bc594f9da 100644 --- a/conf.py +++ b/conf.py @@ -334,7 +334,6 @@ def setup(app): app.add_javascript('misc.js') app.add_javascript('inventory.js') - app.add_javascript('coa-valuation.js') app.add_javascript('coa-valuation-continental.js') app.add_javascript('coa-valuation-anglo-saxon.js')