Preserva classificacao contabilistica aceite e bases locais
Regista aceitacao funcional do primeiro incremento PGC-NIRF e preserva as dependencias documentais e tecnicas existentes. A validacao do calculo fiscal continua separada e pendente. Sem credenciais, bases operacionais ou publicacao.
This commit is contained in:
@@ -0,0 +1,29 @@
|
||||
<?php
|
||||
namespace App\Modules\Services\Http;
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Modules\Services\CatalogueAccounting;
|
||||
use Illuminate\Http\Request;
|
||||
|
||||
final class CatalogueAccountingController extends Controller
|
||||
{
|
||||
private function response(array $data) { return response()->json($data)->header('Cache-Control','no-store, private'); }
|
||||
private function only(Request $r,array $keys): void { abort_if(array_diff(array_keys($r->all()),$keys)!==[],422,'Campo protegido ou fora do âmbito.'); }
|
||||
public function index(Request $r,CatalogueAccounting $c) { return $this->response($c->listing($r->user()->id)); }
|
||||
public function propose(Request $r,CatalogueAccounting $c) {
|
||||
$this->only($r,['kind','data','valid_from','valid_until','reason','previous_id','replaces_id']);
|
||||
$data=$r->validate(['kind'=>'required|in:plan,account,category,service_link,service_override','data'=>'required|array','valid_from'=>'required|date_format:Y-m-d','valid_until'=>'nullable|date_format:Y-m-d|after_or_equal:valid_from','reason'=>'required|string|max:2000','previous_id'=>'nullable|integer|min:1','replaces_id'=>'nullable|integer|min:1']);
|
||||
return $this->response($c->propose($r->user()->id,$data,(string)$r->header('Idempotency-Key')));
|
||||
}
|
||||
public function submit(Request $r,int $id,CatalogueAccounting $c) { $this->only($r,[]); return $this->response($c->submit($id,$r->user()->id,(string)$r->header('Idempotency-Key'))); }
|
||||
public function decide(Request $r,int $id,CatalogueAccounting $c) {
|
||||
$this->only($r,['decision','reason']); return $this->response($c->decide($id,$r->user()->id,$r->validate(['decision'=>'required|in:approved,refused','reason'=>'required|string|max:2000']),(string)$r->header('Idempotency-Key')));
|
||||
}
|
||||
public function resolve(Request $r,int $service,CatalogueAccounting $c) { $this->only($r,['reference_date']); $r->validate(['reference_date'=>'nullable|date_format:Y-m-d']); return $this->response($c->resolve($service,$r->query('reference_date'),$r->user()->id)); }
|
||||
public function capture(Request $r,CatalogueAccounting $c) {
|
||||
$this->only($r,['area','record_id','record_version','service_id','reference_date','resolution_revision']);
|
||||
$data=$r->validate(['area'=>'required|in:service_drafts,billing_drafts','record_id'=>'required|integer|min:1','record_version'=>'required|integer|min:1','service_id'=>'required|integer|min:1','reference_date'=>'required|date_format:Y-m-d','resolution_revision'=>'required|string|regex:/^[a-f0-9]{64}$/D']);
|
||||
foreach(['record_id','record_version','service_id'] as $field)$data[$field]=(int)$data[$field];
|
||||
return $this->response($c->capture($r->user()->id,$data,(string)$r->header('Idempotency-Key')));
|
||||
}
|
||||
public function history(Request $r,string $area,int $record,CatalogueAccounting $c) { abort_unless(in_array($area,['service_drafts','billing_drafts'],true),404); return $this->response(['records'=>$c->history($r->user()->id,$area,$record)]); }
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
<?php
|
||||
|
||||
namespace App\Modules\Services\Http;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Modules\Services\DocumentPreparation;
|
||||
use Illuminate\Http\Request;
|
||||
|
||||
final class DocumentPreparationController extends Controller
|
||||
{
|
||||
public function index(Request $request, string $kind, DocumentPreparation $preparation) { return response()->json(['records' => $preparation->index($kind, $request->user()->id)]); }
|
||||
public function show(Request $request, string $kind, int $id, DocumentPreparation $preparation) { return response()->json($preparation->show($kind, $id, $request->user()->id)); }
|
||||
public function save(Request $request, string $kind, int $id, DocumentPreparation $preparation)
|
||||
{
|
||||
$preparation->scope($kind, $request->user()->id, 'edit');
|
||||
$fields = in_array($kind, ['issuer','client'], true) ? DocumentPreparation::PROFILE_FIELDS : ($kind === 'payment' ? DocumentPreparation::PAYMENT_FIELDS : DocumentPreparation::DRAFT_FIELDS);
|
||||
$allowed = array_merge($fields, ['version'], str_ends_with($kind, '_drafts') ? ['draft_version','currency'] : []);
|
||||
abort_if(array_diff(array_keys($request->all()), $allowed) !== [], 422, 'Campo não suportado; não introduza credenciais, tokens ou dados de cartões.');
|
||||
$rules = ['version' => 'required|integer|min:0'];
|
||||
foreach ($fields as $field) { $rules[$field] = 'nullable|string|max:500'; }
|
||||
if ($kind === 'payment') {
|
||||
$rules['label'] = 'required|string|max:120'; $rules['instructions'] = 'nullable|string|max:2000'; $rules['currency'] = 'nullable|string|regex:/^[A-Z]{3}$/';
|
||||
} elseif (str_ends_with($kind, '_drafts')) {
|
||||
foreach (['service_date','period_start','period_end','proposed_due_date'] as $field) { $rules[$field] = 'nullable|date_format:Y-m-d'; }
|
||||
if ($request->filled('period_start')) { $rules['period_end'] .= '|after_or_equal:period_start'; }
|
||||
$rules['payment_terms'] = 'nullable|string|max:1000';
|
||||
$rules['price_mode'] = 'required|in:undefined,included,added';
|
||||
$rules['units'] = 'required|array|min:1|max:100'; $rules['units.*'] = 'nullable|string|max:80';
|
||||
$rules['payment_instruction_ids'] = 'present|array|max:20'; $rules['payment_instruction_ids.*'] = 'required|integer|min:1|distinct';
|
||||
$rules['draft_version'] = 'required|integer|min:1'; $rules['currency'] = 'nullable|string|regex:/^[A-Z]{3}$/';
|
||||
}
|
||||
$data = $request->validate($rules); $data['version'] = (int) $data['version'];
|
||||
foreach ($fields as $field) { if (! array_key_exists($field, $data)) { $data[$field] = null; } }
|
||||
if (isset($data['draft_version'])) { $data['draft_version'] = (int) $data['draft_version']; $data['currency'] ??= null; $data['payment_instruction_ids'] = array_map('intval', $data['payment_instruction_ids']); }
|
||||
// Refuse obvious secret assignments in free text; no secret fields are supported.
|
||||
foreach ($data as $value) { if (is_string($value)) { abort_if((bool) preg_match('/(?:password|palavra.passe|token|secret|cvv|cvc|pin)\s*[:=]/iu', $value), 422, 'Não introduza credenciais ou segredos nas instruções.'); } }
|
||||
return response()->json($preparation->save($kind, $id, $request->user()->id, $data));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
<?php
|
||||
|
||||
namespace App\Modules\Services\Http;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Modules\Services\DocumentPreview;
|
||||
use Illuminate\Http\Request;
|
||||
|
||||
final class DocumentPreviewController extends Controller
|
||||
{
|
||||
public function calculate(Request $request, int $id, \App\Modules\Services\ServiceCalculation $calculation)
|
||||
{
|
||||
abort_if(array_diff(array_keys($request->all()), ['draft_version','preparation_version','profile_id','profile_version']) !== [], 422);
|
||||
$data = $request->validate(['draft_version'=>'required|integer|min:1','preparation_version'=>'required|integer|min:0','profile_id'=>'required|integer|min:1','profile_version'=>'required|integer|min:1']);
|
||||
return $this->response($calculation->calculate($id,$request->user()->id,array_map('intval',$data)));
|
||||
}
|
||||
private function response(array $data) { return response()->json($data)->header('Cache-Control', 'no-store, private, max-age=0')->header('Pragma', 'no-cache')->header('Vary', 'Cookie'); }
|
||||
public function model(Request $request, DocumentPreview $preview) { return $this->response($preview->configuration($request->user()->id)); }
|
||||
public function configure(Request $request, DocumentPreview $preview)
|
||||
{
|
||||
abort_if(array_diff(array_keys($request->all()), ['version', ...array_keys(DocumentPreview::DEFAULT_MODEL)]) !== [], 422, 'Campo não configurável: aviso e pendências são obrigatórios.');
|
||||
$rules = ['version' => 'required|integer|min:0', 'contact_text' => 'nullable|string|max:2000', 'observations' => 'nullable|string|max:2000'];
|
||||
foreach (['show_logo','show_contacts','show_observations','show_payment_instructions'] as $field) { $rules[$field] = 'required|boolean'; }
|
||||
$data = $request->validate($rules); $data['version'] = (int) $data['version'];
|
||||
foreach (['show_logo','show_contacts','show_observations','show_payment_instructions'] as $field) { $data[$field] = (bool) $data[$field]; }
|
||||
$data['contact_text'] ??= ''; $data['observations'] ??= '';
|
||||
return $this->response($preview->configure($request->user()->id, $data));
|
||||
}
|
||||
public function draft(Request $request, int $id, DocumentPreview $preview) { return $this->response($preview->read($id, $request->user()->id)); }
|
||||
public function historical(Request $request, int $id, DocumentPreview $preview) { return $this->response($preview->read($id, $request->user()->id, true)); }
|
||||
public function revision(Request $request, string $mode, int $id, DocumentPreview $preview)
|
||||
{
|
||||
abort_unless(in_array($mode, ['draft','history'], true), 404);
|
||||
$result = $preview->read($id, $request->user()->id, $mode === 'history');
|
||||
return $this->response(['revision' => $result['revision']]);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user