powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / Delphi [игнор отключен] [закрыт для гостей] / Delphi + онлайн-кассы
25 сообщений из 125, страница 1 из 5
Delphi + онлайн-кассы
    #39550056
арт2010
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
На подходе переход на онлайн кассы. У нас по точкам самописная кассовая прога (Delphi 2007), аппараты Штрих-М. Сейчас печатаем чек в собственном формате (основная инфа + общая скидка по чеку). Как я понимаю скоро всю инфу надо будет передавать через онлайн кассы в строго определенном формате (в частности, к примеру, как я понимаю скидка уже должна быть по каждому наименованию в чеке). Кто-нибудь может поделиться выходными структурами данными на Delphi, которые должны буду передаваться в онлайн по новому формату? Как это вообще все должно работать? В общем нужна любая инфа по теме Delphi + онлайн-кассы
...
Рейтинг: 0 / 0
Delphi + онлайн-кассы
    #39550077
Фотография krapotkin
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
насколько я понимаю, всю инфу должна передавать сама касса с онлайн-эклз
...
Рейтинг: 0 / 0
Delphi + онлайн-кассы
    #39550157
Близнец1980
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
арт2010,

Касса сама данные передает ОФД.
Мне не потребовалось много усилий переделать под он-лайн, тоже ШТРИХ.
Там все тоже самое, что и раньше, кроме нескольких нюансов.

Я использую такой алгоритм:

по каждой строке чека:
Price - цена уже со скидкой, т.к. скидку он не делает, а в конце чека просто ее печатаем как обычный текст.
Quantity - Количество,
Department - Отдел,
StringforPrinting = Наименование товара. Тут из-за одного аппарата пришлось резать до 1 строки - 48 символов для ШТРИХ-М-02Ф, а то ошибку выдавало. А вообще в ОФД должно передаваться не более 64 символов.
Дальше Sale или ReturnSale, с чеками корректировки так и не разобрался.
Любой дополнительный текст StringforPrinting и PrintString.

После в Summ1 - сумма от покупателя наличными, Summ2..4 - электронными (названия настраиваются в кассовом аппарате)
Если нужно отправить чек на эл.почту или на телефон, то в CustomerEmail соответственно адрес почты или № телефона и вызываем метод FNSendCustomerEmail. Но дойдет или нет зависит от ОФД.
Закрытие чека CloseCheck.

Еще одна особенности ШТРИХа:
Хоть и ФИО кассира настраивается в самом аппарате в отдельном поле, но аппарат его берет из таблицы настроек паролей кассиров.
Что-бы аппарат выводил правильное ФИО кассира, а сделал так:
Код: pascal
1.
2.
3.
4.
5.
6.
7.
DrvFR = := CreateOleObject('AddIn.DrvFR');
            DrvFR.Password:=30;
            DrvFR.TableNumber:=2;
            DrvFR.RowNumber:=30;
            DrvFR.FieldNumber:=2;
            DrvFR.ValueOfFieldString:='ÊÀÑÑÈÐ '+User;
            DrvFR.WriteTable;


т.е. подмена названия кассира и работаем всегда от сист.администратора.
...
Рейтинг: 0 / 0
Delphi + онлайн-кассы
    #39550158
Фотография Gallemar
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
krapotkinнасколько я понимаю, всю инфу должна передавать сама касса с онлайн-эклз
Не обязательно. Есть ккм с ethernet,они сразу передают, есть с usb, там эмуляция ethernet over usb, там на кассе ПО ставится
...
Рейтинг: 0 / 0
Период между сообщениями больше года.
Delphi + онлайн-кассы
    #39781935
Aleks2019
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Близнец1980, Есть исходные коды для Delphi 2010? хочу прикрутить функционал к проге для работы с Штрих-М и онлайн-кассой
...
Рейтинг: 0 / 0
Delphi + онлайн-кассы
    #39781957
Близнец1980
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Aleks2019,

Delphi 7, если нужно могу немного кода именно работы со Штрихом сюда выложить.
...
Рейтинг: 0 / 0
Delphi + онлайн-кассы
    #39782003
Aleks2019
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Близнец1980, на почту мне можешь скинуть исх.коды?
...
Рейтинг: 0 / 0
Delphi + онлайн-кассы
    #39782008
Близнец1980
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Aleks2019,

E-Mail: скрыт
...
Рейтинг: 0 / 0
Delphi + онлайн-кассы
    #39782021
Aleks2019
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Близнец1980,auto-soft2012@mail.ru
...
Рейтинг: 0 / 0
Delphi + онлайн-кассы
    #39782064
Alex Zhuravlev
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
А можно сюда код выложить?
...
Рейтинг: 0 / 0
Delphi + онлайн-кассы
    #39782141
Близнец1980
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Alex Zhuravlev,

Код работы с ККТ из работающей программы.

