I was once asked:
“Why write something that has already been written many times and on a more professional level? What you do will obviously be worse and deprived of competent support. ” I then answered simply: “I would like it to be a linux and that the code is free. So as not to buy drivers for the cash register .
"Yes,
Linux checkout under the GPL . In these words, in fact, is the exact description of this craft. This is an absolutely free code, parts of which can be easily separated and used in their developments. The second version was the answer to all the innovations in retail. Now, it can be said that the cashier is in charge of all these new requirements and continues to exist in the alternative space of self-written coding.
What for goat boyan?
In general, of course, “why?” Is a very important question. They need to be puzzled in advance. Before you write something, you need to assess the need, the usefulness, so that it will not hurt yourself later. I later, more than once assessed why I was doing this project, I found clever explanations, but in fact ... just so that under Linux and so that the code is free. And, of course, drivers for fiscal devices - this is little understood by me business.
')
So, I wanted to make some basis for the cash workplace, which could be changed for their tasks. Say what you like, but very many are modifying the box office "for themselves." Cashier would have to work under Linux, in a web browser, and its server part could theoretically be located anywhere. Now fiscal registrars are already “almost” obliged to have a network interface, which means that the server part can be anywhere. Though at your home in the nightstand on raspberry. This is no longer news, the ticket office mutates. The interface of the ticket office climbs onto tablets and phones.
In general, you can find almost free and almost free cash register software. Something will not be completely free, not always free, cumbersome and not separable from its own system. So often it happens that a simple project becomes more complicated and creates its own whole environment, from which it cannot be torn off. It was not possible to find the necessary software with the web interface. Well, then I rolled up my sleeves, and a month later, and my eyes ... And the coder
hell appeared like paradise before me.
First version. With wild eyes and manic hard work.

The first version, I made it fast. About this, I wrote an article on Habré once. Yes, there were a lot of errors and terrible code. But it performed at the time the task minimum. In the beginning it was a light and weak (almost HTML) website in
PHP and several utilities on python.
MySQL database , data transport with pearl scripts. Back office also has a site for viewing checks and derivative reports. The free driver for Shtrikh-M, written by a coder, was stuck to my system. Although, to be fair, it is more correct to say that this driver served as the basis and nothing would have happened without it. It was then that I realized the main problem of self-written free cash register software - there are no free drivers for PRK.
I was constantly finishing the site, as usual, being late with refactoring and the code had acquired a complex callocode. It happens when it is not clear which way and how far the concept will go. And threw her in different directions is not childish. Various promotions, bonuses, prize systems. The complexity increased, the entropy ate the project from the inside. The cons of the system, which was no longer possible to put up, eventually forced me to rewrite it all. In addition to restoring order in the code, it was necessary to divide in the cash register all the subsystems that had already begun to stick together with each other, multiplying the chaos.
We all came EGAIS! And not only..

