From e279e84501a311e7003047ee386ce8d1dcc104a8 Mon Sep 17 00:00:00 2001 From: "admin.suherdy" Date: Thu, 27 Nov 2025 10:11:39 +0700 Subject: [PATCH] fix bugs --- README.md | 124 ++--- __init__.py | 2 +- __manifest__.py | 114 ++--- __pycache__/__init__.cpython-310.pyc | Bin 0 -> 249 bytes .../__pycache__/__init__.cpython-310.pyc | Bin 0 -> 225 bytes controllers/__pycache__/main.cpython-310.pyc | Bin 0 -> 3142 bytes controllers/main.py | 178 ++++---- data/ir_actions_server.xml | 30 +- models/__init__.py | 6 +- models/__pycache__/__init__.cpython-310.pyc | Bin 0 -> 334 bytes .../__pycache__/direct_print.cpython-310.pyc | Bin 0 -> 4875 bytes .../purchase_order.cpython-310.pyc | Bin 0 -> 896 bytes models/__pycache__/sale_order.cpython-310.pyc | Bin 0 -> 865 bytes .../__pycache__/stock_picking.cpython-310.pyc | Bin 0 -> 1600 bytes models/direct_print.py | 422 ++++++++--------- models/purchase_order.py | 34 +- models/sale_order.py | 34 +- models/stock_picking.py | 110 ++--- static/src/js/direct_print.js | 430 +++++++++--------- static/src/xml/direct_print.xml | 22 +- views/account_move_views.xml | 228 +++++----- views/assets.xml | 4 +- views/direct_print_templates.xml | 18 +- views/purchase_order_form_views.xml | 40 +- views/purchase_order_views.xml | 42 +- views/sale_order_form_views.xml | 40 +- views/sale_order_views.xml | 42 +- views/stock_picking_form_views.xml | 42 +- views/stock_picking_views.xml | 318 ++++++------- 29 files changed, 1140 insertions(+), 1140 deletions(-) create mode 100644 __pycache__/__init__.cpython-310.pyc create mode 100644 controllers/__pycache__/__init__.cpython-310.pyc create mode 100644 controllers/__pycache__/main.cpython-310.pyc create mode 100644 models/__pycache__/__init__.cpython-310.pyc create mode 100644 models/__pycache__/direct_print.cpython-310.pyc create mode 100644 models/__pycache__/purchase_order.cpython-310.pyc create mode 100644 models/__pycache__/sale_order.cpython-310.pyc create mode 100644 models/__pycache__/stock_picking.cpython-310.pyc diff --git a/README.md b/README.md index 9e9ef55..5d16fe3 100644 --- a/README.md +++ b/README.md @@ -1,63 +1,63 @@ -# Web Direct Print Module for Odoo 18 - -This module enables direct printing of reports to local printers connected to the user's computer without downloading PDF files. It uses browser printing capabilities for a seamless printing experience. - -## Features - -- Direct print from web interface to local printer -- Integration with existing report actions -- Browser-based printing without downloads -- Support for all standard Odoo reports -- Direct print button in report dialogs - -## Installation - -1. Place the `web_direct_print` folder in your Odoo addons directory -2. Update your Odoo configuration to include this directory in `addons_path` -3. Restart your Odoo server -4. Install the module from Apps menu (search for "Web Direct Print") - -## Usage - -Once installed, the module works automatically with existing reports: - -1. When viewing a document (Invoice, Sale Order, Purchase Order, etc.), click the print button -2. Instead of downloading a PDF, you'll see options to print directly -3. Select "Direct Print" to send the report directly to your default printer -4. The browser's print dialog will appear, allowing you to select your printer and print settings - -## Technical Details - -The module works by: - -1. Intercepting report generation requests -2. Converting reports to PDF in the backend -3. Sending the PDF data to the browser as a blob -4. Using JavaScript to create a temporary iframe with the PDF -5. Calling the browser's print function on the iframe - -## Browser Compatibility - -This module relies on browser printing capabilities, which are available in all modern browsers (Chrome, Firefox, Safari, Edge). For best results, use the latest version of your preferred browser. - -## Troubleshooting - -### Browser Settings -Make sure your browser allows popups from your Odoo instance, as some browsers may block the print dialog. - -### Printer Access -The module sends print jobs to the browser's default printer. Users can change printer settings in the browser's print dialog. - -### Security Restrictions -Some browsers may have security restrictions that prevent direct printing. If direct print doesn't work, the module will fall back to opening the report in a new tab where users can manually print using Ctrl+P. - -## Limitations - -- Requires user to have a local printer configured -- Browser-dependent functionality -- May not work in all network configurations -- Users need to confirm print dialog (cannot print silently) - -## Security - +# Web Direct Print Module for Odoo 18 + +This module enables direct printing of reports to local printers connected to the user's computer without downloading PDF files. It uses browser printing capabilities for a seamless printing experience. + +## Features + +- Direct print from web interface to local printer +- Integration with existing report actions +- Browser-based printing without downloads +- Support for all standard Odoo reports +- Direct print button in report dialogs + +## Installation + +1. Place the `web_direct_print` folder in your Odoo addons directory +2. Update your Odoo configuration to include this directory in `addons_path` +3. Restart your Odoo server +4. Install the module from Apps menu (search for "Web Direct Print") + +## Usage + +Once installed, the module works automatically with existing reports: + +1. When viewing a document (Invoice, Sale Order, Purchase Order, etc.), click the print button +2. Instead of downloading a PDF, you'll see options to print directly +3. Select "Direct Print" to send the report directly to your default printer +4. The browser's print dialog will appear, allowing you to select your printer and print settings + +## Technical Details + +The module works by: + +1. Intercepting report generation requests +2. Converting reports to PDF in the backend +3. Sending the PDF data to the browser as a blob +4. Using JavaScript to create a temporary iframe with the PDF +5. Calling the browser's print function on the iframe + +## Browser Compatibility + +This module relies on browser printing capabilities, which are available in all modern browsers (Chrome, Firefox, Safari, Edge). For best results, use the latest version of your preferred browser. + +## Troubleshooting + +### Browser Settings +Make sure your browser allows popups from your Odoo instance, as some browsers may block the print dialog. + +### Printer Access +The module sends print jobs to the browser's default printer. Users can change printer settings in the browser's print dialog. + +### Security Restrictions +Some browsers may have security restrictions that prevent direct printing. If direct print doesn't work, the module will fall back to opening the report in a new tab where users can manually print using Ctrl+P. + +## Limitations + +- Requires user to have a local printer configured +- Browser-dependent functionality +- May not work in all network configurations +- Users need to confirm print dialog (cannot print silently) + +## Security + The module follows Odoo's security model and only allows users to print documents they have access to. \ No newline at end of file diff --git a/__init__.py b/__init__.py index 38718f0..af57e79 100644 --- a/__init__.py +++ b/__init__.py @@ -1,2 +1,2 @@ -from . import models +from . import models from . import controllers \ No newline at end of file diff --git a/__manifest__.py b/__manifest__.py index 83fea89..5167361 100644 --- a/__manifest__.py +++ b/__manifest__.py @@ -1,58 +1,58 @@ -{ - 'name': 'Web Direct Print', - 'version': '18.0.1.0.0', - 'category': 'Extra Tools', - 'summary': 'Enable direct printing from web browser to local printers', - 'description': """ - This module enables direct printing of reports to local printers - connected to the user's computer without downloading PDF files. - Uses browser printing capabilities for seamless printing experience. - - Features: - • Sales: Direct print quotations and sales orders - • Purchase: Direct print purchase orders and vendor bills - • Inventory: Direct print delivery slips, picking operations, internal transfers, receipts - • Accounting: Direct print customer invoices, vendor bills, payment receipts, account statements - • Stock Management: Direct print stock moves, inventory valuation, package contents - - Supported Reports: - - Sales Orders & Quotations - - Purchase Orders & RFQs - - Customer Invoices & Credit Notes - - Vendor Bills & Credit Notes - - Delivery Orders & Picking Lists - - Internal Transfers & Receipts - - Payment Receipts & Statements - - Stock Moves & Inventory Reports - - Package & Lot Tracking Labels - """, - 'author': 'Suherdy Yacob', - 'depends': [ - 'base', - 'web', - 'account', - 'sale', - 'purchase', - 'stock', - ], - 'data': [ - 'data/ir_actions_server.xml', - 'views/direct_print_templates.xml', - 'views/sale_order_views.xml', - 'views/sale_order_form_views.xml', - 'views/purchase_order_views.xml', - 'views/purchase_order_form_views.xml', - 'views/stock_picking_views.xml', - 'views/stock_picking_form_views.xml', - 'views/account_move_views.xml', - ], - 'assets': { - 'web.assets_backend': [ - 'web_direct_print/static/src/js/direct_print.js', - 'web_direct_print/static/src/xml/direct_print.xml', - ], - }, - 'installable': True, - 'auto_install': False, - 'license': 'LGPL-3', +{ + 'name': 'Web Direct Print', + 'version': '18.0.1.0.0', + 'category': 'Extra Tools', + 'summary': 'Enable direct printing from web browser to local printers', + 'description': """ + This module enables direct printing of reports to local printers + connected to the user's computer without downloading PDF files. + Uses browser printing capabilities for seamless printing experience. + + Features: + • Sales: Direct print quotations and sales orders + • Purchase: Direct print purchase orders and vendor bills + • Inventory: Direct print delivery slips, picking operations, internal transfers, receipts + • Accounting: Direct print customer invoices, vendor bills, payment receipts, account statements + • Stock Management: Direct print stock moves, inventory valuation, package contents + + Supported Reports: + - Sales Orders & Quotations + - Purchase Orders & RFQs + - Customer Invoices & Credit Notes + - Vendor Bills & Credit Notes + - Delivery Orders & Picking Lists + - Internal Transfers & Receipts + - Payment Receipts & Statements + - Stock Moves & Inventory Reports + - Package & Lot Tracking Labels + """, + 'author': 'Suherdy Yacob', + 'depends': [ + 'base', + 'web', + 'account', + 'sale', + 'purchase', + 'stock', + ], + 'data': [ + 'data/ir_actions_server.xml', + 'views/direct_print_templates.xml', + 'views/sale_order_views.xml', + 'views/sale_order_form_views.xml', + 'views/purchase_order_views.xml', + 'views/purchase_order_form_views.xml', + 'views/stock_picking_views.xml', + 'views/stock_picking_form_views.xml', + 'views/account_move_views.xml', + ], + 'assets': { + 'web.assets_backend': [ + 'web_direct_print/static/src/js/direct_print.js', + 'web_direct_print/static/src/xml/direct_print.xml', + ], + }, + 'installable': True, + 'auto_install': False, + 'license': 'LGPL-3', } \ No newline at end of file diff --git a/__pycache__/__init__.cpython-310.pyc b/__pycache__/__init__.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..e1fb1db1f64b1b1269eb1d78dfc963fa5987ef7b GIT binary patch literal 249 zcmYk0F^a=55Je?B8ULoMybr_YV^ysf&GPo_1>L`F{!c;XKpVeFfC0D6@s{(<1#!_9#N~i|HsLyEiKG%y2k`4RfZ!*|F A_5c6? literal 0 HcmV?d00001 diff --git a/controllers/__pycache__/__init__.cpython-310.pyc b/controllers/__pycache__/__init__.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..04a9dea3b37b077fe24bd9abe980638247828549 GIT binary patch literal 225 zcmYjLu?oU46ijLd5emh>=+fZkAkr@o!ObP4dBFyfypp6yKghvf>gwbNba66u^5E{c zgM-7O*pP(zF?ZYKuO<8=OQA^&WfCAj4YBk}DS_-ls@0pOx}sBVg?6VZn}}Z)PvY}r zKl$8PhgPvLbjrh6k3wSGSkVhtORP1p^B6mH5v_GT&$)i^Ddzyxs_z#ywJLV%$s#*<{Am3KkmWqlDxy(d3v++`>Jjnw`-}sVJQ~+$rdf;3w@Ca0H-A1)GhT9eaiIBY9mt17GV> zLA7_nWV@j9lY(-3og|c(ClokLmx1$5zQrpAdrssIx5qEoX@ytL=ngny!jh6+DL`)@ z=x<5#flG9C{5wkU*C!M9m?ZUM+=t;l>abw)yMpy;LXm6jUA6Ys(8|}YwQBXK#_QL~ zY5j~GH40j=!qKZoYv|~SS9sr&eFFQekN-x=q)bVE>q<{-@HJg7%6R72;2la}w@to| z6yKO~_~u{0YL7gIoST$imiK4>$Ml#quLW!1=BhvY7E$zvLJv~z>(n0v36F(84XAGe z>d$gd%_TddKn6pYAEi?Fl3*x0{x0->`oz}*F=L=QtKeNZo`w-u9sk!m3MF8e4Mn2W ze-{XJ(DA?EJkn8`1hLOy!he#=rQH^rNTD;Cbo}4!f4vK)s8O0I;U7nOFgp)Q&zDPZ z3E9nWEO`U+Ttv?W?<}A2ZeH;}!d&k7d9`^Pt%gIuEYhIxt|4#e?GUw{e+-Bcw0&sG zhptZw@`u`l7W9;y5y|w7I-!4N&)7csi9o@Wl$O!RI8aJ3Vy#aNeIZvt+IDZk_8=XK zw#o)V@^Nb%gz4eEVK54kR+zRT-rgHSER!(hqMh>c2loH&x znIp825dWq8xtp)dUHWDnY@8`=*#trWL^H(;oo_A$N=TVXh{xK)ERKCGgHRj>;nU8; zpO`7DEW|xc$*yW%Gvzq#_oJk5R{BDJ1+lrsnAfd`|P*aUmlqek}ApjSi z!Z;8U2+Sysv;^#jCEo;bCLZAa(!mKwB+rejGM<`i%l_yEA?B>ShKp7nya>g}j<@Vs zoR6Co5Ek(hv%2II<4u#yxR_w_0~9Iu@DyOV2brD4+EB4b4!Mp?YRmhtz>K;F9b2i; zD*cpJopoAej8@nd{JY=RXoa%3Ro0+etl?Ct_ttY7FjuATL1WCLoBytS&;FI){Qtqv zKfH7sw87WC>6z4p;y|zAg=*pdD8?u5OB^5OR1LR~5U|5283Y1h|_SXdz|ly(v^cw#?OZ{s*pH z(lnQnn{c#;@;&Hxo1V=T>BB(YfX=*+-kA%Z`$_&B7kmg^(~-B3{v~!FV>br^8*BLq z%zX|`;Wo_Mq#kW7g7!B5`0Aitxoy66IeHr291^Sl5txF-A@SNaWvEaUX>lo{2!FqY zrf?aDE3|;PG+F+|+#!!Zqc0LZN&(=ma=8B_OKi;qP;KM6T+j#I^HKN4&e!)JJ>GlZ z5A-nJUd+Ec6aimw@#5?1NXKG(>KA_xUo1Y_)NM~03svpG1>x>t%E#~M8r-?8$lnY4 zqT2@6T$SB-wEbuhDFDDeT(4pXSPXy#{hIj0QooypWeNB z93?zGof$c^?J{;AjX$QuV?eo zlw_L0HF6u4+A5HDkXo2!Da1pGMquiy26PqDU^UukRq1-8K`jrl7jMd`-W4QU`0Sn* oD_-EnI}DWg>{q6`z!EEZ)qbYZo!Y&P#h?)5Y6MZXLbsg%0AsOI!2kdN literal 0 HcmV?d00001 diff --git a/controllers/main.py b/controllers/main.py index 668804b..01b6140 100644 --- a/controllers/main.py +++ b/controllers/main.py @@ -1,90 +1,90 @@ -from odoo import http -from odoo.http import request -import json -import base64 - - -class DirectPrintController(http.Controller): - - @http.route('/web/direct_print', type='json', auth='user') - def direct_print(self, report_name, docids, data=None): - """ - Controller method to handle direct print requests - :param report_name: Name of the report to print - :param docids: IDs of documents to print - :param data: Additional data for the report - :return: JSON response with print data - """ - try: - import logging - _logger = logging.getLogger(__name__) - _logger.info(f"Controller received: report_name={report_name} (type: {type(report_name)}), docids={docids} (type: {type(docids)}), data={data}") - - # Handle parameters that might come as different types - if isinstance(report_name, list): - report_name = report_name[0] if report_name else '' - - if isinstance(docids, str): - try: - # Try to convert string to list of integers - if ',' in docids: - docids = [int(x.strip()) for x in docids.split(',') if x.strip()] - else: - docids = [int(docids)] - except ValueError: - docids = [] - elif not isinstance(docids, list): - docids = [docids] if docids else [] - - _logger.info(f"Processed parameters: report_name={report_name}, docids={docids}") - - # Call the direct print model method with proper context - result = request.env['web.direct.print'].sudo().direct_print_action( - report_name, docids, data, context=request.context - ) - return result - except Exception as e: - import logging - _logger = logging.getLogger(__name__) - _logger.error(f"Controller error: {str(e)}") - _logger.exception("Full traceback:") - return { - 'success': False, - 'error': str(e) - } - - @http.route('/web/direct_print/get_reports', type='json', auth='user') - def get_available_reports(self): - """ - Controller method to get available reports for direct printing - :return: JSON response with available reports - """ - try: - result = request.env['web.direct.print'].sudo().get_available_reports() - return result - except Exception as e: - return { - 'success': False, - 'error': str(e) - } - - @http.route('/web/direct_print/test', type='http', auth='user', website=True) - def test_direct_print(self, **kwargs): - """ - Test endpoint for direct printing functionality - """ - # This could be used for testing purposes - html_content = """ - - - - Direct Print Test - - -

