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

feat: Reports

This commit is contained in:
Faris Ansari 2019-10-14 03:26:20 +05:30
parent bd5d812d77
commit 86993edee2
6 changed files with 142 additions and 34 deletions

View File

@ -5,7 +5,8 @@ export default {
title: _('Item'),
columns: [
'name',
'unit',
'tax',
'rate',
'tax'
]
}

View File

@ -95,39 +95,48 @@ const viewConfig = {
return [
{
label: 'Date',
fieldtype: 'Date'
fieldtype: 'Date',
fieldname: 'date'
},
{
label: 'Account',
fieldtype: 'Link'
fieldtype: 'Link',
fieldname: 'account'
},
{
label: 'Debit',
fieldtype: 'Currency'
fieldtype: 'Currency',
fieldname: 'debit'
},
{
label: 'Credit',
fieldtype: 'Currency'
fieldtype: 'Currency',
fieldname: 'credit'
},
{
label: 'Balance',
fieldtype: 'Currency'
fieldtype: 'Currency',
fieldname: 'balance'
},
{
label: 'Reference Type',
fieldtype: 'Data'
fieldtype: 'Data',
fieldname: 'referenceType'
},
{
label: 'Reference Name',
fieldtype: 'Data'
fieldtype: 'Data',
fieldname: 'referenceName'
},
{
label: 'Party',
fieldtype: 'Link'
fieldtype: 'Link',
fieldname: 'party'
},
{
label: 'Description',
fieldtype: 'Data'
fieldtype: 'Data',
fieldname: 'description'
}
];
}

View File

@ -14,21 +14,24 @@ export default {
ratio: {
type: Array,
default: () => []
}
},
gap: String
},
computed: {
style() {
let obj = {};
if (this.columnCount) {
return {
'grid-template-columns': `repeat(${this.columnCount}, 1fr)`
}
obj['grid-template-columns'] = `repeat(${this.columnCount}, 1fr)`;
}
if (this.ratio.length) {
return {
'grid-template-columns': this.ratio.map(r => `${r}fr`).join(' ')
}
obj['grid-template-columns'] = this.ratio.map(r => `${r}fr`).join(' ');
}
if (this.gap) {
obj['grid-gap'] = this.gap;
}
return obj;
}
}
}
};
</script>

View File

@ -1,15 +1,16 @@
<template>
<div class="px-8 pb-8 mt-2 text-sm flex flex-col justify-between">
<div>
<Row class="text-gray-700" :columnCount="columns.length">
<Row class="text-gray-700" :columnCount="columns.length" gap="1rem">
<div
v-for="column in columns"
:key="column.label"
class="py-4 truncate"
:class="['Float', 'Currency'].includes(column.fieldtype) ? 'text-right pr-10' : ''"
:class="['Float', 'Currency'].includes(column.fieldtype) ? 'text-right' : ''"
>{{ column.label }}</div>
</Row>
<Row
gap="1rem"
class="cursor-pointer text-gray-900 hover:text-gray-600"
v-for="doc in data"
:key="doc.name"
@ -19,14 +20,19 @@
<ListCell
v-for="column in columns"
:key="column.label"
:class="['Float', 'Currency'].includes(column.fieldtype) ? 'text-right pr-10' : ''"
:class="['Float', 'Currency'].includes(column.fieldtype) ? 'text-right' : ''"
:doc="doc"
:column="column"
></ListCell>
</Row>
</div>
<div class="flex items-center justify-center">
<Button :icon="true" :class="start == 0 && 'text-gray-600'" :disabled="start == 0" @click="prevPage">
<Button
:icon="true"
:class="start == 0 && 'text-gray-600'"
:disabled="start == 0"
@click="prevPage"
>
<svg
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 24 24"
@ -45,7 +51,12 @@
<span class="text-gray-600">of</span>
<span class="font-medium">{{ totalCount }}</span>
</div>
<Button :icon="true" :class="start + pageLength >= totalCount && 'text-gray-600'" :disabled="start + pageLength >= totalCount" @click="nextPage">
<Button
:icon="true"
:class="start + pageLength >= totalCount && 'text-gray-600'"
:disabled="start + pageLength >= totalCount"
@click="nextPage"
>
<svg
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 24 24"

91
src/pages/Report.vue Normal file
View File

@ -0,0 +1,91 @@
<template>
<div class="flex flex-col">
<PageHeader>
<h1 slot="title" class="text-xl font-bold">{{ report.title }}</h1>
<template slot="actions">
<SearchBar class="ml-2" />
</template>
</PageHeader>
<div class="flex flex-col flex-1 px-8 mt-4">
<Row :columnCount="columns.length" gap="1rem">
<div
class="text-gray-600 text-sm truncate py-4"
v-for="column in columns"
:key="column.label"
>{{ column.label }}</div>
</Row>
<div class="flex-1 overflow-auto">
<Row v-for="row in rows" :columnCount="columns.length" gap="1rem">
<div
class="text-gray-900 text-sm truncate py-4"
v-for="column in columns"
:key="column.label"
v-html="row[column.fieldname]"
></div>
</Row>
</div>
</div>
</div>
</template>
<script>
import frappe from 'frappejs';
import PageHeader from '@/components/PageHeader';
import Button from '@/components/Button';
import SearchBar from '@/components/SearchBar';
import Row from '@/components/Row';
import reportViewConfig from '@/../reports/view';
export default {
name: 'Report',
props: ['reportName'],
components: {
PageHeader,
Button,
SearchBar,
Row
},
data() {
return {
rows: [],
columns: []
};
},
mounted() {
this.columns = this.report.getColumns();
this.fetchReportData();
},
methods: {
async fetchReportData() {
let data = await frappe.call({
method: this.report.method,
args: {
fromDate: '2019-09-01',
toDate: '2019-10-31'
}
});
let rows, columns;
if (data.rows) {
rows = data.rows;
} else {
rows = data;
}
if (data.columns) {
this.columns = this.report.getColumns(data);
}
if (!rows) {
rows = [];
}
this.rows = rows;
}
},
computed: {
report() {
return reportViewConfig[this.reportName];
}
}
};
</script>

View File

@ -7,7 +7,7 @@ import FormView from '@/pages/FormView/FormView';
import PrintView from '@/pages/PrintView';
import QuickEditForm from '@/pages/QuickEditForm';
import Report from '@/pages/Report';
import Report from '@/pages/Report.vue';
import reportViewConfig from '../reports/view';
import DataImport from '@/pages/DataImport';
@ -29,7 +29,7 @@ const routes = [
component: Dashboard
},
{
path: '/edit/SalesInvoice/:name',
path: '/edit/:doctype/:name',
name: 'InvoiceForm',
components: {
default: InvoiceForm,
@ -74,14 +74,7 @@ const routes = [
path: '/report/:reportName',
name: 'Report',
component: Report,
props: route => {
const { reportName } = route.params;
return {
reportName,
reportConfig: reportViewConfig[reportName] || null,
filters: route.query
};
}
props: true
},
{
path: '/data-import',
@ -119,6 +112,6 @@ const routes = [
];
let router = new Router({ routes });
router.replace('/list/Item');
router.replace('/report/general-ledger');
export default router;