Copied to clipboard

Flag this post as spam?

This post will be reported to the moderators as potential spam to be looked at


  • Michael Nielsen 82 posts 362 karma points
    Dec 16, 2020 @ 12:51
    Michael Nielsen
    0

    Bulk Action Print

    Hi

    I'm trying to setup a bulk action to print out packing slips.

    I've got my "Print" button into the backend, but when I hit it, I can see that it runs my function once for every item selected.

    What I expected, was to be able to get an array of ids, so I can render the print output for the orders in a single document, and then open a print dialog.

    Anyone have any ideas on how to solve this?

  • Matt Brailsford 4123 posts 22194 karma points MVP 9x c-trib
    Dec 16, 2020 @ 13:10
    Matt Brailsford
    0

    Hi Michael,

    Unfortunately this is just how bulk actions work, and is inline with how core bulk actions work. The action is performed 1 by 1 on each item allowing for the progress to be updated in the selection header.

    We are planning to do some work on bulk actions to allow performing a "configuration" step which could be to display a dialog to select options, but we haven't gotten to this work item yet.

    The better option might be to add a Menu Action instead and then present a dialog in which you can control everything.

    Hope this helps

    Matt

    PS Maybe Callum Whyte could offer some advice here as I'm pretty sure he's done something like this and is planning on open sourcing it.

  • Michael Nielsen 82 posts 362 karma points
    Dec 16, 2020 @ 13:44
    Michael Nielsen
    0

    Thats a bummer, especially for the webshop owners, as bulk printing packing slips is something they really need.

    As of now, the only option they have for printing out packing slips, is to bcc themselves the order confirmation mail, and to print that.

    I've looked at Callums Order Label project, but as far as I can tell, it converts an order to a zip file. There isn't really anything in there that can help with a bulk printing option.

    I could put it anywhere else in Menu action or Dashboard, but I feel that it belongs in the orderlist, along with other bulk actions for e.g: Send Email, Change Orderstatus, Capture.

    I'll try and see if I can come up with some kind of solution.

  • Matt Brailsford 4123 posts 22194 karma points MVP 9x c-trib
    Dec 16, 2020 @ 14:55
    Matt Brailsford
    0

    Hi Michael,

    I totally agree the bulk action would be a better location for this, and as I say, it's definitely something we want to improve, I'm just trying to get you to a solution that's available now.

    Maybe we will extend on the default behavior of bulk actions and let them expose a setting to say whether they can handle the entire selection, or should run one by one, then we could cater for both options.

  • Michael Nielsen 82 posts 362 karma points
    Dec 18, 2020 @ 09:46
    Michael Nielsen
    0

    As an alternative, it would be nice to be able to add buttons here https://prnt.sc/w58vfu

  • Matt Brailsford 4123 posts 22194 karma points MVP 9x c-trib
    Dec 18, 2020 @ 09:52
    Matt Brailsford
    0

    Hey Michael,

    That's a nice idea. I'll see what we can do to extend that too 👍

    Matt

  • Michael Nielsen 82 posts 362 karma points
    Dec 18, 2020 @ 10:39
    Michael Nielsen
    0

    I'm close to, not the perfect solution, but one that would work, but Angular is tripping me up...

    When the user clicks the Print button, I call a surface controller, that returns the html to be printed.

    angular.module('vendr')
            .factory('vendrPackingSlipsResource', ['$http', 'umbRequestHelper', function ($http, umbRequestHelper) {
                return {
                    printPackingSlips: function (orderId) {
                        return umbRequestHelper.resourcePromise(
                            $http.get('/Umbraco/Surface/PrintOrder/Print',{
                                params: {
                                    orderId: orderId
                                }
                            }, 'Failed to print orders')
                        );
                    }
                }
            }])
    

    I figured I could just add then() to the $http.get, to open up a new window for every bulk item, not perfect, but it would be an ok alternative

    .then(function successCallback(response) {
          var win = window.open()
          win.document.write(response.data)
          win.print();
          win.close();
     }, function errorCallback(response) {
    
     })
    

    But adding that seems to block further $http.get, so it only does it for the first item. 🤔

    Anyone with a suggestion to what I'm doing wrong, or what I can do instead?

  • Matt Brailsford 4123 posts 22194 karma points MVP 9x c-trib
    Dec 18, 2020 @ 11:23
    Matt Brailsford
    1

    I believe your then also needs to return a response as that then becomes the promise fed into the bulk action sequence. By not returning a response, it means the actions promise never resolves and so it never completes.

    Hope this helps

    Matt

  • Matt Brailsford 4123 posts 22194 karma points MVP 9x c-trib
    Dec 18, 2020 @ 11:31
    Matt Brailsford
    1

    PS I had a chat with Callum about this yesterday, and I do think there might be a workaround.

    My thought is that you add a bulk action, but in the doAction you launch a dialog for whatever config you want and in it's success handle, you perform some action to process all the selected items and then return the doAction promise (promises should wait indefinitely so launching the dialog should be fine). Before you return the promise though, store a reference globally to show that you have really completed your action, and then in your doAction you check this flag before perming the above mentioned logic, thus the dialog / processing logic only occurs in first action. If the flag is set, then have all other calls to doAction just return a successful promise.

    To clear the flag when everything is completed, you could implement the bulk actions getSuccessMessage(total) and in there reset the flag, and then return the message response $q.resolve(total + " items successfully processed");

    Ultimately, you use the first doAction call of the bulk action process to actually perform your action, and then all other doAction calls just skip, and then your reset your flag at the end.

    Not ideal, but it could work.

  • Michael Nielsen 82 posts 362 karma points
    Dec 18, 2020 @ 12:24
    Michael Nielsen
    101

    Oh... I did try and return nothing, which did not work, but returning the response gives me a callback for all bulk items.

    Now it opens a new tab for every bulk item, with the print dialog, and after printing or cancelling, it closes the window, and opens a new for the next bulk item, repeating for all selected items.

    That is an acceptable solution for now.

    If anyone else need something similar, then it looks like this

    angular.module('vendr')
        .factory('vendrPackingSlipsResource', ['$http', 'umbRequestHelper', function ($http, umbRequestHelper) {
            return {
                printPackingSlips: function (orderId) {
                    return umbRequestHelper.resourcePromise(
                        $http.get('/Umbraco/Surface/PrintOrder/Print',{
                            params: {
                                orderId: orderId
                            }
                        }, 'Failed to print orders')
                    ).then(function successCallback(response) {
                        var win = window.open()
                        win.document.write(response)
                        win.print();
                        win.close();
    
                        return response;
                    }, function errorCallback(response) {
    
                    });
                }
            }
        }])
    
Please Sign in or register to post replies

Write your reply to:

Draft