Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[FR] Allow label printing plugins to handle printing in bulk #4167

Closed
1 of 2 tasks
wolflu05 opened this issue Jan 7, 2023 · 29 comments · Fixed by #5883
Closed
1 of 2 tasks

[FR] Allow label printing plugins to handle printing in bulk #4167

wolflu05 opened this issue Jan 7, 2023 · 29 comments · Fixed by #5883
Assignees
Labels
enhancement This is an suggested enhancement or new feature plugin Plugin ecosystem report Report/Label generation
Milestone

Comments

@wolflu05
Copy link
Contributor

wolflu05 commented Jan 7, 2023

Please verify that this feature request has NOT been suggested before.

  • I checked and didn't find similar feature request

Problem statement

Currently it is not possible to bulk print multiple labels in a single job. This is useful if your labels are not printed with a label printer, instead a normal paper printer. There you don't want to waste much paper, so printing out each label onto a singe A4/Letter page is wasting paper.

Suggested solution

The current solution calls the print function of the label printing plugin once for each label.

for idx, output in enumerate(outputs):
"""For each output, we generate a temporary image file, which will then get sent to the printer."""
# Generate PDF data for the label
pdf = output.get_document().write_pdf()
# Offload a background task to print the provided label
offload_task(
plugin_label.print_label,
plugin.plugin_slug(),
pdf,
filename=label_names[idx],
label_instance=label_instances[idx],
user=request.user,
)

Maybe there could be a second function which can be implemented by the label plugin for print_labels (function gets list of labels). It would be also great to implement a printing queue directly into inventree and add a quick access button to print the whole queue, but I am not sure how many people would benefit from this.

Describe alternatives you've considered

The print_label function of a plugin could queue labels itself until a page is full or ... and then print out all labels, but if the page is not filled and you want to have your labels printed you would have to add a custom url to your plugin which can trigger an "early print". This API endpoint could be called by a custom navigation button.

Examples of other systems

don't know any other systems

Do you want to develop this?

  • I want to develop this.
@wolflu05 wolflu05 added enhancement This is an suggested enhancement or new feature triage:not-checked Item was not checked by the core team labels Jan 7, 2023
@matmair matmair added plugin Plugin ecosystem report Report/Label generation and removed triage:not-checked Item was not checked by the core team labels Jan 7, 2023
@matmair
Copy link
Member

matmair commented Jan 7, 2023

This is probably a bit more complex than it sounds when implemented right but I like the idea.

In general, I think it would be good to add a layer of attraction wherever we interface with 'real' machines, printers etc. So that we can have some meta info for the devices, maybe connect multiple ones, scope them to locations etc.

As for the print queue: If we need/want this fast it could just be moved into the print_label function of a plugin and add navigation to get to a page where settings and a 'print' button are.

@wolflu05
Copy link
Contributor Author

wolflu05 commented Jan 7, 2023

So that we can have some meta info for the devices, maybe connect multiple ones, scope them to locations etc.

This is actually a feature which I haven't thought of, but I like the solution of scoping printers to a location. And for meta info, you mean plugins can expose if wired/wireless printers are "alive" or not reachable and also some kind of indicator for remaining pages/labels, ...?

As for the print queue: If we need/want this fast it could just be moved into the print_label function of a plugin and add navigation to get to a page where settings and a 'print' button are.

But doesn't that mean it would break existing plugins?

I would even go a step further and say, that label printing plugins can also expose multiple printers. E.g. the one I own has two label printers in it. One for big spool and one for a tapes. So it would be nice if plugins can expose multiple printers?

@SchrodingersGat
Copy link
Member

@wolflu05 to simplify the scope of this particular issue, I think a simple approach would be to slightly change the way we interface to external label printing plugins.

Instead of the plugin providing a method "print_label", it provides "print_labels" - and the server simply throws all the selected labels to the printer at once. The plugin can then determine how it handles "multiple labels".

  • If a plugin provides a "print_labels" method, that is used in preference
  • Legacy plugins can still provide "print_label" method which will be supported

From the user side, the UX is the same. However plugins can now "choose" how they handle multiple labels being printed at once.

@SchrodingersGat
Copy link
Member

@wolflu05 @matmair if you think the idea above has merit, I can implement that quite quickly.

@wolflu05
Copy link
Contributor Author

wolflu05 commented Jan 7, 2023

So you think queuing systems should be implemented by each individual plugin?

@SchrodingersGat SchrodingersGat added this to the 0.10.0 milestone Jan 7, 2023
@SchrodingersGat
Copy link
Member

I think that a queuing system is a different issue and much harder problem than the relatively simple change to allow printing of multiple labels.

@wolflu05
Copy link
Contributor Author

wolflu05 commented Jan 8, 2023

Ok. So what do you think, does this get actually often used, or is this just some thinking of a software developer? If first, I'll should open a new issue for that?

And absolutely, splitting this into two issues would probably decrease complexity.

@matmair
Copy link
Member

matmair commented Jan 8, 2023

A general queuing system is probably needed at some point, the question is if we really need it for this right now.

@wolflu05
Copy link
Contributor Author

wolflu05 commented Jan 8, 2023

It would make sense, if you have lots of sub categories and don't use the tree view (I don't remember if it's possible with tree to select multiple and print multiple labels from there). But if this is possible, I would say, this is not needed right now and the simple bulk printing (already mentioned as easy to implement) should fit the needs.

@martonmiklos
Copy link
Contributor

@wolflu05 @matmair if you think the idea above has merit, I can implement that quite quickly.

Even if I was not asked ;) I support the approach. This would help me to quickly overcome on the #4626

