mirror of
https://github.com/frappe/books.git
synced 2025-01-03 07:12:21 +00:00
incr: add ledger links
- fix sidebar issue - show grand total
This commit is contained in:
parent
9a510f1a63
commit
5d732844fb
@ -7,11 +7,11 @@ import { safeParseFloat } from 'utils/index';
|
|||||||
import { Router } from 'vue-router';
|
import { Router } from 'vue-router';
|
||||||
import {
|
import {
|
||||||
AccountRootType,
|
AccountRootType,
|
||||||
AccountRootTypeEnum
|
AccountRootTypeEnum,
|
||||||
} from './baseModels/Account/types';
|
} from './baseModels/Account/types';
|
||||||
import {
|
import {
|
||||||
Defaults,
|
Defaults,
|
||||||
numberSeriesDefaultsMap
|
numberSeriesDefaultsMap,
|
||||||
} from './baseModels/Defaults/Defaults';
|
} from './baseModels/Defaults/Defaults';
|
||||||
import { InvoiceStatus, ModelNameEnum } from './types';
|
import { InvoiceStatus, ModelNameEnum } from './types';
|
||||||
|
|
||||||
@ -60,15 +60,27 @@ export function getInvoiceActions(
|
|||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
export function getLedgerLinkAction(fyo: Fyo): Action {
|
export function getLedgerLinkAction(
|
||||||
|
fyo: Fyo,
|
||||||
|
isStock: boolean = false
|
||||||
|
): Action {
|
||||||
|
|
||||||
|
let label = fyo.t`Ledger Entries`;
|
||||||
|
let reportClassName = 'GeneralLedger';
|
||||||
|
|
||||||
|
if (isStock) {
|
||||||
|
label = fyo.t`Stock Entries`;
|
||||||
|
reportClassName = 'StockLedger';
|
||||||
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
label: fyo.t`Ledger Entries`,
|
label,
|
||||||
condition: (doc: Doc) => doc.isSubmitted,
|
condition: (doc: Doc) => doc.isSubmitted,
|
||||||
action: async (doc: Doc, router: Router) => {
|
action: async (doc: Doc, router: Router) => {
|
||||||
router.push({
|
router.push({
|
||||||
name: 'Report',
|
name: 'Report',
|
||||||
params: {
|
params: {
|
||||||
reportClassName: 'GeneralLedger',
|
reportClassName,
|
||||||
defaultFilters: JSON.stringify({
|
defaultFilters: JSON.stringify({
|
||||||
referenceType: doc.schemaName,
|
referenceType: doc.schemaName,
|
||||||
referenceName: doc.name,
|
referenceName: doc.name,
|
||||||
|
@ -1,10 +1,12 @@
|
|||||||
|
import { Fyo } from 'fyo';
|
||||||
import {
|
import {
|
||||||
|
Action,
|
||||||
DefaultMap,
|
DefaultMap,
|
||||||
FiltersMap,
|
FiltersMap,
|
||||||
FormulaMap,
|
FormulaMap,
|
||||||
ListViewSettings,
|
ListViewSettings
|
||||||
} from 'fyo/model/types';
|
} from 'fyo/model/types';
|
||||||
import { getDocStatusListColumn } from 'models/helpers';
|
import { getDocStatusListColumn, getLedgerLinkAction } from 'models/helpers';
|
||||||
import { LedgerPosting } from 'models/Transactional/LedgerPosting';
|
import { LedgerPosting } from 'models/Transactional/LedgerPosting';
|
||||||
import { ModelNameEnum } from 'models/types';
|
import { ModelNameEnum } from 'models/types';
|
||||||
import { Money } from 'pesa';
|
import { Money } from 'pesa';
|
||||||
@ -63,4 +65,8 @@ export class StockMovement extends Transfer {
|
|||||||
toLocation: row.toLocation,
|
toLocation: row.toLocation,
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static getActions(fyo: Fyo): Action[] {
|
||||||
|
return [getLedgerLinkAction(fyo, true)];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,10 +1,10 @@
|
|||||||
import { t } from 'fyo';
|
import { Fyo, t } from 'fyo';
|
||||||
import { Attachment } from 'fyo/core/types';
|
import { Attachment } from 'fyo/core/types';
|
||||||
import { Doc } from 'fyo/model/doc';
|
import { Doc } from 'fyo/model/doc';
|
||||||
import { DefaultMap, FiltersMap, FormulaMap } from 'fyo/model/types';
|
import { Action, DefaultMap, FiltersMap, FormulaMap } from 'fyo/model/types';
|
||||||
import { NotFoundError, ValidationError } from 'fyo/utils/errors';
|
import { ValidationError } from 'fyo/utils/errors';
|
||||||
import { Defaults } from 'models/baseModels/Defaults/Defaults';
|
import { Defaults } from 'models/baseModels/Defaults/Defaults';
|
||||||
import { getNumberSeries } from 'models/helpers';
|
import { getLedgerLinkAction, getNumberSeries } from 'models/helpers';
|
||||||
import { LedgerPosting } from 'models/Transactional/LedgerPosting';
|
import { LedgerPosting } from 'models/Transactional/LedgerPosting';
|
||||||
import { ModelNameEnum } from 'models/types';
|
import { ModelNameEnum } from 'models/types';
|
||||||
import { Money } from 'pesa';
|
import { Money } from 'pesa';
|
||||||
@ -100,7 +100,7 @@ export abstract class StockTransfer extends Transfer {
|
|||||||
await posting.credit(stockReceivedButNotBilled, amount);
|
await posting.credit(stockReceivedButNotBilled, amount);
|
||||||
}
|
}
|
||||||
|
|
||||||
await posting.makeRoundOffEntry()
|
await posting.makeRoundOffEntry();
|
||||||
return posting;
|
return posting;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -133,4 +133,8 @@ export abstract class StockTransfer extends Transfer {
|
|||||||
throw new ValidationError(messages.join(' '));
|
throw new ValidationError(messages.join(' '));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static getActions(fyo: Fyo): Action[] {
|
||||||
|
return [getLedgerLinkAction(fyo, false), getLedgerLinkAction(fyo, true)];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -17,6 +17,8 @@ type ReferenceType =
|
|||||||
| ModelNameEnum.PurchaseInvoice
|
| ModelNameEnum.PurchaseInvoice
|
||||||
| ModelNameEnum.Payment
|
| ModelNameEnum.Payment
|
||||||
| ModelNameEnum.JournalEntry
|
| ModelNameEnum.JournalEntry
|
||||||
|
| ModelNameEnum.Shipment
|
||||||
|
| ModelNameEnum.PurchaseReceipt
|
||||||
| 'All';
|
| 'All';
|
||||||
|
|
||||||
export class GeneralLedger extends LedgerReport {
|
export class GeneralLedger extends LedgerReport {
|
||||||
@ -272,17 +274,25 @@ export class GeneralLedger extends LedgerReport {
|
|||||||
}
|
}
|
||||||
|
|
||||||
getFilters() {
|
getFilters() {
|
||||||
|
const refTypeOptions = [
|
||||||
|
{ label: t`All`, value: 'All' },
|
||||||
|
{ label: t`Sales Invoices`, value: 'SalesInvoice' },
|
||||||
|
{ label: t`Purchase Invoices`, value: 'PurchaseInvoice' },
|
||||||
|
{ label: t`Payments`, value: 'Payment' },
|
||||||
|
{ label: t`Journal Entries`, value: 'JournalEntry' },
|
||||||
|
];
|
||||||
|
|
||||||
|
if (this.fyo.store.appFlags.isInventoryEnabled) {
|
||||||
|
refTypeOptions.push(
|
||||||
|
{ label: t`Shipment`, value: 'Shipment' },
|
||||||
|
{ label: t`Purchase Receipt`, value: 'PurchaseReceipt' }
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
return [
|
return [
|
||||||
{
|
{
|
||||||
fieldtype: 'Select',
|
fieldtype: 'Select',
|
||||||
options: [
|
options: refTypeOptions,
|
||||||
{ label: t`All`, value: 'All' },
|
|
||||||
{ label: t`Sales Invoices`, value: 'SalesInvoice' },
|
|
||||||
{ label: t`Purchase Invoices`, value: 'PurchaseInvoice' },
|
|
||||||
{ label: t`Payments`, value: 'Payment' },
|
|
||||||
{ label: t`Journal Entries`, value: 'JournalEntry' },
|
|
||||||
],
|
|
||||||
|
|
||||||
label: t`Ref Type`,
|
label: t`Ref Type`,
|
||||||
fieldname: 'referenceType',
|
fieldname: 'referenceType',
|
||||||
placeholder: t`Ref Type`,
|
placeholder: t`Ref Type`,
|
||||||
|
@ -11,6 +11,12 @@ import { isNumeric } from 'src/utils';
|
|||||||
import { getRawStockLedgerEntries, getStockLedgerEntries } from './helpers';
|
import { getRawStockLedgerEntries, getStockLedgerEntries } from './helpers';
|
||||||
import { ComputedStockLedgerEntry } from './types';
|
import { ComputedStockLedgerEntry } from './types';
|
||||||
|
|
||||||
|
type ReferenceType =
|
||||||
|
| ModelNameEnum.StockMovement
|
||||||
|
| ModelNameEnum.Shipment
|
||||||
|
| ModelNameEnum.PurchaseReceipt
|
||||||
|
| 'All';
|
||||||
|
|
||||||
export class StockLedger extends Report {
|
export class StockLedger extends Report {
|
||||||
static title = t`Stock Ledger`;
|
static title = t`Stock Ledger`;
|
||||||
static reportName = 'stock-ledger';
|
static reportName = 'stock-ledger';
|
||||||
@ -25,6 +31,9 @@ export class StockLedger extends Report {
|
|||||||
fromDate?: string;
|
fromDate?: string;
|
||||||
toDate?: string;
|
toDate?: string;
|
||||||
ascending?: boolean;
|
ascending?: boolean;
|
||||||
|
referenceType?: ReferenceType = 'All';
|
||||||
|
referenceName?: string;
|
||||||
|
|
||||||
groupBy: 'none' | 'item' | 'location' = 'none';
|
groupBy: 'none' | 'item' | 'location' = 'none';
|
||||||
|
|
||||||
constructor(fyo: Fyo) {
|
constructor(fyo: Fyo) {
|
||||||
@ -101,6 +110,17 @@ export class StockLedger extends Report {
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (
|
||||||
|
this.referenceType !== 'All' &&
|
||||||
|
row.referenceType !== this.referenceType
|
||||||
|
) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.referenceName && row.referenceName !== this.referenceName) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
row.name = ++i;
|
row.name = ++i;
|
||||||
filteredRawData.push(row);
|
filteredRawData.push(row);
|
||||||
}
|
}
|
||||||
@ -265,14 +285,14 @@ export class StockLedger extends Report {
|
|||||||
|
|
||||||
getFilters(): Field[] {
|
getFilters(): Field[] {
|
||||||
return [
|
return [
|
||||||
/*
|
|
||||||
{
|
{
|
||||||
fieldtype: 'Select',
|
fieldtype: 'Select',
|
||||||
options: [
|
options: [
|
||||||
{ label: t`All`, value: 'All' },
|
{ label: t`All`, value: 'All' },
|
||||||
{ label: t`Stock Movements`, value: 'StockMovement' },
|
{ label: t`Stock Movements`, value: 'StockMovement' },
|
||||||
|
{ label: t`Shipment`, value: 'Shipment' },
|
||||||
|
{ label: t`Purchase Receipt`, value: 'PurchaseReceipt' },
|
||||||
],
|
],
|
||||||
|
|
||||||
label: t`Ref Type`,
|
label: t`Ref Type`,
|
||||||
fieldname: 'referenceType',
|
fieldname: 'referenceType',
|
||||||
placeholder: t`Ref Type`,
|
placeholder: t`Ref Type`,
|
||||||
@ -285,7 +305,6 @@ export class StockLedger extends Report {
|
|||||||
emptyMessage: t`Change Ref Type`,
|
emptyMessage: t`Change Ref Type`,
|
||||||
fieldname: 'referenceName',
|
fieldname: 'referenceName',
|
||||||
},
|
},
|
||||||
*/
|
|
||||||
{
|
{
|
||||||
fieldtype: 'Link',
|
fieldtype: 'Link',
|
||||||
target: 'Item',
|
target: 'Item',
|
||||||
|
@ -208,11 +208,18 @@ export default {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
isItemActive(item) {
|
isItemActive(item) {
|
||||||
let { path: currentRoute, params } = this.$route;
|
const { path: currentRoute, params } = this.$route;
|
||||||
let routeMatch = currentRoute === item.route;
|
const routeMatch = currentRoute === item.route;
|
||||||
let schemaNameMatch =
|
|
||||||
|
const schemaNameMatch =
|
||||||
item.schemaName && params.schemaName === item.schemaName;
|
item.schemaName && params.schemaName === item.schemaName;
|
||||||
return routeMatch || schemaNameMatch;
|
|
||||||
|
const isMatch = routeMatch || schemaNameMatch;
|
||||||
|
if (params.name && item.schemaName && !isMatch) {
|
||||||
|
return currentRoute.includes(`${item.schemaName}/${params.name}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
return isMatch;
|
||||||
},
|
},
|
||||||
isGroupActive(group) {
|
isGroupActive(group) {
|
||||||
return this.activeGroup && group.label === this.activeGroup.label;
|
return this.activeGroup && group.label === this.activeGroup.label;
|
||||||
|
@ -28,7 +28,7 @@
|
|||||||
<hr />
|
<hr />
|
||||||
|
|
||||||
<div>
|
<div>
|
||||||
<!-- Invoice Form Data Entry -->
|
<!-- Form Data Entry -->
|
||||||
<div class="m-4 grid grid-cols-3 gap-4">
|
<div class="m-4 grid grid-cols-3 gap-4">
|
||||||
<FormControl
|
<FormControl
|
||||||
input-class="font-semibold"
|
input-class="font-semibold"
|
||||||
@ -66,7 +66,7 @@
|
|||||||
</div>
|
</div>
|
||||||
<hr />
|
<hr />
|
||||||
|
|
||||||
<!-- Invoice Items Table -->
|
<!-- Items Table -->
|
||||||
<Table
|
<Table
|
||||||
class="text-base"
|
class="text-base"
|
||||||
:df="getField('items')"
|
:df="getField('items')"
|
||||||
@ -79,8 +79,7 @@
|
|||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Invoice Form Footer -->
|
<!-- Form Footer -->
|
||||||
|
|
||||||
<div v-if="doc.items?.length ?? 0" class="mt-auto">
|
<div v-if="doc.items?.length ?? 0" class="mt-auto">
|
||||||
<hr />
|
<hr />
|
||||||
<div class="flex justify-between text-base m-4 gap-12">
|
<div class="flex justify-between text-base m-4 gap-12">
|
||||||
@ -96,6 +95,21 @@
|
|||||||
:read-only="doc?.submitted"
|
:read-only="doc?.submitted"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="w-1/2" v-if="doc.grandTotal">
|
||||||
|
<!-- Grand Total -->
|
||||||
|
<div
|
||||||
|
class="
|
||||||
|
flex
|
||||||
|
justify-between
|
||||||
|
text-green-600
|
||||||
|
font-semibold
|
||||||
|
text-base
|
||||||
|
"
|
||||||
|
>
|
||||||
|
<div>{{ t`Grand Total` }}</div>
|
||||||
|
<div>{{ formattedValue('grandTotal') }}</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
@ -119,6 +133,7 @@
|
|||||||
</template>
|
</template>
|
||||||
<script>
|
<script>
|
||||||
import { computed } from '@vue/reactivity';
|
import { computed } from '@vue/reactivity';
|
||||||
|
import { t } from 'fyo';
|
||||||
import { getDocStatus } from 'models/helpers';
|
import { getDocStatus } from 'models/helpers';
|
||||||
import Button from 'src/components/Button.vue';
|
import Button from 'src/components/Button.vue';
|
||||||
import FormControl from 'src/components/Controls/FormControl.vue';
|
import FormControl from 'src/components/Controls/FormControl.vue';
|
||||||
@ -235,7 +250,7 @@ export default {
|
|||||||
message,
|
message,
|
||||||
buttons: [
|
buttons: [
|
||||||
{
|
{
|
||||||
label: this.t`Yes`,
|
label: t`Yes`,
|
||||||
async action() {
|
async action() {
|
||||||
try {
|
try {
|
||||||
await ref.doc.submit();
|
await ref.doc.submit();
|
||||||
@ -245,7 +260,7 @@ export default {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: this.t`No`,
|
label: t`No`,
|
||||||
action() {},
|
action() {},
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
|
Loading…
Reference in New Issue
Block a user