Files
SGF/app/Modules/Services/DraftValues.php
T

59 lines
3.0 KiB
PHP

<?php
namespace App\Modules\Services;
use Brick\Math\BigDecimal;
use Illuminate\Support\Facades\DB;
use Illuminate\Validation\ValidationException;
final class DraftValues
{
public static function decimal(mixed $value, string $field, bool $positive = false): ?string
{
if ($value === null || $value === '') { return null; }
if (! is_string($value) || ! preg_match('/^(0|[1-9][0-9]{0,15})(\.[0-9]{1,8})?$/D', $value)) {
throw ValidationException::withMessages([$field => 'Use uma cadeia decimal com ponto, até 16 algarismos inteiros e 8 decimais; sem expoentes ou arredondamento.']);
}
$decimal = BigDecimal::of($value);
if ($positive && $decimal->isLessThanOrEqualTo(BigDecimal::zero())) { throw ValidationException::withMessages([$field => 'A quantidade deve ser superior a zero quando preenchida.']); }
return (string) $decimal->stripTrailingZeros();
}
public static function lines(array $lines, array $scope): array
{
$result = [];
foreach ($lines as $index => $line) {
$service = DB::table('a_services')->where('tenant_id', $scope['tenant_id'])->where('company_id', $scope['company_id'])->where('id', $line['service_id'])->first();
abort_unless($service, 403, 'Serviço fora da empresa autorizada.');
$result[] = ['service_id' => (int) $service->id, 'service_name' => $service->name,
'description' => $line['description'] ?? null,
'quantity' => self::decimal($line['quantity'] ?? null, "lines.$index.quantity", true),
'unit_price' => self::decimal($line['unit_price'] ?? null, "lines.$index.unit_price")];
}
return $result;
}
public static function pending(array $data): array
{
$pending = ['tax_rule_pending' => 'Imposto por definir e validar; não foi considerado zero.',
'accounting_rule_pending' => 'Regras contabilísticas por validar; nenhum lançamento foi produzido.'];
if (empty($data['currency'])) { $pending['currency_missing'] = 'Moeda não indicada; nenhuma moeda foi presumida.'; }
else { $pending['currency_validation_pending'] = 'Moeda indicada pelo utilizador; a sua aplicabilidade e a moeda funcional continuam por validar.'; }
foreach ($data['lines'] as $index => $line) {
if ($line['quantity'] === null) { $pending["quantity_missing_$index"] = 'Quantidade por preencher na linha '.($index + 1).'.'; }
if ($line['unit_price'] === null) { $pending["price_missing_$index"] = 'Preço proposto por preencher na linha '.($index + 1).'.'; }
}
return $pending;
}
public static function base(array $data): ?string
{
$sum = BigDecimal::zero();
foreach ($data['lines'] ?? [] as $line) {
if ($line['quantity'] === null || $line['unit_price'] === null) { return null; }
$sum = $sum->plus(BigDecimal::of($line['quantity'])->multipliedBy($line['unit_price']));
}
return (string) $sum->stripTrailingZeros();
}
}