Direct Print Test Page

-

This page demonstrates the direct print functionality.

- - - - """ +from odoo import http +from odoo.http import request +import json +import base64 + + +class DirectPrintController(http.Controller): + + @http.route('/web/direct_print', type='json', auth='user') + def direct_print(self, report_name, docids, data=None): + """ + Controller method to handle direct print requests + :param report_name: Name of the report to print + :param docids: IDs of documents to print + :param data: Additional data for the report + :return: JSON response with print data + """ + try: + import logging + _logger = logging.getLogger(__name__) + _logger.info(f"Controller received: report_name={report_name} (type: {type(report_name)}), docids={docids} (type: {type(docids)}), data={data}") + + # Handle parameters that might come as different types + if isinstance(report_name, list): + report_name = report_name[0] if report_name else '' + + if isinstance(docids, str): + try: + # Try to convert string to list of integers + if ',' in docids: + docids = [int(x.strip()) for x in docids.split(',') if x.strip()] + else: + docids = [int(docids)] + except ValueError: + docids = [] + elif not isinstance(docids, list): + docids = [docids] if docids else [] + + _logger.info(f"Processed parameters: report_name={report_name}, docids={docids}") + + # Call the direct print model method with proper context + result = request.env['web.direct.print'].sudo().direct_print_action( + report_name, docids, data, context=request.context + ) + return result + except Exception as e: + import logging + _logger = logging.getLogger(__name__) + _logger.error(f"Controller error: {str(e)}") + _logger.exception("Full traceback:") + return { + 'success': False, + 'error': str(e) + } + + @http.route('/web/direct_print/get_reports', type='json', auth='user') + def get_available_reports(self): + """ + Controller method to get available reports for direct printing + :return: JSON response with available reports + """ + try: + result = request.env['web.direct.print'].sudo().get_available_reports() + return result + except Exception as e: + return { + 'success': False, + 'error': str(e) + } + + @http.route('/web/direct_print/test', type='http', auth='user', website=True) + def test_direct_print(self, **kwargs): + """ + Test endpoint for direct printing functionality + """ + # This could be used for testing purposes + html_content = """ + + + + Direct Print Test + + +

