Compare commits

..

4 Commits
v1.0.0 ... main

Author SHA1 Message Date
c0290e776c
Remove unnecessary import block formatting
Consolidate the import statement to a single line for readability. This change reduces code clutter and adheres to cleaner code standards.
2024-09-09 18:14:37 +03:00
05b8245f11
Refactor category variables and client authentication.
Renamed category variables to use underscores for better clarity and consistency. Updated client authentication method to accept username and password directly instead of using a Credentials struct.
2024-09-08 19:04:06 +03:00
8eac71e65c
Add README and LICENSE files
Introduce initial README.md with project setup, usage instructions, and method documentation for the IEK business platform API client. Additionally, include the MIT license information in LICENSE.md.
2024-09-08 14:25:11 +03:00
cea1f96bb4
Refactor credential handling and improve parsing logic
Deleted client/credential.go and moved the Credentials struct to the api package for better modularity. Enhanced type safety in api by checking type assertions and added detailed comments in model structs.
2024-09-08 13:50:05 +03:00
10 changed files with 350 additions and 201 deletions

21
LICENSE.md Normal file
View File

@ -0,0 +1,21 @@
Лицензия MIT (MIT)
Авторские права (c) 2024 Павел Синицин
Настоящим предоставляется бесплатное разрешение любому лицу, получившему копию
этого программного обеспечения и сопутствующей документации (в дальнейшем "Программное обеспечение"), использовать
Программное обеспечение без ограничений, включая неограниченное право на использование, копирование, изменение, слияние,
публикацию, распространение, сублицензирование и/или продажу копий
Программного обеспечения, а также лицам, которым предоставляется данное Программное обеспечение, при соблюдении
следующих условий:
Указанное выше уведомление об авторских правах и данное разрешение должны быть включены во все
копии или значительные части этого Программного обеспечения.
Программное обеспечение предоставляется "КАК ЕСТЬ", без каких-либо гарантий, явных или
подразумеваемых, включая, но не ограничиваясь, гарантии товарной пригодности, пригодности
для конкретной цели и ненарушения прав. Ни в коем случае авторы или
владельцы авторских прав не несут ответственности за любые претензии, убытки или другие обязательства, будь то в иске по
договору, деликту или ином,
возникающем из, связанного с Программным обеспечением или использования Программного обеспечения или других действий с
Программным обеспечением.

133
README.md Normal file
View File