By that time, when the writing of the second version was overdue, they had already trumpeted that it was not a long century of ordinary fiscal machines. Let me remind you that over the past two years there have been significant changes in the legislation in the field of retail accounting. And for a long time, the unchanging state of affairs in this sector has been shaken by a series of innovations. The first came EGAIS. Yes, my organization was engaged in the sale of beer and alcohol. My colleagues from other organizations, as well as we, with “joy” met a single electronic document management. I will not whine about the flaws of this system. Now, everything is somehow more or less normal. Of course, the moment of introduction is always especially vivid and memorable days and nights ... Everything was as usual - crazy terms, impossibility of normal testing, difficulty of registration, lack of technical support and the New Year). Now it seems to me that all we did was some kind of unrealistic comedy, the participants of which pretend to be serious.
In general, there were quite a few solutions on the market that could be used to fulfill this requirement. However, we needed to put the JaCarta key on each cash desk and ensure this workflow through the UTM program (Universal Transport Module). At the time of implementation, as is usually the case, the software was only for Windows. Therefore, no matter what fantastic plots the innovators of this business would not draw, telling us how everything will be easy and simple and under any system, in fact it turned out to be wrong to say the least.
In general, by the deadline, we did not have time to equip outlets with new software systems for EGAIS. But, to be honest, I didn’t really want to change the software at fifty sites, buying licensed Windows and cash register software at the same time. Only on the keys JaCarta had to simultaneously throw out decent money. But many then refused to trade in alcohol. Scratching our turnips, we did it the same way. A web service was quickly thrown around, which interacted with a single copy of the UTM and dozens of accounts at trade sites, where the receipt documents were confirmed. A bunch of fifty keys jaCarta was handed over to a specially trained employee. She was supplied with a computer with the necessary software. Peretykaya every day (for six months), the keys and poking the mouse on the site in the right places, the latter-day freelance provider EGAISA exchanged documents. I think we are not the only ones in this idiocy, some are still doing so today.
The sale of alcohol involves working with EGAIS at the time of the sale of each check, and this already required the finalization of the cash register software. Until the moment of introduction it was only six months. So, working at a simple temporary house for receiving EGAIS documents, we quickly quickly began to make the second version of our cash register.
We write on Feng Shui.
So half a year to develop is a lot. The catch is that the developer is essentially one. To help him only a sysadmin. Well, no one freed us from current work. But I really wanted to make a new version, so again I eagerly started to lose. Now there was already an understanding of what independent parts the project should consist of and how to implement these parts.
So, we stopped on the following scheme.
DRIVER SERVER
In addition to the existing driver for Shtrih-M, it was necessary to implement a driver for FPRINT (Atol) and a driver for thermal printers. All of these drivers are unified by the same printing methods and uniform check design.
In general, the idea to connect more and thermal printers, of which we had in bulk, seemed to me successful. I did not know that after two years it would be possible to print only fiscal checks for updated PRK, confirmed online by the fiscal data operator. Although later, the option in which the thermo printer seriously tried to pretend to be a PRK + OFD turned out to be the way during the moments when the fiscal was broken.
Management of fiscal restaurateurs and thermo-printers supporting the ESCPOS protocol should be carried out through a separate web service. That is, all that relates to the interaction with the equipment is separated into a separate independent application, the interaction with which should be carried out according to the XML protocol.

All this was written and tested in a couple of months. I was lucky that I wrote a similar task to order. That is, the implementation of printing on thermal printers for XML was implemented the day before. It remained only to write the driver atolovsky and somehow unify the whole of this
zoo industrial park with the same seal of checks and their copies. The result was a separate service, which I called
DTPrint . He also had a small website for detailed settings of the PRK. Later I wrote a console script with which you could access the service and send it a text file for printing with the necessary parameters. So, at my work, I got my fax-log of messages from the server, which printed all admin info from the server. And later he duplicated messages from the jabber-client pidgin. In general, I did not deny myself anything, in the process of a creative
breakthrough impulse). Oh yeah, the fprint driver also played an imperial march with a beeper after removing the z-report.
SITE OF CASH
As in the first version, the basis should be a web site. Only now without apache and PHP - only
Python . The cashier's interface should become more friendly). It was also necessary to screw admin functions into the interface and service functions for initializing data exchange and other usefulness.
The web ticket office, of course, had to interact with the driver server, the data exchange service, the bonus server, and a number of other back office services.
The data also decided to be stored in
MySQL . I decided to leave the transaction storage system (as in Shtrikh-M). Now it was the checks that were stored in the database entirely. All the necessary additional data about operations with a check were deposited in the form of the values of the header field or the contents of the check. This I wanted to do for a long time. Samples from such a database were simple and concise. Calculation of reports is transparent and without problems.
The structure of the program site should have been divided into separate modules containing subtask objects as much as possible inside. USAIS module, bonus module, check processing module, query database module, etc.
An important addition was to be the implementation of the
Unified State Automated Information System . Firstly, in terms of receiving and confirming parishes, and secondly, in terms of the sale of alcohol. In general, EGAIS, later turned out to be a large and endless stream of various documents, requests and updates. Now, I would single it out in a separate module above the UTM. The UTM program itself was constantly changing, and the protocol was changing. Recently (July 1, 2017) they introduced its second version. It is not convenient to update the key on the
JaCarta token. Although now, many organizations offer to do this remotely, for Linux + JaCarta it is still difficult. Therefore, we update the keys by connecting them to a laptop with
Windows . I think this part could be improved, but it turns out too troublesome.
I hesitated for a long time about how to implement the unloading of checks. If it is simpler to say, I was tormented by the question: “How much online does the checkout box need?”. Will it have online, offline modes, how will the exchange take place? As a result, the ticket office was implemented separately from the exchange function. The site responds to the commands for uploading checks, reporting reports or downloading data from the server. Exchange processes launched with the desired frequency from the
crontab do not affect the operation of the cash register. There is no connection - it doesn't matter, as it appears, the accumulated data on the bounced checks will be gone, the price will be updated.
As practice has shown, the most complicated node is the processing of a check. And this is not only a print, it is mainly a sequential calculation of the check. It was here that all sorts of refinements of the logic of different actions, bonuses, and raffles made the calculation of the check in the first version of an absolutely incomprehensible black hole. Therefore, in the new version, I decided everything that concerns the check to determine as much as possible and beautifully decompose into object methods.

