2
0
mirror of https://github.com/frappe/books.git synced 2024-12-23 03:19:01 +00:00

Add Report View and Dynamic Link

This commit is contained in:
Suraj Shetty 2018-06-11 16:50:34 +05:30
parent 441ec973e2
commit 7b9b897f9b
20 changed files with 181 additions and 90 deletions

View File

@ -25,6 +25,9 @@ module.exports = {
'generator-star-spacing': 'off',
// allow debugger during development
'no-debugger': process.env.NODE_ENV === 'production' ? 'error' : 'off',
'semi': 'off'
'semi': 'on',
'indent': 'off',
// 'indent': ["error", 4],
'space-before-function-paren': 'off'
}
}

View File

@ -11,5 +11,5 @@ module.exports = {
}
};
}
},
}
}
}

View File

@ -0,0 +1,36 @@
const title = 'General Ledger';
module.exports = {
title: title,
method: 'general-ledger',
filterFields: [
{
fieldtype: 'Select',
options: ['', 'Invoice', 'Payment'],
label: 'Reference Type',
fieldname: 'referenceType'
},
{
fieldtype: 'DynamicLink',
references: 'referenceType',
label: 'Reference Name',
fieldname: 'referenceName'
},
{ fieldtype: 'Link', target: 'Account', label: 'Account', fieldname: 'account' },
{ fieldtype: 'Link', target: 'Party', label: 'Party', fieldname: 'party' },
{ fieldtype: 'Date', label: 'From Date', fieldname: 'fromDate' },
{ fieldtype: 'Date', label: 'To Date', fieldname: 'toDate' }
],
getColumns() {
return [
{ label: 'Date', fieldtype: 'Date' },
{ label: 'Account', fieldtype: 'Link' },
{ label: 'Debit', fieldtype: 'Currency' },
{ label: 'Credit', fieldtype: 'Currency' },
{ label: 'Balance', fieldtype: 'Currency' },
{ label: 'Reference Type', fieldtype: 'Data' },
{ label: 'Reference Name', fieldtype: 'Data' },
{ label: 'Party', fieldtype: 'Link' },
{ label: 'Description', fieldtype: 'Data' }
]
}
}

View File

@ -9,7 +9,7 @@ module.exports = class RegisterView extends ReportPage {
title,
filterFields: [
{fieldtype: 'Date', fieldname: 'fromDate', label: 'From Date', required: 1},
{fieldtype: 'Date', fieldname: 'toDate', label: 'To Date', required: 1}
{fieldtype: 'Date', fieldname: 'toDate', label: 'To Date', required: 1}
]
});

View File

