mirror of
https://github.com/frappe/books.git
synced 2024-11-09 23:30:56 +00:00
incr: clean up coa markup, show balance on leaf ac
This commit is contained in:
parent
8c19f51814
commit
9a012207f1
@ -152,11 +152,11 @@ export class Converter {
|
||||
}
|
||||
|
||||
function toDocString(value: RawValue, field: Field) {
|
||||
if (typeof value === 'string') {
|
||||
return value;
|
||||
if (value === null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (value === null) {
|
||||
if (typeof value === 'string') {
|
||||
return value;
|
||||
}
|
||||
|
||||
@ -164,6 +164,10 @@ function toDocString(value: RawValue, field: Field) {
|
||||
}
|
||||
|
||||
function toDocDate(value: RawValue, field: Field) {
|
||||
if (value === null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (typeof value !== 'number' && typeof value !== 'string') {
|
||||
throwError(value, field, 'doc');
|
||||
}
|
||||
@ -189,6 +193,10 @@ function toDocCurrency(value: RawValue, field: Field, fyo: Fyo) {
|
||||
return fyo.pesa(Number(value));
|
||||
}
|
||||
|
||||
if (value === null) {
|
||||
return fyo.pesa(0);
|
||||
}
|
||||
|
||||
throwError(value, field, 'doc');
|
||||
}
|
||||
|
||||
@ -209,6 +217,10 @@ function toDocFloat(value: RawValue, field: Field): number {
|
||||
value = parseFloat(value);
|
||||
}
|
||||
|
||||
if (value === null) {
|
||||
value = 0;
|
||||
}
|
||||
|
||||
if (typeof value === 'number' && !Number.isNaN(value)) {
|
||||
return value;
|
||||
}
|
||||
|
@ -1,10 +1,8 @@
|
||||
import { Fyo } from 'fyo';
|
||||
import { Action, ListViewSettings } from 'fyo/model/types';
|
||||
import { LedgerPosting } from 'models/ledgerPosting/ledgerPosting';
|
||||
import {
|
||||
getTransactionActions,
|
||||
getTransactionStatusColumn,
|
||||
} from '../../helpers';
|
||||
import { ModelNameEnum } from 'models/types';
|
||||
import { getInvoiceActions, getTransactionStatusColumn } from '../../helpers';
|
||||
import { Invoice } from '../Invoice/Invoice';
|
||||
import { PurchaseInvoiceItem } from '../PurchaseInvoiceItem/PurchaseInvoiceItem';
|
||||
|
||||
@ -37,7 +35,7 @@ export class PurchaseInvoice extends Invoice {
|
||||
}
|
||||
|
||||
static getActions(fyo: Fyo): Action[] {
|
||||
return getTransactionActions('PurchaseInvoice', fyo);
|
||||
return getInvoiceActions(ModelNameEnum.PurchaseInvoice, fyo);
|
||||
}
|
||||
|
||||
static getListViewSettings(): ListViewSettings {
|
||||
|
@ -1,10 +1,8 @@
|
||||
import { Fyo } from 'fyo';
|
||||
import { Action, ListViewSettings } from 'fyo/model/types';
|
||||
import { LedgerPosting } from 'models/ledgerPosting/ledgerPosting';
|
||||
import {
|
||||
getTransactionActions,
|
||||
getTransactionStatusColumn,
|
||||
} from '../../helpers';
|
||||
import { ModelNameEnum } from 'models/types';
|
||||
import { getInvoiceActions, getTransactionStatusColumn } from '../../helpers';
|
||||
import { Invoice } from '../Invoice/Invoice';
|
||||
import { SalesInvoiceItem } from '../SalesInvoiceItem/SalesInvoiceItem';
|
||||
|
||||
@ -35,7 +33,7 @@ export class SalesInvoice extends Invoice {
|
||||
}
|
||||
|
||||
static getActions(fyo: Fyo): Action[] {
|
||||
return getTransactionActions('SalesInvoice', fyo);
|
||||
return getInvoiceActions(ModelNameEnum.SalesInvoice, fyo);
|
||||
}
|
||||
|
||||
static getListViewSettings(): ListViewSettings {
|
||||
|
@ -5,7 +5,7 @@ import { NotFoundError } from 'fyo/utils/errors';
|
||||
import { DateTime } from 'luxon';
|
||||
import Money from 'pesa/dist/types/src/money';
|
||||
import { Router } from 'vue-router';
|
||||
import { InvoiceStatus } from './types';
|
||||
import { InvoiceStatus, ModelNameEnum } from './types';
|
||||
|
||||
export function getLedgerLinkAction(fyo: Fyo): Action {
|
||||
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 [
|
||||
{
|
||||
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),
|
||||
];
|
||||
}
|
||||
|
@ -1,125 +1,133 @@
|
||||
<template>
|
||||
<div class="flex flex-col overflow-y-hidden">
|
||||
<PageHeader :title="t`Chart of Accounts`" />
|
||||
<div class="flex-1 flex px-8 overflow-y-auto">
|
||||
<div class="flex-1" v-if="root">
|
||||
<div v-for="account in allAccounts" :key="account.name">
|
||||
<div
|
||||
class="
|
||||
mt-2
|
||||
px-4
|
||||
py-2
|
||||
cursor-pointer
|
||||
hover:bg-gray-100
|
||||
rounded-md
|
||||
group
|
||||
"
|
||||
:class="[
|
||||
account.level !== 0 ? 'text-base' : 'text-lg',
|
||||
isQuickEditOpen(account) ? 'bg-gray-200' : '',
|
||||
]"
|
||||
@click="onClick(account)"
|
||||
>
|
||||
<div class="flex items-center" :class="`pl-${account.level * 8}`">
|
||||
<component :is="getIconComponent(account)" />
|
||||
<div class="flex items-baseline">
|
||||
<div
|
||||
class="ml-3"
|
||||
:class="[!account.parentAccount && 'font-semibold']"
|
||||
>
|
||||
{{ account.name }}
|
||||
</div>
|
||||
<div
|
||||
v-if="account.isGroup"
|
||||
class="ml-6 hidden group-hover:block"
|
||||
>
|
||||
<button
|
||||
class="
|
||||
text-xs text-gray-800
|
||||
hover:text-gray-900
|
||||
focus:outline-none
|
||||
"
|
||||
@click.stop="addAccount(account, 'addingAccount')"
|
||||
>
|
||||
{{ t`Add Account` }}
|
||||
</button>
|
||||
<button
|
||||
class="
|
||||
ml-3
|
||||
text-xs text-gray-800
|
||||
hover:text-gray-900
|
||||
focus:outline-none
|
||||
"
|
||||
@click.stop="addAccount(account, 'addingGroupAccount')"
|
||||
>
|
||||
{{ t`Add Group` }}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Chart of Accounts -->
|
||||
<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
|
||||
class="
|
||||
mt-2
|
||||
px-4
|
||||
py-2
|
||||
cursor-pointer
|
||||
hover:bg-gray-100
|
||||
rounded-md
|
||||
group
|
||||
flex
|
||||
items-center
|
||||
"
|
||||
:class="[
|
||||
account.level !== 0 ? 'text-base' : 'text-lg',
|
||||
isQuickEditOpen(account) ? 'bg-gray-200' : '',
|
||||
`pl-${account.level * 8}`,
|
||||
]"
|
||||
@click="onClick(account)"
|
||||
>
|
||||
<component :is="getIconComponent(account)" />
|
||||
<div class="flex items-baseline">
|
||||
<div
|
||||
class="ml-3"
|
||||
:class="[!account.parentAccount && 'font-semibold']"
|
||||
>
|
||||
{{ account.name }}
|
||||
</div>
|
||||
|
||||
<!-- Add Account Buttons on Group Hover -->
|
||||
<div v-if="account.isGroup" class="ml-6 hidden group-hover:block">
|
||||
<button
|
||||
class="
|
||||
text-xs text-gray-800
|
||||
hover:text-gray-900
|
||||
focus:outline-none
|
||||
"
|
||||
@click.stop="addAccount(account, 'addingAccount')"
|
||||
>
|
||||
{{ t`Add Account` }}
|
||||
</button>
|
||||
<button
|
||||
class="
|
||||
ml-3
|
||||
text-xs text-gray-800
|
||||
hover:text-gray-900
|
||||
focus:outline-none
|
||||
"
|
||||
@click.stop="addAccount(account, 'addingGroupAccount')"
|
||||
>
|
||||
{{ t`Add Group` }}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
v-if="account.addingAccount || account.addingGroupAccount"
|
||||
class="
|
||||
mt-2
|
||||
px-4
|
||||
py-2
|
||||
cursor-pointer
|
||||
hover:bg-gray-100
|
||||
rounded-md
|
||||
group
|
||||
"
|
||||
:class="[account.level !== 0 ? 'text-base' : 'text-lg']"
|
||||
:key="account.name + '-adding-account'"
|
||||
>
|
||||
<div
|
||||
class="flex items-center"
|
||||
:class="`pl-${(account.level + 1) * 8}`"
|
||||
|
||||
<!-- Account Balance String -->
|
||||
<p class="ml-auto text-base text-gray-800" v-if="!account.isGroup">
|
||||
{{ getBalanceString(account) }}
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<!-- Add Account/Group -->
|
||||
<div
|
||||
v-if="account.addingAccount || account.addingGroupAccount"
|
||||
class="
|
||||
mt-2
|
||||
px-4
|
||||
py-2
|
||||
cursor-pointer
|
||||
hover:bg-gray-100
|
||||
rounded-md
|
||||
group
|
||||
flex
|
||||
items-center
|
||||
"
|
||||
:class="`${account.level !== 0 ? 'text-base' : 'text-lg'} pl-${
|
||||
(account.level + 1) * 8
|
||||
}`"
|
||||
:key="account.name + '-adding-account'"
|
||||
>
|
||||
<component
|
||||
:is="getIconComponent({ isGroup: account.addingGroupAccount })"
|
||||
/>
|
||||
<div class="flex items-baseline ml-3">
|
||||
<input
|
||||
class="focus:outline-none bg-transparent"
|
||||
:class="{ 'text-gray-600': insertingAccount }"
|
||||
:placeholder="t`New Account`"
|
||||
:ref="account.name"
|
||||
@keydown.esc="cancelAddingAccount(account)"
|
||||
@keydown.enter="
|
||||
(e) =>
|
||||
createNewAccount(
|
||||
e.target.value,
|
||||
account,
|
||||
account.addingGroupAccount
|
||||
)
|
||||
"
|
||||
type="text"
|
||||
:disabled="insertingAccount"
|
||||
/>
|
||||
<button
|
||||
v-if="!insertingAccount"
|
||||
class="
|
||||
ml-4
|
||||
text-xs text-gray-800
|
||||
hover:text-gray-900
|
||||
focus:outline-none
|
||||
"
|
||||
@click="cancelAddingAccount(account)"
|
||||
>
|
||||
<component
|
||||
:is="getIconComponent({ isGroup: account.addingGroupAccount })"
|
||||
/>
|
||||
<div class="flex items-baseline">
|
||||
<div class="ml-3">
|
||||
<input
|
||||
class="focus:outline-none bg-transparent"
|
||||
:class="{ 'text-gray-600': insertingAccount }"
|
||||
:placeholder="t`New Account`"
|
||||
:ref="account.name"
|
||||
@keydown.esc="cancelAddingAccount(account)"
|
||||
@keydown.enter="
|
||||
(e) =>
|
||||
createNewAccount(
|
||||
e.target.value,
|
||||
account,
|
||||
account.addingGroupAccount
|
||||
)
|
||||
"
|
||||
type="text"
|
||||
:disabled="insertingAccount"
|
||||
/>
|
||||
<button
|
||||
v-if="!insertingAccount"
|
||||
class="
|
||||
ml-4
|
||||
text-xs text-gray-800
|
||||
hover:text-gray-900
|
||||
focus:outline-none
|
||||
"
|
||||
@click="cancelAddingAccount(account)"
|
||||
>
|
||||
{{ t`Cancel` }}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{{ t`Cancel` }}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
import { t } from 'fyo';
|
||||
import { AccountRootTypeEnum } from 'models/baseModels/Account/types';
|
||||
import { ModelNameEnum } from 'models/types';
|
||||
import PageHeader from 'src/components/PageHeader';
|
||||
import { fyo } from 'src/initFyo';
|
||||
@ -146,6 +154,26 @@ export default {
|
||||
}
|
||||
},
|
||||
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() {
|
||||
this.settings = fyo.models[ModelNameEnum.Account].getTreeSettings(fyo);
|
||||
const { currency } = await fyo.doc.getSingle('AccountingSettings');
|
||||
|
@ -258,7 +258,7 @@ function getCancelAction(doc: Doc): Action {
|
||||
component: {
|
||||
template: '<span class="text-red-700">{{ t`Cancel` }}</span>',
|
||||
},
|
||||
condition: (doc: Doc) => !doc.cancelled,
|
||||
condition: (doc: Doc) => !!doc.submitted && !doc.cancelled,
|
||||
action: () => {
|
||||
cancelDocWithPrompt(doc).then((res) => {
|
||||
if (res) {
|
||||
@ -276,10 +276,7 @@ function getDeleteAction(doc: Doc): Action {
|
||||
template: '<span class="text-red-700">{{ t`Delete` }}</span>',
|
||||
},
|
||||
condition: (doc: Doc) =>
|
||||
!doc.notInserted &&
|
||||
!doc.submitted &&
|
||||
!doc.schema.isSingle &&
|
||||
!doc.cancelled,
|
||||
!doc.notInserted && !doc.submitted && !doc.schema.isSingle,
|
||||
action: () =>
|
||||
deleteDocWithPrompt(doc).then((res) => {
|
||||
if (res) {
|
||||
@ -296,7 +293,7 @@ function getDuplicateAction(doc: Doc): Action {
|
||||
condition: (doc: Doc) =>
|
||||
!!(
|
||||
((isSubmittable && doc && doc.submitted) || !isSubmittable) &&
|
||||
!doc._notInserted &&
|
||||
!doc.notInserted &&
|
||||
!(doc.cancelled || false)
|
||||
),
|
||||
action: () => {
|
||||
|
Loading…
Reference in New Issue
Block a user