The code was written, it seems to me, quite well. It can always be better, of course. But what was done for a long time was enough for a stable complication of the project without fear of moving into the chaotic code (
G-CODE ). Of course there are some ugliness. So, different ways of interacting with javascript are used. It began with the development of templates in the server part, ended with json loading and more complex javascript functions on the client side.
XML to interact with the server drivers, of course, it would be better to replace json. But, it was no time to recycle. And, of course, I saved on design, as the designer in me died at birth.
On the comments of the system administrator Vovka about the poisonousness of flowers, I just grunted that you need to write several different CSS colors. But in the end only one more was added - gray, and it became the main one. A poisonous admin has become. This was useful in order not to be confused in the cash desk sessions.

One of the advantages was that everything turned out to be divided into the most independent software modules, any of which can be safely rewritten without affecting the main code. In general, this approach seemed to me very correct. With such a mosaic of code, you can assemble different constructions, focusing only on the interaction protocols. However, there is one important point - the protocols should be initially well thought out, so that later it would be easy to refine them and not change the basis.
Simultaneous work by different users with the cash register site made it possible to trade from various devices in the sales area. Later, I modified the module to the checkout in order to work with orders in the style of serving the queue of fast food cafes. Everything turned out to be easily refined and scalable.
It also turned out to be useful to quickly connect to the cashier’s current interface, actually watching his actions online via the browser or stuffing a pending check to himself so as not to stand in line).

In general, the administration speed has increased significantly. It became possible to interfere with the payment process, settings, driver management from the browser on the phone (via VPN). Although no one canceled
VNC and
ssh and all the tools were actively used. Some settings were global and the cash registers themselves took them from the server, at the same time sending information about themselves (essential settings, ip-address, connection time, software version). Over time, at the checkout, a rich
crontab and scripts of any self-diagnostics and sending reports to the server were formed. But there’s nothing to boast about, everyone is doing it.
CASH MANAGEMENT SERVER
For effective administration of cash registers, it was necessary to create a cash register management server itself. At a minimum, all checks from cash registers should have been collected into it and software updates should have occurred through it. As practice has shown, this is a very important task in a samopisny project.
In fact, it was another web service and site. It should have entered the main directories: organizations, prices, product groups., Cash and their type of price. Cash offices should be divided into organizations (branches), which can be any set. Later, an action system was added here - this is writing and distributing action scripts to the cash registers. Well, something like the language of these same actions had to be invented.
The first important function of this server is to accept and distribute new prices to the cash registers, and I began with it. Price lists should have been tied to the box office. That is, on the server itself, we indicate for each cash register our price list available. Cashier just calls the server by telling your ID number. In response, the server gives the go-ahead for GET downloading a zip-archive. If the download was successful, the server itself marks the time of the last download for this client and the price does not give it more. Well, of course, until the new price list is uploaded to the server itself.
And uploading a file to the server is also an ordinary HTTP HTTPUT operation; you only need to specify the ID of the branch office and the price list itself. Later, my friend, to whom we at work also implemented part of my system, on 1C wrote the necessary processing for uploading the price directly to the server. At the same time, they wrote processing for downloading JSON Zet reports from the same server.
The second important function is to collect data from the cash registers. Zet reports and checks. In general, I came to the conclusion that the cash register at the checkout began to form the checkout itself. That is, ready-made, grouped by product, with the necessary final parameters, ZET reports are in the database. And in the web interface you can study them in detail. At the early stage of writing the cash desk, I implemented everything without a data collection server, therefore the cash desk and the server contain identical functions for issuing reports and checks upon request from outside. It turns out that if you wish, you can do without a server, just request data directly from the cashier. So, the cash desk, upon request, forms two data streams in json - the stream of unloaded ZET reports and the stream of unloaded checks. Data is uploaded to the server, and from there on request, it is uploaded for 1C. As an option, scripts were written that download reports to specialized text files, like Shtrih-M files.

