59 lines
3.0 KiB
PHP
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();
|
|
}
|
|
}
|