@ -0,0 +1,133 @@
# API клиент бизнес-платформы IEK
## Содержание
- [Начало работы](#начало-работы)
- [Установка](#установка)
- [Использование](#использование)
- [Доступные методы](#доступные-методы)
- [Используемые инструменты](#используемые-инструменты)
- [Авторы](#авторы)
- [Лицензия](#лицензия)
## Начало работы
Эти инструкции помогут вам запустить копию проекта на вашем локальном компьютере для целей разработки и тестирования.
#### Установка Go
Убедитесь, что у вас установлена последняя версия Go. Инструкции по установке можно найти на официальном
сайте [Go](https://golang.org/doc/install).
Пример:
```sh
go version go1.23.1
```
### Установка
Пошаговая инструкция по созданию окружения.
1. Установите проект с помощью `go get`
```sh
go get -u gitea.24example.ru/spavelit/bpiek
```
2. Установите зависимости
```sh
go mod tidy
```
### Использование
Инструкции по использованию вашего проекта.
#### Запуск приложения
Пример:
```sh
go run main.go
```
#### Пример использования
Примечание:
Добавьте пример кода, чтобы пользователи могли быстро начать работу с вашим проектом.
```go
package main
import (
"encoding/json"
"fmt"
bpiek "gitea.24example.ru/spavelit/bpiek/api"
)
func main() {
credentials := bpiek.Credentials{
Username: "mail@example.ru",
Password: "password",
}
api := bpiek.NewApi(credentials)
result, err := api.GetRemainsAndPlanresidues()
if err != nil {
panic(err)
}
b, _ := json.MarshalIndent(result[1], "", " ")
fmt.Print(string(b))
}
```
### Доступные методы
В данном разделе приведены основные методы, доступные в API клиенте для бизнес-платформы IEK:
1. `NewApi(credentials bpiek.Credentials)`
- Создает новый экземпляр API клиента с предоставленными учетными данными.
2. `GetParentCategories() ([]model.Category, error)`
- Возвращает массив категорий каталога 1-ого уровня.
3. `GetCategories() ([]model.Category, error)`
- Возвращает массив с категориями.
4. `GetTreeCategories() ([]model.TreeCategories, error)`
- Возвращает дерево категорий.
5. `GetProducts() ([]model.Product, error)`
- Возвращает массив с продукцией.
6. `GetProductByArticle(article string) (model.Product, error)`
- Возвращает товар по артикулу.
7. `GetRemainsAndPlanresidues() ([]model.ShortProduct, error)`
- Возвращает массив, в котором содержатся актуальные цены
и остатки товаров.
Эти методы могут использоваться для взаимодействия с бизнес-платформой IEK в рамках вашего проекта. Подробная
документация каждого метода доступна в исходниках или официальной документации БП IEK.
## Используемые инструменты
Список инструментов и библиотек, которые использовались при создании проекта.
* [GoLang](https://golang.org/) - Язык программирования.
* [Resty](https://github.com/go-resty/resty) - Simple HTTP and REST client library for Go.
## Авторы
* **Павел Синицин** - *Rosar-L* - [Gitea](https://gitea.24example.ru/spavelit/)
## Лицензия
Этот проект лицензирован под лицензией MIT - подробности смотрите в файле [LICENSE.md](LICENSE.md).

View File

@ -5,22 +5,27 @@ import (
"gitea.24example.ru/spavelit/bpiek/model"
)
type Api struct {
type (
Api struct {
Client *client.Client
}
}
Credentials struct {
Username string
Password string
}
type Method interface {
GetParentCategories() ([]model.Category, error)
GetCategories() ([]model.Category, error)
GetTreeCategories() ([]model.TreeCategories, error)
Method interface {
GetParentCategories() ([]model.Category, error) // Возвращает массив категорий каталога 1-ого уровня.
GetCategories() ([]model.Category, error) // Возвращает массив с категориями
GetTreeCategories() ([]model.TreeCategories, error) // Возвращает дерево категорий
GetProducts() ([]model.Product, error) // Возвращает массив с продукцией
GetProductByArticle(article string) (model.Product, error) // Возвращает товар по артикул
GetRemainsAndPlanresidues() ([]model.ShortProduct, error) // Возвращает массив, в котором содержатся актуальные цены и остатки товаров.
}
)
GetProducts() ([]model.Product, error)
GetProductByArticle(article string) (model.Product, error)
GetRemainsAndPlanresidues() ([]model.ShortProduct, error)
}
func NewApi(credentials client.Credentials) Method {
func NewApi(credentials Credentials) Method {
return &Api{
Client: client.NewClient(credentials),
Client: client.NewClient(credentials.Username, credentials.Password),
}
}

View File

@ -6,13 +6,13 @@ import (
"gitea.24example.ru/spavelit/bpiek/utils"
)
var categories []model.Category
var parentCategories []model.Category
var treeCategories []model.TreeCategories
var _categories []model.Category
var _parentCategories []model.Category
var _treeCategories []model.TreeCategories
func (a *Api) GetCategories() ([]model.Category, error) {
if len(categories) > 0 {
return categories, nil
if len(_categories) > 0 {
return _categories, nil
}
parentCategories, err := a.GetParentCategories()
@ -22,23 +22,26 @@ func (a *Api) GetCategories() ([]model.Category, error) {
}
for _, category := range parentCategories {
_categories = append(_categories, category)
categoriesAndProduct, err := a.GetCategoriesAndProductsBySlugParentCategory(category.Slug)
if err != nil {
return nil, err
}
if len(categoriesAndProduct.Categories) != 0 {
categories = append(categories, categoriesAndProduct.Categories...)
_categories = append(_categories, categoriesAndProduct.Categories...)
}
}
return categories, nil
return _categories, nil
}
func (a *Api) GetParentCategories() ([]model.Category, error) {
if len(parentCategories) > 0 {
return parentCategories, nil
if len(_parentCategories) > 0 {
return _parentCategories, nil
}
apiResponse, err := a.Client.HTTPClient.R().SetResult(&model.CategoryResponse{}).Get("client/catalog")
@ -56,9 +59,9 @@ func (a *Api) GetParentCategories() ([]model.Category, error) {
return nil, errors.New("no categories found")
}
parentCategories = result
_parentCategories = result
return parentCategories, nil
return _parentCategories, nil
}
func (a *Api) GetCategoriesAndProductsBySlugParentCategory(slug string) (*model.CategoriesAndProductsBySlugParentCategoryResponse, error) {
@ -78,34 +81,20 @@ func (a *Api) GetCategoriesAndProductsBySlugParentCategory(slug string) (*model.
}
func (a *Api) GetTreeCategories() ([]model.TreeCategories, error) {
if len(treeCategories) > 0 {
return treeCategories, nil
if len(_treeCategories) > 0 {
return _treeCategories, nil
}
tree := map[string]interface{}{}
parentCategories, err := a.GetParentCategories()
categories, err := a.GetCategories()
if err != nil {
return nil, err
}
for _, parent := range parentCategories {
tree[parent.Slug] = map[string]interface{}{
"name": parent.Name,
"slug": parent.Slug,
"url": parent.Url,
"children": map[string]interface{}{},
}
utils.ConvertListToNestedDict(categories, tree)
categoriesAndProduct, err := a.GetCategoriesAndProductsBySlugParentCategory(parent.Slug)
if err != nil {
return nil, err
}
_treeCategories = utils.ConvertToNestedList(tree)
utils.ConvertListToNestedDict(categoriesAndProduct.Categories, tree)
}
treeCategories = utils.ConvertToNestedList(tree)
return treeCategories, nil
return _treeCategories, nil
}

View File

@ -49,7 +49,12 @@ func (a *Api) GetProductByArticle(article string) (model.Product, error) {
"error getting product by article: " + article)
}
return apiResponse.Result().(model.Product), nil
product, ok := apiResponse.Result().(*model.Product)
if !ok {
return model.Product{}, errors.New("failed to parse product from response")
}
return *product, nil
}
func (a *Api) GetRemainsAndPlanresidues() ([]model.ShortProduct, error) {
@ -77,7 +82,7 @@ func (a *Api) GetRemainsAndPlanresidues() ([]model.ShortProduct, error) {
return nil, errors.New("file remains and planresidues not found")
}
result := apiResponse.Result().(model.RemainsAndPlanresiduesResponse)
result := apiResponse.Result().(*model.RemainsAndPlanresiduesResponse)
if len(result.Products) != 0 {
remainsAndPlanresidues = append(remainsAndPlanresidues, result.Products...)

View File

@ -2,14 +2,9 @@ package client
import "github.com/go-resty/resty/v2"
// import (
// "net/http"
// "net/url"
// )
const (
AUTH_API_URL = "https://bp.iek.ru/oauth/login"
BASE_API_URL = "https://bp.iek.ru/api/catalog/v1/"
AuthApiUrl = "https://bp.iek.ru/oauth/login"
BaseApiUrl = "https://bp.iek.ru/api/catalog/v1/"
)
type (
@ -27,18 +22,18 @@ type (
}
)
func NewClient(credentials Credentials) *Client {
func NewClient(username string, password string) *Client {
authSuccess := &AuthSuccess{}
client := resty.New()
client.SetBaseURL(BASE_API_URL)
client.SetBaseURL(BaseApiUrl)
response, err := client.R().
SetFormData(map[string]string{
"username": credentials.GetUsername(),
"password": credentials.GetPassword(),
"username": username,
"password": password,
}).
SetResult(&authSuccess).
Post(AUTH_API_URL)
Post(AuthApiUrl)
if err != nil {
panic(err)
@ -49,7 +44,7 @@ func NewClient(credentials Credentials) *Client {
}
client.SetHeader("Content-Type", "application/json")
client.SetHeader("Authorization", "Bearer "+authSuccess.AccessToken)
client.SetHeader("Authorization", authSuccess.TokenType+" "+authSuccess.AccessToken)
return &Client{
HTTPClient: client,

View File

@ -1,17 +0,0 @@
package client
type (
// Credentials provides constant credential values.
Credentials struct {
Username string `json:"username"`
Password string `json:"password"`
}
)
func (c *Credentials) GetUsername() string {
return c.Username
}
func (c *Credentials) GetPassword() string {
return c.Password
}

View File

@ -1,15 +1,15 @@
package model
type Category struct {
Slug string `json:"slug"`
Name string `json:"name"`
Url string `json:"url"`
ApiUrl string `json:"apiUrl"`
Slug string `json:"slug"` // Слаг категории
Name string `json:"name"` // Название категории
Url string `json:"url"` // Ссылка на скачивание файла с содержимым категории
ApiUrl string `json:"apiUrl"` // Относительный адрес категории
}
type TreeCategories struct {
Slug string `json:"slug"`
Name string `json:"name"`
Url string `json:"url"`
Children []TreeCategories `json:"children"`
Slug string `json:"slug"` // Слаг категории
Name string `json:"name"` // Название категории
Url string `json:"url"` // Относительный адрес категории
Children []TreeCategories `json:"children"` // Children nested categories in TreeCategories
}

View File

@ -2,150 +2,168 @@ package model
type (
ImageVariant struct {
Url string `json:"url"`
Ext string `json:"ext"`
Width int `json:"width"`
Url string `json:"url"` // Ссылка
Ext string `json:"ext"` // Расширение
Width int `json:"width"` // Ширина
}
Complects struct {
Article string `json:"article"`
Name string `json:"name"`
Quantity int `json:"quantity"`
Article string `json:"article"` // Артикул
Name string `json:"name"` // Наименование
Quantity int `json:"quantity"` // Количество
}
LeftPeriod struct {
Name string `json:"name"`
Value string `json:"value"`
Name string `json:"name"` // Название характеристики
Value string `json:"value"` // Значение характеристики
}
LeftPeriodRaw struct {
Lifespan interface{} `json:"lifespan"`
Warranty interface{} `json:"warranty"`
Lifespan struct {
Limit string `json:"limit"` // Предельное значение
Value string `json:"value"` // Значение
Units string `json:"units"` // Единицы измерения
} `json:"lifespan"` // Срок службы
Warranty struct {
Value string `json:"value"` // Значение
Units string `json:"units"` // Единицы измерения
} `json:"warranty"` // Гарантийный срок
}
DesignFeatures struct {
ImageUrl string `json:"imageUrl"`
Description string `json:"description"`
ImageUrl string `json:"imageUrl"` // Ссылка на изображение
Description string `json:"description"` // Описание
}
Video struct {
Name string `json:"name"`
Description string `json:"description"`
Url string `json:"url"`
Type string `json:"type"`
Name string `json:"name"` // Наименование
Description string `json:"description"` // Описание
Url string `json:"url"` // Ссылка
Type string `json:"type"` // Тип (ссылка на видео-хостинг или прямая ссылка на скачивание); Enum: "url" "file"
}
Software struct {
Name string `json:"name"`
Description string `json:"description"`
Url string `json:"url"`
Size int `json:"size"`
Name string `json:"name"` // Наименование
Description string `json:"description"` // Описание
Url string `json:"url"` // Ссылка
Size int `json:"size"` // Размер
}
Analog struct {
Article string `json:"article"`
Name string `json:"name"`
ShortName string `json:"shortName"`
Description string `json:"description"`
ImageUrl string `json:"imageUrl"`
ImageUrls []string `json:"imageUrls"`
ImageVariants []ImageVariant `json:"imageVariants"`
IsArchived bool `json:"isArchived"`
Tm string `json:"tm"`
Article string `json:"article"` // Артикул товара
Name string `json:"name"` // Полное название товара
ShortName string `json:"shortName"` // Краткое название
Description string `json:"description"` // Описание
ImageUrl string `json:"imageUrl"` // Фото товара (основное)
ImageUrls []string `json:"imageUrls"` // Все фото товара
ImageVariants []ImageVariant `json:"imageVariants"` // Вариации изображений
IsArchived bool `json:"isArchived"` // Архивный или нет
Tm string `json:"tm"` // Торговая марка
}
WarehouseData struct {
WarehouseId string `json:"warehouseId"`
WarehouseName string `json:"warehouseName"`
AvailableAmount int `json:"availableAmount"`
WarehouseId string `json:"warehouseId"` // Идентификатор склада
WarehouseName string `json:"warehouseName"` // Наименование склада
AvailableAmount int `json:"availableAmount"` // Доступное количество
Incoming []struct {
DateBegan string `json:"dateBegan"`
DateEnd string `json:"dateEnd"`
Amount int `json:"amount"`
Type string `json:"type"`
}
DateBegan string `json:"dateBegan"` // Дата начала периода поступления на склад
DateEnd string `json:"dateEnd"` // Дата окончания периода поступления на склад
Amount int `json:"amount"` // Ожидаемое количество
Type string `json:"type"` // Тип поступления, production - поступление после производства, shipping - доставка на склад
} // Ближайшие поступления
}
Etim struct {
Features []struct {
Id string `json:"id"`
Name string `json:"name"`
Sort int `json:"sort"`
Unit string `json:"unit"`
Value string `json:"value"`
} `json:"features"`
Id string `json:"id"` //
Name string `json:"name"` // Название свойства
Sort int `json:"sort"` // Порядок сортировки по умолчанию
Unit string `json:"unit"` // Единицы измерения
Value string `json:"value"` // Значение свойства
ValueUnion string `json:"value_union"` // Код значения
} `json:"features"` // Features represents a list of product features with detailed information.
Class struct {
Id string `json:"id"`
Name string `json:"name"`
} `json:"class"`
Id string `json:"id"` //
Name string `json:"name"` // Название класса
} `json:"class"` // ETIM-класс товара
}
LogisticParams struct {
Name string `json:"name"`
NameOrig string `json:"nameOrig"`
Name string `json:"name"` // Название параметра
NameOrig string `json:"nameOrig"` // Название характеристики (исходное)
Value struct {
Group string `json:"group"`
Individual string `json:"individual"`
Transport string `json:"transport"`
} `json:"value"`
Group string `json:"group"` // Значение для группового варианта
Individual string `json:"individual"` // Значение для индивидуального варианта
Transport string `json:"transport"` // Значение для транспортного варианта
} `json:"value"` // Value represents group, individual, and transport logistics values in JSON format.
}
LogisticParamsData struct {
SinglePackage struct {
Multiplicity int `json:"multiplicity"`
Unit string `json:"unit"`
} `json:"singlePackage"`
Multiplicity int `json:"multiplicity"` // Кратность
Unit string `json:"unit"` // Единицы измерения
} `json:"singlePackage"` // Для индивидуальной упаковки
}
ShortProduct struct {
Article string `json:"article"`
Name string `json:"name"`
Multiplicity int `json:"multiplicity"`
PriceBase int `json:"priceBase"`
PriceRrc int `json:"priceRrc"`
Available int `json:"available"`
Units string `json:"units"`
WarehouseData []WarehouseData `json:"warehouseData"`
Article string `json:"article"` // Артикул товара
Name string `json:"name"` // Полное наименование товара
Multiplicity int `json:"multiplicity"` // Кратность продажи
PriceBase float64 `json:"priceBase"` // Базовая цена с НДС
PriceRrc float64 `json:"priceRrc"` // Рекомендованная розничная цена (РРЦ) с НДС
Available float64 `json:"available"` // Значение остатка
Units string `json:"units"` // Единицы измерения
WarehouseData []WarehouseData `json:"warehouseData"` // Информация по складам
}
Product struct {
ShortName string `json:"shortName"`
Description string `json:"description"`
CategoryName string `json:"categoryName"`
Category string `json:"category"`
Slug string `json:"slug"`
Tm string `json:"tm"`
Url string `json:"url"`
IsArchived bool `json:"isArchived"`
ImageUrl string `json:"imageUrl"`
ImageUrls []string `json:"imageUrls"`
ImageVariants []ImageVariant `json:"imageVariants"`
Advantages string `json:"advantages"`
Etim Etim `json:"etim"`
Complects []Complects `json:"complects"`
Complectations string `json:"complectations"`
Files []interface{} `json:"files"`
LeftPeriod []LeftPeriod `json:"leftPeriod"`
LeftPeriodRaw LeftPeriodRaw `json:"leftPeriodRaw"`
LogisticParams []LogisticParams `json:"logisticParams"`
LogisticParamsData LogisticParamsData `json:"logisticParamsData"`
Novelty bool `json:"novelty"`
DesignFeatures []DesignFeatures `json:"designFeatures"`
Videos []Video `json:"videos"`
Software []Software `json:"software"`
Banner string `json:"banner"`
LastModified string `json:"lastModified"`
CountryOfProduction string `json:"countryOfProduction"`
FirstSaleDate string `json:"firstSaleDate"`
Feacn string `json:"feacn"`
Family string `json:"family"`
Series string `json:"series"`
IndPacking []string `json:"indPacking"`
Analogs []Analog `json:"analogs"`
Related []Analog `json:"related"`
QrCode string `json:"qrCode"`
IsOutOfAssortment bool `json:"isOutOfAssortment"`
IsOutOfProduction bool `json:"isOutOfProduction"`
Article string `json:"article"` // Артикул товара
Name string `json:"name"` // Полное наименование товара
ShortName string `json:"shortName"` // Краткое название
Description string `json:"description"` // Описание
CategoryName string `json:"categoryName"` // Название категории
Category string `json:"category"` // Относительный путь до категории в каталоге
Slug string `json:"slug"` // Слаг товара
Tm string `json:"tm"` // Торговая марка
Url string `json:"url"` // Ссылка на товар
IsArchived bool `json:"isArchived"` // Архивный или нет
ImageUrl string `json:"imageUrl"` // Фото товара (основное)
ImageUrls []string `json:"imageUrls"` // Все фото товара
ImageVariants []ImageVariant `json:"imageVariants"` // Вариации изображений
ImageUrlsVariants []interface{} `json:"imageUrlsVariants"` // Все вариации изображений
Advantages string `json:"advantages"` // Преимущества
Etim Etim `json:"etim"` // ETIM характеристики товара
Complects []Complects `json:"complects"` // Комплектация и сопутствующие товары
Complectations string `json:"complectations"` // Комплектация
Files []interface{} `json:"files"` // Список файлов, относящихся к товару (ГЧ, КД, CAD-модели и т.д.)
LeftPeriod []LeftPeriod `json:"leftPeriod"` // Характеристики срока службы
LeftPeriodRaw LeftPeriodRaw `json:"leftPeriodRaw"` // Гарантийные показатели
LogisticParams []LogisticParams `json:"logisticParams"` // Логистические характеристики
LogisticParamsData LogisticParamsData `json:"logisticParamsData"` // Подробные логистические характеристики
Novelty bool `json:"novelty"` // Новинка или нет
DesignFeatures []DesignFeatures `json:"designFeatures"` // Отличительные особенности
Videos []Video `json:"videos"` // Видео по товару
Software []Software `json:"software"` // ПО по товару
Banner string `json:"banner"` // Текст баннера
LastModified string `json:"lastModified"` // Дата последнего изменения
CountryOfProduction string `json:"countryOfProduction"` // Страна производства
FirstSaleDate string `json:"firstSaleDate"` // Дата начала продаж
Feacn string `json:"feacn"` // Код ТН ВЭД
Multiplicity int `json:"multiplicity"` // Кратность продажи
PriceBase float64 `json:"priceBase"` // Базовая цена с НДС
PriceRrc float64 `json:"priceRrc"` // Персональная цена с НДС
PricePersonal float64 `json:"pricePersonal"` // Рекомендованная розничная цена (РРЦ) с НДС
Available int `json:"available"` // Значение остатка
Units string `json:"units"` // Единицы измерения
Family string `json:"family"` // Family specifies the family category of the product.
Series string `json:"series"` // Series is the series of the product.
IndPacking []string `json:"indPacking"` // Ссылки на фото упаковки
Analogs []Analog `json:"analogs"` // Аналоги
Related []Analog `json:"related"` // Совместно применяемые изделия
QrCode string `json:"qrCode"` // QR код со ссылкой на товар в Бизнес платформе
IsOutOfAssortment bool `json:"isOutOfAssortment"` // Выведенный из ассортимента
IsOutOfProduction bool `json:"isOutOfProduction"` // Выводимый из ассортимента
WarehouseData []WarehouseData `json:"warehouseData"` // Информация по складам
}
)

View File

@ -1,32 +1,32 @@
package model
type CategoryResponse struct {
Categories []Category `json:"categories"`
Categories []Category `json:"categories"` // Массив категорий 1-го уровня
}
type CategoriesAndProductsBySlugParentCategoryResponse struct {
Date string `json:"date"`
Slug string `json:"slug"`
Name string `json:"name"`
Url string `json:"url"`
Categories []Category `json:"categories"`
Products []Product `json:"products"`
Date string `json:"date"` // Дата формирования файла
Slug string `json:"slug"` // Слаг категории 1-го уровня
Name string `json:"name"` // Название категории 1-го уровня
Url string `json:"url"` // Относительный адрес категории 1-го уровня
Categories []Category `json:"categories"` // Массив всех входящих категорий
Products []Product `json:"products"` // Массив всех входящих товаров
}
type NewProductsResponse struct {
Data struct {
Products []Product `json:"products"`
} `json:"data"`
Products []Product `json:"products"` // Список новинок
} `json:"data"` // Список новинок
Meta struct {
Page int `json:"page"`
TotalPages int `json:"totalPages"`
TotalCount int `json:"totalCount"`
PageSize int `json:"pageSize"`
} `json:"_meta"`
Page int `json:"page"` // Текущая страница
TotalPages int `json:"totalPages"` // Всего страниц
TotalCount int `json:"totalCount"` // Всего элементов
PageSize int `json:"pageSize"` // Размер страницы
} `json:"_meta"` // Параметры пагинации
}
type RemainsAndPlanresiduesResponse struct {
Date string `json:"date"`
Products []ShortProduct `json:"products"`
Date string `json:"date"` // Дата создания файла
Products []ShortProduct `json:"products"` // Массив остатков по товарам
}