From the server interface itself it was possible to view the checks. But this functionality was uncomfortable and not powerful enough. Therefore, later, I wrote another site), through which it was possible to make various samples from the database of checks. I planned to develop this site by adding there the ability to view the Z-reports and other developments on existing working web applications focused on the previous version of IceCash. But alas, it didn’t have enough time for this, it’s just the site of one report.


Also, the server was assigned the
function of updating the cash register software . The updates were of two types: system update and program update. Any update starts with version tracking. The versions that we commission (prod) are simply set by global variables on the server (
update and
upgrade ). All server variables are automatically distributed to the box office. This may also include any global parameters of interest for all cash registers that require constant replication. For example, my temperature is so high. Each branch can have its own set of variables and values, so the weather is distributed regionally. It was not required for fun. There was such an action - according to the weather, there the discount formula was focused on temperature.
So, here, the version prescribed to install the update is also distributed variables, regionally. This is convenient for step testing. First at one box office, then at a small branch, the next day - at a large one. Well, if this is all for Feng Shui, then for us, at the beginning, there were often hard-handed jobs involving the inconsistent version roll.
Updating the program is actually downloading the correct version and replacing the old one with restarting services. The version of the working program, the program knows from a constant in the code. On the server, you can set any larger version than the current one and the cash desk will pick it up.
System update is a tbz archive containing the necessary files and a bash update script. These updates are performed sequentially. All archives are required on the server in order for the ticket office to sequentially install them, updating its status to the required one.

The fact is that we install the cashier by unpacking the dump of the working system, which is not always ... or, more precisely, it is always not fresh enough. Therefore, in order to avoid conflicts between the application and the execution environment, the newly unpacked image itself sequentially rolls in system updates.
In addition to these tasks, the system of creating, storing and distributing
share scripts was also invented. Modern retail can not live without these shares. I do not know how much they are really needed, but for programmers of retail there is a special place in hell - an action system. Shares are constantly in conflict:
- With yourself.
- With a bonus system.
- The system of restrictions based on prices.
- With all systems working with a check.

Shares are capricious and insidious. At the same time, they are always held in high esteem by managers, and the director will necessarily request a detailed analysis of their effectiveness, which boils the brain. And that's not all, the shares simply do not want to be of the same type. Each does not want to be like the others and strives to snatch the extra hours of your attention in order to understand and test this infection. And yes, it is important not to forget to set the current duration of its work.

In general, my attempts to automate the process of creating stocks in the first version did not lead to anything except wasting time and nerves. Therefore, in the second version, I completely refused to create web forms with a million ticks for managers, because the next action will require a million first tick. Instead, I wrote a separate module in which I implemented the mini-language of these actions. And already in this language I consistently described each action with my own script. Check condition, selection, grouping, replacing and adding items, etc.

