inventree / inventree-brother-plugin

Label printing plugin for Brother series printers
MIT License
16 stars 12 forks source link

[FR] Print multiple copies of a label #30

Closed Alex9779 closed 9 months ago

Alex9779 commented 9 months ago

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

Problem statement

I started using InvenTree a few weeks ago and use a Brother label printer now. I am pretty impressed what InvenTree does and how it helps me now. I also figure out how to adjust the label to how I want them to be, especially those for locations. Though it is disruptive when I want to print certain labels for which I need multiple copies.

Suggested solution

As far as I can see there are two possible solutions:

  1. allow setting the amount of copies directly in the printing dialog.
  2. allow setting the number of copies on a label definition.

Both would be cool.

I am not a Python pro nor you can call me a beginner, I can read the code a little and I found that the labels have a input box for "plugin metadata", so for me a simple approch to solve my second suggestion would be to use that and pass a number of copies to the plugin. But I have no idea how to access those values from a plugin, maybe if someone can point me to a sample. As far as I can see the brother_ql lib does not support printing copies so my simple solution would be to loop the "send" command for the number of copies passed form the metadata of a label. This would be totally enough for me, as I am going to design labels for every use case because they are different in size and information so the number I want to have is also fixed for most of them. And if not I would have to create just a copy and name the label also by the numbers of copies the template prints.

Describe alternatives you've considered

Printing labels not with the Brother plugin but generate the PDF and print that but this results in a slightly different look and size and also uses too many clicks to be a productive solution.

Examples of other systems

No response

Do you want to develop this?

Alex9779 commented 9 months ago

I think I have a working solution for my second suggestion. I changes the end of brother_plugin.py to this:

copies = kwargs['label_instance'].metadata.get('copies')

if not copies:
    send(
        instructions=instructions,
        printer_identifier=f'tcp://{ip_address}',
        backend_identifier='network',
        blocking=True
    )
else:
    i = 1
    while i <= copies:
        send(
            instructions=instructions,
            printer_identifier=f'tcp://{ip_address}',
            backend_identifier='network',
            blocking=True
        )
        i += 1

So with this I can add for example {"copies": 4} to the metadata of a label and get copies...

If this would be a PR would this comply to your standards?

SchrodingersGat commented 9 months ago

Hey @Alex9779 very nice timing - we are currently discussing how to expose custom printing options!

  1. allow setting the amount of copies directly in the printing dialog.

We should be able to implement this very shortly with the new InvenTree printing options feature by @wolflu05

Alex9779 commented 9 months ago

Cool... But I am now very happy whith what I figured out. No matter a better printing dialog with all the features in that dicussion is nice, though I love to have some things pre-configured and just hit one button and get a result. This is what I have now, well not one button, but I have a label for labelling my boxes where I want to have 4 copies every time, hit print, select label, submit... Maybe it would be a nice addition if the label can carry the new options too.

wolflu05 commented 9 months ago

As a simple improvement for your code @Alex9779 and to improve readability, I would suggest the following:

    copies = kwargs['label_instance'].metadata.get('copies', 1)
    for _ in range(copies):
        send(
            instructions=instructions,
            printer_identifier=f'tcp://{ip_address}',
            backend_identifier='network',
            blocking=True
        )

This uses 1 as a default if copies is not specified and don't errors out if the key copies is not set. That way the if else and duplicate send logic is unnecessary. And secondly, instead of a while you could use the more pythonic approach using the for i in range(n) approach.

Printing options would be very interesting use case for solving this too, but I'm not sure if this should be handled by each printing driver (later machine inventree/InvenTree#4824)? But I think @Alex9779 now wants something which can be set per label now, and I think adding dedicated label options would only complicate everything, because where is defined what options are available? I mean printing plugins are selected after a label template is defined, a template can be printed using multiple printer plugins. The best think to use here which is already there is metadata.

I think the best thing for @Alex9779 to go is using his metadata approach in combination with a custom printing plugin. Maybe he can invoke the print_label function from the Brother plugin x times with his plugin, so business logic about printing doesn't need to be duplicated?

Maybe something like this? (Or even some king of proxy functionality for using the printing args for letting a user define the amount of copies and the target plugin.)

from plugin import registry
...
  def print_label(self, *args, **kwargs):
    copies = kwargs['label_instance'].metadata.get('copies', 1)
    plugin_slug = kwargs['label_instance'].metadata.get('printing_driver', 'brother')
    for _ in range(copies):
      brother_plg = registry.get_plugin(plugin_slug)
      brother_plg.print_label(*args, **kwargs)
Alex9779 commented 9 months ago

Nice, thanks for your detailed explanation, I think I am going to play with that. For this simple functionality for copies your code demo is alomst the full plugin.

Alex9779 commented 9 months ago

Ok I developed my system a bit further and came to the point where I wanted to add addtional printing parameters to a label configuration like everything which has to do with the label roll in the printer like paper size and rotation. So just building a plugin for copies is not enough anymore. I don't like to change the main configuration in the brother plugin just if I change the label. So I modified the brother plugin to allow overriding those parameters with metadata in a fork. I think this is a custom solution now for me and I just wanted you to know. For the moment it seems it is something just I need so I will maintain my fork and use that and see what's coming next.

Thanks so...

SchrodingersGat commented 9 months ago

@Alex9779 check out the PR in https://github.com/inventree/inventree-brother-plugin/pull/31 - comments welcome :)