2
0
mirror of https://github.com/frappe/books.git synced 2025-02-08 23:18:31 +00:00

incr: clean up coa markup, show balance on leaf ac

This commit is contained in:
18alantom 2022-05-02 20:47:14 +05:30
parent 8c19f51814
commit 9a012207f1
6 changed files with 167 additions and 138 deletions

View File

@ -152,11 +152,11 @@ export class Converter {
} }
function toDocString(value: RawValue, field: Field) { function toDocString(value: RawValue, field: Field) {
if (typeof value === 'string') { if (value === null) {
return value; return null;
} }
if (value === null) { if (typeof value === 'string') {
return value; return value;
} }
@ -164,6 +164,10 @@ function toDocString(value: RawValue, field: Field) {
} }
function toDocDate(value: RawValue, field: Field) { function toDocDate(value: RawValue, field: Field) {
if (value === null) {
return null;
}
if (typeof value !== 'number' && typeof value !== 'string') { if (typeof value !== 'number' && typeof value !== 'string') {
throwError(value, field, 'doc'); throwError(value, field, 'doc');
} }
@ -189,6 +193,10 @@ function toDocCurrency(value: RawValue, field: Field, fyo: Fyo) {
return fyo.pesa(Number(value)); return fyo.pesa(Number(value));
} }
if (value === null) {
return fyo.pesa(0);
}
throwError(value, field, 'doc'); throwError(value, field, 'doc');
} }
@ -209,6 +217,10 @@ function toDocFloat(value: RawValue, field: Field): number {
value = parseFloat(value); value = parseFloat(value);
} }
if (value === null) {
value = 0;
}
if (typeof value === 'number' && !Number.isNaN(value)) { if (typeof value === 'number' && !Number.isNaN(value)) {
return value; return value;
} }

View File

@ -1,10 +1,8 @@
import { Fyo } from 'fyo'; import { Fyo } from 'fyo';
import { Action, ListViewSettings } from 'fyo/model/types'; import { Action, ListViewSettings } from 'fyo/model/types';
import { LedgerPosting } from 'models/ledgerPosting/ledgerPosting'; import { LedgerPosting } from 'models/ledgerPosting/ledgerPosting';
import { import { ModelNameEnum } from 'models/types';
getTransactionActions, import { getInvoiceActions, getTransactionStatusColumn } from '../../helpers';
getTransactionStatusColumn,
} from '../../helpers';
import { Invoice } from '../Invoice/Invoice'; import { Invoice } from '../Invoice/Invoice';
import { PurchaseInvoiceItem } from '../PurchaseInvoiceItem/PurchaseInvoiceItem'; import { PurchaseInvoiceItem } from '../PurchaseInvoiceItem/PurchaseInvoiceItem';
@ -37,7 +35,7 @@ export class PurchaseInvoice extends Invoice {
} }
static getActions(fyo: Fyo): Action[] { static getActions(fyo: Fyo): Action[] {
return getTransactionActions('PurchaseInvoice', fyo); return getInvoiceActions(ModelNameEnum.PurchaseInvoice, fyo);
} }
static getListViewSettings(): ListViewSettings { static getListViewSettings(): ListViewSettings {

View File

@ -1,10 +1,8 @@
import { Fyo } from 'fyo'; import { Fyo } from 'fyo';
import { Action, ListViewSettings } from 'fyo/model/types'; import { Action, ListViewSettings } from 'fyo/model/types';
import { LedgerPosting } from 'models/ledgerPosting/ledgerPosting'; import { LedgerPosting } from 'models/ledgerPosting/ledgerPosting';
import { import { ModelNameEnum } from 'models/types';
getTransactionActions, import { getInvoiceActions, getTransactionStatusColumn } from '../../helpers';
getTransactionStatusColumn,
} from '../../helpers';
import { Invoice } from '../Invoice/Invoice'; import { Invoice } from '../Invoice/Invoice';
import { SalesInvoiceItem } from '../SalesInvoiceItem/SalesInvoiceItem'; import { SalesInvoiceItem } from '../SalesInvoiceItem/SalesInvoiceItem';
@ -35,7 +33,7 @@ export class SalesInvoice extends Invoice {
} }
static getActions(fyo: Fyo): Action[] { static getActions(fyo: Fyo): Action[] {
return getTransactionActions('SalesInvoice', fyo); return getInvoiceActions(ModelNameEnum.SalesInvoice, fyo);
} }
static getListViewSettings(): ListViewSettings { static getListViewSettings(): ListViewSettings {

View File

@ -5,7 +5,7 @@ import { NotFoundError } from 'fyo/utils/errors';
import { DateTime } from 'luxon'; import { DateTime } from 'luxon';
import Money from 'pesa/dist/types/src/money'; import Money from 'pesa/dist/types/src/money';
import { Router } from 'vue-router'; import { Router } from 'vue-router';
import { InvoiceStatus } from './types'; import { InvoiceStatus, ModelNameEnum } from './types';
export function getLedgerLinkAction(fyo: Fyo): Action { export function getLedgerLinkAction(fyo: Fyo): Action {
return { return {
@ -27,7 +27,10 @@ export function getLedgerLinkAction(fyo: Fyo): Action {
}; };
} }
export function getTransactionActions(schemaName: string, fyo: Fyo): Action[] { export function getInvoiceActions(
schemaName: ModelNameEnum.PurchaseInvoice | ModelNameEnum.SalesInvoice,
fyo: Fyo
): Action[] {
return [ return [
{ {
label: fyo.t`Make Payment`, label: fyo.t`Make Payment`,
@ -64,13 +67,6 @@ export function getTransactionActions(schemaName: string, fyo: Fyo): Action[] {
}); });
}, },
}, },
{
label: fyo.t`Print`,
condition: (doc: Doc) => doc.submitted as boolean,
action: async (doc: Doc, router: Router) => {
router.push({ path: `/print/${doc.schemaName}/${doc.name}` });
},
},
getLedgerLinkAction(fyo), getLedgerLinkAction(fyo),
]; ];
} }

