medusajs-documents-plugin 0.0.0-stage → 1.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.medusa/server/src/admin/index.js +2427 -0
- package/.medusa/server/src/admin/index.mjs +2428 -0
- package/.medusa/server/src/api/admin/documents/[id]/document/route.js +36 -0
- package/.medusa/server/src/api/admin/documents/[id]/send/route.js +41 -0
- package/.medusa/server/src/api/admin/documents/[id]/sync-zoho/route.js +68 -0
- package/.medusa/server/src/api/admin/documents/custom/route.js +48 -0
- package/.medusa/server/src/api/admin/documents/manual/route.js +46 -0
- package/.medusa/server/src/api/admin/documents/route.js +36 -0
- package/.medusa/server/src/api/admin/documents/settings/route.js +44 -0
- package/.medusa/server/src/api/admin/documents/templates/preview/route.js +159 -0
- package/.medusa/server/src/api/admin/documents/zoho/list/route.js +51 -0
- package/.medusa/server/src/api/documents/[id]/document/route.js +36 -0
- package/.medusa/server/src/api/documents/r/[code]/route.js +29 -0
- package/.medusa/server/src/api/documents/templates/preview/route.js +159 -0
- package/.medusa/server/src/api/store/documents/r/[code]/route.js +22 -0
- package/.medusa/server/src/index.js +27 -0
- package/.medusa/server/src/modules/documents/index.js +13 -0
- package/.medusa/server/src/modules/documents/migrations/Migration20261012164601.js +23 -0
- package/.medusa/server/src/modules/documents/migrations/Migration20261014150000.js +20 -0
- package/.medusa/server/src/modules/documents/models/document-link.js +12 -0
- package/.medusa/server/src/modules/documents/models/document-record.js +33 -0
- package/.medusa/server/src/modules/documents/models/document-settings.js +61 -0
- package/.medusa/server/src/modules/documents/service.js +456 -0
- package/.medusa/server/src/services/notification-sender.js +293 -0
- package/.medusa/server/src/services/pdf-post-processor.js +64 -0
- package/.medusa/server/src/services/pdfkit-generator.js +438 -0
- package/.medusa/server/src/services/zoho-books.js +221 -0
- package/.medusa/server/src/subscribers/order-documents.js +178 -0
- package/.medusa/server/src/subscribers/repair-documents.js +162 -0
- package/.medusa/server/src/utils/integrate.js +37 -0
- package/.medusa/server/src/utils/payment-link.js +69 -0
- package/.medusa/server/src/workflows/create-manual-document.js +27 -0
- package/.medusa/server/src/workflows/generate-document.js +24 -0
- package/.medusa/server/src/workflows/index.js +20 -0
- package/.medusa/server/src/workflows/send-document-notification.js +41 -0
- package/CHANGELOG.md +87 -0
- package/LICENSE +21 -0
- package/README.md +201 -2
- package/package.json +86 -4
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.GET = GET;
|
|
4
|
+
const documents_1 = require("../../../../../modules/documents");
|
|
5
|
+
// GET /admin/documents/:id/document
|
|
6
|
+
async function GET(req, res) {
|
|
7
|
+
const documentService = req.scope.resolve(documents_1.DOCUMENTS_MODULE);
|
|
8
|
+
const id = req.params.id;
|
|
9
|
+
try {
|
|
10
|
+
let record = null;
|
|
11
|
+
// Check by ID or display_id
|
|
12
|
+
try {
|
|
13
|
+
record = await documentService.retrieveDocumentRecord(id);
|
|
14
|
+
}
|
|
15
|
+
catch (e) {
|
|
16
|
+
const records = await documentService.listDocumentRecords({ display_id: id });
|
|
17
|
+
if (records && records.length > 0) {
|
|
18
|
+
record = records[0];
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
if (!record) {
|
|
22
|
+
return res.status(404).send("Document not found");
|
|
23
|
+
}
|
|
24
|
+
const pdfBuffer = await documentService.getPdfForRecord(record.id, req.scope);
|
|
25
|
+
res.setHeader("Content-Type", "application/pdf");
|
|
26
|
+
res.setHeader("Content-Disposition", `inline; filename="${record.display_id}.pdf"`);
|
|
27
|
+
res.setHeader("Content-Length", String(pdfBuffer.length));
|
|
28
|
+
res.setHeader("Cache-Control", "no-cache, no-store, must-revalidate");
|
|
29
|
+
return res.send(pdfBuffer);
|
|
30
|
+
}
|
|
31
|
+
catch (err) {
|
|
32
|
+
req.scope.resolve("logger")?.error(`[Documents-API] Error streaming PDF: ${err.message}`);
|
|
33
|
+
return res.status(500).send(`Failed to generate document: ${err.message}`);
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicm91dGUuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi8uLi8uLi9zcmMvYXBpL2FkbWluL2RvY3VtZW50cy9baWRdL2RvY3VtZW50L3JvdXRlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7O0FBS0Esa0JBK0JDO0FBbkNELGdFQUFvRTtBQUdwRSxvQ0FBb0M7QUFDN0IsS0FBSyxVQUFVLEdBQUcsQ0FBQyxHQUFrQyxFQUFFLEdBQW1CO0lBQy9FLE1BQU0sZUFBZSxHQUEwQixHQUFHLENBQUMsS0FBSyxDQUFDLE9BQU8sQ0FBQyw0QkFBZ0IsQ0FBQyxDQUFDO0lBQ25GLE1BQU0sRUFBRSxHQUFHLEdBQUcsQ0FBQyxNQUFNLENBQUMsRUFBRSxDQUFDO0lBRXpCLElBQUksQ0FBQztRQUNILElBQUksTUFBTSxHQUFRLElBQUksQ0FBQztRQUN2Qiw0QkFBNEI7UUFDNUIsSUFBSSxDQUFDO1lBQ0gsTUFBTSxHQUFHLE1BQU0sZUFBZSxDQUFDLHNCQUFzQixDQUFDLEVBQUUsQ0FBQyxDQUFDO1FBQzVELENBQUM7UUFBQyxPQUFPLENBQUMsRUFBRSxDQUFDO1lBQ1gsTUFBTSxPQUFPLEdBQUcsTUFBTSxlQUFlLENBQUMsbUJBQW1CLENBQUMsRUFBRSxVQUFVLEVBQUUsRUFBRSxFQUFFLENBQUMsQ0FBQztZQUM5RSxJQUFJLE9BQU8sSUFBSSxPQUFPLENBQUMsTUFBTSxHQUFHLENBQUMsRUFBRSxDQUFDO2dCQUNsQyxNQUFNLEdBQUcsT0FBTyxDQUFDLENBQUMsQ0FBQyxDQUFDO1lBQ3RCLENBQUM7UUFDSCxDQUFDO1FBRUQsSUFBSSxDQUFDLE1BQU0sRUFBRSxDQUFDO1lBQ1osT0FBTyxHQUFHLENBQUMsTUFBTSxDQUFDLEdBQUcsQ0FBQyxDQUFDLElBQUksQ0FBQyxvQkFBb0IsQ0FBQyxDQUFDO1FBQ3BELENBQUM7UUFFRCxNQUFNLFNBQVMsR0FBRyxNQUFNLGVBQWUsQ0FBQyxlQUFlLENBQUMsTUFBTSxDQUFDLEVBQUUsRUFBRSxHQUFHLENBQUMsS0FBSyxDQUFDLENBQUM7UUFFOUUsR0FBRyxDQUFDLFNBQVMsQ0FBQyxjQUFjLEVBQUUsaUJBQWlCLENBQUMsQ0FBQztRQUNqRCxHQUFHLENBQUMsU0FBUyxDQUFDLHFCQUFxQixFQUFFLHFCQUFxQixNQUFNLENBQUMsVUFBVSxPQUFPLENBQUMsQ0FBQztRQUNwRixHQUFHLENBQUMsU0FBUyxDQUFDLGdCQUFnQixFQUFFLE1BQU0sQ0FBQyxTQUFTLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQztRQUMxRCxHQUFHLENBQUMsU0FBUyxDQUFDLGVBQWUsRUFBRSxxQ0FBcUMsQ0FBQyxDQUFDO1FBQ3RFLE9BQU8sR0FBRyxDQUFDLElBQUksQ0FBQyxTQUFTLENBQUMsQ0FBQztJQUM3QixDQUFDO0lBQUMsT0FBTyxHQUFRLEVBQUUsQ0FBQztRQUNsQixHQUFHLENBQUMsS0FBSyxDQUFDLE9BQU8sQ0FBQyxRQUFRLENBQUMsRUFBRSxLQUFLLENBQUMsd0NBQXdDLEdBQUcsQ0FBQyxPQUFPLEVBQUUsQ0FBQyxDQUFDO1FBQzFGLE9BQU8sR0FBRyxDQUFDLE1BQU0sQ0FBQyxHQUFHLENBQUMsQ0FBQyxJQUFJLENBQUMsZ0NBQWdDLEdBQUcsQ0FBQyxPQUFPLEVBQUUsQ0FBQyxDQUFDO0lBQzdFLENBQUM7QUFDSCxDQUFDIn0=
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.POST = POST;
|
|
4
|
+
const documents_1 = require("../../../../../modules/documents");
|
|
5
|
+
const notification_sender_1 = require("../../../../../services/notification-sender");
|
|
6
|
+
// POST /admin/documents/:id/send
|
|
7
|
+
async function POST(req, res) {
|
|
8
|
+
const documentService = req.scope.resolve(documents_1.DOCUMENTS_MODULE);
|
|
9
|
+
const id = req.params.id;
|
|
10
|
+
const { channels, custom_message, subject } = req.body;
|
|
11
|
+
const record = await documentService.retrieveDocumentRecord(id);
|
|
12
|
+
const settings = await documentService.getSettings();
|
|
13
|
+
const dispatchResult = await notification_sender_1.NotificationSender.send({
|
|
14
|
+
container: req.scope,
|
|
15
|
+
document: {
|
|
16
|
+
id: record.id,
|
|
17
|
+
display_id: record.display_id,
|
|
18
|
+
title: record.title,
|
|
19
|
+
type: record.type,
|
|
20
|
+
customer_name: record.customer_name,
|
|
21
|
+
customer_email: record.customer_email,
|
|
22
|
+
customer_phone: record.customer_phone,
|
|
23
|
+
total_amount: record.total_amount,
|
|
24
|
+
currency_code: record.currency_code,
|
|
25
|
+
payment_status: record.payment_status,
|
|
26
|
+
payment_link: record.payment_link,
|
|
27
|
+
short_payment_link: record.short_payment_link,
|
|
28
|
+
pdf_url: record.pdf_url,
|
|
29
|
+
short_pdf_link: record.short_pdf_link,
|
|
30
|
+
custom_message,
|
|
31
|
+
subject,
|
|
32
|
+
},
|
|
33
|
+
channels: channels || ["email"],
|
|
34
|
+
settings,
|
|
35
|
+
});
|
|
36
|
+
res.json({
|
|
37
|
+
success: true,
|
|
38
|
+
result: dispatchResult,
|
|
39
|
+
});
|
|
40
|
+
}
|
|
41
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicm91dGUuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi8uLi8uLi9zcmMvYXBpL2FkbWluL2RvY3VtZW50cy9baWRdL3NlbmQvcm91dGUudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7QUFNQSxvQkFvQ0M7QUF6Q0QsZ0VBQW9FO0FBRXBFLHFGQUFpRjtBQUVqRixpQ0FBaUM7QUFDMUIsS0FBSyxVQUFVLElBQUksQ0FBQyxHQUFrQyxFQUFFLEdBQW1CO0lBQ2hGLE1BQU0sZUFBZSxHQUEwQixHQUFHLENBQUMsS0FBSyxDQUFDLE9BQU8sQ0FBQyw0QkFBZ0IsQ0FBQyxDQUFDO0lBQ25GLE1BQU0sRUFBRSxHQUFHLEdBQUcsQ0FBQyxNQUFNLENBQUMsRUFBRSxDQUFDO0lBQ3pCLE1BQU0sRUFBRSxRQUFRLEVBQUUsY0FBYyxFQUFFLE9BQU8sRUFBRSxHQUFHLEdBQUcsQ0FBQyxJQUFXLENBQUM7SUFFOUQsTUFBTSxNQUFNLEdBQUcsTUFBTSxlQUFlLENBQUMsc0JBQXNCLENBQUMsRUFBRSxDQUFDLENBQUM7SUFDaEUsTUFBTSxRQUFRLEdBQUcsTUFBTSxlQUFlLENBQUMsV0FBVyxFQUFFLENBQUM7SUFFckQsTUFBTSxjQUFjLEdBQUcsTUFBTSx3Q0FBa0IsQ0FBQyxJQUFJLENBQUM7UUFDbkQsU0FBUyxFQUFFLEdBQUcsQ0FBQyxLQUFLO1FBQ3BCLFFBQVEsRUFBRTtZQUNSLEVBQUUsRUFBRSxNQUFNLENBQUMsRUFBRTtZQUNiLFVBQVUsRUFBRSxNQUFNLENBQUMsVUFBVTtZQUM3QixLQUFLLEVBQUUsTUFBTSxDQUFDLEtBQUs7WUFDbkIsSUFBSSxFQUFFLE1BQU0sQ0FBQyxJQUFJO1lBQ2pCLGFBQWEsRUFBRSxNQUFNLENBQUMsYUFBYTtZQUNuQyxjQUFjLEVBQUUsTUFBTSxDQUFDLGNBQWM7WUFDckMsY0FBYyxFQUFFLE1BQU0sQ0FBQyxjQUFjO1lBQ3JDLFlBQVksRUFBRSxNQUFNLENBQUMsWUFBWTtZQUNqQyxhQUFhLEVBQUUsTUFBTSxDQUFDLGFBQWE7WUFDbkMsY0FBYyxFQUFFLE1BQU0sQ0FBQyxjQUFjO1lBQ3JDLFlBQVksRUFBRSxNQUFNLENBQUMsWUFBWTtZQUNqQyxrQkFBa0IsRUFBRSxNQUFNLENBQUMsa0JBQWtCO1lBQzdDLE9BQU8sRUFBRSxNQUFNLENBQUMsT0FBTztZQUN2QixjQUFjLEVBQUUsTUFBTSxDQUFDLGNBQWM7WUFDckMsY0FBYztZQUNkLE9BQU87U0FDUjtRQUNELFFBQVEsRUFBRSxRQUFRLElBQUksQ0FBQyxPQUFPLENBQUM7UUFDL0IsUUFBUTtLQUNULENBQUMsQ0FBQztJQUVILEdBQUcsQ0FBQyxJQUFJLENBQUM7UUFDUCxPQUFPLEVBQUUsSUFBSTtRQUNiLE1BQU0sRUFBRSxjQUFjO0tBQ3ZCLENBQUMsQ0FBQztBQUNMLENBQUMifQ==
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.POST = POST;
|
|
4
|
+
const documents_1 = require("../../../../../modules/documents");
|
|
5
|
+
const zoho_books_1 = require("../../../../../services/zoho-books");
|
|
6
|
+
// POST /admin/documents/:id/sync-zoho
|
|
7
|
+
async function POST(req, res) {
|
|
8
|
+
const documentService = req.scope.resolve(documents_1.DOCUMENTS_MODULE);
|
|
9
|
+
const id = req.params.id;
|
|
10
|
+
const record = await documentService.retrieveDocumentRecord(id);
|
|
11
|
+
const settings = await documentService.getSettings();
|
|
12
|
+
if (!settings.zoho_books_enabled || !settings.zoho_client_id) {
|
|
13
|
+
return res.status(400).json({
|
|
14
|
+
message: "Zoho Books integration is not enabled or credentials are missing.",
|
|
15
|
+
});
|
|
16
|
+
}
|
|
17
|
+
const zoho = new zoho_books_1.ZohoBooksService({
|
|
18
|
+
client_id: settings.zoho_client_id,
|
|
19
|
+
client_secret: settings.zoho_client_secret,
|
|
20
|
+
refresh_token: settings.zoho_refresh_token,
|
|
21
|
+
organization_id: settings.zoho_organization_id,
|
|
22
|
+
domain: settings.zoho_domain || "com",
|
|
23
|
+
}, req.scope.resolve("logger"));
|
|
24
|
+
// 1. Sync contact
|
|
25
|
+
const contactId = await zoho.syncContact({
|
|
26
|
+
first_name: record.customer_name || "Customer",
|
|
27
|
+
email: record.customer_email || undefined,
|
|
28
|
+
phone: record.customer_phone || undefined,
|
|
29
|
+
});
|
|
30
|
+
const meta = (record.metadata || {});
|
|
31
|
+
const items = (meta.items || []).map((it) => ({
|
|
32
|
+
name: it.title,
|
|
33
|
+
description: it.description || "",
|
|
34
|
+
rate: Number(it.unit_price || 0).toFixed(2),
|
|
35
|
+
quantity: it.quantity || 1,
|
|
36
|
+
}));
|
|
37
|
+
let zohoDocId;
|
|
38
|
+
if (record.type === "estimate") {
|
|
39
|
+
const est = await zoho.createEstimate(contactId, {
|
|
40
|
+
reference_number: record.display_id,
|
|
41
|
+
line_items: items,
|
|
42
|
+
notes: meta.notes || settings.zoho_invoice_notes,
|
|
43
|
+
});
|
|
44
|
+
zohoDocId = est.estimate_id;
|
|
45
|
+
}
|
|
46
|
+
else {
|
|
47
|
+
const inv = await zoho.createInvoice(contactId, {
|
|
48
|
+
reference_number: record.display_id,
|
|
49
|
+
line_items: items,
|
|
50
|
+
notes: meta.notes || settings.zoho_invoice_notes,
|
|
51
|
+
terms: settings.zoho_invoice_terms,
|
|
52
|
+
payment_terms: settings.zoho_payment_terms_days,
|
|
53
|
+
is_inclusive_tax: settings.zoho_tax_inclusive,
|
|
54
|
+
});
|
|
55
|
+
zohoDocId = inv.invoice_id;
|
|
56
|
+
}
|
|
57
|
+
const updated = await documentService.updateDocumentRecords({
|
|
58
|
+
id: record.id,
|
|
59
|
+
source: "zoho",
|
|
60
|
+
zoho_document_id: zohoDocId,
|
|
61
|
+
});
|
|
62
|
+
res.json({
|
|
63
|
+
document: updated,
|
|
64
|
+
zoho_document_id: zohoDocId,
|
|
65
|
+
success: true,
|
|
66
|
+
});
|
|
67
|
+
}
|
|
68
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicm91dGUuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi8uLi8uLi9zcmMvYXBpL2FkbWluL2RvY3VtZW50cy9baWRdL3N5bmMtem9oby9yb3V0ZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOztBQU1BLG9CQXNFQztBQTNFRCxnRUFBb0U7QUFFcEUsbUVBQXNFO0FBRXRFLHNDQUFzQztBQUMvQixLQUFLLFVBQVUsSUFBSSxDQUFDLEdBQWtDLEVBQUUsR0FBbUI7SUFDaEYsTUFBTSxlQUFlLEdBQTBCLEdBQUcsQ0FBQyxLQUFLLENBQUMsT0FBTyxDQUFDLDRCQUFnQixDQUFDLENBQUM7SUFDbkYsTUFBTSxFQUFFLEdBQUcsR0FBRyxDQUFDLE1BQU0sQ0FBQyxFQUFFLENBQUM7SUFFekIsTUFBTSxNQUFNLEdBQUcsTUFBTSxlQUFlLENBQUMsc0JBQXNCLENBQUMsRUFBRSxDQUFDLENBQUM7SUFDaEUsTUFBTSxRQUFRLEdBQUcsTUFBTSxlQUFlLENBQUMsV0FBVyxFQUFFLENBQUM7SUFFckQsSUFBSSxDQUFDLFFBQVEsQ0FBQyxrQkFBa0IsSUFBSSxDQUFDLFFBQVEsQ0FBQyxjQUFjLEVBQUUsQ0FBQztRQUM3RCxPQUFPLEdBQUcsQ0FBQyxNQUFNLENBQUMsR0FBRyxDQUFDLENBQUMsSUFBSSxDQUFDO1lBQzFCLE9BQU8sRUFBRSxtRUFBbUU7U0FDN0UsQ0FBQyxDQUFDO0lBQ0wsQ0FBQztJQUVELE1BQU0sSUFBSSxHQUFHLElBQUksNkJBQWdCLENBQy9CO1FBQ0UsU0FBUyxFQUFFLFFBQVEsQ0FBQyxjQUFjO1FBQ2xDLGFBQWEsRUFBRSxRQUFRLENBQUMsa0JBQWtCO1FBQzFDLGFBQWEsRUFBRSxRQUFRLENBQUMsa0JBQWtCO1FBQzFDLGVBQWUsRUFBRSxRQUFRLENBQUMsb0JBQW9CO1FBQzlDLE1BQU0sRUFBRSxRQUFRLENBQUMsV0FBVyxJQUFJLEtBQUs7S0FDdEMsRUFDRCxHQUFHLENBQUMsS0FBSyxDQUFDLE9BQU8sQ0FBQyxRQUFRLENBQUMsQ0FDNUIsQ0FBQztJQUVGLGtCQUFrQjtJQUNsQixNQUFNLFNBQVMsR0FBRyxNQUFNLElBQUksQ0FBQyxXQUFXLENBQUM7UUFDdkMsVUFBVSxFQUFFLE1BQU0sQ0FBQyxhQUFhLElBQUksVUFBVTtRQUM5QyxLQUFLLEVBQUUsTUFBTSxDQUFDLGNBQWMsSUFBSSxTQUFTO1FBQ3pDLEtBQUssRUFBRSxNQUFNLENBQUMsY0FBYyxJQUFJLFNBQVM7S0FDMUMsQ0FBQyxDQUFDO0lBRUgsTUFBTSxJQUFJLEdBQUcsQ0FBQyxNQUFNLENBQUMsUUFBUSxJQUFJLEVBQUUsQ0FBUSxDQUFDO0lBQzVDLE1BQU0sS0FBSyxHQUFHLENBQUMsSUFBSSxDQUFDLEtBQUssSUFBSSxFQUFFLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxFQUFPLEVBQUUsRUFBRSxDQUFDLENBQUM7UUFDakQsSUFBSSxFQUFFLEVBQUUsQ0FBQyxLQUFLO1FBQ2QsV0FBVyxFQUFFLEVBQUUsQ0FBQyxXQUFXLElBQUksRUFBRTtRQUNqQyxJQUFJLEVBQUUsTUFBTSxDQUFDLEVBQUUsQ0FBQyxVQUFVLElBQUksQ0FBQyxDQUFDLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQztRQUMzQyxRQUFRLEVBQUUsRUFBRSxDQUFDLFFBQVEsSUFBSSxDQUFDO0tBQzNCLENBQUMsQ0FBQyxDQUFDO0lBRUosSUFBSSxTQUFpQixDQUFDO0lBQ3RCLElBQUksTUFBTSxDQUFDLElBQUksS0FBSyxVQUFVLEVBQUUsQ0FBQztRQUMvQixNQUFNLEdBQUcsR0FBRyxNQUFNLElBQUksQ0FBQyxjQUFjLENBQUMsU0FBUyxFQUFFO1lBQy9DLGdCQUFnQixFQUFFLE1BQU0sQ0FBQyxVQUFVO1lBQ25DLFVBQVUsRUFBRSxLQUFLO1lBQ2pCLEtBQUssRUFBRSxJQUFJLENBQUMsS0FBSyxJQUFJLFFBQVEsQ0FBQyxrQkFBa0I7U0FDakQsQ0FBQyxDQUFDO1FBQ0gsU0FBUyxHQUFHLEdBQUcsQ0FBQyxXQUFXLENBQUM7SUFDOUIsQ0FBQztTQUFNLENBQUM7UUFDTixNQUFNLEdBQUcsR0FBRyxNQUFNLElBQUksQ0FBQyxhQUFhLENBQUMsU0FBUyxFQUFFO1lBQzlDLGdCQUFnQixFQUFFLE1BQU0sQ0FBQyxVQUFVO1lBQ25DLFVBQVUsRUFBRSxLQUFLO1lBQ2pCLEtBQUssRUFBRSxJQUFJLENBQUMsS0FBSyxJQUFJLFFBQVEsQ0FBQyxrQkFBa0I7WUFDaEQsS0FBSyxFQUFFLFFBQVEsQ0FBQyxrQkFBa0I7WUFDbEMsYUFBYSxFQUFFLFFBQVEsQ0FBQyx1QkFBdUI7WUFDL0MsZ0JBQWdCLEVBQUUsUUFBUSxDQUFDLGtCQUFrQjtTQUM5QyxDQUFDLENBQUM7UUFDSCxTQUFTLEdBQUcsR0FBRyxDQUFDLFVBQVUsQ0FBQztJQUM3QixDQUFDO0lBRUQsTUFBTSxPQUFPLEdBQUcsTUFBTSxlQUFlLENBQUMscUJBQXFCLENBQUM7UUFDMUQsRUFBRSxFQUFFLE1BQU0sQ0FBQyxFQUFFO1FBQ2IsTUFBTSxFQUFFLE1BQU07UUFDZCxnQkFBZ0IsRUFBRSxTQUFTO0tBQzVCLENBQUMsQ0FBQztJQUVILEdBQUcsQ0FBQyxJQUFJLENBQUM7UUFDUCxRQUFRLEVBQUUsT0FBTztRQUNqQixnQkFBZ0IsRUFBRSxTQUFTO1FBQzNCLE9BQU8sRUFBRSxJQUFJO0tBQ2QsQ0FBQyxDQUFDO0FBQ0wsQ0FBQyJ9
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.POST = POST;
|
|
4
|
+
const documents_1 = require("../../../../modules/documents");
|
|
5
|
+
// POST /admin/documents/custom
|
|
6
|
+
async function POST(req, res) {
|
|
7
|
+
try {
|
|
8
|
+
const documentService = req.scope.resolve(documents_1.DOCUMENTS_MODULE);
|
|
9
|
+
const { title = "Custom Document", customer, body_text, items = [], total = 0, currency_code = "usd", notes, custom_fields, send_email_now = true, email_subject, custom_email_message, } = req.body || {};
|
|
10
|
+
let computedTotal = Number(total || 0);
|
|
11
|
+
if (items.length > 0 && computedTotal === 0) {
|
|
12
|
+
for (const item of items) {
|
|
13
|
+
computedTotal += Number(item.quantity || 1) * Number(item.unit_price || 0);
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
const result = await documentService.generateDocument({
|
|
17
|
+
title: title,
|
|
18
|
+
type: "custom",
|
|
19
|
+
customer: {
|
|
20
|
+
name: customer?.name || "Customer",
|
|
21
|
+
email: customer?.email,
|
|
22
|
+
phone: customer?.phone,
|
|
23
|
+
address: customer?.address,
|
|
24
|
+
},
|
|
25
|
+
items,
|
|
26
|
+
total: computedTotal,
|
|
27
|
+
currency_code,
|
|
28
|
+
body_text,
|
|
29
|
+
notes,
|
|
30
|
+
custom_fields,
|
|
31
|
+
force_source: "pdfkit",
|
|
32
|
+
auto_send: send_email_now,
|
|
33
|
+
notification_channels: ["email"],
|
|
34
|
+
email_subject: email_subject || `${title} from ${req.body?.company_name || "Store"}`,
|
|
35
|
+
custom_email_message: custom_email_message || body_text,
|
|
36
|
+
}, req.scope);
|
|
37
|
+
return res.json({
|
|
38
|
+
document: result.record,
|
|
39
|
+
sent_via_email: send_email_now,
|
|
40
|
+
success: true,
|
|
41
|
+
});
|
|
42
|
+
}
|
|
43
|
+
catch (err) {
|
|
44
|
+
req.scope.resolve("logger")?.error(`[Documents-API] Error generating custom document: ${err.message}`);
|
|
45
|
+
return res.status(500).json({ message: err.message, success: false });
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicm91dGUuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi8uLi9zcmMvYXBpL2FkbWluL2RvY3VtZW50cy9jdXN0b20vcm91dGUudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7QUFLQSxvQkEyREM7QUEvREQsNkRBQWlFO0FBR2pFLCtCQUErQjtBQUN4QixLQUFLLFVBQVUsSUFBSSxDQUFDLEdBQXVCLEVBQUUsR0FBbUI7SUFDckUsSUFBSSxDQUFDO1FBQ0gsTUFBTSxlQUFlLEdBQTBCLEdBQUcsQ0FBQyxLQUFLLENBQUMsT0FBTyxDQUFDLDRCQUFnQixDQUFDLENBQUM7UUFFbkYsTUFBTSxFQUNKLEtBQUssR0FBRyxpQkFBaUIsRUFDekIsUUFBUSxFQUNSLFNBQVMsRUFDVCxLQUFLLEdBQUcsRUFBRSxFQUNWLEtBQUssR0FBRyxDQUFDLEVBQ1QsYUFBYSxHQUFHLEtBQUssRUFDckIsS0FBSyxFQUNMLGFBQWEsRUFDYixjQUFjLEdBQUcsSUFBSSxFQUNyQixhQUFhLEVBQ2Isb0JBQW9CLEdBQ3JCLEdBQUcsR0FBRyxDQUFDLElBQUksSUFBSSxFQUFFLENBQUM7UUFFbkIsSUFBSSxhQUFhLEdBQUcsTUFBTSxDQUFDLEtBQUssSUFBSSxDQUFDLENBQUMsQ0FBQztRQUN2QyxJQUFJLEtBQUssQ0FBQyxNQUFNLEdBQUcsQ0FBQyxJQUFJLGFBQWEsS0FBSyxDQUFDLEVBQUUsQ0FBQztZQUM1QyxLQUFLLE1BQU0sSUFBSSxJQUFJLEtBQUssRUFBRSxDQUFDO2dCQUN6QixhQUFhLElBQUksTUFBTSxDQUFDLElBQUksQ0FBQyxRQUFRLElBQUksQ0FBQyxDQUFDLEdBQUcsTUFBTSxDQUFDLElBQUksQ0FBQyxVQUFVLElBQUksQ0FBQyxDQUFDLENBQUM7WUFDN0UsQ0FBQztRQUNILENBQUM7UUFFRCxNQUFNLE1BQU0sR0FBRyxNQUFNLGVBQWUsQ0FBQyxnQkFBZ0IsQ0FDbkQ7WUFDRSxLQUFLLEVBQUUsS0FBSztZQUNaLElBQUksRUFBRSxRQUFRO1lBQ2QsUUFBUSxFQUFFO2dCQUNSLElBQUksRUFBRSxRQUFRLEVBQUUsSUFBSSxJQUFJLFVBQVU7Z0JBQ2xDLEtBQUssRUFBRSxRQUFRLEVBQUUsS0FBSztnQkFDdEIsS0FBSyxFQUFFLFFBQVEsRUFBRSxLQUFLO2dCQUN0QixPQUFPLEVBQUUsUUFBUSxFQUFFLE9BQU87YUFDM0I7WUFDRCxLQUFLO1lBQ0wsS0FBSyxFQUFFLGFBQWE7WUFDcEIsYUFBYTtZQUNiLFNBQVM7WUFDVCxLQUFLO1lBQ0wsYUFBYTtZQUNiLFlBQVksRUFBRSxRQUFRO1lBQ3RCLFNBQVMsRUFBRSxjQUFjO1lBQ3pCLHFCQUFxQixFQUFFLENBQUMsT0FBTyxDQUFDO1lBQ2hDLGFBQWEsRUFBRSxhQUFhLElBQUksR0FBRyxLQUFLLFNBQVMsR0FBRyxDQUFDLElBQUksRUFBRSxZQUFZLElBQUksT0FBTyxFQUFFO1lBQ3BGLG9CQUFvQixFQUFFLG9CQUFvQixJQUFJLFNBQVM7U0FDeEQsRUFDRCxHQUFHLENBQUMsS0FBSyxDQUNWLENBQUM7UUFFRixPQUFPLEdBQUcsQ0FBQyxJQUFJLENBQUM7WUFDZCxRQUFRLEVBQUUsTUFBTSxDQUFDLE1BQU07WUFDdkIsY0FBYyxFQUFFLGNBQWM7WUFDOUIsT0FBTyxFQUFFLElBQUk7U0FDZCxDQUFDLENBQUM7SUFDTCxDQUFDO0lBQUMsT0FBTyxHQUFRLEVBQUUsQ0FBQztRQUNsQixHQUFHLENBQUMsS0FBSyxDQUFDLE9BQU8sQ0FBQyxRQUFRLENBQUMsRUFBRSxLQUFLLENBQUMscURBQXFELEdBQUcsQ0FBQyxPQUFPLEVBQUUsQ0FBQyxDQUFDO1FBQ3ZHLE9BQU8sR0FBRyxDQUFDLE1BQU0sQ0FBQyxHQUFHLENBQUMsQ0FBQyxJQUFJLENBQUMsRUFBRSxPQUFPLEVBQUUsR0FBRyxDQUFDLE9BQU8sRUFBRSxPQUFPLEVBQUUsS0FBSyxFQUFFLENBQUMsQ0FBQztJQUN4RSxDQUFDO0FBQ0gsQ0FBQyJ9
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.POST = POST;
|
|
4
|
+
const documents_1 = require("../../../../modules/documents");
|
|
5
|
+
// POST /admin/documents/manual
|
|
6
|
+
async function POST(req, res) {
|
|
7
|
+
try {
|
|
8
|
+
const documentService = req.scope.resolve(documents_1.DOCUMENTS_MODULE);
|
|
9
|
+
const { display_id, title, type = "invoice", customer, items = [], currency_code = "usd", notes, terms, force_source, auto_send = false, send_email_now = false, notification_channels, email_subject, custom_email_message, } = req.body || {};
|
|
10
|
+
let total = 0;
|
|
11
|
+
for (const item of items) {
|
|
12
|
+
const qty = Number(item.quantity || 1);
|
|
13
|
+
const rate = Number(item.unit_price || 0);
|
|
14
|
+
total += qty * rate;
|
|
15
|
+
}
|
|
16
|
+
const result = await documentService.generateDocument({
|
|
17
|
+
display_id,
|
|
18
|
+
title: title || (type === "invoice" ? "Tax Invoice" : "Quotation"),
|
|
19
|
+
type: type,
|
|
20
|
+
customer: {
|
|
21
|
+
name: customer?.name || "Customer",
|
|
22
|
+
email: customer?.email,
|
|
23
|
+
phone: customer?.phone,
|
|
24
|
+
address: customer?.address,
|
|
25
|
+
},
|
|
26
|
+
items,
|
|
27
|
+
total,
|
|
28
|
+
currency_code,
|
|
29
|
+
notes,
|
|
30
|
+
force_source,
|
|
31
|
+
auto_send: auto_send || send_email_now,
|
|
32
|
+
notification_channels,
|
|
33
|
+
email_subject,
|
|
34
|
+
custom_email_message,
|
|
35
|
+
}, req.scope);
|
|
36
|
+
return res.json({
|
|
37
|
+
document: result.record,
|
|
38
|
+
success: true,
|
|
39
|
+
});
|
|
40
|
+
}
|
|
41
|
+
catch (err) {
|
|
42
|
+
req.scope.resolve("logger")?.error(`[Documents-API] Error creating manual document: ${err.message}`);
|
|
43
|
+
return res.status(500).json({ message: err.message, success: false });
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicm91dGUuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi8uLi9zcmMvYXBpL2FkbWluL2RvY3VtZW50cy9tYW51YWwvcm91dGUudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7QUFLQSxvQkE0REM7QUFoRUQsNkRBQWlFO0FBR2pFLCtCQUErQjtBQUN4QixLQUFLLFVBQVUsSUFBSSxDQUFDLEdBQXVCLEVBQUUsR0FBbUI7SUFDckUsSUFBSSxDQUFDO1FBQ0gsTUFBTSxlQUFlLEdBQTBCLEdBQUcsQ0FBQyxLQUFLLENBQUMsT0FBTyxDQUFDLDRCQUFnQixDQUFDLENBQUM7UUFFbkYsTUFBTSxFQUNKLFVBQVUsRUFDVixLQUFLLEVBQ0wsSUFBSSxHQUFHLFNBQVMsRUFDaEIsUUFBUSxFQUNSLEtBQUssR0FBRyxFQUFFLEVBQ1YsYUFBYSxHQUFHLEtBQUssRUFDckIsS0FBSyxFQUNMLEtBQUssRUFDTCxZQUFZLEVBQ1osU0FBUyxHQUFHLEtBQUssRUFDakIsY0FBYyxHQUFHLEtBQUssRUFDdEIscUJBQXFCLEVBQ3JCLGFBQWEsRUFDYixvQkFBb0IsR0FDckIsR0FBRyxHQUFHLENBQUMsSUFBSSxJQUFJLEVBQUUsQ0FBQztRQUVuQixJQUFJLEtBQUssR0FBRyxDQUFDLENBQUM7UUFDZCxLQUFLLE1BQU0sSUFBSSxJQUFJLEtBQUssRUFBRSxDQUFDO1lBQ3pCLE1BQU0sR0FBRyxHQUFHLE1BQU0sQ0FBQyxJQUFJLENBQUMsUUFBUSxJQUFJLENBQUMsQ0FBQyxDQUFDO1lBQ3ZDLE1BQU0sSUFBSSxHQUFHLE1BQU0sQ0FBQyxJQUFJLENBQUMsVUFBVSxJQUFJLENBQUMsQ0FBQyxDQUFDO1lBQzFDLEtBQUssSUFBSSxHQUFHLEdBQUcsSUFBSSxDQUFDO1FBQ3RCLENBQUM7UUFFRCxNQUFNLE1BQU0sR0FBRyxNQUFNLGVBQWUsQ0FBQyxnQkFBZ0IsQ0FDbkQ7WUFDRSxVQUFVO1lBQ1YsS0FBSyxFQUFFLEtBQUssSUFBSSxDQUFDLElBQUksS0FBSyxTQUFTLENBQUMsQ0FBQyxDQUFDLGFBQWEsQ0FBQyxDQUFDLENBQUMsV0FBVyxDQUFDO1lBQ2xFLElBQUksRUFBRSxJQUFXO1lBQ2pCLFFBQVEsRUFBRTtnQkFDUixJQUFJLEVBQUUsUUFBUSxFQUFFLElBQUksSUFBSSxVQUFVO2dCQUNsQyxLQUFLLEVBQUUsUUFBUSxFQUFFLEtBQUs7Z0JBQ3RCLEtBQUssRUFBRSxRQUFRLEVBQUUsS0FBSztnQkFDdEIsT0FBTyxFQUFFLFFBQVEsRUFBRSxPQUFPO2FBQzNCO1lBQ0QsS0FBSztZQUNMLEtBQUs7WUFDTCxhQUFhO1lBQ2IsS0FBSztZQUNMLFlBQVk7WUFDWixTQUFTLEVBQUUsU0FBUyxJQUFJLGNBQWM7WUFDdEMscUJBQXFCO1lBQ3JCLGFBQWE7WUFDYixvQkFBb0I7U0FDckIsRUFDRCxHQUFHLENBQUMsS0FBSyxDQUNWLENBQUM7UUFFRixPQUFPLEdBQUcsQ0FBQyxJQUFJLENBQUM7WUFDZCxRQUFRLEVBQUUsTUFBTSxDQUFDLE1BQU07WUFDdkIsT0FBTyxFQUFFLElBQUk7U0FDZCxDQUFDLENBQUM7SUFDTCxDQUFDO0lBQUMsT0FBTyxHQUFRLEVBQUUsQ0FBQztRQUNsQixHQUFHLENBQUMsS0FBSyxDQUFDLE9BQU8sQ0FBQyxRQUFRLENBQUMsRUFBRSxLQUFLLENBQUMsbURBQW1ELEdBQUcsQ0FBQyxPQUFPLEVBQUUsQ0FBQyxDQUFDO1FBQ3JHLE9BQU8sR0FBRyxDQUFDLE1BQU0sQ0FBQyxHQUFHLENBQUMsQ0FBQyxJQUFJLENBQUMsRUFBRSxPQUFPLEVBQUUsR0FBRyxDQUFDLE9BQU8sRUFBRSxPQUFPLEVBQUUsS0FBSyxFQUFFLENBQUMsQ0FBQztJQUN4RSxDQUFDO0FBQ0gsQ0FBQyJ9
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.GET = GET;
|
|
4
|
+
const documents_1 = require("../../../modules/documents");
|
|
5
|
+
// GET /admin/documents
|
|
6
|
+
async function GET(req, res) {
|
|
7
|
+
const documentService = req.scope.resolve(documents_1.DOCUMENTS_MODULE);
|
|
8
|
+
const { type, source, status, search, take = 50, skip = 0 } = req.query;
|
|
9
|
+
const filters = {};
|
|
10
|
+
if (type && type !== "all")
|
|
11
|
+
filters.type = type;
|
|
12
|
+
if (source && source !== "all")
|
|
13
|
+
filters.source = source;
|
|
14
|
+
if (status && status !== "all")
|
|
15
|
+
filters.status = status;
|
|
16
|
+
const [records, count] = await documentService.listAndCountDocumentRecords(filters, {
|
|
17
|
+
take: Number(take),
|
|
18
|
+
skip: Number(skip),
|
|
19
|
+
order: { created_at: "DESC" },
|
|
20
|
+
});
|
|
21
|
+
let filteredRecords = records;
|
|
22
|
+
if (search && typeof search === "string" && search.trim() !== "") {
|
|
23
|
+
const q = search.toLowerCase();
|
|
24
|
+
filteredRecords = records.filter((r) => r.display_id?.toLowerCase().includes(q) ||
|
|
25
|
+
r.customer_name?.toLowerCase().includes(q) ||
|
|
26
|
+
r.customer_email?.toLowerCase().includes(q) ||
|
|
27
|
+
r.title?.toLowerCase().includes(q));
|
|
28
|
+
}
|
|
29
|
+
res.json({
|
|
30
|
+
documents: filteredRecords,
|
|
31
|
+
count: count || filteredRecords.length,
|
|
32
|
+
take: Number(take),
|
|
33
|
+
skip: Number(skip),
|
|
34
|
+
});
|
|
35
|
+
}
|
|
36
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicm91dGUuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi9zcmMvYXBpL2FkbWluL2RvY3VtZW50cy9yb3V0ZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOztBQUtBLGtCQXFDQztBQXpDRCwwREFBOEQ7QUFHOUQsdUJBQXVCO0FBQ2hCLEtBQUssVUFBVSxHQUFHLENBQUMsR0FBa0IsRUFBRSxHQUFtQjtJQUMvRCxNQUFNLGVBQWUsR0FBMEIsR0FBRyxDQUFDLEtBQUssQ0FBQyxPQUFPLENBQUMsNEJBQWdCLENBQUMsQ0FBQztJQUVuRixNQUFNLEVBQUUsSUFBSSxFQUFFLE1BQU0sRUFBRSxNQUFNLEVBQUUsTUFBTSxFQUFFLElBQUksR0FBRyxFQUFFLEVBQUUsSUFBSSxHQUFHLENBQUMsRUFBRSxHQUFHLEdBQUcsQ0FBQyxLQUFZLENBQUM7SUFFL0UsTUFBTSxPQUFPLEdBQXdCLEVBQUUsQ0FBQztJQUN4QyxJQUFJLElBQUksSUFBSSxJQUFJLEtBQUssS0FBSztRQUFFLE9BQU8sQ0FBQyxJQUFJLEdBQUcsSUFBSSxDQUFDO0lBQ2hELElBQUksTUFBTSxJQUFJLE1BQU0sS0FBSyxLQUFLO1FBQUUsT0FBTyxDQUFDLE1BQU0sR0FBRyxNQUFNLENBQUM7SUFDeEQsSUFBSSxNQUFNLElBQUksTUFBTSxLQUFLLEtBQUs7UUFBRSxPQUFPLENBQUMsTUFBTSxHQUFHLE1BQU0sQ0FBQztJQUV4RCxNQUFNLENBQUMsT0FBTyxFQUFFLEtBQUssQ0FBQyxHQUFHLE1BQU0sZUFBZSxDQUFDLDJCQUEyQixDQUN4RSxPQUFPLEVBQ1A7UUFDRSxJQUFJLEVBQUUsTUFBTSxDQUFDLElBQUksQ0FBQztRQUNsQixJQUFJLEVBQUUsTUFBTSxDQUFDLElBQUksQ0FBQztRQUNsQixLQUFLLEVBQUUsRUFBRSxVQUFVLEVBQUUsTUFBTSxFQUFFO0tBQzlCLENBQ0YsQ0FBQztJQUVGLElBQUksZUFBZSxHQUFHLE9BQU8sQ0FBQztJQUM5QixJQUFJLE1BQU0sSUFBSSxPQUFPLE1BQU0sS0FBSyxRQUFRLElBQUksTUFBTSxDQUFDLElBQUksRUFBRSxLQUFLLEVBQUUsRUFBRSxDQUFDO1FBQ2pFLE1BQU0sQ0FBQyxHQUFHLE1BQU0sQ0FBQyxXQUFXLEVBQUUsQ0FBQztRQUMvQixlQUFlLEdBQUcsT0FBTyxDQUFDLE1BQU0sQ0FDOUIsQ0FBQyxDQUFNLEVBQUUsRUFBRSxDQUNULENBQUMsQ0FBQyxVQUFVLEVBQUUsV0FBVyxFQUFFLENBQUMsUUFBUSxDQUFDLENBQUMsQ0FBQztZQUN2QyxDQUFDLENBQUMsYUFBYSxFQUFFLFdBQVcsRUFBRSxDQUFDLFFBQVEsQ0FBQyxDQUFDLENBQUM7WUFDMUMsQ0FBQyxDQUFDLGNBQWMsRUFBRSxXQUFXLEVBQUUsQ0FBQyxRQUFRLENBQUMsQ0FBQyxDQUFDO1lBQzNDLENBQUMsQ0FBQyxLQUFLLEVBQUUsV0FBVyxFQUFFLENBQUMsUUFBUSxDQUFDLENBQUMsQ0FBQyxDQUNyQyxDQUFDO0lBQ0osQ0FBQztJQUVELEdBQUcsQ0FBQyxJQUFJLENBQUM7UUFDUCxTQUFTLEVBQUUsZUFBZTtRQUMxQixLQUFLLEVBQUUsS0FBSyxJQUFJLGVBQWUsQ0FBQyxNQUFNO1FBQ3RDLElBQUksRUFBRSxNQUFNLENBQUMsSUFBSSxDQUFDO1FBQ2xCLElBQUksRUFBRSxNQUFNLENBQUMsSUFBSSxDQUFDO0tBQ25CLENBQUMsQ0FBQztBQUNMLENBQUMifQ==
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.GET = GET;
|
|
4
|
+
exports.POST = POST;
|
|
5
|
+
const documents_1 = require("../../../../modules/documents");
|
|
6
|
+
// GET /admin/documents/settings
|
|
7
|
+
async function GET(req, res) {
|
|
8
|
+
try {
|
|
9
|
+
const documentService = req.scope.resolve(documents_1.DOCUMENTS_MODULE);
|
|
10
|
+
const settings = await documentService.getSettings();
|
|
11
|
+
return res.json({ settings, success: true });
|
|
12
|
+
}
|
|
13
|
+
catch (err) {
|
|
14
|
+
req.scope.resolve("logger")?.error(`[Documents-API] Error fetching settings: ${err.message}`);
|
|
15
|
+
return res.status(500).json({ message: err.message, error: true });
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
// POST /admin/documents/settings
|
|
19
|
+
async function POST(req, res) {
|
|
20
|
+
try {
|
|
21
|
+
const documentService = req.scope.resolve(documents_1.DOCUMENTS_MODULE);
|
|
22
|
+
let [settings] = await documentService.listDocumentSettings({});
|
|
23
|
+
// Filter out read-only / metadata columns that cause MikroORM update errors
|
|
24
|
+
const { id, created_at, updated_at, deleted_at, ...cleanData } = req.body || {};
|
|
25
|
+
if (cleanData.zoho_payment_terms_days !== undefined) {
|
|
26
|
+
cleanData.zoho_payment_terms_days = Number(cleanData.zoho_payment_terms_days || 0);
|
|
27
|
+
}
|
|
28
|
+
if (!settings) {
|
|
29
|
+
settings = await documentService.createDocumentSettings(cleanData);
|
|
30
|
+
}
|
|
31
|
+
else {
|
|
32
|
+
settings = await documentService.updateDocumentSettings({
|
|
33
|
+
id: settings.id,
|
|
34
|
+
...cleanData,
|
|
35
|
+
});
|
|
36
|
+
}
|
|
37
|
+
return res.json({ settings, success: true });
|
|
38
|
+
}
|
|
39
|
+
catch (err) {
|
|
40
|
+
req.scope.resolve("logger")?.error(`[Documents-API] Error updating settings: ${err.message}`);
|
|
41
|
+
return res.status(500).json({ message: err.message, error: true });
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicm91dGUuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi8uLi9zcmMvYXBpL2FkbWluL2RvY3VtZW50cy9zZXR0aW5ncy9yb3V0ZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOztBQUtBLGtCQVNDO0FBR0Qsb0JBMEJDO0FBMUNELDZEQUFpRTtBQUdqRSxnQ0FBZ0M7QUFDekIsS0FBSyxVQUFVLEdBQUcsQ0FBQyxHQUFrQixFQUFFLEdBQW1CO0lBQy9ELElBQUksQ0FBQztRQUNILE1BQU0sZUFBZSxHQUEwQixHQUFHLENBQUMsS0FBSyxDQUFDLE9BQU8sQ0FBQyw0QkFBZ0IsQ0FBQyxDQUFDO1FBQ25GLE1BQU0sUUFBUSxHQUFHLE1BQU0sZUFBZSxDQUFDLFdBQVcsRUFBRSxDQUFDO1FBQ3JELE9BQU8sR0FBRyxDQUFDLElBQUksQ0FBQyxFQUFFLFFBQVEsRUFBRSxPQUFPLEVBQUUsSUFBSSxFQUFFLENBQUMsQ0FBQztJQUMvQyxDQUFDO0lBQUMsT0FBTyxHQUFRLEVBQUUsQ0FBQztRQUNsQixHQUFHLENBQUMsS0FBSyxDQUFDLE9BQU8sQ0FBQyxRQUFRLENBQUMsRUFBRSxLQUFLLENBQUMsNENBQTRDLEdBQUcsQ0FBQyxPQUFPLEVBQUUsQ0FBQyxDQUFDO1FBQzlGLE9BQU8sR0FBRyxDQUFDLE1BQU0sQ0FBQyxHQUFHLENBQUMsQ0FBQyxJQUFJLENBQUMsRUFBRSxPQUFPLEVBQUUsR0FBRyxDQUFDLE9BQU8sRUFBRSxLQUFLLEVBQUUsSUFBSSxFQUFFLENBQUMsQ0FBQztJQUNyRSxDQUFDO0FBQ0gsQ0FBQztBQUVELGlDQUFpQztBQUMxQixLQUFLLFVBQVUsSUFBSSxDQUFDLEdBQXVCLEVBQUUsR0FBbUI7SUFDckUsSUFBSSxDQUFDO1FBQ0gsTUFBTSxlQUFlLEdBQTBCLEdBQUcsQ0FBQyxLQUFLLENBQUMsT0FBTyxDQUFDLDRCQUFnQixDQUFDLENBQUM7UUFDbkYsSUFBSSxDQUFDLFFBQVEsQ0FBQyxHQUFHLE1BQU0sZUFBZSxDQUFDLG9CQUFvQixDQUFDLEVBQUUsQ0FBQyxDQUFDO1FBRWhFLDRFQUE0RTtRQUM1RSxNQUFNLEVBQUUsRUFBRSxFQUFFLFVBQVUsRUFBRSxVQUFVLEVBQUUsVUFBVSxFQUFFLEdBQUcsU0FBUyxFQUFFLEdBQUcsR0FBRyxDQUFDLElBQUksSUFBSSxFQUFFLENBQUM7UUFFaEYsSUFBSSxTQUFTLENBQUMsdUJBQXVCLEtBQUssU0FBUyxFQUFFLENBQUM7WUFDcEQsU0FBUyxDQUFDLHVCQUF1QixHQUFHLE1BQU0sQ0FBQyxTQUFTLENBQUMsdUJBQXVCLElBQUksQ0FBQyxDQUFDLENBQUM7UUFDckYsQ0FBQztRQUVELElBQUksQ0FBQyxRQUFRLEVBQUUsQ0FBQztZQUNkLFFBQVEsR0FBRyxNQUFNLGVBQWUsQ0FBQyxzQkFBc0IsQ0FBQyxTQUFTLENBQUMsQ0FBQztRQUNyRSxDQUFDO2FBQU0sQ0FBQztZQUNOLFFBQVEsR0FBRyxNQUFNLGVBQWUsQ0FBQyxzQkFBc0IsQ0FBQztnQkFDdEQsRUFBRSxFQUFFLFFBQVEsQ0FBQyxFQUFFO2dCQUNmLEdBQUcsU0FBUzthQUNiLENBQUMsQ0FBQztRQUNMLENBQUM7UUFFRCxPQUFPLEdBQUcsQ0FBQyxJQUFJLENBQUMsRUFBRSxRQUFRLEVBQUUsT0FBTyxFQUFFLElBQUksRUFBRSxDQUFDLENBQUM7SUFDL0MsQ0FBQztJQUFDLE9BQU8sR0FBUSxFQUFFLENBQUM7UUFDbEIsR0FBRyxDQUFDLEtBQUssQ0FBQyxPQUFPLENBQUMsUUFBUSxDQUFDLEVBQUUsS0FBSyxDQUFDLDRDQUE0QyxHQUFHLENBQUMsT0FBTyxFQUFFLENBQUMsQ0FBQztRQUM5RixPQUFPLEdBQUcsQ0FBQyxNQUFNLENBQUMsR0FBRyxDQUFDLENBQUMsSUFBSSxDQUFDLEVBQUUsT0FBTyxFQUFFLEdBQUcsQ0FBQyxPQUFPLEVBQUUsS0FBSyxFQUFFLElBQUksRUFBRSxDQUFDLENBQUM7SUFDckUsQ0FBQztBQUNILENBQUMifQ==
|
|
@@ -0,0 +1,159 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.GET = GET;
|
|
4
|
+
const documents_1 = require("../../../../../modules/documents");
|
|
5
|
+
const pdfkit_generator_1 = require("../../../../../services/pdfkit-generator");
|
|
6
|
+
// GET /admin/documents/templates/preview?style=modern | classic | minimal&type=invoice | receipt | packing_slip | estimate | custom | job_card
|
|
7
|
+
async function GET(req, res) {
|
|
8
|
+
try {
|
|
9
|
+
const documentService = req.scope.resolve(documents_1.DOCUMENTS_MODULE);
|
|
10
|
+
const settings = (await documentService.getSettings().catch(() => ({}))) || {};
|
|
11
|
+
const rawStyle = String(req.query.style || "").trim().toLowerCase();
|
|
12
|
+
const style = ["modern", "classic", "minimal"].includes(rawStyle) ? rawStyle : "modern";
|
|
13
|
+
const rawType = String(req.query.type || "").trim().toLowerCase();
|
|
14
|
+
const validTypes = ["invoice", "receipt", "packing_slip", "estimate", "custom", "job_card"];
|
|
15
|
+
const type = (validTypes.includes(rawType) ? rawType : "invoice");
|
|
16
|
+
const isJobCard = type === "job_card";
|
|
17
|
+
const isCustom = type === "custom";
|
|
18
|
+
const isReceipt = type === "receipt";
|
|
19
|
+
const isPackingSlip = type === "packing_slip";
|
|
20
|
+
const isEstimate = type === "estimate";
|
|
21
|
+
const companyName = settings.company_name || "Urban Device Care Ltd";
|
|
22
|
+
const sampleData = {
|
|
23
|
+
display_id: isJobCard
|
|
24
|
+
? "JOB-1042"
|
|
25
|
+
: isReceipt
|
|
26
|
+
? "REC-4019"
|
|
27
|
+
: isPackingSlip
|
|
28
|
+
? "PKG-8821"
|
|
29
|
+
: isEstimate
|
|
30
|
+
? "EST-3091"
|
|
31
|
+
: isCustom
|
|
32
|
+
? "CERT-7701"
|
|
33
|
+
: "INV-1092",
|
|
34
|
+
title: isJobCard
|
|
35
|
+
? "Repair Job Card"
|
|
36
|
+
: type === "invoice"
|
|
37
|
+
? "Tax Invoice"
|
|
38
|
+
: isReceipt
|
|
39
|
+
? "Payment Receipt"
|
|
40
|
+
: isPackingSlip
|
|
41
|
+
? "Packing Slip"
|
|
42
|
+
: isEstimate
|
|
43
|
+
? "Quotation / Estimate"
|
|
44
|
+
: "Warranty Certificate",
|
|
45
|
+
type: type,
|
|
46
|
+
date: new Date().toISOString().split("T")[0],
|
|
47
|
+
due_date: (type === "invoice" || isEstimate)
|
|
48
|
+
? new Date(Date.now() + 14 * 86400000).toISOString().split("T")[0]
|
|
49
|
+
: undefined,
|
|
50
|
+
customer: {
|
|
51
|
+
name: "Jane Doe",
|
|
52
|
+
email: "jane.doe@example.com",
|
|
53
|
+
phone: "+44 7911 123456",
|
|
54
|
+
address: "221B Baker Street, Marylebone, London, NW1 6XE",
|
|
55
|
+
},
|
|
56
|
+
company: {
|
|
57
|
+
name: companyName,
|
|
58
|
+
logo_url: settings.pdf_logo_url,
|
|
59
|
+
address: settings.pdf_address || "123 High Street, Tech Park, London",
|
|
60
|
+
phone: settings.pdf_phone || "+44 20 7946 0991",
|
|
61
|
+
email: settings.pdf_email || "support@urbandevicecare.co.uk",
|
|
62
|
+
website: settings.pdf_website || "www.urbandevicecare.co.uk",
|
|
63
|
+
payment_details: settings.pdf_payment_details || "Bank: Barclays | Acct: 12345678 | Sort: 20-00-00",
|
|
64
|
+
terms: settings.pdf_terms || "Payment is due within 14 days of invoice date. Thank you for your business.",
|
|
65
|
+
},
|
|
66
|
+
items: isJobCard
|
|
67
|
+
? [
|
|
68
|
+
{ title: "Initial Physical Inspection & Safety Boot Test", quantity: 1, unit_price: 0, total: 0 },
|
|
69
|
+
{ title: "OEM OLED Display Replacement & Digitizer Calibration", quantity: 1, unit_price: 0, total: 0 },
|
|
70
|
+
{ title: "TrueTone & Ambient Light Sensor Transfer", quantity: 1, unit_price: 0, total: 0 },
|
|
71
|
+
{ title: "Battery Health Diagnostic & Load Testing", quantity: 1, unit_price: 0, total: 0 },
|
|
72
|
+
{ title: "Final Multi-Point Bench Clearance & Sanitization", quantity: 1, unit_price: 0, total: 0 },
|
|
73
|
+
]
|
|
74
|
+
: isCustom
|
|
75
|
+
? [
|
|
76
|
+
{
|
|
77
|
+
title: "OEM Component & Hardware Warranty",
|
|
78
|
+
description: "90-Day Comprehensive Hardware Protection",
|
|
79
|
+
quantity: 1,
|
|
80
|
+
unit_price: 0,
|
|
81
|
+
total: 0,
|
|
82
|
+
},
|
|
83
|
+
{
|
|
84
|
+
title: "Workshop Quality Clearance",
|
|
85
|
+
description: "Multi-Point Hardware Bench Certification",
|
|
86
|
+
quantity: 1,
|
|
87
|
+
unit_price: 0,
|
|
88
|
+
total: 0,
|
|
89
|
+
},
|
|
90
|
+
]
|
|
91
|
+
: [
|
|
92
|
+
{
|
|
93
|
+
title: "Apple iPhone 14 Screen Replacement",
|
|
94
|
+
description: "OEM Grade OLED Assembly with TrueTone restoration",
|
|
95
|
+
quantity: 1,
|
|
96
|
+
unit_price: 189.0,
|
|
97
|
+
total: 189.0,
|
|
98
|
+
},
|
|
99
|
+
{
|
|
100
|
+
title: "Diagnostic & Workshop Labor Fee",
|
|
101
|
+
description: "Full device diagnostic and multi-point hardware inspection",
|
|
102
|
+
quantity: 1,
|
|
103
|
+
unit_price: 45.0,
|
|
104
|
+
total: 45.0,
|
|
105
|
+
},
|
|
106
|
+
{
|
|
107
|
+
title: "Tempered Glass Screen Protector",
|
|
108
|
+
description: "9H Hardness Edge-to-Edge protection",
|
|
109
|
+
quantity: 1,
|
|
110
|
+
unit_price: 15.0,
|
|
111
|
+
total: 15.0,
|
|
112
|
+
},
|
|
113
|
+
],
|
|
114
|
+
subtotal: (isJobCard || isPackingSlip || isCustom) ? undefined : 249.0,
|
|
115
|
+
tax_total: (isJobCard || isPackingSlip || isCustom) ? undefined : 24.9,
|
|
116
|
+
discount_total: (isJobCard || isPackingSlip || isCustom) ? undefined : 10.0,
|
|
117
|
+
total: (isJobCard || isPackingSlip || isCustom) ? 0 : 263.9,
|
|
118
|
+
currency_code: "usd",
|
|
119
|
+
payment_status: isReceipt ? "paid" : "unpaid",
|
|
120
|
+
payment_link: (type === "invoice" || isEstimate) ? "https://store.urbandevicecare.co.uk/pay/sample-preview-token" : undefined,
|
|
121
|
+
qr_url: (type === "invoice" || isEstimate || isJobCard) ? "https://store.urbandevicecare.co.uk/track/JOB-1042" : undefined,
|
|
122
|
+
notes: isJobCard
|
|
123
|
+
? "Customer acknowledges device physical intake condition and workshop repair terms."
|
|
124
|
+
: isReceipt
|
|
125
|
+
? "Payment received in full via Paystack. Thank you for your custom!"
|
|
126
|
+
: isPackingSlip
|
|
127
|
+
? "Please inspect contents immediately upon receipt. Keep this slip for your delivery records."
|
|
128
|
+
: isEstimate
|
|
129
|
+
? "This quotation is valid for 30 calendar days from the date of issue."
|
|
130
|
+
: isCustom
|
|
131
|
+
? "Retain this warranty certificate for official warranty claim verification."
|
|
132
|
+
: "Please scan the QR code to complete payment securely via Paystack.",
|
|
133
|
+
body_text: isCustom
|
|
134
|
+
? "This official certificate verifies that the aforementioned device has undergone professional repairs with genuine OEM-specification components and has passed our multi-point quality assurance inspection.\n\nAll hardware replacements and associated workshop labor are covered under our comprehensive 90-day warranty against defects in parts and workmanship."
|
|
135
|
+
: undefined,
|
|
136
|
+
custom_fields: isJobCard
|
|
137
|
+
? {
|
|
138
|
+
"Device Model": "Apple iPhone 14 Pro Max",
|
|
139
|
+
"Serial / IMEI": "F2LZ90K8MD6R",
|
|
140
|
+
"Technician": "Alex Morgan",
|
|
141
|
+
"Reported Fault": "Cracked front glass, intermittent touch on upper quadrant",
|
|
142
|
+
"Cosmetic Condition": "Light casing scuffs; screen fractured",
|
|
143
|
+
"Accessories Left": "None (Unit only)",
|
|
144
|
+
}
|
|
145
|
+
: undefined,
|
|
146
|
+
};
|
|
147
|
+
const pdfBuffer = await pdfkit_generator_1.PDFKitGenerator.generate(sampleData, style);
|
|
148
|
+
res.setHeader("Content-Type", "application/pdf");
|
|
149
|
+
res.setHeader("Content-Disposition", `inline; filename="preview-${style}-${type}.pdf"`);
|
|
150
|
+
res.setHeader("Content-Length", String(pdfBuffer.length));
|
|
151
|
+
res.setHeader("Cache-Control", "no-cache, no-store, must-revalidate");
|
|
152
|
+
return res.send(pdfBuffer);
|
|
153
|
+
}
|
|
154
|
+
catch (err) {
|
|
155
|
+
req.scope.resolve("logger")?.error(`[Documents-API] Error generating preview: ${err.message}`);
|
|
156
|
+
return res.status(500).send(`Failed to generate preview: ${err.message}`);
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicm91dGUuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi8uLi8uLi9zcmMvYXBpL2FkbWluL2RvY3VtZW50cy90ZW1wbGF0ZXMvcHJldmlldy9yb3V0ZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOztBQU1BLGtCQTZKQztBQWxLRCxnRUFBb0U7QUFFcEUsK0VBQXlGO0FBRXpGLCtJQUErSTtBQUN4SSxLQUFLLFVBQVUsR0FBRyxDQUFDLEdBQWtCLEVBQUUsR0FBbUI7SUFDL0QsSUFBSSxDQUFDO1FBQ0gsTUFBTSxlQUFlLEdBQTBCLEdBQUcsQ0FBQyxLQUFLLENBQUMsT0FBTyxDQUFDLDRCQUFnQixDQUFDLENBQUM7UUFDbkYsTUFBTSxRQUFRLEdBQUcsQ0FBQyxNQUFNLGVBQWUsQ0FBQyxXQUFXLEVBQUUsQ0FBQyxLQUFLLENBQUMsR0FBRyxFQUFFLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDLElBQUksRUFBRSxDQUFDO1FBRS9FLE1BQU0sUUFBUSxHQUFHLE1BQU0sQ0FBQyxHQUFHLENBQUMsS0FBSyxDQUFDLEtBQUssSUFBSSxFQUFFLENBQUMsQ0FBQyxJQUFJLEVBQUUsQ0FBQyxXQUFXLEVBQUUsQ0FBQztRQUNwRSxNQUFNLEtBQUssR0FBRyxDQUFDLFFBQVEsRUFBRSxTQUFTLEVBQUUsU0FBUyxDQUFDLENBQUMsUUFBUSxDQUFDLFFBQVEsQ0FBQyxDQUFDLENBQUMsQ0FBQyxRQUFRLENBQUMsQ0FBQyxDQUFDLFFBQVEsQ0FBQztRQUV4RixNQUFNLE9BQU8sR0FBRyxNQUFNLENBQUMsR0FBRyxDQUFDLEtBQUssQ0FBQyxJQUFJLElBQUksRUFBRSxDQUFDLENBQUMsSUFBSSxFQUFFLENBQUMsV0FBVyxFQUFFLENBQUM7UUFDbEUsTUFBTSxVQUFVLEdBQUcsQ0FBQyxTQUFTLEVBQUUsU0FBUyxFQUFFLGNBQWMsRUFBRSxVQUFVLEVBQUUsUUFBUSxFQUFFLFVBQVUsQ0FBQyxDQUFDO1FBQzVGLE1BQU0sSUFBSSxHQUFHLENBQUMsVUFBVSxDQUFDLFFBQVEsQ0FBQyxPQUFPLENBQUMsQ0FBQyxDQUFDLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQyxTQUFTLENBQXlCLENBQUM7UUFFMUYsTUFBTSxTQUFTLEdBQUcsSUFBSSxLQUFLLFVBQVUsQ0FBQztRQUN0QyxNQUFNLFFBQVEsR0FBRyxJQUFJLEtBQUssUUFBUSxDQUFDO1FBQ25DLE1BQU0sU0FBUyxHQUFHLElBQUksS0FBSyxTQUFTLENBQUM7UUFDckMsTUFBTSxhQUFhLEdBQUcsSUFBSSxLQUFLLGNBQWMsQ0FBQztRQUM5QyxNQUFNLFVBQVUsR0FBRyxJQUFJLEtBQUssVUFBVSxDQUFDO1FBRXZDLE1BQU0sV0FBVyxHQUFHLFFBQVEsQ0FBQyxZQUFZLElBQUksdUJBQXVCLENBQUM7UUFFckUsTUFBTSxVQUFVLEdBQWlCO1lBQy9CLFVBQVUsRUFBRSxTQUFTO2dCQUNuQixDQUFDLENBQUMsVUFBVTtnQkFDWixDQUFDLENBQUMsU0FBUztvQkFDWCxDQUFDLENBQUMsVUFBVTtvQkFDWixDQUFDLENBQUMsYUFBYTt3QkFDZixDQUFDLENBQUMsVUFBVTt3QkFDWixDQUFDLENBQUMsVUFBVTs0QkFDWixDQUFDLENBQUMsVUFBVTs0QkFDWixDQUFDLENBQUMsUUFBUTtnQ0FDVixDQUFDLENBQUMsV0FBVztnQ0FDYixDQUFDLENBQUMsVUFBVTtZQUNkLEtBQUssRUFBRSxTQUFTO2dCQUNkLENBQUMsQ0FBQyxpQkFBaUI7Z0JBQ25CLENBQUMsQ0FBQyxJQUFJLEtBQUssU0FBUztvQkFDcEIsQ0FBQyxDQUFDLGFBQWE7b0JBQ2YsQ0FBQyxDQUFDLFNBQVM7d0JBQ1gsQ0FBQyxDQUFDLGlCQUFpQjt3QkFDbkIsQ0FBQyxDQUFDLGFBQWE7NEJBQ2YsQ0FBQyxDQUFDLGNBQWM7NEJBQ2hCLENBQUMsQ0FBQyxVQUFVO2dDQUNaLENBQUMsQ0FBQyxzQkFBc0I7Z0NBQ3hCLENBQUMsQ0FBQyxzQkFBc0I7WUFDMUIsSUFBSSxFQUFFLElBQUk7WUFDVixJQUFJLEVBQUUsSUFBSSxJQUFJLEVBQUUsQ0FBQyxXQUFXLEVBQUUsQ0FBQyxLQUFLLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDO1lBQzVDLFFBQVEsRUFBRSxDQUFDLElBQUksS0FBSyxTQUFTLElBQUksVUFBVSxDQUFDO2dCQUMxQyxDQUFDLENBQUMsSUFBSSxJQUFJLENBQUMsSUFBSSxDQUFDLEdBQUcsRUFBRSxHQUFHLEVBQUUsR0FBRyxRQUFRLENBQUMsQ0FBQyxXQUFXLEVBQUUsQ0FBQyxLQUFLLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDO2dCQUNsRSxDQUFDLENBQUMsU0FBUztZQUNiLFFBQVEsRUFBRTtnQkFDUixJQUFJLEVBQUUsVUFBVTtnQkFDaEIsS0FBSyxFQUFFLHNCQUFzQjtnQkFDN0IsS0FBSyxFQUFFLGlCQUFpQjtnQkFDeEIsT0FBTyxFQUFFLGdEQUFnRDthQUMxRDtZQUNELE9BQU8sRUFBRTtnQkFDUCxJQUFJLEVBQUUsV0FBVztnQkFDakIsUUFBUSxFQUFFLFFBQVEsQ0FBQyxZQUFZO2dCQUMvQixPQUFPLEVBQUUsUUFBUSxDQUFDLFdBQVcsSUFBSSxvQ0FBb0M7Z0JBQ3JFLEtBQUssRUFBRSxRQUFRLENBQUMsU0FBUyxJQUFJLGtCQUFrQjtnQkFDL0MsS0FBSyxFQUFFLFFBQVEsQ0FBQyxTQUFTLElBQUksK0JBQStCO2dCQUM1RCxPQUFPLEVBQUUsUUFBUSxDQUFDLFdBQVcsSUFBSSwyQkFBMkI7Z0JBQzVELGVBQWUsRUFBRSxRQUFRLENBQUMsbUJBQW1CLElBQUksa0RBQWtEO2dCQUNuRyxLQUFLLEVBQUUsUUFBUSxDQUFDLFNBQVMsSUFBSSw2RUFBNkU7YUFDM0c7WUFDRCxLQUFLLEVBQUUsU0FBUztnQkFDZCxDQUFDLENBQUM7b0JBQ0UsRUFBRSxLQUFLLEVBQUUsZ0RBQWdELEVBQUUsUUFBUSxFQUFFLENBQUMsRUFBRSxVQUFVLEVBQUUsQ0FBQyxFQUFFLEtBQUssRUFBRSxDQUFDLEVBQUU7b0JBQ2pHLEVBQUUsS0FBSyxFQUFFLHNEQUFzRCxFQUFFLFFBQVEsRUFBRSxDQUFDLEVBQUUsVUFBVSxFQUFFLENBQUMsRUFBRSxLQUFLLEVBQUUsQ0FBQyxFQUFFO29CQUN2RyxFQUFFLEtBQUssRUFBRSwwQ0FBMEMsRUFBRSxRQUFRLEVBQUUsQ0FBQyxFQUFFLFVBQVUsRUFBRSxDQUFDLEVBQUUsS0FBSyxFQUFFLENBQUMsRUFBRTtvQkFDM0YsRUFBRSxLQUFLLEVBQUUsMENBQTBDLEVBQUUsUUFBUSxFQUFFLENBQUMsRUFBRSxVQUFVLEVBQUUsQ0FBQyxFQUFFLEtBQUssRUFBRSxDQUFDLEVBQUU7b0JBQzNGLEVBQUUsS0FBSyxFQUFFLGtEQUFrRCxFQUFFLFFBQVEsRUFBRSxDQUFDLEVBQUUsVUFBVSxFQUFFLENBQUMsRUFBRSxLQUFLLEVBQUUsQ0FBQyxFQUFFO2lCQUNwRztnQkFDSCxDQUFDLENBQUMsUUFBUTtvQkFDVixDQUFDLENBQUM7d0JBQ0U7NEJBQ0UsS0FBSyxFQUFFLG1DQUFtQzs0QkFDMUMsV0FBVyxFQUFFLDBDQUEwQzs0QkFDdkQsUUFBUSxFQUFFLENBQUM7NEJBQ1gsVUFBVSxFQUFFLENBQUM7NEJBQ2IsS0FBSyxFQUFFLENBQUM7eUJBQ1Q7d0JBQ0Q7NEJBQ0UsS0FBSyxFQUFFLDRCQUE0Qjs0QkFDbkMsV0FBVyxFQUFFLDBDQUEwQzs0QkFDdkQsUUFBUSxFQUFFLENBQUM7NEJBQ1gsVUFBVSxFQUFFLENBQUM7NEJBQ2IsS0FBSyxFQUFFLENBQUM7eUJBQ1Q7cUJBQ0Y7b0JBQ0gsQ0FBQyxDQUFDO3dCQUNFOzRCQUNFLEtBQUssRUFBRSxvQ0FBb0M7NEJBQzNDLFdBQVcsRUFBRSxtREFBbUQ7NEJBQ2hFLFFBQVEsRUFBRSxDQUFDOzRCQUNYLFVBQVUsRUFBRSxLQUFLOzRCQUNqQixLQUFLLEVBQUUsS0FBSzt5QkFDYjt3QkFDRDs0QkFDRSxLQUFLLEVBQUUsaUNBQWlDOzRCQUN4QyxXQUFXLEVBQUUsNERBQTREOzRCQUN6RSxRQUFRLEVBQUUsQ0FBQzs0QkFDWCxVQUFVLEVBQUUsSUFBSTs0QkFDaEIsS0FBSyxFQUFFLElBQUk7eUJBQ1o7d0JBQ0Q7NEJBQ0UsS0FBSyxFQUFFLGlDQUFpQzs0QkFDeEMsV0FBVyxFQUFFLHFDQUFxQzs0QkFDbEQsUUFBUSxFQUFFLENBQUM7NEJBQ1gsVUFBVSxFQUFFLElBQUk7NEJBQ2hCLEtBQUssRUFBRSxJQUFJO3lCQUNaO3FCQUNGO1lBQ0wsUUFBUSxFQUFFLENBQUMsU0FBUyxJQUFJLGFBQWEsSUFBSSxRQUFRLENBQUMsQ0FBQyxDQUFDLENBQUMsU0FBUyxDQUFDLENBQUMsQ0FBQyxLQUFLO1lBQ3RFLFNBQVMsRUFBRSxDQUFDLFNBQVMsSUFBSSxhQUFhLElBQUksUUFBUSxDQUFDLENBQUMsQ0FBQyxDQUFDLFNBQVMsQ0FBQyxDQUFDLENBQUMsSUFBSTtZQUN0RSxjQUFjLEVBQUUsQ0FBQyxTQUFTLElBQUksYUFBYSxJQUFJLFFBQVEsQ0FBQyxDQUFDLENBQUMsQ0FBQyxTQUFTLENBQUMsQ0FBQyxDQUFDLElBQUk7WUFDM0UsS0FBSyxFQUFFLENBQUMsU0FBUyxJQUFJLGFBQWEsSUFBSSxRQUFRLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxLQUFLO1lBQzNELGFBQWEsRUFBRSxLQUFLO1lBQ3BCLGNBQWMsRUFBRSxTQUFTLENBQUMsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsUUFBUTtZQUM3QyxZQUFZLEVBQUUsQ0FBQyxJQUFJLEtBQUssU0FBUyxJQUFJLFVBQVUsQ0FBQyxDQUFDLENBQUMsQ0FBQyw4REFBOEQsQ0FBQyxDQUFDLENBQUMsU0FBUztZQUM3SCxNQUFNLEVBQUUsQ0FBQyxJQUFJLEtBQUssU0FBUyxJQUFJLFVBQVUsSUFBSSxTQUFTLENBQUMsQ0FBQyxDQUFDLENBQUMsb0RBQW9ELENBQUMsQ0FBQyxDQUFDLFNBQVM7WUFDMUgsS0FBSyxFQUFFLFNBQVM7Z0JBQ2QsQ0FBQyxDQUFDLG1GQUFtRjtnQkFDckYsQ0FBQyxDQUFDLFNBQVM7b0JBQ1gsQ0FBQyxDQUFDLG1FQUFtRTtvQkFDckUsQ0FBQyxDQUFDLGFBQWE7d0JBQ2YsQ0FBQyxDQUFDLDZGQUE2Rjt3QkFDL0YsQ0FBQyxDQUFDLFVBQVU7NEJBQ1osQ0FBQyxDQUFDLHNFQUFzRTs0QkFDeEUsQ0FBQyxDQUFDLFFBQVE7Z0NBQ1YsQ0FBQyxDQUFDLDRFQUE0RTtnQ0FDOUUsQ0FBQyxDQUFDLG9FQUFvRTtZQUN4RSxTQUFTLEVBQUUsUUFBUTtnQkFDakIsQ0FBQyxDQUFDLHNXQUFzVztnQkFDeFcsQ0FBQyxDQUFDLFNBQVM7WUFDYixhQUFhLEVBQUUsU0FBUztnQkFDdEIsQ0FBQyxDQUFDO29CQUNFLGNBQWMsRUFBRSx5QkFBeUI7b0JBQ3pDLGVBQWUsRUFBRSxjQUFjO29CQUMvQixZQUFZLEVBQUUsYUFBYTtvQkFDM0IsZ0JBQWdCLEVBQUUsMkRBQTJEO29CQUM3RSxvQkFBb0IsRUFBRSx1Q0FBdUM7b0JBQzdELGtCQUFrQixFQUFFLGtCQUFrQjtpQkFDdkM7Z0JBQ0gsQ0FBQyxDQUFDLFNBQVM7U0FDZCxDQUFDO1FBRUYsTUFBTSxTQUFTLEdBQUcsTUFBTSxrQ0FBZSxDQUFDLFFBQVEsQ0FBQyxVQUFVLEVBQUUsS0FBSyxDQUFDLENBQUM7UUFFcEUsR0FBRyxDQUFDLFNBQVMsQ0FBQyxjQUFjLEVBQUUsaUJBQWlCLENBQUMsQ0FBQztRQUNqRCxHQUFHLENBQUMsU0FBUyxDQUFDLHFCQUFxQixFQUFFLDZCQUE2QixLQUFLLElBQUksSUFBSSxPQUFPLENBQUMsQ0FBQztRQUN4RixHQUFHLENBQUMsU0FBUyxDQUFDLGdCQUFnQixFQUFFLE1BQU0sQ0FBQyxTQUFTLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQztRQUMxRCxHQUFHLENBQUMsU0FBUyxDQUFDLGVBQWUsRUFBRSxxQ0FBcUMsQ0FBQyxDQUFDO1FBQ3RFLE9BQU8sR0FBRyxDQUFDLElBQUksQ0FBQyxTQUFTLENBQUMsQ0FBQztJQUM3QixDQUFDO0lBQUMsT0FBTyxHQUFRLEVBQUUsQ0FBQztRQUNsQixHQUFHLENBQUMsS0FBSyxDQUFDLE9BQU8sQ0FBQyxRQUFRLENBQUMsRUFBRSxLQUFLLENBQUMsNkNBQTZDLEdBQUcsQ0FBQyxPQUFPLEVBQUUsQ0FBQyxDQUFDO1FBQy9GLE9BQU8sR0FBRyxDQUFDLE1BQU0sQ0FBQyxHQUFHLENBQUMsQ0FBQyxJQUFJLENBQUMsK0JBQStCLEdBQUcsQ0FBQyxPQUFPLEVBQUUsQ0FBQyxDQUFDO0lBQzVFLENBQUM7QUFDSCxDQUFDIn0=
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.GET = GET;
|
|
4
|
+
const documents_1 = require("../../../../../modules/documents");
|
|
5
|
+
const zoho_books_1 = require("../../../../../services/zoho-books");
|
|
6
|
+
// GET /admin/documents/zoho/list?type=invoices | estimates | payments
|
|
7
|
+
async function GET(req, res) {
|
|
8
|
+
const documentService = req.scope.resolve(documents_1.DOCUMENTS_MODULE);
|
|
9
|
+
const settings = await documentService.getSettings();
|
|
10
|
+
if (!settings.zoho_books_enabled || !settings.zoho_client_id) {
|
|
11
|
+
return res.json({
|
|
12
|
+
enabled: false,
|
|
13
|
+
message: "Zoho Books integration is not configured or disabled.",
|
|
14
|
+
items: [],
|
|
15
|
+
});
|
|
16
|
+
}
|
|
17
|
+
try {
|
|
18
|
+
const zoho = new zoho_books_1.ZohoBooksService({
|
|
19
|
+
client_id: settings.zoho_client_id,
|
|
20
|
+
client_secret: settings.zoho_client_secret,
|
|
21
|
+
refresh_token: settings.zoho_refresh_token,
|
|
22
|
+
organization_id: settings.zoho_organization_id,
|
|
23
|
+
domain: settings.zoho_domain || "com",
|
|
24
|
+
}, req.scope.resolve("logger"));
|
|
25
|
+
const type = req.query.type || "invoices";
|
|
26
|
+
let items = [];
|
|
27
|
+
if (type === "estimates") {
|
|
28
|
+
items = await zoho.listEstimates();
|
|
29
|
+
}
|
|
30
|
+
else if (type === "payments") {
|
|
31
|
+
items = await zoho.listPayments();
|
|
32
|
+
}
|
|
33
|
+
else {
|
|
34
|
+
items = await zoho.listInvoices();
|
|
35
|
+
}
|
|
36
|
+
res.json({
|
|
37
|
+
enabled: true,
|
|
38
|
+
type,
|
|
39
|
+
items,
|
|
40
|
+
});
|
|
41
|
+
}
|
|
42
|
+
catch (error) {
|
|
43
|
+
req.scope.resolve("logger")?.error(`[Documents-API] Failed to fetch Zoho documents: ${error.message}`);
|
|
44
|
+
res.status(500).json({
|
|
45
|
+
enabled: true,
|
|
46
|
+
error: error.message,
|
|
47
|
+
items: [],
|
|
48
|
+
});
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicm91dGUuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi8uLi8uLi9zcmMvYXBpL2FkbWluL2RvY3VtZW50cy96b2hvL2xpc3Qvcm91dGUudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7QUFNQSxrQkFnREM7QUFyREQsZ0VBQW9FO0FBRXBFLG1FQUFzRTtBQUV0RSxzRUFBc0U7QUFDL0QsS0FBSyxVQUFVLEdBQUcsQ0FBQyxHQUFrQixFQUFFLEdBQW1CO0lBQy9ELE1BQU0sZUFBZSxHQUEwQixHQUFHLENBQUMsS0FBSyxDQUFDLE9BQU8sQ0FBQyw0QkFBZ0IsQ0FBQyxDQUFDO0lBQ25GLE1BQU0sUUFBUSxHQUFHLE1BQU0sZUFBZSxDQUFDLFdBQVcsRUFBRSxDQUFDO0lBRXJELElBQUksQ0FBQyxRQUFRLENBQUMsa0JBQWtCLElBQUksQ0FBQyxRQUFRLENBQUMsY0FBYyxFQUFFLENBQUM7UUFDN0QsT0FBTyxHQUFHLENBQUMsSUFBSSxDQUFDO1lBQ2QsT0FBTyxFQUFFLEtBQUs7WUFDZCxPQUFPLEVBQUUsdURBQXVEO1lBQ2hFLEtBQUssRUFBRSxFQUFFO1NBQ1YsQ0FBQyxDQUFDO0lBQ0wsQ0FBQztJQUVELElBQUksQ0FBQztRQUNILE1BQU0sSUFBSSxHQUFHLElBQUksNkJBQWdCLENBQy9CO1lBQ0UsU0FBUyxFQUFFLFFBQVEsQ0FBQyxjQUFjO1lBQ2xDLGFBQWEsRUFBRSxRQUFRLENBQUMsa0JBQWtCO1lBQzFDLGFBQWEsRUFBRSxRQUFRLENBQUMsa0JBQWtCO1lBQzFDLGVBQWUsRUFBRSxRQUFRLENBQUMsb0JBQW9CO1lBQzlDLE1BQU0sRUFBRSxRQUFRLENBQUMsV0FBVyxJQUFJLEtBQUs7U0FDdEMsRUFDRCxHQUFHLENBQUMsS0FBSyxDQUFDLE9BQU8sQ0FBQyxRQUFRLENBQUMsQ0FDNUIsQ0FBQztRQUVGLE1BQU0sSUFBSSxHQUFJLEdBQUcsQ0FBQyxLQUFLLENBQUMsSUFBZSxJQUFJLFVBQVUsQ0FBQztRQUN0RCxJQUFJLEtBQUssR0FBVSxFQUFFLENBQUM7UUFFdEIsSUFBSSxJQUFJLEtBQUssV0FBVyxFQUFFLENBQUM7WUFDekIsS0FBSyxHQUFHLE1BQU0sSUFBSSxDQUFDLGFBQWEsRUFBRSxDQUFDO1FBQ3JDLENBQUM7YUFBTSxJQUFJLElBQUksS0FBSyxVQUFVLEVBQUUsQ0FBQztZQUMvQixLQUFLLEdBQUcsTUFBTSxJQUFJLENBQUMsWUFBWSxFQUFFLENBQUM7UUFDcEMsQ0FBQzthQUFNLENBQUM7WUFDTixLQUFLLEdBQUcsTUFBTSxJQUFJLENBQUMsWUFBWSxFQUFFLENBQUM7UUFDcEMsQ0FBQztRQUVELEdBQUcsQ0FBQyxJQUFJLENBQUM7WUFDUCxPQUFPLEVBQUUsSUFBSTtZQUNiLElBQUk7WUFDSixLQUFLO1NBQ04sQ0FBQyxDQUFDO0lBQ0wsQ0FBQztJQUFDLE9BQU8sS0FBVSxFQUFFLENBQUM7UUFDcEIsR0FBRyxDQUFDLEtBQUssQ0FBQyxPQUFPLENBQUMsUUFBUSxDQUFDLEVBQUUsS0FBSyxDQUFDLG1EQUFtRCxLQUFLLENBQUMsT0FBTyxFQUFFLENBQUMsQ0FBQztRQUN2RyxHQUFHLENBQUMsTUFBTSxDQUFDLEdBQUcsQ0FBQyxDQUFDLElBQUksQ0FBQztZQUNuQixPQUFPLEVBQUUsSUFBSTtZQUNiLEtBQUssRUFBRSxLQUFLLENBQUMsT0FBTztZQUNwQixLQUFLLEVBQUUsRUFBRTtTQUNWLENBQUMsQ0FBQztJQUNMLENBQUM7QUFDSCxDQUFDIn0=
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.GET = GET;
|
|
4
|
+
const documents_1 = require("../../../../modules/documents");
|
|
5
|
+
// GET /documents/:id/document (Public PDF download & view for recipients)
|
|
6
|
+
async function GET(req, res) {
|
|
7
|
+
const documentService = req.scope.resolve(documents_1.DOCUMENTS_MODULE);
|
|
8
|
+
const id = req.params.id;
|
|
9
|
+
try {
|
|
10
|
+
let record = null;
|
|
11
|
+
// Check by primary ID or human display_id (e.g. INV-1092)
|
|
12
|
+
try {
|
|
13
|
+
record = await documentService.retrieveDocumentRecord(id);
|
|
14
|
+
}
|
|
15
|
+
catch (e) {
|
|
16
|
+
const records = await documentService.listDocumentRecords({ display_id: id });
|
|
17
|
+
if (records && records.length > 0) {
|
|
18
|
+
record = records[0];
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
if (!record) {
|
|
22
|
+
return res.status(404).send("Document not found");
|
|
23
|
+
}
|
|
24
|
+
const pdfBuffer = await documentService.getPdfForRecord(record.id, req.scope);
|
|
25
|
+
res.setHeader("Content-Type", "application/pdf");
|
|
26
|
+
res.setHeader("Content-Disposition", `inline; filename="${record.display_id}.pdf"`);
|
|
27
|
+
res.setHeader("Content-Length", String(pdfBuffer.length));
|
|
28
|
+
res.setHeader("Cache-Control", "public, max-age=3600");
|
|
29
|
+
return res.send(pdfBuffer);
|
|
30
|
+
}
|
|
31
|
+
catch (err) {
|
|
32
|
+
req.scope.resolve("logger")?.error(`[Documents-Public] Error streaming PDF: ${err.message}`);
|
|
33
|
+
return res.status(500).send(`Failed to generate document: ${err.message}`);
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicm91dGUuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi8uLi9zcmMvYXBpL2RvY3VtZW50cy9baWRdL2RvY3VtZW50L3JvdXRlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7O0FBS0Esa0JBK0JDO0FBbkNELDZEQUFpRTtBQUdqRSwwRUFBMEU7QUFDbkUsS0FBSyxVQUFVLEdBQUcsQ0FBQyxHQUFrQyxFQUFFLEdBQW1CO0lBQy9FLE1BQU0sZUFBZSxHQUEwQixHQUFHLENBQUMsS0FBSyxDQUFDLE9BQU8sQ0FBQyw0QkFBZ0IsQ0FBQyxDQUFDO0lBQ25GLE1BQU0sRUFBRSxHQUFHLEdBQUcsQ0FBQyxNQUFNLENBQUMsRUFBRSxDQUFDO0lBRXpCLElBQUksQ0FBQztRQUNILElBQUksTUFBTSxHQUFRLElBQUksQ0FBQztRQUN2QiwwREFBMEQ7UUFDMUQsSUFBSSxDQUFDO1lBQ0gsTUFBTSxHQUFHLE1BQU0sZUFBZSxDQUFDLHNCQUFzQixDQUFDLEVBQUUsQ0FBQyxDQUFDO1FBQzVELENBQUM7UUFBQyxPQUFPLENBQUMsRUFBRSxDQUFDO1lBQ1gsTUFBTSxPQUFPLEdBQUcsTUFBTSxlQUFlLENBQUMsbUJBQW1CLENBQUMsRUFBRSxVQUFVLEVBQUUsRUFBRSxFQUFFLENBQUMsQ0FBQztZQUM5RSxJQUFJLE9BQU8sSUFBSSxPQUFPLENBQUMsTUFBTSxHQUFHLENBQUMsRUFBRSxDQUFDO2dCQUNsQyxNQUFNLEdBQUcsT0FBTyxDQUFDLENBQUMsQ0FBQyxDQUFDO1lBQ3RCLENBQUM7UUFDSCxDQUFDO1FBRUQsSUFBSSxDQUFDLE1BQU0sRUFBRSxDQUFDO1lBQ1osT0FBTyxHQUFHLENBQUMsTUFBTSxDQUFDLEdBQUcsQ0FBQyxDQUFDLElBQUksQ0FBQyxvQkFBb0IsQ0FBQyxDQUFDO1FBQ3BELENBQUM7UUFFRCxNQUFNLFNBQVMsR0FBRyxNQUFNLGVBQWUsQ0FBQyxlQUFlLENBQUMsTUFBTSxDQUFDLEVBQUUsRUFBRSxHQUFHLENBQUMsS0FBSyxDQUFDLENBQUM7UUFFOUUsR0FBRyxDQUFDLFNBQVMsQ0FBQyxjQUFjLEVBQUUsaUJBQWlCLENBQUMsQ0FBQztRQUNqRCxHQUFHLENBQUMsU0FBUyxDQUFDLHFCQUFxQixFQUFFLHFCQUFxQixNQUFNLENBQUMsVUFBVSxPQUFPLENBQUMsQ0FBQztRQUNwRixHQUFHLENBQUMsU0FBUyxDQUFDLGdCQUFnQixFQUFFLE1BQU0sQ0FBQyxTQUFTLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQztRQUMxRCxHQUFHLENBQUMsU0FBUyxDQUFDLGVBQWUsRUFBRSxzQkFBc0IsQ0FBQyxDQUFDO1FBQ3ZELE9BQU8sR0FBRyxDQUFDLElBQUksQ0FBQyxTQUFTLENBQUMsQ0FBQztJQUM3QixDQUFDO0lBQUMsT0FBTyxHQUFRLEVBQUUsQ0FBQztRQUNsQixHQUFHLENBQUMsS0FBSyxDQUFDLE9BQU8sQ0FBQyxRQUFRLENBQUMsRUFBRSxLQUFLLENBQUMsMkNBQTJDLEdBQUcsQ0FBQyxPQUFPLEVBQUUsQ0FBQyxDQUFDO1FBQzdGLE9BQU8sR0FBRyxDQUFDLE1BQU0sQ0FBQyxHQUFHLENBQUMsQ0FBQyxJQUFJLENBQUMsZ0NBQWdDLEdBQUcsQ0FBQyxPQUFPLEVBQUUsQ0FBQyxDQUFDO0lBQzdFLENBQUM7QUFDSCxDQUFDIn0=
|