ImportMafOrdersServiceTest.php 8.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257
  1. <?php
  2. namespace Tests\Unit\Services\Import;
  3. use App\Models\MafOrder;
  4. use App\Models\Product;
  5. use App\Services\Import\ImportMafOrdersService;
  6. use Illuminate\Foundation\Testing\RefreshDatabase;
  7. use PhpOffice\PhpSpreadsheet\Spreadsheet;
  8. use PhpOffice\PhpSpreadsheet\Writer\Xlsx;
  9. use Tests\TestCase;
  10. class ImportMafOrdersServiceTest extends TestCase
  11. {
  12. use RefreshDatabase;
  13. protected $seed = true;
  14. private string $tempFilePath;
  15. private Product $product1;
  16. private Product $product2;
  17. private int $testYear = 2025;
  18. protected function setUp(): void
  19. {
  20. parent::setUp();
  21. $this->product1 = Product::factory()->create(['article' => 'MAF.0001', 'year' => $this->testYear]);
  22. $this->product2 = Product::factory()->create(['article' => 'MAF.0002', 'year' => $this->testYear]);
  23. }
  24. protected function tearDown(): void
  25. {
  26. if (isset($this->tempFilePath) && file_exists($this->tempFilePath)) {
  27. unlink($this->tempFilePath);
  28. }
  29. parent::tearDown();
  30. }
  31. public function test_import_creates_maf_orders(): void
  32. {
  33. $this->createTestFile([
  34. ['MAF.0001', 10, '55/5224', 'На складе'],
  35. ['MAF.0002', 5, '1554-55453', 'Заказан'],
  36. ]);
  37. $service = new ImportMafOrdersService($this->tempFilePath, 1, $this->testYear);
  38. $result = $service->handle();
  39. $this->assertTrue($result['success']);
  40. $this->assertEquals(2, $result['imported']);
  41. $this->assertEquals(0, $result['errors']);
  42. $this->assertDatabaseHas('maf_orders', [
  43. 'product_id' => $this->product1->id,
  44. 'quantity' => 10,
  45. 'in_stock' => 10,
  46. 'order_number' => '55/5224',
  47. 'status' => 'на складе',
  48. 'year' => $this->testYear,
  49. ]);
  50. $this->assertDatabaseHas('maf_orders', [
  51. 'product_id' => $this->product2->id,
  52. 'quantity' => 5,
  53. 'in_stock' => 0,
  54. 'order_number' => '1554-55453',
  55. 'status' => 'заказан',
  56. 'year' => $this->testYear,
  57. ]);
  58. }
  59. public function test_import_reports_error_for_unknown_article(): void
  60. {
  61. $this->createTestFile([
  62. ['UNKNOWN.ARTICLE', 10, '55/5224', 'На складе'],
  63. ['MAF.0001', 5, '55/5224', 'На складе'],
  64. ]);
  65. $service = new ImportMafOrdersService($this->tempFilePath, 1, $this->testYear);
  66. $result = $service->handle();
  67. $this->assertFalse($result['success']);
  68. $this->assertEquals(1, $result['imported']);
  69. $this->assertEquals(1, $result['errors']);
  70. $hasErrorLog = false;
  71. foreach ($result['logs'] as $log) {
  72. if (str_contains($log, 'UNKNOWN.ARTICLE') && str_contains($log, 'не найден')) {
  73. $hasErrorLog = true;
  74. break;
  75. }
  76. }
  77. $this->assertTrue($hasErrorLog, 'Should log error for unknown article');
  78. }
  79. public function test_import_reports_error_for_unknown_status(): void
  80. {
  81. $this->createTestFile([
  82. ['MAF.0001', 10, '55/5224', 'Неизвестный статус'],
  83. ]);
  84. $service = new ImportMafOrdersService($this->tempFilePath, 1, $this->testYear);
  85. $result = $service->handle();
  86. $this->assertFalse($result['success']);
  87. $this->assertEquals(0, $result['imported']);
  88. $this->assertEquals(1, $result['errors']);
  89. }
  90. public function test_import_skips_empty_rows(): void
  91. {
  92. $this->createTestFile([
  93. ['', '', '', ''],
  94. ['MAF.0001', 10, '55/5224', 'На складе'],
  95. ]);
  96. $service = new ImportMafOrdersService($this->tempFilePath, 1, $this->testYear);
  97. $result = $service->handle();
  98. $this->assertTrue($result['success']);
  99. $this->assertEquals(1, $result['imported']);
  100. $this->assertEquals(1, $result['skipped']);
  101. }
  102. public function test_import_parses_status_correctly(): void
  103. {
  104. $this->createTestFile([
  105. ['MAF.0001', 1, 'order1', 'На складе'],
  106. ['MAF.0002', 1, 'order2', 'Заказан'],
  107. ]);
  108. $service = new ImportMafOrdersService($this->tempFilePath, 1, $this->testYear);
  109. $result = $service->handle();
  110. $this->assertTrue($result['success']);
  111. $this->assertDatabaseHas('maf_orders', [
  112. 'product_id' => $this->product1->id,
  113. 'status' => 'на складе',
  114. 'in_stock' => 1,
  115. ]);
  116. $this->assertDatabaseHas('maf_orders', [
  117. 'product_id' => $this->product2->id,
  118. 'status' => 'заказан',
  119. 'in_stock' => 0,
  120. ]);
  121. }
  122. public function test_import_only_uses_products_from_specified_year(): void
  123. {
  124. // Создаём продукт с другим годом
  125. Product::factory()->create(['article' => 'MAF.OTHER', 'year' => 2020]);
  126. $this->createTestFile([
  127. ['MAF.OTHER', 10, '55/5224', 'На складе'],
  128. ]);
  129. $service = new ImportMafOrdersService($this->tempFilePath, 1, $this->testYear);
  130. $result = $service->handle();
  131. $this->assertFalse($result['success']);
  132. $this->assertEquals(0, $result['imported']);
  133. $this->assertEquals(1, $result['errors']);
  134. $hasErrorLog = false;
  135. foreach ($result['logs'] as $log) {
  136. if (str_contains($log, 'MAF.OTHER') && str_contains($log, $this->testYear . ' года')) {
  137. $hasErrorLog = true;
  138. break;
  139. }
  140. }
  141. $this->assertTrue($hasErrorLog, 'Should log error mentioning the year');
  142. }
  143. public function test_import_returns_summary(): void
  144. {
  145. $this->createTestFile([
  146. ['MAF.0001', 10, '55/5224', 'На складе'],
  147. ['UNKNOWN', 5, '55/5224', 'На складе'],
  148. [' ', '', '', ''],
  149. ]);
  150. $service = new ImportMafOrdersService($this->tempFilePath, 1, $this->testYear);
  151. $result = $service->handle();
  152. $this->assertArrayHasKey('imported', $result);
  153. $this->assertArrayHasKey('skipped', $result);
  154. $this->assertArrayHasKey('errors', $result);
  155. $this->assertArrayHasKey('logs', $result);
  156. $this->assertEquals(1, $result['imported']);
  157. $this->assertEquals(1, $result['skipped']);
  158. $this->assertEquals(1, $result['errors']);
  159. $hasSummary = false;
  160. foreach ($result['logs'] as $log) {
  161. if (str_contains($log, 'РЕЗЮМЕ')) {
  162. $hasSummary = true;
  163. break;
  164. }
  165. }
  166. $this->assertTrue($hasSummary, 'Should include summary in logs');
  167. }
  168. public function test_import_sets_in_stock_based_on_status(): void
  169. {
  170. $this->createTestFile([
  171. ['MAF.0001', 15, 'order1', 'На складе'],
  172. ['MAF.0002', 20, 'order2', 'Заказан'],
  173. ]);
  174. $service = new ImportMafOrdersService($this->tempFilePath, 1, $this->testYear);
  175. $result = $service->handle();
  176. $this->assertTrue($result['success']);
  177. // На складе - in_stock = quantity
  178. $this->assertDatabaseHas('maf_orders', [
  179. 'product_id' => $this->product1->id,
  180. 'quantity' => 15,
  181. 'in_stock' => 15,
  182. ]);
  183. // Заказан - in_stock = 0
  184. $this->assertDatabaseHas('maf_orders', [
  185. 'product_id' => $this->product2->id,
  186. 'quantity' => 20,
  187. 'in_stock' => 0,
  188. ]);
  189. }
  190. private function createTestFile(array $rows): void
  191. {
  192. $spreadsheet = new Spreadsheet();
  193. $sheet = $spreadsheet->getActiveSheet();
  194. // Headers
  195. $sheet->setCellValue('A1', 'Артикул МАФ');
  196. $sheet->setCellValue('B1', 'кол-во');
  197. $sheet->setCellValue('C1', 'Номер заказа');
  198. $sheet->setCellValue('D1', 'Статус');
  199. // Data rows
  200. $rowNum = 2;
  201. foreach ($rows as $row) {
  202. $sheet->setCellValue('A' . $rowNum, $row[0] ?? '');
  203. $sheet->setCellValue('B' . $rowNum, $row[1] ?? '');
  204. $sheet->setCellValue('C' . $rowNum, $row[2] ?? '');
  205. $sheet->setCellValue('D' . $rowNum, $row[3] ?? '');
  206. $rowNum++;
  207. }
  208. $this->tempFilePath = sys_get_temp_dir() . '/test_maf_orders_' . uniqid() . '.xlsx';
  209. $writer = new Xlsx($spreadsheet);
  210. $writer->save($this->tempFilePath);
  211. }
  212. }