datatype date fixed
This commit is contained in:
parent
20d4907fc5
commit
cb7851f91c
|
|
@ -130,7 +130,7 @@ public function storeContract(ClientCase $clientCase, StoreContractRequest $requ
|
||||||
// Create contract
|
// Create contract
|
||||||
$contract = $clientCase->contracts()->create([
|
$contract = $clientCase->contracts()->create([
|
||||||
'reference' => $request->input('reference'),
|
'reference' => $request->input('reference'),
|
||||||
'start_date' => date('Y-m-d', strtotime($request->input('start_date'))),
|
'start_date' => \App\Services\DateNormalizer::toDate($request->input('start_date')),
|
||||||
'type_id' => $request->input('type_id'),
|
'type_id' => $request->input('type_id'),
|
||||||
'description' => $request->input('description'),
|
'description' => $request->input('description'),
|
||||||
]);
|
]);
|
||||||
|
|
@ -169,7 +169,7 @@ public function updateContract(ClientCase $clientCase, string $uuid, UpdateContr
|
||||||
'reference' => $request->input('reference'),
|
'reference' => $request->input('reference'),
|
||||||
'type_id' => $request->input('type_id'),
|
'type_id' => $request->input('type_id'),
|
||||||
'description' => $request->input('description'),
|
'description' => $request->input('description'),
|
||||||
'start_date' => $request->filled('start_date') ? date('Y-m-d', strtotime($request->input('start_date'))) : $contract->start_date,
|
'start_date' => $request->filled('start_date') ? \App\Services\DateNormalizer::toDate($request->input('start_date')) : $contract->start_date,
|
||||||
]);
|
]);
|
||||||
|
|
||||||
$initial = $request->input('initial_amount');
|
$initial = $request->input('initial_amount');
|
||||||
|
|
|
||||||
56
app/Services/DateNormalizer.php
Normal file
56
app/Services/DateNormalizer.php
Normal file
|
|
@ -0,0 +1,56 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Services;
|
||||||
|
|
||||||
|
class DateNormalizer
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Normalize a raw date string to Y-m-d (ISO) or return null if unparseable.
|
||||||
|
* Accepted examples: 30.10.2025, 30/10/2025, 30-10-2025, 1/2/25, 2025-10-30
|
||||||
|
*/
|
||||||
|
public static function toDate(?string $raw): ?string
|
||||||
|
{
|
||||||
|
if ($raw === null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
$raw = trim($raw);
|
||||||
|
if ($raw === '') {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Common European and ISO formats first (day-first, then ISO)
|
||||||
|
$candidates = [
|
||||||
|
'd.m.Y', 'd.m.y',
|
||||||
|
'd/m/Y', 'd/m/y',
|
||||||
|
'd-m-Y', 'd-m-y',
|
||||||
|
'Y-m-d', 'Y/m/d', 'Y.m.d',
|
||||||
|
];
|
||||||
|
|
||||||
|
foreach ($candidates as $fmt) {
|
||||||
|
$dt = \DateTime::createFromFormat($fmt, $raw);
|
||||||
|
if ($dt instanceof \DateTime) {
|
||||||
|
$errors = \DateTime::getLastErrors();
|
||||||
|
if ((int) ($errors['warning_count'] ?? 0) === 0 && (int) ($errors['error_count'] ?? 0) === 0) {
|
||||||
|
// Adjust two-digit years to reasonable century (00-69 => 2000-2069, 70-99 => 1970-1999)
|
||||||
|
$year = (int) $dt->format('Y');
|
||||||
|
if ($year < 100) {
|
||||||
|
$year += ($year <= 69) ? 2000 : 1900;
|
||||||
|
// Rebuild date with corrected year
|
||||||
|
$month = (int) $dt->format('m');
|
||||||
|
$day = (int) $dt->format('d');
|
||||||
|
return sprintf('%04d-%02d-%02d', $year, $month, $day);
|
||||||
|
}
|
||||||
|
return $dt->format('Y-m-d');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Fallback: strtotime (permissive). If fails, return null.
|
||||||
|
$ts = @strtotime($raw);
|
||||||
|
if ($ts === false) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return date('Y-m-d', $ts);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -553,7 +553,8 @@ public function process(Import $import, ?Authenticatable $user = null): array
|
||||||
$payload = [
|
$payload = [
|
||||||
'account_id' => $accountIdForPayment,
|
'account_id' => $accountIdForPayment,
|
||||||
'reference' => $p['reference'] ?? null,
|
'reference' => $p['reference'] ?? null,
|
||||||
'paid_at' => $p['payment_date'] ?? ($p['paid_at'] ?? null),
|
// Normalize payment date to ISO (Y-m-d) to avoid DB parse errors
|
||||||
|
'paid_at' => \App\Services\DateNormalizer::toDate((string) (($p['payment_date'] ?? ($p['paid_at'] ?? '')))),
|
||||||
'currency' => $p['currency'] ?? 'EUR',
|
'currency' => $p['currency'] ?? 'EUR',
|
||||||
'created_by' => $user?->getAuthIdentifier(),
|
'created_by' => $user?->getAuthIdentifier(),
|
||||||
];
|
];
|
||||||
|
|
@ -1742,31 +1743,8 @@ private function sanitizeHeaderName(string $v): string
|
||||||
*/
|
*/
|
||||||
private function normalizeDate(?string $raw): ?string
|
private function normalizeDate(?string $raw): ?string
|
||||||
{
|
{
|
||||||
if ($raw === null) {
|
// Delegate to shared normalizer for consistency across the app
|
||||||
return null;
|
return \App\Services\DateNormalizer::toDate($raw);
|
||||||
}
|
|
||||||
$raw = trim($raw);
|
|
||||||
if ($raw === '') {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
$candidates = ['d.m.Y', 'd.m.y', 'd/m/Y', 'd/m/y', 'Y-m-d'];
|
|
||||||
foreach ($candidates as $fmt) {
|
|
||||||
$dt = \DateTime::createFromFormat($fmt, $raw);
|
|
||||||
if ($dt instanceof \DateTime) {
|
|
||||||
// Reject invalid (createFromFormat returns false on mismatch; partial matches handled by checking errors)
|
|
||||||
$errors = \DateTime::getLastErrors();
|
|
||||||
if (($errors['warning_count'] ?? 0) === 0 && ($errors['error_count'] ?? 0) === 0) {
|
|
||||||
return $dt->format('Y-m-d');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// Fallback: strtotime (very permissive); if fails return null
|
|
||||||
$ts = @strtotime($raw);
|
|
||||||
if ($ts === false) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
return date('Y-m-d', $ts);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private function findSourceColumnFor($mappings, string $targetField): ?string
|
private function findSourceColumnFor($mappings, string $targetField): ?string
|
||||||
|
|
|
||||||
21
tests/Unit/DateNormalizerTest.php
Normal file
21
tests/Unit/DateNormalizerTest.php
Normal file
|
|
@ -0,0 +1,21 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
use App\Services\DateNormalizer;
|
||||||
|
|
||||||
|
it('normalizes common European and ISO date formats to Y-m-d', function () {
|
||||||
|
expect(DateNormalizer::toDate('30.10.2025'))->toBe('2025-10-30');
|
||||||
|
expect(DateNormalizer::toDate('30/10/2025'))->toBe('2025-10-30');
|
||||||
|
expect(DateNormalizer::toDate('30-10-2025'))->toBe('2025-10-30');
|
||||||
|
expect(DateNormalizer::toDate('1/2/25'))->toBe('2025-02-01');
|
||||||
|
expect(DateNormalizer::toDate('2025-10-30'))->toBe('2025-10-30');
|
||||||
|
expect(DateNormalizer::toDate('2025/10/30'))->toBe('2025-10-30');
|
||||||
|
expect(DateNormalizer::toDate(' 30.10.2025 '))->toBe('2025-10-30');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('returns null for empty or invalid dates', function () {
|
||||||
|
expect(DateNormalizer::toDate(null))->toBeNull();
|
||||||
|
expect(DateNormalizer::toDate(''))->toBeNull();
|
||||||
|
expect(DateNormalizer::toDate('not-a-date'))->toBeNull();
|
||||||
|
// invalid calendar date
|
||||||
|
expect(DateNormalizer::toDate('32.01.2025'))->toBeNull();
|
||||||
|
});
|
||||||
Loading…
Reference in New Issue
Block a user