Как стать автором
Обновить

Онлайн кассы ОФД класс на Delphi

Время на прочтение7 мин
Количество просмотров3.1K

Создаем Свои класс для взаимодействия с ООФ КазакТелеком

Объявим вспомогательные типы

type
TSellBuy = class(TObject)
  Sum : Double;
  PaymentType : Integer;
  PaymentTypeName : String;
end;
type
TNonNullableType = record
  Sell : Double;
  Buy : Double;
  ReturnSell : Double;
  ReturnBuy : Double;

end;

Объявим тип для хранения данных ZX отчета

type
TZXReport = class(TObject)
  ReportNumber : Integer;
  TaxPayerName :  String;
  TaxPayerIN : String;
  TaxPayerVAT : Boolean;
  TaxPayerVATSeria : String;
  TaxPayerVATNumber : String;
  CashBoxSN : String;
  CashBoxIN : String;
  CashBoxRN : String;
  StartOn : String;
  ReportOn : String;
  CloseOn : String;
  CashierCode : Integer;
  ShiftNumber : Integer;
  DocumentCount : Integer;
  PutMoneySum : Double;
  TakeMoneySum : Double;
  ControlSum : String;
  OfflineMode : Boolean;
  CashBoxOfflineMode : Boolean;
  SumInCashbox  : Double;
  Sell : TList;{ of TSellBuy;}
  Buy : TList {of TSellBuy;};
  ReturnSell : TList {of TSellBuy;};
  ReturnBuy : TList {of TSellBuy;};
   StartNonNullable : TNonNullableType;
   EndNonNullable : TNonNullableType;

end;
type
TControlTape = class(TObject)
  OperationTypeText : String;
  Sum : Double;
  Date : String;
  EmployeeCode : Integer;
  Number : String;
  isOffline : Boolean;
  ExternalOperationId : String;
end;

Объявим тип для хранения данных кассы, в дальнейшем этот тип будем использовать чтобы авторизовываться в системе и для быстрой смены кассы

type
  TCassa = class(Tobject)
    UniqueNumber: String;
    RegistrationNumber: String;
    IdentificationNumber: String;
    Name: String;
    Description: String;
    IsOffline: Boolean;
    CurrentStatus: Integer;
    Shift: Integer;
  end;

Данный тип будем использовать как вспомогательный, чтобы хранить в

type
  Tpayment = class(Tobject)
    Sum: double;
    PaymentType: LongInt;

  end;
type
  Tposition = class(Tobject)
    Count: double;
    Price: double;
    Tax: double;
    TaxType: LongInt;
    PositionName: String;
    PositionCode: double;
    Discount: double;
    Markup: double;
    SectionCode: String;
    IsStorno: Boolean;

    UnitCode: Integer;
  end;
type
  TSendCheck = class(Tobject)
  public
    Token: String;
    CashboxUniqueNumber: String;
    OperationType: LongInt;
    Position: TJSONArray;
    Payment: TJSONArray;
    Change: double;
    RoundType: Integer;
    ExternalCheckNumber: String;
    CustomerEmail: String;

  end;
type
  Tcashbox = class(Tobject)
    Unique_Number: String;
    Registration_Number: String;
    Identity_Number: String;
    Address: String;
  end;
type
TMoneyOperation = class(TObject)
  OfflineMode : Boolean;
  CashBoxOfflineMode : Boolean;
  DateTime : String;
  Sum : Double;
  CashBox : Tcashbox;
end;
type
  TAnswerCheck = class(Tobject)
  public
  var
    check_number: String;
    date_time: String;
    offline_mode: Boolean;
    cashbox: Tcashbox;
    CheckOrderNumber: Integer;
    ShiftNumber: Integer;
    EmployeeName: String;
    TicketUrl: String;
  end;

Объявим наш основной тип, который будем использовать и добавлять в него наши функции

type
  TOOFD = class(Tobject)

  private const
    API_URL = 'https://devkkm.webkassa.kz/api/';

  var
    HTTP: TIdHTTP;
    SSLIO: TIdSSLIOHandlerSocketOpenSSL;

  public
    constructor Create();
    destructor Destroy();

Добавим в наш основной тип функцию авторизации в ККМ системе, тут в принципе все довольно просто, используя REST API производится запрос по указанному адресу, в обратном ответе возвращается токен, по которому мы будем делать дальнейшие действия

function TOOFD.Autorize(login: String; passwd: String): String;
var
  json_stream: TStringStream;
  json_obj: TJSONObject;
  json_pair: TJSONPair;
  response: String;
  Token: String;
  json_response: TJSONObject;
