# 機能設計書 102-タイムシート管理

## 概要

本ドキュメントは、タイムシートプラグイン(timesheets)におけるタイムシート管理機能の設計仕様を定義する。

### 本機能の処理概要

プロジェクトおよびタスクに対する作業時間を記録・管理し、工数の可視化と分析を可能にする機能を提供する。

**業務上の目的・背景**：プロジェクトベースの業務において、各タスクにどれだけの時間が費やされたかを正確に記録することは、プロジェクト管理・原価管理・生産性分析において不可欠である。タイムシート機能により、従業員が作業時間を簡単に記録し、管理者がプロジェクト全体の工数を把握できる。

**機能の利用シーン**：
- 従業員が日々の作業時間を記録する
- プロジェクトマネージャーがチームの工数を確認・分析する
- 経理部門が請求可能時間を集計する

**主要な処理内容**：
1. タイムシートエントリの作成・編集・削除
2. プロジェクト・タスク別の作業時間記録
3. 従業員別・日付別の作業時間表示
4. 作業時間の集計（Sum機能）
5. 日付範囲・プロジェクト・タスク・従業員でのフィルタリング

**関連システム・外部連携**：projectsプラグインのTask、Projectモデルと連携。タイムシート記録時にタスクの工数情報（effective_hours、remaining_hours等）を自動更新する。

**権限による制御**：認証済みユーザーのみアクセス可能。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| SCR-TS-001 | TimesheetResource | 主画面 | タイムシート一覧表示・作成・編集・削除 |

## 機能種別

CRUD操作 / トランザクション記録

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| type | string | Yes | タイプ(隠しフィールド) | 固定値'projects' |
| date | date | Yes | 作業日 | 日付形式 |
| user_id | integer | Yes | 従業員ID | usersテーブルに存在するID |
| project_id | integer | Yes | プロジェクトID | projectsテーブルに存在するID |
| task_id | integer | Yes | タスクID | 選択されたproject_idに属するタスク |
| name | string | No | 説明 | - |
| unit_amount | float | Yes | 作業時間(時間単位) | 数値、0以上、最大99999999999 |

### 入力データソース

画面フォーム入力、Timesheetモデル

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| id | integer | タイムシートID |
| date | date | 作業日 |
| user.name | string | 従業員名 |
| project.name | string | プロジェクト名 |
| task.title | string | タスク名 |
| name | string | 説明 |
| unit_amount | float | 作業時間(時間:分形式で表示) |
| created_at | datetime | 作成日時 |
| updated_at | datetime | 更新日時 |

### 出力先

Filamentテーブル画面、データベース(analytics_records / projects_timesheets)

## 処理フロー

### 処理シーケンス

```
1. タイムシート一覧表示
   └─ type='projects'のレコードをフィルタして表示
2. タイムシート作成
   └─ フォーム入力 → バリデーション → DBへ保存 → タスク工数自動更新
3. タイムシート編集
   └─ 既存データ取得 → フォーム表示 → 更新保存 → タスク工数自動更新
4. タイムシート削除
   └─ 削除確認 → 物理削除 → タスク工数自動更新
```

### フローチャート