Ничего сложного нет, все в документации описано.


Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
74.
75.
76.
77.
78.
79.
80.
81.
82.
83.
84.
85.
86.
87.
88.
89.
90.
91.
92.
93.
94.
95.
96.
97.
98.
99.
100.
101.
102.
103.
104.
105.
106.
107.
108.
109.
110.
111.
112.
113.
114.
115.
116.
117.
118.
119.
120.
121.
122.
123.
124.
125.
126.
127.
128.
129.
130.
131.
132.
133.
134.
135.
136.
137.
138.
139.
140.
141.
142.
143.
144.
145.
146.
147.
148.
149.
150.
151.
152.
153.
154.
155.
156.
157.
158.
159.
160.
161.
162.
163.
164.
165.
166.
167.
168.
169.
170.
171.
172.
173.
174.
175.
176.
177.
178.
179.
180.
181.
182.
183.
184.
185.
186.
187.
188.
189.
190.
191.
192.
193.
194.
195.
196.
197.
198.
199.
200.
201.
202.
203.
204.
205.
206.
207.
208.
209.
210.
211.
212.
213.
214.
215.
216.
217.
218.
219.
220.
221.
222.
223.
224.
225.
226.
227.
228.
229.
230.
231.
232.
233.
234.
235.
236.
237.
238.
239.
240.
241.
242.
243.
244.
245.
246.
247.
248.
249.
250.
251.
252.
253.
254.
255.
256.
257.
258.
259.
260.
261.
262.
263.
264.
265.
266.
267.
268.
269.
270.
271.
272.
273.
274.
275.
276.
277.
278.
279.
280.
281.
282.
283.
284.
285.
286.
287.
288.
289.
290.
291.
292.
293.
294.
295.
296.
297.
298.
299.
300.
301.
302.
303.
304.
305.
306.
307.
308.
309.
310.
311.
312.
313.
314.
315.
316.
317.
318.
319.
320.
321.
322.
323.
324.
325.
326.
327.
328.
329.
330.
331.
332.
333.
334.
335.
336.
337.
338.
339.
340.
341.
342.
343.
344.
345.
346.
347.
348.
349.
350.
351.
352.
353.
354.
355.
356.
357.
358.
359.
360.
361.
362.
363.
364.
365.
366.
367.
368.
369.
370.
371.
372.
373.
374.
375.
376.
377.
378.
379.
380.
381.
382.
383.
384.
385.
386.
387.
388.
389.
390.
391.
392.
393.
394.
395.
396.
397.
398.
399.
400.
401.
402.
403.
404.
405.
406.
407.
408.
409.
410.
411.
412.
413.
414.
415.
416.
417.
418.
419.
420.
421.
422.
423.
424.
425.
426.
427.
428.
429.
430.
431.
432.
433.
434.
435.
436.
437.
438.
439.
440.
441.
442.
443.
444.
445.
446.
447.
448.
449.
450.
451.
452.
453.
454.
455.
456.
457.
458.
459.
460.
461.
462.
463.
464.
465.
466.
467.
468.
469.
470.
471.
472.
473.
474.
475.
476.
477.
478.
479.
480.
481.
482.
483.
484.
485.
486.
487.
488.
489.
490.
491.
492.
493.
494.
495.
496.
497.
498.
499.
500.
501.
502.
503.
504.
505.
506.
507.
508.
509.
510.
511.
512.
513.
514.
515.
516.
517.
518.
519.
520.
521.
522.
523.
524.
525.
526.
527.
528.
529.
530.
531.
532.
533.
534.
535.
536.
537.
538.
539.
540.
541.
542.
543.
544.
545.
546.
547.
548.
549.
550.
551.
552.
553.
554.
555.
556.
557.
558.
559.
560.
561.
562.
563.
564.
565.
566.
567.
568.
569.
570.
571.
572.
573.
574.
575.
576.
577.
578.
579.
580.
581.
582.
583.
584.
585.
586.
587.
588.
589.
590.
591.
592.
593.
594.
595.
596.
597.
598.
599.
600.
601.
602.
603.
604.
605.
606.
607.
608.
609.
610.
611.
612.
613.
614.
615.
616.
617.
618.
619.
620.
621.
622.
623.
624.
625.
626.
627.
628.
629.
630.
631.
632.
633.
634.
635.
636.
637.
638.
639.
640.
641.
642.
643.
644.
645.
646.
647.
648.
649.
650.
651.
652.
653.
654.
655.
656.
657.
658.
659.
660.
661.
662.
663.
664.
665.
666.
667.
668.
669.
670.
671.
672.
673.
674.
675.
676.
677.
678.
679.
680.
681.
682.
683.
//регистрация чека в ККТ
function TFProdChek.RegProdInFR: boolean;
var
  Npp, I, lStrSum, len: integer;
  S, S1: string;
  BonusPlus, BonusMinus, BonusOst: Double;
  DECIMALSEPARATOR_OLD :Char;

