Comparing version 1.0.3 to 2.0.0
{ | ||
"name": "medici", | ||
"version": "1.0.3", | ||
"version": "2.0.0", | ||
"description": "Simple double-entry accounting for Node + Mongoose", | ||
"main": "src/index.js", | ||
"scripts": { | ||
"test": "mocha" | ||
"test": "mocha && npm i mongoose@4 && mocha && npm i mongoose@5" | ||
}, | ||
@@ -32,9 +32,10 @@ "files": [ | ||
"dependencies": { | ||
"mongoose": "^4.11.7" | ||
"mongoose": "^5.2.2" | ||
}, | ||
"homepage": "https://github.com/koresar/medici", | ||
"devDependencies": { | ||
"mocha": "^3.5.0", | ||
"mocha": "^5.2.0", | ||
"prettier": "^1.13.7", | ||
"should": "^11.2.1" | ||
} | ||
} |
187
README.md
[![Build Status](https://travis-ci.org/koresar/medici.png?branch=master)](https://travis-ci.org/koresar/medici) | ||
medici | ||
====== | ||
# medici | ||
@@ -12,3 +11,3 @@ Double-entry accounting system for nodejs + mongoose | ||
Medici divides itself into "books", each of which store *journal entries* and their child *transactions*. The cardinal rule of double-entry accounting is that "everything must balance out to zero", and that rule is applied to every journal entry written to the book. If the transactions for a journal entry do not balance out to zero, the system will throw a new error with the message `INVALID JOURNAL`. | ||
Medici divides itself into "books", each of which store _journal entries_ and their child _transactions_. The cardinal rule of double-entry accounting is that "for every debit entry, there must be a corresponding credit entry" which means "everything must balance out to zero", and that rule is applied to every journal entry written to the book. If the transactions for a journal entry do not balance out to zero, the system will throw a new error with the message `INVALID JOURNAL`. | ||
@@ -26,6 +25,6 @@ Books simply represent the physical book in which you would record your transactions - on a technical level, the "book" attribute simply is added as a key-value pair to both the `Medici_Transactions` and `Medici_Journals` collection to allow you to have multiple books if you want to. | ||
```js | ||
const {book} = require('medici'); | ||
const { book } = require("medici"); | ||
// The first argument is the book name, which is used to determine which book the transactions and journals are queried from. | ||
const myBook = new book('MyBook'); | ||
const myBook = new book("MyBook"); | ||
``` | ||
@@ -52,11 +51,13 @@ | ||
```js | ||
myBook.balance({ | ||
account:'Assets:Accounts Receivable', | ||
client:'Joe Blow' | ||
}).then((balance) => { | ||
myBook | ||
.balance({ | ||
account: "Assets:Accounts Receivable", | ||
client: "Joe Blow" | ||
}) | ||
.then(balance => { | ||
console.log("Joe Blow owes me", balance); | ||
}); | ||
}); | ||
``` | ||
Note that the `meta` query parameters are on the same level as the default query parameters (account, _journal, start_date, end_date). Medici parses the query and automatically turns any values that do not match top-level schema properties into meta parameters. | ||
Note that the `meta` query parameters are on the same level as the default query parameters (account, \_journal, start_date, end_date). Medici parses the query and automatically turns any values that do not match top-level schema properties into meta parameters. | ||
@@ -68,12 +69,16 @@ ## Retrieving Transactions | ||
```js | ||
const startDate = moment().subtract('months', 1).toDate(); // One month ago | ||
const startDate = moment() | ||
.subtract("months", 1) | ||
.toDate(); // One month ago | ||
const endDate = new Date(); //today | ||
myBook.ledger({ | ||
account: 'Income', | ||
myBook | ||
.ledger({ | ||
account: "Income", | ||
start_date: startDate, | ||
end_date: endDate | ||
}).then((transactions) => { | ||
}) | ||
.then(transactions => { | ||
// Do something with the returned transaction documents | ||
}); | ||
}); | ||
``` | ||
@@ -86,7 +91,7 @@ | ||
To void a journal entry, you can either call the `void(void_reason)` method on a Medici_Journal document, or use the `book.void(journal_id, void_reason)` method if you know the journal document's ID. | ||
```js | ||
myBook.void("123456", "I made a mistake").then(() => { | ||
// Do something after voiding | ||
}) | ||
// Do something after voiding | ||
}); | ||
``` | ||
@@ -96,3 +101,2 @@ | ||
## Document Schema | ||
@@ -104,18 +108,20 @@ | ||
JournalSchema = { | ||
datetime: Date, | ||
memo: { | ||
type: String, | ||
default: '' | ||
}, | ||
_transactions: [{ | ||
type: Schema.Types.ObjectId, | ||
ref: 'Medici_Transaction' | ||
}], | ||
book: String, | ||
voided: { | ||
type: Boolean, | ||
default: false | ||
}, | ||
void_reason: String | ||
} | ||
datetime: Date, | ||
memo: { | ||
type: String, | ||
default: "" | ||
}, | ||
_transactions: [ | ||
{ | ||
type: Schema.Types.ObjectId, | ||
ref: "Medici_Transaction" | ||
} | ||
], | ||
book: String, | ||
voided: { | ||
type: Boolean, | ||
default: false | ||
}, | ||
void_reason: String | ||
}; | ||
``` | ||
@@ -127,21 +133,21 @@ | ||
TransactionSchema = { | ||
credit: Number, | ||
debit: Number, | ||
meta: Schema.Types.Mixed, | ||
datetime: Date, | ||
account_path: [String], | ||
accounts: String, | ||
book: String, | ||
memo: String, | ||
_journal: { | ||
type: Schema.Types.ObjectId, | ||
ref:'Medici_Journal' | ||
}, | ||
timestamp: Date, | ||
voided: { | ||
type: Boolean, | ||
default: false | ||
}, | ||
void_reason: String | ||
} | ||
credit: Number, | ||
debit: Number, | ||
meta: Schema.Types.Mixed, | ||
datetime: Date, | ||
account_path: [String], | ||
accounts: String, | ||
book: String, | ||
memo: String, | ||
_journal: { | ||
type: Schema.Types.ObjectId, | ||
ref: "Medici_Journal" | ||
}, | ||
timestamp: Date, | ||
voided: { | ||
type: Boolean, | ||
default: false | ||
}, | ||
void_reason: String | ||
}; | ||
``` | ||
@@ -151,4 +157,2 @@ | ||
### Customizing the Transaction document schema | ||
@@ -162,25 +166,25 @@ | ||
MyTransactionSchema = { | ||
_person: { | ||
type:Schema.Types.ObjectId, | ||
ref:'Person' | ||
}, | ||
credit: Number, | ||
debit: Number, | ||
meta: Schema.Types.Mixed, | ||
datetime: Date, | ||
account_path: [String], | ||
accounts: String, | ||
book: String, | ||
memo: String, | ||
_journal: { | ||
type: Schema.Types.ObjectId, | ||
ref: 'Medici_Journal' | ||
}, | ||
timestamp: Date, | ||
voided: { | ||
type: Boolean, | ||
default: false | ||
}, | ||
void_reason: String | ||
} | ||
_person: { | ||
type: Schema.Types.ObjectId, | ||
ref: "Person" | ||
}, | ||
credit: Number, | ||
debit: Number, | ||
meta: Schema.Types.Mixed, | ||
datetime: Date, | ||
account_path: [String], | ||
accounts: String, | ||
book: String, | ||
memo: String, | ||
_journal: { | ||
type: Schema.Types.ObjectId, | ||
ref: "Medici_Journal" | ||
}, | ||
timestamp: Date, | ||
voided: { | ||
type: Boolean, | ||
default: false | ||
}, | ||
void_reason: String | ||
}; | ||
``` | ||
@@ -192,10 +196,15 @@ | ||
* **v1.0.0** _See [this PR](https://github.com/koresar/medici/pull/5) for more details_ | ||
* **BREAKING**: Dropped support of node.js v0.10, v0.12, v4, and io.js. Node.js >= v6 is supported only. This allowed to drop several production dependencies. Also, few bugs were automatically fixed. | ||
* **BREAKING**: Upgraded `mongoose` to v4. This allows `medici` to be used with wider mongodb versions. | ||
* Dropped production dependencies: `moment`, `q`, `underscore`. | ||
* Dropped dev dependencies: `grunt`, `grunt-exec`, `grunt-contrib-coffee`, `grunt-sed`, `grunt-contrib-watch`, `semver`. | ||
* No `.coffee` any more. Using node.js v6 compatible JavaScript only. | ||
* There are no API changes. | ||
* Fixed a [bug](https://github.com/koresar/medici/issues/4). Transaction meta data was not voided correctly. | ||
* This module maintainer is now [koresar](https://github.com/koresar) instead of the original author [jraede](http://github.com/jraede). | ||
- **v1.1.0** | ||
- Support two mongoose versions simultaneously - v4 and v5. | ||
- Support node.js v10. | ||
- **v1.0.0** _See [this PR](https://github.com/koresar/medici/pull/5) for more details_ | ||
- **BREAKING**: Dropped support of node.js v0.10, v0.12, v4, and io.js. Node.js >= v6 is supported only. This allowed to drop several production dependencies. Also, few bugs were automatically fixed. | ||
- **BREAKING**: Upgraded `mongoose` to v4. This allows `medici` to be used with wider mongodb versions. | ||
- Dropped production dependencies: `moment`, `q`, `underscore`. | ||
- Dropped dev dependencies: `grunt`, `grunt-exec`, `grunt-contrib-coffee`, `grunt-sed`, `grunt-contrib-watch`, `semver`. | ||
- No `.coffee` any more. Using node.js v6 compatible JavaScript only. | ||
- There are no API changes. | ||
- Fixed a [bug](https://github.com/koresar/medici/issues/4). Transaction meta data was not voided correctly. | ||
- This module maintainer is now [koresar](https://github.com/koresar) instead of the original author [jraede](http://github.com/jraede). |
157
src/book.js
@@ -1,3 +0,3 @@ | ||
const mongoose = require('mongoose'); | ||
const entry = require('./entry'); | ||
const mongoose = require("mongoose"); | ||
const entry = require("./entry"); | ||
@@ -7,4 +7,4 @@ module.exports = class Book { | ||
this.name = name; | ||
this.transactionModel = mongoose.model('Medici_Transaction'); | ||
this.journalModel = mongoose.model('Medici_Journal'); | ||
this.transactionModel = mongoose.model("Medici_Transaction"); | ||
this.journalModel = mongoose.model("Medici_Journal"); | ||
} | ||
@@ -30,3 +30,3 @@ | ||
for (let acct of account) { | ||
accounts = acct.split(':'); | ||
accounts = acct.split(":"); | ||
const match = {}; | ||
@@ -38,5 +38,5 @@ for (i = 0; i < accounts.length; i++) { | ||
} | ||
parsed['$or'] = $or; | ||
parsed["$or"] = $or; | ||
} else { | ||
accounts = account.split(':'); | ||
accounts = account.split(":"); | ||
for (i = 0; i < accounts.length; i++) { | ||
@@ -50,3 +50,3 @@ parsed[`account_path.${i}`] = accounts[i]; | ||
if (query._journal) { | ||
parsed['_journal'] = query._journal; | ||
parsed["_journal"] = query._journal; | ||
} | ||
@@ -57,3 +57,3 @@ | ||
end_date = new Date(parseInt(query.end_date)); | ||
parsed['datetime'] = { | ||
parsed["datetime"] = { | ||
$gte: start_date, | ||
@@ -65,6 +65,6 @@ $lte: end_date | ||
} else if (query.start_date) { | ||
parsed['datetime'] = {$gte: new Date(parseInt(query.start_date))}; | ||
parsed["datetime"] = { $gte: new Date(parseInt(query.start_date)) }; | ||
delete query.start_date; | ||
} else if (query.end_date) { | ||
parsed['datetime'] = {$lte: new Date(parseInt(query.end_date))}; | ||
parsed["datetime"] = { $lte: new Date(parseInt(query.end_date)) }; | ||
delete query.end_date; | ||
@@ -78,3 +78,3 @@ } | ||
// If it starts with a _ assume it's a reference | ||
if (key.substr(0, 1) === '_' && val instanceof String) { | ||
if (key.substr(0, 1) === "_" && val instanceof String) { | ||
val = mongoose.Types.ObjectId(val); | ||
@@ -85,3 +85,3 @@ } | ||
// Assume *_id is an OID | ||
if (key.indexOf('_id') > 0) { | ||
if (key.indexOf("_id") > 0) { | ||
val = mongoose.Types.ObjectId(val); | ||
@@ -114,10 +114,10 @@ } | ||
query = this.parseQuery(query); | ||
const match = {$match: query}; | ||
const match = { $match: query }; | ||
const project = { | ||
$project: { | ||
debit: '$debit', | ||
credit: '$credit', | ||
datetime: '$datetime', | ||
timestamp: '$timestamp' | ||
debit: "$debit", | ||
credit: "$credit", | ||
datetime: "$datetime", | ||
timestamp: "$timestamp" | ||
} | ||
@@ -127,8 +127,8 @@ }; | ||
$group: { | ||
_id: '1', | ||
_id: "1", | ||
credit: { | ||
$sum: '$credit' | ||
$sum: "$credit" | ||
}, | ||
debit: { | ||
$sum: '$debit' | ||
$sum: "$debit" | ||
}, | ||
@@ -141,3 +141,3 @@ count: { | ||
if (pagination) { | ||
const skip = {$skip: (pagination.page - 1) * pagination.perPage}; | ||
const skip = { $skip: (pagination.page - 1) * pagination.perPage }; | ||
const sort = { | ||
@@ -150,37 +150,37 @@ $sort: { | ||
return this.transactionModel | ||
.aggregate(match, project, sort, skip, group) | ||
.then(function (result) { | ||
result = result.shift(); | ||
if (!result) { | ||
.aggregate([match, project, sort, skip, group]) | ||
.then(function(result) { | ||
result = result.shift(); | ||
if (!result) { | ||
return { | ||
balance: 0, | ||
notes: 0 | ||
}; | ||
} | ||
const total = result.credit - result.debit; | ||
return { | ||
balance: 0, | ||
notes: 0 | ||
balance: total, | ||
notes: result.count | ||
}; | ||
} | ||
const total = result.credit - result.debit; | ||
return { | ||
balance: total, | ||
notes: result.count | ||
}; | ||
}); | ||
}); | ||
} else { | ||
return this.transactionModel | ||
.aggregate(match, project, group) | ||
.then(function (result) { | ||
result = result.shift(); | ||
if (!result) { | ||
.aggregate([match, project, group]) | ||
.then(function(result) { | ||
result = result.shift(); | ||
if (!result) { | ||
return { | ||
balance: 0, | ||
notes: 0 | ||
}; | ||
} | ||
const total = result.credit - result.debit; | ||
return { | ||
balance: 0, | ||
notes: 0 | ||
balance: total, | ||
notes: result.count | ||
}; | ||
} | ||
const total = result.credit - result.debit; | ||
return { | ||
balance: total, | ||
notes: result.count | ||
}; | ||
}); | ||
}); | ||
} | ||
@@ -206,7 +206,6 @@ } | ||
if (pagination) { | ||
return this.transactionModel.count(query) | ||
.then(count => { | ||
q | ||
.skip((pagination.page - 1) * pagination.perPage) | ||
.limit(pagination.perPage); | ||
return this.transactionModel.count(query).then(count => { | ||
q.skip((pagination.page - 1) * pagination.perPage).limit( | ||
pagination.perPage | ||
); | ||
q.sort({ | ||
@@ -222,4 +221,3 @@ datetime: -1, | ||
return q.exec() | ||
.then(function (results) { | ||
return q.exec().then(function(results) { | ||
return { | ||
@@ -242,4 +240,3 @@ results, | ||
return q.exec() | ||
.then(function (results) { | ||
return q.exec().then(function(results) { | ||
return { | ||
@@ -255,4 +252,4 @@ results, | ||
return this.journalModel | ||
.findById(journal_id) | ||
.then(journal => journal.void(this, reason)); | ||
.findById(journal_id) | ||
.then(journal => journal.void(this, reason)); | ||
} | ||
@@ -262,22 +259,22 @@ | ||
return this.transactionModel | ||
.find({book: this.name}) | ||
.distinct('accounts') | ||
.then(function (results) { | ||
// Make array | ||
const final = []; | ||
for (let result of results) { | ||
const paths = result.split(':'); | ||
const prev = []; | ||
for (let acct of paths) { | ||
prev.push(acct); | ||
final.push(prev.join(':')); | ||
.find({ book: this.name }) | ||
.distinct("accounts") | ||
.then(function(results) { | ||
// Make array | ||
const final = []; | ||
for (let result of results) { | ||
const paths = result.split(":"); | ||
const prev = []; | ||
for (let acct of paths) { | ||
prev.push(acct); | ||
final.push(prev.join(":")); | ||
} | ||
} | ||
} | ||
return Array.from(new Set(final)); // uniques | ||
}) | ||
.catch(err => { | ||
console.error(err); | ||
throw err; | ||
}); | ||
return Array.from(new Set(final)); // uniques | ||
}) | ||
.catch(err => { | ||
console.error(err); | ||
throw err; | ||
}); | ||
} | ||
}; |
@@ -8,3 +8,3 @@ module.exports = class Entry { | ||
this.book = book; | ||
const {journalModel} = this.book; | ||
const { journalModel } = this.book; | ||
this.journal = new journalModel(); | ||
@@ -34,8 +34,8 @@ this.journal.memo = memo; | ||
amount = parseFloat(amount); | ||
if (typeof account_path === 'string') { | ||
account_path = account_path.split(':'); | ||
if (typeof account_path === "string") { | ||
account_path = account_path.split(":"); | ||
} | ||
if (account_path.length > 3) { | ||
throw 'Account path is too deep (maximum 3)'; | ||
throw "Account path is too deep (maximum 3)"; | ||
} | ||
@@ -45,3 +45,3 @@ | ||
account_path, | ||
accounts: account_path.join(':'), | ||
accounts: account_path.join(":"), | ||
credit: amount, | ||
@@ -76,7 +76,7 @@ debit: 0.0, | ||
amount = parseFloat(amount); | ||
if (typeof account_path === 'string') { | ||
account_path = account_path.split(':'); | ||
if (typeof account_path === "string") { | ||
account_path = account_path.split(":"); | ||
} | ||
if (account_path.length > 3) { | ||
throw 'Account path is too deep (maximum 3)'; | ||
throw "Account path is too deep (maximum 3)"; | ||
} | ||
@@ -86,3 +86,3 @@ | ||
account_path, | ||
accounts: account_path.join(':'), | ||
accounts: account_path.join(":"), | ||
credit: 0.0, | ||
@@ -144,16 +144,19 @@ debit: amount, | ||
if (total > 0 || total < 0) { | ||
const err = new Error('INVALID_JOURNAL'); | ||
const err = new Error("INVALID_JOURNAL"); | ||
err.code = 400; | ||
console.error('Journal is invalid. Total is:', total); | ||
console.error("Journal is invalid. Total is:", total); | ||
return Promise.reject(err); | ||
} else { | ||
return Promise.all(this.transactions.map(tx => this.saveTransaction(tx))) | ||
.then(() => { | ||
return this.journal.save() | ||
.then(() => this.journal).catch(err => { | ||
this.book.transactionModel.remove({ | ||
_journal: this.journal._id | ||
return Promise.all( | ||
this.transactions.map(tx => this.saveTransaction(tx)) | ||
).then(() => { | ||
return this.journal | ||
.save() | ||
.then(() => this.journal) | ||
.catch(err => { | ||
this.book.transactionModel.remove({ | ||
_journal: this.journal._id | ||
}); | ||
throw new Error(`Failure to save journal: ${err.message}`); | ||
}); | ||
throw new Error(`Failure to save journal: ${err.message}`); | ||
}); | ||
}); | ||
@@ -160,0 +163,0 @@ } |
182
src/index.js
@@ -1,4 +0,4 @@ | ||
const Book = require('./book'); | ||
const mongoose = require('mongoose'); | ||
const {Schema} = mongoose; | ||
const Book = require("./book"); | ||
const mongoose = require("mongoose"); | ||
const { Schema } = mongoose; | ||
@@ -8,3 +8,3 @@ // This lets you register your own schema before including Medici. Useful if you want to store additional information | ||
try { | ||
mongoose.model('Medici_Transaction'); | ||
mongoose.model("Medici_Transaction"); | ||
} catch (error) { | ||
@@ -22,3 +22,3 @@ const transactionSchema = new Schema({ | ||
type: Schema.Types.ObjectId, | ||
ref: 'Medici_Journal' | ||
ref: "Medici_Journal" | ||
}, | ||
@@ -41,3 +41,3 @@ timestamp: { | ||
}); | ||
mongoose.model('Medici_Transaction', transactionSchema); | ||
mongoose.model("Medici_Transaction", transactionSchema); | ||
} | ||
@@ -50,3 +50,3 @@ | ||
try { | ||
journalSchema = mongoose.model('Medici_Journal'); | ||
journalSchema = mongoose.model("Medici_Journal"); | ||
} catch (error) { | ||
@@ -57,3 +57,3 @@ journalSchema = new Schema({ | ||
type: String, | ||
default: '' | ||
default: "" | ||
}, | ||
@@ -63,3 +63,3 @@ _transactions: [ | ||
type: Schema.Types.ObjectId, | ||
ref: 'Medici_Transaction' | ||
ref: "Medici_Transaction" | ||
} | ||
@@ -79,5 +79,5 @@ ], | ||
journalSchema.methods.void = function (book, reason) { | ||
journalSchema.methods.void = function(book, reason) { | ||
if (this.voided === true) { | ||
return Promise.reject(new Error('Journal already voided')); | ||
return Promise.reject(new Error("Journal already voided")); | ||
} | ||
@@ -88,3 +88,3 @@ | ||
if (!reason) { | ||
this.void_reason = ''; | ||
this.void_reason = ""; | ||
} else { | ||
@@ -96,83 +96,83 @@ this.void_reason = reason; | ||
return mongoose | ||
.model('Medici_Transaction') | ||
.findByIdAndUpdate(trans_id, { | ||
voided: true, | ||
void_reason: this.void_reason | ||
}) | ||
.catch(err => { | ||
console.error('Failed to void transaction:', err); | ||
throw err; | ||
}); | ||
.model("Medici_Transaction") | ||
.findByIdAndUpdate(trans_id, { | ||
voided: true, | ||
void_reason: this.void_reason | ||
}) | ||
.catch(err => { | ||
console.error("Failed to void transaction:", err); | ||
throw err; | ||
}); | ||
}; | ||
return Promise.all(this._transactions.map(voidTransaction)) | ||
.then(transactions => { | ||
let newMemo; | ||
if (this.void_reason) { | ||
newMemo = this.void_reason; | ||
} else { | ||
// It's either VOID, UNVOID, or REVOID | ||
if (this.memo.substr(0, 6) === '[VOID]') { | ||
newMemo = this.memo.replace('[VOID]', '[UNVOID]'); | ||
} else if (this.memo.substr(0, 8) === '[UNVOID]') { | ||
newMemo = this.memo.replace('[UNVOID]', '[REVOID]'); | ||
} else if (this.memo.substr(0, 8) === '[REVOID]') { | ||
newMemo = this.memo.replace('[REVOID]', '[UNVOID]'); | ||
return Promise.all(this._transactions.map(voidTransaction)).then( | ||
transactions => { | ||
let newMemo; | ||
if (this.void_reason) { | ||
newMemo = this.void_reason; | ||
} else { | ||
newMemo = `[VOID] ${this.memo}`; | ||
// It's either VOID, UNVOID, or REVOID | ||
if (this.memo.substr(0, 6) === "[VOID]") { | ||
newMemo = this.memo.replace("[VOID]", "[UNVOID]"); | ||
} else if (this.memo.substr(0, 8) === "[UNVOID]") { | ||
newMemo = this.memo.replace("[UNVOID]", "[REVOID]"); | ||
} else if (this.memo.substr(0, 8) === "[REVOID]") { | ||
newMemo = this.memo.replace("[REVOID]", "[UNVOID]"); | ||
} else { | ||
newMemo = `[VOID] ${this.memo}`; | ||
} | ||
} | ||
} | ||
// Ok now create an equal and opposite journal | ||
const entry = book.entry(newMemo, null, this._id); | ||
const valid_fields = [ | ||
'credit', | ||
'debit', | ||
'account_path', | ||
'accounts', | ||
'datetime', | ||
'book', | ||
'memo', | ||
'timestamp', | ||
'voided', | ||
'void_reason', | ||
'_original_journal' | ||
]; | ||
// Ok now create an equal and opposite journal | ||
const entry = book.entry(newMemo, null, this._id); | ||
const valid_fields = [ | ||
"credit", | ||
"debit", | ||
"account_path", | ||
"accounts", | ||
"datetime", | ||
"book", | ||
"memo", | ||
"timestamp", | ||
"voided", | ||
"void_reason", | ||
"_original_journal" | ||
]; | ||
function processMetaField(key, val, meta) { | ||
if (key === '_id' || key === '_journal') { | ||
} else if (valid_fields.indexOf(key) === -1) { | ||
return meta[key] = val; | ||
function processMetaField(key, val, meta) { | ||
if (key === "_id" || key === "_journal") { | ||
} else if (valid_fields.indexOf(key) === -1) { | ||
return (meta[key] = val); | ||
} | ||
} | ||
} | ||
for (let trans of transactions) { | ||
trans = trans.toObject(); | ||
const meta = {}; | ||
for (let trans of transactions) { | ||
trans = trans.toObject(); | ||
const meta = {}; | ||
Object.keys(trans).forEach(key => { | ||
const val = trans[key]; | ||
if (key === 'meta') { | ||
Object.keys(trans['meta']).forEach(keyMeta => { | ||
processMetaField(keyMeta, trans['meta'][keyMeta], meta); | ||
}); | ||
} else { | ||
processMetaField(key, val, meta); | ||
Object.keys(trans).forEach(key => { | ||
const val = trans[key]; | ||
if (key === "meta") { | ||
Object.keys(trans["meta"]).forEach(keyMeta => { | ||
processMetaField(keyMeta, trans["meta"][keyMeta], meta); | ||
}); | ||
} else { | ||
processMetaField(key, val, meta); | ||
} | ||
}); | ||
if (trans.credit) { | ||
entry.debit(trans.account_path, trans.credit, meta); | ||
} | ||
}); | ||
if (trans.debit) { | ||
entry.credit(trans.account_path, trans.debit, meta); | ||
} | ||
} | ||
if (trans.credit) { | ||
entry.debit(trans.account_path, trans.credit, meta); | ||
} | ||
if (trans.debit) { | ||
entry.credit(trans.account_path, trans.debit, meta); | ||
} | ||
return entry.commit(); | ||
} | ||
return entry.commit(); | ||
}); | ||
); | ||
}; | ||
journalSchema.pre('save', function (next) { | ||
if (!(this.isModified('approved') && this.approved === true)) { | ||
journalSchema.pre("save", function(next) { | ||
if (!(this.isModified("approved") && this.approved === true)) { | ||
return next(); | ||
@@ -182,14 +182,16 @@ } | ||
return mongoose | ||
.model('Medici_Transaction') | ||
.find({_journal: this._id}) | ||
.then((transactions) => Promise.all(transactions.map(tx => { | ||
tx.approved = true; | ||
return tx.save(); | ||
})) | ||
.then(() => next()) | ||
); | ||
.model("Medici_Transaction") | ||
.find({ _journal: this._id }) | ||
.then(transactions => | ||
Promise.all( | ||
transactions.map(tx => { | ||
tx.approved = true; | ||
return tx.save(); | ||
}) | ||
).then(() => next()) | ||
); | ||
}); | ||
mongoose.model('Medici_Journal', journalSchema); | ||
mongoose.model("Medici_Journal", journalSchema); | ||
} | ||
module.exports = {book: Book}; | ||
module.exports = { book: Book }; |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
25948
552
200
3
+ Added@types/bson@4.0.5(transitive)
+ Added@types/mongodb@3.6.20(transitive)
+ Added@types/node@22.9.1(transitive)
+ Addedbl@2.2.1(transitive)
+ Addedbluebird@3.5.1(transitive)
+ Addedbson@1.1.6(transitive)
+ Addeddebug@3.1.0(transitive)
+ Addeddenque@1.5.1(transitive)
+ Addedkareem@2.3.2(transitive)
+ Addedmemory-pager@1.5.0(transitive)
+ Addedmongodb@3.7.4(transitive)
+ Addedmongoose@5.13.22(transitive)
+ Addedmongoose-legacy-pluralize@1.0.2(transitive)
+ Addedmpath@0.8.4(transitive)
+ Addedmquery@3.2.5(transitive)
+ Addedms@2.1.2(transitive)
+ Addedoptional-require@1.0.31.1.8(transitive)
+ Addedprocess-nextick-args@2.0.1(transitive)
+ Addedreadable-stream@2.3.8(transitive)
+ Addedregexp-clone@1.0.0(transitive)
+ Addedrequire-at@1.0.6(transitive)
+ Addedsafe-buffer@5.2.1(transitive)
+ Addedsaslprep@1.0.3(transitive)
+ Addedsift@13.5.2(transitive)
+ Addedsparse-bitfield@3.0.3(transitive)
+ Addedstring_decoder@1.1.1(transitive)
+ Addedundici-types@6.19.8(transitive)
- Removedasync@2.6.0(transitive)
- Removedbluebird@3.5.0(transitive)
- Removedbson@1.0.9(transitive)
- Removedbuffer-shims@1.0.0(transitive)
- Removeddebug@2.6.9(transitive)
- Removedes6-promise@3.2.1(transitive)
- Removedhooks-fixed@2.0.2(transitive)
- Removedkareem@1.5.0(transitive)
- Removedlodash@4.17.21(transitive)
- Removedlodash.get@4.4.2(transitive)
- Removedmongodb@2.2.34(transitive)
- Removedmongodb-core@2.1.18(transitive)
- Removedmongoose@4.13.21(transitive)
- Removedmpath@0.5.1(transitive)
- Removedmpromise@0.5.5(transitive)
- Removedmquery@2.3.3(transitive)
- Removedmuri@1.3.0(transitive)
- Removedprocess-nextick-args@1.0.7(transitive)
- Removedreadable-stream@2.2.7(transitive)
- Removedregexp-clone@0.0.1(transitive)
- Removedrequire_optional@1.0.1(transitive)
- Removedresolve-from@2.0.0(transitive)
- Removedsemver@5.7.2(transitive)
- Removedsliced@0.0.5(transitive)
- Removedstring_decoder@1.0.3(transitive)
Updatedmongoose@^5.2.2