Initial commit

This commit is contained in:
gsinghpal
2026-02-22 01:22:18 -05:00
commit 5200d5baf0
2394 changed files with 386834 additions and 0 deletions

View File

@@ -0,0 +1,185 @@
/** @odoo-module **/
import { registry } from "@web/core/registry";
import { _t } from "@web/core/l10n/translation";
import { session } from "@web/session";
import { rpc } from "@web/core/network/rpc";
import { user } from "@web/core/user";
import { Component, useState, onMounted } from "@odoo/owl";
import { Dialog } from "@web/core/dialog/dialog";
export class PDFViewerDialog extends Component {
setup() {
this.state = useState({
isLoading: true,
viewerUrl: this.getViewerUrl(),
isMaximized: false
});
}
getViewerUrl() {
const baseUrl = '/pdf_print_preview/static/lib/pdfjs/web/viewer.html';
return `${baseUrl}?file=${this.props.url}`;
}
onIframeLoad() {
this.state.isLoading = false;
}
toggle() {
this.state.isMaximized = !this.state.isMaximized;
}
getDialogSize() {
if (this.state.isMaximized) {
return 'fullscreen';
}
return 'xl';
}
getFrameStyle() {
if (this.state.isMaximized) {
return 'height: calc(98vh - 141px) !important;';
}
return 'height: calc(90vh - 100px) !important;';
}
}
PDFViewerDialog.template = 'pdf_print_preview.PDFViewerDialog';
PDFViewerDialog.components = { Dialog };
// Register for use in actions
registry.category("dialog").add("PDFViewerDialog", PDFViewerDialog);
export function openPDFViewer(env, url, title = "PDF Document") {
const dialog = env.services.dialog;
return dialog.add(PDFViewerDialog, {
url: url,
title: title
});
}
/**
* Helper function to handle automatic printing
* @param {string} url - URL of the PDF to print
* @param {Object} env - Environment object for notifications
*/
function handleAutomaticPrinting(url, env) {
const printFrame = document.createElement('iframe');
printFrame.style.display = 'none';
printFrame.src = url;
printFrame.onload = function() {
try {
printFrame.contentWindow.print();
} catch (err) {
env.services.notification.add(
_t("Failed to print automatically. Please check your browser settings."),
{
type: 'warning',
sticky: true,
title: _t("Printing Error"),
}
);
document.body.removeChild(printFrame);
}
};
const cleanup = () => {
document.body.removeChild(printFrame);
window.removeEventListener('focus', cleanup);
};
window.addEventListener('focus', cleanup);
document.body.appendChild(printFrame);
}
/**
* Generates the report url given a report action.
*
* @private
* @param {ReportAction} action
* @param {env} env
* @returns {string}
*/
function _getReportUrl(action, env, filename) {
let url = `/report/pdf/${action.report_name}`;
const actionContext = action.context || {};
filename = filename || action.name;
if(filename !== undefined)
filename = filename.replace(/[/?%#&=]/g, "_") + ".pdf";
if (action.data && JSON.stringify(action.data) !== "{}") {
const options = encodeURIComponent(JSON.stringify(action.data));
const context = encodeURIComponent(JSON.stringify(actionContext));
url += `?filename=${filename}&options=${options}&context=${context}&`;
} else {
if (actionContext.active_ids) {
url += `/${actionContext.active_ids.join(",")}?filename=${filename}&context=${encodeURIComponent(JSON.stringify(user.context))}&`;
}
}
return url;
}
async function PdfPrintPreview(action, options, env) {
const link = '<br><br><a href="http://wkhtmltopdf.org/" target="_blank">wkhtmltopdf.org</a>';
const WKHTMLTOPDF_MESSAGES = {
broken:
_t(
"Your installation of Wkhtmltopdf seems to be broken. The report will be shown " +
"in html."
) + link,
install:
_t(
"Unable to find Wkhtmltopdf on this system. The report will be shown in " + "html."
) + link,
upgrade:
_t(
"You should upgrade your version of Wkhtmltopdf to at least 0.12.0 in order to " +
"get a correct display of headers and footers as well as support for " +
"table-breaking between pages."
) + link,
workers: _t(
"You need to start Odoo with at least two workers to print a pdf version of " +
"the reports."
),
};
if (action.report_type === "qweb-pdf" && env.services.menu.getCurrentApp() !== undefined && (session.preview_print || session.automatic_printing)) {
let getReportResult = rpc("/pdf_print_preview/get_report_name", {
report_name: action.report_name,
data: JSON.stringify(action.context)
});
const result = await getReportResult;
const state = result["wkhtmltopdf_state"];
// display a notification according to wkhtmltopdf's state
if (state in WKHTMLTOPDF_MESSAGES) {
env.services.notification.add(WKHTMLTOPDF_MESSAGES[state], {
sticky: true,
title: _t("Report"),
});
}
if (state === "upgrade" || state === "ok") {
let url = _getReportUrl(action, env, result["file_name"]);
if(session.preview_print) {
// PreviewDialog.createPreviewDialog(self, url, action.name);
openPDFViewer(env, url, action.name);
}
if (session.automatic_printing) {
handleAutomaticPrinting(url, env);
}
return true;
}
}
}
registry
.category("ir.actions.report handlers")
.add("pdf_print_preview", PdfPrintPreview);

View File

@@ -0,0 +1,26 @@
/** @odoo-module **/
import { registry } from "@web/core/registry";
import { _t } from "@web/core/l10n/translation";
import { rpc } from "@web/core/network/rpc";
import { user } from "@web/core/user";
function reportPreviewConfigItem(env) {
return {
type: "item",
id: "report_preview",
description: _t("Report preview"),
callback: async function () {
const actionDescription = await rpc("/web/action/load", {
action_id: "pdf_print_preview.action_short_preview_print"
});
actionDescription.res_id = user.userId;
env.services.action.doAction(actionDescription);
},
sequence: 52,
};
}
registry.category("user_menuitems")
.add("report_preview", reportPreviewConfigItem);

View File

@@ -0,0 +1,41 @@
<?xml version="1.0" encoding="UTF-8"?>
<templates xml:space="preserve">
<t t-name="pdf_print_preview.PDFViewerDialog">
<Dialog size="getDialogSize()" footer="false">
<t t-set-slot="header">
<div class="d-flex align-items-center justify-content-between flex w-100">
<div style="width: 90px"></div>
<h4 class="modal-title text-break fw-normal">
<b><t t-esc="props.title" /></b>
</h4>
<div class="d-flex align-items-center" style="width: 45px">
<button type="button" class="btn" t-on-click="toggle">
<i t-if="!state.isMaximized" class="fa fa-square-o" />
<i t-else="" class="fa fa-clone" />
</button>
<button type="button" class="btn-close" t-on-click="props.close"/>
</div>
</div>
</t>
<div class="o_pdf_viewer position-relative">
<!-- Loading spinner -->
<div t-if="state.isLoading"
class="position-absolute w-100 h-100 d-flex justify-content-center align-items-center"
style="z-index: 1;">
<div class="spinner-border" role="status">
<span class="visually-hidden">Loading...</span>
</div>
</div>
<!-- PDF.js viewer iframe -->
<iframe t-att-src="state.viewerUrl"
class="w-100 border-0"
t-att-style="getFrameStyle()"
t-on-load="onIframeLoad"
allowfullscreen="true"
webkitallowfullscreen="true" />
</div>
</Dialog>
</t>
</templates>