Taxcom::getShiftList()   A
last analyzed

Complexity

Conditions 6
Paths 24

Size

Total Lines 30
Code Lines 19

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 6
eloc 19
c 1
b 0
f 0
nc 24
nop 3
dl 0
loc 30
rs 9.0111
1
<?php
2
3
namespace alekciy\ofd\providers\taxcom;
4
5
use alekciy\ffd\DocumentInterface as ffdDocument;
6
use alekciy\ffd\documents\Check;
7
use alekciy\ffd\documents\Close;
8
use alekciy\ffd\documents\Confirmation;
9
use alekciy\ffd\documents\FnClose;
10
use alekciy\ffd\documents\Open;
11
use alekciy\ffd\documents\Registration;
12
use alekciy\ffd\documents\RegistrationChange;
13
use alekciy\ffd\documents\State;
14
use alekciy\ffd\documents\Strict;
15
use alekciy\ffd\documents\StrictCorrect;
16
use alekciy\ffd\tags\Tag1012;
17
use alekciy\ofd\interfaces\CashDeskInterface;
18
use alekciy\ofd\interfaces\DocumentInterface;
19
use alekciy\ofd\interfaces\OutletInterface;
20
use alekciy\ofd\interfaces\ShiftInterface;
21
use alekciy\ofd\interfaces\ProviderInterface;
22
use alekciy\ofd\providers\taxcom\Model\CashDeskShort;
23
use alekciy\ofd\providers\taxcom\Model\Document;
24
use alekciy\ofd\providers\taxcom\Model\OutletShort;
25
use alekciy\ofd\providers\taxcom\Model\ShiftShort;
26
use alekciy\ofd\providers\taxcom\Request\DocumentInfo;
27
use GuzzleHttp\Exception\GuzzleException;
28
use DateTime;
29
use alekciy\ofd\providers\taxcom\Request\DocumentList;
30
use alekciy\ofd\providers\taxcom\Request\CashDeskList;
31
use alekciy\ofd\providers\taxcom\Request\OutletList;
32
use alekciy\ofd\providers\taxcom\Request\ShiftList;
33
use DateTimeZone;
34
35
/**
36
 * @see https://lk-ofd.taxcom.ru/ApiHelp/
37
 */
38
class Taxcom implements ProviderInterface
39
{
40
	/** @var Client */
41
	protected $client = null;
42
43
	/**
44
	 * @param Client $client
45
	 */
46
	public function __construct(Client $client)
47
	{
48
		$this->client = $client;
49
	}
50
51
	/**
52
	 * Для запросов с постраничной навигацией загрузит все возможные элементы.
53
	 *
54
	 * @param RequestPage $endpoint
55
	 * @return array
56
	 * @throws Exception
57
	 * @throws GuzzleException
58
	 */
59
	private function getAllItemList(RequestPage $endpoint): array
60
	{
61
		$result = [];
62
		do {
63
			$response = $this->client->request($endpoint);
64
			foreach ($response['records'] as $record) {
65
				$result[] = $record;
66
			}
67
68
			$lastPageNumber = ceil($response['counts']['recordFilteredCount'] / $endpoint->perPage);
69
			++$endpoint->pageNumber;
70
		} while ($endpoint->pageNumber <= $lastPageNumber);
71
		return $result;
72
	}
73
74
	/**
75
	 * @inheritDoc
76
	 *
77
	 * @return OutletInterface[]
78
	 * @throws GuzzleException
79
	 * @throws Exception
80
	 */
81
	public function getOutletList(): array
82
	{
83
		$result = [];
84
		$responseOutletList = $this->getAllItemList(new OutletList([]));
85
		foreach ($responseOutletList as $responseOutlet) {
86
			$outletShort = new OutletShort($responseOutlet);
87
			$result[$outletShort->id] = $outletShort;
88
		}
89
		return $result;
90
	}
91
92
	/**
93
	 * @inheritDoc
94
	 *
95
	 * @throws GuzzleException
96
	 * @throws Exception
97
	 */
98
	public function getCashDeskList(OutletInterface $outlet = null): array
99
	{
100
		$result = [];
101
		$outletList = $outlet instanceof OutletInterface
102
			? [$outlet]
103
			: $this->getOutletList();
104
		foreach ($outletList as $outlet) {
105
			$responseCashDeskList = $this->getAllItemList(new CashDeskList([
106
				'outletId' => $outlet->getId(),
107
			]));
108
			foreach ($responseCashDeskList as $responseCashDesk) {
109
				$result[] = new CashDeskShort($responseCashDesk);
110
			}
111
		}
112
		return $result;
113
	}
114
115
	/**
116
	 * @inheritDoc
117
	 *
118
	 * @throws Exception
119
	 * @throws GuzzleException
120
	 */
121
	public function getShiftList(CashDeskInterface $cashDesk = null, DateTime $start = null, DateTime $end = null): array
122
	{
123
		$result = [];
124
125
		// Задаем время
126
		if (!$start instanceof DateTime) {
127
			$start = new DateTime('today');
128
		}
129
		if (!$end instanceof DateTime) {
130
			$end = new DateTime('tomorrow');
131
		}
132
		// Сервис оперирует часовым поясом +0, поэтому корректируем
133
		$tz = new DateTimeZone('UTC');
134
		$start->setTimezone($tz);
135
		$end->setTimezone($tz);
136
137
		$cashDeskList = $cashDesk instanceof CashDeskInterface
138
			? [$cashDesk]
139
			: $this->getCashDeskList();
140
		foreach ($cashDeskList as $cashDesk) {
141
			$responseShiftList = $this->getAllItemList(new ShiftList([
142
				'fnFactoryNumber' => $cashDesk->getFnFactoryNumber(),
143
				'start'           => $start->format('Y-m-d\TH:i:s'),
144
				'end'             => $end->format('Y-m-d\TH:i:s'),
145
			]));
146
			foreach ($responseShiftList as $responseShift) {
147
				$result[] = new ShiftShort($responseShift);
148
			}
149
		}
150
		return $result;
151
	}
152
153
	/**
154
	 * @inheritDoc
155
	 *
156
	 * @throws Exception
157
	 * @throws GuzzleException
158
	 */
159
	public function getDocumentList(ShiftInterface $shift = null, DateTime $start = null, DateTime $end = null): array
160
	{
161
		$result = [];
162
163
		// Задаем время
164
		if (!$start instanceof DateTime) {
165
			$start = new DateTime('today');
166
		}
167
		if (!$end instanceof DateTime) {
168
			$end = new DateTime('tomorrow');
169
		}
170
		// Сервис оперирует часовым поясом +0, поэтому корректируем
171
		$tz = new DateTimeZone('UTC');
172
		$start->setTimezone($tz);
173
		$end->setTimezone($tz);
174
175
		$shiftList = $shift instanceof ShiftInterface
176
			? [$shift]
177
			: $this->getShiftList(null, $start, $end);
178
		foreach ($shiftList as $shift) {
179
			$responseDocumentList = $this->getAllItemList(new DocumentList([
180
				'fnFactoryNumber' => $shift->getFnFactoryNumber(),
181
				'shiftNumber'     => $shift->getShiftNumber(),
182
			]));
183
			foreach ($responseDocumentList as $responseDocument) {
184
				$result[] = new Document($responseDocument);
185
			}
186
		}
187
		return $result;
188
	}
189
190
	/**
191
	 * @param DocumentInterface $document
192
	 * @return Registration|Open|Check|Strict|Close|FnClose|Confirmation|RegistrationChange|State|StrictCorrect
193
	 * @throws GuzzleException
194
	 * @throws Exception
195
	 */
196
	public function getDocumentTag(DocumentInterface $document): ffdDocument
197
	{
198
		$documentTagList = $this->getDocumentTagList($document);
199
		return reset($documentTagList);
200
	}
201
202
	/**
203
	 * Получить список тегов (реквизитов) документа(-ов) за заданный период. По умолчанию за сегодня.
204
	 *
205
	 * @param Document[]|Document $document
206
	 * @param DateTime|null $start
207
	 * @param DateTime|null $end
208
	 * @return Registration[]|Open[]|Check[]|Strict[]|Close[]|FnClose[]|Confirmation[]|RegistrationChange[]|State[]|StrictCorrect[]
209
	 * @throws GuzzleException
210
	 * @throws Exception
211
	 */
212
	public function getDocumentTagList($document = null, DateTime $start = null, DateTime $end = null): array
213
	{
214
		$result = [];
215
216
		// Задаем время
217
		if (!$start instanceof DateTime) {
218
			$start = new DateTime('today');
219
		}
220
		if (!$end instanceof DateTime) {
221
			$end = new DateTime('tomorrow');
222
		}
223
		// Сервис оперирует часовым поясом +0, поэтому корректируем
224
		$tz = new DateTimeZone('UTC');
225
		$start->setTimezone($tz);
226
		$end->setTimezone($tz);
227
228
		$documentList = $document instanceof DocumentInterface
229
			? [$document]
230
			: $this->getDocumentList(null, $start, $end);
231
		foreach ($documentList as $document) {
232
			$responseDocumentInfo = $this->client->request(new DocumentInfo([
233
				'fnFactoryNumber' => $document->getFnFactoryNumber(),
234
				'fdNumber'        => $document->getNumber(),
235
			]));
236
237
			$tagList = $responseDocumentInfo['document'];
238
			$version = $responseDocumentInfo['documentFormatVersion'];
239
			$format = ffdDocument::FORMAT_PRINT;
240
241
			$tagList[Tag1012::getCode()] = (new DateTime($tagList[Tag1012::getCode()], $tz))->format('d.m.y H:i');
242
243
			switch ($responseDocumentInfo['documentType']) {
244
				case ffdDocument::TYPE_REGISTRATION:
245
					$result[] = new Registration($version, $format, $tagList);
246
					break;
247
				case ffdDocument::TYPE_OPEN:
248
					$result[] = new Open($version, $format, $tagList);
249
					break;
250
				case ffdDocument::TYPE_CHECK:
251
					$result[] = new Check($version, $format, $tagList);
252
					break;
253
				case ffdDocument::TYPE_STRICT:
254
					$result[] = new Strict($version, $format, $tagList);
255
					break;
256
				case ffdDocument::TYPE_CLOSE:
257
					$result[] = new Close($version, $format, $tagList);
258
					break;
259
				case ffdDocument::TYPE_FN_CLOSE:
260
					$result[] = new FnClose($version, $format, $tagList);
261
					break;
262
				case ffdDocument::TYPE_CONFIRMATION:
263
					$result[] = new Confirmation($version, $format, $tagList);
264
					break;
265
				case ffdDocument::TYPE_REGISTRATION_CHANGE:
266
					$result[] = new RegistrationChange($version, $format, $tagList);
267
					break;
268
				case ffdDocument::TYPE_STATE:
269
					$result[] = new State($version, $format, $tagList);
270
					break;
271
				case ffdDocument::TYPE_STRICT_CORRECT:
272
					$result[] = new StrictCorrect($version, $format, $tagList);
273
					break;
274
				default:
275
					throw new Exception('Неизвестный тип документа');
276
			}
277
		}
278
		return $result;
279
	}
280
}
281