2
0
mirror of https://github.com/frappe/books.git synced 2024-12-22 10:58:59 +00:00

incr: insert or update .template.html files

- move .template.html files out of fixtures
This commit is contained in:
18alantom 2023-03-07 14:16:19 +05:30
parent dabcbcd2ce
commit eda3bb7576
13 changed files with 161 additions and 7 deletions

View File

@ -5,6 +5,7 @@ extraResources:
[
{ from: 'log_creds.txt', to: '../creds/log_creds.txt' },
{ from: 'translations', to: '../translations' },
{ from: 'translations', to: '../translations' },
]
mac:
type: distribution

View File

@ -4,7 +4,7 @@ import {
app,
BrowserWindow,
BrowserWindowConstructorOptions,
protocol
protocol,
} from 'electron';
import Store from 'electron-store';
import { autoUpdater } from 'electron-updater';

41
main/getPrintTemplates.ts Normal file
View File

@ -0,0 +1,41 @@
import fs from 'fs/promises';
import path from 'path';
import { TemplateFile } from 'utils/types';
export async function getTemplates() {
const paths = await getPrintTemplatePaths();
if (!paths) {
return [];
}
const templates: TemplateFile[] = [];
for (const file of paths.files) {
const filePath = path.join(paths.root, file);
const template = await fs.readFile(filePath, 'utf-8');
const { mtime } = await fs.stat(filePath);
templates.push({ template, file, modified: mtime.toISOString() });
}
return templates;
}
async function getPrintTemplatePaths(): Promise<{
files: string[];
root: string;
} | null> {
let root = path.join(process.resourcesPath, `../templates`);
try {
const files = await fs.readdir(root);
return { files, root };
} catch {
root = path.join(__dirname, `../templates`);
}
try {
const files = await fs.readdir(root);
return { files, root };
} catch {
return null;
}
}

View File

