Merge pull request #882 from bigcapitalhq/bugs-bashing2

Bug fixes, refactoring, and improvements
This commit is contained in:
Ahmed Bouhuolia
2025-12-31 01:01:08 +02:00
committed by GitHub
6 changed files with 190 additions and 22 deletions

View File

@@ -1,4 +1,27 @@
// import { getTransactionsLockingSettingsSchema } from '@/api/controllers/TransactionsLocking/utils'; import { chain, mapKeys } from 'lodash';
const getTransactionsLockingSettingsSchema = (modules: string[]) => {
const moduleSchema = {
active: { type: 'boolean' },
lock_to_date: { type: 'date' },
unlock_from_date: { type: 'date' },
unlock_to_date: { type: 'date' },
lock_reason: { type: 'string' },
unlock_reason: { type: 'string' },
};
return chain(modules)
.map((module: string) => {
return mapKeys(moduleSchema, (value, key: string) => `${module}.${key}`);
})
.flattenDeep()
.reduce((result, value) => {
return {
...result,
...value,
};
}, {})
.value();
};
export const SettingsOptions = { export const SettingsOptions = {
organization: { organization: {
@@ -223,12 +246,12 @@ export const SettingsOptions = {
'locking-type': { 'locking-type': {
type: 'string', type: 'string',
}, },
// ...getTransactionsLockingSettingsSchema([ ...getTransactionsLockingSettingsSchema([
// 'all', 'all',
// 'sales', 'sales',
// 'purchases', 'purchases',
// 'financial', 'financial',
// ]), ]),
}, },
features: { features: {
'multi-warehouses': { 'multi-warehouses': {

View File

@@ -1,14 +1,13 @@
import { Injectable } from '@nestjs/common'; import { Injectable } from '@nestjs/common';
import { ChromiumlyTenancy } from '../ChromiumlyTenancy/ChromiumlyTenancy.service'; import { ChromiumlyTenancy } from '../ChromiumlyTenancy/ChromiumlyTenancy.service';
import { TemplateInjectable } from '../TemplateInjectable/TemplateInjectable.service'; import { renderExportResourceTableTemplateHtml } from '@bigcapital/pdf-templates';
import { mapPdfRows } from './utils'; import { mapPdfRows } from './utils';
@Injectable() @Injectable()
export class ExportPdf { export class ExportPdf {
constructor( constructor(
private readonly templateInjectable: TemplateInjectable,
private readonly chromiumlyTenancy: ChromiumlyTenancy, private readonly chromiumlyTenancy: ChromiumlyTenancy,
) {} ) { }
/** /**
* Generates the pdf table sheet for the given data and columns. * Generates the pdf table sheet for the given data and columns.
@@ -19,21 +18,18 @@ export class ExportPdf {
* @returns * @returns
*/ */
public async pdf( public async pdf(
columns: { accessor: string }, columns: { accessor: string; name?: string; style?: string; group?: string }[],
data: Record<string, any>, data: Record<string, any>,
sheetTitle: string = '', sheetTitle: string = '',
sheetDescription: string = '' sheetDescription: string = ''
) { ) {
const rows = mapPdfRows(columns, data); const rows = mapPdfRows(columns, data);
const htmlContent = await this.templateInjectable.render( const htmlContent = renderExportResourceTableTemplateHtml({
'modules/export-resource-table', table: { rows, columns },
{ sheetTitle,
table: { rows, columns }, sheetDescription,
sheetTitle, });
sheetDescription,
}
);
// Convert the HTML content to PDF // Convert the HTML content to PDF
return this.chromiumlyTenancy.convertHtmlContent(htmlContent, { return this.chromiumlyTenancy.convertHtmlContent(htmlContent, {
margins: { top: 0.2, bottom: 0.2, left: 0.2, right: 0.2 }, margins: { top: 0.2, bottom: 0.2, left: 0.2, right: 0.2 },

View File

@@ -364,13 +364,18 @@ const TransLockingItemDesc = styled.p`
`; `;
const TransLockingIcon = styled.div` const TransLockingIcon = styled.div`
--x-text-color: #93a1ba;
.bp4-dark & {
--x-text-color: rgba(255, 255, 255, 0.6);
}
border: 1px solid var(--color-transaction-locking-item-icon-border); border: 1px solid var(--color-transaction-locking-item-icon-border);
height: 45px; height: 45px;
width: 45px; width: 45px;
text-align: center; text-align: center;
line-height: 45px; line-height: 45px;
border-radius: 8px; border-radius: 8px;
color: #93a1ba; color: var(--x-text-color);
.bp4-icon { .bp4-icon {
position: relative; position: relative;
@@ -395,15 +400,24 @@ export const TransLockingContent = styled.div`
export const TransLockingReason = styled.div` export const TransLockingReason = styled.div`
font-size: 13px; font-size: 13px;
--x-text-color: #777;
.bp4-dark & {
--x-text-color: rgba(255, 255, 255, 0.6);
}
strong { strong {
color: #777; color: var(--x-text-color);
} }
`; `;
const TransUnlockWrap = styled.div` const TransUnlockWrap = styled.div`
-x-border-color: #ddd;
.bp4-dark & {
--x-border-color: rgba(255, 255, 255, 0.1);
}
padding-top: 10px; padding-top: 10px;
border-top: 1px solid #ddd; border-top: 1px solid var(--x-border-color);
margin-top: 10px; margin-top: 10px;
${TransLockingReason} { ${TransLockingReason} {

View File

@@ -0,0 +1,119 @@
import React from 'react';
import { x } from '@xstyled/emotion';
import { Box } from '../lib/layout/Box';
export interface ExportResourceTableColumn {
accessor: string;
name?: string;
style?: string;
group?: string;
}
export interface ExportResourceTableCell {
key: string;
value: string;
}
export interface ExportResourceTableRow {
cells: ExportResourceTableCell[];
classNames?: string;
}
export interface ExportResourceTableTemplateProps {
sheetTitle?: string;
sheetDescription?: string;
table: {
columns: ExportResourceTableColumn[];
rows: ExportResourceTableRow[];
};
customCSS?: string;
}
export function ExportResourceTableTemplate({
sheetTitle,
sheetDescription,
table,
customCSS,
}: ExportResourceTableTemplateProps) {
return (
<Box fontSize="12px" lineHeight="1.4" fontFamily='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"'>
<Box p="20px">
{(sheetTitle || sheetDescription) && (
<Box mb="18px" className="sheet__title">
{sheetTitle && (
<x.h2 m={0} mb="10px" fontSize="16px" lineHeight="1" className="sheetTitle">
{sheetTitle}
</x.h2>
)}
{sheetDescription && (
<x.p m={0} className="sheetDesc">
{sheetDescription}
</x.p>
)}
</Box>
)}
<x.table
className="sheet__table"
fontSize="inherit"
lineHeight="inherit"
w="100%"
tableLayout="auto"
borderCollapse="collapse"
>
<x.thead>
<x.tr>
{table.columns.map((column) => {
let styleObj: React.CSSProperties | undefined;
if (column.style) {
try {
// Handle style as JSON string
styleObj = JSON.parse(column.style);
} catch {
// If parsing fails, ignore the style
styleObj = undefined;
}
}
return (
<x.th
key={column.accessor}
borderTop="1px solid #000"
borderBottom="1px solid #000"
bg="#fff"
p="4px"
lineHeight="1.2"
className={`column--${column.accessor}`}
style={styleObj}
>
{column.name || column.accessor}
</x.th>
);
})}
</x.tr>
</x.thead>
<x.tbody>
{table.rows.map((row, rowIndex) => (
<x.tr key={rowIndex} className={row.classNames}>
{row.cells.map((cell) => (
<x.td
key={cell.key}
p="4px 8px"
borderBottom="1px solid #CCC"
className={`cell--${cell.key}`}
>
<span dangerouslySetInnerHTML={{ __html: cell.value }} />
</x.td>
))}
</x.tr>
))}
</x.tbody>
</x.table>
{customCSS && (
<x.style dangerouslySetInnerHTML={{ __html: customCSS }} />
)}
</Box>
</Box>
);
}

View File

@@ -4,9 +4,11 @@ export * from './components/EstimatePaperTemplate';
export * from './components/ReceiptPaperTemplate'; export * from './components/ReceiptPaperTemplate';
export * from './components/PaymentReceivedPaperTemplate'; export * from './components/PaymentReceivedPaperTemplate';
export * from './components/FinancialSheetTemplate'; export * from './components/FinancialSheetTemplate';
export * from './components/ExportResourceTableTemplate';
export * from './renders/render-invoice-paper-template'; export * from './renders/render-invoice-paper-template';
export * from './renders/render-estimate-paper-template'; export * from './renders/render-estimate-paper-template';
export * from './renders/render-receipt-paper-template'; export * from './renders/render-receipt-paper-template';
export * from './renders/render-payment-received-paper-template'; export * from './renders/render-payment-received-paper-template';
export * from './renders/render-financial-sheet-template'; export * from './renders/render-financial-sheet-template';
export * from './renders/render-export-resource-table-template';

View File

@@ -0,0 +1,14 @@
import {
ExportResourceTableTemplate,
ExportResourceTableTemplateProps,
} from '../components/ExportResourceTableTemplate';
import { renderSSR } from './render-ssr';
export const renderExportResourceTableTemplateHtml = (
props: ExportResourceTableTemplateProps
) => {
return renderSSR(
<ExportResourceTableTemplate {...props} />
);
};