begin
  FMain.WriteLogToFile('Регистрация чека в ККМ');
  Result := False;
  len := 0; //длина строки

  if KKM = 1 then
    len := 50
  else if (KKM = 2) or (KKM = 3) then
    len := 48;

  try
     DECIMALSEPARATOR_OLD := DECIMALSEPARATOR ;
     DECIMALSEPARATOR := '.';

    //открываем чек
    if TypeCheck = 1 then
      FMain.DrvFR.CheckType := 0//продажа
    else
      FMain.DrvFR.CheckType := 2; //возврат
    if FMain.DrvFR.OpenCheck <> 0 then
    begin
      FMain.GetErrorFR;
      FMain.WriteLogToFile('Ошибка ККМ: Не открывается чек!');
      raise Exception.Create('Ошибка ККМ!' + #13 + 'Не открывается чек!');
      Exit;
    end;
     //строки
    MTChek.First;
    Npp := 0;
    BonusPlus := 0;
    BonusMinus := 0;
    BonusOst := 0;
    while not MTChek.Eof do
    begin
      Npp := Npp + 1;
      if TypeCheck = 1 then
        if KKM = 3 then //он-лайн
           FMain.DrvFR.Price := MTChek.FieldByName('ZENAPROD').Value
        else
          FMain.DrvFR.Price := MTChek.FieldByName('ZENBSK').Value
      else
        FMain.DrvFR.Price := MTChek.FieldByName('ZENAPROD').Value;

      FMain.DrvFR.Quantity := MTChek.FieldByName('KOL').Value;

	//наименование товара
      S := IntToStr(Npp) + '. ' + MTChek.FieldByName('CODE').AsString + ' ' + MTChek.FieldByName('NAME').AsString + ' ' + MTChek.FieldByName('MODEL').AsString + ', ' + MTChek.FieldByName('EDIZM').AsString;
      FMain.WriteLogToFile('S = ' + S);

      if length(s) > len then
      begin
        s:=Copy(S, 0, len);
      end;

      FMain.DrvFR.StringforPrinting := S;

      if TypeCheck = 1 then
      begin

        if FMain.DrvFR.Sale <> 0 then
        begin
          FMain.GetErrorFR;
          FMain.WriteLogToFile('Ошибка ККМ: Не регистрируется продажа по строке - ' + IntToStr(Npp) + ' !');
          raise Exception.Create('Ошибка ККМ!' + #13 + 'Не регистрируется продажа по строке - ' + IntToStr(Npp) + ' !');
          Exit;
        end;
      end
      else
      begin
        if FMain.DrvFR.ReturnSale <> 0 then
        begin
          FMain.GetErrorFR;
          FMain.WriteLogToFile('Ошибка ККМ: Не регистрируется возврат продажи по строке - ' + IntToStr(Npp) + ' !');
          raise Exception.Create('Ошибка ККМ!' + #13 + 'Не регистрируется возврат продажи по строке - ' + IntToStr(Npp) + ' !');
          Exit;
        end;
      end;

      FMain.WriteLogToFile('Регистрация в ККМ, подсчет бонусов');
      BonusPlus := BonusPlus + MTChek.FieldByName('BonusPlus').AsFloat;

      BonusMinus := BonusMinus + MTChek.FieldByName('BonusMinus').AsFloat;

      if MTChek.FieldByName('SumSK').AsFloat <> 0 then
         begin

            S := 'ЦЕНА БЕЗ СКИДКИ:';
            S1 := Format('= %0:f', [MTChek.FieldByName('ZENBSK').AsFloat]);
            lStrSum := len - length(S1);
            for I := 17 to lStrSum do
              S := S + '_';

            S := S + S1;
            FMain.DrvFR.StringforPrinting := S;
            FMain.DrvFR.PrintString;

            FMain.WriteLogToFile('Строка ЦЕНА БЕЗ СКИДКИ: "'+S+'"');

            S := Format('СКИДКА: %0:.1f', [MTChek.FieldByName('ProcSK').AsFloat])+'%';
            S1 := Format('= %0:f', [MTChek.FieldByName('SumSK').AsFloat]);
            lStrSum := len - length(S1);
            for I := 14 to lStrSum do
              S := S + '_';

            S := S + S1;
            FMain.DrvFR.StringforPrinting := S;
            FMain.DrvFR.PrintString;

            FMain.WriteLogToFile('Строка со скидкой: "'+S+'"');

         end;


      MTChek.Next;

    end;

    FMain.WriteLogToFile('закрываем чек');

     //закрываем чек
         //скидка
    FMain.DrvFR.StringforPrinting := '==================================================';
    FMain.DrvFR.PrintString;

    if TypeCheck = 1 then
    begin
      if SumSkid <> 0 then
      begin
        //итоговая сумма
        S := 'ИТОГО БЕЗ СКИДКИ:';
        S1 := Format('%0:f', [SumBezSkid]); 
        lStrSum := len - length(S1);
        for I := 18 to lStrSum do
          S := S + '_';

        S := S + S1;
        FMain.DrvFR.StringforPrinting := S;
        FMain.DrvFR.PrintString;

        FMain.WriteLogToFile('S = ' + S);

        if trim(Shtrih) <> '' then
          if FMain.ThisBonusCard(Shtrih) then
            FMain.DrvFR.StringforPrinting := 'Бонусная карта: ' + Shtrih
          else
            FMain.DrvFR.StringforPrinting := 'Дисконтная карта: ' + Shtrih
        else
          FMain.DrvFR.StringforPrinting := '';

        FMain.WriteLogToFile('скидка = ' + FloatToStr(SumSkid) + ' FMain.DrvFR.StringforPrinting = ' + FMain.DrvFR.StringforPrinting);

        if KKM = 3 then //он-лайн
          begin
             FMain.DrvFR.PrintString;
             FMain.DrvFR.FontType:=2;

              S := 'СКИДКА';
              S1 := Format('%0:f', [SumSkid]); //Trim(CurrToStr(SumChek+SumSkid));
              lStrSum := 23 - length(S1);
              for I := 6 to lStrSum do
                S := S + ' ';

              S := S + S1;
              FMain.DrvFR.StringforPrinting := S;

             FMain.DrvFR.PrintStringWithFont;

          end
        else
          begin
             //скидка
             FMain.DrvFR.Summ1 := SumSkid;
              if FMain.DrvFR.Discount <> 0 then
              begin
                FMain.GetErrorFR;
                FMain.WriteLogToFile('Ошибка ККМ: Некорректная скидка!');
                raise Exception.Create('Ошибка ККМ!' + #13 + 'Некорректная скидка!');
                Exit;
              end;

          end;

      end;

    end; //продажа

        //бонусы
    if FMain.ThisBonusCard(Shtrih) then
    begin
      if FMain.ZConMySQL.Connected then
              //проверим еще раз
        if FMain.ZConMySQL.PingServer then
        begin
          try
            FMain.ZQTmp.Close;
            FMain.ZQTmp.SQL.Text := 'SELECT SUM(ba.Summa) AS Summa FROM sprdk s, bonus_account ba WHERE s.ID_BONUS_ACCOUNT = ba.ID AND s.Shtrih = :vShtrih ';
            FMain.ZQTmp.ParamByName('vShtrih').Value := Shtrih;
            FMain.ZQTmp.Open;
            if FMain.ZQTmp.RecordCount > 0 then
              BonusOst := FMain.ZQTmp.FIeldByName('Summa').Value;
          except
            BonusOst := 0;
          end;

        end;

      FMain.DrvFR.StringforPrinting := '';
      FMain.DrvFR.PrintString;
      FMain.DrvFR.StringforPrinting := '==================================================';
      FMain.DrvFR.PrintString;
      FMain.DrvFR.StringforPrinting := '';
      FMain.DrvFR.PrintString;

      if BonusPlus > 0 then
      begin
        if TypeCheck = 1 then
          S := 'Начислено бонусов:'
        else
          S := 'Списано бонусов:';

        S1 := Format('%0:f', [BonusPlus]);
        lStrSum := len - length(S1);
        for I := length(S) + 1 to lStrSum do
          S := S + '_';
        S := S + S1;
        FMain.DrvFR.StringforPrinting := S;
        FMain.DrvFR.PrintString;
        FMain.WriteLogToFile('S = ' + S);

      end;


      if BonusMinus > 0 then
      begin
        if TypeCheck = 1 then
          S := 'Использовано бонусов:'
        else
          S := 'Возвращено бонусов:';

        S1 := Format('%0:f', [BonusMinus]);
        lStrSum := len - length(S1);
        for I := length(S) + 1 to lStrSum do
          S := S + '_';
        S := S + S1;

        FMain.DrvFR.StringforPrinting := S;
        FMain.DrvFR.PrintString;

        FMain.WriteLogToFile('S = ' + S);

      end;

      if BonusOst <> 0 then
      begin
        S := 'Остаток бонусов:';
        S1 := Format('%0:f', [BonusOst]);
        lStrSum := len - length(S1);
        for I := length(S) + 1 to lStrSum do
          S := S + '_';
        S := S + S1;
        FMain.DrvFR.StringforPrinting := S;
        FMain.DrvFR.PrintString;

        FMain.WriteLogToFile('S = ' + S);

      end;

      FMain.DrvFR.StringforPrinting := '';
      FMain.DrvFR.PrintString;
      FMain.DrvFR.StringforPrinting := '==================================================';
      FMain.DrvFR.PrintString;
      FMain.DrvFR.StringforPrinting := '';
      FMain.DrvFR.PrintString;

    end;

    FMain.DrvFR.Summ1:=0;
    FMain.DrvFR.Summ2:=0;
    FMain.DrvFR.Summ3:=0;
    FMain.DrvFR.Summ4:=0;

        //суммы от покупателя
    if (CurrEditNal.Value = 0) and (CurrEditCart.Value <> SumChek) then
      FMain.DrvFR.Summ1 := SumChek  - CurrEditCart.Value
    else
      FMain.DrvFR.Summ1 := CurrEditNal.Value;

    if CBCard.Checked then
       FMain.DrvFR.Summ4 := CurrEditCart.Value;

    if Trim(edEmail.Text) <> '' then
       begin
         //В качестве параметра можно передавать или телефон (+7хххххххххх) или e-mail: test@test.com
         try
            FMain.DrvFR.CustomerEmail := Trim(edEmail.Text);
            FMain.DrvFR.FNSendCustomerEmail;
          except
           on E: Exception do
             begin
                 FMain.WriteLogToFile('Регистрация в ККМ: Ошибка передачи телефона или e-mail: '+E.Message);
             end;

          end;
       end;

    FMain.DrvFR.StringforPrinting := '';
    if FMain.DrvFR.CloseCheck <> 0 then
    begin
      FMain.GetErrorFR;
      FMain.WriteLogToFile('Ошибка ККМ: Ошибка закрытия чека!');
      FMain.DrvFR.CancelCheck;
      raise Exception.Create('Ошибка ККМ!' + #13 + 'Ошибка закрытия чека!');
      Exit;
    end;
       result:=True;
  finally
     DECIMALSEPARATOR := DECIMALSEPARATOR_OLD;

  end;
end;


procedure TFMain.FormDestroy(Sender: TObject);
begin
	DrvFR.Disconnect;
end;

procedure TFMain.FormCreate(Sender: TObject);
begin
	DrvFR:= CreateOleObject('AddIn.DrvFR');
end;

procedure TFMain.FormShow(Sender: TObject);
begin      
    if DrvFR.Connect = 0 then
        begin
            DrvFR.Password:=30;
            DrvFR.TableNumber:=2;
            DrvFR.RowNumber:=30;
            DrvFR.FieldNumber:=2;
            DrvFR.ValueOfFieldString:='КАССИР '+User;
            DrvFR.WriteTable;
            FWait.Close;
        end
    else
            GetErrorFR;
    end;
end;

procedure TFMain.GetErrorFR;
var
  ResultCode: Integer;
  ResultCodeDescription: string;
begin
  ResultCode := DrvFR.ResultCode;
  ResultCodeDescription := DrvFR.ResultCodeDescription;
  WriteLogToFile('Ошибка фискального регистратора: '+Format('(%d) %s', [ResultCode, ResultCodeDescription]));
  Application.MessageBox(PAnsiChar('Ошибка фискального регистратора!'+#13+Format('(%d) %s', [ResultCode, ResultCodeDescription])),'Ошибка ККМ',MB_ICONSTOP);
end;

//аннулировать чек
procedure TFMain.N36Click(Sender: TObject);
begin
   if DrvFR.CancelCheck<>0 then
       GetErrorFR;
end;

//закрыть чек
procedure TFMain.N35Click(Sender: TObject);
begin
   if DrvFR.CloseCheck<>0 then
       GetErrorFR;
end;

//окно свойств
procedure TFMain.NNastrFRClick(Sender: TObject);
begin
    DrvFR.ShowProperties;
end;

//Z-Отчет
procedure TFMain.NCloseSmenFRClick(Sender: TObject);
begin
    if Application.MessageBox('Закрыть смену в ККМ и снять Z-Отчет ?', 'Касса', MB_ICONWARNING+MB_YESNO) = IDYES then
      begin
        DrvFR.Password:=30;
        if DrvFR.PrintReportWithCleaning<>0 then
	    // DrvFR.PrintReportWithoutCleaning - Х-отчет (без гашения)

            GetErrorFR;
      end;
end;

//продолжить печать
procedure TFMain.NContinuePrintClick(Sender: TObject);
begin
   if DrvFR.ContinuePrint<>0 then
       GetErrorFR;
end;

//повторная печать последнего чека
procedure TFMain.N33Click(Sender: TObject);
begin
   if DrvFR.RepeatDocument<>0 then
       GetErrorFR;
end;

//показать статус ККМ
procedure TFMain.NGetModeFRClick(Sender: TObject);
begin
    if DrvFR.GetShortECRStatus=0 then
        ShowMessage('Режим ККМ: '+DrvFR.ECRModeDescription+#13+'Подрежим ККМ:'+DrvFR.ECRAdvancedModeDescription)
    else
        GetErrorFR;
end;

//данные по кассовой смене из ККМ 
procedure TFMain.AddToJournKKM(Kassmen:string);
var SumN, SumViruchki, SumProd:Double;
begin

   if not CreateFR then Exit;


    //данные ККМ запишем в таблицу

    if FTJournKKM.Locate('Kassmen',Kassmen,[]) then
       FTJournKKM.Edit
    else
       FTJournKKM.Append;

    FTJournKKM.FieldByName('Kassmen').Value:= Kassmen;
    FTJournKKM.FieldByName('datetime').AsDateTime := Now;

    SumViruchki:=0;
    SumProd:=0;

    //сумма на начало смены
    DrvFR.Password:= 30;
    DrvFR.TypeOfSumOfEntriesFM := True;
    DrvFR.GetFMRecordsSum;
    SumN:=DrvFR.Summ1;
    FTJournKKM.FieldByName('sumsmenn').Value:=SumN ;

   // ДЕНЕЖНЫЕ РЕГИСТРЫ

   //продажа наличнымим
    DrvFR.RegisterNumber:= 193;
    DrvFR.GetCashReg;
    FMain.FTJournKKM.FieldByName('SUMNAL').Value:=DrvFR.ContentsOfCashRegister;
    SumProd:=DrvFR.ContentsOfCashRegister;

    SumViruchki:=DrvFR.ContentsOfCashRegister;

   //продажа по картам
    DrvFR.RegisterNumber:= 205;
    DrvFR.GetCashReg;
    FMain.FTJournKKM.FieldByName('SUMCARD').Value:=DrvFR.ContentsOfCashRegister;
    SumProd:=SumProd + DrvFR.ContentsOfCashRegister;
    SumViruchki:=SumViruchki + DrvFR.ContentsOfCashRegister;

    FTJournKKM.FieldByName('sumsmenk').Value:=SumN+SumProd;
    FMain.FTJournKKM.FieldByName('SUMPROD').Value:=SumProd;


   //возврат продажа наличнымим
    DrvFR.RegisterNumber:= 195;
    DrvFR.GetCashReg;
    FMain.FTJournKKM.FieldByName('SUMVNAL').Value:=DrvFR.ContentsOfCashRegister;

    SumViruchki:=SumViruchki - DrvFR.ContentsOfCashRegister;

   //возврат продажа по картам
    DrvFR.RegisterNumber:= 207;
    DrvFR.GetCashReg;
    FMain.FTJournKKM.FieldByName('SUMVCARD').Value:=DrvFR.ContentsOfCashRegister;

    SumViruchki:=SumViruchki - DrvFR.ContentsOfCashRegister;

   //наличность в кассе
    DrvFR.RegisterNumber:= 241;
    DrvFR.GetCashReg;
    FMain.FTJournKKM.FieldByName('SUMNALKAS').Value:=DrvFR.ContentsOfCashRegister;

   //внесенные суммы
    DrvFR.RegisterNumber:= 242;
    DrvFR.GetCashReg;
    FMain.FTJournKKM.FieldByName('SUMVNESEN').Value:=DrvFR.ContentsOfCashRegister;

   //выплаченные суммы
    DrvFR.RegisterNumber:= 243;
    DrvFR.GetCashReg;
    FMain.FTJournKKM.FieldByName('SUMVIPLAT').Value:=DrvFR.ContentsOfCashRegister;


     //сумма выручки
     //(193-194-195+196)+(197-198-199+200)+(201-202-203+204)+(205-206-207+208)
     //наш часный случай   (193-195)+(205-207)
      FMain.FTJournKKM.FieldByName('Viruchka').Value:=SumViruchki ;

   // ОПЕРАЦИОННЫЕ РЕГИСТРЫ

   //кол-во продаж
     DrvFR.RegisterNumber:= 144;
     DrvFR.GetOperationReg;
     FMain.FTJournKKM.FieldByName('KOLPROD').Value:=DrvFR.ContentsOfOperationRegister;

     //кол возвратов продаж
     DrvFR.RegisterNumber:= 146;
     DrvFR.GetOperationReg;
     FMain.FTJournKKM.FieldByName('KOLVOZVRAT').Value:=DrvFR.ContentsOfOperationRegister;

     //номер смены
     //GetEKLZCode2Report
     DrvFR.GetECRStatus;
     FMain.FTJournKKM.FieldByName('NUMBER').Value:=DrvFR.SessionNumber+1;

    FMain.FTJournKKM.Post;
    FMain.FTJournKKM.Close;

end;


//закончились ли 24 часа в текущей смене
function  TFMain.ItEnded24Hours:Boolean;
begin
   result:=False;

   if CreateFR then
       begin
       if FMain.DrvFR.GetECRStatus <> 0 then
          begin
              FMain.WriteLogToFile('Ошибка получения статуса ККМ! '+Format('(%d) %s', [FMain.DrvFR.ResultCode, FMain.DrvFR.ResultCodeDescription]));
              Application.MessageBox(PAnsiChar('Ошибка получения статуса ККМ! '+#13+Format('(%d) %s', [FMain.DrvFR.ResultCode, FMain.DrvFR.ResultCodeDescription])),'Регистрация чека',MB_ICONSTOP);
              Exit;
          end;
       
         if DrvFR.IsFM24HoursOver then
            begin
               Application.MessageBox(PAnsiChar('Время текущей смены в ККМ превысило 24 часа!'+#13+'Закройте текущую смену и откройте новую!'),'24 часа кончились', MB_ICONSTOP);
               result:= True;
            end;
       end;

end;

перед регистрацией продажи
    //если открытый документ, пытаемся аннулировать
       if FMain.DrvFR.ECRMode = 8 then
          begin
               FMain.DrvFR.Password:=30;
               FMain.DrvFR.SysAdminCancelCheck;
          end;


       if (FMain.DrvFR.ECRMode <> 2) and (FMain.DrvFR.ECRMode <> 4) then
          begin
              FMain.WriteLogToFile('ККМ находиться в неправильном режиме! Режим ККМ: '+FMain.DrvFR.ECRModeDescription+', Подрежим ККМ:'+FMain.DrvFR.ECRAdvancedModeDescription);
//              Application.MessageBox(PAnsiChar(
              ShowMessage('ККМ находиться в неправильном режиме!'+#13+'Режим ККМ: '+FMain.DrvFR.ECRModeDescription+#13+'Подрежим ККМ: '+FMain.DrvFR.ECRAdvancedModeDescription) ;
              //,'Регистрация чека',MB_ICONSTOP);
              Exit;
          end;


        FMain.WriteLogToFile('Режим ККМ: '+FMain.DrvFR.ECRModeDescription+', Подрежим ККМ:'+FMain.DrvFR.ECRAdvancedModeDescription);

        //текст в чеке внизу
        FMain.DrvFR.TableNumber:=4;
        FMain.DrvFR.FieldNumber:=1;

        for J:=1 to 3 do
           begin
              FMain.DrvFR.RowNumber:=J;
              if J > ChechReklama.Count then
                 FMain.DrvFR.ValueOfFieldString:=''
              else
                FMain.DrvFR.ValueOfFieldString:=ChechReklama.Strings[J-1];

              FMain.DrvFR.WriteTable;
           end;





   //Регистрация в ФР
      //открываем чек
        try

           if  OperKKM='Продажа' then
               FMain.DrvFR.CheckType := 0
           else
              if OperKKM='Возврат продажи' then
                 FMain.DrvFR.CheckType := 2;

           if (OperKKM='Продажа') or (OperKKM='Возврат продажи') then
               if FMain.DrvFR.OpenCheck<> 0 then
                  begin
                    FMain.GetErrorFR;
                    FMain.WriteLogToFile('Ошибка ККМ: Не открывается чек!');
                    raise Exception.Create('Ошибка ККМ!'+#13+'Не открывается чек!')
                  end;


    FMain.DrvFR.Summ1:=0;
    FMain.DrvFR.Summ2:=0;
    FMain.DrvFR.Summ3:=0;
    FMain.DrvFR.Summ4:=0;

        //суммы от покупателя
    if (CurrEditNal.Value = 0) and (CurrEditCart.Value <> CurrEditSum.Value) then
      FMain.DrvFR.Summ1 := CurrEditSum.Value - CurrEditCart.Value
    else
      FMain.DrvFR.Summ1 := CurrEditNal.Value;

    FMain.DrvFR.Summ4 := CurrEditCart.Value;

            FMain.DrvFR.Price := CurrEditSum.Value;
            FMain.DrvFR.Quantity :=1;

            if (OperKKM='Продажа') or (OperKKM='Возврат продажи') then
               begin
                  FMain.DrvFR.Department := StrToInt(EditOtdel.Text); //отдел
               end;

            FMain.DrvFR.StringforPrinting := ComboBoxOper.Text;

           if  OperKKM='Продажа' then
               if FMain.DrvFR.Sale<>0 then
                  begin
                    FMain.GetErrorFR;
                    FMain.WriteLogToFile('Ошибка ККМ: Не регистрируется продажа!');
                    raise Exception.Create('Ошибка ККМ!'+#13+'Не регистрируется продажа!')
                  end;
           if OperKKM='Возврат продажи' then
               if FMain.DrvFR.ReturnSale<>0 then
                  begin
                    FMain.GetErrorFR;
                    FMain.WriteLogToFile('Ошибка ККМ: Не регистрируется возврат продажи!');
                    raise Exception.Create('Ошибка ККМ!'+#13+'Не регистрируется возврат продажи!')
                  end;
           if OperKKM='Внесение' then
               if FMain.DrvFR.CashIncome<>0 then
                  begin
                    FMain.GetErrorFR;
                    FMain.WriteLogToFile('Ошибка ККМ: Не регистрируется внесение!');
                    raise Exception.Create('Ошибка ККМ!'+#13+'Не регистрируется внесение!')
                  end;

           if OperKKM='Выплата' then
              BEGIN
               if FMain.DrvFR.CashOutcome<>0 then
                  begin
                    FMain.GetErrorFR;
                    FMain.WriteLogToFile('Ошибка ККМ: Не регистрируется выплата!');
                    raise Exception.Create('Ошибка ККМ!'+#13+'Не регистрируется выплата!')
                  end;
               end;


           if (OperKKM='Продажа') or (OperKKM='Возврат продажи') then
              begin
                FMain.DrvFR.StringforPrinting := '';
                if FMain.DrvFR.CloseCheck<>0 then
                    begin
                      FMain.GetErrorFR;
                      FMain.WriteLogToFile('Ошибка ККМ: Ошибка закрытия чека!');
                      raise Exception.Create('Ошибка ККМ!'+#13+'Ошибка закрытия чека!');
                    end;
              end;
         except
           exit;
         end;
    end; // Регистрация в ФР


...
Рейтинг: 0 / 0
Delphi + онлайн-кассы
    #39782269
DmSer
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Код работы с ККТ из работающей программы.

У этой чудесной программы есть имя?
...
Рейтинг: 0 / 0
Delphi + онлайн-кассы
    #39782314
Близнец1980
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
DmSerКод работы с ККТ из работающей программы.
У этой чудесной программы есть имя?
Да. В одной небольшой компании на кассовых терминалах работает, а что не так?
...
Рейтинг: 0 / 0
Delphi + онлайн-кассы
    #39782323
cptngrb
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Близнец1980, а номер чека где берешь?
...
Рейтинг: 0 / 0
Delphi + онлайн-кассы
    #39782376
Близнец1980
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
cptngrbБлизнец1980, а номер чека где берешь?
Сам формирую, независимо от ККМ.
В других операциях (не продажа или возврат) беру из ККМ так:
Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
       if KKM = 3 then //он-лайн
            begin
               FMain.DrvFR.FNGetCurrentSessionParams;
               FMain.FTJournNOPER.AsInteger := FMain.DrvFR.ReceiptNumber;
            end
       else
         if StrToInt(EditNChek.Text) = 0 then
            begin
              FMain.DrvFR.GetECRStatus;
              FMain.FTJournNOPER.AsInteger := FMain.DrvFR.OpenDocumentNumber;
            end
         else
          FMain.FTJournNOPER.AsInteger := StrToInt(EditNChek.Text);
...
Рейтинг: 0 / 0
Delphi + онлайн-кассы
    #39782384
cptngrb
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Близнец1980, я делаю по справке, но номер чека отличается на бумажном чеке почему то. А в твоем примере берется сквозной номер документа

автор запрос содержимого операционного регистра 148 (номер чека продажи)
Перед тем, как вызвать метод GetOperationReg, необходимо заполнить следующие
свойства: присвоим свойству Password значение «1» (пароль кассира №1 по умолчанию),
а свойству RegisterNumber – значение «148» (номер операционного регистра). Вызовем
метод. В случае успешного выполнения метода значение свойства ResultCode будет
равно «0» («Ошибок нет»), в противном случае см. описание кода ошибки в свойстве
ResultCodeDescription. Если ResultCode=0, метод возвращает значения в следующие
свойства: OperatorNumber=1 (порядковый номер оператора, вызвавшего метод);
ContentsOfOperationRegister=13 (содержимое операционного регистра №148 – 13 чеков
продаж); NameOperationReg=«Номер чека продажи» (название регистра).

Код: pascal
1.
2.
3.
4.
Driver.Password:= PASSWD;
Driver.RegisterNumber:= 148;
Driver.GetOperationReg;
Result:= Driver.ContentsOfOperationRegister;
...
Рейтинг: 0 / 0
Delphi + онлайн-кассы
    #39782403
Близнец1980
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
cptngrbБлизнец1980, я делаю по справке, но номер чека отличается на бумажном чеке почему то. А в твоем примере берется сквозной номер документа

Сейчас проверил на одной кассе:
Код: pascal
1.
2.
FMain.DrvFR.FNGetCurrentSessionParams;
ShowMessage('FMain.DrvFR.ReceiptNumber = '+IntToStr(FMain.DrvFR.ReceiptNumber));

показал правильный номер последнего пробитого чека в текущей смене (12)

Код: pascal
1.
2.
3.
DrvFR.RegisterNumber:= 148;
DrvFR.GetOperationReg;
ShowMessage('Name='+DrvFR.NameOperationReg+' content '+IntToStr(DrvFR.ContentsOfOperationRegister));


непонятная цифра 666.
...
Рейтинг: 0 / 0
Delphi + онлайн-кассы
    #39782404
Alex Zhuravlev
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Близнец1980Alex Zhuravlev,
Код работы с ККТ из работающей программы.
Ничего сложного нет, все в документации описано.

Спасибо. Касса подключена к компу или по сети общение идет?
...
Рейтинг: 0 / 0
Delphi + онлайн-кассы
    #39782407
Близнец1980
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Alex ZhuravlevСпасибо. Касса подключена к компу или по сети общение идет?
К ПК по кабелю COM или USB.
...
Рейтинг: 0 / 0
Delphi + онлайн-кассы
    #39782415
V.Borzov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Близнец1980арт2010,

Еще одна особенности ШТРИХа:
Хоть и ФИО кассира настраивается в самом аппарате в отдельном поле, но аппарат его берет из таблицы настроек паролей кассиров.
Что-бы аппарат выводил правильное ФИО кассира, а сделал так:
Код: pascal
1.
2.
3.
4.
5.
6.
7.
DrvFR = := CreateOleObject('AddIn.DrvFR');
            DrvFR.Password:=30;
            DrvFR.TableNumber:=2;
            DrvFR.RowNumber:=30;
            DrvFR.FieldNumber:=2;
            DrvFR.ValueOfFieldString:='&#202;&#192;&#209;&#209;&#200;&#208; '+User;
            DrvFR.WriteTable;


т.е. подмена названия кассира и работаем всегда от сист.администратора.

Попробовал вот так юзера в чеке задать, вроде прокатило:

Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
          VarDevice.TagNumber := 1021;
          VarDevice.TagType := 7;
          VarDevice.TagValueStr := 'Неворишка М.Н.';
          VarDevice.FNSendTag;

          VarDevice.TagNumber := 1203;
          VarDevice.TagType := 7;
          VarDevice.TagValueStr := '123456789012';  // ИНН
          VarDevice.FNSendTag;


Пароль - первого кассира, например, '1', то есть.
...
Рейтинг: 0 / 0
Delphi + онлайн-кассы
    #39782418
V.Borzov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
cptngrbБлизнец1980, а номер чека где берешь?

DocumentNumber не подходит?
...
Рейтинг: 0 / 0
Delphi + онлайн-кассы
    #39782433
DmSer
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Близнец1980DmSerпропущено...

У этой чудесной программы есть имя?
Да. В одной небольшой компании на кассовых терминалах работает, а что не так?

Вы опубликовали в качестве примера код крайне низкого качества. Но для небольшой компании возможно, что и сойдёт.
...
Рейтинг: 0 / 0
Delphi + онлайн-кассы
    #39782594
cptngrb
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
V.Borzov, может и подходит, только я в справке нашел только по номеру регистра. надо попробовать
...
Рейтинг: 0 / 0
Delphi + онлайн-кассы
    #39782595
cptngrb
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
DmSer,
а покажите тот же код высокого качества, пожалуйста (кусочек)
...
Рейтинг: 0 / 0
Delphi + онлайн-кассы
    #39782612
DmSer
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
cptngrbDmSer,
а покажите тот же код высокого качества, пожалуйста (кусочек)

У меня есть исходники работы с ККМ по протоколам Штрих, Атол, Дримкас, они работают безупречно, нет сомнения в их работоспособности, но публиковать их не буду, поскольку для этого нужно их сперва привести в соответствующий вид, который не будет вызывать нареканий, а это значительная работа.
...
Рейтинг: 0 / 0
25 сообщений из 125, страница 1 из 5
Форумы / Delphi [игнор отключен] [закрыт для гостей] / Delphi + онлайн-кассы
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]