Direct Print Test Page

+

This page demonstrates the direct print functionality.

+ + + + """ return html_content \ No newline at end of file diff --git a/data/ir_actions_server.xml b/data/ir_actions_server.xml index 756d11a..eb37416 100644 --- a/data/ir_actions_server.xml +++ b/data/ir_actions_server.xml @@ -1,16 +1,16 @@ - - - - - - Direct Print - - code - -if object: - action = env['web.direct.print'].direct_print_action(object.report_name, env.context.get('active_ids', []), context=env.context) - - - - + + + + + + Direct Print + + code + +if object: + action = env['web.direct.print'].direct_print_action(object.report_name, env.context.get('active_ids', []), context=env.context) + + + + \ No newline at end of file diff --git a/models/__init__.py b/models/__init__.py index bd0fadf..d50d46a 100644 --- a/models/__init__.py +++ b/models/__init__.py @@ -1,4 +1,4 @@ -from . import direct_print -from . import stock_picking -from . import sale_order +from . import direct_print +from . import stock_picking +from . import sale_order from . import purchase_order \ No newline at end of file diff --git a/models/__pycache__/__init__.cpython-310.pyc b/models/__pycache__/__init__.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..7d75823a2346c0f3f576c3136ad7931100ed46f1 GIT binary patch literal 334 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 literal 0 HcmV?d00001 diff --git a/models/__pycache__/purchase_order.cpython-310.pyc b/models/__pycache__/purchase_order.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..6961c431c91083084d00a87f8d9d7dad36f083ea GIT binary patch literal 896 zcmaJxSK-OeDKtzpBTqd3X6Bnw%jFz-`MUU1o(2g00%t0rch0<;2i|bRag7?B z<0i<1hU5gJSBM9kd`FxJybZsRJmTSdw2FTFc(fueZWI@_aq*@SH8+kFZN=bjDn4_c z<*q*nlw*$afa9F>*m>Avy5)MOSy>qIMsuML$L-*z3Venqm~cMw`rNAlSdIaVhhNYZ zdBxj+M?Yd;YJ7M$PX>8WX~AsL>Pp(AV75{+*(jZiiIOgnNeao6cQ4xYMvN~iq; zld`%J(z*rj&}fHtxHn+0JM6KMr0?W(Opt2PDsAcLcllPa3+=uYj@aUZ3uVy=cVh_b zoR}+Cd2)}Kl2&}So_7L15%Qy6_~uvGg+|nypGe>I?p2wUsu7vll|u7qJ1sJ{%$2h(^JRC{tI2zdfAJF+Kax+SS5=z~iQeV}shVz2b%Uw|qH#1sE z-*{#9EuXbxWMWR>U*rw!zKOk=p%5>E?%z4g0vOS-vzmZ`I2XN!J?~;BSU|Q0KsS5R P7xNSr)4-G4=nnY{J(c+d literal 0 HcmV?d00001 diff --git a/models/__pycache__/sale_order.cpython-310.pyc b/models/__pycache__/sale_order.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..f01ca14b62dfb2f0b4c3503389680d9bfead1074 GIT binary patch literal 865 zcmZ`%v5wR*5VhkZx9sg94gsP7DIHphM06Agoy1909EY|`WBFn)n^h7A+Y4kx2cN+Y z@Jnu~_yVM>m~oa)KcOeKck4AedaBZ;I9X=zE@ zsEk@xGD=<(8AsWk#w)T+enCE2GM~0us>b?sU8_b~&qQBWcs3R2Ja%~q zjv^(Mq>Lmj*@#`nBc{K#5{-Imq%!-t1vl5|S9F4f{t@UaP>XPqB8ZH?kSzhF+ejwg zQy4MbpU<;{oYzKGF6&L*xlB~9)?K#NCc`FKXks(b$?U^UJAtS6rgVQ=n|v&>dDYaa zbABNM9uIi?M+fxFfd1|;L@_RMKP+NYuZ`pAhjz=<$8PAAXHLBLaVJ{kj}J*9NTsf7 z;Pa@`ol~D3P|YxAs{3dbu=kSs*s5mzgP1!IUdv*mTUFTIMj1KegQ)b?Su1+c<(1BB zSzHcoqq_>OtI$&GXU~gjXPs_^l(28{NnP>jTE%#=1&++a%y~cf$0HN}Wbzx<@M7$3 zFi{dw{9>BY^m_kf1t5Wr1C#%$zgQ-I#yJwexu0_mGwh%}_X`ePL~}Tq@w$UGYiI64 zv#|ffoZ`O(3_fm~f|-$+E~4=70-4AC4L(Z4&|scV-rz$HITI|T)*zsty%>jii7(J% J$vyIb{Q>0M?0oX-nP3c zC;Bn?0{KdF<;1xMq&@MT?cMB(ppG>^`#ryz_wP4jMxz6UKIlw&Gk2srO5MHwxn{nV*!tR6komY1Ujfa{KI?dsrk*GNW zA8iC7g#h7ej(-JCZzf^?&j7j;(hdnR%*uVL!yOkA;(sD$ea46t0>57+7^;vw3%Nj3yaAj%gytX zGOM#{lADQ!>FJ`qG*}o=Qv=34{&t$rG1)Q$FjX^ssh+3XxlDV`O}l!eLs*k~;f{uC zZX081yC#GfNpp-4`2ml3Kcx^-aC#(ag4OcT*%sl3g6{ZUZ@0rfV&a;8Zy%rloQMsQ z7>1M2kXapvg5{SRG7JsrIkfJ4+!VUrnAk(y%ti>ykGA_4KN*N($*mnBTzmE&ecvab zR$OySp>!?i;US9d__i8tyrae2_Yj1?QYw5P@%3wdCuTKexds~Traa-bRPT#owidMx4%WvM9^nX`B9q+j? zP3a7!sXIthr0Tq&?' + - '' + - 'Printing Document' + - '' + - '' + - '' + - '
    ' + - '' + - '
    ' + - ' - - - `); - printWindow.document.close(); - } - - // Clean up - setTimeout(() => URL.revokeObjectURL(url), 10000); - } - } catch (error) { - console.error("Direct print error:", error); - } +/** @odoo-module **/ + +import { rpc } from "@web/core/network/rpc"; +import { _t } from "@web/core/l10n/translation"; +import { registry } from "@web/core/registry"; +import { Component } from "@odoo/owl"; + +const actionRegistry = registry.category("actions"); + +// Direct Print Action Handler +class DirectPrintAction extends Component { + static template = "web_direct_print.DirectPrintAction"; + + async setup() { + // This action will handle direct print requests + const action = this.props.action; + console.log("DirectPrintAction received action:", action); + + const report_name = action.report_name || action.context?.report_name || ''; + const docids = action.docids || action.context?.active_ids || []; + const data = action.data || {}; + + console.log("Extracted params:", { report_name, docids, data }); + await this.directPrint(report_name, docids, data); + } + + async directPrint(reportName, docIds, data) { + try { + // Call the controller endpoint to get report data + const result = await rpc("/web/direct_print", { + report_name: reportName, + docids: docIds, + data: data || {} + }); + + if (result.success) { + this.printReport(result); + } else { + this.env.services.notification.add( + _t("Error: ") + (result.error || _t("Unknown error occurred")), + { type: "danger" } + ); + } + } catch (error) { + console.error("Direct print error:", error); + this.env.services.notification.add( + _t("Error occurred while preparing print: ") + (error.message || error), + { type: "danger" } + ); + } + } + + printReport(printData) { + // Create a blob from the base64 content + const binaryString = atob(printData.content); + const bytes = new Uint8Array(binaryString.length); + for (let i = 0; i < binaryString.length; i++) { + bytes[i] = binaryString.charCodeAt(i); + } + + const blob = new Blob([bytes], { type: printData.content_type }); + const url = URL.createObjectURL(blob); + + // Create a new window with HTML that embeds the PDF and has print functionality + const printWindow = window.open('', '_blank', 'width=800,height=600'); + if (!printWindow) { + // If popup is blocked, show download option + const a = document.createElement('a'); + a.href = url; + a.download = printData.report_name + '.pdf'; + a.click(); + URL.revokeObjectURL(url); + return; + } + + // Write HTML content that will embed the PDF and automatically trigger print + var htmlContent = '' + + '' + + '' + + 'Printing Document' + + '' + + '' + + '' + + '
    ' + + '' + + '
    ' + + ' + + + `); + printWindow.document.close(); + } + + // Clean up + setTimeout(() => URL.revokeObjectURL(url), 10000); + } + } catch (error) { + console.error("Direct print error:", error); + } }; \ No newline at end of file diff --git a/static/src/xml/direct_print.xml b/static/src/xml/direct_print.xml index eff485f..69a99bf 100644 --- a/static/src/xml/direct_print.xml +++ b/static/src/xml/direct_print.xml @@ -1,12 +1,12 @@ - - - -
    - -
    - -
    Preparing print...
    -
    -
    -
    + + + +
    + +
    + +
    Preparing print...
    +
    +
    +
    \ No newline at end of file diff --git a/views/account_move_views.xml b/views/account_move_views.xml index 0643c0d..9ccea3c 100644 --- a/views/account_move_views.xml +++ b/views/account_move_views.xml @@ -1,115 +1,115 @@ - - - - - - Direct Print Customer Invoice - - - list,form - code - -if records: - # Filter for customer invoices - invoices = records.filtered(lambda r: r.move_type in ['out_invoice', 'out_refund']) - if invoices: - action = { - 'type': 'ir.actions.client', - 'tag': 'direct_print', - 'report_name': 'account.report_invoice', - 'docids': invoices.ids, - 'context': env.context, - } - - - - - - Direct Print Vendor Bill - - - list,form - code - -if records: - # Filter for vendor bills - bills = records.filtered(lambda r: r.move_type in ['in_invoice', 'in_refund']) - if bills: - action = { - 'type': 'ir.actions.client', - 'tag': 'direct_print', - 'report_name': 'account.report_invoice', - 'docids': bills.ids, - 'context': env.context, - } - - - - - - Direct Print Invoice with Payments - - - list,form - code - -if records: - # Filter for customer invoices - invoices = records.filtered(lambda r: r.move_type in ['out_invoice']) - if invoices: - action = { - 'type': 'ir.actions.client', - 'tag': 'direct_print', - 'report_name': 'account.report_invoice_with_payments', - 'docids': invoices.ids, - 'context': env.context, - } - - - - - - Direct Print Payment Receipt - - - list,form - code - -if records: - # Filter for payments - payments = records.filtered(lambda r: r.state == 'posted') - if payments: - action = { - 'type': 'ir.actions.client', - 'tag': 'direct_print', - 'report_name': 'account.action_report_payment_receipt', - 'docids': payments.ids, - 'context': env.context, - } - - - - - - Direct Print Account Statement - - - list,form - code - -if records: - # Filter for partners with accounting entries - partners = records.filtered(lambda r: r.customer_rank > 0 or r.supplier_rank > 0) - if partners: - action = { - 'type': 'ir.actions.client', - 'tag': 'direct_print', - 'report_name': 'account.report_partnerledger', - 'docids': partners.ids, - 'context': env.context, - } - - - - + + + + + + Direct Print Customer Invoice + + + list,form + code + +if records: + # Filter for customer invoices + invoices = records.filtered(lambda r: r.move_type in ['out_invoice', 'out_refund']) + if invoices: + action = { + 'type': 'ir.actions.client', + 'tag': 'direct_print', + 'report_name': 'account.report_invoice', + 'docids': invoices.ids, + 'context': env.context, + } + + + + + + Direct Print Vendor Bill + + + list,form + code + +if records: + # Filter for vendor bills + bills = records.filtered(lambda r: r.move_type in ['in_invoice', 'in_refund']) + if bills: + action = { + 'type': 'ir.actions.client', + 'tag': 'direct_print', + 'report_name': 'account.report_invoice', + 'docids': bills.ids, + 'context': env.context, + } + + + + + + Direct Print Invoice with Payments + + + list,form + code + +if records: + # Filter for customer invoices + invoices = records.filtered(lambda r: r.move_type in ['out_invoice']) + if invoices: + action = { + 'type': 'ir.actions.client', + 'tag': 'direct_print', + 'report_name': 'account.report_invoice_with_payments', + 'docids': invoices.ids, + 'context': env.context, + } + + + + + + Direct Print Payment Receipt + + + list,form + code + +if records: + # Filter for payments + payments = records.filtered(lambda r: r.state == 'posted') + if payments: + action = { + 'type': 'ir.actions.client', + 'tag': 'direct_print', + 'report_name': 'account.action_report_payment_receipt', + 'docids': payments.ids, + 'context': env.context, + } + + + + + + Direct Print Account Statement + + + list,form + code + +if records: + # Filter for partners with accounting entries + partners = records.filtered(lambda r: r.customer_rank > 0 or r.supplier_rank > 0) + if partners: + action = { + 'type': 'ir.actions.client', + 'tag': 'direct_print', + 'report_name': 'account.report_partnerledger', + 'docids': partners.ids, + 'context': env.context, + } + + + + \ No newline at end of file diff --git a/views/assets.xml b/views/assets.xml index bc404c8..a8d032f 100644 --- a/views/assets.xml +++ b/views/assets.xml @@ -1,3 +1,3 @@ - - + + \ No newline at end of file diff --git a/views/direct_print_templates.xml b/views/direct_print_templates.xml index 7aebd43..c5c2bbd 100644 --- a/views/direct_print_templates.xml +++ b/views/direct_print_templates.xml @@ -1,10 +1,10 @@ - - - - + + + + \ No newline at end of file diff --git a/views/purchase_order_form_views.xml b/views/purchase_order_form_views.xml index 64af6e6..36f72bc 100644 --- a/views/purchase_order_form_views.xml +++ b/views/purchase_order_form_views.xml @@ -1,21 +1,21 @@ - - - - - - purchase.order.form.direct.print - purchase.order - - - -