Создаем Свои класс для взаимодействия с ООФ КазакТелеком
Объявим вспомогательные типы
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;
