Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Best Practice for Writing a POS System

I'm putting together a basic Point of Sale (POS) system in C# that needs to print to a receipt printer and open a cash drawer. Do I have to use the Microsoft Point of Service SDK?

I've been playing around with printing to my Samsung printer using the Windows driver that came with it, and it seems to work great. I assume though that other printers may not come with Windows drivers and then I would be stuck? Or would I be able to simply use the Generic/Text Driver to print to any printer that supports it?

For the cash drawer I would need to send codes directly to the COM port which is fine with me, if it saves me the hassle of helping clients setup OPOS drivers on there systems.

Am I going down the wrong path here?

like image 698
Gary Avatar asked Mar 15 '10 16:03

Gary


People also ask

What makes a good POS system?

Ideally, your system should create detailed sales reports, complete with charts and graphs. It also should have an easy-to-comprehend dashboard that provides sales, cash, and inventory data in real time.

What is the best programming language for POS system?

POSXML (acronym for Point Of Sale eXtended Markup Language) is a programming language, based on XML, that is used to create applications for a POS terminal. Normally the programming language used to develop such applications is C or C++.

What is the best practice for protecting point of sale equipment?

Install Antivirus on the POS System This is a simple and obvious solution for preventing POS attacks. If you want to ensure harmful malware doesn't infiltrate your system, install endpoint protection software on your device.


2 Answers

This is probably a slightly different answer to what you were looking for(!)...

When working with "external interfaces" (e.g. printers, cash draws etc) always abstract things. You probably want to implement strategies - Pattern Strategy.

You make an interface for the cash draw:

public interface ICashDrawer
{
    void Open();
}

The provide implementations:

  • one strategy is a class that uses COM to open the draw
  • another is something as simple as a class that does a Debug.WriteLine call so you don't need a cash draw connected to your PC during development

e.g.

public class ComPortCashDrawer : ICashDrawer
{
    public void Open()
    {
        // open via COM port etc
    }
}

public class DebugWriterCashDrawer : ICashDrawer
{
    public void Open()
    {
        Debug.WriteLine("DebugWriterCashDrawer.Open() @ " + DateTime.Now);
    }
}

Again for printing you have a print interface that takes the data:

public interface IRecieptPrinter
{
    bool Print(object someData);
}

then you make one or more implementations.

  • Basic printer
  • Specialized label printer
  • a text based one that saves to a file...

e.g.

public class BasicRecieptPrinter : IRecieptPrinter
{
    public bool Print(object someData)
    {
        // format for a basic A4 print
        return true; // e.g. success etc
    }
}

public class SpecificXyzRecieptPrinter : IRecieptPrinter
{
    public bool Print(object someData)
    {
        // format for a specific printer
        return true; // e.g. success etc
    }
}

public class PlainTextFileRecieptPrinter : IRecieptPrinter
{
    public bool Print(object someData)
    {
        // Render the data as plain old text or something and save 
         // to a file for development or testing.
        return true; // e.g. success etc
    }
}

With respect to the SDK, if down the track you find you need it for some reason you write implementations using the SDK. Over time you may end up with several ways to interface with different external devices. The client may get a new cash draw one day etc etc.

Is that clear, I can flesh out what I mean if you want but you probably get my drift.

Your app sets itself up with the respective implementations at startup, you may want to take a look at Dependency injection as well and you will find things easier if you use a container to resolve the types.

var printer = container.Resolve<IRecieptPrinter>();

PK :-)

like image 54
Paul Kohler Avatar answered Sep 28 '22 07:09

Paul Kohler


I've never dealt programmatically with what you're asking, but I do have some experience when it comes to POS systems which may help you.

What you do for printing and for the cash drawer are highly dependent on the hardware you're working with. And there is a wide variety of hardware out there.

In every POS system I've seen, there are multitudes of drivers for every conceivable receipt printer and cash drawer, so unless you're developing a full-blown system, just concentrate on the specific hardware you're going to be working with. Even then, try to factor your code well so that you maximize the benefit of the strategy pattern. If you're working with more than one type of device, you'll thank yourself later for implementing it that way.


For printing, there are 3 fundamental types of printers you may encounter:

  1. Receipt printer that can only print text (antiquated, but still around)
  2. Receipt printer that can print graphics
  3. A standard printer printing 8.5" x 11" full-page invoices/credit memos (easy, 'nuff said)

I believe most, if not all, modern receipt printers fall into category #2, but you could run into a legacy system using a printer from category #1.

For category #2, you should be able to use the standard .NET printing interface. The only issue may be sending a control code to activate the cutting mechanism (if equipped) at the appropriate time(s); or, the printer driver may do it automatically based on the paper length specified in the printing algorithm. Again, I've never tried this, but if you have access to a receipt printer, you should be able to figure this stuff out in a hurry.

If you're dealing with a single client who has a printer in category #1, you can make a good argument that it will be less expensive to buy a new printer in category #2 than it will be to pay you to develop a dead-end driver to print on their existing hardware.


For cash drawers, I'm less familiar than with printers, but I know of two options as far as communication and hardware arrangement:

  1. Attaches via LPT port through the printer. (Cable chain: computer --> printer --> cash drawer)
  2. Attached directly to the computer, either by a COM/LPT port or probably USB in a modern one.

The first kind operates by sending control codes to the printer port (which the printer would hopefully ignore and not spit out an entire roll of receipt paper), while for the second you'll need to do the COM port communication stuff. In either case, the control codes are hardware-dependent. Most of the time they're found in the user manual, but sometimes the technical writer was feeling particularly evil that day, and you'll have to go digging online.

like image 28
Jon Seigel Avatar answered Sep 28 '22 08:09

Jon Seigel