begin
  try
    begin


      Token := '';
      json_obj := TJSONObject.Create;
      json_pair := TJSONPair.Create('Login', login);
      json_obj.AddPair(json_pair);
      json_pair := TJSONPair.Create('Password', passwd);
      json_obj.AddPair(json_pair);

      json_stream := TStringStream.Create(json_obj.ToJSON);

      response := HTTP.Post(API_URL + 'Authorize', json_stream);
      json_response := TJSONObject.ParseJSONValue(response) as TJSONObject;
      if (json_response.GetValue('Data') <> nil) then
      begin
        Token := (json_response.GetValue('Data') as TJSONObject)
          .GetValue('Token').Value;

      end
      else
      begin
        // error code
       ShowMessage(response);
       Log(response);
      end;

    end;
  finally
    Result := Token;
    json_obj.Free;
    json_stream.Free;

  end;

end;

Добавим функцию которая будет формировать чек и отправлять его в ООФД, тут нужно обратить внимание что чек может быть как "ЧЕК ПОКУПКИ" так и "ЧЕК ВОЗВРАТА" , основные данные которые мы должны отправить это

1.Наш токен - который мы получили при авторизации

2. Наш номер кассы который мы получили когда зарегистрировались в ООФД

3. Вид операции (покупка или возврат)

4. Позиции в чеке - товары или услуги которые мы продаем или по которым делаем возврат

5. Оплаты или Возвраты сумма и количество

Это основные данные которые мы должны передать на сервер ККМ ООФД,

в ответ мы получаем тип который мы описали ранее type TAnswerCheck

function TOOFD.Check(SendCheck: TSendCheck): TAnswerCheck;
var
  json_stream, jsst: TStringStream;
  json_obj: TJSONObject;
  json_pair: TJSONPair;
  response: String;
  json_response: TJSONObject;
  json_data: TJSONObject;
  answer: TAnswerCheck;
  cashbox: Tcashbox;
  cashbox_json: TJSONObject;
  js_str: String;
begin
  try

    json_obj := TJSONObject.Create;

    json_obj.AddPair('Token', SendCheck.Token);
    json_obj.AddPair('CashBoxUniqueNumber', SendCheck.CashboxUniqueNumber);
    json_obj.AddPair('OperationType',
      TJSONNumber.Create(SendCheck.OperationType));
    json_obj.AddPair('Positions', SendCheck.Position);
    json_obj.AddPair('Payments', SendCheck.Payment);

    json_stream := TStringStream.Create(json_obj.ToJSON);

    answer := TAnswerCheck.Create;
    response := HTTP.Post(API_URL + 'Check', json_stream);
    Log(response);

    json_response := (TJSONObject.ParseJSONValue(response) as TJSONObject);
    if (json_response.GetValue('Data') <> nil) then
    begin
      json_data := (json_response.GetValue('Data') as TJSONObject);

      answer.check_number := json_data.GetValue('CheckNumber').Value;
      answer.date_time := json_data.GetValue('DateTime').Value;
      answer.offline_mode := StrToBool(json_data.GetValue('OfflineMode').Value);

      cashbox_json := (json_data.GetValue('Cashbox') as TJSONObject);

      answer.cashbox := Tcashbox.Create;
      answer.cashbox.Unique_Number :=
        cashbox_json.GetValue('UniqueNumber').Value;
      answer.cashbox.Registration_Number :=
        cashbox_json.GetValue('RegistrationNumber').Value;
      answer.cashbox.Identity_Number :=
        cashbox_json.GetValue('IdentityNumber').Value;
      answer.cashbox.Address := cashbox_json.GetValue('Address').Value;

      answer.CheckOrderNumber :=
        StrToInt(json_data.GetValue('CheckOrderNumber').Value);
      answer.ShiftNumber := StrToInt(json_data.GetValue('ShiftNumber').Value);
      answer.EmployeeName := json_data.GetValue('EmployeeName').Value;
      answer.TicketUrl := json_data.GetValue('TicketUrl').Value;

    end
    else
    begin
      // error code
    ShowMessage(response);
    end;

  finally
    Result := answer;
    json_stream.Free;
    json_response.Free;
  end;

end;

Добавляем функцию которая позволит нам получить информацию по ZX Отчетам

function TOOFD.ZReport(Token: String; CassaNumber: String): TZXReport;
var
  json_obj,
  json_data,
  json_response,
  json_ennon: TJSONObject;
  json_stream: TStringStream;
  response: String;
  res : TZXReport;
  sell,
  buy :TSellBuy;
  i : Integer;
  sell_js_arr : TJSONArray;
  type_pay : Integer;
begin