View File

@ -1,9 +1,12 @@
<template> <template>
<div class="flex flex-col overflow-y-hidden"> <div class="flex flex-col overflow-y-hidden">
<PageHeader :title="t`Chart of Accounts`" /> <PageHeader :title="t`Chart of Accounts`" />
<div class="flex-1 flex px-8 overflow-y-auto">
<div class="flex-1" v-if="root"> <!-- Chart of Accounts -->
<div v-for="account in allAccounts" :key="account.name"> <div class="flex-1 flex flex-col px-8 overflow-y-auto" v-if="root">
<!-- Chart of Accounts Indented List -->
<template v-for="account in allAccounts" :key="account.name">
<!-- Account List Item -->
<div <div
class=" class="
mt-2 mt-2
@ -13,14 +16,16 @@
hover:bg-gray-100 hover:bg-gray-100
rounded-md rounded-md
group group
flex
items-center
" "
:class="[ :class="[
account.level !== 0 ? 'text-base' : 'text-lg', account.level !== 0 ? 'text-base' : 'text-lg',
isQuickEditOpen(account) ? 'bg-gray-200' : '', isQuickEditOpen(account) ? 'bg-gray-200' : '',
`pl-${account.level * 8}`,
]" ]"
@click="onClick(account)" @click="onClick(account)"
> >
<div class="flex items-center" :class="`pl-${account.level * 8}`">
<component :is="getIconComponent(account)" /> <component :is="getIconComponent(account)" />
<div class="flex items-baseline"> <div class="flex items-baseline">
<div <div
@ -29,10 +34,9 @@
> >
{{ account.name }} {{ account.name }}
</div> </div>
<div
v-if="account.isGroup" <!-- Add Account Buttons on Group Hover -->
class="ml-6 hidden group-hover:block" <div v-if="account.isGroup" class="ml-6 hidden group-hover:block">
>
<button <button
class=" class="
text-xs text-gray-800 text-xs text-gray-800
@ -56,8 +60,14 @@
</button> </button>
</div> </div>
</div> </div>
<!-- Account Balance String -->
<p class="ml-auto text-base text-gray-800" v-if="!account.isGroup">
{{ getBalanceString(account) }}
</p>
</div> </div>
</div>
<!-- Add Account/Group -->
<div <div
v-if="account.addingAccount || account.addingGroupAccount" v-if="account.addingAccount || account.addingGroupAccount"
class=" class="
@ -68,19 +78,18 @@
hover:bg-gray-100 hover:bg-gray-100
rounded-md rounded-md
group group
flex
items-center
" "
:class="[account.level !== 0 ? 'text-base' : 'text-lg']" :class="`${account.level !== 0 ? 'text-base' : 'text-lg'} pl-${
(account.level + 1) * 8
}`"
:key="account.name + '-adding-account'" :key="account.name + '-adding-account'"
>
<div
class="flex items-center"
:class="`pl-${(account.level + 1) * 8}`"
> >
<component <component
:is="getIconComponent({ isGroup: account.addingGroupAccount })" :is="getIconComponent({ isGroup: account.addingGroupAccount })"
/> />
<div class="flex items-baseline"> <div class="flex items-baseline ml-3">
<div class="ml-3">
<input <input
class="focus:outline-none bg-transparent" class="focus:outline-none bg-transparent"
:class="{ 'text-gray-600': insertingAccount }" :class="{ 'text-gray-600': insertingAccount }"
@ -112,14 +121,13 @@
</button> </button>
</div> </div>
</div> </div>
</div> </template>
</div>
</div>
</div>
</div> </div>
</div> </div>
</template> </template>
<script> <script>
import { t } from 'fyo';
import { AccountRootTypeEnum } from 'models/baseModels/Account/types';
import { ModelNameEnum } from 'models/types'; import { ModelNameEnum } from 'models/types';
import PageHeader from 'src/components/PageHeader'; import PageHeader from 'src/components/PageHeader';
import { fyo } from 'src/initFyo'; import { fyo } from 'src/initFyo';
@ -146,6 +154,26 @@ export default {
} }
}, },
methods: { methods: {
isCredit(rootType) {
switch (rootType) {
case AccountRootTypeEnum.Asset:
return false;
case AccountRootTypeEnum.Liability:
return true;
case AccountRootTypeEnum.Equity:
return true;
case AccountRootTypeEnum.Expense:
return false;
case AccountRootTypeEnum.Income:
return true;
default:
return true;
}
},
getBalanceString(account) {
const suffix = this.isCredit(account.rootType) ? t`Cr.` : t`Dr.`;
return `${fyo.format(account.balance, 'Currency')} ${suffix}`;
},
async fetchAccounts() { async fetchAccounts() {
this.settings = fyo.models[ModelNameEnum.Account].getTreeSettings(fyo); this.settings = fyo.models[ModelNameEnum.Account].getTreeSettings(fyo);
const { currency } = await fyo.doc.getSingle('AccountingSettings'); const { currency } = await fyo.doc.getSingle('AccountingSettings');

View File

@ -258,7 +258,7 @@ function getCancelAction(doc: Doc): Action {
component: { component: {
template: '<span class="text-red-700">{{ t`Cancel` }}</span>', template: '<span class="text-red-700">{{ t`Cancel` }}</span>',
}, },
condition: (doc: Doc) => !doc.cancelled, condition: (doc: Doc) => !!doc.submitted && !doc.cancelled,
action: () => { action: () => {
cancelDocWithPrompt(doc).then((res) => { cancelDocWithPrompt(doc).then((res) => {
if (res) { if (res) {
@ -276,10 +276,7 @@ function getDeleteAction(doc: Doc): Action {
template: '<span class="text-red-700">{{ t`Delete` }}</span>', template: '<span class="text-red-700">{{ t`Delete` }}</span>',
}, },
condition: (doc: Doc) => condition: (doc: Doc) =>
!doc.notInserted && !doc.notInserted && !doc.submitted && !doc.schema.isSingle,
!doc.submitted &&
!doc.schema.isSingle &&
!doc.cancelled,
action: () => action: () =>
deleteDocWithPrompt(doc).then((res) => { deleteDocWithPrompt(doc).then((res) => {
if (res) { if (res) {
@ -296,7 +293,7 @@ function getDuplicateAction(doc: Doc): Action {
condition: (doc: Doc) => condition: (doc: Doc) =>
!!( !!(
((isSubmittable && doc && doc.submitted) || !isSubmittable) && ((isSubmittable && doc && doc.submitted) || !isSubmittable) &&
!doc._notInserted && !doc.notInserted &&
!(doc.cancelled || false) !(doc.cancelled || false)
), ),
action: () => { action: () => {