The importer UI offers "Alert on Response" as a mappable column for
category imports (app/Livewire/Importer.php, categories_fields), but
CategoryImporter only ever read use_default_eula, require_acceptance
and checkin_email. Anything the user mapped to alert_on_response was
dropped: new categories were always created with the column default,
and update-mode imports could never change it.
alert_on_response was added to the Category model in #17116, four days
after the category importer landed in #17062, and the importer's flag
list was never extended to match.
Adds it to the existing boolean-flag loop so it gets the same
fetchHumanBoolean handling and the same present/absent CSV semantics
as its three siblings.
Co-Authored-By: Claude <noreply@anthropic.com>
In update mode, AssetImporter::createAssetIfNotExists() always coerces the
requestable CSV value to a boolean and assigns it directly to the model. When
the import file has no requestable column, that coerces null to 0 and resets
the flag on every asset the update touches. The existing test suite documented
this ("RequestAble is always updated regardless of initial value.") by
commenting out the assertion instead of failing.
byod has the mirror problem: the value is coerced to int 0 before
sanitizeItemForUpdating(), which strips falsy values in update mode, so an
explicit byod=FALSE in the CSV is silently dropped and the flag can never be
cleared through an update import.
Fix: in update mode only touch either flag when the CSV actually provides a
non-blank value, and assign the coerced value directly to the model (as the
requestable line already did) so an explicit falsy value survives the
empty-value stripping. Create-mode behavior is unchanged (missing/blank still
defaults to 0).
Adds regression tests for both directions and restores the previously
commented-out assertion in update_asset_from_import().
Co-Authored-By: Claude <noreply@anthropic.com>
Sibling follow-up to #19306/#19310. UserImporter passed start_date and end_date raw
from the CSV into the User model, whose validation rules require the exact format
Y-m-d ('nullable|date_format:Y-m-d'). Any other representation of a perfectly valid
date - '07/28/2025', '28-12-2025', '2025-07-28 00:00:00' - failed validation and the
whole user row was rejected, while the same date imports fine for assets, licenses,
accessories, consumables and components.
Run both fields through the importer's existing parseOrNullDate() helper, which
parses with CarbonImmutable, normalizes to Y-m-d, logs on failure and returns null.
This also makes handleEmptyStringsForDates() (added in #19294 to fix the empty-string
symptom of the same validation failure, issue #15141) redundant - parseOrNullDate()
already returns null for empty input - so it is removed.
Adds regression tests: a non-ISO date imports as the normalized Y-m-d value, and an
unparseable date imports as null instead of rejecting the row.
Co-Authored-By: Claude <noreply@anthropic.com>
Sibling follow-up to #19306. LicenseImporter used date('Y-m-d 00:00:01', strtotime($value)) for expiration_date and termination_date; strtotime() returns false on failure and date() coerces false to timestamp 0, so unparseable dates were silently stored as 1970-01-01 instead of left empty.
Swap to the importer's existing parseOrNullDate() helper (as #19306 did for purchase_date), which parses with CarbonImmutable, logs on failure, and returns null. Both columns are cast 'date' with toDateString() setters, so valid dates are byte-identical to before; only unparseable input changes (1970-01-01 -> null).
Co-Authored-By: Claude <noreply@anthropic.com>
The base ItemImporter parsed purchase_date with date('Y-m-d', strtotime($value)).
When strtotime() cannot parse the value it returns false, which date() coerces to
timestamp 0 and silently writes 1970-01-01 instead of leaving the field empty. This
affects every item import (assets, accessories, consumables, components) and hits
common non-US inputs such as day-first '31/12/2023'.
Use the project's existing parseOrNullDate() helper - already used for last_audit_date,
next_audit_date, asset_eol_date and the checkin/checkout dates - which parses via
CarbonImmutable and returns null (logging 'Unable to parse date') on invalid input.
Valid dates are unchanged.
Co-Authored-By: Claude <noreply@anthropic.com>
The model save fires before companies are synced, so company_id is stale data, which was causing it to erroneously fail validation. the rule was always wrong in that context for updates. The form request owns this check now.