Print Node Integration for Frappe Framework

@max_morais_dmm thanks for a very sort after product! The frappe team should integrate this.

Just trying to install app - I am receiving the same error as @Randy_Lowery on CENTOS 7 using latest version of Frappe / ERPNext. Any advice?

Thanks

[frappe@erpnext-dev frappe-bench]$ pip --version
pip 9.0.1 from /usr/lib/python2.7/site-packages (python 2.7)
[frappe@erpnext-dev frappe-bench]$ bench get-app printnode GitHub - techmaxsolucoes/printnode-integration: Smarting Printing from Frappe using Print Node API
INFO:bench.app:getting app printnode-integration
INFO:bench.utils:git clone GitHub - techmaxsolucoes/printnode-integration: Smarting Printing from Frappe using Print Node API --origin upstream
Cloning into ‘printnode-integration’…
remote: Counting objects: 299, done.
remote: Total 299 (delta 0), reused 0 (delta 0), pack-reused 299
Receiving objects: 100% (299/299), 35.82 KiB | 0 bytes/s, done.
Resolving deltas: 100% (174/174), done.
(‘installing’, u’printnode_integration’)
INFO:bench.app:installing printnode_integration
INFO:bench.utils:./env/bin/pip install -q -e ./apps/printnode_integration --no-cache-dir
Could not find a version that satisfies the requirement printnodeapi (from printnode-integration==0.0.1) (from versions: )
No matching distribution found for printnodeapi (from printnode-integration==0.0.1)
Traceback (most recent call last):
File “/usr/bin/bench”, line 11, in
load_entry_point(‘bench’, ‘console_scripts’, ‘bench’)()
File “/home/frappe/.bench/bench/cli.py”, line 40, in cli
bench_command()
File “/usr/lib64/python2.7/site-packages/click/core.py”, line 716, in call
return self.main(*args, **kwargs)
File “/usr/lib64/python2.7/site-packages/click/core.py”, line 696, in main
rv = self.invoke(ctx)
File “/usr/lib64/python2.7/site-packages/click/core.py”, line 1060, in invoke
return _process_result(sub_ctx.command.invoke(sub_ctx))
File “/usr/lib64/python2.7/site-packages/click/core.py”, line 889, in invoke
return ctx.invoke(self.callback, **ctx.params)
File “/usr/lib64/python2.7/site-packages/click/core.py”, line 534, in invoke
return callback(*args, **kwargs)
File “/home/frappe/.bench/bench/commands/make.py”, line 32, in get_app
get_app(git_url, branch=branch)
File “/home/frappe/.bench/bench/app.py”, line 76, in get_app
install_app(app=app_name, bench_path=bench_path, verbose=verbose)
File “/home/frappe/.bench/bench/app.py”, line 107, in install_app
find_links=find_links))
File “/home/frappe/.bench/bench/utils.py”, line 140, in exec_cmd
raise CommandFailedError(cmd)
bench.utils.CommandFailedError: ./env/bin/pip install -q -e ./apps/printnode_integration --no-cache-dir

@OneiricIT by some weird reason pip is failling!
So I solve this problem with

cd frappe-bench
./env/bin/pip install -e ./apps/printnode_integration
echo printnode_integration > sites/apps.txt
1 Like

@max_morais_dmm thanks for quick response. Still same issue seen as below… also note running ‘echo printnode_integration > sites/apps.txt’ wipes out existing entries - if anyone else tries this. Had to put back to original afterwards.

[frappe@erpnext-dev frappe-bench]$ ./env/bin/pip install -e ./apps/printnode_integration
Obtaining file:///home/frappe/frappe-bench/apps/printnode_integration
Requirement already satisfied: frappe in ./apps/frappe (from printnode-integration==0.0.1)
Collecting printnodeapi (from printnode-integration==0.0.1)
Could not find a version that satisfies the requirement printnodeapi (from printnode-integration==0.0.1) (from versions: )
No matching distribution found for printnodeapi (from printnode-integration==0.0.1)
[frappe@erpnext-dev frappe-bench]$ echo printnode_integration > sites/apps.txt
[frappe@erpnext-dev frappe-bench]$

After some digging, I found similar cases where pip required ‘–pre’. Ran the below and was able to install without issue.

./env/bin/pip install --pre git+https://github.com/PrintNode/PrintNode-Python.git#egg=printnodeapi
./env/bin/pip install --pre git+https://github.com/fvdsn/py-xml-escpos#egg=pyxmlescpos
bench get-app printnode GitHub - techmaxsolucoes/printnode-integration: Smarting Printing from Frappe using Print Node API

2 Likes

@max_morais_dmm any logging available for timeouts received?

