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