Unicenta OPOS 3.02 allows the use of Print to Kitchen in Product > Stock page
This code builds on Ronnie G's script and dispenses with the need to have reference numbers set aside for different product catagories.
Thanks to Chris J from the Unicenta forge for helping me work this one out!
Assigning Attributes
Add this code to the Product > Properties of each item you have. On Ronnie G's page there is a way to do this to all products at once.
<?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>
If it is a Bar item use:
<?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>
Edit Ticket.Buttons
Make sure the following permissions are allowed in Ticket.Buttons
<event key="ticket.change" code="event.change"/> <event key="ticket.addline" code="event.addline"/> <event key="ticket.removeline" code="event.removeline"/> <event key="ticket.setline" code="event.setline"/>
Create a Script.SendOrder
Rename the existing script.SendOrder to script.SendOrder1
Create a new script called script.SendOrder and populate it with:
// Print an order ticket to the Kitchen boolean kitchen = false; boolean change_kitchen = false; for(int i= 0; i < ticket.getLinesCount(); i++){ line = ticket.getLine(i); if (line.getProperty("sendstatus") == null){ line.setProperty("sendstatus", "No"); } if (line.isProductKitchen()){ line.setProperty("printkb", "Kitchen"); } if((line.isProductKitchen()) && (line.getProperty("sendstatus").equals("No"))){ kitchen = true; //There is something to print to kitchen }else if((line.isProductKitchen()) && (line.getProperty("sendstatus").equals("Cancel"))){ change_kitchen = true; //There is something to change for kitchen } } if ((change_kitchen && kitchen) || (change_kitchen && !kitchen)) { sales.printTicket("Printer.TicketChange_Kitchen"); //Print changed kitchen items to kitchen printer } if (kitchen && !change_kitchen) { sales.printTicket("Printer.TicketKitchen"); //Print kitchen items to kitchen printer } //Show a nice message for confirmation if (kitchen){ javax.swing.JOptionPane.showMessageDialog(null, "Your order has been sent to the Kitchen."); } else if (change_kitchen){ javax.swing.JOptionPane.showMessageDialog(null, "Your changes 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); } }
Create an event.addline script
Create a new script called event.addline and populate it with
//Remove nulls for unknown products if (line.getProperty("printkb") == null){ line.setProperty("printkb", "N/A"); } //Unknown or added products are set as Send to avoid sending them anywhere if (line.getProperty("sendstatus") == null){ line.setProperty("sendstatus", "Yes"); }
Create an event.removeline script
Create a new script called event.removeline and populate it with
// 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"; String d = "Bar"; 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 if (ticket.getLine(i).isProductCom() && ticket.getLine(i).getProperty("sendstatus").equals("Bar")){ 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); } //Allow for removal of Bar items if (a.equals(d) && !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(d) && line.isProductCom()) { ticket.removeLine(index); } //Cancel event removeLine.cancel=true;
Create an event.setline script
// 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.isProductKitchen()) && (!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;
Create/Edit script.EventTotal
Either create one if you dont have it or edit the contents to show:
// script.Event.Total // This script requires ALL Kitchen items to be sent to Kitchen Printer before Payment // ************************************************************************** for(int i= 0; i < ticket.getLinesCount(); i++){ line = ticket.getLine(i); if((line.isProductKitchen()) && (line.getProperty("sendstatus").equals("No"))){ mySent = "No"; } } if (mySent == "No"){ javax.swing.JOptionPane.showMessageDialog(null, "Before closing ticket: Please Send Order to Kitchen", "Send Check", JOptionPane.WARNING_MESSAGE); return "Cancel"; }else{ return Null; }
Create a Printer.TicketKitchen script
If you already have one rename the existing Printer.TicketKitchen to Printer.TicketKitchen1 or something then create a new one and populate it with:
<?xml version="1.0" encoding="UTF-8"?> <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 size="1"> <text align="center" length="42" bold="true">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 bold="true">${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 #if ($ticketline.productAttSetInstId) <line> <text align ="left" length="42"> ${ticketline.productAttSetInstDesc}</text> </line> #end #end <line> <text>------------------------------------------</text> </line> <line> <text align="left" length="15">Cashier:</text> <text>${ticket.printUser()}</text> </line> </ticket> </output>
Create a Printer.TicketChange_Kitchen script
<?xml version="1.0" encoding="UTF-8"?> <output> <display> <line> <text align="left" length="10">Changes 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> #if ($ticketline.productAttSetInstId) <line> <text align ="left" length="42"> ${ticketline.productAttSetInstDesc}</text> </line> #end #end #end <line> <text>------------------------------------------</text> </line> <line> <text align="left" length="15">Cashier:</text> <text>${ticket.printUser()}</text> </line> </ticket> </output>
Restart
Restart Unicenta POS and log in to test it out!
Using this with other scripts
If you want to combine this script with others, some tinkering will be needed.
Here I will show the common/inclusive ones in 3.02 (I will add more if I get requests)
Consolidate Receipts
To use this script with consolidate receipts as they both point to ticket.total you will need to either:
- Add the contents of script.event.total to the TOP of Script.ReceiptConsolidate,
- Or visa versa add script.ReceiptConsolidate to BELOW script.Event.Total
Then you will need to modify the permissions in Ticket.Buttons so that whichever you want is the only one allowed (use brackets to stop the other)
Stock Additions and Removal
To allow the use of the Stock control in 3.02 you will need to:
- Remove permissions from the following in Ticket.Buttons by adding <!-- --> brackets
<!-- <event key="ticket.addline" code="event.addline"/> --> <!-- <event key="ticket.setline" code="event.setline"/> -->
- Then allow the Stock permissions:
SET Stock Level Checking (Default=ENABLED) <event key="ticket.addline" code="script.StockCurrentAdd"/> <event key="ticket.setline" code="script.StockCurrentSet"/>
- Copy the contents of event.addline to the BOTTOM of script.StockCurrentAdd
- Copy the contents of event.setline to the BOTTOM of script.StockCurrentSet
I also found it easier to change the }else if { part of the Stock scripts to if (line.isProductKitchen()){ which will allow you to add custom products or prices without it telling you that the custom thing you just entered is out of stock!