Was able to setup the PrintNode Settings with API key - successfully pulls the test computer I added and lists out the printers. Adding an action was also no issue - created one for Sales Invoice.

When trying to use the Print Node Integration button or the action on Submit in Sales Invoice, it sits at below screen for a while, then I receive a 504 Gateway Time-out in console (nothing else) and a frappe prompt Request Timed Out. Could this be a symptom of the install issue?

Thanks

image

EDIT: Found I had to add the ERPNext site to local host file for 127.0.0.1 - issue I have come across before when printing. Communicating now.

@max_morais_dmm

Great module, this would be something that should be implemented in the core.

Did you consider using https://qz.io/ ? It seems to do something similar as Print Node but is LGPL licensed.
I’m not a developer so I could be completely wrong but I just wanted to point your attention to it. :slight_smile:

2 Likes

@Bas_de_Reus I planned qz.io as the primary option, but Qz has one limitation:

We cannot connect trought the server, so I could not print PDF or Attachment files

Another point is, some speedups that printnode provide to me, like know the devices connected, and the hability to define one action, targeting a printer is impossible into the qz.io, due the API of Qz.io only works in your machine.

If the server instance of ERPNext need access to this, I need to open an ssh tunnel for each machine connected to ERPNext that have an instance of qz.io running, to can send documents to the printer

So you may imagine, why I decided to don’t go trought qz

1 Like

@max_morais_dmm
Thanks ,
i installed your app and got a 1 month of printnode to check , but i see there is no print node client available for linux xD , only for windows and mac.
no way around it?

Also i noticed that print node can only print in pdf formats ,
I want it to print POS reciepts through POS like normally we do in pos submit a transaction and print…
can it do that?

Thanks for active replies

@kt2152

I’m not the developer of Print Node, I just choice the service by the convenience and facility, I know that they develop the product in Python, they may can provide an way yo tou connect trought linux.

Yes, you can print POS Receipts
When you configure one Action like here

You need to to define that the print format is compatible with “XML ESCPOS” and you need to define your template using the XML ESCPOS syntax

Something like this

<receipt>
    <h1>Receipt!</h1>
    <h2>div,span,p,ul,ol are also supported</h2>:w
    <line>
        <left>Product</left>
        <right>0.15€</right>
    </line>
    <hr />
    <line size='double-height'>
        <left>TOTAL</left>
        <right>0.15€</right>
    </line>
    <barcode encoding='ean13'>
        5449000000996
    </barcode>
    <cashdraw /> 
    <cut />
</receipt>

Thanks @max_morais_dmm
Print node is working on rolling out a linux client soon :smile: . i will mange with windows for now

also is there no print option from POS screen ?
i set up the action as

but coudn’t find the button on POS page

only on sales invoice

My entire reason to set this up is because i want precision cutting of POS receipts without any hassle.
IS it possible to set this up ?
if so how?

Thank you for your help so far.
regards

I think you have to choose point of sale doctype instead of sales

POS is a page not Doctype

@kt2152, @SOLOSOFT, @Mohammed_Redha remember, print node integration is based on the backend!

The option “Call Print After” exists for the “Point Of Sales”
When the POS syncronize the Invoice with the backend, it will be sent to the printer!

I dont have plans, neither the options, to integrate this with pages or Reports for now, due the nature of the new POS, it’s a bit crazy to do that, because if your POS is in offline mode, the print-format is only compatible with JavaScript, if the POS is online mode, the print format is compatible with Jinja.

And ESCPOS Print formats are based on the Jinja templates.

These are limitations defined by the ERPNext Point of Sales, is because that I ever plan my integrations in a point that I’ll be able to ensure that the integration will work, without handle some special cases like the Point of Sales. So, linking this with a Sales Invoice, when your Point of Sales Syncronize with Backed, everything is printed!

@max_morais_dmm
As you did a very good job writing this module and it seems a lot of people like it. Would you consider to contribute is to the ERPNext core and send a PR?

I think a lot of people would benefit from this and it seems like a generic addition.

@Bas_de_Reus in fact a PR, just will turn hard my process of maintenance of the app, so, no I dont have plans to send a PR.

@max_morais_dmm
i am having a tough time with the XML print format - i want to duplicate the POS invoice of the sales invoice to make it XML ESC POS compatible.
Heres the actual server side POS Invoice :

style>
.print-format table, .print-format tr,
.print-format td, .print-format div, .print-format p {
font-family: Monospace;
line-height: 200%;
vertical-align: middle;
}
@media screen {
.print-format {
width: 4in;
padding: 0.25in;
min-height: 8in;
}
}
/style>

p class=“text-center”>
{{ doc.company }}

{{ doc.select_print_heading or _(“Invoice”) }}