Sometimes it was necessary to change the script a little bit, sometimes to add a command. But now all the managers and interfaces for them went to the forest. Nervostatraty exactly reduced, it became clearer how it all works. And I did not agree to persuade people to make interfaces for managers, but in jest I suggested studying the language of actions and writing scripts on it.
additional services
We have already developed our own bonus system as a service in
Python + Mysql . Therefore, only a module for interacting with it was added. Also, there was a system of drawing prizes. This is something like a lottery on the server, where each cashier, after paying for a check, initiates a rally. For this, a separate module was also written. And the prize system at the point included a certain action.
All of these services, including the main exchange server were wrapped in their openvpn network, it was the easiest way to secure the system. In addition, the firewall worked at the box office.
OPENVPN key for cash can be used one, if there is no need to accurately assign it to a specific address. We did not touch the entire pool of already generated keys, with the addresses assigned to them. But in theory, the data exchange server always knows which cash register, under what address it was connected to.
Fiscal data operator
Yes, we managed. But there was still plenty of room for creative maneuver. We would have a little time to sip everything beautifully. But ... The second wave of change has come. Those who are familiar with the requirement of the
Federal Law-54 , no need to explain. First launched horror stories from the tax authorities. Along the way, as usual, they
lied assured that in the end the operation of the PRK would be cheaper than before. Then promises from manufacturers of fiscal registrars, assuring us that everything will be on time. Then, as usual, it turned out that no one was ready ... The organization of the sabbath was at C grade.
Business was slowly and snorting with discontent, spitting out a bitter aftertaste of anticipated costs and tasted immature fruits from bistro-automation. And we sadly looked at the Siberian drifts and smiled wryly - before the summer we had something to pass the time.
The most unpleasant thing in all these large-scale changes was that everyone wanted to spit on developers like us. Documentation zero, deadlines compressed. Only white people are allowed to test. It was not possible to touch the new PRK soon. So, there were several options for us:
- New ATOL
- New Shtrikh-M
- Old Shtrih-M with a set of improvements.
In theory, manufacturers of fiscal devices had to change the EKLZ to the Fiscal drive and realize the sending of data to the CRF, providing the fiscal operator with the ability to interact with the Internet connection channel. But you can accomplish the same task in millions of ways. And, of course, they will end up with at least a few. So, there were fiscal users without a LAN jack. With the help of a special driver, it was possible to create a
LAN over USB and enjoy life ... if you are under windows or if you have a lot of time. But, I did not have this time. Therefore, from the cheap cheap crafts from Shtrih-M RITAIL-01 had to be abandoned.
But the option with a set of improvements quite a fit. Fiscal did shunting, inserted new brains and LAN output. However, Stroke did not work as a network printer, it was connected with two tails. One, as before, to the computer, the other (LAN) to the router. Thus, he independently sent the data to the CRF and worked with the driver in the usual way. But the driver had to be modified a little.
Atol the decision was more interesting. In general, the printer could be networked and accessed from the ticket office via LAN. Here, in the driver, also had to make some improvements.
I must say that all testing and improvements on the driver coincided with the change of work and moving to another region. However, this did not become a disaster.
I modified the driver remotely and now it all works reasonably well on fifty objects. However, one organization, which I transferred to IceCash before the introduction of the CRF , still refused to cooperate further with me and, probably, jumped to another software.All the delights of introducing new fiscal apparatuses didn’t touch me either, my former partner Vovka drank this happiness in full. Because I do not know the details of registering and setting up new PRK. But this is not enough written.Saw, Shura, I do not mind.
It so happened that now I work as a programmer in a large company and I am far from the region where the IceCash cash desk is implemented . I finish writing something, but I have terribly strained with time. Requirements for software also do not stand still, EGAIS is developing, new document flows are emerging. It will be a pity if the next retail chain suddenly ceases to exist, and with it the project. Perhaps someone would like this hand-made article, its part, module, piece of code. Maybe then it will be possible to support, develop the project or create a good fork.I tried to do everything so that it was easy for a third-party developer to take any part of the project, to separate it freely, without dragging the whole zoo of the invented functional behind it. In general, who needs to saw;)Links
Here is the IceCash2 code on the git GIT ICECASH2 GIT ICESERV Wikiexchange server , which I did not add: WIKI