```mermaid
flowchart TD
    A[開始] --> B[タイムシート一覧表示]
    B --> C{操作選択}
    C -->|作成| D[作成フォーム表示]
    C -->|編集| E[編集フォーム表示]
    C -->|削除| F[削除確認]
    D --> G[プロジェクト選択]
    G --> H[タスク一覧更新]
    H --> I[入力バリデーション]
    E --> I
    I -->|OK| J[DB保存]
    I -->|NG| K[エラー表示]
    F --> L[物理削除]
    J --> M[タスク工数更新]
    L --> M
    M --> N[成功通知]
    K --> C
    N --> B
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-102-01 | プロジェクト連動タスク | プロジェクト変更時にタスク選択をリセット | プロジェクト変更時 |
| BR-102-02 | タスク工数自動更新 | タイムシート作成/更新/削除時にタスクのeffective_hours等を自動計算 | CUD操作時 |
| BR-102-03 | 時間表示形式 | unit_amountを時間:分形式で表示 | 一覧表示時 |
| BR-102-04 | グループ集計 | グループ化時に作業時間の合計を表示 | グループ化時 |

### 計算ロジック

タスク工数の自動更新(Timesheet::updateTaskTimes):
```
effective_hours = 当該タスクのタイムシート合計
total_hours_spent = effective_hours + サブタスクのタイムシート合計
remaining_hours = allocated_hours - total_hours_spent
overtime = total_hours_spent > allocated_hours ? total_hours_spent - allocated_hours : 0
progress = allocated_hours ? (total_hours_spent / allocated_hours) * 100 : 0
```

時間表示形式:
```
hours = floor(unit_amount)
minutes = (unit_amount - hours) * 60
表示 = hours:minutes
```

## データベース操作仕様

### 操作別データベース影響一覧

| 操作 | 対象テーブル | 操作種別 | 概要 |
|-----|-------------|---------|------|
| 一覧表示 | analytics_records | SELECT | type='projects'でフィルタ |
| 作成 | analytics_records | INSERT | 新規タイムシート登録 |
| 作成後 | projects_tasks | UPDATE | タスクの工数フィールド更新 |
| 編集 | analytics_records | UPDATE | 既存タイムシート更新 |
| 編集後 | projects_tasks | UPDATE | タスクの工数フィールド更新 |
| 削除 | analytics_records | DELETE | 物理削除 |
| 削除後 | projects_tasks | UPDATE | タスクの工数フィールド更新 |

### テーブル別操作詳細

#### analytics_records (Timesheet継承元)

| 操作 | 項目（カラム名） | 更新値・取得条件 | 備考 |
|-----|-----------------|-----------------|------|
| INSERT | type | 'projects' | 固定値 |
| INSERT | date | ユーザー入力値 | 必須 |
| INSERT | user_id | 選択値 | 必須 |
| INSERT | project_id | 選択値 | 必須 |
| INSERT | task_id | 選択値 | 必須 |
| INSERT | name | ユーザー入力値 | 任意 |
| INSERT | unit_amount | ユーザー入力値 | 必須 |

#### projects_tasks (自動更新)

| 操作 | 項目（カラム名） | 更新値・取得条件 | 備考 |
|-----|-----------------|-----------------|------|
| UPDATE | effective_hours | タイムシート合計 | 計算値 |
| UPDATE | total_hours_spent | effective_hours + サブタスク合計 | 計算値 |
| UPDATE | remaining_hours | allocated_hours - total_hours_spent | 計算値 |
| UPDATE | overtime | 超過時間 | 計算値 |
| UPDATE | progress | 進捗率 | 計算値(%) |

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| E-102-01 | バリデーションエラー | 必須項目未入力 | エラーメッセージ表示 |
| E-102-02 | バリデーションエラー | unit_amountが負の値 | エラーメッセージ表示 |
| E-102-03 | 参照エラー | 存在しないプロジェクト/タスク選択 | エラーメッセージ表示 |

### リトライ仕様

特になし(画面操作による再実行)

## トランザクション仕様

タイムシートの作成・編集・削除とタスク工数の更新は同一トランザクション内で実行される（Eloquentイベントによる自動処理）。

## パフォーマンス要件

- 一覧表示: 2秒以内
- 作成/編集/削除: 1秒以内
- 集計計算: リアルタイム表示

## セキュリティ考慮事項

- 認証済みユーザーのみアクセス可能
- プロジェクト/タスクの参照権限チェック

## 備考

- TimesheetモデルはWebkul\Analytic\Models\Recordを継承
- タイムシート操作のイベントフック(created/updated/deleted)でタスク工数を自動更新
- unit_amountは時間単位(小数点以下は分として計算)