try
  DialogProgress;
  json_obj := TJSONObject.Create;

   res := TZXReport.Create;

  json_obj.AddPair('Token', Token);
  json_obj.AddPair('CashBoxUniqueNumber', CassaNumber);

  json_stream := TStringStream.Create(json_obj.ToJSON);
  response := HTTP.Post(API_URL + 'ZReport', json_stream);
   Log(response);

 json_response := (TJSONObject.ParseJSONValue(response) as TJSONObject);
  if (json_response.GetValue('Data') <> nil) then
    begin
      json_data := (json_response.GetValue('Data') as TJSONObject);
      res.ReportNumber := StrToInt(json_data.GetValue('ReportNumber').Value);
      res.TaxPayerName := json_data.GetValue('TaxPayerName').Value;
      res.TaxPayerIN := json_data.GetValue('TaxPayerIN').Value;
      res.TaxPayerVAT := StrToBool(json_data.GetValue('TaxPayerVAT').Value);
      res.TaxPayerVATSeria := json_data.GetValue('TaxPayerVATSeria').Value;
      res.TaxPayerVATNumber := json_data.GetValue('TaxPayerVATNumber').Value;
      res.CashBoxSN := json_data.GetValue('CashboxSN').Value;
      res.CashBoxIN := json_data.GetValue('CashboxIN').Value;
      res.CashBoxRN := json_data.GetValue('CashboxRN').Value;
      res.StartOn := json_data.GetValue('StartOn').Value;
      res.ReportOn := json_data.GetValue('ReportOn').Value;
      res.CloseOn := json_data.GetValue('CloseOn').Value;
      res.CashierCode := StrToInt(json_data.GetValue('CashierCode').Value);
      res.ShiftNumber := StrToInt(json_data.GetValue('ShiftNumber').Value);
      res.DocumentCount := StrToInt(json_data.GetValue('DocumentCount').Value);
      res.PutMoneySum := StrToFloat(json_data.GetValue('PutMoneySum').Value);
      res.TakeMoneySum := StrToFloat(json_data.GetValue('TakeMoneySum').Value);
      res.ControlSum := (json_data.GetValue('ControlSum').Value);
      res.OfflineMode := StrToBool(json_data.GetValue('OfflineMode').Value);
      res.CashBoxOfflineMode := StrToBool(json_data.GetValue('CashboxOfflineMode').Value);
      res.SumInCashbox := StrToFloat(json_data.GetValue('SumInCashbox').Value);

     sell_js_arr :=(TJSONObject(json_data.GetValue('Sell')).GetValue('PaymentsByTypesApiModel') as TJSONArray);
     res.Sell := TList.Create;
     for i := 0 to sell_js_arr.Count-1 do
        begin
        sell := TSellBuy.Create;

        sell.Sum := StrToFloat(TJSONObject(sell_js_arr.Items[i]).GetValue('Sum').Value);
       type_pay := StrToInt(TJSONObject(sell_js_arr.Items[i]).GetValue('Type').Value);

       case type_pay of
       0 : sell.PaymentTypeName := 'Наличные';
       1 : sell.PaymentTypeName := 'Банковская карта';
       2 : sell.PaymentTypeName := 'Оплата в кредит';
       3 : sell.PaymentTypeName := 'Оплата тарой';
       end;

          res.Sell.Add(sell);
        end;

     res.EndNonNullable.Sell := StrToFloat(TJSONObject(json_data.GetValue('EndNonNullable')).GetValue('Sell').Value);
     res.EndNonNullable.Buy := StrToFloat(TJSONObject(json_data.GetValue('EndNonNullable')).GetValue('Buy').Value);
     res.EndNonNullable.ReturnSell := StrToFloat(TJSONObject(json_data.GetValue('EndNonNullable')).GetValue('ReturnSell').Value);
     res.EndNonNullable.ReturnBuy := StrToFloat(TJSONObject(json_data.GetValue('EndNonNullable')).GetValue('ReturnBuy').Value);

     res.StartNonNullable.Sell := StrToFloat(TJSONObject(json_data.GetValue('StartNonNullable')).GetValue('Sell').Value);
     res.StartNonNullable.Buy := StrToFloat(TJSONObject(json_data.GetValue('StartNonNullable')).GetValue('Buy').Value);
     res.StartNonNullable.ReturnSell := StrToFloat(TJSONObject(json_data.GetValue('StartNonNullable')).GetValue('ReturnSell').Value);
     res.StartNonNullable.ReturnBuy := StrToFloat(TJSONObject(json_data.GetValue('StartNonNullable')).GetValue('ReturnBuy').Value);

  //  res.ReturnSell.Add();

   end
   else
   begin
     ShowMessage(response);
   end;

finally
  Result := res;
  CloseDialog;
end;

end;

Пример использования OOFD

if(not Assigned(OOFD))then
  OOFD := TOOFD.Create;

sum := StrToFloat(edt_sum.Text);
 moneyOperation := OOFD.MoneyOperation(MainForm.WEBCASSA_HASH_KEY,UniqueNumberSelect,0,sum,'');
 LoadReport(326);

 frxReport1.Variables['SNCASSA']:=QuotedStr(moneyOperation.CashBox.Unique_Number);
  frxReport1.Variables['REGNUMCASSA']:=QuotedStr(moneyOperation.CashBox.Registration_Number);
   frxReport1.Variables['SUMOPER']:=QuotedStr(FloatToStr(sum));
    frxReport1.Variables['SUMMA']:=QuotedStr(FloatToStr(moneyOperation.Sum));
     frxReport1.Variables['ZAVNUMCASSA']:=QuotedStr(moneyOperation.CashBox.Identity_Number);

 ShowReport;

Теги:
Хабы:
Всего голосов 5: ↑4 и ↓1+3
Комментарии18

Публикации