32 lines
3.3 KiB
PHP
32 lines
3.3 KiB
PHP
<?php
|
|
namespace Tempo\Finance\GeneralLedger;
|
|
use Illuminate\Database\ConnectionInterface;
|
|
use Tempo\Finance\Payables\Payables;
|
|
|
|
/** Immutable native review/execution facts; later eligible returns do not rewrite this fact. */
|
|
final class StockSupplierReturnEvidence
|
|
{
|
|
public function __construct(private ConnectionInterface $db,private array $scope){}
|
|
public function check(object $m,object $op,array $snapshot):array
|
|
{
|
|
if(!LedgerSchema::externalHostComposition($this->db)||$op->kind!=='supplier_return')throw new \DomainException('Devolução ao fornecedor fora da composição QA.');
|
|
$proof=$snapshot['disposition']??null;
|
|
$approved=is_array($proof)?$this->db->table('supply_records')->where(['tenant_id'=>$this->scope['tenant_id'],'id'=>$proof['approved_id']??0,'kind'=>'stock_event','state'=>'approved'])->first():null;
|
|
$executed=$approved?$this->db->table('supply_records')->where(['tenant_id'=>$this->scope['tenant_id'],'record_key'=>$approved->record_key,'version'=>$approved->version+1,'state'=>'executed','kind'=>'stock_event'])->first():null;
|
|
if(!$approved||!$executed)throw new \DomainException('Faltam aprovação e execução nativas.');
|
|
$data=json_decode($approved->data,true,64,JSON_THROW_ON_ERROR);$done=json_decode($executed->data,true,64,JSON_THROW_ON_ERROR);$review=json_decode($approved->snapshot,true,64,JSON_THROW_ON_ERROR);
|
|
$source=$review['source']??null;$receiptItem=$source['receipt']['item_id']??null;
|
|
$line=is_int($receiptItem)?$this->db->table('goods_receipt_items')->where(['tenant_id'=>$this->scope['tenant_id'],'id'=>$receiptItem])->first():null;
|
|
$receipt=$line?$this->db->table('goods_receipts')->where(['tenant_id'=>$this->scope['tenant_id'],'id'=>$line->goods_receipt_id])->first():null;
|
|
$total=$this->db->table('stock_movements')->where(['tenant_id'=>$this->scope['tenant_id'],'movement_type'=>'supplier_return'])->where('snapshot->disposition->source->receipt->item_id',$receiptItem)->sum('quantity_milli');
|
|
if(!$line||!$receipt||$receipt->confirmed_at===null||$line->stock_item_id!==$m->stock_item_id||$receipt->warehouse_id!==$m->warehouse_id
|
|
||($data['kind']??null)!=='supplier_return'||($data['stock_item_id']??null)!==$m->stock_item_id||($data['warehouse_id']??null)!==$m->warehouse_id||($data['receipt_item_id']??null)!==$receiptItem
|
|
||($data['quantity_milli']??null)!==abs((int)$m->quantity_milli)||($done['stock_operation_id']??null)!==$op->id||$executed->created_by!==$m->moved_by
|
|
||$approved->created_by===$executed->created_by||($review['reviewed_by']??null)!==$approved->created_by||in_array($approved->created_by,$review['contributors']??[],true)
|
|
||($proof['record_key']??null)!==$approved->record_key||$op->idempotency_key!==$approved->record_key||($proof['financial_correction_created']??null)!==false
|
|
||Payables::canonical($proof['source']??null)!==Payables::canonical($source)||abs((int)$total)>(int)$line->accepted_milli)
|
|
throw new \DomainException('Devolução sem origem, quantidade, revisão e execução reconciliadas.');
|
|
return ['supplier_return_approved'=>(array)$approved,'supplier_return_executed'=>(array)$executed,'supplier_receipt_item'=>(array)$line,'supplier_receipt'=>(array)$receipt];
|
|
}
|
|
}
|