@SchrodingersGat
Copy link
Member

Does anyone have any experience blitting multiple PDF outputs onto a single page in such a manner? We use django-weasyprint to generate the individual labels, but we'd need a method to combine them onto a single, larger page.

@martonmiklos
Copy link
Contributor

My plan was to use pypdf2 to do the labels merging in a plugin:
https://pypdf2.readthedocs.io/en/latest/modules/PageObject.html#PyPDF2._page.PageObject.mergeRotatedTranslatedPage

To be honest I am not very keen on the approach of creating PDFs and then merging them, but for the plugin approach this looks to be the easiest path.

@SchrodingersGat
Copy link
Member

@martonmiklos if you've got another approach I'm all ears.

@martonmiklos
Copy link
Contributor

@martonmiklos if you've got another approach I'm all ears.

Well I would rather move the multi page merging into the InvenTree itself (not to plugin) to reduce the weasyprint -> PDF -> pypdf -> PDF workflow.

But I agree that the multi page printing can have many options, however I think it is a very common thing to print labels among the intended audience with a standard A4 printer for storage boxes.
I think we could make most of the users satisfied by keeping the options limited.

I am thinking about the following (per label template):

  • Multi page printing (checkbox)
  • Page size for multi page printing (X x Y or preselect from standard page sizes A4/A5...)
  • Orientation: Landscape/portrait
  • Print borders

@SchrodingersGat
Copy link
Member

Well I would rather move the multi page merging into the InvenTree itself (

To be clear, that's what I'm suggesting also. And with additional options you list above.

However, not sure exactly the workflow for generating the individual labels and then combining into a single PDF

@wolflu05
Copy link
Contributor Author

wolflu05 commented May 2, 2023

Please also consider the other ideas with with queuing I suggested if we improve the printing system.

@martonmiklos
Copy link
Contributor

Well I would rather move the multi page merging into the InvenTree itself (

To be clear, that's what I'm suggesting also. And with additional options you list above.

However, not sure exactly the workflow for generating the individual labels and then combining into a single PDF

I reflected to this comment:

#4626 (comment)

But task decoded now, I will figure out how can we perform this in weasyprint.

The following came into my mind: generate a "layout" HTML template based on the label size and the paper size. Basically a tables with fixed col/row heights with properly positioned pagebreaks and add the generated HTML templates into the cells (by stripping the HTML tags) and render the merged html into a PDF.

@SchrodingersGat
Copy link
Member

@martonmiklos would you be willing / able to submit a PR based on this approach?

@martonmiklos
Copy link
Contributor

@martonmiklos would you be willing / able to submit a PR based on this approach?

Sure! Now the objective is clear, my mileage may vary (the way I described above is just a wild idea) but I definitely need the multi page feature so I will work on it.

@SchrodingersGat
Copy link
Member

LMK how you go and if you need anyone to sound ideas off

@martonmiklos
Copy link
Contributor

martonmiklos commented May 2, 2023

We are approaching:

kép

The approach will bring some restrictions on the templates itself (absolute positioning needed to be avoided).

@SchrodingersGat
Copy link
Member

Incredible, that looks amazing. Great progress 😃

Some limitations around multi page printing is not a deal breaker

@matmair
Copy link
Member

matmair commented May 2, 2023

@martonmiklos would be cool to control layout, margins etc with URL parameters; that way we can control it dynamically from the ui (ie preview) in the future

@wolflu05
Copy link
Contributor Author

wolflu05 commented May 3, 2023

This looks cool. Maybe also the ability to add doted/dashed lines or even no lines and just cutting markers on the edges.

@SchrodingersGat
Copy link
Member

@martonmiklos any updates on this one? As we are looking to push next stable release out soon, I'm considering bumping the milestone for this to 0.13.0

@martonmiklos
Copy link
Contributor

martonmiklos commented Jun 20, 2023

@martonmiklos any updates on this one? As we are looking to push next stable release out soon, I'm considering bumping the milestone for this to 0.13.0

If I think correctly you are mainly asking how this issue relates/connects to #4626 / #4805.

In the current state of that PR the "pagination" is handed over to the plugins in the similar way how the non paginated data is passed. (I.e. separate rendered HTMLs and PDFs are passed and in the label details the multi page option is passed).

If you are not comfortable with this approach let me know, I am neutral on this question because both passing the paginated and passing separate could make sense in different plugin approaches I think.

The following is in my mind about passing the paginated outputs to printer plugins:
If the printer plugins prints to some some printer like Zebra / Dymo / Brady which prints for e.g. the following material:

kép

Then the paginated output does not makes too much sense, as the pagination way is more likely will be the part of the plugin logic.

Disclaimer: I never written/used printing plugins of InvenTree ;)

@SchrodingersGat
Copy link
Member

I guess for now I'm wondering about the status of #4805

I think in the future development plans it will definitely be the case that the plugins will be "in charge" of pagination. I'm just considering how close your implementation in #4805 is to being "ready", and whether we ship this now with the understanding that it will later change?

@martonmiklos
Copy link
Contributor

I think in the future development plans it will definitely be the case that the plugins will be "in charge" of pagination.

Okay, then the current implementation fits this vision.

I will respond to the rest in the #4626 to not being offtopic here.

@wolflu05 wolflu05 self-assigned this Jun 25, 2023
@SchrodingersGat
Copy link
Member

Given @martonmiklos is out of action for a bit, and there's still some work required here, I'm going to bump this to the next release cycle.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement This is an suggested enhancement or new feature plugin Plugin ecosystem report Report/Label generation
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants