Skip to content

Commit

Permalink
Added most Entities and Documents (#36)
Browse files Browse the repository at this point in the history
  • Loading branch information
evgeek authored Oct 28, 2023
1 parent 1671c2e commit 0fc72d1
Show file tree
Hide file tree
Showing 475 changed files with 16,984 additions and 1,432 deletions.
13 changes: 13 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,19 @@

Все существенные изменения в проекте будут задокументированы в этом файле. Формат основан на [Keep a Changelog](https://keepachangelog.com/), и этот проект придерживается семантического версионирования ([semver](https://semver.org/)).

## v0.10.0 [[Upgrade guide](/UPGRADE.md#v0100-changelog)]

### Added

* Реализовано большинство сущностей Моего Склада - и в Конструкторе запросов, и в Record.
* debug-метод для `massCreateUpdate()`

### Changed

- Имена классов Record приведены к PascalCase.
- Имена классов Query сегментов приведены к единому виду.
- Словари `Document`, `Endpoint` и `Entity` заменены на `Segment` (сегменты в url) и `Type` (type в meta сущности).

## v0.9.1

### Changed
Expand Down
15 changes: 8 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# SDK для работы с API v1.2 сервиса "Мой Склад"
# SDK для работы с API v1.2 сервиса Мой Склад

Лёгкая и универсальная библиотека, позволяющий работать с [API 1.2](https://dev.moysklad.ru/doc/api/remap/1.2) и `PHP 8.1+`.
Универсальная библиотека, позволяющий работать с [MoySklad API 1.2](https://dev.moysklad.ru/doc/api/remap/1.2) и `PHP 8.1+`.

Находится в разработке, версии до `v1.0.0` могут не обладать обратной совместимостью. Список изменений можно найти в [Changelog](CHANGELOG.md). Инструкция по обновлению для версий, не поддерживающих обратную совместимость - [Upgrade guide](UPGRADE.md).

Expand Down Expand Up @@ -35,11 +35,12 @@ $product = Product::make($ms, ['id' => '25cf41f2-b068-11ed-0a80-0e9700500d7e'])-

## Полная документация

* [Настройка клиента](/docs/setup.md)
* [Взаимодействие с API](/docs/api_interaction.md)
* [Форматтеры](/docs/formatters.md)
* [Вспомогательные инструменты](/docs/tools.md)
* [Обработка исключений](/docs/exceptions.md)
* [Оглавление](/docs/index.md)
* [Настройка клиента](/docs/setup.md)
* [Взаимодействие с API](/docs/api_interaction.md)
* [Форматтеры](/docs/formatters.md)
* [Вспомогательные инструменты](/docs/tools.md)
* [Обработка исключений](/docs/exceptions.md)

## Особенности

Expand Down
46 changes: 46 additions & 0 deletions UPGRADE.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,51 @@
# Upgrade guide

## v0.10.0 [[Changelog](/CHANGELOG.md#v0100-upgrade-guide)]

### Имена классов Query и Record приведены к PascalCase.

Затронуло только `Customerorder`

До:

- `use Evgeek\Moysklad\Api\Query\Segments\Methods\Documents\CustomerorderSegment;`
- `use Evgeek\Moysklad\Api\Record\Objects\Documents\Customerorder;`
- `use Evgeek\Moysklad\Api\Record\Collections\Documents\CustomerorderCollection;`

После:

- `use Evgeek\Moysklad\Api\Query\Segments\Methods\Documents\CustomerOrderSegment;`
- `use Evgeek\Moysklad\Api\Record\Objects\Documents\CustomerOrder;`
- `use Evgeek\Moysklad\Api\Record\Collections\Documents\CustomerOrderCollection;`

### Имена классов Query сегментов приведены к единому виду.

До:

- `use Evgeek\Moysklad\Api\Query\Segments\ById\ByIdSegmentCommon;`
- `use Evgeek\Moysklad\Api\Query\Segments\ById\ByIdSegmentPositioned;`
- `use Evgeek\Moysklad\Api\Query\Segments\Methods\AbstractMethodSegmentNamed;`
- `use Evgeek\Moysklad\Api\Query\Segments\Methods\MethodSegmentCommon;`

После:

- `use Evgeek\Moysklad\Api\Query\Segments\ById\ByIdCommonSegment;`
- `use Evgeek\Moysklad\Api\Query\Segments\ById\ByIdWithPositionsSegment;`
- `use Evgeek\Moysklad\Api\Query\Segments\Methods\AbstractMethodNamedSegment;`
- `use Evgeek\Moysklad\Api\Query\Segments\Methods\MethodCommonSegment;`

### Словари (`Evgeek\Moysklad\Dictionaries\...`) `Document`, `Endpoint` и `Entity` заменены на `Segment` (сегменты в url) и `Type` (type в meta сущности).

До:

- `Endpoint::ENTITY;`
- `Document::CUSTOMERORDER;`

После:

- `Segment::ENTITY;`
- `Type::CUSTOMERORDER;`

## v0.8.0 [[Changelog](/CHANGELOG.md#v080-upgrade-guide)]

### Реорганизация namespace `Evgeek\Moysklad\Api`.
Expand Down
45 changes: 42 additions & 3 deletions docs/active_record.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,14 +14,15 @@
* [Параметры запроса коллекций](/docs/active_record.md#параметры-запроса-коллекций)
* [Методы отправки запросов коллекций](/docs/active_record.md#методы-отправки-запросов-коллекций)
* [Итерирование](/docs/active_record.md#итерирование)
* [Вложенные сущности](/docs/active_record.md#вложенные-сущности)
* [Универсальные методы](/docs/active_record.md#универсальные-методы)
* [Расширяемость](/docs/active_record.md#расширяемость)

## Общая информация

### Свойства

В классах объектов и коллекций при помощи PHPDoc реализованы подсказки имён и типов свойств для IDE. Впрочем, даже если свойство ещё не добавлено в PHPDoc, с ним всё равно можно работать.
В некоторых классах объектов и коллекций при помощи PHPDoc реализованы подсказки имён и типов свойств для IDE. Впрочем, даже если свойство ещё не добавлено в PHPDoc, с ним всё равно можно работать.

```php
use Evgeek\Moysklad\Api\Record\Objects\Entities\Product;
Expand Down Expand Up @@ -230,7 +231,7 @@ $productNext = $product->getNext();
```php
$product1 = $ms->query()->entity()->product()->byId('cc181c35-f259-11ed-0a80-00e900658c8f')->get();
$product2 = Product::make($ms, ['id' => 'd540c409-f259-11ed-0a80-00e900658e53']);
$product3 = ['meta' => Meta::product('d540c409-f259-11ed-0a80-00e900658e53')];
$product3 = ['meta' => Meta::product('25cf41f2-b068-11ed-0a80-0e9700500d7e')];

Product::collection($ms)->massDelete([$product1, $product2, $product3]);

Expand Down Expand Up @@ -279,7 +280,7 @@ Product::collection($ms)

Вышеописанные способы подходят для перебора сущностей, загруженных в коллекцию. Если в Моём Складе сущностей больше, чем помещается в лимит, и требуется перебрать их все, необходимо организовать перебор API. Это можно сделать вручную, при помощи параметров запроса `limit()` и `offset()`, или при помощи методов `getNext()` и `getPrevious()`.

Также имеется более удобный метод, который самостоятельно пройдёт по всему API, отправляя дополнительные запросы в случае необходимости. Метод учитывает параметры, заданные в `limit()` и `offset()`. В отличие от `each()`, коллекцию не нужно заранее загружать, метод сделает это сам.
Также имеется более удобный метод `eachGenerator()`, который самостоятельно пройдёт по всему API, отправляя дополнительные запросы в случае необходимости. Метод учитывает параметры, заданные в `limit()` и `offset()`. В отличие от `each()`, коллекцию не нужно заранее загружать, метод сделает это сам.

```php
Product::collection($ms)
Expand All @@ -303,6 +304,44 @@ Product::collection($ms)
});
```

## Вложенные сущности

При инициализации сущностей, зависящих от других (файлы, изображения, сохранённые фильтры и др.), требуется указать родительскую сущность.

Если родительская сущность является коллекцией (последний сегмент url не является id), это можно сделать в следующих форматах:

```php
//Можно использовать объект Record, имя его класса, сегменты пути или type сущности
$product = Product::make($ms);
$product = Product::class;
$product = ['entity', 'product'];
$product = 'product';

//Получение коллекции вложенных сущностей
$productFilters = NamedFilter::collection($ms, $product)->get();

//Для получения конкретной сущности укажите её id
$productFilter = NamedFilter::make($ms, $product, [
'id' => 'd9b8badf-2332-11ee-0a80-07e1001e2562'
])->get();
```

Если же родительская сущность является конкретным объектом (последний сегмент url является id), требуется сформировать её с id:

```php
//Можно использовать объект Record или сегменты пути
$product = Product::make($ms, ['id' => '8325d6cc-0838-11ee-0a80-08d500275db5']);
$product = ['entity', 'product', '8325d6cc-0838-11ee-0a80-08d500275db5'];

//Получение коллекции вложенных сущностей
$productImages = Image::collection($ms, $product)->get();

//Для получения конкретной сущности укажите её id
$productImage = Image::make($ms, $product, [
'id' => 'fd016e22-9393-4d2c-b9d9-1d46d823f351'
])->get();
```

## Универсальные методы

Позволяют взаимодействовать с API в случае отсутствия нужных методов в библиотеке.
Expand Down
4 changes: 2 additions & 2 deletions docs/formatters.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,10 +34,10 @@ $productArray = (new ArrayFormat())->encode($productString);
Ответы от API преобразуются в объекты на всех уровнях вложенности, что позволяет работать с методами вложенных объектов.

```php
Customerorder::collection($ms)
CustomerOrder::collection($ms)
->limit(100)
->expand('positions.assortment')
->eachGenerator(function (Customerorder $customerorder) {
->eachGenerator(function (CustomerOrder $customerorder) {
echo $customerorder->id . PHP_EOL;

$customerorder->positions
Expand Down
1 change: 1 addition & 0 deletions docs/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
* [Общая информация](/docs/active_record.md#общая-информация)
* [Объекты](/docs/active_record.md#объекты)
* [Коллекции](/docs/active_record.md#коллекции)
* [Вложенные сущности](/docs/active_record.md#вложенные-сущности)
* [Универсальные методы](/docs/active_record.md#универсальные-методы)
* [Расширяемость](/docs/active_record.md#расширяемость)
* [Форматтеры](/docs/formatters.md)
Expand Down
4 changes: 2 additions & 2 deletions docs/query_builder.md
Original file line number Diff line number Diff line change
Expand Up @@ -123,7 +123,7 @@ $ms->query()
#### Нюансы

* И `param()`, и специализированные методы при повторном вызове поддерживают дозапись в параметрах, где это возможно (`filter`, `expand`, `order`). В остальных параметрах ранее установленное значение перезаписывается.
* `filter()` автоматом экранирует `;`. `param()` - нет.
* `filter()` автоматически экранирует `;`. `param()` - нет.

## Методы отправки запросов

Expand Down Expand Up @@ -175,7 +175,7 @@ use Evgeek\Moysklad\Api\Record\Objects\Entities\Product;

$product1 = $ms->query()->entity()->product()->byId('cc181c35-f259-11ed-0a80-00e900658c8f')->get();
$product2 = Product::make($ms, ['id' => 'd540c409-f259-11ed-0a80-00e900658e53']);
$product3 = ['meta' => Meta::product('d540c409-f259-11ed-0a80-00e900658e53')];
$product3 = ['meta' => Meta::product('25cf41f2-b068-11ed-0a80-0e9700500d7e')];

$ms->query()
->entity()
Expand Down
15 changes: 6 additions & 9 deletions src/Api/Query/AbstractBuilder.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,8 @@

namespace Evgeek\Moysklad\Api\Query;

use Evgeek\Moysklad\Api\Query\Segments\AbstractSegmentCommon;
use Evgeek\Moysklad\Api\Query\Segments\AbstractSegmentNamed;
use Evgeek\Moysklad\Api\Query\Traits\Actions\DebugTrait;
use Evgeek\Moysklad\Api\Query\Segments\AbstractCommonSegment;
use Evgeek\Moysklad\Api\Query\Segments\AbstractNamedSegment;
use Evgeek\Moysklad\Enums\HttpMethod;
use Evgeek\Moysklad\Exceptions\RequestException;
use Evgeek\Moysklad\Http\ApiClient;
Expand All @@ -15,8 +14,6 @@

abstract class AbstractBuilder
{
use DebugTrait;

protected array $path;

public function __construct(
Expand Down Expand Up @@ -61,21 +58,21 @@ protected function makePayload(HttpMethod $method, mixed $body = null): Payload
}

/**
* @template T of AbstractSegmentCommon
* @template T of AbstractCommonSegment
*
* @param class-string<T> $builderClass
*/
protected function resolveCommonBuilder(string $builderClass, string $path): AbstractSegmentCommon
protected function resolveCommonBuilder(string $builderClass, string $path): AbstractCommonSegment
{
return new $builderClass($this->api, $this->path, $this->params, $path);
}

/**
* @template T of AbstractSegmentNamed
* @template T of AbstractNamedSegment
*
* @param class-string<T> $builderClass
*/
protected function resolveNamedBuilder(string $builderClass): AbstractSegmentNamed
protected function resolveNamedBuilder(string $builderClass): AbstractNamedSegment
{
return new $builderClass($this->api, $this->path, $this->params);
}
Expand Down
28 changes: 25 additions & 3 deletions src/Api/Query/Debug.php → src/Api/Query/DebugBuilder.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,11 @@

namespace Evgeek\Moysklad\Api\Query;

use Evgeek\Moysklad\Api\Query\Segments\Special\MassDeleteSegment;
use Evgeek\Moysklad\Api\Query\Segments\Special\MassSegmentDelete;
use Evgeek\Moysklad\Enums\HttpMethod;
use Evgeek\Moysklad\Services\CollectionHelper;

class Debug extends AbstractBuilder
class DebugBuilder extends AbstractBuilder
{
/**
* Возвращает отладочную информацию запроса на чтение.
Expand Down Expand Up @@ -58,6 +59,27 @@ public function update(mixed $body)
return $this->apiDebug(HttpMethod::PUT, $body);
}

/**
* Возвращает отладочную информацию запроса на массовое создание/обновление.
*
* <code>
* $debug = $ms->query
* ->entity()
* ->product()
* ->debug()
* ->massCreateUpdate([
* ['name' => 'Корнишоны'],
* ['id' => 'b0d7855d-e1ea-11ed-0a80-0f3f0023b58a', 'name' => 'Черешня'],
* ]);
* </code>
*/
public function massCreateUpdate(mixed $body)
{
$objects = CollectionHelper::extractRows($body);

return $this->apiDebug(HttpMethod::POST, $objects);
}

/**
* Возвращает отладочную информацию запроса на удаление.
*
Expand Down Expand Up @@ -88,7 +110,7 @@ public function delete()
*/
public function massDelete(mixed $body)
{
return (new MassDeleteSegment($this->api, $this->path, $this->params))->massDeleteDebug($body);
return (new MassSegmentDelete($this->api, $this->path, $this->params))->massDeleteDebug($body);
}

/**
Expand Down
44 changes: 38 additions & 6 deletions src/Api/Query/QueryBuilder.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,14 @@

namespace Evgeek\Moysklad\Api\Query;

use Evgeek\Moysklad\Api\Query\Segments\Endpoints\AccountSettingsSegment;
use Evgeek\Moysklad\Api\Query\Segments\Endpoints\AuditSegment;
use Evgeek\Moysklad\Api\Query\Segments\Endpoints\EndpointSegmentCommon;
use Evgeek\Moysklad\Api\Query\Segments\Endpoints\ContextSegment;
use Evgeek\Moysklad\Api\Query\Segments\Endpoints\EndpointCommonSegment;
use Evgeek\Moysklad\Api\Query\Segments\Endpoints\EntitySegment;
use Evgeek\Moysklad\Api\Query\Segments\Endpoints\NotificationSegment;
use Evgeek\Moysklad\Api\Query\Segments\Endpoints\ReportSegment;
use Evgeek\Moysklad\Api\Query\Segments\Methods\MethodSegmentCommon;
use Evgeek\Moysklad\Api\Query\Segments\Methods\MethodCommonSegment;
use Evgeek\Moysklad\Http\ApiClient;
use Evgeek\Moysklad\Services\Url;

Expand All @@ -33,15 +35,15 @@ public function __construct(ApiClient $api)
*
* @param mixed $withParams
*/
public function fromUrl(string $url, $withParams = false): MethodSegmentCommon
public function fromUrl(string $url, $withParams = false): MethodCommonSegment
{
[$path, $params] = Url::parsePathAndParams($url);
$lastSegment = array_pop($path);
if (!$withParams) {
$params = [];
}

return new MethodSegmentCommon($this->api, $path, $params, $lastSegment);
return new MethodCommonSegment($this->api, $path, $params, $lastSegment);
}

/**
Expand All @@ -54,9 +56,9 @@ public function fromUrl(string $url, $withParams = false): MethodSegmentCommon
* ->get();
* </code>
*/
public function endpoint(string $name): EndpointSegmentCommon
public function endpoint(string $name): EndpointCommonSegment
{
return $this->resolveCommonBuilder(EndpointSegmentCommon::class, $name);
return $this->resolveCommonBuilder(EndpointCommonSegment::class, $name);
}

/**
Expand All @@ -77,6 +79,36 @@ public function entity(): EntitySegment
return $this->resolveNamedBuilder(EntitySegment::class);
}

/**
* Входная точка для работы с Контекстом
*
* <code>
* $products = $ms->query()
* ->context()
* ->companysettings()
* ->get();
* </code>
*/
public function context(): ContextSegment
{
return $this->resolveNamedBuilder(ContextSegment::class);
}

/**
* Входная точка для работы с настройками аккаунта
*
* <code>
* $products = $ms->query()
* ->accountSettings()
* ->subscription()
* ->get();
* </code>
*/
public function accountSettings(): AccountSettingsSegment
{
return $this->resolveNamedBuilder(AccountSettingsSegment::class);
}

/**
* Входная точка для работы с Отчётами
*
Expand Down
Loading

0 comments on commit 0fc72d1

Please sign in to comment.