mirror of
https://github.com/bigcapitalhq/bigcapital.git
synced 2026-02-21 15:20:34 +00:00
Merge pull request #460 from bigcapitalhq/print-resources
feat: Export resource tables to pdf
This commit is contained in:
@@ -0,0 +1,38 @@
|
|||||||
|
@import "../base.scss";
|
||||||
|
|
||||||
|
body {
|
||||||
|
font-family: system-ui,-apple-system,"Segoe UI",Roboto,"Helvetica Neue","Noto Sans","Liberation Sans",Arial,sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol","Noto Color Emoji";
|
||||||
|
font-size: 12px;
|
||||||
|
line-height: 1.4;
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
.sheet__title{
|
||||||
|
margin-bottom: 18px;
|
||||||
|
}
|
||||||
|
.sheet__title h2{
|
||||||
|
line-height: 1;
|
||||||
|
margin-top: 0;
|
||||||
|
margin-bottom: 10px;
|
||||||
|
font-size: 16px;
|
||||||
|
}
|
||||||
|
.sheet__table {
|
||||||
|
font-size: inherit;
|
||||||
|
line-height: inherit;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
.sheet__table {
|
||||||
|
table-layout: auto;
|
||||||
|
border-collapse: collapse;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
.sheet__table thead tr th {
|
||||||
|
border-top: 1px solid #000;
|
||||||
|
border-bottom: 1px solid #000;
|
||||||
|
background: #fff;
|
||||||
|
padding: 8px;
|
||||||
|
line-height: 1.2;
|
||||||
|
}
|
||||||
|
.sheet__table tbody tr td {
|
||||||
|
padding: 4px 8px;
|
||||||
|
border-bottom: 1px solid #CCC;
|
||||||
|
}
|
||||||
@@ -0,0 +1,24 @@
|
|||||||
|
block head
|
||||||
|
style
|
||||||
|
include ../../css/modules/export-resource-table.css
|
||||||
|
|
||||||
|
style.
|
||||||
|
!{customCSS}
|
||||||
|
|
||||||
|
block content
|
||||||
|
.sheet
|
||||||
|
.sheet__title
|
||||||
|
h2.sheetTitle= sheetTitle
|
||||||
|
p.sheetDesc= sheetDescription
|
||||||
|
|
||||||
|
table.sheet__table
|
||||||
|
thead
|
||||||
|
tr
|
||||||
|
each column in table.columns
|
||||||
|
th(style=column.style class='column--' + column.key)= column.name
|
||||||
|
tbody
|
||||||
|
each row in table.rows
|
||||||
|
tr(class=row.classNames)
|
||||||
|
each cell in row.cells
|
||||||
|
td(class='cell--' + cell.key)
|
||||||
|
span!= cell.value
|
||||||
@@ -70,6 +70,10 @@ module.exports = {
|
|||||||
src: `${RESOURCES_PATH}/scss/modules/financial-sheet.scss`,
|
src: `${RESOURCES_PATH}/scss/modules/financial-sheet.scss`,
|
||||||
dest: `${RESOURCES_PATH}/css/modules`,
|
dest: `${RESOURCES_PATH}/css/modules`,
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
src: `${RESOURCES_PATH}/scss/modules/export-resource-table.scss`,
|
||||||
|
dest: `${RESOURCES_PATH}/css/modules`,
|
||||||
|
},
|
||||||
],
|
],
|
||||||
// RTL builds.
|
// RTL builds.
|
||||||
rtl: [
|
rtl: [
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ import BaseController from '@/api/controllers/BaseController';
|
|||||||
import { ServiceError } from '@/exceptions';
|
import { ServiceError } from '@/exceptions';
|
||||||
import { ExportApplication } from '@/services/Export/ExportApplication';
|
import { ExportApplication } from '@/services/Export/ExportApplication';
|
||||||
import { ACCEPT_TYPE } from '@/interfaces/Http';
|
import { ACCEPT_TYPE } from '@/interfaces/Http';
|
||||||
|
import { convertAcceptFormatToFormat } from './_utils';
|
||||||
|
|
||||||
@Service()
|
@Service()
|
||||||
export class ExportController extends BaseController {
|
export class ExportController extends BaseController {
|
||||||
@@ -25,7 +26,6 @@ export class ExportController extends BaseController {
|
|||||||
],
|
],
|
||||||
this.validationResult,
|
this.validationResult,
|
||||||
this.export.bind(this),
|
this.export.bind(this),
|
||||||
this.catchServiceErrors
|
|
||||||
);
|
);
|
||||||
return router;
|
return router;
|
||||||
}
|
}
|
||||||
@@ -48,10 +48,12 @@ export class ExportController extends BaseController {
|
|||||||
ACCEPT_TYPE.APPLICATION_CSV,
|
ACCEPT_TYPE.APPLICATION_CSV,
|
||||||
ACCEPT_TYPE.APPLICATION_PDF,
|
ACCEPT_TYPE.APPLICATION_PDF,
|
||||||
]);
|
]);
|
||||||
|
const applicationFormat = convertAcceptFormatToFormat(acceptType);
|
||||||
|
|
||||||
const data = await this.exportResourceApp.export(
|
const data = await this.exportResourceApp.export(
|
||||||
tenantId,
|
tenantId,
|
||||||
query.resource,
|
query.resource,
|
||||||
acceptType === ACCEPT_TYPE.APPLICATION_XLSX ? 'xlsx' : 'csv'
|
applicationFormat
|
||||||
);
|
);
|
||||||
// Retrieves the csv format.
|
// Retrieves the csv format.
|
||||||
if (ACCEPT_TYPE.APPLICATION_CSV === acceptType) {
|
if (ACCEPT_TYPE.APPLICATION_CSV === acceptType) {
|
||||||
@@ -70,31 +72,16 @@ export class ExportController extends BaseController {
|
|||||||
'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'
|
'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'
|
||||||
);
|
);
|
||||||
return res.send(data);
|
return res.send(data);
|
||||||
|
//
|
||||||
|
} else if (ACCEPT_TYPE.APPLICATION_PDF === acceptType) {
|
||||||
|
res.set({
|
||||||
|
'Content-Type': 'application/pdf',
|
||||||
|
'Content-Length': data.length,
|
||||||
|
});
|
||||||
|
res.send(data);
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
next(error);
|
next(error);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Transforms service errors to response.
|
|
||||||
* @param {Error}
|
|
||||||
* @param {Request} req
|
|
||||||
* @param {Response} res
|
|
||||||
* @param {ServiceError} error
|
|
||||||
*/
|
|
||||||
private catchServiceErrors(
|
|
||||||
error,
|
|
||||||
req: Request,
|
|
||||||
res: Response,
|
|
||||||
next: NextFunction
|
|
||||||
) {
|
|
||||||
if (error instanceof ServiceError) {
|
|
||||||
return res.status(400).send({
|
|
||||||
errors: [{ type: error.errorType }],
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
next(error);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
13
packages/server/src/api/controllers/Export/_utils.ts
Normal file
13
packages/server/src/api/controllers/Export/_utils.ts
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
import { ACCEPT_TYPE } from '@/interfaces/Http';
|
||||||
|
import { ExportFormat } from '@/services/Export/common';
|
||||||
|
|
||||||
|
export const convertAcceptFormatToFormat = (accept: string): ExportFormat => {
|
||||||
|
switch (accept) {
|
||||||
|
case ACCEPT_TYPE.APPLICATION_CSV:
|
||||||
|
return ExportFormat.Csv;
|
||||||
|
case ACCEPT_TYPE.APPLICATION_PDF:
|
||||||
|
return ExportFormat.Pdf;
|
||||||
|
case ACCEPT_TYPE.APPLICATION_XLSX:
|
||||||
|
return ExportFormat.Xlsx;
|
||||||
|
}
|
||||||
|
};
|
||||||
@@ -3,7 +3,7 @@ exports.up = function (knex) {
|
|||||||
table.increments('id').primary();
|
table.increments('id').primary();
|
||||||
table.string('key').notNullable();
|
table.string('key').notNullable();
|
||||||
table.string('mime_type').notNullable();
|
table.string('mime_type').notNullable();
|
||||||
table.integer('size').unsigned().notNullable();
|
table.integer('size').unsigned();
|
||||||
table.string('origin_name');
|
table.string('origin_name');
|
||||||
table.timestamps();
|
table.timestamps();
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -122,6 +122,10 @@ export type IModelMetaCollectionField = IModelMetaCollectionFieldCommon &
|
|||||||
export type IModelMetaRelationField = IModelMetaRelationFieldCommon &
|
export type IModelMetaRelationField = IModelMetaRelationFieldCommon &
|
||||||
IModelMetaRelationEnumerationField;
|
IModelMetaRelationEnumerationField;
|
||||||
|
|
||||||
|
interface IModelPrintMeta{
|
||||||
|
pageTitle: string;
|
||||||
|
}
|
||||||
|
|
||||||
export interface IModelMeta {
|
export interface IModelMeta {
|
||||||
defaultFilterField: string;
|
defaultFilterField: string;
|
||||||
defaultSort: IModelMetaDefaultSort;
|
defaultSort: IModelMetaDefaultSort;
|
||||||
@@ -134,6 +138,8 @@ export interface IModelMeta {
|
|||||||
importAggregateOn?: string;
|
importAggregateOn?: string;
|
||||||
importAggregateBy?: string;
|
importAggregateBy?: string;
|
||||||
|
|
||||||
|
print?: IModelPrintMeta;
|
||||||
|
|
||||||
fields: { [key: string]: IModelMetaField };
|
fields: { [key: string]: IModelMetaField };
|
||||||
columns: { [key: string]: IModelMetaColumn };
|
columns: { [key: string]: IModelMetaColumn };
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,6 +8,9 @@ export default {
|
|||||||
},
|
},
|
||||||
importable: true,
|
importable: true,
|
||||||
exportable: true,
|
exportable: true,
|
||||||
|
print: {
|
||||||
|
pageTitle: 'Chart of Accounts',
|
||||||
|
},
|
||||||
fields: {
|
fields: {
|
||||||
name: {
|
name: {
|
||||||
name: 'account.field.name',
|
name: 'account.field.name',
|
||||||
@@ -121,7 +124,7 @@ export default {
|
|||||||
},
|
},
|
||||||
balance: {
|
balance: {
|
||||||
name: 'account.field.balance',
|
name: 'account.field.balance',
|
||||||
accessor: 'amount',
|
accessor: 'formattedAmount',
|
||||||
},
|
},
|
||||||
description: {
|
description: {
|
||||||
name: 'account.field.description',
|
name: 'account.field.description',
|
||||||
@@ -133,6 +136,7 @@ export default {
|
|||||||
},
|
},
|
||||||
createdAt: {
|
createdAt: {
|
||||||
name: 'account.field.created_at',
|
name: 'account.field.created_at',
|
||||||
|
printable: false,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
fields2: {
|
fields2: {
|
||||||
|
|||||||
@@ -10,6 +10,9 @@ export default {
|
|||||||
importAggregator: 'group',
|
importAggregator: 'group',
|
||||||
importAggregateOn: 'entries',
|
importAggregateOn: 'entries',
|
||||||
importAggregateBy: 'billNumber',
|
importAggregateBy: 'billNumber',
|
||||||
|
print: {
|
||||||
|
pageTitle: 'Bills',
|
||||||
|
},
|
||||||
fields: {
|
fields: {
|
||||||
vendor: {
|
vendor: {
|
||||||
name: 'bill.field.vendor',
|
name: 'bill.field.vendor',
|
||||||
@@ -83,6 +86,10 @@ export default {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
columns: {
|
columns: {
|
||||||
|
billDate: {
|
||||||
|
name: 'Date',
|
||||||
|
accessor: 'formattedBillDate',
|
||||||
|
},
|
||||||
billNumber: {
|
billNumber: {
|
||||||
name: 'Bill No.',
|
name: 'Bill No.',
|
||||||
type: 'text',
|
type: 'text',
|
||||||
@@ -91,13 +98,10 @@ export default {
|
|||||||
name: 'Reference No.',
|
name: 'Reference No.',
|
||||||
type: 'text',
|
type: 'text',
|
||||||
},
|
},
|
||||||
billDate: {
|
|
||||||
name: 'Date',
|
|
||||||
type: 'date',
|
|
||||||
},
|
|
||||||
dueDate: {
|
dueDate: {
|
||||||
name: 'Due Date',
|
name: 'Due Date',
|
||||||
type: 'date',
|
type: 'date',
|
||||||
|
accessor: 'formattedDueDate',
|
||||||
},
|
},
|
||||||
vendorId: {
|
vendorId: {
|
||||||
name: 'Vendor',
|
name: 'Vendor',
|
||||||
@@ -111,10 +115,12 @@ export default {
|
|||||||
exchangeRate: {
|
exchangeRate: {
|
||||||
name: 'Exchange Rate',
|
name: 'Exchange Rate',
|
||||||
type: 'number',
|
type: 'number',
|
||||||
|
printable: false,
|
||||||
},
|
},
|
||||||
currencyCode: {
|
currencyCode: {
|
||||||
name: 'Currency Code',
|
name: 'Currency Code',
|
||||||
type: 'text',
|
type: 'text',
|
||||||
|
printable: false,
|
||||||
},
|
},
|
||||||
dueAmount: {
|
dueAmount: {
|
||||||
name: 'Due Amount',
|
name: 'Due Amount',
|
||||||
@@ -127,10 +133,12 @@ export default {
|
|||||||
note: {
|
note: {
|
||||||
name: 'Note',
|
name: 'Note',
|
||||||
type: 'text',
|
type: 'text',
|
||||||
|
printable: false,
|
||||||
},
|
},
|
||||||
open: {
|
open: {
|
||||||
name: 'Open',
|
name: 'Open',
|
||||||
type: 'boolean',
|
type: 'boolean',
|
||||||
|
printable: false,
|
||||||
},
|
},
|
||||||
entries: {
|
entries: {
|
||||||
name: 'Entries',
|
name: 'Entries',
|
||||||
|
|||||||
@@ -77,6 +77,7 @@ export default {
|
|||||||
paymentDate: {
|
paymentDate: {
|
||||||
name: 'bill_payment.field.payment_date',
|
name: 'bill_payment.field.payment_date',
|
||||||
type: 'date',
|
type: 'date',
|
||||||
|
accessor: 'formattedPaymentDate'
|
||||||
},
|
},
|
||||||
paymentNumber: {
|
paymentNumber: {
|
||||||
name: 'bill_payment.field.payment_number',
|
name: 'bill_payment.field.payment_number',
|
||||||
@@ -94,14 +95,17 @@ export default {
|
|||||||
currencyCode: {
|
currencyCode: {
|
||||||
name: 'Currency Code',
|
name: 'Currency Code',
|
||||||
type: 'text',
|
type: 'text',
|
||||||
|
printable: false,
|
||||||
},
|
},
|
||||||
exchangeRate: {
|
exchangeRate: {
|
||||||
name: 'bill_payment.field.exchange_rate',
|
name: 'bill_payment.field.exchange_rate',
|
||||||
type: 'number',
|
type: 'number',
|
||||||
|
printable: false,
|
||||||
},
|
},
|
||||||
statement: {
|
statement: {
|
||||||
name: 'bill_payment.field.note',
|
name: 'bill_payment.field.note',
|
||||||
type: 'text',
|
type: 'text',
|
||||||
|
printable: false,
|
||||||
},
|
},
|
||||||
reference: {
|
reference: {
|
||||||
name: 'bill_payment.field.reference',
|
name: 'bill_payment.field.reference',
|
||||||
|
|||||||
@@ -20,6 +20,10 @@ export default {
|
|||||||
importAggregateOn: 'entries',
|
importAggregateOn: 'entries',
|
||||||
importAggregateBy: 'creditNoteNumber',
|
importAggregateBy: 'creditNoteNumber',
|
||||||
|
|
||||||
|
print: {
|
||||||
|
pageTitle: 'Credit Notes',
|
||||||
|
},
|
||||||
|
|
||||||
fields: {
|
fields: {
|
||||||
customer: {
|
customer: {
|
||||||
name: 'credit_note.field.customer',
|
name: 'credit_note.field.customer',
|
||||||
@@ -88,36 +92,34 @@ export default {
|
|||||||
columns: {
|
columns: {
|
||||||
customer: {
|
customer: {
|
||||||
name: 'Customer',
|
name: 'Customer',
|
||||||
type: 'relation',
|
|
||||||
accessor: 'customer.displayName',
|
accessor: 'customer.displayName',
|
||||||
},
|
},
|
||||||
exchangeRate: {
|
exchangeRate: {
|
||||||
name: 'Exchange Rate',
|
name: 'Exchange Rate',
|
||||||
type: 'number',
|
printable: false,
|
||||||
},
|
},
|
||||||
creditNoteDate: {
|
creditNoteDate: {
|
||||||
name: 'Credit Note Date',
|
name: 'Credit Note Date',
|
||||||
type: 'date',
|
accessor: 'formattedCreditNoteDate'
|
||||||
},
|
},
|
||||||
referenceNo: {
|
referenceNo: {
|
||||||
name: 'Reference No.',
|
name: 'Reference No.',
|
||||||
type: 'text',
|
|
||||||
},
|
},
|
||||||
note: {
|
note: {
|
||||||
name: 'Note',
|
name: 'Note',
|
||||||
type: 'text',
|
|
||||||
},
|
},
|
||||||
termsConditions: {
|
termsConditions: {
|
||||||
name: 'Terms & Conditions',
|
name: 'Terms & Conditions',
|
||||||
type: 'text',
|
printable: false,
|
||||||
},
|
},
|
||||||
creditNoteNumber: {
|
creditNoteNumber: {
|
||||||
name: 'Credit Note Number',
|
name: 'Credit Note Number',
|
||||||
type: 'text',
|
printable: false,
|
||||||
},
|
},
|
||||||
open: {
|
open: {
|
||||||
name: 'Open',
|
name: 'Open',
|
||||||
type: 'boolean',
|
type: 'boolean',
|
||||||
|
printable: false,
|
||||||
},
|
},
|
||||||
entries: {
|
entries: {
|
||||||
name: 'Entries',
|
name: 'Entries',
|
||||||
|
|||||||
@@ -6,6 +6,9 @@ export default {
|
|||||||
sortOrder: 'DESC',
|
sortOrder: 'DESC',
|
||||||
sortField: 'created_at',
|
sortField: 'created_at',
|
||||||
},
|
},
|
||||||
|
print: {
|
||||||
|
pageTitle: 'Customers',
|
||||||
|
},
|
||||||
fields: {
|
fields: {
|
||||||
first_name: {
|
first_name: {
|
||||||
name: 'vendor.field.first_name',
|
name: 'vendor.field.first_name',
|
||||||
@@ -127,100 +130,121 @@ export default {
|
|||||||
balance: {
|
balance: {
|
||||||
name: 'vendor.field.balance',
|
name: 'vendor.field.balance',
|
||||||
type: 'number',
|
type: 'number',
|
||||||
|
accessor: 'formattedBalance',
|
||||||
},
|
},
|
||||||
openingBalance: {
|
openingBalance: {
|
||||||
name: 'vendor.field.opening_balance',
|
name: 'vendor.field.opening_balance',
|
||||||
type: 'number',
|
type: 'number',
|
||||||
|
printable: false
|
||||||
},
|
},
|
||||||
openingBalanceAt: {
|
openingBalanceAt: {
|
||||||
name: 'vendor.field.opening_balance_at',
|
name: 'vendor.field.opening_balance_at',
|
||||||
type: 'date',
|
type: 'date',
|
||||||
|
printable: false
|
||||||
},
|
},
|
||||||
currencyCode: {
|
currencyCode: {
|
||||||
name: 'vendor.field.currency',
|
name: 'vendor.field.currency',
|
||||||
type: 'text',
|
type: 'text',
|
||||||
|
printable: false
|
||||||
},
|
},
|
||||||
status: {
|
status: {
|
||||||
name: 'vendor.field.status',
|
name: 'vendor.field.status',
|
||||||
|
printable: false
|
||||||
},
|
},
|
||||||
note: {
|
note: {
|
||||||
name: 'vendor.field.note',
|
name: 'vendor.field.note',
|
||||||
|
printable: false
|
||||||
},
|
},
|
||||||
// Billing Address
|
// Billing Address
|
||||||
billingAddress1: {
|
billingAddress1: {
|
||||||
name: 'Billing Address 1',
|
name: 'Billing Address 1',
|
||||||
column: 'billing_address1',
|
column: 'billing_address1',
|
||||||
type: 'text',
|
type: 'text',
|
||||||
|
printable: false
|
||||||
},
|
},
|
||||||
billingAddress2: {
|
billingAddress2: {
|
||||||
name: 'Billing Address 2',
|
name: 'Billing Address 2',
|
||||||
column: 'billing_address2',
|
column: 'billing_address2',
|
||||||
type: 'text',
|
type: 'text',
|
||||||
|
printable: false
|
||||||
},
|
},
|
||||||
billingAddressCity: {
|
billingAddressCity: {
|
||||||
name: 'Billing Address City',
|
name: 'Billing Address City',
|
||||||
column: 'billing_address_city',
|
column: 'billing_address_city',
|
||||||
type: 'text',
|
type: 'text',
|
||||||
|
printable: false
|
||||||
},
|
},
|
||||||
billingAddressCountry: {
|
billingAddressCountry: {
|
||||||
name: 'Billing Address Country',
|
name: 'Billing Address Country',
|
||||||
column: 'billing_address_country',
|
column: 'billing_address_country',
|
||||||
type: 'text',
|
type: 'text',
|
||||||
|
printable: false
|
||||||
},
|
},
|
||||||
billingAddressPostcode: {
|
billingAddressPostcode: {
|
||||||
name: 'Billing Address Postcode',
|
name: 'Billing Address Postcode',
|
||||||
column: 'billing_address_postcode',
|
column: 'billing_address_postcode',
|
||||||
type: 'text',
|
type: 'text',
|
||||||
|
printable: false
|
||||||
},
|
},
|
||||||
billingAddressState: {
|
billingAddressState: {
|
||||||
name: 'Billing Address State',
|
name: 'Billing Address State',
|
||||||
column: 'billing_address_state',
|
column: 'billing_address_state',
|
||||||
type: 'text',
|
type: 'text',
|
||||||
|
printable: false
|
||||||
},
|
},
|
||||||
billingAddressPhone: {
|
billingAddressPhone: {
|
||||||
name: 'Billing Address Phone',
|
name: 'Billing Address Phone',
|
||||||
column: 'billing_address_phone',
|
column: 'billing_address_phone',
|
||||||
type: 'text',
|
type: 'text',
|
||||||
|
printable: false
|
||||||
},
|
},
|
||||||
// Shipping Address
|
// Shipping Address
|
||||||
shippingAddress1: {
|
shippingAddress1: {
|
||||||
name: 'Shipping Address 1',
|
name: 'Shipping Address 1',
|
||||||
column: 'shipping_address1',
|
column: 'shipping_address1',
|
||||||
type: 'text',
|
type: 'text',
|
||||||
|
printable: false
|
||||||
},
|
},
|
||||||
shippingAddress2: {
|
shippingAddress2: {
|
||||||
name: 'Shipping Address 2',
|
name: 'Shipping Address 2',
|
||||||
column: 'shipping_address2',
|
column: 'shipping_address2',
|
||||||
type: 'text',
|
type: 'text',
|
||||||
|
printable: false
|
||||||
},
|
},
|
||||||
shippingAddressCity: {
|
shippingAddressCity: {
|
||||||
name: 'Shipping Address City',
|
name: 'Shipping Address City',
|
||||||
column: 'shipping_address_city',
|
column: 'shipping_address_city',
|
||||||
type: 'text',
|
type: 'text',
|
||||||
|
printable: false
|
||||||
},
|
},
|
||||||
shippingAddressCountry: {
|
shippingAddressCountry: {
|
||||||
name: 'Shipping Address Country',
|
name: 'Shipping Address Country',
|
||||||
column: 'shipping_address_country',
|
column: 'shipping_address_country',
|
||||||
type: 'text',
|
type: 'text',
|
||||||
|
printable: false
|
||||||
},
|
},
|
||||||
shippingAddressPostcode: {
|
shippingAddressPostcode: {
|
||||||
name: 'Shipping Address Postcode',
|
name: 'Shipping Address Postcode',
|
||||||
column: 'shipping_address_postcode',
|
column: 'shipping_address_postcode',
|
||||||
type: 'text',
|
type: 'text',
|
||||||
|
printable: false
|
||||||
},
|
},
|
||||||
shippingAddressPhone: {
|
shippingAddressPhone: {
|
||||||
name: 'Shipping Address Phone',
|
name: 'Shipping Address Phone',
|
||||||
column: 'shipping_address_phone',
|
column: 'shipping_address_phone',
|
||||||
type: 'text',
|
type: 'text',
|
||||||
|
printable: false
|
||||||
},
|
},
|
||||||
shippingAddressState: {
|
shippingAddressState: {
|
||||||
name: 'Shipping Address State',
|
name: 'Shipping Address State',
|
||||||
column: 'shipping_address_state',
|
column: 'shipping_address_state',
|
||||||
type: 'text',
|
type: 'text',
|
||||||
|
printable: false
|
||||||
},
|
},
|
||||||
createdAt: {
|
createdAt: {
|
||||||
name: 'vendor.field.created_at',
|
name: 'vendor.field.created_at',
|
||||||
type: 'date',
|
type: 'date',
|
||||||
|
printable: false
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
fields2: {
|
fields2: {
|
||||||
|
|||||||
@@ -10,6 +10,9 @@ export default {
|
|||||||
importable: true,
|
importable: true,
|
||||||
exportFlattenOn: 'categories',
|
exportFlattenOn: 'categories',
|
||||||
exportable: true,
|
exportable: true,
|
||||||
|
print: {
|
||||||
|
pageTitle: 'Expenses',
|
||||||
|
},
|
||||||
fields: {
|
fields: {
|
||||||
payment_date: {
|
payment_date: {
|
||||||
name: 'expense.field.payment_date',
|
name: 'expense.field.payment_date',
|
||||||
@@ -67,7 +70,7 @@ export default {
|
|||||||
paymentReceive: {
|
paymentReceive: {
|
||||||
name: 'expense.field.payment_account',
|
name: 'expense.field.payment_account',
|
||||||
type: 'text',
|
type: 'text',
|
||||||
accessor: 'paymentAccount.name'
|
accessor: 'paymentAccount.name',
|
||||||
},
|
},
|
||||||
referenceNo: {
|
referenceNo: {
|
||||||
name: 'expense.field.reference_no',
|
name: 'expense.field.reference_no',
|
||||||
@@ -75,15 +78,18 @@ export default {
|
|||||||
},
|
},
|
||||||
paymentDate: {
|
paymentDate: {
|
||||||
name: 'expense.field.payment_date',
|
name: 'expense.field.payment_date',
|
||||||
|
accessor: 'formattedDate',
|
||||||
type: 'date',
|
type: 'date',
|
||||||
},
|
},
|
||||||
currencyCode: {
|
currencyCode: {
|
||||||
name: 'expense.field.currency_code',
|
name: 'expense.field.currency_code',
|
||||||
type: 'text',
|
type: 'text',
|
||||||
|
printable: false,
|
||||||
},
|
},
|
||||||
exchangeRate: {
|
exchangeRate: {
|
||||||
name: 'expense.field.exchange_rate',
|
name: 'expense.field.exchange_rate',
|
||||||
type: 'number',
|
type: 'number',
|
||||||
|
printable: false,
|
||||||
},
|
},
|
||||||
description: {
|
description: {
|
||||||
name: 'expense.field.description',
|
name: 'expense.field.description',
|
||||||
@@ -111,6 +117,7 @@ export default {
|
|||||||
publish: {
|
publish: {
|
||||||
name: 'expense.field.publish',
|
name: 'expense.field.publish',
|
||||||
type: 'boolean',
|
type: 'boolean',
|
||||||
|
printable: false,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
fields2: {
|
fields2: {
|
||||||
|
|||||||
@@ -6,6 +6,9 @@ export default {
|
|||||||
sortField: 'name',
|
sortField: 'name',
|
||||||
sortOrder: 'DESC',
|
sortOrder: 'DESC',
|
||||||
},
|
},
|
||||||
|
print: {
|
||||||
|
pageTitle: 'Items',
|
||||||
|
},
|
||||||
fields: {
|
fields: {
|
||||||
type: {
|
type: {
|
||||||
name: 'item.field.type',
|
name: 'item.field.type',
|
||||||
@@ -127,6 +130,7 @@ export default {
|
|||||||
name: 'item.field.type',
|
name: 'item.field.type',
|
||||||
type: 'text',
|
type: 'text',
|
||||||
exportable: true,
|
exportable: true,
|
||||||
|
accessor: 'typeFormatted',
|
||||||
},
|
},
|
||||||
name: {
|
name: {
|
||||||
name: 'item.field.name',
|
name: 'item.field.name',
|
||||||
@@ -142,11 +146,13 @@ export default {
|
|||||||
name: 'item.field.sellable',
|
name: 'item.field.sellable',
|
||||||
type: 'boolean',
|
type: 'boolean',
|
||||||
exportable: true,
|
exportable: true,
|
||||||
|
printable: false,
|
||||||
},
|
},
|
||||||
purchasable: {
|
purchasable: {
|
||||||
name: 'item.field.purchasable',
|
name: 'item.field.purchasable',
|
||||||
type: 'boolean',
|
type: 'boolean',
|
||||||
exportable: true,
|
exportable: true,
|
||||||
|
printable: false,
|
||||||
},
|
},
|
||||||
sellPrice: {
|
sellPrice: {
|
||||||
name: 'item.field.cost_price',
|
name: 'item.field.cost_price',
|
||||||
@@ -163,12 +169,14 @@ export default {
|
|||||||
type: 'text',
|
type: 'text',
|
||||||
accessor: 'costAccount.name',
|
accessor: 'costAccount.name',
|
||||||
exportable: true,
|
exportable: true,
|
||||||
|
printable: false,
|
||||||
},
|
},
|
||||||
sellAccount: {
|
sellAccount: {
|
||||||
name: 'item.field.sell_description',
|
name: 'item.field.sell_description',
|
||||||
type: 'text',
|
type: 'text',
|
||||||
accessor: 'sellAccount.name',
|
accessor: 'sellAccount.name',
|
||||||
exportable: true,
|
exportable: true,
|
||||||
|
printable: false,
|
||||||
},
|
},
|
||||||
inventoryAccount: {
|
inventoryAccount: {
|
||||||
name: 'item.field.inventory_account',
|
name: 'item.field.inventory_account',
|
||||||
@@ -180,11 +188,13 @@ export default {
|
|||||||
name: 'Sell description',
|
name: 'Sell description',
|
||||||
type: 'text',
|
type: 'text',
|
||||||
exportable: true,
|
exportable: true,
|
||||||
|
printable: false,
|
||||||
},
|
},
|
||||||
purchaseDescription: {
|
purchaseDescription: {
|
||||||
name: 'Purchase description',
|
name: 'Purchase description',
|
||||||
type: 'text',
|
type: 'text',
|
||||||
exportable: true,
|
exportable: true,
|
||||||
|
printable: false,
|
||||||
},
|
},
|
||||||
quantityOnHand: {
|
quantityOnHand: {
|
||||||
name: 'item.field.quantity_on_hand',
|
name: 'item.field.quantity_on_hand',
|
||||||
@@ -206,11 +216,13 @@ export default {
|
|||||||
name: 'item.field.active',
|
name: 'item.field.active',
|
||||||
fieldType: 'boolean',
|
fieldType: 'boolean',
|
||||||
exportable: true,
|
exportable: true,
|
||||||
|
printable: false,
|
||||||
},
|
},
|
||||||
createdAt: {
|
createdAt: {
|
||||||
name: 'item.field.created_at',
|
name: 'item.field.created_at',
|
||||||
type: 'date',
|
type: 'date',
|
||||||
exportable: true,
|
exportable: true,
|
||||||
|
printable: false,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
fields2: {
|
fields2: {
|
||||||
|
|||||||
@@ -11,6 +11,11 @@ export default {
|
|||||||
importAggregator: 'group',
|
importAggregator: 'group',
|
||||||
importAggregateOn: 'entries',
|
importAggregateOn: 'entries',
|
||||||
importAggregateBy: 'journalNumber',
|
importAggregateBy: 'journalNumber',
|
||||||
|
|
||||||
|
print: {
|
||||||
|
pageTitle: 'Manual Journals',
|
||||||
|
},
|
||||||
|
|
||||||
fields: {
|
fields: {
|
||||||
date: {
|
date: {
|
||||||
name: 'manual_journal.field.date',
|
name: 'manual_journal.field.date',
|
||||||
@@ -63,6 +68,7 @@ export default {
|
|||||||
date: {
|
date: {
|
||||||
name: 'manual_journal.field.date',
|
name: 'manual_journal.field.date',
|
||||||
type: 'date',
|
type: 'date',
|
||||||
|
accessor: 'formattedDate',
|
||||||
},
|
},
|
||||||
journalNumber: {
|
journalNumber: {
|
||||||
name: 'manual_journal.field.journal_number',
|
name: 'manual_journal.field.journal_number',
|
||||||
@@ -83,10 +89,12 @@ export default {
|
|||||||
currencyCode: {
|
currencyCode: {
|
||||||
name: 'manual_journal.field.currency',
|
name: 'manual_journal.field.currency',
|
||||||
type: 'text',
|
type: 'text',
|
||||||
|
printable: false,
|
||||||
},
|
},
|
||||||
exchangeRate: {
|
exchangeRate: {
|
||||||
name: 'manual_journal.field.exchange_rate',
|
name: 'manual_journal.field.exchange_rate',
|
||||||
type: 'number',
|
type: 'number',
|
||||||
|
printable: false,
|
||||||
},
|
},
|
||||||
description: {
|
description: {
|
||||||
name: 'manual_journal.field.description',
|
name: 'manual_journal.field.description',
|
||||||
@@ -120,13 +128,17 @@ export default {
|
|||||||
publish: {
|
publish: {
|
||||||
name: 'Publish',
|
name: 'Publish',
|
||||||
type: 'boolean',
|
type: 'boolean',
|
||||||
|
printable: false,
|
||||||
},
|
},
|
||||||
publishedAt: {
|
publishedAt: {
|
||||||
name: 'Published At',
|
name: 'Published At',
|
||||||
|
printable: false,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
createdAt: {
|
createdAt: {
|
||||||
name: 'Created At',
|
name: 'Created At',
|
||||||
|
accessor: 'formattedCreatedAt',
|
||||||
|
printable: false,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
fields2: {
|
fields2: {
|
||||||
|
|||||||
@@ -67,10 +67,12 @@ export default {
|
|||||||
paymentDate: {
|
paymentDate: {
|
||||||
name: 'payment_receive.field.payment_date',
|
name: 'payment_receive.field.payment_date',
|
||||||
type: 'date',
|
type: 'date',
|
||||||
|
accessor: 'formattedPaymentDate',
|
||||||
},
|
},
|
||||||
amount: {
|
amount: {
|
||||||
name: 'payment_receive.field.amount',
|
name: 'payment_receive.field.amount',
|
||||||
type: 'number',
|
type: 'number',
|
||||||
|
accessor: 'formattedAmount'
|
||||||
},
|
},
|
||||||
referenceNo: {
|
referenceNo: {
|
||||||
name: 'payment_receive.field.reference_no',
|
name: 'payment_receive.field.reference_no',
|
||||||
@@ -88,10 +90,12 @@ export default {
|
|||||||
statement: {
|
statement: {
|
||||||
name: 'payment_receive.field.statement',
|
name: 'payment_receive.field.statement',
|
||||||
type: 'text',
|
type: 'text',
|
||||||
|
printable: false,
|
||||||
},
|
},
|
||||||
created_at: {
|
created_at: {
|
||||||
name: 'payment_receive.field.created_at',
|
name: 'payment_receive.field.created_at',
|
||||||
type: 'date',
|
type: 'date',
|
||||||
|
printable: false,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
fields2: {
|
fields2: {
|
||||||
|
|||||||
@@ -11,6 +11,11 @@ export default {
|
|||||||
importAggregator: 'group',
|
importAggregator: 'group',
|
||||||
importAggregateOn: 'entries',
|
importAggregateOn: 'entries',
|
||||||
importAggregateBy: 'estimateNumber',
|
importAggregateBy: 'estimateNumber',
|
||||||
|
|
||||||
|
print: {
|
||||||
|
pageTitle: 'Sale Estimates'
|
||||||
|
},
|
||||||
|
|
||||||
fields: {
|
fields: {
|
||||||
amount: {
|
amount: {
|
||||||
name: 'estimate.field.amount',
|
name: 'estimate.field.amount',
|
||||||
@@ -86,11 +91,13 @@ export default {
|
|||||||
estimateDate: {
|
estimateDate: {
|
||||||
name: 'Estimate Date',
|
name: 'Estimate Date',
|
||||||
type: 'date',
|
type: 'date',
|
||||||
|
accessor: 'formattedEstimateDate',
|
||||||
exportable: true,
|
exportable: true,
|
||||||
},
|
},
|
||||||
expirationDate: {
|
expirationDate: {
|
||||||
name: 'Expiration Date',
|
name: 'Expiration Date',
|
||||||
type: 'date',
|
type: 'date',
|
||||||
|
accessor: 'formattedExpirationDate',
|
||||||
exportable: true,
|
exportable: true,
|
||||||
},
|
},
|
||||||
estimateNumber: {
|
estimateNumber: {
|
||||||
@@ -112,26 +119,31 @@ export default {
|
|||||||
name: 'Exchange Rate',
|
name: 'Exchange Rate',
|
||||||
type: 'number',
|
type: 'number',
|
||||||
exportable: true,
|
exportable: true,
|
||||||
|
printable: false,
|
||||||
},
|
},
|
||||||
currencyCode: {
|
currencyCode: {
|
||||||
name: 'Currency',
|
name: 'Currency',
|
||||||
type: 'text',
|
type: 'text',
|
||||||
exportable: true,
|
exportable: true,
|
||||||
|
printable: false,
|
||||||
},
|
},
|
||||||
note: {
|
note: {
|
||||||
name: 'Note',
|
name: 'Note',
|
||||||
type: 'text',
|
type: 'text',
|
||||||
exportable: true,
|
exportable: true,
|
||||||
|
printable: false,
|
||||||
},
|
},
|
||||||
termsConditions: {
|
termsConditions: {
|
||||||
name: 'Terms & Conditions',
|
name: 'Terms & Conditions',
|
||||||
type: 'text',
|
type: 'text',
|
||||||
exportable: true,
|
exportable: true,
|
||||||
|
printable: false,
|
||||||
},
|
},
|
||||||
delivered: {
|
delivered: {
|
||||||
name: 'Delivered',
|
name: 'Delivered',
|
||||||
type: 'boolean',
|
type: 'boolean',
|
||||||
exportable: true,
|
exportable: true,
|
||||||
|
printable: false,
|
||||||
},
|
},
|
||||||
entries: {
|
entries: {
|
||||||
name: 'Entries',
|
name: 'Entries',
|
||||||
@@ -153,6 +165,7 @@ export default {
|
|||||||
},
|
},
|
||||||
description: {
|
description: {
|
||||||
name: 'Item Description',
|
name: 'Item Description',
|
||||||
|
printable: false,
|
||||||
},
|
},
|
||||||
amount: {
|
amount: {
|
||||||
name: 'Item Amount',
|
name: 'Item Amount',
|
||||||
|
|||||||
@@ -11,6 +11,10 @@ export default {
|
|||||||
importAggregator: 'group',
|
importAggregator: 'group',
|
||||||
importAggregateOn: 'entries',
|
importAggregateOn: 'entries',
|
||||||
importAggregateBy: 'invoiceNo',
|
importAggregateBy: 'invoiceNo',
|
||||||
|
|
||||||
|
print: {
|
||||||
|
pageTitle: 'Sale invoices',
|
||||||
|
},
|
||||||
fields: {
|
fields: {
|
||||||
customer: {
|
customer: {
|
||||||
name: 'invoice.field.customer',
|
name: 'invoice.field.customer',
|
||||||
@@ -94,10 +98,12 @@ export default {
|
|||||||
invoiceDate: {
|
invoiceDate: {
|
||||||
name: 'invoice.field.invoice_date',
|
name: 'invoice.field.invoice_date',
|
||||||
type: 'date',
|
type: 'date',
|
||||||
|
accessor: 'invoiceDateFormatted',
|
||||||
},
|
},
|
||||||
dueDate: {
|
dueDate: {
|
||||||
name: 'invoice.field.due_date',
|
name: 'invoice.field.due_date',
|
||||||
type: 'date',
|
type: 'date',
|
||||||
|
accessor: 'dueDateFormatted',
|
||||||
},
|
},
|
||||||
referenceNo: {
|
referenceNo: {
|
||||||
name: 'invoice.field.reference_no',
|
name: 'invoice.field.reference_no',
|
||||||
@@ -120,10 +126,12 @@ export default {
|
|||||||
exchangeRate: {
|
exchangeRate: {
|
||||||
name: 'invoice.field.exchange_rate',
|
name: 'invoice.field.exchange_rate',
|
||||||
type: 'number',
|
type: 'number',
|
||||||
|
printable: false,
|
||||||
},
|
},
|
||||||
currencyCode: {
|
currencyCode: {
|
||||||
name: 'invoice.field.currency',
|
name: 'invoice.field.currency',
|
||||||
type: 'text',
|
type: 'text',
|
||||||
|
printable: false,
|
||||||
},
|
},
|
||||||
paidAmount: {
|
paidAmount: {
|
||||||
name: 'Paid Amount',
|
name: 'Paid Amount',
|
||||||
@@ -136,14 +144,17 @@ export default {
|
|||||||
invoiceMessage: {
|
invoiceMessage: {
|
||||||
name: 'invoice.field.invoice_message',
|
name: 'invoice.field.invoice_message',
|
||||||
type: 'text',
|
type: 'text',
|
||||||
|
printable: false,
|
||||||
},
|
},
|
||||||
termsConditions: {
|
termsConditions: {
|
||||||
name: 'invoice.field.terms_conditions',
|
name: 'invoice.field.terms_conditions',
|
||||||
type: 'text',
|
type: 'text',
|
||||||
|
printable: false,
|
||||||
},
|
},
|
||||||
delivered: {
|
delivered: {
|
||||||
name: 'invoice.field.delivered',
|
name: 'invoice.field.delivered',
|
||||||
type: 'boolean',
|
type: 'boolean',
|
||||||
|
printable: false,
|
||||||
},
|
},
|
||||||
entries: {
|
entries: {
|
||||||
name: 'Entries',
|
name: 'Entries',
|
||||||
@@ -165,6 +176,7 @@ export default {
|
|||||||
},
|
},
|
||||||
description: {
|
description: {
|
||||||
name: 'Item Description',
|
name: 'Item Description',
|
||||||
|
printable: false,
|
||||||
},
|
},
|
||||||
amount: {
|
amount: {
|
||||||
name: 'Item Amount',
|
name: 'Item Amount',
|
||||||
@@ -202,18 +214,22 @@ export default {
|
|||||||
exchangeRate: {
|
exchangeRate: {
|
||||||
name: 'invoice.field.exchange_rate',
|
name: 'invoice.field.exchange_rate',
|
||||||
fieldType: 'number',
|
fieldType: 'number',
|
||||||
|
printable: false,
|
||||||
},
|
},
|
||||||
currencyCode: {
|
currencyCode: {
|
||||||
name: 'invoice.field.currency',
|
name: 'invoice.field.currency',
|
||||||
fieldType: 'text',
|
fieldType: 'text',
|
||||||
|
printable: false,
|
||||||
},
|
},
|
||||||
invoiceMessage: {
|
invoiceMessage: {
|
||||||
name: 'invoice.field.invoice_message',
|
name: 'invoice.field.invoice_message',
|
||||||
fieldType: 'text',
|
fieldType: 'text',
|
||||||
|
printable: false,
|
||||||
},
|
},
|
||||||
termsConditions: {
|
termsConditions: {
|
||||||
name: 'invoice.field.terms_conditions',
|
name: 'invoice.field.terms_conditions',
|
||||||
fieldType: 'text',
|
fieldType: 'text',
|
||||||
|
printable: false,
|
||||||
},
|
},
|
||||||
entries: {
|
entries: {
|
||||||
name: 'invoice.field.entries',
|
name: 'invoice.field.entries',
|
||||||
@@ -249,6 +265,7 @@ export default {
|
|||||||
delivered: {
|
delivered: {
|
||||||
name: 'invoice.field.delivered',
|
name: 'invoice.field.delivered',
|
||||||
fieldType: 'boolean',
|
fieldType: 'boolean',
|
||||||
|
printable: false,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -11,6 +11,10 @@ export default {
|
|||||||
importAggregator: 'group',
|
importAggregator: 'group',
|
||||||
importAggregateOn: 'entries',
|
importAggregateOn: 'entries',
|
||||||
importAggregateBy: 'receiptNumber',
|
importAggregateBy: 'receiptNumber',
|
||||||
|
|
||||||
|
print: {
|
||||||
|
pageTitle: 'Sale Receipts',
|
||||||
|
},
|
||||||
fields: {
|
fields: {
|
||||||
amount: {
|
amount: {
|
||||||
name: 'receipt.field.amount',
|
name: 'receipt.field.amount',
|
||||||
@@ -81,11 +85,6 @@ export default {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
columns: {
|
columns: {
|
||||||
amount: {
|
|
||||||
name: 'receipt.field.amount',
|
|
||||||
column: 'amount',
|
|
||||||
type: 'number',
|
|
||||||
},
|
|
||||||
depositAccount: {
|
depositAccount: {
|
||||||
name: 'receipt.field.deposit_account',
|
name: 'receipt.field.deposit_account',
|
||||||
type: 'text',
|
type: 'text',
|
||||||
@@ -98,6 +97,7 @@ export default {
|
|||||||
},
|
},
|
||||||
receiptDate: {
|
receiptDate: {
|
||||||
name: 'receipt.field.receipt_date',
|
name: 'receipt.field.receipt_date',
|
||||||
|
accessor: 'formattedReceiptDate',
|
||||||
type: 'date',
|
type: 'date',
|
||||||
},
|
},
|
||||||
receiptNumber: {
|
receiptNumber: {
|
||||||
@@ -114,10 +114,17 @@ export default {
|
|||||||
name: 'receipt.field.receipt_message',
|
name: 'receipt.field.receipt_message',
|
||||||
column: 'receipt_message',
|
column: 'receipt_message',
|
||||||
type: 'text',
|
type: 'text',
|
||||||
|
printable: false,
|
||||||
|
},
|
||||||
|
amount: {
|
||||||
|
name: 'receipt.field.amount',
|
||||||
|
accessor: 'formattedAmount',
|
||||||
|
type: 'number',
|
||||||
},
|
},
|
||||||
statement: {
|
statement: {
|
||||||
name: 'receipt.field.statement',
|
name: 'receipt.field.statement',
|
||||||
type: 'text',
|
type: 'text',
|
||||||
|
printable: false,
|
||||||
},
|
},
|
||||||
status: {
|
status: {
|
||||||
name: 'receipt.field.status',
|
name: 'receipt.field.status',
|
||||||
@@ -127,6 +134,7 @@ export default {
|
|||||||
{ key: 'closed', label: 'receipt.field.status.closed' },
|
{ key: 'closed', label: 'receipt.field.status.closed' },
|
||||||
],
|
],
|
||||||
exportable: true,
|
exportable: true,
|
||||||
|
printable: false,
|
||||||
},
|
},
|
||||||
entries: {
|
entries: {
|
||||||
name: 'Entries',
|
name: 'Entries',
|
||||||
@@ -148,6 +156,7 @@ export default {
|
|||||||
},
|
},
|
||||||
description: {
|
description: {
|
||||||
name: 'Item Description',
|
name: 'Item Description',
|
||||||
|
printable: false,
|
||||||
},
|
},
|
||||||
amount: {
|
amount: {
|
||||||
name: 'Item Amount',
|
name: 'Item Amount',
|
||||||
@@ -158,6 +167,7 @@ export default {
|
|||||||
createdAt: {
|
createdAt: {
|
||||||
name: 'receipt.field.created_at',
|
name: 'receipt.field.created_at',
|
||||||
type: 'date',
|
type: 'date',
|
||||||
|
printable: false,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
fields2: {
|
fields2: {
|
||||||
|
|||||||
@@ -131,21 +131,26 @@ export default {
|
|||||||
openingBalance: {
|
openingBalance: {
|
||||||
name: 'vendor.field.opening_balance',
|
name: 'vendor.field.opening_balance',
|
||||||
type: 'number',
|
type: 'number',
|
||||||
|
printable: false
|
||||||
},
|
},
|
||||||
openingBalanceAt: {
|
openingBalanceAt: {
|
||||||
name: 'vendor.field.opening_balance_at',
|
name: 'vendor.field.opening_balance_at',
|
||||||
type: 'date',
|
type: 'date',
|
||||||
|
printable: false
|
||||||
},
|
},
|
||||||
currencyCode: {
|
currencyCode: {
|
||||||
name: 'vendor.field.currency',
|
name: 'vendor.field.currency',
|
||||||
type: 'text',
|
type: 'text',
|
||||||
|
printable: false
|
||||||
},
|
},
|
||||||
status: {
|
status: {
|
||||||
name: 'vendor.field.status',
|
name: 'vendor.field.status',
|
||||||
|
printable: false
|
||||||
},
|
},
|
||||||
note: {
|
note: {
|
||||||
name: 'vendor.field.note',
|
name: 'vendor.field.note',
|
||||||
type: 'text',
|
type: 'text',
|
||||||
|
printable: false
|
||||||
},
|
},
|
||||||
// Billing Address
|
// Billing Address
|
||||||
billingAddress1: {
|
billingAddress1: {
|
||||||
@@ -153,42 +158,49 @@ export default {
|
|||||||
column: 'billing_address1',
|
column: 'billing_address1',
|
||||||
type: 'text',
|
type: 'text',
|
||||||
exportable: true,
|
exportable: true,
|
||||||
|
printable: false
|
||||||
},
|
},
|
||||||
billingAddress2: {
|
billingAddress2: {
|
||||||
name: 'Billing Address 2',
|
name: 'Billing Address 2',
|
||||||
column: 'billing_address2',
|
column: 'billing_address2',
|
||||||
type: 'text',
|
type: 'text',
|
||||||
exportable: true,
|
exportable: true,
|
||||||
|
printable: false
|
||||||
},
|
},
|
||||||
billingAddressCity: {
|
billingAddressCity: {
|
||||||
name: 'Billing Address City',
|
name: 'Billing Address City',
|
||||||
column: 'billing_address_city',
|
column: 'billing_address_city',
|
||||||
type: 'text',
|
type: 'text',
|
||||||
exportable: true,
|
exportable: true,
|
||||||
|
printable: false
|
||||||
},
|
},
|
||||||
billingAddressCountry: {
|
billingAddressCountry: {
|
||||||
name: 'Billing Address Country',
|
name: 'Billing Address Country',
|
||||||
column: 'billing_address_country',
|
column: 'billing_address_country',
|
||||||
type: 'text',
|
type: 'text',
|
||||||
exportable: true,
|
exportable: true,
|
||||||
|
printable: false
|
||||||
},
|
},
|
||||||
billingAddressPostcode: {
|
billingAddressPostcode: {
|
||||||
name: 'Billing Address Postcode',
|
name: 'Billing Address Postcode',
|
||||||
column: 'billing_address_postcode',
|
column: 'billing_address_postcode',
|
||||||
type: 'text',
|
type: 'text',
|
||||||
exportable: true,
|
exportable: true,
|
||||||
|
printable: false
|
||||||
},
|
},
|
||||||
billingAddressState: {
|
billingAddressState: {
|
||||||
name: 'Billing Address State',
|
name: 'Billing Address State',
|
||||||
column: 'billing_address_state',
|
column: 'billing_address_state',
|
||||||
type: 'text',
|
type: 'text',
|
||||||
exportable: true,
|
exportable: true,
|
||||||
|
printable: false
|
||||||
},
|
},
|
||||||
billingAddressPhone: {
|
billingAddressPhone: {
|
||||||
name: 'Billing Address Phone',
|
name: 'Billing Address Phone',
|
||||||
column: 'billing_address_phone',
|
column: 'billing_address_phone',
|
||||||
type: 'text',
|
type: 'text',
|
||||||
exportable: true,
|
exportable: true,
|
||||||
|
printable: false
|
||||||
},
|
},
|
||||||
// Shipping Address
|
// Shipping Address
|
||||||
shippingAddress1: {
|
shippingAddress1: {
|
||||||
@@ -196,47 +208,55 @@ export default {
|
|||||||
column: 'shipping_address1',
|
column: 'shipping_address1',
|
||||||
type: 'text',
|
type: 'text',
|
||||||
exportable: true,
|
exportable: true,
|
||||||
|
printable: false
|
||||||
},
|
},
|
||||||
shippingAddress2: {
|
shippingAddress2: {
|
||||||
name: 'Shipping Address 2',
|
name: 'Shipping Address 2',
|
||||||
column: 'shipping_address2',
|
column: 'shipping_address2',
|
||||||
type: 'text',
|
type: 'text',
|
||||||
exportable: true,
|
exportable: true,
|
||||||
|
printable: false
|
||||||
},
|
},
|
||||||
shippingAddressCity: {
|
shippingAddressCity: {
|
||||||
name: 'Shipping Address City',
|
name: 'Shipping Address City',
|
||||||
column: 'shipping_address_city',
|
column: 'shipping_address_city',
|
||||||
type: 'text',
|
type: 'text',
|
||||||
exportable: true,
|
exportable: true,
|
||||||
|
printable: false
|
||||||
},
|
},
|
||||||
shippingAddressCountry: {
|
shippingAddressCountry: {
|
||||||
name: 'Shipping Address Country',
|
name: 'Shipping Address Country',
|
||||||
column: 'shipping_address_country',
|
column: 'shipping_address_country',
|
||||||
type: 'text',
|
type: 'text',
|
||||||
exportable: true,
|
exportable: true,
|
||||||
|
printable: false
|
||||||
},
|
},
|
||||||
shippingAddressPostcode: {
|
shippingAddressPostcode: {
|
||||||
name: 'Shipping Address Postcode',
|
name: 'Shipping Address Postcode',
|
||||||
column: 'shipping_address_postcode',
|
column: 'shipping_address_postcode',
|
||||||
type: 'text',
|
type: 'text',
|
||||||
exportable: true,
|
exportable: true,
|
||||||
|
printable: false
|
||||||
},
|
},
|
||||||
shippingAddressState: {
|
shippingAddressState: {
|
||||||
name: 'Shipping Address State',
|
name: 'Shipping Address State',
|
||||||
column: 'shipping_address_state',
|
column: 'shipping_address_state',
|
||||||
type: 'text',
|
type: 'text',
|
||||||
exportable: true,
|
exportable: true,
|
||||||
|
printable: false
|
||||||
},
|
},
|
||||||
shippingAddressPhone: {
|
shippingAddressPhone: {
|
||||||
name: 'Shipping Address Phone',
|
name: 'Shipping Address Phone',
|
||||||
column: 'shipping_address_phone',
|
column: 'shipping_address_phone',
|
||||||
type: 'text',
|
type: 'text',
|
||||||
exportable: true,
|
exportable: true,
|
||||||
|
printable: false
|
||||||
},
|
},
|
||||||
createdAt: {
|
createdAt: {
|
||||||
name: 'vendor.field.created_at',
|
name: 'vendor.field.created_at',
|
||||||
type: 'date',
|
type: 'date',
|
||||||
exportable: true,
|
exportable: true,
|
||||||
|
printable: false
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
fields2: {
|
fields2: {
|
||||||
|
|||||||
@@ -20,6 +20,9 @@ export default {
|
|||||||
importAggregateOn: 'entries',
|
importAggregateOn: 'entries',
|
||||||
importAggregateBy: 'vendorCreditNumber',
|
importAggregateBy: 'vendorCreditNumber',
|
||||||
|
|
||||||
|
print: {
|
||||||
|
pageTitle: 'Vendor Credits',
|
||||||
|
},
|
||||||
fields: {
|
fields: {
|
||||||
vendor: {
|
vendor: {
|
||||||
name: 'vendor_credit.field.vendor',
|
name: 'vendor_credit.field.vendor',
|
||||||
@@ -89,6 +92,7 @@ export default {
|
|||||||
exchangeRate: {
|
exchangeRate: {
|
||||||
name: 'Echange Rate',
|
name: 'Echange Rate',
|
||||||
type: 'text',
|
type: 'text',
|
||||||
|
printable: false,
|
||||||
},
|
},
|
||||||
vendorCreditNumber: {
|
vendorCreditNumber: {
|
||||||
name: 'Vendor Credit No.',
|
name: 'Vendor Credit No.',
|
||||||
@@ -100,7 +104,7 @@ export default {
|
|||||||
},
|
},
|
||||||
vendorCreditDate: {
|
vendorCreditDate: {
|
||||||
name: 'Vendor Credit Date',
|
name: 'Vendor Credit Date',
|
||||||
type: 'date',
|
accessor: 'formattedVendorCreditDate',
|
||||||
},
|
},
|
||||||
amount: {
|
amount: {
|
||||||
name: 'Amount',
|
name: 'Amount',
|
||||||
@@ -109,10 +113,12 @@ export default {
|
|||||||
creditRemaining: {
|
creditRemaining: {
|
||||||
name: 'Credits Remaining',
|
name: 'Credits Remaining',
|
||||||
accessor: 'formattedCreditsRemaining',
|
accessor: 'formattedCreditsRemaining',
|
||||||
|
printable: false,
|
||||||
},
|
},
|
||||||
refundedAmount: {
|
refundedAmount: {
|
||||||
name: 'Refunded Amount',
|
name: 'Refunded Amount',
|
||||||
accessor: 'refundedAmount',
|
accessor: 'refundedAmount',
|
||||||
|
printable: false,
|
||||||
},
|
},
|
||||||
invoicedAmount: {
|
invoicedAmount: {
|
||||||
name: 'Invoiced Amount',
|
name: 'Invoiced Amount',
|
||||||
@@ -121,10 +127,12 @@ export default {
|
|||||||
note: {
|
note: {
|
||||||
name: 'Note',
|
name: 'Note',
|
||||||
type: 'text',
|
type: 'text',
|
||||||
|
printable: false,
|
||||||
},
|
},
|
||||||
open: {
|
open: {
|
||||||
name: 'Open',
|
name: 'Open',
|
||||||
type: 'boolean',
|
type: 'boolean',
|
||||||
|
printable: false,
|
||||||
},
|
},
|
||||||
entries: {
|
entries: {
|
||||||
name: 'Entries',
|
name: 'Entries',
|
||||||
|
|||||||
@@ -5,7 +5,11 @@ import { PageProperties, PdfFormat } from '@/lib/Chromiumly/_types';
|
|||||||
import { UrlConverter } from '@/lib/Chromiumly/UrlConvert';
|
import { UrlConverter } from '@/lib/Chromiumly/UrlConvert';
|
||||||
import HasTenancyService from '../Tenancy/TenancyService';
|
import HasTenancyService from '../Tenancy/TenancyService';
|
||||||
import { Chromiumly } from '@/lib/Chromiumly/Chromiumly';
|
import { Chromiumly } from '@/lib/Chromiumly/Chromiumly';
|
||||||
import { PDF_FILE_EXPIRE_IN, getPdfFilesStorageDir } from './utils';
|
import {
|
||||||
|
PDF_FILE_EXPIRE_IN,
|
||||||
|
getPdfFilePath,
|
||||||
|
getPdfFilesStorageDir,
|
||||||
|
} from './utils';
|
||||||
|
|
||||||
@Service()
|
@Service()
|
||||||
export class ChromiumlyHtmlConvert {
|
export class ChromiumlyHtmlConvert {
|
||||||
@@ -22,22 +26,16 @@ export class ChromiumlyHtmlConvert {
|
|||||||
tenantId: number,
|
tenantId: number,
|
||||||
content: string
|
content: string
|
||||||
): Promise<[string, () => Promise<void>]> {
|
): Promise<[string, () => Promise<void>]> {
|
||||||
const { Attachment } = this.tenancy.models(tenantId);
|
const { Document } = this.tenancy.models(tenantId);
|
||||||
|
|
||||||
const filename = `document-${Date.now()}.html`;
|
const filename = `document-print-${Date.now()}.html`;
|
||||||
const storageDir = getPdfFilesStorageDir(filename);
|
const filePath = getPdfFilePath(filename);
|
||||||
const filePath = path.join(global.__storage_dir, storageDir);
|
|
||||||
|
|
||||||
await fs.writeFile(filePath, content);
|
await fs.writeFile(filePath, content);
|
||||||
await Attachment.query().insert({
|
await Document.query().insert({ key: filename, mimeType: 'text/html' });
|
||||||
key: filename,
|
|
||||||
path: storageDir,
|
|
||||||
expire_in: PDF_FILE_EXPIRE_IN, // ms
|
|
||||||
extension: 'html',
|
|
||||||
});
|
|
||||||
const cleanup = async () => {
|
const cleanup = async () => {
|
||||||
await fs.unlink(filePath);
|
await fs.unlink(filePath);
|
||||||
await Attachment.query().where('key', filename).delete();
|
await Document.query().where('key', filename).delete();
|
||||||
};
|
};
|
||||||
return [filename, cleanup];
|
return [filename, cleanup];
|
||||||
}
|
}
|
||||||
@@ -60,6 +58,7 @@ export class ChromiumlyHtmlConvert {
|
|||||||
html
|
html
|
||||||
);
|
);
|
||||||
const fileDir = getPdfFilesStorageDir(filename);
|
const fileDir = getPdfFilesStorageDir(filename);
|
||||||
|
|
||||||
const url = path.join(Chromiumly.GOTENBERG_DOCS_ENDPOINT, fileDir);
|
const url = path.join(Chromiumly.GOTENBERG_DOCS_ENDPOINT, fileDir);
|
||||||
const urlConverter = new UrlConverter();
|
const urlConverter = new UrlConverter();
|
||||||
|
|
||||||
|
|||||||
@@ -5,4 +5,10 @@ export const PDF_FILE_EXPIRE_IN = 40; // ms
|
|||||||
|
|
||||||
export const getPdfFilesStorageDir = (filename: string) => {
|
export const getPdfFilesStorageDir = (filename: string) => {
|
||||||
return path.join(PDF_FILE_SUB_DIR, filename);
|
return path.join(PDF_FILE_SUB_DIR, filename);
|
||||||
}
|
};
|
||||||
|
|
||||||
|
export const getPdfFilePath = (filename: string) => {
|
||||||
|
const storageDir = getPdfFilesStorageDir(filename);
|
||||||
|
|
||||||
|
return path.join(global.__storage_dir, storageDir);
|
||||||
|
};
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
import { Inject, Service } from 'typedi';
|
import { Inject, Service } from 'typedi';
|
||||||
import { ExportResourceService } from './ExportService';
|
import { ExportResourceService } from './ExportService';
|
||||||
|
import { ExportFormat } from './common';
|
||||||
|
|
||||||
@Service()
|
@Service()
|
||||||
export class ExportApplication {
|
export class ExportApplication {
|
||||||
@@ -9,9 +10,9 @@ export class ExportApplication {
|
|||||||
/**
|
/**
|
||||||
* Exports the given resource to csv, xlsx or pdf format.
|
* Exports the given resource to csv, xlsx or pdf format.
|
||||||
* @param {string} reosurce
|
* @param {string} reosurce
|
||||||
* @param {string} format
|
* @param {ExportFormat} format
|
||||||
*/
|
*/
|
||||||
public export(tenantId: number, resource: string, format: string) {
|
public export(tenantId: number, resource: string, format: ExportFormat) {
|
||||||
return this.exportResource.export(tenantId, resource, format);
|
return this.exportResource.export(tenantId, resource, format);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
47
packages/server/src/services/Export/ExportPdf.ts
Normal file
47
packages/server/src/services/Export/ExportPdf.ts
Normal file
@@ -0,0 +1,47 @@
|
|||||||
|
import { Inject, Service } from 'typedi';
|
||||||
|
import { ChromiumlyTenancy } from '../ChromiumlyTenancy/ChromiumlyTenancy';
|
||||||
|
import { TemplateInjectable } from '../TemplateInjectable/TemplateInjectable';
|
||||||
|
import { mapPdfRows } from './utils';
|
||||||
|
|
||||||
|
@Service()
|
||||||
|
export class ExportPdf {
|
||||||
|
@Inject()
|
||||||
|
private templateInjectable: TemplateInjectable;
|
||||||
|
|
||||||
|
@Inject()
|
||||||
|
private chromiumlyTenancy: ChromiumlyTenancy;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Generates the pdf table sheet for the given data and columns.
|
||||||
|
* @param {number} tenantId
|
||||||
|
* @param {} columns
|
||||||
|
* @param {Record<string, string>} data
|
||||||
|
* @param {string} sheetTitle
|
||||||
|
* @param {string} sheetDescription
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
public async pdf(
|
||||||
|
tenantId: number,
|
||||||
|
columns: { accessor: string },
|
||||||
|
data: Record<string, any>,
|
||||||
|
sheetTitle: string = '',
|
||||||
|
sheetDescription: string = ''
|
||||||
|
) {
|
||||||
|
const rows = mapPdfRows(columns, data);
|
||||||
|
|
||||||
|
const htmlContent = await this.templateInjectable.render(
|
||||||
|
tenantId,
|
||||||
|
'modules/export-resource-table',
|
||||||
|
{
|
||||||
|
table: { rows, columns },
|
||||||
|
sheetTitle,
|
||||||
|
sheetDescription,
|
||||||
|
}
|
||||||
|
);
|
||||||
|
// Convert the HTML content to PDF
|
||||||
|
return this.chromiumlyTenancy.convertHtmlContent(tenantId, htmlContent, {
|
||||||
|
margins: { top: 0.2, bottom: 0.2, left: 0.2, right: 0.2 },
|
||||||
|
landscape: true,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -6,9 +6,10 @@ import { sanitizeResourceName } from '../Import/_utils';
|
|||||||
import ResourceService from '../Resource/ResourceService';
|
import ResourceService from '../Resource/ResourceService';
|
||||||
import { ExportableResources } from './ExportResources';
|
import { ExportableResources } from './ExportResources';
|
||||||
import { ServiceError } from '@/exceptions';
|
import { ServiceError } from '@/exceptions';
|
||||||
import { Errors } from './common';
|
import { Errors, ExportFormat } from './common';
|
||||||
import { IModelMeta, IModelMetaColumn } from '@/interfaces';
|
import { IModelMeta, IModelMetaColumn } from '@/interfaces';
|
||||||
import { flatDataCollections, getDataAccessor } from './utils';
|
import { flatDataCollections, getDataAccessor } from './utils';
|
||||||
|
import { ExportPdf } from './ExportPdf';
|
||||||
|
|
||||||
@Service()
|
@Service()
|
||||||
export class ExportResourceService {
|
export class ExportResourceService {
|
||||||
@@ -18,13 +19,20 @@ export class ExportResourceService {
|
|||||||
@Inject()
|
@Inject()
|
||||||
private exportableResources: ExportableResources;
|
private exportableResources: ExportableResources;
|
||||||
|
|
||||||
|
@Inject()
|
||||||
|
private exportPdf: ExportPdf;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Exports the given resource data through csv, xlsx or pdf.
|
* Exports the given resource data through csv, xlsx or pdf.
|
||||||
* @param {number} tenantId - Tenant id.
|
* @param {number} tenantId - Tenant id.
|
||||||
* @param {string} resourceName - Resource name.
|
* @param {string} resourceName - Resource name.
|
||||||
* @param {string} format - File format.
|
* @param {ExportFormat} format - File format.
|
||||||
*/
|
*/
|
||||||
public async export(tenantId: number, resourceName: string, format: string = 'csv') {
|
public async export(
|
||||||
|
tenantId: number,
|
||||||
|
resourceName: string,
|
||||||
|
format: ExportFormat = ExportFormat.Csv
|
||||||
|
) {
|
||||||
const resource = sanitizeResourceName(resourceName);
|
const resource = sanitizeResourceName(resourceName);
|
||||||
const resourceMeta = this.getResourceMeta(tenantId, resource);
|
const resourceMeta = this.getResourceMeta(tenantId, resource);
|
||||||
|
|
||||||
@@ -32,10 +40,24 @@ export class ExportResourceService {
|
|||||||
|
|
||||||
const data = await this.getExportableData(tenantId, resource);
|
const data = await this.getExportableData(tenantId, resource);
|
||||||
const transformed = this.transformExportedData(tenantId, resource, data);
|
const transformed = this.transformExportedData(tenantId, resource, data);
|
||||||
|
|
||||||
|
// Returns the csv, xlsx format.
|
||||||
|
if (format === ExportFormat.Csv || format === ExportFormat.Xlsx) {
|
||||||
const exportableColumns = this.getExportableColumns(resourceMeta);
|
const exportableColumns = this.getExportableColumns(resourceMeta);
|
||||||
const workbook = this.createWorkbook(transformed, exportableColumns);
|
const workbook = this.createWorkbook(transformed, exportableColumns);
|
||||||
|
|
||||||
return this.exportWorkbook(workbook, format);
|
return this.exportWorkbook(workbook, format);
|
||||||
|
// Returns the pdf format.
|
||||||
|
} else if (format === ExportFormat.Pdf) {
|
||||||
|
const printableColumns = this.getPrintableColumns(resourceMeta);
|
||||||
|
|
||||||
|
return this.exportPdf.pdf(
|
||||||
|
tenantId,
|
||||||
|
printableColumns,
|
||||||
|
transformed,
|
||||||
|
resourceMeta?.print?.pageTitle
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -91,6 +113,7 @@ export class ExportResourceService {
|
|||||||
private async getExportableData(tenantId: number, resource: string) {
|
private async getExportableData(tenantId: number, resource: string) {
|
||||||
const exportable =
|
const exportable =
|
||||||
this.exportableResources.registry.getExportable(resource);
|
this.exportableResources.registry.getExportable(resource);
|
||||||
|
|
||||||
return exportable.exportable(tenantId, {});
|
return exportable.exportable(tenantId, {});
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -125,6 +148,32 @@ export class ExportResourceService {
|
|||||||
return processColumns(resourceMeta.columns);
|
return processColumns(resourceMeta.columns);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private getPrintableColumns(resourceMeta: IModelMeta) {
|
||||||
|
const processColumns = (
|
||||||
|
columns: { [key: string]: IModelMetaColumn },
|
||||||
|
parent = ''
|
||||||
|
) => {
|
||||||
|
return Object.entries(columns)
|
||||||
|
.filter(([_, value]) => value.printable !== false)
|
||||||
|
.flatMap(([key, value]) => {
|
||||||
|
if (value.type === 'collection' && value.collectionOf === 'object') {
|
||||||
|
return processColumns(value.columns, key);
|
||||||
|
} else {
|
||||||
|
const group = parent;
|
||||||
|
return [
|
||||||
|
{
|
||||||
|
name: value.name,
|
||||||
|
type: value.type || 'text',
|
||||||
|
accessor: value.accessor || key,
|
||||||
|
group,
|
||||||
|
},
|
||||||
|
];
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
return processColumns(resourceMeta.columns);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a workbook from the provided data and columns.
|
* Creates a workbook from the provided data and columns.
|
||||||
* @param {any[]} data - The data to be included in the workbook.
|
* @param {any[]} data - The data to be included in the workbook.
|
||||||
@@ -136,7 +185,6 @@ export class ExportResourceService {
|
|||||||
const worksheetData = data.map((item) =>
|
const worksheetData = data.map((item) =>
|
||||||
exportableColumns.map((col) => get(item, getDataAccessor(col)))
|
exportableColumns.map((col) => get(item, getDataAccessor(col)))
|
||||||
);
|
);
|
||||||
|
|
||||||
worksheetData.unshift(exportableColumns.map((col) => col.name));
|
worksheetData.unshift(exportableColumns.map((col) => col.name));
|
||||||
|
|
||||||
const worksheet = xlsx.utils.aoa_to_sheet(worksheetData);
|
const worksheet = xlsx.utils.aoa_to_sheet(worksheetData);
|
||||||
|
|||||||
@@ -1,3 +1,9 @@
|
|||||||
export enum Errors {
|
export enum Errors {
|
||||||
RESOURCE_NOT_EXPORTABLE = 'RESOURCE_NOT_EXPORTABLE',
|
RESOURCE_NOT_EXPORTABLE = 'RESOURCE_NOT_EXPORTABLE',
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export enum ExportFormat {
|
||||||
|
Csv = 'csv',
|
||||||
|
Pdf = 'pdf',
|
||||||
|
Xlsx = 'xlsx',
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import { flatMap } from 'lodash';
|
import { flatMap, get } from 'lodash';
|
||||||
/**
|
/**
|
||||||
* Flattens the data based on a specified attribute.
|
* Flattens the data based on a specified attribute.
|
||||||
* @param data - The data to be flattened.
|
* @param data - The data to be flattened.
|
||||||
@@ -25,3 +25,21 @@ export const flatDataCollections = (
|
|||||||
export const getDataAccessor = (col: any) => {
|
export const getDataAccessor = (col: any) => {
|
||||||
return col.group ? `${col.group}.${col.accessor}` : col.accessor;
|
return col.group ? `${col.group}.${col.accessor}` : col.accessor;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Maps the data retrieved from the service layer to the pdf document.
|
||||||
|
* @param {any} columns
|
||||||
|
* @param {Record<stringm any>} data
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
export const mapPdfRows = (columns: any, data: Record<string, any>) => {
|
||||||
|
return data.map((item) => {
|
||||||
|
const cells = columns.map((column) => {
|
||||||
|
return {
|
||||||
|
key: column.accessor,
|
||||||
|
value: get(item, getDataAccessor(column)),
|
||||||
|
};
|
||||||
|
});
|
||||||
|
return { cells, classNames: '' };
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|||||||
@@ -30,6 +30,7 @@ import withSettings from '@/containers/Settings/withSettings';
|
|||||||
import withSettingsActions from '@/containers/Settings/withSettingsActions';
|
import withSettingsActions from '@/containers/Settings/withSettingsActions';
|
||||||
import withDialogActions from '@/containers/Dialog/withDialogActions';
|
import withDialogActions from '@/containers/Dialog/withDialogActions';
|
||||||
|
|
||||||
|
import { useDownloadExportPdf } from '@/hooks/query/FinancialReports/use-export-pdf';
|
||||||
import { compose } from '@/utils';
|
import { compose } from '@/utils';
|
||||||
import { DialogsName } from '@/constants/dialogs';
|
import { DialogsName } from '@/constants/dialogs';
|
||||||
|
|
||||||
@@ -50,7 +51,7 @@ function ManualJournalActionsBar({
|
|||||||
addSetting,
|
addSetting,
|
||||||
|
|
||||||
// #withDialogActions
|
// #withDialogActions
|
||||||
openDialog
|
openDialog,
|
||||||
}) {
|
}) {
|
||||||
// History context.
|
// History context.
|
||||||
const history = useHistory();
|
const history = useHistory();
|
||||||
@@ -58,6 +59,9 @@ function ManualJournalActionsBar({
|
|||||||
// Manual journals context.
|
// Manual journals context.
|
||||||
const { journalsViews, fields } = useManualJournalsContext();
|
const { journalsViews, fields } = useManualJournalsContext();
|
||||||
|
|
||||||
|
// Exports pdf document.
|
||||||
|
const { downloadAsync: downloadExportPdf } = useDownloadExportPdf();
|
||||||
|
|
||||||
// Manual journals refresh action.
|
// Manual journals refresh action.
|
||||||
const { refresh } = useRefreshJournals();
|
const { refresh } = useRefreshJournals();
|
||||||
|
|
||||||
@@ -91,6 +95,11 @@ function ManualJournalActionsBar({
|
|||||||
openDialog(DialogsName.Export, { resource: 'manual_journal' });
|
openDialog(DialogsName.Export, { resource: 'manual_journal' });
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Handle the pdf print button click.
|
||||||
|
const handlePdfPrintBtnSubmit = () => {
|
||||||
|
downloadExportPdf({ resource: 'ManualJournal' });
|
||||||
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<DashboardActionsBar>
|
<DashboardActionsBar>
|
||||||
<NavbarGroup>
|
<NavbarGroup>
|
||||||
@@ -134,10 +143,12 @@ function ManualJournalActionsBar({
|
|||||||
/>
|
/>
|
||||||
</If>
|
</If>
|
||||||
|
|
||||||
|
<NavbarDivider />
|
||||||
<Button
|
<Button
|
||||||
className={Classes.MINIMAL}
|
className={Classes.MINIMAL}
|
||||||
icon={<Icon icon="print-16" iconSize={16} />}
|
icon={<Icon icon="print-16" iconSize={16} />}
|
||||||
text={<T id={'print'} />}
|
text={<T id={'print'} />}
|
||||||
|
onClick={handlePdfPrintBtnSubmit}
|
||||||
/>
|
/>
|
||||||
<Button
|
<Button
|
||||||
className={Classes.MINIMAL}
|
className={Classes.MINIMAL}
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
// @ts-nocheck
|
// @ts-nocheck
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { isEmpty } from 'lodash';
|
import { isEmpty, isUndefined } from 'lodash';
|
||||||
import {
|
import {
|
||||||
Button,
|
Button,
|
||||||
NavbarGroup,
|
NavbarGroup,
|
||||||
@@ -9,7 +9,11 @@ import {
|
|||||||
Intent,
|
Intent,
|
||||||
Switch,
|
Switch,
|
||||||
Alignment,
|
Alignment,
|
||||||
|
ProgressBar,
|
||||||
|
ToastProps,
|
||||||
|
Text,
|
||||||
} from '@blueprintjs/core';
|
} from '@blueprintjs/core';
|
||||||
|
import clsx from 'classnames';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
AdvancedFilterPopover,
|
AdvancedFilterPopover,
|
||||||
@@ -26,8 +30,10 @@ import {
|
|||||||
import { AccountAction, AbilitySubject } from '@/constants/abilityOption';
|
import { AccountAction, AbilitySubject } from '@/constants/abilityOption';
|
||||||
import { DialogsName } from '@/constants/dialogs';
|
import { DialogsName } from '@/constants/dialogs';
|
||||||
|
|
||||||
|
import { useHistory } from 'react-router-dom';
|
||||||
import { useRefreshAccounts } from '@/hooks/query/accounts';
|
import { useRefreshAccounts } from '@/hooks/query/accounts';
|
||||||
import { useAccountsChartContext } from './AccountsChartProvider';
|
import { useAccountsChartContext } from './AccountsChartProvider';
|
||||||
|
import { useDownloadExportPdf } from '@/hooks/query/FinancialReports/use-export-pdf';
|
||||||
|
|
||||||
import withAccounts from './withAccounts';
|
import withAccounts from './withAccounts';
|
||||||
import withAccountsTableActions from './withAccountsTableActions';
|
import withAccountsTableActions from './withAccountsTableActions';
|
||||||
@@ -37,7 +43,6 @@ import withSettings from '@/containers/Settings/withSettings';
|
|||||||
import withSettingsActions from '@/containers/Settings/withSettingsActions';
|
import withSettingsActions from '@/containers/Settings/withSettingsActions';
|
||||||
|
|
||||||
import { compose } from '@/utils';
|
import { compose } from '@/utils';
|
||||||
import { useHistory } from 'react-router-dom';
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Accounts actions bar.
|
* Accounts actions bar.
|
||||||
@@ -57,22 +62,18 @@ function AccountsActionsBar({
|
|||||||
// #withAccountsTableActions
|
// #withAccountsTableActions
|
||||||
setAccountsTableState,
|
setAccountsTableState,
|
||||||
|
|
||||||
// #ownProps
|
|
||||||
onFilterChanged,
|
|
||||||
|
|
||||||
// #withSettings
|
// #withSettings
|
||||||
accountsTableSize,
|
accountsTableSize,
|
||||||
|
|
||||||
// #withSettingsActions
|
// #withSettingsActions
|
||||||
addSetting,
|
addSetting,
|
||||||
}) {
|
}) {
|
||||||
const { resourceViews, fields } = useAccountsChartContext();
|
|
||||||
|
|
||||||
const history = useHistory();
|
const history = useHistory();
|
||||||
|
|
||||||
const onClickNewAccount = () => {
|
const { resourceViews, fields } = useAccountsChartContext();
|
||||||
openDialog(DialogsName.AccountForm, {});
|
|
||||||
};
|
// Exports pdf document.
|
||||||
|
const { downloadAsync: downloadExportPdf } = useDownloadExportPdf();
|
||||||
|
|
||||||
// Accounts refresh action.
|
// Accounts refresh action.
|
||||||
const { refresh } = useRefreshAccounts();
|
const { refresh } = useRefreshAccounts();
|
||||||
@@ -81,35 +82,29 @@ function AccountsActionsBar({
|
|||||||
const handleBulkDelete = () => {
|
const handleBulkDelete = () => {
|
||||||
openAlert('accounts-bulk-delete', { accountsIds: accountsSelectedRows });
|
openAlert('accounts-bulk-delete', { accountsIds: accountsSelectedRows });
|
||||||
};
|
};
|
||||||
|
|
||||||
// Handle bulk accounts activate.
|
// Handle bulk accounts activate.
|
||||||
const handelBulkActivate = () => {
|
const handelBulkActivate = () => {
|
||||||
openAlert('accounts-bulk-activate', { accountsIds: accountsSelectedRows });
|
openAlert('accounts-bulk-activate', { accountsIds: accountsSelectedRows });
|
||||||
};
|
};
|
||||||
|
|
||||||
// Handle bulk accounts inactivate.
|
// Handle bulk accounts inactivate.
|
||||||
const handelBulkInactive = () => {
|
const handelBulkInactive = () => {
|
||||||
openAlert('accounts-bulk-inactivate', {
|
openAlert('accounts-bulk-inactivate', {
|
||||||
accountsIds: accountsSelectedRows,
|
accountsIds: accountsSelectedRows,
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
// Handle tab changing.
|
// Handle tab changing.
|
||||||
const handleTabChange = (view) => {
|
const handleTabChange = (view) => {
|
||||||
setAccountsTableState({ viewSlug: view ? view.slug : null });
|
setAccountsTableState({ viewSlug: view ? view.slug : null });
|
||||||
};
|
};
|
||||||
|
|
||||||
// Handle inactive switch changing.
|
// Handle inactive switch changing.
|
||||||
const handleInactiveSwitchChange = (event) => {
|
const handleInactiveSwitchChange = (event) => {
|
||||||
const checked = event.target.checked;
|
const checked = event.target.checked;
|
||||||
setAccountsTableState({ inactiveMode: checked });
|
setAccountsTableState({ inactiveMode: checked });
|
||||||
};
|
};
|
||||||
|
|
||||||
// Handle click a refresh accounts
|
// Handle click a refresh accounts
|
||||||
const handleRefreshBtnClick = () => {
|
const handleRefreshBtnClick = () => {
|
||||||
refresh();
|
refresh();
|
||||||
};
|
};
|
||||||
|
|
||||||
// Handle table row size change.
|
// Handle table row size change.
|
||||||
const handleTableRowSizeChange = (size) => {
|
const handleTableRowSizeChange = (size) => {
|
||||||
addSetting('accounts', 'tableSize', size);
|
addSetting('accounts', 'tableSize', size);
|
||||||
@@ -122,6 +117,14 @@ function AccountsActionsBar({
|
|||||||
const handleExportBtnClick = () => {
|
const handleExportBtnClick = () => {
|
||||||
openDialog(DialogsName.Export, { resource: 'account' });
|
openDialog(DialogsName.Export, { resource: 'account' });
|
||||||
};
|
};
|
||||||
|
// Handle the print button click.
|
||||||
|
const handlePrintBtnClick = () => {
|
||||||
|
downloadExportPdf({ resource: 'Account' });
|
||||||
|
};
|
||||||
|
// Handle click new account.
|
||||||
|
const onClickNewAccount = () => {
|
||||||
|
openDialog(DialogsName.AccountForm, {});
|
||||||
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<DashboardActionsBar>
|
<DashboardActionsBar>
|
||||||
@@ -185,6 +188,7 @@ function AccountsActionsBar({
|
|||||||
className={Classes.MINIMAL}
|
className={Classes.MINIMAL}
|
||||||
icon={<Icon icon="print-16" iconSize={16} />}
|
icon={<Icon icon="print-16" iconSize={16} />}
|
||||||
text={<T id={'print'} />}
|
text={<T id={'print'} />}
|
||||||
|
onClick={handlePrintBtnClick}
|
||||||
/>
|
/>
|
||||||
<Button
|
<Button
|
||||||
className={Classes.MINIMAL}
|
className={Classes.MINIMAL}
|
||||||
|
|||||||
@@ -25,6 +25,7 @@ import {
|
|||||||
|
|
||||||
import { useCustomersListContext } from './CustomersListProvider';
|
import { useCustomersListContext } from './CustomersListProvider';
|
||||||
import { useRefreshCustomers } from '@/hooks/query/customers';
|
import { useRefreshCustomers } from '@/hooks/query/customers';
|
||||||
|
import { useDownloadExportPdf } from '@/hooks/query/FinancialReports/use-export-pdf';
|
||||||
|
|
||||||
import withCustomers from './withCustomers';
|
import withCustomers from './withCustomers';
|
||||||
import withCustomersActions from './withCustomersActions';
|
import withCustomersActions from './withCustomersActions';
|
||||||
@@ -70,6 +71,9 @@ function CustomerActionsBar({
|
|||||||
// Customers refresh action.
|
// Customers refresh action.
|
||||||
const { refresh } = useRefreshCustomers();
|
const { refresh } = useRefreshCustomers();
|
||||||
|
|
||||||
|
// Exports pdf document.
|
||||||
|
const { downloadAsync: downloadExportPdf } = useDownloadExportPdf();
|
||||||
|
|
||||||
const onClickNewCustomer = () => {
|
const onClickNewCustomer = () => {
|
||||||
history.push('/customers/new');
|
history.push('/customers/new');
|
||||||
};
|
};
|
||||||
@@ -109,6 +113,10 @@ function CustomerActionsBar({
|
|||||||
const handleExportBtnClick = () => {
|
const handleExportBtnClick = () => {
|
||||||
openDialog(DialogsName.Export, { resource: 'customer' });
|
openDialog(DialogsName.Export, { resource: 'customer' });
|
||||||
};
|
};
|
||||||
|
// Handle the print button click.
|
||||||
|
const handlePrintBtnClick = () => {
|
||||||
|
downloadExportPdf({ resource: 'Customer' });
|
||||||
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<DashboardActionsBar>
|
<DashboardActionsBar>
|
||||||
@@ -154,6 +162,13 @@ function CustomerActionsBar({
|
|||||||
onClick={handleBulkDelete}
|
onClick={handleBulkDelete}
|
||||||
/>
|
/>
|
||||||
</If>
|
</If>
|
||||||
|
<NavbarDivider />
|
||||||
|
<Button
|
||||||
|
className={Classes.MINIMAL}
|
||||||
|
icon={<Icon icon="print-16" iconSize={16} />}
|
||||||
|
text={<T id={'print'} />}
|
||||||
|
onClick={handlePrintBtnClick}
|
||||||
|
/>
|
||||||
<Button
|
<Button
|
||||||
className={Classes.MINIMAL}
|
className={Classes.MINIMAL}
|
||||||
icon={<Icon icon="file-import-16" iconSize={16} />}
|
icon={<Icon icon="file-import-16" iconSize={16} />}
|
||||||
|
|||||||
@@ -23,8 +23,11 @@ import {
|
|||||||
} from '@/components';
|
} from '@/components';
|
||||||
|
|
||||||
import { ExpenseAction, AbilitySubject } from '@/constants/abilityOption';
|
import { ExpenseAction, AbilitySubject } from '@/constants/abilityOption';
|
||||||
|
import { DialogsName } from '@/constants/dialogs';
|
||||||
|
|
||||||
import { useRefreshExpenses } from '@/hooks/query/expenses';
|
import { useRefreshExpenses } from '@/hooks/query/expenses';
|
||||||
import { useExpensesListContext } from './ExpensesListProvider';
|
import { useExpensesListContext } from './ExpensesListProvider';
|
||||||
|
import { useDownloadExportPdf } from '@/hooks/query/FinancialReports/use-export-pdf';
|
||||||
|
|
||||||
import withExpenses from './withExpenses';
|
import withExpenses from './withExpenses';
|
||||||
import withExpensesActions from './withExpensesActions';
|
import withExpensesActions from './withExpensesActions';
|
||||||
@@ -33,7 +36,6 @@ import withDialogActions from '@/containers/Dialog/withDialogActions';
|
|||||||
import withSettings from '@/containers/Settings/withSettings';
|
import withSettings from '@/containers/Settings/withSettings';
|
||||||
|
|
||||||
import { compose } from '@/utils';
|
import { compose } from '@/utils';
|
||||||
import { DialogsName } from '@/constants/dialogs';
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Expenses actions bar.
|
* Expenses actions bar.
|
||||||
@@ -60,6 +62,9 @@ function ExpensesActionsBar({
|
|||||||
// Expenses list context.
|
// Expenses list context.
|
||||||
const { expensesViews, fields } = useExpensesListContext();
|
const { expensesViews, fields } = useExpensesListContext();
|
||||||
|
|
||||||
|
// Exports pdf document.
|
||||||
|
const { downloadAsync: downloadExportPdf } = useDownloadExportPdf();
|
||||||
|
|
||||||
// Expenses refresh action.
|
// Expenses refresh action.
|
||||||
const { refresh } = useRefreshExpenses();
|
const { refresh } = useRefreshExpenses();
|
||||||
|
|
||||||
@@ -92,6 +97,10 @@ function ExpensesActionsBar({
|
|||||||
const handleExportBtnClick = () => {
|
const handleExportBtnClick = () => {
|
||||||
openDialog(DialogsName.Export, { resource: 'expense' });
|
openDialog(DialogsName.Export, { resource: 'expense' });
|
||||||
};
|
};
|
||||||
|
// Handles the print button click.
|
||||||
|
const handlePrintBtnClick = () => {
|
||||||
|
downloadExportPdf({ resource: 'Expense' });
|
||||||
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<DashboardActionsBar>
|
<DashboardActionsBar>
|
||||||
@@ -135,11 +144,12 @@ function ExpensesActionsBar({
|
|||||||
onClick={handleBulkDelete}
|
onClick={handleBulkDelete}
|
||||||
/>
|
/>
|
||||||
</If>
|
</If>
|
||||||
|
<NavbarDivider />
|
||||||
<Button
|
<Button
|
||||||
className={Classes.MINIMAL}
|
className={Classes.MINIMAL}
|
||||||
icon={<Icon icon="print-16" iconSize={16} />}
|
icon={<Icon icon="print-16" iconSize={16} />}
|
||||||
text={<T id={'print'} />}
|
text={<T id={'print'} />}
|
||||||
|
onClick={handlePrintBtnClick}
|
||||||
/>
|
/>
|
||||||
<Button
|
<Button
|
||||||
className={Classes.MINIMAL}
|
className={Classes.MINIMAL}
|
||||||
|
|||||||
@@ -27,6 +27,7 @@ import {
|
|||||||
import { ItemAction, AbilitySubject } from '@/constants/abilityOption';
|
import { ItemAction, AbilitySubject } from '@/constants/abilityOption';
|
||||||
import { useItemsListContext } from './ItemsListProvider';
|
import { useItemsListContext } from './ItemsListProvider';
|
||||||
import { useRefreshItems } from '@/hooks/query/items';
|
import { useRefreshItems } from '@/hooks/query/items';
|
||||||
|
import { useDownloadExportPdf } from '@/hooks/query/FinancialReports/use-export-pdf';
|
||||||
|
|
||||||
import withItems from './withItems';
|
import withItems from './withItems';
|
||||||
import withItemsActions from './withItemsActions';
|
import withItemsActions from './withItemsActions';
|
||||||
@@ -60,11 +61,14 @@ function ItemsActionsBar({
|
|||||||
addSetting,
|
addSetting,
|
||||||
|
|
||||||
// #withDialogActions
|
// #withDialogActions
|
||||||
openDialog
|
openDialog,
|
||||||
}) {
|
}) {
|
||||||
// Items list context.
|
// Items list context.
|
||||||
const { itemsViews, fields } = useItemsListContext();
|
const { itemsViews, fields } = useItemsListContext();
|
||||||
|
|
||||||
|
// Exports pdf document.
|
||||||
|
const { downloadAsync: downloadExportPdf } = useDownloadExportPdf();
|
||||||
|
|
||||||
// Items refresh action.
|
// Items refresh action.
|
||||||
const { refresh } = useRefreshItems();
|
const { refresh } = useRefreshItems();
|
||||||
|
|
||||||
@@ -107,7 +111,12 @@ function ItemsActionsBar({
|
|||||||
// Handle the export button click.
|
// Handle the export button click.
|
||||||
const handleExportBtnClick = () => {
|
const handleExportBtnClick = () => {
|
||||||
openDialog(DialogsName.Export, { resource: 'item' });
|
openDialog(DialogsName.Export, { resource: 'item' });
|
||||||
}
|
};
|
||||||
|
|
||||||
|
// Handle the print button click.
|
||||||
|
const handlePrintBtnClick = () => {
|
||||||
|
downloadExportPdf({ resource: 'Item' });
|
||||||
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<DashboardActionsBar>
|
<DashboardActionsBar>
|
||||||
@@ -153,7 +162,12 @@ function ItemsActionsBar({
|
|||||||
onClick={handleBulkDelete}
|
onClick={handleBulkDelete}
|
||||||
/>
|
/>
|
||||||
</If>
|
</If>
|
||||||
|
<Button
|
||||||
|
className={Classes.MINIMAL}
|
||||||
|
icon={<Icon icon={'print-16'} iconSize={'16'} />}
|
||||||
|
text={<T id={'print'} />}
|
||||||
|
onClick={handlePrintBtnClick}
|
||||||
|
/>
|
||||||
<Button
|
<Button
|
||||||
className={Classes.MINIMAL}
|
className={Classes.MINIMAL}
|
||||||
icon={<Icon icon="file-import-16" iconSize={16} />}
|
icon={<Icon icon="file-import-16" iconSize={16} />}
|
||||||
@@ -204,5 +218,5 @@ export default compose(
|
|||||||
})),
|
})),
|
||||||
withItemsActions,
|
withItemsActions,
|
||||||
withAlertActions,
|
withAlertActions,
|
||||||
withDialogActions
|
withDialogActions,
|
||||||
)(ItemsActionsBar);
|
)(ItemsActionsBar);
|
||||||
|
|||||||
@@ -28,11 +28,13 @@ import withBills from './withBills';
|
|||||||
import withBillsActions from './withBillsActions';
|
import withBillsActions from './withBillsActions';
|
||||||
import withSettings from '@/containers/Settings/withSettings';
|
import withSettings from '@/containers/Settings/withSettings';
|
||||||
import withSettingsActions from '@/containers/Settings/withSettingsActions';
|
import withSettingsActions from '@/containers/Settings/withSettingsActions';
|
||||||
|
import withDialogActions from '@/containers/Dialog/withDialogActions';
|
||||||
|
|
||||||
import { useBillsListContext } from './BillsListProvider';
|
import { useBillsListContext } from './BillsListProvider';
|
||||||
import { useRefreshBills } from '@/hooks/query/bills';
|
import { useRefreshBills } from '@/hooks/query/bills';
|
||||||
|
import { useDownloadExportPdf } from '@/hooks/query/FinancialReports/use-export-pdf';
|
||||||
|
|
||||||
import { compose } from '@/utils';
|
import { compose } from '@/utils';
|
||||||
import withDialogActions from '@/containers/Dialog/withDialogActions';
|
|
||||||
import { DialogsName } from '@/constants/dialogs';
|
import { DialogsName } from '@/constants/dialogs';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -62,11 +64,13 @@ function BillActionsBar({
|
|||||||
// Bills list context.
|
// Bills list context.
|
||||||
const { billsViews, fields } = useBillsListContext();
|
const { billsViews, fields } = useBillsListContext();
|
||||||
|
|
||||||
|
// Exports pdf document.
|
||||||
|
const { downloadAsync: downloadExportPdf } = useDownloadExportPdf();
|
||||||
|
|
||||||
// Handle click a new bill.
|
// Handle click a new bill.
|
||||||
const handleClickNewBill = () => {
|
const handleClickNewBill = () => {
|
||||||
history.push('/bills/new');
|
history.push('/bills/new');
|
||||||
};
|
};
|
||||||
|
|
||||||
// Handle tab change.
|
// Handle tab change.
|
||||||
const handleTabChange = (view) => {
|
const handleTabChange = (view) => {
|
||||||
setBillsTableState({
|
setBillsTableState({
|
||||||
@@ -77,21 +81,22 @@ function BillActionsBar({
|
|||||||
const handleRefreshBtnClick = () => {
|
const handleRefreshBtnClick = () => {
|
||||||
refresh();
|
refresh();
|
||||||
};
|
};
|
||||||
|
|
||||||
// Handle table row size change.
|
// Handle table row size change.
|
||||||
const handleTableRowSizeChange = (size) => {
|
const handleTableRowSizeChange = (size) => {
|
||||||
addSetting('bills', 'tableSize', size);
|
addSetting('bills', 'tableSize', size);
|
||||||
};
|
};
|
||||||
|
|
||||||
// Handle the import button click.
|
// Handle the import button click.
|
||||||
const handleImportBtnClick = () => {
|
const handleImportBtnClick = () => {
|
||||||
history.push('/bills/import');
|
history.push('/bills/import');
|
||||||
};
|
};
|
||||||
|
|
||||||
// Handle the export button click.
|
// Handle the export button click.
|
||||||
const handleExportBtnClick = () => {
|
const handleExportBtnClick = () => {
|
||||||
openDialog(DialogsName.Export, { resource: 'bill' });
|
openDialog(DialogsName.Export, { resource: 'bill' });
|
||||||
};
|
};
|
||||||
|
// Handle the print button click.
|
||||||
|
const handlePrintBtnClick = () => {
|
||||||
|
downloadExportPdf({ resource: 'Bill' });
|
||||||
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<DashboardActionsBar>
|
<DashboardActionsBar>
|
||||||
@@ -133,13 +138,14 @@ function BillActionsBar({
|
|||||||
icon={<Icon icon={'trash-16'} iconSize={16} />}
|
icon={<Icon icon={'trash-16'} iconSize={16} />}
|
||||||
text={<T id={'delete'} />}
|
text={<T id={'delete'} />}
|
||||||
intent={Intent.DANGER}
|
intent={Intent.DANGER}
|
||||||
// onClick={handleBulkDelete}
|
|
||||||
/>
|
/>
|
||||||
</If>
|
</If>
|
||||||
|
<NavbarDivider />
|
||||||
<Button
|
<Button
|
||||||
className={Classes.MINIMAL}
|
className={Classes.MINIMAL}
|
||||||
icon={<Icon icon={'print-16'} iconSize={'16'} />}
|
icon={<Icon icon={'print-16'} iconSize={'16'} />}
|
||||||
text={<T id={'print'} />}
|
text={<T id={'print'} />}
|
||||||
|
onClick={handlePrintBtnClick}
|
||||||
/>
|
/>
|
||||||
<Button
|
<Button
|
||||||
className={Classes.MINIMAL}
|
className={Classes.MINIMAL}
|
||||||
@@ -153,7 +159,6 @@ function BillActionsBar({
|
|||||||
text={<T id={'export'} />}
|
text={<T id={'export'} />}
|
||||||
onClick={handleExportBtnClick}
|
onClick={handleExportBtnClick}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<NavbarDivider />
|
<NavbarDivider />
|
||||||
<DashboardRowsHeightButton
|
<DashboardRowsHeightButton
|
||||||
initialValue={billsTableSize}
|
initialValue={billsTableSize}
|
||||||
|
|||||||
@@ -21,6 +21,7 @@ import {
|
|||||||
} from '@/components';
|
} from '@/components';
|
||||||
|
|
||||||
import { useVendorsCreditNoteListContext } from './VendorsCreditNoteListProvider';
|
import { useVendorsCreditNoteListContext } from './VendorsCreditNoteListProvider';
|
||||||
|
import { useDownloadExportPdf } from '@/hooks/query/FinancialReports/use-export-pdf';
|
||||||
import { VendorCreditAction, AbilitySubject } from '@/constants/abilityOption';
|
import { VendorCreditAction, AbilitySubject } from '@/constants/abilityOption';
|
||||||
|
|
||||||
import withVendorsCreditNotesActions from './withVendorsCreditNotesActions';
|
import withVendorsCreditNotesActions from './withVendorsCreditNotesActions';
|
||||||
@@ -60,35 +61,37 @@ function VendorsCreditNoteActionsBar({
|
|||||||
const { VendorCreditsViews, fields, refresh } =
|
const { VendorCreditsViews, fields, refresh } =
|
||||||
useVendorsCreditNoteListContext();
|
useVendorsCreditNoteListContext();
|
||||||
|
|
||||||
|
// Exports pdf document.
|
||||||
|
const { downloadAsync: downloadExportPdf } = useDownloadExportPdf();
|
||||||
|
|
||||||
// Handle click a new Vendor.
|
// Handle click a new Vendor.
|
||||||
const handleClickNewVendorCredit = () => {
|
const handleClickNewVendorCredit = () => {
|
||||||
history.push('/vendor-credits/new');
|
history.push('/vendor-credits/new');
|
||||||
};
|
};
|
||||||
|
|
||||||
// Handle view tab change.
|
// Handle view tab change.
|
||||||
const handleTabChange = (view) => {
|
const handleTabChange = (view) => {
|
||||||
setVendorCreditsTableState({ viewSlug: view ? view.slug : null });
|
setVendorCreditsTableState({ viewSlug: view ? view.slug : null });
|
||||||
};
|
};
|
||||||
|
|
||||||
// Handle click a refresh credit note.
|
// Handle click a refresh credit note.
|
||||||
const handleRefreshBtnClick = () => {
|
const handleRefreshBtnClick = () => {
|
||||||
refresh();
|
refresh();
|
||||||
};
|
};
|
||||||
|
|
||||||
// Handle table row size change.
|
// Handle table row size change.
|
||||||
const handleTableRowSizeChange = (size) => {
|
const handleTableRowSizeChange = (size) => {
|
||||||
addSetting('vendorCredit', 'tableSize', size);
|
addSetting('vendorCredit', 'tableSize', size);
|
||||||
};
|
};
|
||||||
|
|
||||||
// Handle import button click.
|
// Handle import button click.
|
||||||
const handleImportBtnClick = () => {
|
const handleImportBtnClick = () => {
|
||||||
history.push('/vendor-credits/import');
|
history.push('/vendor-credits/import');
|
||||||
};
|
};
|
||||||
|
|
||||||
// Handle the export button click.
|
// Handle the export button click.
|
||||||
const handleExportBtnClick = () => {
|
const handleExportBtnClick = () => {
|
||||||
openDialog(DialogsName.Export, { resource: 'vendor_credit' });
|
openDialog(DialogsName.Export, { resource: 'vendor_credit' });
|
||||||
};
|
};
|
||||||
|
// Handle the print button click.
|
||||||
|
const handlePrintBtnClick = () => {
|
||||||
|
downloadExportPdf({ resource: 'VendorCredit' });
|
||||||
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<DashboardActionsBar>
|
<DashboardActionsBar>
|
||||||
@@ -127,6 +130,7 @@ function VendorsCreditNoteActionsBar({
|
|||||||
className={Classes.MINIMAL}
|
className={Classes.MINIMAL}
|
||||||
icon={<Icon icon={'print-16'} iconSize={'16'} />}
|
icon={<Icon icon={'print-16'} iconSize={'16'} />}
|
||||||
text={<T id={'print'} />}
|
text={<T id={'print'} />}
|
||||||
|
onClick={handlePrintBtnClick}
|
||||||
/>
|
/>
|
||||||
<Button
|
<Button
|
||||||
className={Classes.MINIMAL}
|
className={Classes.MINIMAL}
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
// @ts-nocheck
|
// @ts-nocheck
|
||||||
import React from 'react';
|
|
||||||
import {
|
import {
|
||||||
Button,
|
Button,
|
||||||
Classes,
|
Classes,
|
||||||
@@ -22,19 +21,20 @@ import {
|
|||||||
DashboardRowsHeightButton,
|
DashboardRowsHeightButton,
|
||||||
DashboardActionsBar,
|
DashboardActionsBar,
|
||||||
} from '@/components';
|
} from '@/components';
|
||||||
|
import { PaymentMadeAction, AbilitySubject } from '@/constants/abilityOption';
|
||||||
|
|
||||||
import withPaymentMade from './withPaymentMade';
|
import withPaymentMade from './withPaymentMade';
|
||||||
import withPaymentMadeActions from './withPaymentMadeActions';
|
import withPaymentMadeActions from './withPaymentMadeActions';
|
||||||
import withSettings from '@/containers/Settings/withSettings';
|
import withSettings from '@/containers/Settings/withSettings';
|
||||||
import withSettingsActions from '@/containers/Settings/withSettingsActions';
|
import withSettingsActions from '@/containers/Settings/withSettingsActions';
|
||||||
|
import withDialogActions from '@/containers/Dialog/withDialogActions';
|
||||||
|
|
||||||
import { usePaymentMadesListContext } from './PaymentMadesListProvider';
|
import { usePaymentMadesListContext } from './PaymentMadesListProvider';
|
||||||
import { useRefreshPaymentMades } from '@/hooks/query/paymentMades';
|
import { useRefreshPaymentMades } from '@/hooks/query/paymentMades';
|
||||||
import { PaymentMadeAction, AbilitySubject } from '@/constants/abilityOption';
|
import { useDownloadExportPdf } from '@/hooks/query/FinancialReports/use-export-pdf';
|
||||||
|
|
||||||
import { compose } from '@/utils';
|
|
||||||
import withDialogActions from '@/containers/Dialog/withDialogActions';
|
|
||||||
import { DialogsName } from '@/constants/dialogs';
|
import { DialogsName } from '@/constants/dialogs';
|
||||||
|
import { compose } from '@/utils';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Payment made actions bar.
|
* Payment made actions bar.
|
||||||
@@ -57,6 +57,9 @@ function PaymentMadeActionsBar({
|
|||||||
}) {
|
}) {
|
||||||
const history = useHistory();
|
const history = useHistory();
|
||||||
|
|
||||||
|
// Exports pdf document.
|
||||||
|
const { downloadAsync: downloadExportPdf } = useDownloadExportPdf();
|
||||||
|
|
||||||
// Payment receives list context.
|
// Payment receives list context.
|
||||||
const { paymentMadesViews, fields } = usePaymentMadesListContext();
|
const { paymentMadesViews, fields } = usePaymentMadesListContext();
|
||||||
|
|
||||||
@@ -67,31 +70,30 @@ function PaymentMadeActionsBar({
|
|||||||
const handleClickNewPaymentMade = () => {
|
const handleClickNewPaymentMade = () => {
|
||||||
history.push('/payment-mades/new');
|
history.push('/payment-mades/new');
|
||||||
};
|
};
|
||||||
|
|
||||||
// Handle tab changing.
|
// Handle tab changing.
|
||||||
const handleTabChange = (viewSlug) => {
|
const handleTabChange = (viewSlug) => {
|
||||||
setPaymentMadesTableState({ viewSlug });
|
setPaymentMadesTableState({ viewSlug });
|
||||||
};
|
};
|
||||||
|
|
||||||
// Handle click a refresh payment receives.
|
// Handle click a refresh payment receives.
|
||||||
const handleRefreshBtnClick = () => {
|
const handleRefreshBtnClick = () => {
|
||||||
refresh();
|
refresh();
|
||||||
};
|
};
|
||||||
|
|
||||||
// Handle table row size change.
|
// Handle table row size change.
|
||||||
const handleTableRowSizeChange = (size) => {
|
const handleTableRowSizeChange = (size) => {
|
||||||
addSetting('billPayments', 'tableSize', size);
|
addSetting('billPayments', 'tableSize', size);
|
||||||
};
|
};
|
||||||
|
|
||||||
// Handle the import button click.
|
// Handle the import button click.
|
||||||
const handleImportBtnClick = () => {
|
const handleImportBtnClick = () => {
|
||||||
history.push('/payment-mades/import');
|
history.push('/payment-mades/import');
|
||||||
};
|
};
|
||||||
|
|
||||||
// Handle the export button click.
|
// Handle the export button click.
|
||||||
const handleExportBtnClick = () => {
|
const handleExportBtnClick = () => {
|
||||||
openDialog(DialogsName.Export, { resource: 'bill_payment' });
|
openDialog(DialogsName.Export, { resource: 'bill_payment' });
|
||||||
};
|
};
|
||||||
|
// Handle the print button click.
|
||||||
|
const handlePrintBtnClick = () => {
|
||||||
|
downloadExportPdf({ resource: 'BillPayment' });
|
||||||
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<DashboardActionsBar>
|
<DashboardActionsBar>
|
||||||
@@ -138,6 +140,7 @@ function PaymentMadeActionsBar({
|
|||||||
className={Classes.MINIMAL}
|
className={Classes.MINIMAL}
|
||||||
icon={<Icon icon={'print-16'} iconSize={'16'} />}
|
icon={<Icon icon={'print-16'} iconSize={'16'} />}
|
||||||
text={<T id={'print'} />}
|
text={<T id={'print'} />}
|
||||||
|
onClick={handlePrintBtnClick}
|
||||||
/>
|
/>
|
||||||
<Button
|
<Button
|
||||||
className={Classes.MINIMAL}
|
className={Classes.MINIMAL}
|
||||||
|
|||||||
@@ -20,6 +20,8 @@ import {
|
|||||||
} from '@/components';
|
} from '@/components';
|
||||||
|
|
||||||
import { useCreditNoteListContext } from './CreditNotesListProvider';
|
import { useCreditNoteListContext } from './CreditNotesListProvider';
|
||||||
|
import { useDownloadExportPdf } from '@/hooks/query/FinancialReports/use-export-pdf';
|
||||||
|
|
||||||
import { CreditNoteAction, AbilitySubject } from '@/constants/abilityOption';
|
import { CreditNoteAction, AbilitySubject } from '@/constants/abilityOption';
|
||||||
import withCreditNotes from './withCreditNotes';
|
import withCreditNotes from './withCreditNotes';
|
||||||
import withCreditNotesActions from './withCreditNotesActions';
|
import withCreditNotesActions from './withCreditNotesActions';
|
||||||
@@ -27,8 +29,8 @@ import withSettings from '@/containers/Settings/withSettings';
|
|||||||
import withSettingsActions from '@/containers/Settings/withSettingsActions';
|
import withSettingsActions from '@/containers/Settings/withSettingsActions';
|
||||||
import withDialogActions from '@/containers/Dialog/withDialogActions';
|
import withDialogActions from '@/containers/Dialog/withDialogActions';
|
||||||
|
|
||||||
import { compose } from '@/utils';
|
|
||||||
import { DialogsName } from '@/constants/dialogs';
|
import { DialogsName } from '@/constants/dialogs';
|
||||||
|
import { compose } from '@/utils';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Credit note table actions bar.
|
* Credit note table actions bar.
|
||||||
@@ -54,6 +56,9 @@ function CreditNotesActionsBar({
|
|||||||
// credit note list context.
|
// credit note list context.
|
||||||
const { CreditNotesView, fields, refresh } = useCreditNoteListContext();
|
const { CreditNotesView, fields, refresh } = useCreditNoteListContext();
|
||||||
|
|
||||||
|
// Exports pdf document.
|
||||||
|
const { downloadAsync: downloadExportPdf } = useDownloadExportPdf();
|
||||||
|
|
||||||
// Handle view tab change.
|
// Handle view tab change.
|
||||||
const handleTabChange = (view) => {
|
const handleTabChange = (view) => {
|
||||||
setCreditNotesTableState({ viewSlug: view ? view.slug : null });
|
setCreditNotesTableState({ viewSlug: view ? view.slug : null });
|
||||||
@@ -68,21 +73,22 @@ function CreditNotesActionsBar({
|
|||||||
const handleRefreshBtnClick = () => {
|
const handleRefreshBtnClick = () => {
|
||||||
refresh();
|
refresh();
|
||||||
};
|
};
|
||||||
|
|
||||||
// Handle table row size change.
|
// Handle table row size change.
|
||||||
const handleTableRowSizeChange = (size) => {
|
const handleTableRowSizeChange = (size) => {
|
||||||
addSetting('creditNote', 'tableSize', size);
|
addSetting('creditNote', 'tableSize', size);
|
||||||
};
|
};
|
||||||
|
|
||||||
// Handle import button click.
|
// Handle import button click.
|
||||||
const handleImportBtnClick = () => {
|
const handleImportBtnClick = () => {
|
||||||
history.push('/credit-notes/import');
|
history.push('/credit-notes/import');
|
||||||
};
|
};
|
||||||
|
|
||||||
// Handle the export button click.
|
// Handle the export button click.
|
||||||
const handleExportBtnClick = () => {
|
const handleExportBtnClick = () => {
|
||||||
openDialog(DialogsName.Export, { resource: 'credit_note' });
|
openDialog(DialogsName.Export, { resource: 'credit_note' });
|
||||||
};
|
};
|
||||||
|
// Handle print button click.
|
||||||
|
const handlePrintBtnClick = () => {
|
||||||
|
downloadExportPdf({ resource: 'CreditNote' });
|
||||||
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<DashboardActionsBar>
|
<DashboardActionsBar>
|
||||||
@@ -121,6 +127,7 @@ function CreditNotesActionsBar({
|
|||||||
className={Classes.MINIMAL}
|
className={Classes.MINIMAL}
|
||||||
icon={<Icon icon={'print-16'} iconSize={'16'} />}
|
icon={<Icon icon={'print-16'} iconSize={'16'} />}
|
||||||
text={<T id={'print'} />}
|
text={<T id={'print'} />}
|
||||||
|
onClick={handlePrintBtnClick}
|
||||||
/>
|
/>
|
||||||
<Button
|
<Button
|
||||||
className={Classes.MINIMAL}
|
className={Classes.MINIMAL}
|
||||||
|
|||||||
@@ -26,12 +26,14 @@ import withEstimates from './withEstimates';
|
|||||||
import withEstimatesActions from './withEstimatesActions';
|
import withEstimatesActions from './withEstimatesActions';
|
||||||
import withSettings from '@/containers/Settings/withSettings';
|
import withSettings from '@/containers/Settings/withSettings';
|
||||||
import withSettingsActions from '@/containers/Settings/withSettingsActions';
|
import withSettingsActions from '@/containers/Settings/withSettingsActions';
|
||||||
|
import withDialogActions from '@/containers/Dialog/withDialogActions';
|
||||||
|
|
||||||
import { useEstimatesListContext } from './EstimatesListProvider';
|
import { useEstimatesListContext } from './EstimatesListProvider';
|
||||||
import { useRefreshEstimates } from '@/hooks/query/estimates';
|
import { useRefreshEstimates } from '@/hooks/query/estimates';
|
||||||
|
import { useDownloadExportPdf } from '@/hooks/query/FinancialReports/use-export-pdf';
|
||||||
|
|
||||||
import { SaleEstimateAction, AbilitySubject } from '@/constants/abilityOption';
|
import { SaleEstimateAction, AbilitySubject } from '@/constants/abilityOption';
|
||||||
import { compose } from '@/utils';
|
import { compose } from '@/utils';
|
||||||
import withDialogActions from '@/containers/Dialog/withDialogActions';
|
|
||||||
import { DialogsName } from '@/constants/dialogs';
|
import { DialogsName } from '@/constants/dialogs';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -58,6 +60,9 @@ function EstimateActionsBar({
|
|||||||
// Estimates list context.
|
// Estimates list context.
|
||||||
const { estimatesViews, fields } = useEstimatesListContext();
|
const { estimatesViews, fields } = useEstimatesListContext();
|
||||||
|
|
||||||
|
// Exports pdf document.
|
||||||
|
const { downloadAsync: downloadExportPdf } = useDownloadExportPdf();
|
||||||
|
|
||||||
// Handle click a new sale estimate.
|
// Handle click a new sale estimate.
|
||||||
const onClickNewEstimate = () => {
|
const onClickNewEstimate = () => {
|
||||||
history.push('/estimates/new');
|
history.push('/estimates/new');
|
||||||
@@ -71,17 +76,14 @@ function EstimateActionsBar({
|
|||||||
viewSlug: view ? view.slug : null,
|
viewSlug: view ? view.slug : null,
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
// Handle click a refresh sale estimates
|
// Handle click a refresh sale estimates
|
||||||
const handleRefreshBtnClick = () => {
|
const handleRefreshBtnClick = () => {
|
||||||
refresh();
|
refresh();
|
||||||
};
|
};
|
||||||
|
|
||||||
// Handle table row size change.
|
// Handle table row size change.
|
||||||
const handleTableRowSizeChange = (size) => {
|
const handleTableRowSizeChange = (size) => {
|
||||||
addSetting('salesEstimates', 'tableSize', size);
|
addSetting('salesEstimates', 'tableSize', size);
|
||||||
};
|
};
|
||||||
|
|
||||||
// Handle the import button click.
|
// Handle the import button click.
|
||||||
const handleImportBtnClick = () => {
|
const handleImportBtnClick = () => {
|
||||||
history.push('/estimates/import');
|
history.push('/estimates/import');
|
||||||
@@ -90,6 +92,10 @@ function EstimateActionsBar({
|
|||||||
const handleExportBtnClick = () => {
|
const handleExportBtnClick = () => {
|
||||||
openDialog(DialogsName.Export, { resource: 'sale_estimate' });
|
openDialog(DialogsName.Export, { resource: 'sale_estimate' });
|
||||||
};
|
};
|
||||||
|
// Handles the print button click.
|
||||||
|
const handlePrintBtnClick = () => {
|
||||||
|
downloadExportPdf({ resource: 'SaleEstimate' });
|
||||||
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<DashboardActionsBar>
|
<DashboardActionsBar>
|
||||||
@@ -138,8 +144,8 @@ function EstimateActionsBar({
|
|||||||
className={Classes.MINIMAL}
|
className={Classes.MINIMAL}
|
||||||
icon={<Icon icon={'print-16'} iconSize={'16'} />}
|
icon={<Icon icon={'print-16'} iconSize={'16'} />}
|
||||||
text={<T id={'print'} />}
|
text={<T id={'print'} />}
|
||||||
|
onClick={handlePrintBtnClick}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<Button
|
<Button
|
||||||
className={Classes.MINIMAL}
|
className={Classes.MINIMAL}
|
||||||
icon={<Icon icon={'file-import-16'} />}
|
icon={<Icon icon={'file-import-16'} />}
|
||||||
@@ -180,5 +186,5 @@ export default compose(
|
|||||||
withSettings(({ estimatesSettings }) => ({
|
withSettings(({ estimatesSettings }) => ({
|
||||||
estimatesTableSize: estimatesSettings?.tableSize,
|
estimatesTableSize: estimatesSettings?.tableSize,
|
||||||
})),
|
})),
|
||||||
withDialogActions
|
withDialogActions,
|
||||||
)(EstimateActionsBar);
|
)(EstimateActionsBar);
|
||||||
|
|||||||
@@ -23,6 +23,7 @@ import { SaleInvoiceAction, AbilitySubject } from '@/constants/abilityOption';
|
|||||||
|
|
||||||
import { useRefreshInvoices } from '@/hooks/query/invoices';
|
import { useRefreshInvoices } from '@/hooks/query/invoices';
|
||||||
import { useInvoicesListContext } from './InvoicesListProvider';
|
import { useInvoicesListContext } from './InvoicesListProvider';
|
||||||
|
import { useDownloadExportPdf } from '@/hooks/query/FinancialReports/use-export-pdf';
|
||||||
|
|
||||||
import withInvoices from './withInvoices';
|
import withInvoices from './withInvoices';
|
||||||
import withInvoiceActions from './withInvoiceActions';
|
import withInvoiceActions from './withInvoiceActions';
|
||||||
@@ -49,13 +50,16 @@ function InvoiceActionsBar({
|
|||||||
addSetting,
|
addSetting,
|
||||||
|
|
||||||
// #withDialogsActions
|
// #withDialogsActions
|
||||||
openDialog
|
openDialog,
|
||||||
}) {
|
}) {
|
||||||
const history = useHistory();
|
const history = useHistory();
|
||||||
|
|
||||||
// Sale invoices list context.
|
// Sale invoices list context.
|
||||||
const { invoicesViews, invoicesFields } = useInvoicesListContext();
|
const { invoicesViews, invoicesFields } = useInvoicesListContext();
|
||||||
|
|
||||||
|
// Exports pdf document.
|
||||||
|
const { downloadAsync: downloadExportPdf } = useDownloadExportPdf();
|
||||||
|
|
||||||
// Handle new invoice button click.
|
// Handle new invoice button click.
|
||||||
const handleClickNewInvoice = () => {
|
const handleClickNewInvoice = () => {
|
||||||
history.push('/invoices/new');
|
history.push('/invoices/new');
|
||||||
@@ -88,6 +92,10 @@ function InvoiceActionsBar({
|
|||||||
const handleExportBtnClick = () => {
|
const handleExportBtnClick = () => {
|
||||||
openDialog(DialogsName.Export, { resource: 'sale_invoice' });
|
openDialog(DialogsName.Export, { resource: 'sale_invoice' });
|
||||||
};
|
};
|
||||||
|
// Handles the print button click.
|
||||||
|
const handlePrintBtnClick = () => {
|
||||||
|
downloadExportPdf({ resource: 'SaleInvoice' });
|
||||||
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<DashboardActionsBar>
|
<DashboardActionsBar>
|
||||||
@@ -134,6 +142,7 @@ function InvoiceActionsBar({
|
|||||||
className={Classes.MINIMAL}
|
className={Classes.MINIMAL}
|
||||||
icon={<Icon icon={'print-16'} iconSize={'16'} />}
|
icon={<Icon icon={'print-16'} iconSize={'16'} />}
|
||||||
text={<T id={'print'} />}
|
text={<T id={'print'} />}
|
||||||
|
onClick={handlePrintBtnClick}
|
||||||
/>
|
/>
|
||||||
<Button
|
<Button
|
||||||
className={Classes.MINIMAL}
|
className={Classes.MINIMAL}
|
||||||
|
|||||||
@@ -31,8 +31,11 @@ import {
|
|||||||
PaymentReceiveAction,
|
PaymentReceiveAction,
|
||||||
AbilitySubject,
|
AbilitySubject,
|
||||||
} from '@/constants/abilityOption';
|
} from '@/constants/abilityOption';
|
||||||
|
|
||||||
import { usePaymentReceivesListContext } from './PaymentReceiptsListProvider';
|
import { usePaymentReceivesListContext } from './PaymentReceiptsListProvider';
|
||||||
import { useRefreshPaymentReceive } from '@/hooks/query/paymentReceives';
|
import { useRefreshPaymentReceive } from '@/hooks/query/paymentReceives';
|
||||||
|
import { useDownloadExportPdf } from '@/hooks/query/FinancialReports/use-export-pdf';
|
||||||
|
|
||||||
import { compose } from '@/utils';
|
import { compose } from '@/utils';
|
||||||
import { DialogsName } from '@/constants/dialogs';
|
import { DialogsName } from '@/constants/dialogs';
|
||||||
|
|
||||||
@@ -61,6 +64,9 @@ function PaymentReceiveActionsBar({
|
|||||||
// Payment receives list context.
|
// Payment receives list context.
|
||||||
const { paymentReceivesViews, fields } = usePaymentReceivesListContext();
|
const { paymentReceivesViews, fields } = usePaymentReceivesListContext();
|
||||||
|
|
||||||
|
// Exports pdf document.
|
||||||
|
const { downloadAsync: downloadExportPdf } = useDownloadExportPdf();
|
||||||
|
|
||||||
// Handle new payment button click.
|
// Handle new payment button click.
|
||||||
const handleClickNewPaymentReceive = () => {
|
const handleClickNewPaymentReceive = () => {
|
||||||
history.push('/payment-receives/new');
|
history.push('/payment-receives/new');
|
||||||
@@ -91,6 +97,10 @@ function PaymentReceiveActionsBar({
|
|||||||
const handleExportBtnClick = () => {
|
const handleExportBtnClick = () => {
|
||||||
openDialog(DialogsName.Export, { resource: 'payment_receive' });
|
openDialog(DialogsName.Export, { resource: 'payment_receive' });
|
||||||
};
|
};
|
||||||
|
// Handles the print button click.
|
||||||
|
const handlePrintBtnClick = () => {
|
||||||
|
downloadExportPdf({ resource: 'PaymentReceive' });
|
||||||
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<DashboardActionsBar>
|
<DashboardActionsBar>
|
||||||
@@ -137,6 +147,7 @@ function PaymentReceiveActionsBar({
|
|||||||
className={Classes.MINIMAL}
|
className={Classes.MINIMAL}
|
||||||
icon={<Icon icon={'print-16'} iconSize={'16'} />}
|
icon={<Icon icon={'print-16'} iconSize={'16'} />}
|
||||||
text={<T id={'print'} />}
|
text={<T id={'print'} />}
|
||||||
|
onClick={handlePrintBtnClick}
|
||||||
/>
|
/>
|
||||||
<Button
|
<Button
|
||||||
className={Classes.MINIMAL}
|
className={Classes.MINIMAL}
|
||||||
|
|||||||
@@ -29,14 +29,15 @@ import withReceipts from './withReceipts';
|
|||||||
import withReceiptsActions from './withReceiptsActions';
|
import withReceiptsActions from './withReceiptsActions';
|
||||||
import withSettings from '@/containers/Settings/withSettings';
|
import withSettings from '@/containers/Settings/withSettings';
|
||||||
import withSettingsActions from '@/containers/Settings/withSettingsActions';
|
import withSettingsActions from '@/containers/Settings/withSettingsActions';
|
||||||
|
import withDialogActions from '@/containers/Dialog/withDialogActions';
|
||||||
|
|
||||||
import { useReceiptsListContext } from './ReceiptsListProvider';
|
import { useReceiptsListContext } from './ReceiptsListProvider';
|
||||||
import { useRefreshReceipts } from '@/hooks/query/receipts';
|
import { useRefreshReceipts } from '@/hooks/query/receipts';
|
||||||
|
import { useDownloadExportPdf } from '@/hooks/query/FinancialReports/use-export-pdf';
|
||||||
import { SaleReceiptAction, AbilitySubject } from '@/constants/abilityOption';
|
import { SaleReceiptAction, AbilitySubject } from '@/constants/abilityOption';
|
||||||
|
|
||||||
import { compose } from '@/utils';
|
|
||||||
import withDialogActions from '@/containers/Dialog/withDialogActions';
|
|
||||||
import { DialogsName } from '@/constants/dialogs';
|
import { DialogsName } from '@/constants/dialogs';
|
||||||
|
import { compose } from '@/utils';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Receipts actions bar.
|
* Receipts actions bar.
|
||||||
@@ -62,6 +63,9 @@ function ReceiptActionsBar({
|
|||||||
// Sale receipts list context.
|
// Sale receipts list context.
|
||||||
const { receiptsViews, fields } = useReceiptsListContext();
|
const { receiptsViews, fields } = useReceiptsListContext();
|
||||||
|
|
||||||
|
// Exports pdf document.
|
||||||
|
const { downloadAsync: downloadExportPdf } = useDownloadExportPdf();
|
||||||
|
|
||||||
// Handle new receipt button click.
|
// Handle new receipt button click.
|
||||||
const onClickNewReceipt = () => {
|
const onClickNewReceipt = () => {
|
||||||
history.push('/receipts/new');
|
history.push('/receipts/new');
|
||||||
@@ -95,6 +99,10 @@ function ReceiptActionsBar({
|
|||||||
const handleExportBtnClick = () => {
|
const handleExportBtnClick = () => {
|
||||||
openDialog(DialogsName.Export, { resource: 'sale_receipt' });
|
openDialog(DialogsName.Export, { resource: 'sale_receipt' });
|
||||||
};
|
};
|
||||||
|
// Handle print button click.
|
||||||
|
const handlePrintButtonClick = () => {
|
||||||
|
downloadExportPdf({ resource: 'SaleReceipt' });
|
||||||
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<DashboardActionsBar>
|
<DashboardActionsBar>
|
||||||
@@ -143,8 +151,8 @@ function ReceiptActionsBar({
|
|||||||
className={Classes.MINIMAL}
|
className={Classes.MINIMAL}
|
||||||
icon={<Icon icon={'print-16'} iconSize={'16'} />}
|
icon={<Icon icon={'print-16'} iconSize={'16'} />}
|
||||||
text={<T id={'print'} />}
|
text={<T id={'print'} />}
|
||||||
|
onClick={handlePrintButtonClick}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<Button
|
<Button
|
||||||
className={Classes.MINIMAL}
|
className={Classes.MINIMAL}
|
||||||
icon={<Icon icon={'file-import-16'} />}
|
icon={<Icon icon={'file-import-16'} />}
|
||||||
|
|||||||
@@ -22,10 +22,12 @@ import {
|
|||||||
AdvancedFilterPopover,
|
AdvancedFilterPopover,
|
||||||
} from '@/components';
|
} from '@/components';
|
||||||
|
|
||||||
import { useRefreshVendors } from '@/hooks/query/vendors';
|
|
||||||
import { VendorAction, AbilitySubject } from '@/constants/abilityOption';
|
import { VendorAction, AbilitySubject } from '@/constants/abilityOption';
|
||||||
|
|
||||||
|
import { useRefreshVendors } from '@/hooks/query/vendors';
|
||||||
import { useVendorsListContext } from './VendorsListProvider';
|
import { useVendorsListContext } from './VendorsListProvider';
|
||||||
import { useHistory } from 'react-router-dom';
|
import { useHistory } from 'react-router-dom';
|
||||||
|
import { useDownloadExportPdf } from '@/hooks/query/FinancialReports/use-export-pdf';
|
||||||
|
|
||||||
import withVendors from './withVendors';
|
import withVendors from './withVendors';
|
||||||
import withVendorsActions from './withVendorsActions';
|
import withVendorsActions from './withVendorsActions';
|
||||||
@@ -61,11 +63,13 @@ function VendorActionsBar({
|
|||||||
// Vendors list context.
|
// Vendors list context.
|
||||||
const { vendorsViews, fields } = useVendorsListContext();
|
const { vendorsViews, fields } = useVendorsListContext();
|
||||||
|
|
||||||
|
// Exports pdf document.
|
||||||
|
const { downloadAsync: downloadExportPdf } = useDownloadExportPdf();
|
||||||
|
|
||||||
// Handles new vendor button click.
|
// Handles new vendor button click.
|
||||||
const onClickNewVendor = () => {
|
const onClickNewVendor = () => {
|
||||||
history.push('/vendors/new');
|
history.push('/vendors/new');
|
||||||
};
|
};
|
||||||
|
|
||||||
// Vendors refresh action.
|
// Vendors refresh action.
|
||||||
const { refresh } = useRefreshVendors();
|
const { refresh } = useRefreshVendors();
|
||||||
|
|
||||||
@@ -73,31 +77,30 @@ function VendorActionsBar({
|
|||||||
const handleTabChange = (viewSlug) => {
|
const handleTabChange = (viewSlug) => {
|
||||||
setVendorsTableState({ viewSlug });
|
setVendorsTableState({ viewSlug });
|
||||||
};
|
};
|
||||||
|
|
||||||
// Handle inactive switch changing.
|
// Handle inactive switch changing.
|
||||||
const handleInactiveSwitchChange = (event) => {
|
const handleInactiveSwitchChange = (event) => {
|
||||||
const checked = event.target.checked;
|
const checked = event.target.checked;
|
||||||
setVendorsTableState({ inactiveMode: checked });
|
setVendorsTableState({ inactiveMode: checked });
|
||||||
};
|
};
|
||||||
|
|
||||||
// Handle click a refresh sale estimates
|
// Handle click a refresh sale estimates
|
||||||
const handleRefreshBtnClick = () => {
|
const handleRefreshBtnClick = () => {
|
||||||
refresh();
|
refresh();
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleTableRowSizeChange = (size) => {
|
const handleTableRowSizeChange = (size) => {
|
||||||
addSetting('vendors', 'tableSize', size);
|
addSetting('vendors', 'tableSize', size);
|
||||||
};
|
};
|
||||||
|
|
||||||
// Handle import button success.
|
// Handle import button success.
|
||||||
const handleImportBtnSuccess = () => {
|
const handleImportBtnSuccess = () => {
|
||||||
history.push('/vendors/import');
|
history.push('/vendors/import');
|
||||||
};
|
};
|
||||||
|
|
||||||
// Handle the export button click.
|
// Handle the export button click.
|
||||||
const handleExportBtnClick = () => {
|
const handleExportBtnClick = () => {
|
||||||
openDialog(DialogsName.Export, { resource: 'vendor' });
|
openDialog(DialogsName.Export, { resource: 'vendor' });
|
||||||
};
|
};
|
||||||
|
// Handle the print button click.
|
||||||
|
const handlePrintBtnClick = () => {
|
||||||
|
downloadExportPdf({ resource: 'Vendor' });
|
||||||
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<DashboardActionsBar>
|
<DashboardActionsBar>
|
||||||
@@ -140,6 +143,13 @@ function VendorActionsBar({
|
|||||||
intent={Intent.DANGER}
|
intent={Intent.DANGER}
|
||||||
/>
|
/>
|
||||||
</If>
|
</If>
|
||||||
|
<NavbarDivider />
|
||||||
|
<Button
|
||||||
|
className={Classes.MINIMAL}
|
||||||
|
icon={<Icon icon="print-16" iconSize={16} />}
|
||||||
|
text={<T id={'print'} />}
|
||||||
|
onClick={handlePrintBtnClick}
|
||||||
|
/>
|
||||||
<Button
|
<Button
|
||||||
className={Classes.MINIMAL}
|
className={Classes.MINIMAL}
|
||||||
icon={<Icon icon="file-import-16" iconSize={16} />}
|
icon={<Icon icon="file-import-16" iconSize={16} />}
|
||||||
|
|||||||
@@ -0,0 +1,62 @@
|
|||||||
|
// @ts-nocheck
|
||||||
|
import { downloadFile } from '@/hooks/useDownloadFile';
|
||||||
|
import useApiRequest from '@/hooks/useRequest';
|
||||||
|
import { AxiosError } from 'axios';
|
||||||
|
import { useMutation } from 'react-query';
|
||||||
|
import { asyncToastProgress } from '@/utils/async-toast-progress';
|
||||||
|
|
||||||
|
interface ResourceExportValues {
|
||||||
|
resource: string;
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* Initiates a download of the balance sheet in XLSX format.
|
||||||
|
* @param {Object} query - The query parameters for the request.
|
||||||
|
* @param {Object} args - Additional configurations for the download.
|
||||||
|
* @returns {Function} A function to trigger the file download.
|
||||||
|
*/
|
||||||
|
export const useResourceExportPdf = (props) => {
|
||||||
|
const apiRequest = useApiRequest();
|
||||||
|
|
||||||
|
return useMutation<void, AxiosError, any>((data: ResourceExportValues) => {
|
||||||
|
return apiRequest.get(
|
||||||
|
'/export',
|
||||||
|
{
|
||||||
|
responseType: 'blob',
|
||||||
|
headers: {
|
||||||
|
accept: 'application/pdf',
|
||||||
|
},
|
||||||
|
params: {
|
||||||
|
resource: data.resource,
|
||||||
|
format: data.format,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
props,
|
||||||
|
);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
export const useDownloadExportPdf = () => {
|
||||||
|
const { startProgress, stopProgress } = asyncToastProgress();
|
||||||
|
|
||||||
|
const resourceExportPdfMutation = useResourceExportPdf({
|
||||||
|
onMutate: () => {},
|
||||||
|
});
|
||||||
|
const { mutateAsync, isLoading: isExportPdfLoading } =
|
||||||
|
resourceExportPdfMutation;
|
||||||
|
|
||||||
|
const downloadAsync = (values) => {
|
||||||
|
if (!isExportPdfLoading) {
|
||||||
|
startProgress();
|
||||||
|
return mutateAsync(values).then((res) => {
|
||||||
|
downloadFile(res.data, `${values.resource}.pdf`);
|
||||||
|
stopProgress();
|
||||||
|
|
||||||
|
return res;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
return {
|
||||||
|
...resourceExportPdfMutation,
|
||||||
|
downloadAsync,
|
||||||
|
};
|
||||||
|
};
|
||||||
@@ -134,7 +134,6 @@ const invalidateResourcesOnImport = (
|
|||||||
queryClient: QueryClient,
|
queryClient: QueryClient,
|
||||||
resource: string,
|
resource: string,
|
||||||
) => {
|
) => {
|
||||||
debugger;
|
|
||||||
switch (resource) {
|
switch (resource) {
|
||||||
case 'Item':
|
case 'Item':
|
||||||
queryClient.invalidateQueries(T.ITEMS);
|
queryClient.invalidateQueries(T.ITEMS);
|
||||||
|
|||||||
@@ -190,7 +190,10 @@ $dashboard-views-bar-height: 44px;
|
|||||||
background: #a7b6c21f;
|
background: #a7b6c21f;
|
||||||
color: #32304a;
|
color: #32304a;
|
||||||
}
|
}
|
||||||
|
&.bp4-disabled{
|
||||||
|
background: transparent;
|
||||||
|
color: rgba(50, 48, 74, 0.4);
|
||||||
|
}
|
||||||
&.has-active-filters {
|
&.has-active-filters {
|
||||||
|
|
||||||
&,
|
&,
|
||||||
|
|||||||
76
packages/webapp/src/utils/async-toast-progress.tsx
Normal file
76
packages/webapp/src/utils/async-toast-progress.tsx
Normal file
@@ -0,0 +1,76 @@
|
|||||||
|
import { isUndefined } from 'lodash';
|
||||||
|
import clsx from 'classnames';
|
||||||
|
import {
|
||||||
|
Classes,
|
||||||
|
Intent,
|
||||||
|
ProgressBar,
|
||||||
|
Text,
|
||||||
|
ToastProps,
|
||||||
|
} from '@blueprintjs/core';
|
||||||
|
import { AppToaster } from '@/components';
|
||||||
|
|
||||||
|
interface AsyncToastProgress {
|
||||||
|
renderProgressProps?: (amount: number) => ToastProps;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function asyncToastProgress({
|
||||||
|
renderProgressProps,
|
||||||
|
}: AsyncToastProgress = {}) {
|
||||||
|
let progressToastInterval: number;
|
||||||
|
let progress = 0;
|
||||||
|
let key: string = '';
|
||||||
|
|
||||||
|
const renderProgress = (amount: number): ToastProps => {
|
||||||
|
const customProgressProps = !isUndefined(renderProgressProps)
|
||||||
|
? renderProgressProps(amount)
|
||||||
|
: {};
|
||||||
|
|
||||||
|
return {
|
||||||
|
icon: 'hand',
|
||||||
|
message: (
|
||||||
|
<>
|
||||||
|
<Text style={{ fontSize: 12, marginBottom: 6 }}>
|
||||||
|
Preparing the document.
|
||||||
|
</Text>
|
||||||
|
<ProgressBar
|
||||||
|
className={clsx({
|
||||||
|
[Classes.PROGRESS_NO_STRIPES]: amount >= 100,
|
||||||
|
})}
|
||||||
|
intent={amount < 100 ? Intent.PRIMARY : Intent.SUCCESS}
|
||||||
|
value={amount / 100}
|
||||||
|
/>
|
||||||
|
</>
|
||||||
|
),
|
||||||
|
onDismiss: (didTimeoutExpire: boolean) => {
|
||||||
|
if (!didTimeoutExpire) {
|
||||||
|
// user dismissed toast with click
|
||||||
|
window.clearInterval(progressToastInterval);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
timeout: amount < 100 ? 0 : 2000,
|
||||||
|
...customProgressProps,
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
const startProgress = () => {
|
||||||
|
key = AppToaster.show(renderProgress(0));
|
||||||
|
|
||||||
|
progressToastInterval = window.setInterval(() => {
|
||||||
|
if (progress > 100) {
|
||||||
|
window.clearInterval(progressToastInterval);
|
||||||
|
} else {
|
||||||
|
progress += 10 + Math.random() * 20;
|
||||||
|
progress = Math.min(progress, 95); // Ensure progress never reaches 100
|
||||||
|
|
||||||
|
AppToaster.show(renderProgress(progress), key);
|
||||||
|
}
|
||||||
|
}, 1000);
|
||||||
|
};
|
||||||
|
|
||||||
|
const stopProgress = () => {
|
||||||
|
progress = 100;
|
||||||
|
AppToaster.show(renderProgress(progress), key);
|
||||||
|
window.clearInterval(progressToastInterval);
|
||||||
|
};
|
||||||
|
return { startProgress, stopProgress };
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user