![](http://habrastorage.org/getpro/habr/avatars/078/3f9/4c7/0783f94c7f7cafe34e02b5445961ef24.jpg)
IceCash 2.0 Web Cashier AWS and AIS for exchanging data with cash registers for Linux in Python
![](https://habrastorage.org/web/372/17b/415/37217b4151bb4a3ba49c2fba7d1a9331.png)
Somehow they asked me: “Why write what has already been written many times and on a more professional level? What you do will be deliberately worse and lack competent support. ” I then answered simply: “I would like for linux and so that the code is free. So that drivers do not buy for the cash register . "
Yes, Linux box office under the GPL . In these words, in fact, lies the exact description of this craft. This is absolutely free code, parts of which can be easily separated and used in your development. The second version was the answer to all the innovations in retail. Now, we can say that the box office meets all these new requirements and continues to exist in the alternative space of self-written coding.
What for a goat slaughter?
In general, of course, “why?” Is a very important question. They need to be puzzled in advance. Before you write something, you need to evaluate the need, usefulness, so that you yourself would not be offended later. I then, more than once evaluated why I was doing this project, found clever explanations, but in reality ... just so that under Linux and so that the code is free. And, of course, drivers for fiscal apparatuses are a poorly understood business by me.
So, I wanted to make some basis for the cash register workplace, which could be changed for my tasks. Like it or not, but a lot of people are working out cash registers "for themselves." The cash desk should 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 side can be anywhere at all. Though at home in your nightstand on raspberry. This is no longer news, the box office is mutating. The cash desk interface 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, bulky and not separable from your own system. It so often happens that a simple project is complicated and creates its own environment, from which it can not be torn off later. Finding the right software with the web interface did not work. Well then, I rolled up my sleeves, and a month later my eyes ... And the codery
First version. With wild eyes and manic industriousness.
![image](https://habrastorage.org/getpro/habr/post_images/221/051/d2c/221051d2c1a93a395c1c37eeda628f8e.png)
The first version, I made quickly. About it, I wrote an article on a habr once. Yes there were a lot of bugs and terrible code. But it performed at that time the minimum task. In the beginning, it was a light and weak (almost HTML) site in PHP and several utilities in python. Database in MySQL , data transport with pearl scripts. The back office also has a site for viewing checks and derivative reports. The free driver for Barcode-M, written by a certain encoder, was stuck to my system. Although, to be fair, it is more correct to say that this driver served as the basis and without it nothing would have come out. It was then that I understood the main problem of self-written free cash register software - there are no free drivers for PRK.
I constantly added the site, as usual, being late with refactoring and the code was already overgrown with complex callocode. This happens when it is not clear which way and how far the concept will begin to go. And he threw it in different directions not childishly. Various promotions, bonuses, prize systems. The complexity increased, entropy ate the project from the inside. The disadvantages of the system, which was no longer possible to put up with, eventually made me rewrite all this. In addition to restoring order in the code, it was necessary to divide at the checkout all the subsystems that had already begun to stick together with each other, multiplying chaos.
EGAIS has come to all of us! And not only..
![](https://habrastorage.org/web/d7e/b83/a6a/d7eb83a6a9af4f8eaa700b2d6b828078.png)
By the time the writing of the second version had matured, they were already trumpeting that the century of ordinary fiscal apparatuses was not long. 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 was not badly shaken by a number of innovations. The first came EGAIS. Yes, my organization traded in beer and alcohol. My colleagues from other organizations, as well as we, with "joy" met a single electronic document flow. I will not whine about the flaws of this system. Now, everything is somehow more or less normal. Of course, the moment of implementation is always especially bright and memorable days and nights ... Everything was as usual - crazy deadlines, the impossibility of normal testing, the complexity of registration, lack of technical support and New Year). Now it seems to me that all we did was some kind of unrealistic comedy, the participants of which pretend that this is serious.
In general, quite a few solutions appeared on the market with the help of which it was possible to fulfill this requirement. However, it was necessary for us to deliver the JaCarta key at each ticket office and provide this document flow through the UTM (Universal Transport Module) program. 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 drew, telling us how everything will be easy and simple and for any system, in fact it turned out to be mildly wrong.
In general, by the deadline, we did not manage to equip retail outlets with new software systems for EGAIS. But, frankly, I didn’t really want to change the software at fifty sites, buying a licensed Windows and cash register software along the way. Only on keys JaCarta had to throw decent money at a time. But many then completely abandoned the alcohol trade. After scratching our turnips, we did the old fashioned way. A web service was quickly thrown in, which interacted with a single copy of UTM and dozens of accounts at retail outlets where confirmation of incoming documents was carried out. A bunch of fifty jaCarta keys was handed to a specially trained employee. She was delivered a computer with mastday and the necessary software. Dragging the keys every day (for six months) and poking with the mouse on the site to the right places, the new freelance provider EGAISA exchanged documents. I think we are not the only ones in this idiocy, some still do.
The sale of alcohol involves working with EGAIS at the time of sale of each check, and this already required the refinement of cash register software. Before the introduction, it was only six months. So, working at a simple temporary hut for receiving EGAIS documents, we quickly quickly started making the second version of our ticket office.
We write in Feng Shui.
So six months for development is a lot. The catch is that the developer is essentially one. To help him only the system administrator. Well, no one freed us from current work. But I really wanted to make a new version, so I started to skip greedily again. Now there was already an understanding of what independent parts the project should consist of and how to implement these parts.
So, we settled on the following scheme.
DRIVER SERVER
In addition to the existing driver for Barcode-M, it was necessary to implement a driver for FPRINT (Atol) and a driver for thermal printers. Unify all these drivers with the same printing methods and a single check design.
In general, the idea to connect also 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 receipts on updated PRKs, confirmed online by the fiscal data operator. Although later, the option in which the thermal printer was seriously trying to pretend PRK + OFD turned out to be handy at times when the fiscal was broken.
Management of fiscal restaurateurs and thermal printers that support the ESCPOS protocol should have been carried out through a separate web-service. That is, everything related to interaction with equipment is separated into a separate independent application, the interaction with which should be carried out using the XML protocol.
![](https://habrastorage.org/web/ef3/df4/04b/ef3df404b35b4acf90dbd9449dd71122.png)
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 using XML was implemented the day before. It only remained to write the Atol driver and somehow unify this entire
SITE OF THE CASH OFFICE
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 the admin functions to the interface and service functions to initialize the exchange of data and other utilities.
Web-box office, of course, had to interact with the driver server, data exchange service, bonus server and a number of other back-office services.
They also decided to store data in MySQL.. I decided to leave the transaction storage system (like with Bar-M). Now it was checks that were stored in the database in its entirety. All the necessary additional data about operations with the check settled in the form of header field values or check contents. I wanted to do this for a long time. Samples from such a database were simple and concise. Calculation of zet reports is transparent and without troubles.
The structure of the program site should have been maximally divided internally into separate modules containing objects of subtasks. EGAIS module, bonus module, check processing module, query database module, etc.
An important addition was to be the implementation of EGAIS. Firstly, in terms of receipt and confirmation of incomes, and secondly in terms of sales 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 over UTM. The UTM program itself was constantly changing, and the protocol was changing. Recently (July 1, 2017) introduced its second version. The key update on the JaCarta token was not convenient . Although now, many organizations offer to do this remotely, for Linux + JaCarta it is still complicated. Therefore, we update the keys by connecting them to a laptop with Windows . I think this part could be finalized, otherwise it is too troublesome.
I hesitated for a long time about how to implement the unloading of checks. To put it simply, the question was: "How much online does the box office need?" Will she have online, offline modes, how will the exchange go? As a result, the cashier was implemented separately from the exchange function. The site responds to commands for downloading checks, reporting reports or downloading data from the server. Exchange processes launched at the right frequency from crontab do not affect the operation of the cash register. There is no connection - it does not matter how it appears, the accumulated data on the chipped checks will go away, the price will be updated.
As practice has shown, the most complex node is check processing. And this is not only a print, it is mainly a consistent check calculation. It was here that all sorts of improvements to the logic of different promotions, bonuses, and draws made the calculation of the check in the first version an absolutely incomprehensible black hole. Therefore, in the new version, I decided everything as to determine the check as much as possible and beautifully decompose it into object methods.
![](https://habrastorage.org/web/d95/2cf/477/d952cf477a5241e4b130d0c77f936c4a.png)
The code was written, it seems to me, quite well. You can always get better, of course. But what has been done for long enough for a stable complexity of the project safely gathered in
To the comments of the system administrator Vovka regarding the toxicity of colors, I just got into a fuss about writing several different CSS colors. But in the end, only one more was added - gray, it became the main one. And the poison has become admin. This was useful in order not to get confused at box office sessions.
![](https://habrastorage.org/web/9a7/e58/a32/9a7e58a328f64a18ab5bb1b67dba784d.png)
Of the pluses was that everything turned out to be divided into the most independent program modules, any of which can be safely rewritten without affecting the main code. In general, this approach seemed to me very correct. With this mosaic of code, you can assemble different designs, focusing only on the interaction protocols. However, there is one important point - the protocols should be well thought out initially, so that later they can be easily modified and not change the basis.
Simultaneous work by different users with the checkout site has made it possible to trade from various devices in the trading floor. Later, I finalized the module for the checkout so that I could work with orders in the style of serving the queue of fast-food cafes. Everything turned out to be easily modifiable and scalable.
It also turned out to be useful to quickly connect to the cashier’s current interface, actually observing his actions online through a browser or by typing a delayed check to himself, so as not to stand in line).
![](https://habrastorage.org/web/aa9/9ca/f66/aa99caf6674d4d6993a18e0d1653739c.png)
In general, the speed of administration has increased significantly. It became possible to intervene in the process of payment, settings, driver management from the browser on the phone (via VPN). Although VNC and ssh were not canceled, all the tools were actively used. Some settings were global and cash desks themselves took them from the server, at the same time sending information about themselves (significant settings, ip-address, connection time, software version). Over time, a rich crontab formed at the checkoutand scripts of any self-diagnosis and sending reports to the server. But there’s nothing to boast about, everyone does it.
CASH MANAGEMENT SERVER
For the efficient administration of cash desks, it was necessary to create, in fact, a cash management server. At a minimum, all receipts from cash desks should have been collected in it and software update should have taken place through it. As practice has shown, this is a very important task in a self-written project.
In fact, it was another web service and site. The main directories should have been entered into it: organizations, prices, groups of goods., Cash desks and their type of price. Cash desks should have been divided by organizations (branches), which can be any number. Later, an action system was added here - this is the writing and distribution of promotional scripts to the box office. Well, something like my own language of these same actions had to be invented.
![](https://habrastorage.org/web/f82/e54/78f/f82e5478f2e5417eb01c7e2c98dc4d38.png)
Firstan important function of this server is to receive and distribute new prices to ticket offices, I started with it. Prices should have been tied to the box office. That is, on the server itself, we indicate for each ticket office our price list from the available ones. The cashier simply contacts the server with its identification number. In response, the server gives the green light to downloading the zip archive. If the download was successful, then the server itself marks the time of the last download for this client and does not give the price anymore. Well, of course, until the new price is uploaded to the server itself.
And uploading the file to the server is also a normal PUT HTTP operation, you only need to specify the identifier of the branch and the price itself. Later, my friend, to whom we also introduced part of my system at work, wrote the necessary processing on 1C to upload the price directly to the server. At the same time, he wrote the processing for downloading JSON zet reports from the same server.
![](https://habrastorage.org/web/fbf/d01/dff/fbfd01dffb4e459185851205bc82228a.png)
Secondan important function is the collection of data from cash desks. Zet reports and checks. In general, I came to the conclusion that the cash register itself began to generate zet reports at the checkout. That is, ready-made, grouped by product, with the desired totals, zet reports are in the database. And in the web interface they can be studied in detail. At the early stage of writing a checkout, I implemented everything without a data collection server, so the checkout and server contain identical functions for issuing reports and checks upon request from outside. It turns out that if you want, you can do without a server, just request data directly from the ticket office. So, the cashier, upon request, generates two data streams in json - a stream of non-uploaded zet-reports and a stream of non-uploaded checks. Data is uploaded to the server, and from there, upon request, uploaded for 1C. Alternatively, scripts were written,
![](https://habrastorage.org/web/a76/1eb/663/a761eb663031486bbb6408ae7163353c.png)
From the server interface itself, it was possible to view receipts. But this functionality was inconvenient 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 the ability to view zet reports and other developments on existing working web applications focused on the previous version of IceCash. But alas, there wasn’t enough time for this, this remained the site of one report.
![](https://habrastorage.org/web/1b2/2cd/2ff/1b22cd2ffd4144f6a345c57f3f607743.png)
![](https://habrastorage.org/web/4a3/6e3/0ed/4a36e30edb2d4e17b0f92b548cf7025f.png)
Also, the server was assigned the function of updating cash register software . There were two types of updates: system update and program update. Any update starts with version tracking. The versions that we put into operation (prod) are simply set by global variables on the server ( update andupgrade ). All server variables are automatically distributed to the box office. This can also include any global parameters that interest us for all cash desks, requiring constant replication. For example, my air temperature sounds like this. Each branch can have its own set of variables and values, so that the weather is distributed regionally. This was not needed for fun. There was such an action - according to the weather, there the discount formula was based on temperature.
So, here, the version prescribed for installing the update is also distributed by variables, regionally. This is convenient for step testing. First at one checkout, then at a small branch, the next day at a large branch. Well, if it’s all about Feng Shui, then in the beginning we often had rumors associated with the inconsistent version roll-over.
Program update, This is actually downloading the desired version and replacing the old one, with restarting the services. The version of the working program, the program knows from a constant in the code. On the server, you can set any larger than the working version and the cash register will pick it up.
System update is a tbz archive containing the necessary files and bash update script. These updates are performed sequentially. All archives on the server are needed so that the cashier can install them sequentially, updating their status to the required one.
![](https://habrastorage.org/web/ad7/b72/9a8/ad7b729a8ff54b1caf3b125f7976d10c.png)
The fact is that we establish the cash desk by unpacking the dump of the working system, which is not always ... or rather, always not fresh enough. Therefore, in order to avoid conflicts between the application and the runtime, the newly unpacked image sequentially rolls system updates.
In addition to these tasks, in the end, a system was created for creating, storing and distributing stock scripts . Modern retail cannot live without these promotions. I do not know how much they are really needed, but for retail programmers there is a special place in hell - the action system. Stocks are constantly in conflict:
- With yourself.
- With a bonus system.
- Price-based restriction system.
- With all systems working with a check.
![](https://habrastorage.org/web/9c0/9a5/2af/9c09a52af88c42e1823624073add39f1.png)
Stocks are capricious and treacherous. Moreover, they are always held in high esteem by managers, and the director will necessarily require a detailed analysis of their effectiveness, from which the brain boils. And that’s not all, shares simply do not want to be the same. 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 actual term of its work.
![](https://habrastorage.org/web/aec/868/65d/aec86865da44436e9353fed7e92708bb.png)
In general, my attempts to automate the process of creating shares in the first version did not lead to anything other than a waste of time and nerves. Therefore, in the second version, I completely refused to create web forms with a million checkmarks for managers, because the next promotion will require a million first checkmark. Instead, I wrote a separate module in which I implemented the mini-language of these stocks. And already with this language I consistently described each action with my script. Check condition, selection, grouping, replacement and addition of positions, etc.
![](https://habrastorage.org/web/5e1/904/5ab/5e19045ab7bf474fb726add60c23ffac.png)
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 through the forest. Nervous costs have definitely decreased, it became clear how this all works. And I did not agree to make interfaces for managers, but jokingly offered to learn the language of stocks and write scripts on it.
additional services
We have already developed our own bonus system in the form of a service in Python + Mysql . Therefore, only a module was added to interact with it. Also, there was a prize draw system. This is something like a lottery on the server, where each cashier, after paying a check, initiates a draw. A separate module was also written for this. And the prize system at the point was included in a certain action.
All these services, including the main exchange server, were wrapped in their openvpn network, this was the easiest way to secure the system. In addition, at the box office worked his firewall.
An OPENVPN cash register key can be used alone if it is not necessary to precisely assign it to a specific address. The entire pool of already generated keys, with the addresses assigned to them, we did not touch. But in theory, the data exchange server always knows which ticket office, under what address it is connected.
Fiscal data operator
Yes, we did it. But there was still plenty of room for creative maneuver. We would have little time to cut everything beautifully. But ... A second wave of change has come. Those who are familiar with the requirement of FZ-54 need not explain. First, horror stories from tax authorities were launched. Along the way, as usual, they
The business slowly and snorted with discontent spit out the bitter aftertaste of the anticipated costs and tasted the immature fruits of the bistro-automation. But we looked sadly at the Siberian snowdrifts and smiled wryly - before the summer we had something to pass the time.
The most unpleasant thing about all these large-scale changes is that everyone wanted to spit on developers like us. The documentation is zero, the deadlines are tight. Only white people are allowed to test. It was not soon possible to feel the new PRK. So, there were several options for us:
- New ATOL
- New Bar M
- Old Shtrikh-M with a set of improvements.
In theory, manufacturers of fiscal devices were supposed to exchange EKLZ on the Fiscal drive and implement sending data to the OFD, providing the fiscal with the ability to interact with the Internet communication channel. But you can accomplish the same task in millions of ways. And, of course, there will be at least a few of them as a result. So, there were fiscal people without a LAN jack. Using a special driver, you could 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, the new cheap crafts from Shtrikh-M RETAIL-01 had to be abandoned.
But the option with a set of improvements quite suited itself. They made a shunt to the fiscal, inserted new brains and a LAN output. However, Barcode did not work as a network printer; it connected with two tails. One, as before, to the computer, the other (LAN) to the router. Thus, he independently sent data to the OFD and worked with the driver in the usual way. But the driver had to be modified a bit.
Atol's decision was more interesting. The printer in general could be made networked and accessed from the cash desk to it via LAN. Here, the driver also had to make some improvements.
I must say that all the testing and improvements on the driver coincided with my change of work and moving to another region. However, this did not become a disaster. I finalized the drivers remotely and now all this works reasonably well on fifty objects. True, one organization that I transferred to IceCash before the introduction of the OFD , nevertheless refused to continue cooperation with me and, probably, jumped to other software.
All the delights of introducing new fiscal apparatuses didn’t touch me either, my former partner Vovka drank this happiness in full. Therefore, I don’t know the details about registering and setting up new PRKs. But much has been written about this.
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 has been introduced . I’m adding something, but I have a terrible strain over time. Software requirements also do not stand still, EGAIS is developing, new document flows are emerging. It will be a pity if suddenly another retail chain ceases to exist, and with it the project. Perhaps someone will like this craft, its part, module, piece of code. Maybe then we can 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, separate it freely, without dragging the entire zoo of the invented functionality behind it. In general, nag anyone;)
References
Here is the IceCash2 code for git GIT ICECASH2 GIT ICESERV Wiki
sharing server , which I did not add: WIKI