@ -10,6 +10,7 @@ import { DatabaseMethod } from '../utils/db/types';
import { IPC_ACTIONS } from '../utils/messages';
import { getUrlAndTokenString, sendError } from './contactMothership';
import { getLanguageMap } from './getLanguageMap';
import { getTemplates } from './getPrintTemplates';
import {
getConfigFilesWithModified,
getErrorHandledReponse,
@ -117,7 +118,7 @@ export default function registerIpcMainActionListeners(main: Main) {
);
ipcMain.handle(IPC_ACTIONS.GET_CREDS, async (event) => {
return await getUrlAndTokenString();
return getUrlAndTokenString();
});
ipcMain.handle(IPC_ACTIONS.DELETE_FILE, async (_, filePath) => {
@ -137,6 +138,10 @@ export default function registerIpcMainActionListeners(main: Main) {
};
});
ipcMain.handle(IPC_ACTIONS.GET_TEMPLATES, async () => {
return getTemplates();
});
/**
* Database Related Actions
*/

View File

@ -111,6 +111,8 @@ function setOnWindow(isDevelopment: boolean) {
window.fyo = fyo;
// @ts-ignore
window.DateTime = DateTime;
// @ts-ignore
window.ipcRenderer = ipcRenderer;
}
function getPlatformName(platform: string) {

View File

@ -1,6 +1,5 @@
import { Fyo } from 'fyo';
import { ConfigFile, ConfigKeys } from 'fyo/core/types';
import { Doc } from 'fyo/model/doc';
import { getRegionalModels, models } from 'models/index';
import { ModelNameEnum } from 'models/types';
import { TargetField } from 'schemas/types';
@ -9,6 +8,7 @@ import {
getRandomString,
getValueMapFromList,
} from 'utils/index';
import { updatePrintTemplates } from './printTemplates';
export async function initializeInstance(
dbPath: string,
@ -34,6 +34,7 @@ export async function initializeInstance(
await setInstanceId(fyo);
await setOpenCount(fyo);
await setCurrencySymbols(fyo);
await updatePrintTemplates(fyo);
}
async function closeDbIfConnected(fyo: Fyo) {

View File

@ -6,7 +6,7 @@ import { t } from 'fyo';
import { BaseError } from 'fyo/utils/errors';
import { BackendResponse } from 'utils/ipc/types';
import { IPC_ACTIONS, IPC_MESSAGES } from 'utils/messages';
import { SelectFileOptions, SelectFileReturn } from 'utils/types';
import { SelectFileOptions, SelectFileReturn, TemplateFile } from 'utils/types';
import { setLanguageMap } from './language';
import { showMessageDialog, showToast } from './ui';
@ -14,6 +14,10 @@ export function reloadWindow() {
return ipcRenderer.send(IPC_MESSAGES.RELOAD_MAIN_WINDOW);
}
export async function getTemplates(): Promise<TemplateFile[]> {
return await ipcRenderer.invoke(IPC_ACTIONS.GET_TEMPLATES);
}
export async function selectFile(
options: SelectFileOptions
): Promise<SelectFileReturn> {

View File

@ -3,10 +3,14 @@ import { Doc } from 'fyo/model/doc';
import { Invoice } from 'models/baseModels/Invoice/Invoice';
import { ModelNameEnum } from 'models/types';
import { FieldTypeEnum, Schema, TargetField } from 'schemas/types';
import { getSavePath, makePDF } from './ipcCalls';
import { getValueMapFromList } from 'utils/index';
import { TemplateFile } from 'utils/types';
import { getSavePath, getTemplates, makePDF } from './ipcCalls';
import { PrintValues } from './types';
import { getDocFromNameIfExistsElseNew } from './ui';
type PrintTemplateData = Record<string, unknown>;
type TemplateUpdateItem = { name: string; template: string; type: string };
const printSettingsFields = [
'logo',
@ -256,3 +260,92 @@ function getAllCSSAsStyleElem() {
styleElem.innerHTML = cssTexts.join('\n');
return styleElem;
}
export async function updatePrintTemplates(fyo: Fyo) {
const templateFiles = await getTemplates();
const existingTemplates = (await fyo.db.getAll(ModelNameEnum.PrintTemplate, {
fields: ['name', 'modified'],
filters: { isCustom: false },
})) as { name: string; modified: Date }[];
const nameModifiedMap = getValueMapFromList(
existingTemplates,
'name',
'modified'
);
const updateList: TemplateUpdateItem[] = [];
for (const templateFile of templateFiles) {
const updates = getPrintTemplateUpdateList(
templateFile,
nameModifiedMap,
fyo
);
updateList.push(...updates);
}
for (const { name, type, template } of updateList) {
const doc = await getDocFromNameIfExistsElseNew(
ModelNameEnum.PrintTemplate,
name
);
await doc.set({ name, type, template, isCustom: false });
await doc.sync();
}
}
function getPrintTemplateUpdateList(
{ file, template, modified: modifiedString }: TemplateFile,
nameModifiedMap: Record<string, Date>,
fyo: Fyo
): TemplateUpdateItem[] {
const templateList: TemplateUpdateItem[] = [];
const dbModified = new Date(modifiedString);
for (const { name, type } of getNameAndTypeFromTemplateFile(file, fyo)) {
const fileModified = nameModifiedMap[name];
if (fileModified && dbModified.valueOf() >= fileModified.valueOf()) {
continue;
}
templateList.push({
name,
type,
template,
});
}
return templateList;
}
function getNameAndTypeFromTemplateFile(
file: string,
fyo: Fyo
): { name: string; type: string }[] {
/**
* Template File Name Format:
* TemplateName[.SchemaName].template.html
*
* If the SchemaName is absent then it is assumed
* that the SchemaName is:
* - SalesInvoice
* - PurchaseInvoice
*/
const fileName = file.split('.template.html')[0];
const name = fileName.split('.')[0];
const schemaName = fileName.split('.')[1];
if (schemaName) {
const label = fyo.schemaMap[schemaName]?.label ?? schemaName;
return [{ name: `${name} - ${label}`, type: schemaName }];
}
return [ModelNameEnum.SalesInvoice, ModelNameEnum.PurchaseInvoice].map(
(schemaName) => {
const label = fyo.schemaMap[schemaName]?.label ?? schemaName;
return { name: `${name} - ${label}`, type: schemaName };
}
);
}

View File

@ -22,6 +22,7 @@ export enum IPC_ACTIONS {
SELECT_FILE = 'select-file',
GET_CREDS = 'get-creds',
GET_DB_LIST = 'get-db-list',
GET_TEMPLATES = 'get-templates',
DELETE_FILE = 'delete-file',
// Database messages
DB_CREATE = 'db-create',

View File

@ -23,14 +23,18 @@ export interface VersionParts {
beta?: number;
}
export type Creds = { errorLogUrl: string; telemetryUrl: string; tokenString: string };
export type Creds = {
errorLogUrl: string;
telemetryUrl: string;
tokenString: string;
};
export type UnexpectedLogObject = {
name: string;
message: string;
stack: string;
more: Record<string, unknown>;
}
};
export interface SelectFileOptions {
title: string;
@ -48,3 +52,5 @@ export interface SelectFileReturn {
export type PropertyEnum<T extends Record<string, any>> = {
[key in keyof Required<T>]: key;
};
export type TemplateFile = { file: string; template: string; modified: string };