## Context

`contract_position` was introduced by the archived change `add-contract-position`. Contract documents now read `employee_position` from `employee->contract_position` (`app/Models/Field.php`), so a blank value prints a blank position on contracts.

Current behaviour on creation:

- `EmployeeController::store()` falls back to `$model->positions()->first()->name` only when `!request()->has('contract_position')`. Requests go through `TrimStrings` and `ConvertEmptyStringsToNull`, so `""` and `"   "` arrive as `null`. However, `has()` is still true, so no fallback happens and `null` is stored.
- `EmployeeController::import()` builds `'contract_position' => $cell ?? ''` with no fallback and no trim. Before that, it resolves `$positionName`: an unknown or empty "Vị trí" falls back to `Position::getDefault()`, and the row is skipped if there is still no position. `Account::createAccount()` later syncs that position by name.

## Goals / Non-Goals

**Goals:**
- A newly created employee never ends up with a blank `contract_position` when a position is assigned.
- Store and import use one rule: blank means "use the assigned position's name".

**Non-Goals:**
- Changing update behaviour. Clearing the field on update stays allowed, per the existing "independent of current position" requirement.
- Changing `updateMulti`, which has no contract position column.
- Backfilling existing employees whose `contract_position` is already blank.
- Adding a fallback at contract render time.

## Decisions

**1. "Blank" is judged on the value, not on key presence.**
In `store()`, replace `!request()->has('contract_position')` with `blank($employeeData['contract_position'] ?? null)`. This uses the validated data, and `blank()` covers missing, `null`, `''` and whitespace-only values. Excel always contains the column, so key presence is meaningless there. Using a value check in both flows keeps them aligned.
*Alternative:* keep `has()` and ask FE to omit the key. Rejected because it is fragile and leaves the API inconsistent with import.

**2. Import defaults to the resolved `$positionName`.**
Use the position name after the default-position fallback, which is exactly the position `createAccount()` assigns. This mirrors `store()`, which uses the actually synced position.
*Alternatives:* use the raw "Vị trí" text, which may name a non-existent position and would mismatch the assigned one; or leave it blank when "Vị trí" was invalid, which reproduces the blank-contract bug. Both rejected.

**3. Trim the "Vị trí HĐ" cell.**
Use `trim($cell ?? '')`, consistent with how "Vị trí" is read. A whitespace-only cell counts as blank.

**4. Keep the logic inline in each flow; no shared helper.**
Each site is one to two lines, and their position sources differ: a synced relation in store, a resolved name string in import. A helper would add indirection without removing real duplication.
*Alternative:* move the default into `Account::createAccount()`. Rejected because that method is generic (also used with faker or seeding) and is not where the import's business rules live.

## Risks / Trade-offs

- [A client that intentionally sent `null` to keep `contract_position` empty on create will now get the position name instead.] → This is the intended behaviour. An empty contract position at creation is the bug being fixed.
- [`positions()->first()` order is not explicitly defined when several positions are assigned.] → Behaviour is unchanged from today's fallback. The admin can override `contract_position` explicitly.
- [Update can still blank the field, so contracts can still print blank for edited employees.] → Accepted (decision to keep update independent). It is covered by an explicit scenario, so no one "fixes" it accidentally.
