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 = {
organization: {
@@ -223,12 +246,12 @@ export const SettingsOptions = {
'locking-type': {
type: 'string',
},
// ...getTransactionsLockingSettingsSchema([
// 'all',
// 'sales',
// 'purchases',
// 'financial',
// ]),
...getTransactionsLockingSettingsSchema([
'all',
'sales',
'purchases',
'financial',
]),
},
features: {
'multi-warehouses': {

View File

@@ -1,14 +1,13 @@
import { Injectable } from '@nestjs/common';
import { ChromiumlyTenancy } from '../ChromiumlyTenancy/ChromiumlyTenancy.service';
import { TemplateInjectable } from '../TemplateInjectable/TemplateInjectable.service';
import { renderExportResourceTableTemplateHtml } from '@bigcapital/pdf-templates';
import { mapPdfRows } from './utils';
@Injectable()
export class ExportPdf {
constructor(
private readonly templateInjectable: TemplateInjectable,
private readonly chromiumlyTenancy: ChromiumlyTenancy,
) {}
) { }
/**
* Generates the pdf table sheet for the given data and columns.
@@ -19,21 +18,18 @@ export class ExportPdf {
* @returns
*/
public async pdf(
columns: { accessor: string },
columns: { accessor: string; name?: string; style?: string; group?: string }[],
data: Record<string, any>,
sheetTitle: string = '',
sheetDescription: string = ''
) {
const rows = mapPdfRows(columns, data);
const htmlContent = await this.templateInjectable.render(
'modules/export-resource-table',
{
table: { rows, columns },
sheetTitle,
sheetDescription,
}
);
const htmlContent = renderExportResourceTableTemplateHtml({
table: { rows, columns },
sheetTitle,
sheetDescription,
});
// Convert the HTML content to PDF
return this.chromiumlyTenancy.convertHtmlContent(htmlContent, {
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`
--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);
height: 45px;
width: 45px;
text-align: center;
line-height: 45px;
border-radius: 8px;
color: #93a1ba;
color: var(--x-text-color);
.bp4-icon {
position: relative;
@@ -395,15 +400,24 @@ export const TransLockingContent = styled.div`
export const TransLockingReason = styled.div`
font-size: 13px;
--x-text-color: #777;
.bp4-dark & {
--x-text-color: rgba(255, 255, 255, 0.6);
}
strong {
color: #777;
color: var(--x-text-color);
}
`;
const TransUnlockWrap = styled.div`
-x-border-color: #ddd;
.bp4-dark & {
--x-border-color: rgba(255, 255, 255, 0.1);
}
padding-top: 10px;
border-top: 1px solid #ddd;
border-top: 1px solid var(--x-border-color);
margin-top: 10px;
${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/PaymentReceivedPaperTemplate';
export * from './components/FinancialSheetTemplate';
export * from './components/ExportResourceTableTemplate';
export * from './renders/render-invoice-paper-template';
export * from './renders/render-estimate-paper-template';
export * from './renders/render-receipt-paper-template';
export * from './renders/render-payment-received-paper-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} />
);
};