@ -33,7 +33,7 @@ function registerReportMethods() {
{
method: 'purchase-register',
class: PurchaseRegister
},
}
];
reports.forEach(report => {

View File

@ -1,70 +1,3 @@
const frappe = require('frappejs');
const GeneralLedgerView = require('../reports/GeneralLedger/GeneralLedgerView');
const ProfitAndLossView = require('./ProfitAndLoss/ProfitAndLossView');
const BalanceSheetView = require('./BalanceSheet/BalanceSheetView');
const TrialBalanceView = require('./TrialBalance/TrialBalanceView');
const SalesRegisterView = require('./SalesRegister/SalesRegisterView');
const PurchaseRegisterView = require('./PurchaseRegister/PurchaseRegisterView');
const AccountsReceivableView = require('./AccountsReceivablePayable/AccountsReceivableView');
const AccountsPayableView = require('./AccountsReceivablePayable/AccountsPayableView');
// called on client side
function registerReportRoutes() {
frappe.router.add('report/general-ledger', async (params) => {
if (!frappe.views.GeneralLedger) {
frappe.views.GeneralLedger = new GeneralLedgerView();
}
await frappe.views.GeneralLedger.show(params);
});
frappe.router.add('report/profit-and-loss', async (params) => {
if (!frappe.views.ProfitAndLoss) {
frappe.views.ProfitAndLoss = new ProfitAndLossView();
}
await frappe.views.ProfitAndLoss.show(params);
});
frappe.router.add('report/balance-sheet', async (params) => {
if (!frappe.views.BalanceSheet) {
frappe.views.BalanceSheet = new BalanceSheetView();
}
await frappe.views.BalanceSheet.show(params);
});
frappe.router.add('report/trial-balance', async (params) => {
if (!frappe.views.TrialBalance) {
frappe.views.TrialBalance = new TrialBalanceView();
}
await frappe.views.TrialBalance.show(params);
});
frappe.router.add('report/sales-register', async (params) => {
if (!frappe.views.SalesRegister) {
frappe.views.SalesRegister = new SalesRegisterView();
}
await frappe.views.SalesRegister.show(params);
});
frappe.router.add('report/purchase-register', async (params) => {
if (!frappe.views.PurchaseRegister) {
frappe.views.PurchaseRegister = new PurchaseRegisterView();
}
await frappe.views.PurchaseRegister.show(params);
});
frappe.router.add('report/accounts-receivable', async (params) => {
if (!frappe.views.AccountsReceivable) {
frappe.views.AccountsReceivable = new AccountsReceivableView();
}
await frappe.views.AccountsReceivable.show(params);
});
frappe.router.add('report/accounts-payable', async (params) => {
if (!frappe.views.AccountsPayable) {
frappe.views.AccountsPayable = new AccountsPayableView();
}
await frappe.views.AccountsPayable.show(params);
});
module.exports = {
'General Ledger': require('./GeneralLedger/viewConfig')
}
module.exports = registerReportRoutes;

View File

@ -33,6 +33,7 @@ export default {
<style lang="scss">
@import "~bootstrap/scss/bootstrap";
@import '~frappe-datatable/dist/frappe-datatable';
html {
font-size: 14px;

View File

@ -12,8 +12,7 @@
:isActive="doc.name === $route.params.name"
:isChecked="isChecked(doc.name)"
@clickItem="openForm(doc.name)"
@checkItem="toggleCheck(doc.name)"
>
@checkItem="toggleCheck(doc.name)">
{{ doc[meta.titleField || 'name'] }}
</list-item>
</ul>

52
src/components/Report.vue Normal file
View File

@ -0,0 +1,52 @@
<template>
<div>
<div class="p-4">
<h4 class="pb-2">{{ reportName }}</h4>
<report-filters v-if="reportConfig.filterFields.length" :filters="reportConfig.filterFields" @change="getReportData"></report-filters>
<div class="pt-2" ref="datatable" v-once></div>
</div>
<not-found v-if="!reportConfig" />
</div>
</template>
<script>
import DataTable from 'frappe-datatable'
import frappe from 'frappejs'
import FrappeControl from './controls/FrappeControl'
import ReportFilters from './ReportFilters'
import utils from 'frappejs/client/ui/utils'
import getReportViewConfig from '../../reports/view'
export default {
props: ['reportName'],
data() {
return {
'reportConfig': getReportViewConfig[this.reportName]
}
},
computed: {
reportColumns() {
return utils.convertFieldsToDatatableColumns(this.reportConfig.getColumns())
}
},
methods: {
getReportData(filters) {
frappe.methods[this.reportConfig.method](filters).then(data => {
if (this.datatable) {
this.datatable.refresh(data || [])
} else {
this.datatable = new DataTable(this.$refs.datatable, {
columns: this.reportColumns,
data: data || [],
});
}
})
}
},
components: {
FrappeControl,
ReportFilters,
}
}
</script>
<style>
</style>

View File

@ -0,0 +1,43 @@
<template>
<div class="row pb-4">
<frappe-control class="col-lg col-md-3 col-sm-6"
v-for="docfield in filters"
:key="docfield.fieldname"
:docfield="docfield"
:value="$data[docfield.fieldname]"
@change="updateValue(docfield.fieldname, $event)"/>
</div>
</template>
<script>
import FrappeControl from './controls/FrappeControl'
export default {
props: ['filters'],
data () {
const filterValues = {};
for (let filter of this.filters) {
filterValues[filter.fieldname] = '';
}
return {filterValues};
},
provide() {
return {
dynamicLinkTarget: (reference) => {
return this.filterValues[reference]
}
};
},
methods: {
updateValue(fieldname, value) {
this.filterValues[fieldname] = value;
this.$emit('change', this.filterValues)
}
},
components: {
FrappeControl
}
}
</script>
<style>
</style>

View File

@ -13,8 +13,7 @@
<li class="nav-item">
<a v-for="item in sidebarGroup.items" :key="item.route"
:href="item.route"
:class="['nav-link', isActive(item) ? 'text-light bg-secondary' : 'text-dark']"
>
:class="['nav-link', isActive(item) ? 'text-light bg-secondary' : 'text-dark']" >
{{ item.label }}
</a>
</li>
@ -35,9 +34,11 @@ export default {
isActive(item) {
if (this.$route.params.doctype) {
return this.$route.params.doctype === item.label;
} else if(this.$route.params.reportName) {
return this.$route.params.reportName === item.label;
}
const route = item.route.slice(1);
return this.$route.params.doctype === route;
return this.$route.path === route;
}
}
}

View File

@ -44,6 +44,7 @@ export default {
return li;
}
});
input.addEventListener('awesomplete-select', (e) => { console.log(e);this.$emit('awesomplete-select', e)} )
},
sort() {
}

View File

@ -40,7 +40,7 @@ export default {
},
getLabelElement(h) {
return h('label', {
class: this.labelClass,
class: [this.labelClass, 'text-muted'],
attrs: {
for: this.id
},

View File

@ -4,8 +4,7 @@
<flat-pickr
:value="value"
class="form-control"
@on-change="emitChange"
>
@on-change="emitChange">
</flat-pickr>
</div>
<flat-pickr

View File

@ -0,0 +1,14 @@
<script>
import frappe from 'frappejs';
import Link from './Link';
export default {
extends: Link,
inject: ['dynamicLinkTarget'],
methods: {
getTarget() {
return this.dynamicLinkTarget(this.docfield.references);
}
}
}
</script>

View File

@ -19,6 +19,7 @@ import Link from './Link';
import Select from './Select';
import Table from './Table';
import Text from './Text';
import DynamicLink from './DynamicLink';
export default {
props: ['docfield', 'value', 'onlyInput'],
@ -37,6 +38,7 @@ export default {
Select,
Table,
Text,
DynamicLink,
}[this.docfield.fieldtype];
}
}

View File

@ -8,7 +8,7 @@ export default {
methods: {
async getList(query) {
const list = await frappe.db.getAll({
doctype: this.docfield.target,
doctype: this.getTarget(),
filters: {
keywords: ["like", query]
},
@ -28,10 +28,13 @@ export default {
value: d.name
}))
.concat({
label: plusIcon + ' New ' + this.docfield.target,
label: plusIcon + ' New ' + this.getTarget(),
value: '__newItem'
})
},
getTarget() {
return this.docfield.target;
},
sort() {
return (a, b) => {
if (a.value === '__newitem' || b.value === '__newitem') {

View File

@ -21,6 +21,7 @@ import FeatherIcon from './components/FeatherIcon';
import FrappeControl from './components/controls/FrappeControl';
import Button from './components/Button';
import Indicator from './components/Indicator';
import registerReportMethods from '../reports';
frappe.init();
frappe.registerLibs(common);
@ -34,6 +35,7 @@ frappe.db.bindSocketClient(socket);
frappe.registerModels(models);
frappe.docs = new Observable();
frappe.getSingle('SystemSettings');
registerReportMethods()
frappe.getSingle('AccountingSettings')
.then(accountingSettings => {

View File

@ -2,6 +2,7 @@ import Vue from 'vue'
import Router from 'vue-router'
import ListAndForm from '@/components/ListAndForm'
import SetupWizard from '@/pages/SetupWizard/SetupWizard'
import Report from '@/components/Report'
Vue.use(Router)
@ -25,13 +26,14 @@ export default new Router({
components: {
setup: SetupWizard
}
},
{
path: '/report/:reportName',
name: 'Report',
component: Report,
props: true
}
// {
// path: '/tree/:doctype',
// name: '',
// component: ''
// },
// {
// path: '/table/:doctype',
// name: '',
// component: ''

View File

@ -33,7 +33,7 @@ export default [
title: 'Reports',
items: [
{
label: 'General Ledger', route: '#/report/general-ledger'
label: 'General Ledger', route: '#/report/General Ledger'
}
]
}