Реализация функций на VB.net



Imports System.IO
Imports System.Net
Imports System.Text
Imports System.Collections.Generic
Imports Newtonsoft.Json

Public Class PSCWebApi
    Private ReadOnly _baseUrl As String = "https://pscw.autoxp.ru/api.aspx"
    Private _sessionCode As String
    Private ReadOnly _keyNumber As String
    Private ReadOnly _codeSync As String

    Public Sub New(keyNumber As String, codeSync As String)
        _keyNumber = keyNumber
        _codeSync = codeSync
    End Sub

    Public Function GetSession() As String
        ' Получение кода сессии
        Dim parameters = New Dictionary(Of String, String) From {
            {"keynumber", _keyNumber},
            {"codesync", _codeSync}
        }
        Dim queryString = BuildQueryString(parameters)
        Dim result = SendGetRequest($"{_baseUrl}{queryString}")
        If result.StartsWith("!") Then
            Throw New Exception($"Ошибка авторизации: {result}")
        End If
        Dim jsonResponse = JsonConvert.DeserializeObject(Of Dictionary(Of String, String))(result)
        _sessionCode = jsonResponse("ses")
        Return result
    End Function

    Public Sub SetSession(sessionCode As String)
        ' Установка сессии вручную (если уже есть)
        _sessionCode = sessionCode
    End Sub

    Public Function GetCurrentSession() As String
        ' Получение текущей сессии
        Return _sessionCode
    End Function

    Public Function GetListOfLastDocuments(Optional fields As String = Nothing, Optional countOfDocs As Integer = 200) As List(Of List(Of String))
        ' Получение списка документов как объект
        CheckSession()
        Dim parameters = New Dictionary(Of String, String) From {
            {"ses", _sessionCode},
            {"task", "listoflastdocs"}
        }
        If Not String.IsNullOrEmpty(fields) Then
            parameters.Add("fields", fields)
        End If
        parameters.Add("countofdocs", countOfDocs.ToString())
        Dim response = SendPostRequest(parameters)
        If response.StartsWith("!") Then
            Throw New Exception($"Ошибка получения списка документов: {response}")
        End If
        Return ParseTableToList(response)
    End Function

    Public Function CreateDocument(blankCode As String) As String
        ' Создание нового документа
        CheckSession()
        Dim parameters = New Dictionary(Of String, String) From {
            {"ses", _sessionCode},
            {"bnk", blankCode}
        }
        Dim queryString = BuildQueryString(parameters)
        Dim result = SendGetRequest($"{_baseUrl}{queryString}")
        If result.StartsWith("!") Then
            Throw New Exception($"Ошибка создания документа: {result}")
        End If
        Dim jsonResponse = JsonConvert.DeserializeObject(Of Dictionary(Of String, String))(result)
        Return jsonResponse("doc")
    End Function

    Public Function GetFieldValue(documentIndex As String, fieldIndex As String) As String
        ' Получение содержимого поля документа
        CheckSession()
        Dim parameters = New Dictionary(Of String, String) From {
            {"ses", _sessionCode},
            {"doc", documentIndex},
            {"frmfield", fieldIndex}
        }
        Dim queryString = BuildQueryString(parameters)
        Dim result = SendGetRequest($"{_baseUrl}{queryString}")
        If result.StartsWith("!") Then
            Throw New Exception($"Ошибка получения поля: {result}")
        End If
        Return If(result = "null", Nothing, result)
    End Function

    Public Function GetMultipleFields(documentIndex As String, fieldIndexes As List(Of String)) As Dictionary(Of String, String)
        ' Получение содержимого нескольких полей документа
        CheckSession()
        Dim parameters = New Dictionary(Of String, String) From {
            {"ses", _sessionCode},
            {"doc", documentIndex},
            {"frmfields", String.Join(",", fieldIndexes)}
        }
        Dim response = SendPostRequest(parameters)
        If response.StartsWith("!") Then
            Throw New Exception($"Ошибка получения полей: {response}")
        End If
        Return ParseFieldListToDictionary(response)
    End Function

    Public Function SetFieldValue(documentIndex As String, fieldIndex As String, value As String) As Boolean
        ' Изменение содержимого поля документа
        CheckSession()
        Dim parameters = New Dictionary(Of String, String) From {
            {"ses", _sessionCode},
            {"doc", documentIndex},
            {"frmfield", fieldIndex},
            {"val", If(String.IsNullOrEmpty(value), "null", value)}
        }
        Dim response = SendPostRequest(parameters)
        If response.StartsWith("!") Then
            Throw New Exception($"Ошибка изменения поля: {response}")
        End If
        Return response = "OK"
    End Function

    Public Function SetMultipleFields(documentIndex As String, fieldsValues As Dictionary(Of String, String)) As Boolean
        ' Изменение нескольких полей документа
        CheckSession()
        Dim fieldIndexes = New List(Of String)()
        Dim values = New List(Of String)()
        For Each kvp In fieldsValues
            fieldIndexes.Add(kvp.Key)
            values.Add(If(String.IsNullOrEmpty(kvp.Value), "null", kvp.Value))
        Next
        Dim parameters = New Dictionary(Of String, String) From {
            {"ses", _sessionCode},
            {"doc", documentIndex},
            {"frmfields", String.Join(",", fieldIndexes)},
            {"vals", String.Join("[s]", values)}
        }
        Dim response = SendPostRequest(parameters)
        If response.StartsWith("!") Then
            Throw New Exception($"Ошибка изменения полей: {response}")
        End If
        Return response = "OK"
    End Function

    Public Function GetTableRows(documentIndex As String, tableIndex As String) As List(Of List(Of String))
        ' Получение содержимого таблицы документа
        CheckSession()
        Dim parameters = New Dictionary(Of String, String) From {
            {"ses", _sessionCode},
            {"doc", documentIndex},
            {"task", "tblrows"},
            {"table", tableIndex}
        }
        Dim response = SendPostRequest(parameters)
        If response.StartsWith("!") Then
            Throw New Exception($"Ошибка получения таблицы: {response}")
        End If
        Return ParseTableToList(response)
    End Function

    Public Function AddTableRowsFrom(documentIndex As String, tableIndex As String, rowsJson As String) As Boolean
        ' Добавление записей в таблицу документа из JSON
        CheckSession()
        Dim parameters = New Dictionary(Of String, String) From {
            {"ses", _sessionCode},
            {"doc", documentIndex},
            {"task", "tbladdrows"},
            {"table", tableIndex},
            {"rows", rowsJson}
        }
        Dim response = SendPostRequest(parameters)
        If response.StartsWith("!") Then
            Throw New Exception($"Ошибка добавления строк: {response}")
        End If
        Return response = "OK"
    End Function

    Public Function DeleteTableRows(documentIndex As String, tableIndex As String, rowIndexes As List(Of String)) As Boolean
        ' Удаление записей из таблицы документа
        CheckSession()
        Dim parameters = New Dictionary(Of String, String) From {
            {"ses", _sessionCode},
            {"doc", documentIndex},
            {"task", "tbldelrows"},
            {"table", tableIndex},
            {"rows", String.Join(",", rowIndexes)}
        }
        Dim response = SendPostRequest(parameters)
        If response.StartsWith("!") Then
            Throw New Exception($"Ошибка удаления строк: {response}")
        End If
        Return response = "OK"
    End Function

    Public Function GetDocumentStatus(documentIndex As String) As String
        ' Получение статуса документа
        CheckSession()
        Dim parameters = New Dictionary(Of String, String) From {
            {"ses", _sessionCode},
            {"doc", documentIndex},
            {"task", "getdocstatus"}
        }
        Dim queryString = BuildQueryString(parameters)
        Dim result = SendGetRequest($"{_baseUrl}{queryString}")
        If result.StartsWith("!") Then
            Throw New Exception($"Ошибка получения статуса: {result}")
        End If
        Return If(result = "null", Nothing, result)
    End Function

    Public Function GetDocumentStatusWithTime(documentIndex As String) As Dictionary(Of String, String)
        ' Получение статуса документа со временем
        CheckSession()
        Dim parameters = New Dictionary(Of String, String) From {
            {"ses", _sessionCode},
            {"doc", documentIndex},
            {"task", "getdocstatuswtime"}
        }
        Dim queryString = BuildQueryString(parameters)
        Dim result = SendGetRequest($"{_baseUrl}{queryString}")
        If result.StartsWith("!") Then
            Throw New Exception($"Ошибка получения статуса: {result}")
        End If
        Dim statusInfo As New Dictionary(Of String, String)()
        ' Парсинг ответа (формат: status|time или status)
        Dim parts = result.Split("|"c)
        statusInfo("status") = If(parts(0) = "null", Nothing, parts(0))
        statusInfo("time") = If(parts.Length > 1 AndAlso parts(1) <> "null", parts(1), Nothing)
        Return statusInfo
    End Function

    Public Function SetDocumentStatus(documentIndex As String, status As String) As Boolean
        ' Изменение статуса документа
        CheckSession()
        Dim parameters = New Dictionary(Of String, String) From {
            {"ses", _sessionCode},
            {"doc", documentIndex},
            {"task", "setdocstatus"},
            {"val", If(String.IsNullOrEmpty(status), "null", status)}
        }
        Dim queryString = BuildQueryString(parameters)
        Dim result = SendGetRequest($"{_baseUrl}{queryString}")
        If result.StartsWith("!") Then
            Throw New Exception($"Ошибка изменения статуса: {result}")
        End If
        Return result = "OK"
    End Function

    Public Function GetDocumentSymbol(documentIndex As String) As String
        ' Получение символа признака документа
        CheckSession()
        Dim parameters = New Dictionary(Of String, String) From {
            {"ses", _sessionCode},
            {"doc", documentIndex},
            {"task", "getdocsymbol"}
        }
        Dim queryString = BuildQueryString(parameters)
        Dim result = SendGetRequest($"{_baseUrl}{queryString}")
        If result.StartsWith("!") Then
            Throw New Exception($"Ошибка получения символа: {result}")
        End If
        Return If(result = "null", Nothing, result)
    End Function

    Public Function SetDocumentSymbol(documentIndex As String, symbol As String) As Boolean
        ' Изменение символа признака документа
        CheckSession()
        Dim validSymbols = {"alert", "express", "phone", "print", "flag", "light"}
        If Not validSymbols.Contains(symbol) Then
            Throw New ArgumentException("Неверный символ. Допустимые значения: alert, express, phone, print, flag, light")
        End If
        Dim parameters = New Dictionary(Of String, String) From {
            {"ses", _sessionCode},
            {"doc", documentIndex},
            {"task", "setdocsymbol"},
            {"val", symbol}
        }
        Dim queryString = BuildQueryString(parameters)
        Dim result = SendGetRequest($"{_baseUrl}{queryString}")
        If result.StartsWith("!") Then
            Throw New Exception($"Ошибка изменения символа: {result}")
        End If
        Return result = "OK"
    End Function

    Public Function GetImagesList(documentIndex As String, gallery As String) As List(Of List(Of String))
        ' Получение списка изображений из документа
        CheckSession()
        Dim parameters = New Dictionary(Of String, String) From {
            {"ses", _sessionCode},
            {"doc", documentIndex},
            {"task", "listofimages"},
            {"gallery", gallery}
        }
        Dim queryString = BuildQueryString(parameters)
        Dim response = SendGetRequest($"{_baseUrl}{queryString}")
        If response.StartsWith("!") Then
            Throw New Exception($"Ошибка получения списка изображений: {response}")
        End If
        Return ParseTableToList(response)
    End Function

    Public Function GetImage(documentIndex As String, imageIndex As String) As Byte()
        ' Получение изображения из документа
        CheckSession()
        Dim parameters = New Dictionary(Of String, String) From {
            {"ses", _sessionCode},
            {"doc", documentIndex},
            {"image", imageIndex}
        }
        Dim queryString = BuildQueryString(parameters)
        Return SendGetRequestBytes($"{_baseUrl}{queryString}")
    End Function

    Public Sub SaveImageToFile(documentIndex As String, imageIndex As String, filePath As String)
        ' Сохранение изображения в файл
        Dim imageData = GetImage(documentIndex, imageIndex)
        File.WriteAllBytes(filePath, imageData)
    End Sub

    Public Function GetCatalogsByVin(vin As String) As String
        ' Поиск каталога по VIN
        CheckSession()
        Dim parameters = New Dictionary(Of String, String) From {
            {"ses", _sessionCode},
            {"task", "catalogsbyvin"},
            {"vin", vin}
        }
        Dim response = SendPostRequest(parameters)
        If response.StartsWith("!") Then
            Throw New Exception($"Ошибка поиска каталога: {response}")
        End If
        Return response
    End Function

    Public Function FixCatalogToDocument(documentIndex As String, markaIndex As String, axpCode As String, madeYear As String) As Boolean
        ' Привязка каталога к документу
        CheckSession()
        Dim parameters = New Dictionary(Of String, String) From {
            {"ses", _sessionCode},
            {"doc", documentIndex},
            {"task", "fixcatalog"},
            {"marka", markaIndex},
            {"axp", axpCode},
            {"made", madeYear}
        }
        Dim response = SendPostRequest(parameters)
        If response.StartsWith("!") Then
            Throw New Exception($"Ошибка привязки каталога: {response}")
        End If
        Return response = "OK"
    End Function

    Public Function CreateSelectionFromText(documentIndex As String, text As String) As Boolean
        ' Формирование выборки из текста
        CheckSession()
        Dim parameters = New Dictionary(Of String, String) From {
            {"ses", _sessionCode},
            {"doc", documentIndex},
            {"task", "lgselectident"},
            {"text", text}
        }
        Dim response = SendPostRequest(parameters)
        If response.StartsWith("!") Then
            Throw New Exception($"Ошибка формирования выборки: {response}")
        End If
        Return response = "OK"
    End Function

    Public Function CalculateFromSelection(documentIndex As String) As Boolean
        ' Расчёт калькуляции из выборки
        CheckSession()
        Dim parameters = New Dictionary(Of String, String) From {
            {"ses", _sessionCode},
            {"doc", documentIndex},
            {"task", "lgselectcalc"}
        }
        Dim queryString = BuildQueryString(parameters)
        Dim response = SendGetRequest($"{_baseUrl}{queryString}")
        If response.StartsWith("!") Then
            Throw New Exception($"Ошибка расчёта калькуляции: {response}")
        End If
        If Len(response) > 3 Then
            If Mid(response, 1, 2) = "OK" Then Return True
        End If
        Return False
    End Function

    Public Function UpdatePartPrices(documentIndex As String, source As String) As Boolean
        ' Актуализация цен на запчасти
        CheckSession()
        Dim validSources = {"rsa", "rrc", "arc"}
        If Not validSources.Contains(source) Then
            Throw New ArgumentException("Неверный источник. Допустимые значения: rsa, rrc, arc")
        End If
        Dim parameters = New Dictionary(Of String, String) From {
            {"ses", _sessionCode},
            {"doc", documentIndex},
            {"task", "regpartprices"},
            {"src", source}
        }
        Dim response = SendPostRequest(parameters)
        If response.StartsWith("!") Then
            Throw New Exception($"Ошибка актуализации цен: {response}")
        End If
        Return response = "OK"
    End Function

    ' Приватные вспомогательные методы
    Private Sub CheckSession()
        If String.IsNullOrEmpty(_sessionCode) Then
            Throw New InvalidOperationException("Сессия не инициализирована. Вызовите GetSession() или SetSession() сначала.")
        End If
    End Sub

    Private Function BuildQueryString(parameters As Dictionary(Of String, String)) As String
        If parameters Is Nothing OrElse parameters.Count = 0 Then
            Return String.Empty
        End If
        Dim sb As New StringBuilder()
        sb.Append("?")
        Dim first = True
        For Each kvp In parameters
            If Not first Then
                sb.Append("&")
            End If
            sb.Append($"{Uri.EscapeDataString(kvp.Key)}={Uri.EscapeDataString(kvp.Value)}")
            first = False
        Next
        Return sb.ToString()
    End Function

    Private Function SendGetRequest(url As String) As String
        Using client As New WebClient()
            client.Encoding = Encoding.UTF8
            Try
                Return client.DownloadString(url)
            Catch ex As WebException
                If ex.Response IsNot Nothing Then
                    Using reader As New StreamReader(ex.Response.GetResponseStream())
                        Dim errorResponse = reader.ReadToEnd()
                        Throw New Exception($"HTTP ошибка: {errorResponse}")
                    End Using
                End If
                Throw
            End Try
        End Using
    End Function

    Private Function SendGetRequestBytes(url As String) As Byte()
        Using client As New WebClient()
            Try
                Return client.DownloadData(url)
            Catch ex As WebException
                If ex.Response IsNot Nothing Then
                    Using reader As New StreamReader(ex.Response.GetResponseStream())
                        Dim errorResponse = reader.ReadToEnd()
                        Throw New Exception($"HTTP ошибка: {errorResponse}")
                    End Using
                End If
                Throw
            End Try
        End Using
    End Function

    Private Function SendPostRequest(parameters As Dictionary(Of String, String)) As String
        Dim postData As New StringBuilder()

        For Each kvp In parameters
            If postData.Length > 0 Then
                postData.Append("&")
            End If
            postData.Append($"{Uri.EscapeDataString(kvp.Key)}={Uri.EscapeDataString(kvp.Value)}")
        Next

        Dim dataBytes As Byte() = Encoding.UTF8.GetBytes(postData.ToString())

        Using client As New WebClient()
            client.Headers.Add("Content-Type", "application/x-www-form-urlencoded")
            Try
                Dim responseBytes As Byte() = client.UploadData(_baseUrl, "POST", dataBytes)
                Return Encoding.UTF8.GetString(responseBytes)
            Catch ex As WebException
                If ex.Response IsNot Nothing Then
                    Using reader As New StreamReader(ex.Response.GetResponseStream())
                        Dim errorResponse = reader.ReadToEnd()
                        Throw New Exception($"HTTP ошибка: {errorResponse}")
                    End Using
                End If
                Throw
            End Try
        End Using
    End Function

    Private Function ParseTableToList(response As String) As List(Of List(Of String))
        Dim result As New List(Of List(Of String))()
        If String.IsNullOrEmpty(response) OrElse response.StartsWith("!") Then
            Return result
        End If
        Dim documentsArray = JsonConvert.DeserializeObject(Of List(Of List(Of String)))(response)
        Return documentsArray
    End Function

    Private Function ParseFieldListToDictionary(response As String) As Dictionary(Of String, String)
        Dim result As New Dictionary(Of String, String)()
        If String.IsNullOrEmpty(response) OrElse response.StartsWith("!") Then
            Return result
        End If
        Dim lines = response.Trim().Split({Environment.NewLine, vbCrLf, vbCr, vbLf}, StringSplitOptions.RemoveEmptyEntries)
        For Each line In lines
            Dim parts = line.Split(vbTab)
            If parts.Length >= 2 Then
                Dim fieldIndex = parts(0)
                Dim value = If(parts(1) = "null", Nothing, parts(1))
                result.Add(fieldIndex, value)
            End If
        Next
        Return result
    End Function

