ultimatepos/Modules/IndustrialEngineering/Services/ConnectionGateService.php

73 lines
2.5 KiB
PHP

<?php
namespace Modules\IndustrialEngineering\Services;
use Modules\IndustrialEngineering\Models\Bom;
use Modules\IndustrialEngineering\Models\ItemMaster;
/**
* Validates integration health; blocks critical ops until required links exist.
*/
class ConnectionGateService
{
public function __construct(
protected BomService $bomService,
protected LiveBomCostingService $liveCosting
) {
}
public function assessBom(Bom $bom, float $plannedQty = 1): array
{
$analysis = $this->liveCosting->analyze($bom, $plannedQty);
$leafParts = collect($analysis['leaf_lines']);
$unlinked = $leafParts->filter(fn ($l) => empty($l['variation_id']));
$linked = $leafParts->filter(fn ($l) => ! empty($l['variation_id']));
$assemblies = $leafParts->filter(fn ($l) => in_array($l['item_type'], ['assembly', 'subassembly', 'device'], true));
$blockers = [];
if ($leafParts->isEmpty()) {
$blockers[] = __('industrialengineering::lang.gate_no_bom_leaves');
}
$warnings = [];
foreach ($unlinked as $row) {
$warnings[] = __('industrialengineering::lang.gate_unlinked_item', [
'code' => $row['item_code'],
'name' => $row['item_name'],
]);
}
return [
'can_run_mrp' => empty($blockers) && $unlinked->isEmpty(),
'can_run_mrp_with_warnings' => empty($blockers) && $unlinked->isNotEmpty(),
'blockers' => $blockers,
'warnings' => $warnings,
'stats' => [
'total_leaves' => $leafParts->count(),
'erp_linked' => $linked->count(),
'unlinked' => $unlinked->count(),
'assemblies' => $assemblies->count(),
'shortage_count' => count($analysis['shortages']),
],
'analysis' => $analysis,
];
}
public function assertMrpAllowed(Bom $bom, float $plannedQty = 1, bool $force = false): void
{
$gate = $this->assessBom($bom, $plannedQty);
if (! empty($gate['blockers'])) {
throw new \RuntimeException(implode("\n", $gate['blockers']));
}
if (! empty($gate['warnings']) && ! $force) {
throw new \RuntimeException(
__('industrialengineering::lang.gate_mrp_blocked_unlinked')."\n".
implode("\n", array_slice($gate['warnings'], 0, 5)).
(count($gate['warnings']) > 5 ? "\n..." : '')
);
}
}
}