/p>
p>
{{ _(“Receipt No”) }}: {{ doc.name }}

{{ _(“Date”) }}: {{ doc.get_formatted(“posting_date”) }}

{{ _(“Customer”) }}: {{ doc.customer_name }}
/p>

hr>
table class=“table table-condensed cart no-border”>
thead>
tr>
{{ _(“Item”) }}
{{ _(“Qty”) }}
{{ _(“Amount”) }}
/tr>
/thead>
tbody>
{%- for item in doc.items -%}
tr>
td>
{{ item.item_code }}
{%- if item.item_name != item.item_code -%}

{{ item.item_name }}{%- endif -%}
/td>
{{ item.qty }}
@ {{ item.get_formatted(“rate”) }}
{{ item.get_formatted(“amount”) }}

{%- endfor -%}

{%- for row in doc.taxes -%} {%- if not row.included_in_print_rate -%} {%- endif -%} {%- endfor -%} {%- if doc.discount_amount -%} {%- endif -%}
{{ _("Net Total") }} {{ doc.get_formatted("net_total") }}
{{ row.description }} {{ row.get_formatted("tax_amount", doc) }}
{{ _("Discount") }} {{ doc.get_formatted("discount_amount") }}
{{ _("Grand Total") }} {{ doc.get_formatted("grand_total") }}
{% if doc.get("taxes", filters={"included_in_print_rate": 1}) %}

Taxes Included:

{%- for row in doc.taxes -%} {%- if row.included_in_print_rate -%} {%- endif -%} {%- endfor -%}
{{ row.description }} {{ row.get_formatted("tax_amount_after_discount_amount", doc) }}
{%- endif -%}

{{ doc.terms or "" }}

{{ _("Thank you, please visit again.") }}

what out of these i can use , and how can i replicate–
i am guessing style tags will go also media…
but other than that how-
i created a new custom print format of type server and copy pasted it and removed the style tags…
Can you help me out please?

thanks for the app.

@Taher_Khalil, right now, the unique way that you can do the print format, is following the standards for XML ESC/POS

One important fact is, thermal printers, aren’t like normal printers, it don’t cover all capabilities that do you want, and the ESC/POS is a bit limited, each model and each vendor, define they on support for ESCPOS

as reference for wikipedia:

Derivation[edit]
ESC/P derives its name from the start of the escape sequences used, which start with the escape character ESC (ASCII code 27). As an example, ESC E will switch to printing in bold font, while ESC F switches off bold printing. The ESC/P control codes are sometimes also referred to as Epson LQ codes, as they were made popular by the Epson LQ series of dot matrix printers, even though ESC/P was introduced long before LQ printers.

Variants[edit]
There are several variants of ESC/P, as not all printers implement all commands.

ESC/P J84 adds special support for Japanese computers.
ESC/P2 is a more recent variant of ESC/P by Epson. ESC/P2 is backward compatible with ESC/P, but adds commands for new printer features such as scalable fonts and enhanced graphics printing.
ESC/P-R is a variant now used by Epson on many inkjet printers.[1]
ESC/POS is a variant for controlling receipt printers as commonly used at the point of sale (POS)[2]

So, don’t expect that your termal printer will follow the same printer quality that you have in the normal printers, beause it wont will.

XML-ESCPos ensure that the minimal commands are provided pro printer something in a thermal device

Oh I see ,
Guess I will have to do a bit more digging around and work on it …
Thanks , and so let us know if you have any similar awesome apps for various functionalities.

Regards,

max_morais_dmm
October 22
@Taher_Khalil, right now, the unique way that you can do the print format, is following the standards for XML ESC/POS

One important fact is, thermal printers, aren’t like normal printers, it don’t cover all capabilities that do you want, and the ESC/POS is a bit limited, each model and each vendor, define they on support for ESCPOS

as reference for wikipedia:

> Derivation[edit] ESC/P derives its name from the start of the escape sequences used, which start with the escape character ESC (ASCII code 27). As an example, ESC E will switch to printing in bold font, while ESC F switches off bold printing. The ESC/P control codes are sometimes also referred to as Epson LQ codes, as they were made popular by the Epson LQ series of dot matrix printers, even though ESC/P was introduced long before LQ printers. Variants[edit] There are several variants of ESC/P, as not all printers implement all commands. ESC/P J84 adds special support for Japanese computers. ESC/P2 is a more recent variant of ESC/P by Epson. ESC/P2 is backward compatible with ESC/P, but adds commands for new printer features such as scalable fonts and enhanced graphics printing. ESC/P-R is a variant now used by Epson on many inkjet printers.[1] ESC/POS is a variant for controlling receipt printers as commonly used at the point of sale (POS)[2]

@max_morais_dmm