End Class

							

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

	' Инициализация API
	Dim api As New PSCWebApi("ВАШ_НОМЕР_ЛИЦЕНЗИИ", "ВАШ_КОД_СИНХРОНИЗАЦИИ")
	' Получение сессии
	Dim sessionCode = api.GetSession()
	' Создание документа
	Dim docIndex = api.CreateDocument("AXP00100") ' КАСКО
	' Установка значения поля
	api.SetFieldValue(docIndex, "model", "Модель автомобиля")
	' Получение значения поля
	Dim model = api.GetFieldValue(docIndex, "model")
	' Получение списка последних документов
	Dim documents = api.GetListOfLastDocuments("model,vin,", 50)

							

Быстрый расчёт из текста акта-осмотра

	' Инициализация API
	Dim api As New PSCWebApi("ВАШ_НОМЕР_ЛИЦЕНЗИИ", "ВАШ_КОД_СИНХРОНИЗАЦИИ")
	' Получение сессии
	Dim sessionCode = api.GetSession()
	' Создание документа
	Dim docIndex = api.CreateDocument("AXP00100") ' КАСКО
	' Подбор каталога по VIN
	Dim catJson = api.GetCatalogsByVin("X7LHSRDJN49873939")
	Dim catArray = JsonConvert.DeserializeObject(Of List(Of Object))(catJson)
	If catArray IsNot Nothing AndAlso catArray.Count = 0 Then
		MsgBox("Каталог подобрать не удалось!")
		Exit Sub
	End If
	Dim str = JsonConvert.SerializeObject(catArray(0))
	Dim json = JsonConvert.DeserializeObject(Of Dictionary(Of String, String))(str)
	Dim catMarkaind = json("markaind")
	Dim catAXP = json("axp")
	Dim catYearmade = json("yearmade")
	' Привязка каталога к документу
	If api.FixCatalogToDocument(docIndex, catMarkaind, catAXP, catYearmade) = False Then
		MsgBox("Привязать каталог к документу не удалось!")
		Exit Sub
	End If
	' Формирование выборки из текста
	Dim strUserText As String = "Крыло переднее левое - замена; бампер передний - ремонт (1ч.); Фара передняя левая - замена;"
	If api.CreateSelectionFromText(docIndex, strUserText) Then
		Dim countRows = api.GetTableRows(docIndex, "tblLGSEL").Count
	Else
		MsgBox("Сформировать выборку по тексту не удалось!"
		Exit Sub
	End If
	' Расчёт калькуляции из выборки
	If api.CalculateFromSelection(docIndex) Then
		MsgBox("Расчёт калькуляции из выборки выполнен)")
	Else
		MsgBox("Ошибка при расчёте калькуляции из выборки!")
	End If