POS - Kitchen\Bar Printing
Code snippetName: POS - Kitchen\Bar Printing
|
This code was created using mySQL in Windows.
These scripts will allow you to print different product items to different printers. In this example we use two printers (kitchen & bar). For more help you can try this thread.
1) Setting the Attributes
Start by setting the attribute property (call it 'printkb') for each product item to either Kitchen or Bar. I have used the product REFERENCE of 0001-1999 for BAR and 2000 upwards for KITCHEN. Do this is in MySQL after all the products have been added. Then use the MySQL Query Browser and run the following two statements in the 'products' table:
UPDATE products SET Attributes = '<?xml version="1.0" encoding="UTF-8" standalone="no"?> <!DOCTYPE properties SYSTEM "http://java.sun.com/dtd/properties.dtd"> <properties> <entry key="printkb">Kitchen</entry> <entry key="sendstatus">No</entry> </properties>' where REFERENCE >= 2000 ;
UPDATE products SET Attributes = '<?xml version="1.0" encoding="UTF-8" standalone="no"?> <!DOCTYPE properties SYSTEM "http://java.sun.com/dtd/properties.dtd"> <properties> <entry key="printkb">Bar</entry> <entry key="sendstatus">No</entry> </properties>' where REFERENCE < 2000 ;
Your properties have now been set.
In case you don't have MySQL, PostgreSQL, etc. and you don't have too many products listed, another way to set the properties is by adding the code in the "preferences" Tab of your products. e.g.
<?xml version="1.0" encoding="UTF-8" standalone="no"?> <!DOCTYPE properties SYSTEM "http://java.sun.com/dtd/properties.dtd"> <properties> <entry key="printkb">Bar</entry> <entry key="sendstatus">No</entry> </properties>
2) Add Button & Events to the Ticket.Buttons Resource
Add the following button & events to the Ticket.Buttons resource:
<button key="button.sendorder" name="button.sendorder" code="Script.SendOrder"/> <event key="ticket.addline" code="event.addline"/> <event key="ticket.removeline" code="event.removeline"/> <event key="ticket.setline" code="event.setline"/> <event key="ticket.total" code="event.total"/>
3) Add Columns to the Ticket.Line Resource
To see what the properties are set to in the Sales panel, add two columns to the resource Ticket.Line. Add them after <line>:
<column name="label.sendorder" width="5" align="left" value="${ticketline.getProperty('printkb','??')}"/> <column name="label.sendstatus" width="5" align="left" value="${ticketline.getProperty('sendstatus','??')}"/>
4) Set Button Name and Column Name Labels
Add the following to the bottom of the pos_messages.properties file in locales folder:
button.sendorder=Send label.sendorder=Dest. label.sendstatus=Sent
5) Give Permission to the Send Order Button
In Maintenance > Roles, give permission to the Print Order button. Add the following line:
<class name="button.sendorder"/>
6) Add the Script SendOrder
Create a text resource called Script.SendOrder. Add the following script to it:
// Print an order ticket to the Kitchen & Bar\Dessert boolean kitchen = false; boolean bar = false; boolean change_kitchen = false; boolean change_bar = false; for(int i= 0; i < ticket.getLinesCount(); i++){ line = ticket.getLine(i); // Set Discount(printkb=NULL) to N/A so it does not error on next section. if (line.getProperty("printkb") == null){ line.setProperty("printkb", "N/A"); } if (line.getProperty("sendstatus") == null){ line.setProperty("sendstatus", "No"); } if((line.getProperty("printkb").equals("Kitchen")) && (line.getProperty("sendstatus").equals("No"))){ kitchen = true; //There is something to print to kitchen }else if ((line.getProperty("printkb").equals("Bar")) && (line.getProperty("sendstatus").equals("No"))){ bar = true; //There is something to print to bar }else if ((line.getProperty("printkb").equals("Kitchen")) && (line.getProperty("sendstatus").equals("Cancel"))){ change_kitchen = true; //There is something to change for kitchen }else if ((line.getProperty("printkb").equals("Bar")) && (line.getProperty("sendstatus").equals("Cancel"))){ change_bar = true; //There is something to change for bar } } if ((change_kitchen && kitchen) || (change_kitchen && !kitchen)) { sales.printTicket("Printer.TicketChange_Kitchen"); //Print changed kitchen items to kitchen printer } if ((change_bar && bar) || (change_bar && !bar)) { sales.printTicket("Printer.TicketChange_Bar"); //Print changed bar items to bar printer } if (kitchen && !change_kitchen) { sales.printTicket("Printer.TicketKitchen"); //Print kitchen items to kitchen printer } if (bar && !change_bar) { sales.printTicket("Printer.TicketBar"); //Print bar items to bar printer } //Show a nice message for confirmation if (kitchen && bar){ javax.swing.JOptionPane.showMessageDialog(null, "Your order has been sent to the Kitchen & Bar."); } else if (kitchen && !bar){ javax.swing.JOptionPane.showMessageDialog(null, "Your order has been sent to the Kitchen only."); } else if (!kitchen && bar){ javax.swing.JOptionPane.showMessageDialog(null, "Your order has been sent to the Bar only."); } else if (change_kitchen || change_bar){ javax.swing.JOptionPane.showMessageDialog(null, "Your cancelled items have been sent."); } else { javax.swing.JOptionPane.showMessageDialog(null, "There is nothing new to send.", "Print Warning", JOptionPane.WARNING_MESSAGE); } //Set printkb property of item to Yes so it is not printed again for(int i = ticket.getLinesCount()-1; i>= 0 ; i--){ line = ticket.getLine(i); String a = line.getProperty("sendstatus"); String b = "Cancel"; if(((line.getProperty("printkb").equals("Kitchen")) || (line.getProperty("printkb").equals("Bar"))) && (line.getProperty("sendstatus").equals("No"))){ line.setProperty("sendstatus", "Yes"); } //Remove cancelled lines if (a.equals(b)) { ticket.removeLine(i); } }
7) Create the event.addline Resource
Create a text resource called event.addline and add the following to it:
//Remove nulls for unknown products if (line.getProperty("printkb") == null){ line.setProperty("printkb", "N/A"); } //No need to send unknown products anywhere if (line.getProperty("sendstatus") == null){ line.setProperty("sendstatus", "Yes"); }
8) Create the event.removeline Resource
Create a text resource called event.removeline and add the following to it:
// Set SendStatus and print removals line = ticket.getLine(index); //Remove nulls for unknown products if (line.getProperty("printkb") == null){ line.setProperty("printkb", "N/A"); } //No need to send unknown products anywhere if (line.getProperty("sendstatus") == null){ line.setProperty("sendstatus", "No"); } String a = line.getProperty("sendstatus"); String b = "Yes"; String c = "No"; Integer myCount = 0; //get count of auxiliar after the main product for (i = index+1; i < ticket.getLinesCount(); i++) { if (ticket.getLine(i).isProductCom()){ myCount = myCount + 1; }else{ break; } } //Set SendStatus of sent items to Cancel if (a.equals(b) && !line.isProductCom()) { for (i = index + myCount; i>= index ; i--) { if (ticket.getLine(i).isProductCom() && ticket.getLine(i).getProperty("sendstatus").equals("Yes")){ ticket.getLine(i).setProperty("sendstatus", "Cancel"); }else if (ticket.getLine(i).isProductCom() && ticket.getLine(i).getProperty("sendstatus").equals("No")){ ticket.removeLine(i); }else{ break; } } line.setProperty("sendstatus", "Cancel"); } //Removelines of NOT sent items if (a.equals(c) && !line.isProductCom()) { for (i = index + myCount; i>= index ; i--) { if (ticket.getLine(i).isProductCom()){ ticket.removeLine(i); }else{ break; } } ticket.removeLine(index); }else if (a.equals(c) && line.isProductCom()) { ticket.removeLine(index); } //Cancel event removeLine.cancel=true;
9) Create the event.setline Resource
Create a text resource called event.setline and add the following to it:
// Set Discount(printkb=NULL) to N/A so it does not error on next section. if (line.getProperty("printkb") == null){ line.setProperty("printkb", "N/A"); } if (line.getProperty("sendstatus") == null){ line.setProperty("sendstatus", "No"); } //Stop the line modification of sent products if (!line.getProperty("sendstatus").equals("No")){ JOptionPane.showMessageDialog(null, "You cannot modify a sent item.", "Error", JOptionPane.ERROR_MESSAGE); }else{ ticket.setLine(index, line); } cancel=true;
10) Create the event.total Resource
Create a text resource called event.total and add the following to it:
//Stop payment when all items not sent for(int i= 0; i < ticket.getLinesCount(); i++){ line = ticket.getLine(i); // Set Discount(printkb=NULL) to N/A so it does not error on next section. if (line.getProperty("printkb") == null){ line.setProperty("printkb", "N/A"); } if (line.getProperty("sendstatus") == null){ line.setProperty("sendstatus", "No"); } if(line.getProperty("sendstatus").equals("No") || line.getProperty("sendstatus").equals("Cancel")){ mySent = "No"; } } if (mySent == "No"){ javax.swing.JOptionPane.showMessageDialog(null, "You must Send all items to Kitchen and/or bar before payment", "Send Warning", JOptionPane.WARNING_MESSAGE); return "Cancel"; }else{ return null; }
11) Create the Kitchen and Bar Printer Tickets
Create four text resources for tickets called Printer.TicketKitchen, Printer.TicketBar, Printer.TicketChange_Kitchen & Printer.TicketChange_Bar.
Add the following to the Printer.TicketKitchen & Printer.TicketBar though replace the word Kitchen with Bar in the Printer.TicketBar resource.
<?xml version="1.0" encoding="UTF-8"?> <!-- Openbravo POS is a point of sales application designed for touch screens. Copyright (C) 2008 Openbravo, S.L.U. http://sourceforge.net/projects/openbravopos This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA --> <output> <display> <line> <text align="left" length="10">Order sent to Kitchen</text> <text align="right" length="10">${ticket.printTotal()}</text> </line> <line> <text align="center" length="20">Thank you.</text> </line> </display> <ticket printer = "2"> <line></line> <line></line> <line> <text align="center" length="42">Kitchen Order</text> </line> <line></line> <line> <text align="left" length="15">Receipt:</text> <text>${ticket.printId()}</text> </line> <line> <text align="left" length="15">Date:</text> <text>${ticket.printDate()}</text> </line> #if ($ticket.getCustomer()) <line> <text align="left" length="15">Customer:</text> <text>${ticket.getCustomer().getName()}</text> </line> <line> <text align="left" length="15"></text> <text>${ticket.getCustomer().getTaxid()}</text> </line> #end #if ($place != "") <line> <text align="left" length="15">Table:</text> <text>${place}</text> </line> #end <line></line> <line> <text align ="left" length="17">Item</text> <text align ="right" length="5"></text> </line> <line> <text>------------------------------------------</text> </line> #foreach ($ticketline in $ticket.getLines()) #if (($ticketline.getProperty("printkb").equals("Kitchen")) && ($ticketline.getProperty("sendstatus").equals("No"))) <line> <text align ="left" length="5" bold="true">${ticketline.printMultiply()}x</text> #if ($ticketline.isProductCom()) <text align ="left" length="37">--${ticketline.printName()}</text> #else <text align ="left" length="37" bold="true">${ticketline.printName()}</text> #end </line> #end <!-- Add the following lines only for 2.30 Attributes --> #if ($ticketline.productAttSetInstId) <line> <text align ="left" length="42"> ${ticketline.productAttSetInstDesc}</text> </line> #end <!-- Add the previous lines only for 2.30 Attributes --> #end <line> <text>------------------------------------------</text> </line> <line> <text align="left" length="15">Cashier:</text> <text>${ticket.printUser()}</text> </line> </ticket> </output>
Add the following to the Printer.TicketChange_Kitchen & Printer.TicketChange_Bar though replace the word Kitchen with Bar in the Printer.TicketChange_Bar resource.
<?xml version="1.0" encoding="UTF-8"?> <!-- Openbravo POS is a point of sales application designed for touch screens. Copyright (C) 2008 Openbravo, S.L.U. http://sourceforge.net/projects/openbravopos This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA Ticket for changing a Sent Kitchen Order --> <output> <display> <line> <text align="left" length="10">Change Sent</text> <text align="right" length="10">${ticket.printTotal()}</text> </line> <line> <text align="center" length="20">Thank you.</text> </line> </display> <ticket printer = "2"> <line></line> <line></line> <line size="1"> <text align="center" length="42" bold="true">Changed Kitchen Items</text> </line> <line></line> <line> <text align="left" length="15">Receipt:</text> <text>${ticket.printId()}</text> </line> <line> <text align="left" length="15">Date:</text> <text>${ticket.printDate()}</text> </line> #if ($ticket.getCustomer()) <line> <text align="left" length="15">Customer:</text> <text>${ticket.getCustomer().getName()}</text> </line> <line> <text align="left" length="15"></text> <text>${ticket.getCustomer().getTaxid()}</text> </line> #end #if ($place != "") <line> <text align="left" length="15">Table:</text> <text>${place}</text> </line> #end <line></line> <line> <text align ="left" length="17">Item</text> <text align ="right" length="5"></text> </line> <line> <text>------------------------------------------</text> </line> #foreach ($ticketline in $ticket.getLines()) #if (($ticketline.getProperty("printkb").equals("Kitchen") && $ticketline.getProperty("sendstatus").equals("Cancel"))||($ticketline.getProperty("printkb").equals("Kitchen") && $ticketline.getProperty("sendstatus").equals("No"))) <line> #if ($ticketline.getProperty("sendstatus").equals("No")) <text align ="left" length="7" bold="true">Add</text> #else <text align ="left" length="7" bold="true">${ticketline.getProperty("sendstatus")}</text> #end <text align ="left" length="5" bold="true">${ticketline.printMultiply()}x</text> #if ($ticketline.isProductCom()) <text align ="left" length="30">--${ticketline.printName()}</text> #else <text align ="left" length="30" bold="true">${ticketline.printName()}</text> #end </line> <!-- Add the following lines only for 2.30 Attributes --> #if ($ticketline.productAttSetInstId) <line> <text align ="left" length="42"> ${ticketline.productAttSetInstDesc}</text> </line> #end <!-- Add the previous lines only for 2.30 Attributes --> #end #end <line> <text>------------------------------------------</text> </line> </ticket> </output>
If the bar printer is also the receipt printer, change <ticket printer = "2"> to <ticket> for the resources Printer.TicketBar & Printer.TicketChange_Bar. You can set printer script to either:
<ticket> <ticket printer = "2"> <ticket printer = "3">
to direct it to which printer you want it printed on.
That should be it. You can obviously change anything you wish to suite your setup. Lets me know if something is not working or something can be bone better.
Good Luck, Ronny G