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.
Files changed (39) hide show
  1. package/.medusa/server/src/admin/index.js +2427 -0
  2. package/.medusa/server/src/admin/index.mjs +2428 -0
  3. package/.medusa/server/src/api/admin/documents/[id]/document/route.js +36 -0
  4. package/.medusa/server/src/api/admin/documents/[id]/send/route.js +41 -0
  5. package/.medusa/server/src/api/admin/documents/[id]/sync-zoho/route.js +68 -0
  6. package/.medusa/server/src/api/admin/documents/custom/route.js +48 -0
  7. package/.medusa/server/src/api/admin/documents/manual/route.js +46 -0
  8. package/.medusa/server/src/api/admin/documents/route.js +36 -0
  9. package/.medusa/server/src/api/admin/documents/settings/route.js +44 -0
  10. package/.medusa/server/src/api/admin/documents/templates/preview/route.js +159 -0
  11. package/.medusa/server/src/api/admin/documents/zoho/list/route.js +51 -0
  12. package/.medusa/server/src/api/documents/[id]/document/route.js +36 -0
  13. package/.medusa/server/src/api/documents/r/[code]/route.js +29 -0
  14. package/.medusa/server/src/api/documents/templates/preview/route.js +159 -0
  15. package/.medusa/server/src/api/store/documents/r/[code]/route.js +22 -0
  16. package/.medusa/server/src/index.js +27 -0
  17. package/.medusa/server/src/modules/documents/index.js +13 -0
  18. package/.medusa/server/src/modules/documents/migrations/Migration20261012164601.js +23 -0
  19. package/.medusa/server/src/modules/documents/migrations/Migration20261014150000.js +20 -0
  20. package/.medusa/server/src/modules/documents/models/document-link.js +12 -0
  21. package/.medusa/server/src/modules/documents/models/document-record.js +33 -0
  22. package/.medusa/server/src/modules/documents/models/document-settings.js +61 -0
  23. package/.medusa/server/src/modules/documents/service.js +456 -0
  24. package/.medusa/server/src/services/notification-sender.js +293 -0
  25. package/.medusa/server/src/services/pdf-post-processor.js +64 -0
  26. package/.medusa/server/src/services/pdfkit-generator.js +438 -0
  27. package/.medusa/server/src/services/zoho-books.js +221 -0
  28. package/.medusa/server/src/subscribers/order-documents.js +178 -0
  29. package/.medusa/server/src/subscribers/repair-documents.js +162 -0
  30. package/.medusa/server/src/utils/integrate.js +37 -0
  31. package/.medusa/server/src/utils/payment-link.js +69 -0
  32. package/.medusa/server/src/workflows/create-manual-document.js +27 -0
  33. package/.medusa/server/src/workflows/generate-document.js +24 -0
  34. package/.medusa/server/src/workflows/index.js +20 -0
  35. package/.medusa/server/src/workflows/send-document-notification.js +41 -0
  36. package/CHANGELOG.md +87 -0
  37. package/LICENSE +21 -0
  38. package/README.md +201 -2
  39. 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,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicm91dGUuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi8uLi8uLi9zcmMvYXBpL2FkbWluL2RvY3VtZW50cy90ZW1wbGF0ZXMvcHJldmlldy9yb3V0ZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOztBQU1BLGtCQTZKQztBQWxLRCxnRUFBb0U7QUFFcEUsK0VBQXlGO0FBRXpGLCtJQUErSTtBQUN4SSxLQUFLLFVBQVUsR0FBRyxDQUFDLEdBQWtCLEVBQUUsR0FBbUI7SUFDL0QsSUFBSSxDQUFDO1FBQ0gsTUFBTSxlQUFlLEdBQTBCLEdBQUcsQ0FBQyxLQUFLLENBQUMsT0FBTyxDQUFDLDRCQUFnQixDQUFDLENBQUM7UUFDbkYsTUFBTSxRQUFRLEdBQUcsQ0FBQyxNQUFNLGVBQWUsQ0FBQyxXQUFXLEVBQUUsQ0FBQyxLQUFLLENBQUMsR0FBRyxFQUFFLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDLElBQUksRUFBRSxDQUFDO1FBRS9FLE1BQU0sUUFBUSxHQUFHLE1BQU0sQ0FBQyxHQUFHLENBQUMsS0FBSyxDQUFDLEtBQUssSUFBSSxFQUFFLENBQUMsQ0FBQyxJQUFJLEVBQUUsQ0FBQyxXQUFXLEVBQUUsQ0FBQztRQUNwRSxNQUFNLEtBQUssR0FBRyxDQUFDLFFBQVEsRUFBRSxTQUFTLEVBQUUsU0FBUyxDQUFDLENBQUMsUUFBUSxDQUFDLFFBQVEsQ0FBQyxDQUFDLENBQUMsQ0FBQyxRQUFRLENBQUMsQ0FBQyxDQUFDLFFBQVEsQ0FBQztRQUV4RixNQUFNLE9BQU8sR0FBRyxNQUFNLENBQUMsR0FBRyxDQUFDLEtBQUssQ0FBQyxJQUFJLElBQUksRUFBRSxDQUFDLENBQUMsSUFBSSxFQUFFLENBQUMsV0FBVyxFQUFFLENBQUM7UUFDbEUsTUFBTSxVQUFVLEdBQUcsQ0FBQyxTQUFTLEVBQUUsU0FBUyxFQUFFLGNBQWMsRUFBRSxVQUFVLEVBQUUsUUFBUSxFQUFFLFVBQVUsQ0FBQyxDQUFDO1FBQzVGLE1BQU0s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
@@ -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=