feat(v1.5): complete phases 40-43 workflow cleanup

This commit is contained in:
2026-03-25 22:46:51 +01:00
parent b8dda81e7b
commit 3610571949
37 changed files with 1557 additions and 259 deletions

View File

@@ -162,69 +162,4 @@ final class PrintApiController
return Response::json(['id' => $jobId, 'status' => 'completed']);
}
public function bulkCreateJobs(Request $request): Response
{
$body = json_decode((string) file_get_contents('php://input'), true);
if (!is_array($body)) {
$body = [];
}
$token = (string) ($body['_token'] ?? $request->input('_token', ''));
if (!Csrf::validate($token)) {
return Response::json(['error' => 'Invalid CSRF token'], 403);
}
$packageIds = $body['package_ids'] ?? $request->input('package_ids', []);
if (!is_array($packageIds) || $packageIds === []) {
$orderIds = $body['order_ids'] ?? $request->input('order_ids', []);
if (!is_array($orderIds) || $orderIds === []) {
return Response::json(['error' => 'package_ids or order_ids required'], 400);
}
$intOrderIds = array_map('intval', $orderIds);
$packages = $this->printJobs->findPackagesWithLabelsByOrderIds($intOrderIds);
$packageIds = array_map(static fn(array $p): int => (int) $p['id'], $packages);
}
$user = $this->auth->user();
$userId = (int) ($user['id'] ?? 0);
$created = [];
$skipped = [];
foreach ($packageIds as $pkgId) {
$pkgId = (int) $pkgId;
if ($pkgId <= 0) {
continue;
}
$existing = $this->printJobs->findPendingByPackageId($pkgId);
if ($existing !== null) {
$skipped[] = ['package_id' => $pkgId, 'reason' => 'already_pending'];
continue;
}
$package = $this->packages->findById($pkgId);
if ($package === null) {
$skipped[] = ['package_id' => $pkgId, 'reason' => 'not_found'];
continue;
}
$labelPath = $this->ensureLabel($pkgId, $package);
if ($labelPath === '') {
$skipped[] = ['package_id' => $pkgId, 'reason' => 'no_label'];
continue;
}
$jobId = $this->printJobs->create([
'order_id' => (int) ($package['order_id'] ?? 0),
'package_id' => $pkgId,
'label_path' => $labelPath,
'created_by' => $userId,
]);
$created[] = ['id' => $jobId, 'package_id' => $pkgId];
}
return Response::json(['created' => $created, 'skipped' => $skipped], 201);
}
}

View File

@@ -86,6 +86,14 @@ final class PrintJobRepository
$statement->execute(['id' => $id]);
}
public function deleteById(int $id): bool
{
$statement = $this->pdo->prepare('DELETE FROM print_jobs WHERE id = :id');
$statement->execute(['id' => $id]);
return $statement->rowCount() > 0;
}
/**
* @return list<int>
*/
@@ -141,25 +149,4 @@ final class PrintJobRepository
return is_array($rows) ? $rows : [];
}
/**
* @param list<int> $orderIds
* @return list<array<string, mixed>>
*/
public function findPackagesWithLabelsByOrderIds(array $orderIds): array
{
if ($orderIds === []) {
return [];
}
$placeholders = implode(',', array_fill(0, count($orderIds), '?'));
$statement = $this->pdo->prepare(
"SELECT id, order_id, label_path FROM shipment_packages
WHERE order_id IN ($placeholders) AND label_path IS NOT NULL AND label_path != ''
AND status != 'error'"
);
$statement->execute(array_values($orderIds));
$rows = $statement->fetchAll(PDO::FETCH_ASSOC);
return is_array($rows) ? $rows : [];
}
}