Please i am trying to deploy this on my instance but i am getting the error message below…How do i proceed from here…

:~$ bench get-app printnode GitHub - techmaxsolucoes/printnode-integration: Smarting Printing from Frappe using Print Node API
INFO:bench.app:getting app printnode-integration
INFO:bench.utils:git clone GitHub - techmaxsolucoes/printnode-integration: Smarting Printing from Frappe using Print Node API --origin upstream
Cloning into ‘printnode-integration’…
remote: Counting objects: 322, done.
remote: Compressing objects: 100% (16/16), done.
remote: Total 322 (delta 6), reused 12 (delta 3), pack-reused 303
Receiving objects: 100% (322/322), 41.17 KiB | 0 bytes/s, done.
Resolving deltas: 100% (183/183), done.
Checking connectivity… done.
(‘installing’, u’printnode_integration’)
INFO:bench.app:installing printnode_integration
INFO:bench.utils:./env/bin/pip install -q -e ./apps/printnode_integration --no-cache-dir
/home/ubuntu/frappe-bench/apps/frappe/frappe/build.py:106: UserWarning: Source /home/ubuntu/frappe-bench/apps/knowledge_base/knowledge_base/docs does not exists.
warnings.warn(‘Source {source} does not exists.’.format(source = source))
/home/ubuntu/frappe-bench/apps/frappe/frappe/build.py:106: UserWarning: Source /home/ubuntu/frappe-bench/apps/poll/poll/public does not exists.
warnings.warn(‘Source {source} does not exists.’.format(source = source))
/home/ubuntu/frappe-bench/apps/frappe/frappe/build.py:106: UserWarning: Source /home/ubuntu/frappe-bench/apps/bench_manager/bench_manager/docs does not exists.
warnings.warn(‘Source {source} does not exists.’.format(source = source))
/home/ubuntu/frappe-bench/apps/frappe/frappe/build.py:106: UserWarning: Source /home/ubuntu/frappe-bench/apps/xlevel/xlevel/public does not exists.
warnings.warn(‘Source {source} does not exists.’.format(source = source))
/home/ubuntu/frappe-bench/apps/frappe/frappe/build.py:106: UserWarning: Source /home/ubuntu/frappe-bench/apps/xlevel/xlevel/docs does not exists.
warnings.warn(‘Source {source} does not exists.’.format(source = source))
/home/ubuntu/frappe-bench/apps/frappe/frappe/build.py:106: UserWarning: Source /home/ubuntu/frappe-bench/apps/library_management/library_management/public does not exists.
warnings.warn(‘Source {source} does not exists.’.format(source = source))
/home/ubuntu/frappe-bench/apps/frappe/frappe/build.py:106: UserWarning: Source /home/ubuntu/frappe-bench/apps/library_management/library_management/docs does not exists.
warnings.warn(‘Source {source} does not exists.’.format(source = source))
/home/ubuntu/frappe-bench/apps/frappe/frappe/build.py:106: UserWarning: Source /home/ubuntu/frappe-bench/apps/printnode_integration/printnode_integration/docs does not exists.
warnings.warn(‘Source {source} does not exists.’.format(source = source))
Wrote css/frappe-web.css - 65.11 KB
Wrote js/frappe-web.min.js - 132.05 KB
Wrote js/control.min.js - 65.84 KB
Wrote js/dialog.min.js - 111.18 KB
Wrote css/desk.min.css - 293.95 KB
Wrote css/frappe-rtl.css - 32.49 KB
Wrote js/libs.min.js - 861.86 KB
Wrote js/desk.min.js - 506.52 KB
Wrote css/module.min.css - 2.08 KB
Wrote css/form.min.css - 4.47 KB
Wrote js/form.min.js - 195.27 KB
Wrote css/list.min.css - 14.72 KB
Wrote js/list.min.js - 143.46 KB
Wrote css/report.min.css - 7.89 KB
Wrote js/report.min.js - 260.05 KB
Wrote js/web_form.min.js - 247.55 KB
Wrote css/web_form.css - 24.42 KB
Wrote js/print_format_v3.min.js - 23.39 KB
Wrote css/erpnext.css - 8 KB
Wrote js/erpnext-web.min.js - 3.73 KB
Wrote js/erpnext.min.js - 137.33 KB
Wrote js/item-dashboard.min.js - 7.91 KB
INFO:bench.utils:sudo supervisorctl restart frappe-bench-workers: frappe-bench-web:

@EnSealm it’s not an error, is just a verbose message from frappe code, that dont found documentation in some projects, you can ignore this!

thank you for your prompt response…

Is there any configuration instruction referenced anywhere? i see it install but i am trying to getting around how it works.

Thanks a bunch