受注編集: 削除明細のスロット再利用が起きる根本原因(コレクションキー衝突)の解消
- Dominant language
- PHP
- Stars
- 788
- Forks
- 719
- Avg merge
- 4d 4h
- Merged PRs (30d)
- 39
Description
## 背景
PR #6926 (Closes #6444) は、受注編集で明細の最終行を削除し保存せずに明細を追加したとき、削除した明細の派生値(税表示区分・規格情報・`processor_name`・Shipping 紐付け)が新しい明細に引き継がれる問題を修正した。
ただし #6926 は「コアが把握している派生フィールドを明細種別・ProductClass の変化時にクリアする」**対症療法**であり、根本原因そのものは残っている。
## 根本原因
未保存の明細削除は DB に反映されないため、再計算・明細追加のたびにサーバは DB から全明細を読み直す。再描画されるフォームは削除行を詰めて再採番するため、次に追加する明細のコレクションキーが **DB に残ったままの削除対象 `OrderItem` のキーと衝突**し、新しい明細のデータが既存エンティティに上書きバインドされる(既存エンティティは id を持つため、`OrderType::associateOrderAndShipping` の従来の「id 有無」判定でも既存扱いになっていた)。
## 対症療法で塞ぎきれない範囲
#6926 のクリアはコアが把握しているフィールドの denylist のため、**`app/Customize`・プラグインが `OrderItem` にトレイトで追加した拡張フィールドは引き継がれ続ける**。#6444 の報告者は規格商品のフィールドを拡張したカスタム環境が発端であり、その環境では拡張フィールドの引き継ぎが残る可能性がある。
## 提案(未検証)
新しく追加する明細のコレクションキーを、DB に残る既存明細のキーと衝突しない値(`new_0` 等)にすれば、キー衝突自体が起きず拡張フィールドも含めてまとめて直る。`associateOrderAndShipping` でも新規扱いになる。
ただし再描画後の JS の index 算出(`src/Eccube/Resource/template/admin/Order/edit.twig:107-112` の `row.replace(formIdPrefix, '')` → 以降の `index--`)が文字列キーで NaN になるため、そこも合わせて直す必要がある。**本方針は未検証**のため、回帰テストとセットで実測して確定する。
## 参考
- PR #6926 / Issue #6444
- レビュー: https://github.com/EC-CUBE/ec-cube/pull/6926 (@nanasess のコメント)
Contributor guide
Research direction
Start with src/Eccube/Resource/template/admin/Order/edit.twig:107-112 and the OrderType::associateOrderAndShipping flow described in the issue. Reproduce deletion, unsaved save, recalculation, and line addition to verify whether a nonnumeric collection key avoids collisions and whether the JavaScript index logic handles it. Add regression coverage for core and extended OrderItem fields, then confirm the existing association behavior remains correct.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- javascript, php, symfony
- Domain
- backend, frontend, full-stack
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Quiet
- Clarity
- Mostly clear
- Newbie friendliness
- 52/100