mirror of
https://github.com/frappe/books.git
synced 2025-03-31 23:41:32 +00:00
added ledger
This commit is contained in:
parent
c5b9ae8691
commit
b72878110d
83
accounting/ledgerPosting.js
Normal file
83
accounting/ledgerPosting.js
Normal file
@ -0,0 +1,83 @@
|
|||||||
|
const frappe = require('frappejs');
|
||||||
|
|
||||||
|
module.exports = class LedgerPosting {
|
||||||
|
constructor({reference, party, date, description}) {
|
||||||
|
Object.assign(this, arguments[0]);
|
||||||
|
this.entries = [];
|
||||||
|
this.entryMap = {};
|
||||||
|
}
|
||||||
|
|
||||||
|
debit(account, amount) {
|
||||||
|
const entry = this.getEntry(account);
|
||||||
|
entry.debit += amount;
|
||||||
|
}
|
||||||
|
|
||||||
|
credit(account, amount) {
|
||||||
|
const entry = this.getEntry(account);
|
||||||
|
entry.credit += amount;
|
||||||
|
}
|
||||||
|
|
||||||
|
getEntry(account) {
|
||||||
|
if (!this.entryMap[account]) {
|
||||||
|
const entry = {
|
||||||
|
account: account,
|
||||||
|
party: this.party,
|
||||||
|
date: this.date || this.reference.date,
|
||||||
|
referenceType: this.reference.doctype,
|
||||||
|
referenceName: this.reference.name,
|
||||||
|
description: this.description,
|
||||||
|
debit: 0,
|
||||||
|
credit: 0
|
||||||
|
};
|
||||||
|
|
||||||
|
this.entries.push(entry);
|
||||||
|
this.entryMap[account] = entry;
|
||||||
|
}
|
||||||
|
|
||||||
|
return this.entryMap[account];
|
||||||
|
}
|
||||||
|
|
||||||
|
async post() {
|
||||||
|
this.validateEntries();
|
||||||
|
await this.insertEntries();
|
||||||
|
}
|
||||||
|
|
||||||
|
async postReverse() {
|
||||||
|
this.validateEntries();
|
||||||
|
let temp;
|
||||||
|
for (let entry of this.entries) {
|
||||||
|
temp = entry.debit;
|
||||||
|
entry.debit = entry.credit;
|
||||||
|
entry.credit = temp;
|
||||||
|
}
|
||||||
|
await this.insertEntries();
|
||||||
|
}
|
||||||
|
|
||||||
|
validateEntries() {
|
||||||
|
let debit = 0, credit = 0;
|
||||||
|
let debitAccounts = [], creditAccounts = [];
|
||||||
|
for (let entry of this.entries) {
|
||||||
|
debit += entry.debit;
|
||||||
|
credit += entry.credit;
|
||||||
|
if (debit) {
|
||||||
|
debitAccounts.push(entry.account);
|
||||||
|
} else {
|
||||||
|
creditAccounts.push(entry.account);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (debit !== credit) {
|
||||||
|
throw frappe.errors.ValidationError(frappe._("Debit {0} must be equal to Credit {1}", [debit, credit]));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async insertEntries() {
|
||||||
|
for (let entry of this.entries) {
|
||||||
|
let entryDoc = frappe.newDoc({
|
||||||
|
doctype: 'AccountingLedgerEntry'
|
||||||
|
});
|
||||||
|
Object.assign(entryDoc, entry);
|
||||||
|
await entryDoc.insert();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
67
dist/css/style.css
vendored
67
dist/css/style.css
vendored
@ -1,3 +1,4 @@
|
|||||||
|
@charset "UTF-8";
|
||||||
/*!
|
/*!
|
||||||
* Bootstrap v4.0.0 (https://getbootstrap.com)
|
* Bootstrap v4.0.0 (https://getbootstrap.com)
|
||||||
* Copyright 2011-2018 The Bootstrap Authors
|
* Copyright 2011-2018 The Bootstrap Authors
|
||||||
@ -7129,10 +7130,10 @@ div.CodeMirror-dragcursors {
|
|||||||
/* Help users use markselection to safely style text background */
|
/* Help users use markselection to safely style text background */
|
||||||
span.CodeMirror-selectedtext {
|
span.CodeMirror-selectedtext {
|
||||||
background: none; }
|
background: none; }
|
||||||
|
/* This file is processed by postcss */
|
||||||
/* variables */
|
/* variables */
|
||||||
.data-table {
|
.data-table {
|
||||||
/* styling */
|
/* styling */
|
||||||
width: 100%;
|
|
||||||
position: relative;
|
position: relative;
|
||||||
overflow: auto; }
|
overflow: auto; }
|
||||||
/* resets */
|
/* resets */
|
||||||
@ -7184,16 +7185,22 @@ span.CodeMirror-selectedtext {
|
|||||||
top: 50%;
|
top: 50%;
|
||||||
-webkit-transform: translateY(-50%);
|
-webkit-transform: translateY(-50%);
|
||||||
transform: translateY(-50%); }
|
transform: translateY(-50%); }
|
||||||
.data-table .trash-container {
|
|
||||||
position: absolute;
|
|
||||||
bottom: 0;
|
|
||||||
left: 30%;
|
|
||||||
right: 30%;
|
|
||||||
height: 70px;
|
|
||||||
background: palevioletred;
|
|
||||||
opacity: 0.5; }
|
|
||||||
.data-table .hide {
|
.data-table .hide {
|
||||||
display: none; }
|
display: none; }
|
||||||
|
.data-table .toast-message {
|
||||||
|
position: absolute;
|
||||||
|
bottom: 16px;
|
||||||
|
bottom: 1rem;
|
||||||
|
left: 50%;
|
||||||
|
-webkit-transform: translateX(-50%);
|
||||||
|
transform: translateX(-50%); }
|
||||||
|
.data-table .toast-message span {
|
||||||
|
display: inline-block;
|
||||||
|
background-color: rgba(0, 0, 0, 0.8);
|
||||||
|
color: #dfe2e5;
|
||||||
|
border-radius: 3px;
|
||||||
|
padding: 8px 16px;
|
||||||
|
padding: 0.5rem 1rem; }
|
||||||
.body-scrollable {
|
.body-scrollable {
|
||||||
max-height: 500px;
|
max-height: 500px;
|
||||||
overflow: auto;
|
overflow: auto;
|
||||||
@ -7256,42 +7263,54 @@ span.CodeMirror-selectedtext {
|
|||||||
padding: 0.5rem 1rem; }
|
padding: 0.5rem 1rem; }
|
||||||
.data-table-header .data-table-dropdown-list > div:hover {
|
.data-table-header .data-table-dropdown-list > div:hover {
|
||||||
background-color: #f5f7fa; }
|
background-color: #f5f7fa; }
|
||||||
.data-table-header .data-table-col.remove-column {
|
.data-table-header .data-table-cell.remove-column {
|
||||||
background-color: #FD8B8B;
|
background-color: #FD8B8B;
|
||||||
-webkit-transition: 300ms background-color ease-in-out;
|
-webkit-transition: 300ms background-color ease-in-out;
|
||||||
transition: 300ms background-color ease-in-out; }
|
transition: 300ms background-color ease-in-out; }
|
||||||
.data-table-header .data-table-col.sortable-chosen {
|
.data-table-header .data-table-cell.sortable-chosen {
|
||||||
background-color: #f5f7fa; }
|
background-color: #f5f7fa; }
|
||||||
.data-table-col {
|
.data-table-cell {
|
||||||
position: relative; }
|
position: relative; }
|
||||||
.data-table-col .content {
|
.data-table-cell .content {
|
||||||
padding: 8px;
|
padding: 8px;
|
||||||
padding: 0.5rem;
|
padding: 0.5rem;
|
||||||
border: 2px solid transparent; }
|
border: 2px solid transparent; }
|
||||||
.data-table-col .content.ellipsis {
|
.data-table-cell .content.ellipsis {
|
||||||
text-overflow: ellipsis;
|
text-overflow: ellipsis;
|
||||||
white-space: nowrap;
|
white-space: nowrap;
|
||||||
overflow: hidden; }
|
overflow: hidden; }
|
||||||
.data-table-col .edit-cell {
|
.data-table-cell .edit-cell {
|
||||||
display: none;
|
display: none;
|
||||||
padding: 8px;
|
padding: 8px;
|
||||||
padding: 0.5rem;
|
padding: 0.5rem;
|
||||||
background: #fff;
|
background: #fff;
|
||||||
z-index: 1;
|
z-index: 1;
|
||||||
height: 100%; }
|
height: 100%; }
|
||||||
.data-table-col.selected .content {
|
.data-table-cell.selected .content {
|
||||||
border: 2px solid #5292f7; }
|
border: 2px solid #5292f7; }
|
||||||
.data-table-col.editing .content {
|
.data-table-cell.editing .content {
|
||||||
display: none; }
|
display: none; }
|
||||||
.data-table-col.editing .edit-cell {
|
.data-table-cell.editing .edit-cell {
|
||||||
border: 2px solid #5292f7;
|
border: 2px solid #5292f7;
|
||||||
display: block; }
|
display: block; }
|
||||||
.data-table-col.highlight {
|
.data-table-cell.highlight {
|
||||||
background-color: #f5f7fa; }
|
background-color: #f5f7fa; }
|
||||||
.data-table-col:hover .column-resizer {
|
.data-table-cell:hover .column-resizer {
|
||||||
display: inline-block; }
|
display: inline-block; }
|
||||||
.data-table-col:hover .data-table-dropdown-toggle {
|
.data-table-cell:hover .data-table-dropdown-toggle {
|
||||||
display: block; }
|
display: block; }
|
||||||
|
.data-table-cell .tree-node {
|
||||||
|
display: inline-block;
|
||||||
|
position: relative; }
|
||||||
|
.data-table-cell .toggle {
|
||||||
|
display: inline-block;
|
||||||
|
position: absolute;
|
||||||
|
padding: 0 4px;
|
||||||
|
cursor: pointer; }
|
||||||
|
.data-table-cell .toggle:before {
|
||||||
|
content: '▼'; }
|
||||||
|
.data-table-cell.tree-close .toggle:before {
|
||||||
|
content: '►'; }
|
||||||
.data-table-row.row-highlight {
|
.data-table-row.row-highlight {
|
||||||
background-color: #f5f7fa; }
|
background-color: #f5f7fa; }
|
||||||
.noselect {
|
.noselect {
|
||||||
@ -7363,6 +7382,12 @@ html {
|
|||||||
padding: 200px 0px; }
|
padding: 200px 0px; }
|
||||||
.form-body {
|
.form-body {
|
||||||
padding: 2rem; }
|
padding: 2rem; }
|
||||||
|
.form-body .form-check {
|
||||||
|
margin-bottom: 0.5rem; }
|
||||||
|
.form-body .form-check .form-check-input {
|
||||||
|
margin-top: 0.25rem; }
|
||||||
|
.form-body .form-check .form-check-label {
|
||||||
|
margin-left: 0.25rem; }
|
||||||
.form-body .form-control.font-weight-bold {
|
.form-body .form-control.font-weight-bold {
|
||||||
background-color: lightyellow; }
|
background-color: lightyellow; }
|
||||||
.form-body .alert {
|
.form-body .alert {
|
||||||
|
5979
dist/js/bundle.js
vendored
5979
dist/js/bundle.js
vendored
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,67 @@
|
|||||||
|
module.exports = {
|
||||||
|
name: "AccountingLedgerEntry",
|
||||||
|
label: "Ledger Entry",
|
||||||
|
naming: "autoincrement",
|
||||||
|
doctype: "DocType",
|
||||||
|
isSingle: 0,
|
||||||
|
isChild: 0,
|
||||||
|
keywordFields: [],
|
||||||
|
fields: [
|
||||||
|
{
|
||||||
|
fieldname: "date",
|
||||||
|
label: "Date",
|
||||||
|
fieldtype: "Date"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
fieldname: "account",
|
||||||
|
label: "Account",
|
||||||
|
fieldtype: "Link",
|
||||||
|
target: "Account",
|
||||||
|
required: 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
fieldname: "description",
|
||||||
|
label: "Description",
|
||||||
|
fieldtype: "Text"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
fieldname: "party",
|
||||||
|
label: "Party",
|
||||||
|
fieldtype: "Link",
|
||||||
|
target: "Party",
|
||||||
|
required: 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
fieldname: "debit",
|
||||||
|
label: "Debit",
|
||||||
|
fieldtype: "Currency",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
fieldname: "credit",
|
||||||
|
label: "Credit",
|
||||||
|
fieldtype: "Currency",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
fieldname: "againstAccount",
|
||||||
|
label: "Against Account",
|
||||||
|
fieldtype: "Text",
|
||||||
|
required: 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
fieldname: "referenceType",
|
||||||
|
label: "Reference Type",
|
||||||
|
fieldtype: "Data",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
fieldname: "referenceName",
|
||||||
|
label: "Reference Name",
|
||||||
|
fieldtype: "Dynamic Link",
|
||||||
|
references: "referenceType"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
fieldname: "balance",
|
||||||
|
label: "Balance",
|
||||||
|
fieldtype: "Currency",
|
||||||
|
},
|
||||||
|
]
|
||||||
|
}
|
@ -23,9 +23,15 @@ module.exports = {
|
|||||||
"fieldname": "customer",
|
"fieldname": "customer",
|
||||||
"label": "Customer",
|
"label": "Customer",
|
||||||
"fieldtype": "Link",
|
"fieldtype": "Link",
|
||||||
"target": "Customer",
|
"target": "Party",
|
||||||
"required": 1
|
"required": 1
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"fieldname": "account",
|
||||||
|
"label": "Account",
|
||||||
|
"fieldtype": "Link",
|
||||||
|
"target": "Account"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"fieldname": "items",
|
"fieldname": "items",
|
||||||
"label": "Items",
|
"label": "Items",
|
||||||
@ -72,5 +78,24 @@ module.exports = {
|
|||||||
"label": "Terms",
|
"label": "Terms",
|
||||||
"fieldtype": "Text"
|
"fieldtype": "Text"
|
||||||
}
|
}
|
||||||
|
],
|
||||||
|
|
||||||
|
layout: [
|
||||||
|
// section 1
|
||||||
|
{
|
||||||
|
columns: [
|
||||||
|
{ fields: [ "customer", "account" ] },
|
||||||
|
{ fields: [ "date" ] }
|
||||||
|
]
|
||||||
|
},
|
||||||
|
|
||||||
|
// section 2
|
||||||
|
{ fields: [ "items" ] },
|
||||||
|
|
||||||
|
// section 3
|
||||||
|
{ fields: [ "netTotal", "taxes", "grandTotal" ] },
|
||||||
|
|
||||||
|
// section 4
|
||||||
|
{ fields: [ "terms" ] },
|
||||||
]
|
]
|
||||||
}
|
}
|
31
models/doctype/Invoice/InvoiceServer.js
Normal file
31
models/doctype/Invoice/InvoiceServer.js
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
const Invoice = require('./invoiceDocument');
|
||||||
|
const frappe = require('frappejs');
|
||||||
|
const LedgerPosting = require.main.require('./accounting/ledgerPosting');
|
||||||
|
|
||||||
|
module.exports = class InvoiceServer extends Invoice {
|
||||||
|
getPosting() {
|
||||||
|
let entries = new LedgerPosting({reference: this, party: this.customer});
|
||||||
|
entries.debit(this.account, this.grandTotal);
|
||||||
|
|
||||||
|
for (let item of this.items) {
|
||||||
|
entries.credit(item.account, item.amount);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.taxes) {
|
||||||
|
for (let tax of this.taxes) {
|
||||||
|
entries.credit(tax.account, tax.amount);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return entries;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
async afterSubmit() {
|
||||||
|
console.log('here');
|
||||||
|
await this.getPosting().post();
|
||||||
|
}
|
||||||
|
|
||||||
|
async afterRevert() {
|
||||||
|
await this.getPosting().postReverse();
|
||||||
|
}
|
||||||
|
}
|
@ -2,10 +2,6 @@ const BaseDocument = require('frappejs/model/document');
|
|||||||
const frappe = require('frappejs');
|
const frappe = require('frappejs');
|
||||||
|
|
||||||
module.exports = class Invoice extends BaseDocument {
|
module.exports = class Invoice extends BaseDocument {
|
||||||
async afterSubmit() {
|
|
||||||
// make ledger entry
|
|
||||||
}
|
|
||||||
|
|
||||||
async getRowTax(row) {
|
async getRowTax(row) {
|
||||||
if (row.tax) {
|
if (row.tax) {
|
||||||
let tax = await this.getTax(row.tax);
|
let tax = await this.getTax(row.tax);
|
||||||
@ -62,6 +58,7 @@ module.exports = class Invoice extends BaseDocument {
|
|||||||
// clear no taxes
|
// clear no taxes
|
||||||
this.taxes = this.taxes.filter(d => d.amount);
|
this.taxes = this.taxes.filter(d => d.amount);
|
||||||
}
|
}
|
||||||
|
|
||||||
getGrandTotal() {
|
getGrandTotal() {
|
||||||
this.makeTaxSummary();
|
this.makeTaxSummary();
|
||||||
let grandTotal = this.netTotal;
|
let grandTotal = this.netTotal;
|
||||||
|
@ -1,10 +1,11 @@
|
|||||||
module.exports = {
|
module.exports = {
|
||||||
"name": "InvoiceItem",
|
name: "InvoiceItem",
|
||||||
"doctype": "DocType",
|
doctype: "DocType",
|
||||||
"isSingle": 0,
|
isSingle: 0,
|
||||||
"isChild": 1,
|
isChild: 1,
|
||||||
"keywordFields": [],
|
keywordFields: [],
|
||||||
"fields": [
|
layout: 'ratio',
|
||||||
|
fields: [
|
||||||
{
|
{
|
||||||
"fieldname": "item",
|
"fieldname": "item",
|
||||||
"label": "Item",
|
"label": "Item",
|
||||||
@ -32,6 +33,14 @@ module.exports = {
|
|||||||
"required": 1,
|
"required": 1,
|
||||||
formula: (row, doc) => doc.getFrom('Item', row.item, 'rate')
|
formula: (row, doc) => doc.getFrom('Item', row.item, 'rate')
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
fieldname: "account",
|
||||||
|
label: "Account",
|
||||||
|
hidden: 1,
|
||||||
|
fieldtype: "Link",
|
||||||
|
target: "Account",
|
||||||
|
formula: (row, doc) => doc.getFrom('Item', row.item, 'incomeAccount')
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"fieldname": "tax",
|
"fieldname": "tax",
|
||||||
"label": "Tax",
|
"label": "Tax",
|
||||||
|
@ -1,28 +1,29 @@
|
|||||||
module.exports = {
|
module.exports = {
|
||||||
"name": "Item",
|
name: "Item",
|
||||||
"doctype": "DocType",
|
doctype: "DocType",
|
||||||
"isSingle": 0,
|
isSingle: 0,
|
||||||
"keywordFields": [
|
keywordFields: [
|
||||||
"name",
|
"name",
|
||||||
"description"
|
"description"
|
||||||
],
|
],
|
||||||
"fields": [
|
fields: [
|
||||||
{
|
{
|
||||||
"fieldname": "name",
|
fieldname: "name",
|
||||||
"label": "Item Name",
|
label: "Item Name",
|
||||||
"fieldtype": "Data",
|
fieldtype: "Data",
|
||||||
"required": 1
|
required: 1
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"fieldname": "description",
|
fieldname: "description",
|
||||||
"label": "Description",
|
label: "Description",
|
||||||
"fieldtype": "Text"
|
fieldtype: "Text"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"fieldname": "unit",
|
fieldname: "unit",
|
||||||
"label": "Unit",
|
label: "Unit",
|
||||||
"fieldtype": "Select",
|
fieldtype: "Select",
|
||||||
"options": [
|
default: "No",
|
||||||
|
options: [
|
||||||
"No",
|
"No",
|
||||||
"Kg",
|
"Kg",
|
||||||
"Gram",
|
"Gram",
|
||||||
@ -31,15 +32,48 @@ module.exports = {
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"fieldname": "tax",
|
fieldname: "incomeAccount",
|
||||||
"label": "Tax",
|
label: "Income Account",
|
||||||
"fieldtype": "Link",
|
fieldtype: "Link",
|
||||||
"target": "Tax"
|
target: "Account"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"fieldname": "rate",
|
fieldname: "expenseAccount",
|
||||||
"label": "Rate",
|
label: "Expense Account",
|
||||||
"fieldtype": "Currency"
|
fieldtype: "Link",
|
||||||
|
target: "Account"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
fieldname: "tax",
|
||||||
|
label: "Tax",
|
||||||
|
fieldtype: "Link",
|
||||||
|
target: "Tax"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
fieldname: "rate",
|
||||||
|
label: "Rate",
|
||||||
|
fieldtype: "Currency"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
layout: [
|
||||||
|
// section 1
|
||||||
|
{
|
||||||
|
columns: [
|
||||||
|
{ fields: [ "name", "unit" ] },
|
||||||
|
{ fields: [ "rate" ] }
|
||||||
|
]
|
||||||
|
},
|
||||||
|
|
||||||
|
// section 2
|
||||||
|
{ fields: [ "description" ] },
|
||||||
|
|
||||||
|
// section 3
|
||||||
|
{
|
||||||
|
title: "Accounting",
|
||||||
|
columns: [
|
||||||
|
{ fields: [ "incomeAccount", "expenseAccount" ] },
|
||||||
|
{ fields: [ "tax" ] }
|
||||||
|
]
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
13
models/doctype/Party/CustomerList.js
Normal file
13
models/doctype/Party/CustomerList.js
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
const BaseList = require('frappejs/client/view/list');
|
||||||
|
const frappe = require('frappejs');
|
||||||
|
|
||||||
|
module.exports = class CustomerList extends BaseList {
|
||||||
|
constructor({doctype, parent, fields, page}) {
|
||||||
|
super({doctype: 'Party', parent: parent, fields: fields, page: page});
|
||||||
|
}
|
||||||
|
getFilters() {
|
||||||
|
let filters = super.getFilters();
|
||||||
|
filters.customer = 1;
|
||||||
|
return filters;
|
||||||
|
}
|
||||||
|
}
|
@ -1,5 +1,5 @@
|
|||||||
module.exports = {
|
module.exports = {
|
||||||
"name": "Customer",
|
"name": "Party",
|
||||||
"doctype": "DocType",
|
"doctype": "DocType",
|
||||||
"isSingle": 0,
|
"isSingle": 0,
|
||||||
"istable": 0,
|
"istable": 0,
|
||||||
@ -12,6 +12,16 @@ module.exports = {
|
|||||||
"label": "Name",
|
"label": "Name",
|
||||||
"fieldtype": "Data",
|
"fieldtype": "Data",
|
||||||
"required": 1
|
"required": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fieldname": "customer",
|
||||||
|
"label": "Customer",
|
||||||
|
"fieldtype": "Check"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fieldname": "supplier",
|
||||||
|
"label": "Supplier",
|
||||||
|
"fieldtype": "Check"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
@ -1,11 +1,14 @@
|
|||||||
module.exports = {
|
module.exports = {
|
||||||
Account: require('./doctype/Account/Account.js'),
|
models: {
|
||||||
Customer: require('./doctype/Customer/Customer.js'),
|
Account: require('./doctype/Account/Account.js'),
|
||||||
Item: require('./doctype/Item/Item.js'),
|
AccountingLedgerEntry: require('./doctype/AccountingLedgerEntry/AccountingLedgerEntry.js'),
|
||||||
Invoice: require('./doctype/Invoice/Invoice.js'),
|
Party: require('./doctype/Party/Party.js'),
|
||||||
InvoiceItem: require('./doctype/InvoiceItem/InvoiceItem.js'),
|
Item: require('./doctype/Item/Item.js'),
|
||||||
InvoiceSettings: require('./doctype/InvoiceSettings/InvoiceSettings.js'),
|
Invoice: require('./doctype/Invoice/Invoice.js'),
|
||||||
Tax: require('./doctype/Tax/Tax.js'),
|
InvoiceItem: require('./doctype/InvoiceItem/InvoiceItem.js'),
|
||||||
TaxDetail: require('./doctype/TaxDetail/TaxDetail.js'),
|
InvoiceSettings: require('./doctype/InvoiceSettings/InvoiceSettings.js'),
|
||||||
TaxSummary: require('./doctype/TaxSummary/TaxSummary.js')
|
Tax: require('./doctype/Tax/Tax.js'),
|
||||||
|
TaxDetail: require('./doctype/TaxDetail/TaxDetail.js'),
|
||||||
|
TaxSummary: require('./doctype/TaxSummary/TaxSummary.js')
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"name": "frappe-accounting",
|
"name": "frappe-accounting",
|
||||||
"version": "1.0.0",
|
"version": "1.0.0",
|
||||||
"main": "index.js",
|
"main": "server.js",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"test": "mocha tests",
|
"test": "mocha tests",
|
||||||
|
@ -7,5 +7,9 @@ server.start({
|
|||||||
static: './',
|
static: './',
|
||||||
models: require('./models')
|
models: require('./models')
|
||||||
}).then(() => {
|
}).then(() => {
|
||||||
|
// set server-side modules
|
||||||
|
frappe.models.Invoice.documentClass = require('./models/doctype/Invoice/InvoiceServer.js');
|
||||||
|
frappe.metaCache = {};
|
||||||
|
|
||||||
frappe.syncDoc(require('./fixtures/invoicePrint'));
|
frappe.syncDoc(require('./fixtures/invoicePrint'));
|
||||||
});
|
});
|
@ -7,12 +7,13 @@ client.start({
|
|||||||
}).then(() => {
|
}).then(() => {
|
||||||
|
|
||||||
// require modules
|
// require modules
|
||||||
frappe.registerModels(require('../models'));
|
frappe.registerModels(require('../models'), 'client');
|
||||||
|
|
||||||
frappe.registerView('List', 'ToDo', require('frappejs/models/doctype/ToDo/ToDoList.js'));
|
frappe.registerView('List', 'ToDo', require('frappejs/models/doctype/ToDo/ToDoList.js'));
|
||||||
frappe.registerView('List', 'Account', require('../models/doctype/Account/AccountList.js'));
|
frappe.registerView('List', 'Account', require('../models/doctype/Account/AccountList.js'));
|
||||||
frappe.registerView('Form', 'Account', require('../models/doctype/Account/AccountForm.js'));
|
frappe.registerView('Form', 'Account', require('../models/doctype/Account/AccountForm.js'));
|
||||||
frappe.registerView('List', 'Invoice', require('../models/doctype/Invoice/InvoiceList.js'));
|
frappe.registerView('List', 'Invoice', require('../models/doctype/Invoice/InvoiceList.js'));
|
||||||
|
frappe.registerView('List', 'Customer', require('../models/doctype/Party/CustomerList.js'));
|
||||||
|
|
||||||
frappe.desk.menu.addItem('ToDo', '#list/ToDo');
|
frappe.desk.menu.addItem('ToDo', '#list/ToDo');
|
||||||
frappe.desk.menu.addItem('Accounts', '#list/Account');
|
frappe.desk.menu.addItem('Accounts', '#list/Account');
|
||||||
|
@ -4,8 +4,8 @@ const helpers = require('frappejs/tests/helpers');
|
|||||||
const models = require('../models');
|
const models = require('../models');
|
||||||
|
|
||||||
async function makeFixtures() {
|
async function makeFixtures() {
|
||||||
if (!(await frappe.db.exists('Customer', 'Test Customer'))) {
|
if (!(await frappe.db.exists('Party', 'Test Customer'))) {
|
||||||
await frappe.insert({doctype:'Customer', name:'Test Customer'})
|
await frappe.insert({doctype:'Party', name:'Test Customer'})
|
||||||
await frappe.insert({doctype:'Item', name:'Test Item 1', description:'Test Item Description 1', unit:'No', rate: 100})
|
await frappe.insert({doctype:'Item', name:'Test Item 1', description:'Test Item Description 1', unit:'No', rate: 100})
|
||||||
await frappe.insert({doctype:'Item', name:'Test Item 2', description:'Test Item Description 2', unit:'No', rate: 200})
|
await frappe.insert({doctype:'Item', name:'Test Item 2', description:'Test Item Description 2', unit:'No', rate: 200})
|
||||||
await frappe.insert({doctype:'Account', name:'GST', parent_account: 'Liabilities'});
|
await frappe.insert({doctype:'Account', name:'GST', parent_account: 'Liabilities'});
|
||||||
|
Loading…
x
Reference in New Issue
Block a user