{"id":269356,"date":"2015-12-01T10:09:02","date_gmt":"2015-12-01T07:09:02","guid":{"rendered":"http:\/\/savepearlharbor.com\/?p=269356"},"modified":"-0001-11-30T00:00:00","modified_gmt":"-0001-11-29T21:00:00","slug":"","status":"publish","type":"post","link":"https:\/\/savepearlharbor.com\/?p=269356","title":{"rendered":"AllcountJS: POS demo"},"content":{"rendered":"<p>       \u041f\u0440\u043e\u0434\u043e\u043b\u0436\u0430\u0435\u043c \u0437\u043d\u0430\u043a\u043e\u043c\u0441\u0442\u0432\u043e \u0441 <a href=\"https:\/\/allcountjs.com\/\">AllcountJS<\/a> \u2014 \u0444\u0440\u0435\u0439\u043c\u0432\u043e\u0440\u043a\u043e\u043c \u0434\u043b\u044f \u0431\u044b\u0441\u0442\u0440\u043e\u0439 \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0438 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0439 \u043d\u0430 \u043f\u043b\u0430\u0442\u0444\u043e\u0440\u043c\u0435 NodeJS. \u0412 \u044d\u0442\u043e\u0439 \u0441\u0442\u0430\u0442\u044c\u0435 \u043c\u044b \u0440\u0430\u0441\u0441\u043c\u043e\u0442\u0440\u0438\u043c \u043f\u0440\u0438\u043c\u0435\u0440 \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438 \u043a\u0430\u0441\u0442\u043e\u043c\u043d\u043e\u0433\u043e \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441\u0430 \u0441 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435\u043c AngualrJS \u0438 jade, \u0430 \u0442\u0430\u043a\u0436\u0435 \u043d\u0435\u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u0438 \u043a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f, \u043e \u043a\u043e\u0442\u043e\u0440\u044b\u0445 \u043c\u044b \u0435\u0449\u0451 \u043d\u0435 \u0443\u043f\u043e\u043c\u0438\u043d\u0430\u043b\u0438.<\/p>\n<p>  POS (Point Of Sale) \u2014 \u0432 \u043f\u0440\u044f\u043c\u043e\u043c \u0441\u043c\u044b\u0441\u043b\u0435 \u0442\u043e\u0447\u043a\u0430 \u043f\u0440\u043e\u0434\u0430\u0436\u0438, \u043d\u043e \u043e\u0431\u044b\u0447\u043d\u043e \u044d\u0442\u043e\u0442 \u0442\u0435\u0440\u043c\u0438\u043d \u043e\u0431\u043e\u0437\u043d\u0430\u0447\u0430\u0435\u0442 \u0440\u0430\u0431\u043e\u0447\u0435\u0435 \u043c\u0435\u0441\u0442\u043e \u043a\u0430\u0441\u0441\u0438\u0440\u0430 \u0432\u043c\u0435\u0441\u0442\u0435 \u0441 \u0442\u043e\u0440\u0433\u043e\u0432\u044b\u043c \u043e\u0431\u043e\u0440\u0443\u0434\u043e\u0432\u0430\u043d\u0438\u0435\u043c. \u0422\u0430\u043a\u0438\u0435 \u0442\u0435\u0440\u043c\u0438\u043d\u0430\u043b\u044b \u043d\u0430\u0445\u043e\u0434\u044f\u0442\u0441\u044f \u043f\u043e\u0447\u0442\u0438 \u0432 \u043a\u0430\u0436\u0434\u043e\u043c \u043c\u0435\u0441\u0442\u0435 \u0433\u0434\u0435 \u043d\u0430\u043c \u0447\u0442\u043e-\u043d\u0438\u0431\u0443\u0434\u044c \u043f\u0440\u043e\u0434\u0430\u044e\u0442. \u0418 \u0441\u0435\u0439\u0447\u0430\u0441 \u043c\u044b \u0441\u043e\u0437\u0434\u0430\u0434\u0438\u043c \u043f\u0440\u043e\u0441\u0442\u043e\u0435 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0435, \u043a\u043e\u0442\u043e\u0440\u043e\u0435 \u043f\u043e\u0437\u0432\u043e\u043b\u0438\u0442 \u0432\u0435\u0441\u0442\u0438 \u0441\u043f\u0438\u0441\u043e\u043a \u0442\u043e\u0432\u0430\u0440\u043e\u0432 \u0441 \u043e\u0441\u0442\u0430\u0442\u043a\u0430\u043c\u0438 \u0438 \u0441\u043e\u0437\u0434\u0430\u0432\u0430\u0442\u044c \u0437\u0430\u043f\u0438\u0441\u0438 \u043e \u043f\u0440\u043e\u0434\u0430\u0436\u0430\u0445.<br \/>  <img decoding=\"async\" src=\"https:\/\/habrastorage.org\/files\/323\/7be\/a9a\/3237bea9ace842da947ff037fa7af49f.png\" alt=\"POS main UI\"\/><br \/>  \u041a\u0430\u043a \u043e\u0431\u044b\u0447\u043d\u043e, \u043d\u0430 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442 \u043c\u043e\u0436\u043d\u043e \u043f\u043e\u0441\u043c\u043e\u0442\u0440\u0435\u0442\u044c \u0432 <a href=\"https:\/\/allcountjs.com\/entity\/DemoGallery\/5608faa748c663113053d164\">\u0434\u0435\u043c\u043e \u0433\u0430\u043b\u0435\u0440\u0435\u0438<\/a>.<br \/>  <a name=\"habracut\"><\/a>  <\/p>\n<h1>\u041c\u043e\u0434\u0435\u043b\u044c \u0438 \u0431\u0438\u0437\u043d\u0435\u0441-\u043b\u043e\u0433\u0438\u043a\u0430<\/h1>\n<p>  \u041d\u0430\u0447\u043d\u0451\u043c \u0441 \u043e\u043f\u0438\u0441\u0430\u043d\u0438\u044f \u0441\u0430\u043c\u043e\u0433\u043e \u0432\u0430\u0436\u043d\u043e\u0433\u043e \u2014 \u043f\u043e\u0437\u0438\u0446\u0438\u0439 (\u0442\u043e\u0432\u0430\u0440\u043e\u0432), \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0431\u0443\u0434\u0435\u043c \u043f\u0440\u043e\u0434\u0430\u0432\u0430\u0442\u044c.  <\/p>\n<pre><code class=\"javascript\">Item: {     fields: {         name: Fields.text(&quot;Name&quot;),                 stock: Fields.integer(&quot;Stock&quot;).computed('sum(transactions.quantity)'),                 price: Fields.money(&quot;Price&quot;),                 transactions: Fields.relation(&quot;Transactions&quot;, &quot;Transaction&quot;, &quot;item&quot;)     },     referenceName: &quot;name&quot; } <\/code><\/pre>\n<p>  \u0421\u0430\u043c\u043e\u0435 \u0438\u043d\u0442\u0435\u0440\u0435\u0441\u043d\u043e\u0435 \u0442\u0443\u0442 \u2014 \u044d\u0442\u043e \u043f\u043e\u043b\u0435 \u0441 \u043e\u0441\u0442\u0430\u0442\u043a\u0430\u043c\u0438 stock. \u041e\u043d\u043e \u0434\u043e\u043b\u0436\u043d\u043e <a href=\"https:\/\/allcountjs.com\/docs\/apps#computed-fields\">\u0441\u0447\u0438\u0442\u0430\u0442\u044c\u0441\u044f <\/a>\u0430\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u0438 \u043f\u043e \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u0443 (quantity) \u0438\u0437 \u0442\u0440\u0430\u043d\u0437\u0430\u043a\u0446\u0438\u0439 (transactions). \u0418\u043c\u0435\u043d\u043d\u043e \u0442\u0430\u043a \u0438 \u043d\u0430\u043f\u0438\u0441\u0430\u043d\u043e \u0432 \u043d\u0430\u0448\u0435\u0439 \u043a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0430\u0446\u0438\u0438: \u0446\u0435\u043b\u043e\u0447\u0438\u0441\u043b\u0435\u043d\u043d\u043e\u0435 \u043f\u043e\u043b\u0435 stock \u0432\u044b\u0447\u0438\u0441\u043b\u044f\u0435\u0442\u0441\u044f \u043a\u0430\u043a \u0441\u0443\u043c\u043c\u0430 transactions \u043f\u043e \u043f\u043e\u043b\u044e quantity. \u0422\u043e\u043b\u044c\u043a\u043e \u0441\u043e \u0441\u043a\u043e\u0431\u043a\u0430\u043c\u0438, \u0442\u043e\u0447\u043a\u0430\u043c\u0438 \u0438 \u043a\u0430\u0432\u044b\u0447\u043a\u0430\u043c\u0438. \u0410 \u043f\u043e\u043b\u0435 \u201ctransactions\u201d \u2014 \u044d\u0442\u043e \u0441\u043f\u0438\u0441\u043e\u043a \u0432\u0441\u0435\u0445 \u0442\u0440\u0430\u043d\u0437\u0430\u043a\u0446\u0438\u0439, \u0432 \u043a\u043e\u0442\u043e\u0440\u044b\u0445 \u0443\u0447\u0430\u0441\u0442\u0432\u0443\u0435\u0442 \u0434\u0430\u043d\u043d\u0430\u044f \u043f\u043e\u0437\u0438\u0446\u0438\u044f. \u0415\u0441\u043b\u0438 \u0447\u0438\u0442\u0430\u0442\u044c \u043f\u043e \u043a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0430\u0446\u0438\u0438: \u201ctransactions\u201d \u044d\u0442\u043e \u043f\u043e\u043b\u0435 \u0442\u0438\u043f\u0430 \u201c<a href=\"https:\/\/allcountjs.com\/docs\/apps#relationships\">relation<\/a>\u201d \u0441\u0432\u044f\u0437\u0430\u043d\u043d\u043e\u0435 \u0441 \u043f\u043e\u043a\u0430 \u043e\u0442\u0441\u0443\u0442\u0441\u0442\u0432\u0443\u044e\u0449\u0435\u0439 \u0441\u0443\u0449\u043d\u043e\u0441\u0442\u044c\u044e \u201cTransaction\u201d \u043f\u043e \u043f\u043e\u043b\u044e \u201citem\u201d. \u0421\u0432\u043e\u0439\u0441\u0442\u0432\u043e \u201creferenceName\u201d \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u044f\u0435\u0442 \u043a\u0430\u043a\u043e\u0435 \u0438\u0437 \u043f\u043e\u043b\u0435\u0439 \u0441\u0443\u0449\u043d\u043e\u0441\u0442\u0438 \u043e\u0442\u043e\u0431\u0440\u0430\u0436\u0430\u0442\u044c \u0432 \u043d\u0430\u0438\u043c\u0435\u043d\u043e\u0432\u0430\u043d\u0438\u044f\u0445 \u0441\u0441\u044b\u043b\u043e\u043a \u0432\u0435\u0434\u0443\u0449\u0438\u0445 \u043d\u0430 \u044d\u0442\u0443 \u0441\u0443\u0449\u043d\u043e\u0441\u0442\u044c. <\/p>\n<p>  \u0422\u0435\u043f\u0435\u0440\u044c \u0434\u043e\u0431\u0430\u0432\u0438\u043c \u0442\u0438\u043f Transaction \u2014 \u0442\u0440\u0430\u043d\u0437\u0430\u043a\u0446\u0438\u0438 \u043e\u043f\u0438\u0441\u044b\u0432\u0430\u044e\u0449\u0438\u0435 \u043f\u043e\u0441\u0442\u0443\u043f\u043b\u0435\u043d\u0438\u0435 \u0438 \u0432\u044b\u0431\u044b\u0442\u0438\u0435 \u0442\u043e\u0432\u0430\u0440\u043e\u0432.  <\/p>\n<pre><code class=\"javascript\">Transaction: {     fields: {         item: Fields.reference(&quot;Item&quot;, &quot;Item&quot;),         order: Fields.reference(&quot;Order&quot;, &quot;Order&quot;),         orderItem: Fields.reference(&quot;Order item&quot;, &quot;OrderItem&quot;),         quantity: Fields.integer(&quot;Quantity&quot;)     },     showInGrid: ['item', 'order', 'quantity'] }  <\/code><\/pre>\n<p>  \u041a\u0430\u043a \u0432\u044b \u0432\u0438\u0434\u0438\u0442\u0435, \u043f\u043e\u043b\u0435 \u201citem\u201d \u0441\u0441\u044b\u043b\u0430\u0435\u0442\u0441\u044f \u043d\u0430 \u0441\u0443\u0449\u043d\u043e\u0441\u0442\u044c \u201cItem\u201d \u0438 \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u0438\u0432\u0430\u0435\u0442 \u0432\u044b\u0448\u0435\u043e\u043f\u0438\u0441\u0430\u043d\u043d\u0443\u044e \u0441\u0432\u044f\u0437\u044c. \u0412 \u043e\u0441\u0442\u0430\u043b\u044c\u043d\u043e\u043c \u043d\u0438\u0447\u0435\u0433\u043e \u043e\u0441\u043e\u0431\u0435\u043d\u043d\u043e\u0433\u043e \u043a\u0440\u043e\u043c\u0435 \u0441\u0432\u043e\u0439\u0441\u0442\u0432\u0430 \u201cshowInGrid\u201d \u2014 \u043e\u043d\u043e \u0437\u0430\u0434\u0430\u0451\u0442 \u0441\u043f\u0438\u0441\u043e\u043a \u043f\u043e\u043b\u0435\u0439, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0431\u0443\u0434\u0443\u0442 \u043e\u0442\u043e\u0431\u0440\u0430\u0436\u0430\u0442\u044c\u0441\u044f \u0432 \u0433\u0440\u0438\u0434\u0435. <\/p>\n<p>  \u0414\u0430\u043b\u0435\u0435 \u043e\u043f\u0438\u0448\u0435\u043c \u0446\u0435\u043d\u0442\u0440\u0430\u043b\u044c\u043d\u0443\u044e \u0447\u0430\u0441\u0442\u044c \u043d\u0430\u0448\u0435\u0439 POS:  <\/p>\n<pre><code class=\"javascript\">Order: {     fields: {         number: Fields.integer(&quot;Order #&quot;),         date: Fields.date(&quot;Date&quot;),         total: Fields.money(&quot;Total&quot;).computed('sum(orderItems.finalPrice)'),         orderItems: Fields.relation(&quot;Items&quot;, &quot;OrderItem&quot;, &quot;order&quot;)     },     beforeSave: function (Entity, Dates, Crud) {         if (!Entity.date) {             Entity.date = Dates.nowDate();         }         return Crud.crudFor('OrderCounter').find({}).then(function (last) {             if (!Entity.number) {                 Entity.number = last[0].number;                 return Crud.crudFor('OrderCounter').updateEntity({id: last[0].id, number: last[0].number + 1});             }         })     },     beforeDelete: function (Entity, Crud, Q) {         var crud = Crud.crudFor('OrderItem');         return crud.find({filtering: {order: Entity.id}}).then(function (items) {             return Q.all(items.map(function (i) {                 return crud.deleteEntity(i.id)             }));         });     },     referenceName: &quot;number&quot;,     views: {         PointOfSale: {             customView: 'pos'         }     } } <\/code><\/pre>\n<p>  \u042f \u043d\u0430\u0437\u044b\u0432\u0430\u044e \u0435\u0451 \u0446\u0435\u043d\u0442\u0440\u0430\u043b\u044c\u043d\u043e\u0439 \u043f\u043e\u0442\u043e\u043c\u0443 \u0447\u0442\u043e \u0432 \u043d\u0435\u0439 \u043c\u044b \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0438\u043b\u0438 \u043d\u0430\u0448\u0435 \u0433\u043b\u0430\u0432\u043d\u043e\u0435 \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u0435\u043d\u0438\u0435 \u201cPointOfSale\u201d, \u043e\u043f\u0438\u0441\u0430\u043d\u043d\u043e\u0435 \u0432 \u0444\u0430\u0439\u043b\u0435 \u201cpos.jade\u201d, \u043d\u043e \u0435\u0433\u043e \u043c\u044b \u043a\u043e\u0441\u043d\u0451\u043c\u0441\u044f \u043f\u043e\u0437\u0436\u0435. \u0422\u0430\u043a\u0436\u0435 \u0432\u044b \u043d\u0430\u0432\u0435\u0440\u043d\u044f\u043a\u0430 \u0437\u0430\u043c\u0435\u0442\u0438\u043b\u0438 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 \u201cbeforeSave\u201d \u0438 \u201cbeforeDelete\u201d. \u042d\u0442\u043e \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a\u0438, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0441\u0440\u0430\u0431\u0430\u0442\u044b\u0432\u0430\u044e\u0442 \u043a\u043e\u0433\u0434\u0430 \u043f\u0440\u043e\u0438\u0441\u0445\u043e\u0434\u044f\u0442 \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0443\u044e\u0449\u0438\u0435 \u0441\u043e\u0431\u044b\u0442\u0438\u044f: \u043f\u0435\u0440\u0435\u0434 \u0441\u043e\u0445\u0440\u0430\u043d\u0435\u043d\u0438\u0435\u043c \u0438 \u043f\u0435\u0440\u0435\u0434 \u0443\u0434\u0430\u043b\u0435\u043d\u0438\u0435\u043c. \u041f\u043e\u0434\u0440\u043e\u0431\u043d\u0435\u0435 \u043e \u043d\u0438\u0445 \u0432\u044b \u043c\u043e\u0436\u0435\u0442\u0435 \u043f\u0440\u043e\u0447\u0438\u0442\u0430\u0442\u044c \u0432 \u043d\u0430\u0448\u0435\u0439 \u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u0430\u0446\u0438\u0438 \u0432 \u0440\u0430\u0437\u0434\u0435\u043b\u0435 <a href=\"https:\/\/allcountjs.com\/docs\/apps\">CRUD hooks<\/a>. \u0422\u0443\u0442 \u044d\u0442\u0438 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 \u043d\u0443\u0436\u043d\u044b \u0447\u0442\u043e\u0431\u044b \u043e\u0431\u043d\u043e\u0432\u043b\u044f\u0442\u044c \u0441\u0447\u0451\u0442\u0447\u0438\u043a \u0437\u0430\u043a\u0430\u0437\u043e\u0432 (order) \u043a\u043e\u0433\u0434\u0430 \u0437\u0430\u043a\u0430\u0437 \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d \u0438 \u0434\u043b\u044f \u0443\u0434\u0430\u043b\u0435\u043d\u0438\u044f \u043f\u043e\u0437\u0438\u0446\u0438\u0439 \u0437\u0430\u043a\u0430\u0437\u0430 \u0432\u043c\u0435\u0441\u0442\u0435 \u0441 \u0441\u0430\u043c\u0438\u043c \u0437\u0430\u043a\u0430\u0437\u043e\u043c.<br \/>  Computed \u0438 relation \u043f\u043e\u043b\u044f \u0432\u0441\u0442\u0440\u0435\u0447\u0430\u044e\u0442\u0441\u044f \u0438 \u0432 \u044d\u0442\u043e\u043c \u043a\u0443\u0441\u043a\u0435 \u043a\u043e\u0434\u0430. \u0412\u044b\u0447\u0438\u0441\u043b\u044f\u0435\u043c\u043e\u0435 \u043f\u043e\u043b\u0435 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f \u0434\u043b\u044f \u0440\u0430\u0441\u0447\u0451\u0442\u0430 \u0438\u0442\u043e\u0433\u043e\u0432\u043e\u0439 \u0441\u0442\u043e\u0438\u043c\u043e\u0441\u0442\u0438 \u0437\u0430\u043a\u0430\u0437\u0430, \u0430 relation \u043f\u043e\u043b\u0435 \u201corderItems\u201d \u043c\u043e\u0436\u043d\u043e \u0432\u043e\u0441\u043f\u0440\u0438\u043d\u0438\u043c\u0430\u0442\u044c \u043a\u0430\u043a \u043f\u0435\u0440\u0435\u0447\u0435\u043d\u044c \u043f\u043e\u0437\u0438\u0446\u0438\u0439 \u0441\u043e\u0434\u0435\u0440\u0436\u0430\u0449\u0438\u0445\u0441\u044f \u0432 \u0434\u0430\u043d\u043d\u043e\u043c \u0437\u0430\u043a\u0430\u0437\u0435. \u041e\u043d\u043e \u0441\u0432\u044f\u0437\u0430\u043d\u043e \u0441 \u0441\u0443\u0449\u043d\u043e\u0441\u0442\u044c\u044e OrderItem:  <\/p>\n<pre><code class=\"javascript\">OrderItem: {     fields: {         order: Fields.reference(&quot;Order&quot;, &quot;Order&quot;),         item: Fields.fixedReference(&quot;Item&quot;, &quot;Item&quot;).required(),         quantity: Fields.integer(&quot;Quantity&quot;).required(),         finalPrice: Fields.money(&quot;Final price&quot;).readOnly().addToTotalRow()     },     showInGrid: ['item', 'quantity', 'finalPrice'],     beforeSave: function (Crud, Entity) {         return Crud.crudFor('Item').readEntity(Entity.item.id).then(function (item) {             Entity.finalPrice = Entity.quantity * item.price;         })     },     afterSave: function (Crud, Entity) {         var crud = Crud.crudForEntityType('Transaction');         return removeTransaction(Crud, Entity).then(function () {             return crud.createEntity({                 order: Entity.order,                 orderItem: {id: Entity.id},                 item: Entity.item,                 quantity: Entity.quantity * -1             })         })     },     beforeDelete: function (Crud, Entity) {         return removeTransaction(Crud, Entity);     } } <\/code><\/pre>\n<p>  \u041a\u0430\u043a \u0432\u044b \u043d\u0430\u0432\u0435\u0440\u043d\u043e \u0437\u0430\u043c\u0435\u0442\u0438\u043b\u0438, \u043a\u0430\u0436\u0434\u044b\u0439 \u0442\u0438\u043f \u0441\u0443\u0449\u043d\u043e\u0441\u0442\u0438, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0443\u0447\u0430\u0441\u0442\u0432\u0443\u0435\u0442 \u0432 \u043f\u043e\u043b\u044f\u0445 \u0441\u043e \u0441\u0432\u044f\u0437\u044f\u043c\u0438 \u0438\u043c\u0435\u044e\u0442 \u0441\u0432\u043e\u0439\u0441\u0442\u0432\u043e \u201cshowInGrid\u201d. \u041e\u043d\u043e \u043d\u0443\u0436\u043d\u043e \u0447\u0442\u043e\u0431\u044b \u043f\u043e\u043a\u0430\u0437\u044b\u0432\u0430\u0442\u044c \u0432 \u0433\u0440\u0438\u0434\u0435 \u0442\u043e\u043b\u044c\u043a\u043e \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0451\u043d\u043d\u044b\u0435 \u043f\u043e\u043b\u044f \u0441\u0443\u0449\u043d\u043e\u0441\u0442\u0438. \u041e\u0431\u044b\u0447\u043d\u043e \u043c\u044b \u043d\u0435 \u0445\u043e\u0442\u0438\u043c \u043f\u043e\u043a\u0430\u0437\u044b\u0432\u0430\u0442\u044c \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044e \u0432\u044b\u0448\u0435\u0441\u0442\u043e\u044f\u0449\u0443\u044e \u0432 \u043e\u0442\u043d\u043e\u0448\u0435\u043d\u0438\u0438 \u0441\u0443\u0449\u043d\u043e\u0441\u0442\u044c, \u043f\u043e\u0441\u043a\u043e\u043b\u044c\u043a\u0443 \u0438\u043c\u0435\u043d\u043d\u043e \u0447\u0435\u0440\u0435\u0437 \u043d\u0435\u0451 \u043e\u043d \u0438 \u0432\u044b\u0448\u0435\u043b \u043d\u0430 \u044d\u0442\u043e \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u0435\u043d\u0438\u0435. \u041d\u043e, \u043a\u043e\u043d\u0435\u0447\u043d\u043e \u0436\u0435, \u044d\u0442\u043e \u043c\u043e\u0436\u043d\u043e \u0438\u0437\u043c\u0435\u043d\u0438\u0442\u044c.<br \/>  \u041e\u0431\u0440\u0430\u0442\u0438\u0442\u0435 \u0432\u043d\u0438\u043c\u0430\u043d\u0438\u0435 \u043d\u0430 \u043f\u043e\u043b\u0435 final price \u2014 \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u0432\u044b\u0437\u043e\u0432\u0430 .addToTotalRow() \u043c\u044b \u043f\u043e\u043c\u0435\u0442\u0438\u043b\u0438 \u0435\u0433\u043e \u0434\u043b\u044f \u0441\u0443\u043c\u043c\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f \u0432 \u0438\u0442\u043e\u0433\u043e\u0432\u043e\u0439 \u0441\u0442\u0440\u043e\u043a\u0435.<br \/>  \u0422\u0443\u0442 \u0442\u0430\u043a\u0436\u0435 \u0435\u0441\u0442\u044c \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e CRUD-hook\u2019\u043e\u0432: \u043f\u0435\u0440\u0435\u0434 \u0441\u043e\u0445\u0440\u0430\u043d\u0435\u043d\u0438\u0435\u043c \u043e\u0431\u043d\u043e\u0432\u043b\u044f\u0435\u043c \u0438\u0442\u043e\u0433\u043e\u0432\u0443\u044e \u0441\u0443\u043c\u043c\u0443 \u043f\u043e\u0437\u0438\u0446\u0438\u0438 \u0437\u0430\u043a\u0430\u0437\u0430 \u0432 \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u0438 \u043e\u0442 \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u0430, \u043f\u043e\u0441\u043b\u0435 \u0441\u043e\u0445\u0440\u0430\u043d\u0435\u043d\u0438\u044f \u0443\u0434\u0430\u043b\u044f\u0435\u043c, \u0438 \u0437\u0430\u043d\u043e\u0432\u043e \u0441\u043e\u0437\u0434\u0430\u0451\u043c \u043d\u043e\u0432\u0443\u044e \u0442\u0440\u0430\u043d\u0437\u0430\u043a\u0446\u0438\u044e, \u0430 \u0442\u0430\u043a\u0436\u0435 \u0443\u0434\u0430\u043b\u044f\u0435\u043c \u0442\u0440\u0430\u043d\u0437\u0430\u043a\u0446\u0438\u0438 \u043f\u0440\u0438 \u0443\u0434\u0430\u043b\u0435\u043d\u0438\u0438 \u043f\u043e\u0437\u0438\u0446\u0438\u0438 \u0437\u0430\u043a\u0430\u0437\u0430. \u0421\u043b\u0435\u0434\u0443\u044f \u043f\u0440\u0438\u043d\u0446\u0438\u043f\u0443 <a href=\"https:\/\/ru.wikipedia.org\/wiki\/Don%E2%80%99t_repeat_yourself\">DRY<\/a>, \u043c\u044b \u043f\u043e\u0432\u0442\u043e\u0440\u043d\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c \u0444\u0443\u043d\u043a\u0446\u0438\u044e \u0434\u043b\u044f \u0443\u0434\u0430\u043b\u0435\u043d\u0438\u044f \u0442\u0440\u0430\u043d\u0437\u0430\u043a\u0446\u0438\u0439:  <\/p>\n<pre><code class=\"javascript\">function removeTransaction(Crud, Entity) {     var crud = Crud.crudForEntityType('Transaction');     return crud.find({filtering: {orderItem: Entity.id}}).then(function (transactions) {         if (transactions.length) {             return crud.deleteEntity(transactions[0].id);         }     }); } <\/code><\/pre>\n<p>  \u0410 \u0434\u043b\u044f \u043f\u043e\u0441\u043b\u0435\u0434\u043e\u0432\u0430\u0442\u0435\u043b\u044c\u043d\u043e\u0439 \u043d\u0443\u043c\u0435\u0440\u0430\u0446\u0438\u0438 \u0437\u0430\u043a\u0430\u0437\u043e\u0432 \u0443 \u043d\u0430\u0441 \u0431\u0443\u0434\u0435\u0442 \u0441\u0447\u0451\u0442\u0447\u0438\u043a \u0437\u0430\u043a\u0430\u0437\u043e\u0432:  <\/p>\n<pre><code class=\"javascript\">OrderCounter: {     fields: {         number: Fields.integer(&quot;Counter&quot;)     } } <\/code><\/pre>\n<p>  <\/p>\n<h1>\u041e\u0441\u043d\u043e\u0432\u043d\u043e\u0439 POS \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441<\/h1>\n<p>  \u0412\u0441\u043f\u043e\u043c\u043d\u0438\u0442\u0435 \u043a\u0430\u043a \u0432\u044b \u0431\u043e\u0440\u043e\u043b\u0438\u0441\u044c \u0441 \u043f\u0435\u0440\u0435\u0433\u0440\u0443\u0436\u0435\u043d\u043d\u044b\u043c\u0438 \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441\u0430\u043c\u0438. \u0418 \u043a\u0430\u043a \u0432\u044b \u0431\u044b\u043b\u0438, \u0432\u0435\u0440\u043e\u044f\u0442\u043d\u043e, \u0441\u0447\u0430\u0441\u0442\u043b\u0438\u0432\u044b \u043d\u0430\u0436\u0438\u043c\u0430\u0442\u044c \u0432\u0441\u0435\u0433\u043e \u043b\u0438\u0448\u044c \u043f\u0430\u0440\u0443 \u0431\u043e\u043b\u044c\u0448\u0438\u0445 \u0446\u0432\u0435\u0442\u043d\u044b\u0445 \u043a\u043d\u043e\u043f\u043e\u043a \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u044e\u0442 \u0432\u0441\u044e \u0440\u0430\u0431\u043e\u0442\u0443. \u041d\u0430\u0448\u0438 \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u0438 \u043f\u043e \u043a\u0430\u0441\u0442\u043e\u043c\u0438\u0437\u0430\u0446\u0438\u0438 \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0442 \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441 \u0434\u043b\u044f \u0440\u0430\u0431\u043e\u0442\u044b \u043f\u0440\u043e\u0441\u0442\u044b\u043c \u0438 \u043f\u043e\u043d\u044f\u0442\u043d\u044b\u043c. <br \/>  \u0412\u044b\u0448\u0435 \u043c\u044b \u0443\u043f\u043e\u043c\u044f\u043d\u0443\u043b\u0438 \u0447\u0442\u043e \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u0435\u043d\u0438\u0435 \u201cPointOfSale\u201d \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u0446\u0435\u043d\u0442\u0440\u0430\u043b\u044c\u043d\u043e\u0439 \u0447\u0430\u0441\u0442\u044c\u044e \u0434\u043b\u044f \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f. \u0412 \u043d\u0451\u043c \u043f\u0440\u043e\u0438\u0441\u0445\u043e\u0434\u0438\u0442 \u043e\u0441\u043d\u043e\u0432\u043d\u0430\u044f \u0440\u0430\u0431\u043e\u0442\u0430 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f \u0441 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0435\u043c \u2014 \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u0435 \u0437\u0430\u043a\u0430\u0437\u043e\u0432. \u041e\u043d\u043e \u0437\u0430\u0434\u0430\u0451\u0442\u0441\u044f \u0432 \u0444\u0430\u0439\u043b\u0435 pos.jade:  <\/p>\n<div class=\"spoiler\"><b class=\"spoiler_title\">pos.jade<\/b><\/p>\n<div class=\"spoiler_text\">\n<pre><code class=\"javascript\">extends main include mixins block vars     - var hasToolbar = false block content     div(ng-app='allcount', ng-controller='EntityViewController')         +defaultList()         .container.screen-container(ng-cloak)             .row(ng-controller=&quot;PosController&quot;)                 .col-md-8                     .items-bar.row.btn-toolbar(lc-list=&quot;'Item'&quot;, paging=&quot;{}&quot;)                         .col-lg-4.col-md-6.col-xs-12(ng-repeat=&quot;item in items&quot;)                             button.btn.btn-lg.btn-block.btn-default(ng-click=&quot;addItem(item)&quot;)                                 p {{item.name}}                                 p {{(item.price \/ 100) | currency}}                     .container-fluid                         h1 Total: {{viewState.editForm.entity().total\/100 | currency}}                     .row.btn-toolbar                         .col-md-4                             button.btn.btn-lg.btn-danger.btn-block(ng-click=&quot;deleteEntity()&quot;, ng-disabled=&quot;!viewState.formEntityId&quot;) Cancel                         .col-md-4(ng-hide='viewState.isFormEditing')                             +startFormEditingButton()(ng-disabled=&quot;!viewState.formEntityId&quot;).btn-block.btn-lg                         .col-md-4(ng-show='viewState.isFormEditing')                             +doneFormEditingButton()(ng-disabled=&quot;!viewState.formEntityId&quot;).btn-block.btn-lg                         .col-md-4                             button.btn.btn-lg.btn-success.btn-block(ng-click=&quot;viewState.mode = 'list'; viewState.formEntityId = undefined&quot;, ng-disabled=&quot;!viewState.formEntityId&quot;) Finish                 .col-md-4                     +defaultEditForm()(ng-show=&quot;true&quot;)                         +defaultFormTemplate() block js     +entityJs()     script.         angular.module('allcount').controller('PosController', ['$scope', 'lcApi', '$q', function ($scope, lcApi, $q) {             $scope.addItem = function (item) {                 var promise;                 if (!$scope.viewState.formEntityId) {                     promise = lcApi.createEntity({entityTypeId: 'Order'}, {}).then(function (orderId) {                         $scope.navigateTo(orderId)                         return orderId;                     })                 } else {                     promise = $q.when($scope.viewState.formEntityId);                 }                 promise.then(function (orderId) {                     return lcApi.findRange({entityTypeId: 'OrderItem'}, {filtering: {order: orderId}}).then(function (items) {                         var existingOrderItem = _.find(items, function (i) {                             return i.item.id === item.id;                         })                         return (existingOrderItem ?                                         lcApi.updateEntity({entityTypeId: 'OrderItem'}, {                                             id: existingOrderItem.id,                                             quantity: 1 + existingOrderItem.quantity                                         }) :                                         lcApi.createEntity({entityTypeId: 'OrderItem'}, {                                             order: {id: orderId},                                             item: item,                                             quantity: 1                                         })                         ).then(function () {                                     return $scope.editForm.reloadEntity();                                 })                     })                 })             }         }])     style.         .items-bar .btn-block {             margin-bottom: 10px;         } <\/code><\/pre>\n<p>  <\/div>\n<\/div>\n<p>  \u0414\u0430\u0432\u0430\u0439\u0442\u0435 \u0440\u0430\u0437\u0431\u0435\u0440\u0451\u043c\u0441\u044f \u0441 \u0442\u0435\u043c, \u0447\u0442\u043e \u0442\u0430\u043c \u043f\u0440\u043e\u0438\u0441\u0445\u043e\u0434\u0438\u0442 \u0432\u043d\u0443\u0442\u0440\u0438.<br \/>  \u0412 \u043d\u0430\u0447\u0430\u043b\u0435 \u043c\u044b \u0432\u0438\u0434\u0438\u043c \u044d\u0442\u0438 \u0434\u0432\u0435 \u0441\u0442\u0440\u043e\u043a\u0438:  <\/p>\n<pre><code class=\"javascript\">    extends main     include mixins <\/code><\/pre>\n<p>  \u201cmain\u201d \u0438 \u201cmixins\u201d \u2014 \u044d\u0442\u043e \u0432\u0441\u0442\u0440\u043e\u0435\u043d\u043d\u044b\u0435 \u0448\u0430\u0431\u043b\u043e\u043d\u044b. \u041f\u0435\u0440\u0432\u044b\u0439 \u2014 \u044d\u0442\u043e \u0444\u0443\u043d\u0434\u0430\u043c\u0435\u043d\u0442 \u0440\u0430\u0437\u043c\u0435\u0442\u043a\u0438, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043f\u0440\u043e\u0441\u0442\u043e \u043e\u0431\u044f\u0437\u0430\u0442\u0435\u043b\u0435\u043d \u0434\u043e \u0442\u0435\u0445 \u043f\u043e\u0440, \u043f\u043e\u043a\u0430 \u0432\u044b \u043d\u0435 \u0445\u043e\u0442\u0438\u0442\u0435 \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u0447\u0442\u043e-\u0442\u043e \u0441\u043e\u0432\u0441\u0435\u043c \u043d\u0435\u043e\u0431\u044b\u0447\u043d\u043e\u0435. \u0412\u0442\u043e\u0440\u043e\u0439 \u043f\u0440\u0435\u0434\u043e\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u0442 \u0432\u0430\u043c \u0441\u0430\u043c\u043e\u0441\u0442\u043e\u044f\u0442\u0435\u043b\u044c\u043d\u044b\u0435 jade-\u0441\u043d\u0438\u043f\u043f\u0435\u0442\u044b \u0434\u043b\u044f \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441\u043d\u044b\u0445 \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u043e\u0432, \u0442\u0430\u043a\u0438\u0445 \u043a\u0430\u043a: \u0442\u0430\u0431\u043b\u0438\u0446\u044b, \u0441\u0442\u0440\u043e\u043a\u0438 \u0442\u0430\u0431\u043b\u0438\u0446, \u043f\u043e\u043b\u044f, \u043f\u043e\u0434\u0432\u0430\u043b\u044b, \u043d\u0430\u0434\u043f\u0438\u0441\u0438 \u0438 \u0442.\u0434. <\/p>\n<p>  \u041f\u0430\u0440\u0430 \u0441\u043b\u043e\u0432 \u043e \u0431\u043b\u043e\u043a\u0430\u0445 \u0432\u043d\u0443\u0442\u0440\u0438 \u201cmain\u201d: \u0442\u0430\u043c \u0435\u0441\u0442\u044c \u0431\u043b\u043e\u043a\u0438 \u201cvars\u201d, \u201ccontent\u201d \u0438 \u201cjs\u201d, \u043d\u0430\u0437\u0432\u0430\u043d\u0438\u044f \u043a\u043e\u0442\u043e\u0440\u044b\u0445 \u043f\u043e \u0441\u0443\u0442\u0438 \u0433\u043e\u0432\u043e\u0440\u044f\u0442 \u0441\u0430\u043c\u0438 \u0437\u0430 \u0441\u0435\u0431\u044f:<br \/>  \u201cvars\u201d \u0440\u0430\u0441\u043f\u043e\u043b\u0430\u0433\u0430\u0435\u0442\u0441\u044f \u0432 \u0441\u0430\u043c\u043e\u043c \u0432\u0435\u0440\u0445\u0443<br \/>  \u201chead\u201d \u2014 \u0432\u043d\u0443\u0442\u0440\u0438 \u0437\u0430\u0433\u043e\u043b\u043e\u0432\u043a\u0430<br \/>  \u201ccontent\u201d \u044d\u0442\u043e \u0447\u0430\u0441\u0442\u044c \u0433\u043b\u0430\u0432\u043d\u043e\u0439 \u043e\u0431\u043b\u0430\u0441\u0442\u0438 \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u044b<br \/>  \u201cjs\u201d \u044d\u0442\u043e \u043f\u043e\u0441\u043b\u0435\u0434\u043d\u0435\u0435 \u0432\u043d\u0443\u0442\u0440\u0438 \u0442\u0435\u043b\u0430 \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u044b<\/p>\n<p>  \u0424\u043b\u0430\u0433 \u201chasToolbar\u201d \u044d\u0442\u043e \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u0430\u044f \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u044f\u0435\u0442 \u043d\u0443\u0436\u043d\u043e \u043b\u0438 \u0434\u043e\u0431\u0430\u0432\u043b\u044f\u0442\u044c \u0434\u0432\u043e\u0439\u043d\u043e\u0439 \u043e\u0442\u0441\u0442\u0443\u043f \u043f\u043e\u0434 \u043d\u0430\u0432\u0438\u0433\u0430\u0446\u0438\u043e\u043d\u043d\u043e\u0439 \u043f\u0430\u043d\u0435\u043b\u044c\u044e.<br \/>  \u0414\u0430\u043b\u044c\u0448\u0435 \u043c\u044b \u043e\u043f\u0438\u0448\u0435\u043c \u043d\u0430\u0448\u0435 \u0433\u043b\u0430\u0432\u043d\u043e\u0435 UI \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0435:   <\/p>\n<pre><code class=\"javascript\">  div(ng-app='allcount', ng-controller='EntityViewController') <\/code><\/pre>\n<p>  \u041e\u0431\u0440\u0430\u0442\u0438\u0442\u0435 \u0432\u043d\u0438\u043c\u0430\u043d\u0438\u0435, \u0447\u0442\u043e \u043c\u044b \u0434\u043e\u043b\u0436\u043d\u044b \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u201callcount\u201d \u0432 \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u0435 \u0438\u043c\u0435\u043d\u0438 \u0434\u043b\u044f \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f. \u042d\u0442\u043e \u043d\u0443\u0436\u043d\u043e \u0434\u043b\u044f \u0442\u043e\u0433\u043e \u0447\u0442\u043e \u0431\u044b \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u044c \u0434\u043e\u0441\u0442\u0443\u043f \u0434\u043e \u0440\u0430\u0437\u043b\u0438\u0447\u043d\u044b\u0445 \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u0435\u0439 AllacountJS Angular \u0442\u0438\u043f\u0430 \u043a\u043e\u043d\u0442\u0440\u043e\u043b\u043b\u0435\u0440\u043e\u0432 \u0438 \u0434\u0438\u0440\u0435\u043a\u0442\u0438\u0432.<\/p>\n<p>  \u201c+defaultList()\u201d \u0434\u043e\u0431\u0430\u0432\u043b\u044f\u0435\u0442 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442 \u201clc-list\u201d \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043c\u044b \u043c\u043e\u0436\u0435\u043c \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0434\u043b\u044f \u043e\u0442\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u044f \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u043e\u0432 \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441\u0430 \u0441\u043f\u0438\u0441\u043e\u0447\u043d\u043e\u0433\u043e \u0442\u0438\u043f\u0430. \u041d\u043e \u043a\u043e\u043d\u043a\u0440\u0435\u0442\u043d\u043e \u044d\u0442\u043e\u0442 \u201c\u0441\u043f\u0438\u0441\u043e\u043a\u201d \u043d\u0430\u0445\u043e\u0434\u0438\u0442\u0441\u044f \u0432 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0438 \u0444\u043e\u0440\u043c\u044b \u0438 \u043d\u0435 \u043e\u0442\u043e\u0431\u0440\u0430\u0436\u0430\u0435\u0442\u0441\u044f \u0432 \u0432\u0438\u0434\u0435 \u0441\u043f\u0438\u0441\u043a\u0430, \u0437\u0430\u0442\u043e \u0434\u0430\u0451\u0442 \u043d\u0430\u043c \u043a\u043d\u043e\u043f\u043a\u0443 \u201cedit\u201d, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u043d\u0443\u0436\u043d\u0430 \u0434\u043b\u044f \u0440\u0435\u0434\u0430\u043a\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f \u0442\u0435\u043a\u0443\u0449\u0435\u0433\u043e \u0437\u0430\u043a\u0430\u0437\u0430.  <\/p>\n<pre><code class=\"javascript\">       .container.screen-container(ng-cloak)        .row(ng-controller=&quot;PosController&quot;) <\/code><\/pre>\n<p>  \u0422\u0443\u0442 \u0443 \u043d\u0430\u0441 \u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440 \u0441 POS \u043a\u043e\u043d\u0442\u0440\u043e\u043b\u043b\u0435\u0440\u043e\u043c, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043c\u044b \u043e\u043f\u0438\u0448\u0435\u043c \u043f\u043e\u0442\u043e\u043c. \u0410 \u0434\u0430\u043b\u0435\u0435 \u0443 \u043d\u0430\u0441 \u0434\u0432\u0435 \u043a\u043e\u043b\u043e\u043d\u043a\u0438:  <\/p>\n<pre><code class=\"javascript\">        .col-md-8            ...          .col-md-4                 \u2026 <\/code><\/pre>\n<p>  \u0412 \u043f\u0435\u0440\u0432\u043e\u0439 (\u0431\u043e\u043b\u044c\u0448\u043e\u0439) \u043a\u043e\u043b\u043e\u043d\u043a\u0435 \u043e\u0442\u043e\u0431\u0440\u0430\u0436\u0430\u0435\u0442\u0441\u044f \u0441\u043f\u0438\u0441\u043e\u043a \u0434\u043e\u0441\u0442\u0443\u043f\u043d\u044b\u0445 \u043f\u043e\u0437\u0438\u0446\u0438\u0439:   <\/p>\n<pre><code class=\"javascript\"> .items-bar.row.btn-toolbar(lc-list=&quot;'Item'&quot;, paging=&quot;{}&quot;)              .col-lg-4.col-md-6.col-xs-12(ng-repeat=&quot;item in items&quot;)                button.btn.btn-lg.btn-block.btn-default(ng-click=&quot;addItem(item)&quot;)                  p {{item.name}}                  p {{(item.price \/ 100) | currency}} <\/code><\/pre>\n<p>  \u0410\u0442\u0440\u0438\u0431\u0443\u0442 lc-list=&quot;&#8217;Item&#8217;&quot; \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u0434\u0438\u0440\u0435\u043a\u0442\u0438\u0432\u043e\u0439 \u0438 \u0442\u0440\u0435\u0431\u0443\u0435\u0442\u0441\u044f \u0434\u043b\u044f \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u0438\u044f \u0441\u043f\u0438\u0441\u043a\u0430 \u043f\u043e\u0437\u0438\u0446\u0438\u0439, \u0430 \u0430\u0442\u0440\u0438\u0431\u0443\u0442 paging={} \u0433\u043e\u0432\u043e\u0440\u0438\u0442 \u043e \u0442\u043e\u043c \u0447\u0442\u043e \u043f\u0435\u0439\u0434\u0436\u0438\u043d\u0433 \u043d\u0430\u043c \u0442\u0443\u0442 \u043d\u0435 \u043d\u0443\u0436\u0435\u043d. <\/p>\n<p>  \u0412\u043d\u0443\u0442\u0440\u0435\u043d\u043d\u0438\u0439 div:   <\/p>\n<pre><code class=\"javascript\"> .col-lg-4.col-md-6.col-xs-12(ng-repeat=&quot;item in items&quot;)<\/code><\/pre>\n<p>  \u043f\u0440\u043e\u0445\u043e\u0434\u0438\u0442 \u043f\u043e \u043f\u043e\u0437\u0438\u0446\u0438\u044f\u043c \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u0434\u0438\u0440\u0435\u043a\u0442\u0438\u0432\u044b \u201cng-repeat\u201d \u0438 \u043e\u0442\u043e\u0431\u0440\u0430\u0436\u0430\u0435\u0442 \u0431\u043e\u043b\u044c\u0448\u0438\u0435 \u043a\u043d\u043e\u043f\u043a\u0438 \u0434\u043b\u044f \u043a\u043e\u043d\u043a\u0440\u0435\u0442\u043d\u043e\u0439 \u043f\u043e\u0437\u0438\u0446\u0438\u0438.<br \/>  <img decoding=\"async\" src=\"https:\/\/habrastorage.org\/files\/4da\/cc5\/442\/4dacc5442de54607853de5e093abaacf.png\" alt=\"item in items\"\/><br \/>  \u041f\u043e\u0434 \u0441\u043f\u0438\u0441\u043a\u043e\u043c \u043f\u043e\u0437\u0438\u0446\u0438\u0439 \u2014 \u0438\u0442\u043e\u0433\u043e\u0432\u0430\u044f \u0441\u0443\u043c\u043c\u0430 \u0432 \u0432\u0430\u043b\u044e\u0442\u0435 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f:  <\/p>\n<pre><code class=\"javascript\">           .container-fluid              h1 Total: {{viewState.editForm.entity().total\/100 | currency}} <\/code><\/pre>\n<p>  \u0418 \u0441\u0442\u0440\u043e\u043a\u0430 \u0441 \u043a\u043d\u043e\u043f\u043a\u0430\u043c\u0438:  <\/p>\n<pre><code class=\"javascript\">    .row.btn-toolbar              .col-md-4                button.btn.btn-lg.btn-danger.btn-block(ng-click=&quot;deleteEntity()&quot;, ng-disabled=&quot;!viewState.formEntityId&quot;) Cancel              .col-md-4(ng-hide='viewState.isFormEditing')                +startFormEditingButton()(ng-disabled=&quot;!viewState.formEntityId&quot;).btn-block.btn-lg              .col-md-4(ng-show='viewState.isFormEditing')                  +doneFormEditingButton()(ng-disabled=&quot;!viewState.formEntityId&quot;).btn-block.btn-lg              .col-md-4                  button.btn.btn-lg.btn-success.btn-block(ng-click=&quot;viewState.mode = 'list'; viewState.formEntityId = undefined&quot;, ng-disabled=&quot;!viewState.formEntityId&quot;) Finish <\/code><\/pre>\n<p>  <img decoding=\"async\" src=\"https:\/\/habrastorage.org\/files\/fc8\/15a\/90a\/fc815a90a31543bc81db4290d7f74853.png\" alt=\"Total and buttons toolbar\"\/><br \/>  \u0415\u0449\u0451 \u0443 \u043d\u0430\u0441 \u0435\u0441\u0442\u044c \u0441\u043d\u0438\u043f\u043f\u0435\u0442 \u0438\u0437 \u0448\u0430\u0431\u043b\u043e\u043d\u0430 \u043d\u0430 \u0444\u043e\u0440\u043c\u0435 \u0434\u043b\u044f \u0442\u0435\u043a\u0443\u0449\u0435\u0433\u043e \u0437\u0430\u043a\u0430\u0437\u0430 \u0432 \u043f\u0440\u0430\u0432\u043e\u0439 \u043a\u043e\u043b\u043e\u043d\u043a\u0435:  <\/p>\n<pre><code class=\"javascript\">             +defaultEditForm()(ng-show=&quot;true&quot;)              +defaultFormTemplate() <\/code><\/pre>\n<p>  <img decoding=\"async\" src=\"https:\/\/habrastorage.org\/files\/72c\/9c2\/3d9\/72c9c23d9e264c2fa9a1c5bd5b940c3e.png\" alt=\"Edit and form template\"\/><br \/>  \u0412 \u043a\u043e\u043d\u0446\u0435 \u0443 \u043d\u0430\u0441 \u0442\u0430\u043a\u043e\u0439 \u0431\u043b\u043e\u043a \u0441 \u043a\u043e\u0434\u043e\u043c:  <\/p>\n<pre><code class=\"javascript\">    block js       +entityJs()       script.         angular.module('allcount').controller('PosController', ['$scope', 'lcApi', '$q', function ($scope, lcApi, $q) {           $scope.addItem = function (item) {             var promise;             if (!$scope.viewState.formEntityId) {               promise = lcApi.createEntity({entityTypeId: 'Order'}, {}).then(function (orderId) {                 $scope.navigateTo(orderId)                 return orderId;               })             } else {               promise = $q.when($scope.viewState.formEntityId);             }             promise.then(function (orderId) {               return lcApi.findRange({entityTypeId: 'OrderItem'}, {filtering: {order: orderId}}).then(function (items) {                 var existingOrderItem = _.find(items, function (i) {                   return i.item.id === item.id;                 })                 return (existingOrderItem ?                    lcApi.updateEntity({entityTypeId: 'OrderItem'}, {id: existingOrderItem.id, quantity: 1 + existingOrderItem.quantity}) :                    lcApi.createEntity({entityTypeId: 'OrderItem'}, {order: {id: orderId}, item: item, quantity: 1})                   ).then(function () {                     return $scope.editForm.reloadEntity();                   })               })             })           }         }])       style.         .items-bar .btn-block {           margin-bottom: 10px;         } <\/code><\/pre>\n<p>  \u0412 \u043d\u0451\u043c \u043c\u044b \u0437\u0430\u0434\u0430\u0451\u043c \u043d\u0430\u0448 \u0433\u043b\u0430\u0432\u043d\u044b\u0439 \u043a\u043e\u043d\u0442\u0440\u043e\u043b\u043b\u0435\u0440, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0432\u0434\u043e\u0445\u043d\u0451\u0442 \u0436\u0438\u0437\u043d\u044c \u0432 POS. \u041f\u043e \u0431\u043e\u043b\u044c\u0448\u0435\u0439 \u0447\u0430\u0441\u0442\u0438 \u043e\u043d \u0433\u043e\u0432\u043e\u0440\u0438\u0442 \u043d\u0430\u0448\u0435\u043c\u0443 \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u0435\u043d\u0438\u044e \u043a\u0430\u043a \u0434\u043e\u0431\u0430\u0432\u043b\u044f\u0442\u044c \u043d\u043e\u0432\u044b\u0435 \u043f\u043e\u0437\u0438\u0446\u0438\u0438 \u0432 \u0437\u0430\u043a\u0430\u0437. \u0412 \u043e\u0441\u043d\u043e\u0432\u043d\u043e\u043c \u0437\u0434\u0435\u0441\u044c \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f \u043a\u043b\u044e\u0447\u0435\u0432\u043e\u0439 \u043c\u0435\u0445\u0430\u043d\u0438\u0437\u043c AllcountJS \u0434\u043b\u044f AngularJS \u2014 \u043f\u0440\u043e\u0432\u0430\u0439\u0434\u0435\u0440 \u201clcApi\u201d. \u0421 \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u043d\u0435\u0433\u043e \u0442\u0443\u0442 \u043f\u0440\u043e\u0438\u0441\u0445\u043e\u0434\u0438\u0442 \u043f\u043e\u0438\u0441\u043a, \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u0435 \u0438 \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u044f \u0437\u0430\u043a\u0430\u0437\u0430 \u0438 \u043f\u043e\u0437\u0438\u0446\u0438\u0439 \u0437\u0430\u043a\u0430\u0437\u0430.<\/p>\n<p>  \u0412 \u0438\u0442\u043e\u0433\u0435 \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u043c\u043e\u0435 \u201cpos.jade\u201d \u0431\u0443\u0434\u0435\u0442 \u0432\u044b\u0433\u043b\u044f\u0434\u0435\u0442\u044c \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u043c \u043e\u0431\u0440\u0430\u0437\u043e\u043c:<\/p>\n<p>  \u0421\u0443\u0442\u044c \u0432 \u0442\u043e\u043c \u0447\u0442\u043e \u0435\u0441\u043b\u0438 \u0443 \u0432\u0430\u0441 \u0435\u0441\u0442\u044c \u043f\u0440\u043e\u0434\u0443\u043c\u0430\u043d\u043d\u044b\u0439 UX, \u0442\u043e \u0432\u044b \u043c\u043e\u0436\u0435\u0442\u0435 \u0441 \u043b\u0435\u0433\u043a\u043e\u0441\u0442\u044c\u044e \u0432\u044b\u0440\u0430\u0437\u0438\u0442\u044c \u0435\u0433\u043e \u0432 UI. \u0418 \u044d\u0442\u043e \u0442\u043e\u0447\u043d\u043e \u0442\u043e \u0447\u0442\u043e \u043c\u044b \u0441\u0435\u0439\u0447\u0430\u0441 \u0441\u0434\u0435\u043b\u0430\u0435\u043c \u2013 \u0441\u043e\u0437\u0434\u0430\u0434\u0438\u043c \u0444\u0430\u0439\u043b \u2018pos.jade\u2019 \u0441\u043e \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u043c \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u043c\u044b\u043c:  <\/p>\n<h1>\u0418\u0442\u043e\u0433\u043e<\/h1>\n<p>  \u0427\u0442\u043e \u0436\u0435 \u043c\u044b \u0441\u0434\u0435\u043b\u0430\u043b\u0438: \u043e\u043f\u0438\u0441\u0430\u043b\u0438 \u043c\u043e\u0434\u0435\u043b\u044c, \u0431\u0438\u0437\u043d\u0435\u0441 \u043b\u043e\u0433\u0438\u043a\u0443 \u0438 \u0443\u0434\u043e\u0431\u043d\u044b\u0439 \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441.<br \/>  \u0422\u0435\u043f\u0435\u0440\u044c \u0441\u043b\u043e\u0436\u0438\u043c \u0432\u0441\u0451 \u0432\u043c\u0435\u0441\u0442\u0435. \u0418\u0442\u043e\u0433\u043e\u0432\u044b\u0439 \u0444\u0430\u0439\u043b \u0441 \u043a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0430\u0446\u0438\u0435\u0439 \u0431\u0443\u0434\u0435\u0442 \u0432\u044b\u0433\u043b\u044f\u0434\u0435\u0442\u044c \u0442\u0430\u043a (\u0438\u0437 \u043d\u0435 \u0443\u043f\u043e\u043c\u044f\u043d\u0443\u0442\u043e\u0433\u043e \u0432 \u043d\u0451\u043c \u0442\u043e\u043b\u044c\u043a\u043e \u043c\u0435\u043d\u044e \u0438 \u043f\u0440\u0438\u043c\u0435\u0440\u044b \u0434\u0430\u043d\u043d\u044b\u0445):  <\/p>\n<div class=\"spoiler\"><b class=\"spoiler_title\">app.js<\/b><\/p>\n<div class=\"spoiler_text\">\n<pre><code class=\"javascript\">A.app({     appName: &quot;POS and inventory&quot;,     appIcon: &quot;calculator&quot;,     onlyAuthenticated: true,     menuItems: [         {             name: &quot;Transactions&quot;,             entityTypeId: &quot;Transaction&quot;,             icon: &quot;send-o&quot;         }, {             name: &quot;Items&quot;,             entityTypeId: &quot;Item&quot;,             icon: &quot;cubes&quot;         }, {             name: &quot;Orders&quot;,             entityTypeId: &quot;Order&quot;,             icon: &quot;shopping-cart&quot;         },         {             name: &quot;POS&quot;,             entityTypeId: &quot;PointOfSale&quot;,             icon: &quot;calculator&quot;         }     ],     entities: function (Fields) {         return {             Transaction: {                 fields: {                     item: Fields.reference(&quot;Item&quot;, &quot;Item&quot;),                     order: Fields.reference(&quot;Order&quot;, &quot;Order&quot;),                     orderItem: Fields.reference(&quot;Order item&quot;, &quot;OrderItem&quot;),                     quantity: Fields.integer(&quot;Quantity&quot;)                 },                 showInGrid: ['item', 'order', 'quantity']             },             Item: {                 fields: {                     name: Fields.text(&quot;Name&quot;),                     stock: Fields.integer(&quot;Stock&quot;).computed('sum(transactions.quantity)'),                     price: Fields.money(&quot;Price&quot;),                     transactions: Fields.relation(&quot;Transactions&quot;, &quot;Transaction&quot;, &quot;item&quot;)                 },                 referenceName: &quot;name&quot;             },             Order: {                 fields: {                     number: Fields.integer(&quot;Order #&quot;),                     date: Fields.date(&quot;Date&quot;),                     total: Fields.money(&quot;Total&quot;).computed('sum(orderItems.finalPrice)'),                     orderItems: Fields.relation(&quot;Items&quot;, &quot;OrderItem&quot;, &quot;order&quot;)                 },                 beforeSave: function (Entity, Dates, Crud) {                     if (!Entity.date) {                         Entity.date = Dates.nowDate();                     }                     return Crud.crudFor('OrderCounter').find({}).then(function (last) {                         if (!Entity.number) {                             Entity.number = last[0].number;                             return Crud.crudFor('OrderCounter').updateEntity({                                 id: last[0].id,                                 number: last[0].number + 1                             });                         }                     })                 },                 beforeDelete: function (Entity, Crud, Q) {                     var crud = Crud.crudFor('OrderItem');                     return crud.find({filtering: {order: Entity.id}}).then(function (items) {                         return Q.all(items.map(function (i) {                             return crud.deleteEntity(i.id)                         }));                     });                 },                 referenceName: &quot;number&quot;,                 views: {                     PointOfSale: {                         customView: 'pos'                     }                 }             },             OrderItem: {                 fields: {                     order: Fields.reference(&quot;Order&quot;, &quot;Order&quot;),                     item: Fields.fixedReference(&quot;Item&quot;, &quot;Item&quot;).required(),                     quantity: Fields.integer(&quot;Quantity&quot;).required(),                     finalPrice: Fields.money(&quot;Final price&quot;).readOnly().addToTotalRow()                 },                 showInGrid: ['item', 'quantity', 'finalPrice'],                 beforeSave: function (Crud, Entity) {                     return Crud.crudFor('Item').readEntity(Entity.item.id).then(function (item) {                         Entity.finalPrice = Entity.quantity * item.price;                     })                 },                 afterSave: function (Crud, Entity) {                     var crud = Crud.crudForEntityType('Transaction');                     return removeTransaction(Crud, Entity).then(function () {                         return crud.createEntity({                             order: Entity.order,                             orderItem: {id: Entity.id},                             item: Entity.item,                             quantity: Entity.quantity * -1                         })                     })                 },                 beforeDelete: function (Crud, Entity) {                     return removeTransaction(Crud, Entity);                 }             },             OrderCounter: {                 fields: {                     number: Fields.integer(&quot;Counter&quot;)                 }             },         }     },     migrations: function (Migrations) {         return [             {                 name: &quot;demo-records-1&quot;,                 operation: Migrations.insert(&quot;Item&quot;, [                     {id: &quot;1&quot;, name: &quot;Snickers&quot;, price: 299},                     {id: &quot;2&quot;, name: &quot;Coffee&quot;, price: 199},                     {id: &quot;3&quot;, name: &quot;Tea&quot;, price: 99}                 ])             },             {                 name: &quot;demo-records-2&quot;,                 operation: Migrations.insert(&quot;Transaction&quot;, [                     {id: &quot;1&quot;, item: {id: &quot;1&quot;}, quantity: &quot;50&quot;},                     {id: &quot;2&quot;, item: {id: &quot;2&quot;}, quantity: &quot;100&quot;},                     {id: &quot;3&quot;, item: {id: &quot;3&quot;}, quantity: &quot;200&quot;}                 ])             },             {                 name: &quot;order-counter&quot;,                 operation: Migrations.insert(&quot;OrderCounter&quot;, [                     {id: &quot;2&quot;, number: 1}                 ])             }         ]     } });  function removeTransaction(Crud, Entity) {     var crud = Crud.crudForEntityType('Transaction');     return crud.find({filtering: {orderItem: Entity.id}}).then(function (transactions) {         if (transactions.length) {             return crud.deleteEntity(transactions[0].id);         }     }); } <\/code><\/pre>\n<p>  <\/div>\n<\/div>\n<p>  \u0417\u0430\u043c\u0435\u0447\u0443 \u0447\u0442\u043e \u0435\u0441\u043b\u0438 \u0443 \u0432\u0430\u0441 \u044f\u0437\u044b\u043a \u0431\u0440\u0430\u0443\u0437\u0435\u0440\u0430 \u0430\u043d\u0433\u043b\u0438\u0439\u0441\u043a\u0438\u0439, \u0442\u043e \u0446\u0435\u043d\u044b \u0431\u0443\u0434\u0443\u0442 \u043e\u0442\u043e\u0431\u0440\u0430\u0436\u0430\u0442\u044c\u0441\u044f \u0432 \u0434\u043e\u043b\u043b\u0430\u0440\u0430\u0445, \u0430 \u0435\u0441\u043b\u0438 \u0440\u0443\u0441\u0441\u043a\u0438\u0439 \u2014 \u0442\u043e \u0432 \u0440\u0443\u0431\u043b\u044f\u0445.   <\/p>\n<h1>\u0417\u0430\u043f\u0443\u0441\u043a<\/h1>\n<p>  \u0415\u0441\u043b\u0438 \u0432\u044b \u0443\u0436\u0435 \u0437\u043d\u0430\u043a\u043e\u043c\u044b \u0441 AllcountJS \u0442\u043e \u0432\u0430\u043c \u043d\u0435 \u0441\u043e\u0441\u0442\u0430\u0432\u0438\u0442 \u0442\u0440\u0443\u0434\u0430 \u0437\u0430\u043f\u0443\u0441\u0442\u0438\u0442\u044c \u044d\u0442\u043e\u0442 \u043a\u043e\u0434. \u0414\u043b\u044f \u043e\u0441\u0442\u0430\u043b\u044c\u043d\u044b\u0445 \u0432\u043a\u0440\u0430\u0442\u0446\u0435 \u0440\u0430\u0441\u0441\u043a\u0430\u0436\u0443 \u043a\u0430\u043a \u044d\u0442\u043e \u0441\u0434\u0435\u043b\u0430\u0442\u044c:  <\/p>\n<ul>\n<li>\u0421\u043e\u0437\u0434\u0430\u0439\u0442\u0435 \u043d\u043e\u0432\u0443\u044e \u0434\u0438\u0440\u0435\u043a\u0442\u043e\u0440\u0438\u044e<\/li>\n<li>\u0421\u043e\u0437\u0434\u0430\u0439\u0442\u0435 \u0432\u043d\u0443\u0442\u0440\u0438 \u043d\u0435\u0451 \u0444\u0430\u0439\u043b app.js \u0438 \u0432\u0441\u0442\u0430\u0442\u044c\u0435 \u0432 \u043d\u0435\u0433\u043e \u043a\u043e\u0434 \u0440\u0430\u0441\u043f\u043e\u043b\u043e\u0436\u0435\u043d\u043d\u044b\u0439 \u0432\u044b\u0448\u0435<\/li>\n<li>\u041f\u043e\u043b\u043e\u0436\u0438\u0442\u0435 \u0444\u0430\u0439\u043b pos.jade \u0440\u044f\u0434\u043e\u043c<\/li>\n<li>\u0423\u0441\u0442\u043d\u043e\u0432\u0438\u0442\u0435 allcountjs-cli (\u043a\u0430\u043a \u044d\u0442\u043e \u0434\u0435\u043b\u0430\u0435\u0442\u0441\u044f \u043e\u043f\u0438\u0441\u0430\u043d\u043e \u0432 \u043f\u0440\u0435\u0434\u044b\u0434\u0443\u0449\u0435\u0439 \u0441\u0442\u0430\u0442\u044c\u0435 \u0438\u043b\u0438 \u043d\u0430 \u043e\u0444\u0444\u0438\u0446\u0438\u0430\u043b\u044c\u043d\u043e\u043c \u0441\u0430\u0439\u0442\u0435)<\/li>\n<li>\u0417\u0430\u043f\u0443\u0441\u0442\u0438\u0442\u044c \u0441\u0435\u0440\u0432\u0435\u0440 allcountjs -c app.js (\u043f\u0440\u0438 \u044d\u0442\u043e\u043c \u0441\u0435\u0440\u0432\u0438\u0441 MongoDB \u0434\u043e\u043b\u0436\u0435\u043d \u0431\u044b\u0442\u044c \u0443\u0436\u0435 \u0437\u0430\u043f\u0443\u0449\u0435\u043d)<\/li>\n<li>\u041f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0435 \u0431\u0443\u0434\u0435\u0442 \u0434\u043e\u0441\u0442\u0443\u043f\u043d\u043e \u043d\u0430 <a href=\"http:\/\/localhost\">localhost<\/a>:9080<\/li>\n<\/ul>\n<h1>\u0410 \u043d\u0430\u0441\u0442\u043e\u044f\u0449\u0438\u0439 POS?<\/h1>\n<p>  \u0418 \u0442\u0430\u043a \u043c\u044b \u0441\u043e\u0437\u0434\u0430\u043b\u0438 \u043f\u0440\u043e\u0441\u0442\u043e\u0435 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0435 \u0434\u043b\u044f POS \u0442\u0435\u0440\u043c\u0438\u043d\u0430\u043b\u0430. \u041a\u0430\u043a \u0435\u0433\u043e \u043c\u043e\u0436\u043d\u043e \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u0440\u0430\u0431\u043e\u0447\u0438\u043c? \u041d\u0443\u0436\u043d\u043e \u043d\u0430\u043f\u0438\u0441\u0430\u0442\u044c \u0430\u043d\u0430\u043b\u043e\u0433 \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u0435\u043d\u0438\u044f PointOfSale \u0434\u043b\u044f \u043c\u043e\u0431\u0438\u043b\u044c\u043d\u043e\u0433\u043e \u0443\u0441\u0442\u0440\u043e\u0439\u0441\u0442\u0432\u0430 \u0438 \u0443\u043f\u0430\u043a\u043e\u0432\u0430\u0442\u044c \u0432\u0435\u0431-\u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0435 \u0432 \u043c\u043e\u0431\u0438\u043b\u044c\u043d\u043e\u0435 \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e ionic, \u0430 \u043f\u043e\u0442\u043e\u043c \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u0438\u043d\u0442\u0435\u0433\u0440\u0430\u0446\u0438\u044e c \u043e\u0434\u043d\u0438\u043c \u0438\u0437 \u0441\u0435\u0440\u0432\u0438\u0441\u043e\u0432 \u043c\u043e\u0431\u0438\u043b\u044c\u043d\u043e\u0433\u043e \u044d\u043a\u0432\u0430\u0439\u0440\u0438\u043d\u0433\u0430 (\u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440 2can \u0438\u043b\u0438 iBox), \u0438 \u0432\u043e\u0442 \u0443 \u0432\u0430\u0441 \u0443\u0436\u0435 \u0440\u0435\u0430\u043b\u044c\u043d\u044b\u0439 \u0440\u0430\u0431\u043e\u0447\u0438\u0439 POS \u0442\u0435\u0440\u043c\u0438\u043d\u0430\u043b.<\/p>\n<p>  \u041d\u0430\u0434\u0435\u044e\u0441\u044c \u0432\u0430\u043c \u0431\u044b\u043b\u043e \u0438\u043d\u0442\u0435\u0440\u0435\u0441\u043d\u043e. \u0411\u0443\u0434\u0435\u043c \u0431\u043b\u0430\u0433\u043e\u0434\u0430\u0440\u043d\u044b \u0437\u0430 \u043b\u044e\u0431\u043e\u0439 \u0444\u0438\u0434\u0431\u044d\u043a. \u0422\u0443\u0442 \u0438\u043b\u0438 \u0432 <a href=\"https:\/\/gitter.im\/allcount\/allcountjs\">gitter<\/a> \u0438 <a href=\"https:\/\/gitter.im\/allcount\/allcountjs-ru\">gitter ru<\/a>.               <\/p>\n<div class=\"clear\"><\/div>\n<p> \u0441\u0441\u044b\u043b\u043a\u0430 \u043d\u0430 \u043e\u0440\u0438\u0433\u0438\u043d\u0430\u043b \u0441\u0442\u0430\u0442\u044c\u0438 <a href=\"http:\/\/habrahabr.ru\/post\/272031\/\"> http:\/\/habrahabr.ru\/post\/272031\/<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<p>       \u041f\u0440\u043e\u0434\u043e\u043b\u0436\u0430\u0435\u043c \u0437\u043d\u0430\u043a\u043e\u043c\u0441\u0442\u0432\u043e \u0441 <a href=\"https:\/\/allcountjs.com\/\">AllcountJS<\/a> \u2014 \u0444\u0440\u0435\u0439\u043c\u0432\u043e\u0440\u043a\u043e\u043c \u0434\u043b\u044f \u0431\u044b\u0441\u0442\u0440\u043e\u0439 \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0438 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0439 \u043d\u0430 \u043f\u043b\u0430\u0442\u0444\u043e\u0440\u043c\u0435 NodeJS. \u0412 \u044d\u0442\u043e\u0439 \u0441\u0442\u0430\u0442\u044c\u0435 \u043c\u044b \u0440\u0430\u0441\u0441\u043c\u043e\u0442\u0440\u0438\u043c \u043f\u0440\u0438\u043c\u0435\u0440 \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438 \u043a\u0430\u0441\u0442\u043e\u043c\u043d\u043e\u0433\u043e \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441\u0430 \u0441 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435\u043c AngualrJS \u0438 jade, \u0430 \u0442\u0430\u043a\u0436\u0435 \u043d\u0435\u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u0438 \u043a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f, \u043e \u043a\u043e\u0442\u043e\u0440\u044b\u0445 \u043c\u044b \u0435\u0449\u0451 \u043d\u0435 \u0443\u043f\u043e\u043c\u0438\u043d\u0430\u043b\u0438.<\/p>\n<p>  POS (Point Of Sale) \u2014 \u0432 \u043f\u0440\u044f\u043c\u043e\u043c \u0441\u043c\u044b\u0441\u043b\u0435 \u0442\u043e\u0447\u043a\u0430 \u043f\u0440\u043e\u0434\u0430\u0436\u0438, \u043d\u043e \u043e\u0431\u044b\u0447\u043d\u043e \u044d\u0442\u043e\u0442 \u0442\u0435\u0440\u043c\u0438\u043d \u043e\u0431\u043e\u0437\u043d\u0430\u0447\u0430\u0435\u0442 \u0440\u0430\u0431\u043e\u0447\u0435\u0435 \u043c\u0435\u0441\u0442\u043e \u043a\u0430\u0441\u0441\u0438\u0440\u0430 \u0432\u043c\u0435\u0441\u0442\u0435 \u0441 \u0442\u043e\u0440\u0433\u043e\u0432\u044b\u043c \u043e\u0431\u043e\u0440\u0443\u0434\u043e\u0432\u0430\u043d\u0438\u0435\u043c. \u0422\u0430\u043a\u0438\u0435 \u0442\u0435\u0440\u043c\u0438\u043d\u0430\u043b\u044b \u043d\u0430\u0445\u043e\u0434\u044f\u0442\u0441\u044f \u043f\u043e\u0447\u0442\u0438 \u0432 \u043a\u0430\u0436\u0434\u043e\u043c \u043c\u0435\u0441\u0442\u0435 \u0433\u0434\u0435 \u043d\u0430\u043c \u0447\u0442\u043e-\u043d\u0438\u0431\u0443\u0434\u044c \u043f\u0440\u043e\u0434\u0430\u044e\u0442. \u0418 \u0441\u0435\u0439\u0447\u0430\u0441 \u043c\u044b \u0441\u043e\u0437\u0434\u0430\u0434\u0438\u043c \u043f\u0440\u043e\u0441\u0442\u043e\u0435 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0435, \u043a\u043e\u0442\u043e\u0440\u043e\u0435 \u043f\u043e\u0437\u0432\u043e\u043b\u0438\u0442 \u0432\u0435\u0441\u0442\u0438 \u0441\u043f\u0438\u0441\u043e\u043a \u0442\u043e\u0432\u0430\u0440\u043e\u0432 \u0441 \u043e\u0441\u0442\u0430\u0442\u043a\u0430\u043c\u0438 \u0438 \u0441\u043e\u0437\u0434\u0430\u0432\u0430\u0442\u044c \u0437\u0430\u043f\u0438\u0441\u0438 \u043e \u043f\u0440\u043e\u0434\u0430\u0436\u0430\u0445.<br \/>  <img decoding=\"async\" src=\"https:\/\/habrastorage.org\/files\/323\/7be\/a9a\/3237bea9ace842da947ff037fa7af49f.png\" alt=\"POS main UI\"\/><br \/>  \u041a\u0430\u043a \u043e\u0431\u044b\u0447\u043d\u043e, \u043d\u0430 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442 \u043c\u043e\u0436\u043d\u043e \u043f\u043e\u0441\u043c\u043e\u0442\u0440\u0435\u0442\u044c \u0432 <a href=\"https:\/\/allcountjs.com\/entity\/DemoGallery\/5608faa748c663113053d164\">\u0434\u0435\u043c\u043e \u0433\u0430\u043b\u0435\u0440\u0435\u0438<\/a>.  <\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[],"tags":[],"class_list":["post-269356","post","type-post","status-publish","format-standard","hentry"],"_links":{"self":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/269356","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=269356"}],"version-history":[{"count":0,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/269356\/revisions"}],"wp:attachment":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=269356"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=269356"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=269356"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}