getDatabaseName()||($p['composition']??null)!==$physical['composition'])throw new \DomainException('Perímetro pertence a outro contexto.'); $stocks=$native->table('gl_stock_books')->where($scope)->orderBy('id')->get(['stock_item_id','warehouse_id']); $actual=$stocks->map(fn($r)=>(array)$r)->all();if(Payables::canonical($actual)!==Payables::canonical($p['valued_stock']))throw new \DomainException('Artigo/armazém de valorização mudou; nova conferência obrigatória.'); $codes=$native->table('stock_items')->where('tenant_id',$scope['tenant_id'])->whereIn('id',$stocks->pluck('stock_item_id'))->pluck('code')->all(); foreach($native->table('gl_cost_sources')->where($scope)->orderBy('id')->cursor() as $map){ $claim=$p['direct_costs'][(string)$map->order_id]??null; if(!$claim||$claim['material_origin']!==$map->material_origin)throw new \DomainException('Custo sem declaração individual de exclusão do Stock valorizado.'); if(!$host->table('wo_orders')->where($scope)->where('id',$map->order_id)->exists())throw new \DomainException('Ordem de custo fora da empresa/unidade.'); $entry=$host->table('wo_entries')->where('order_id',$map->order_id)->where('origin',$map->material_origin)->orderByDesc('version')->first();$data=$entry?json_decode($entry->data,true):null; if(!$entry||$entry->kind!=='material'||($data['resource']??null)!==$claim['resource']||in_array($claim['resource'],$codes,true)||!str_starts_with($claim['resource'],'QA-MATERIAL-DIRECTO-')||isset($data['stock_item_id'])||isset($data['delivery_movement_id']))throw new \DomainException('Material directo partilhado, alterado ou sem fronteira física explícita.'); } foreach($native->table('gl_industrial_sources')->where($scope)->orderBy('id')->cursor() as $map){ $claim=$p['industrial_costs'][(string)$map->lot_id]??null;$origins=json_decode($map->origins,true); if(!$claim||$claim['material_origin']!==($origins['material']??null)||in_array($claim['material_origin'],$codes,true))throw new \DomainException('Material industrial sem exclusão individual do Stock valorizado.'); $entry=$host->table('ic_inputs')->where($scope)->where('lot_id',$map->lot_id)->where('kind','material')->where('source_ref',$claim['material_origin'])->orderByDesc('version')->first(); if(!$entry||!str_starts_with($entry->source_ref,'IND-TEST-MATERIAL-'))throw new \DomainException('Origem industrial fora do perímetro sintético seleccionado.'); } } }