==================================== zsystem.jp 作業記録 2026年05月 ==================================== ------------------------------------ 2026-05-01 作業者: Claude (claude-sonnet-4-6) 対象: letip/salesreport/ ------------------------------------ 【バグ修正】月切り替え時に担当者リストが更新されない問題 - 原因: ページ初期表示時にカレント月のデータから担当者ドロップダウンを生成しており、 月セレクタ変更後もドロップダウンが再構築されなかった。 5月1日起動→4月に切り替えると担当者がゼロのままとなり個人データが参照不可。 - 対応: - index.php に getChargers モードを追加(年・月を受け取り担当者一覧をJSONで返す) - salesreport.js に updateChargers() / onYearMonthChange() を追加 - 年・月セレクタ変更時は担当者リストを再取得してからレポートを更新する順序に変更 - 選択中担当者が新月に存在しない場合は自動的に「全体」にリセット 【UI調整】テーブル列幅・スタイル変更 - 区分列(sub-label)幅: 52px → 35px(約2/3) - 資産元列(src-label)幅: 76px → 51px(約2/3)、連動して sticky left 値も更新 - 月計列左右ボーダー色: #88a → #000(黒) - カテゴリー列背景色廃止(#f5f5e0 → #fff) - ヘッダー日付行・曜日行間のボーダー削除(thead tr:last-child th { border-top: none }) - カテゴリーブロック間に太い黒ボーダー追加(.grp-start td { border-top: 2px solid #000 }) - 月計ヘッダー下ボーダーを他と統一(thead tr:first-child th.total-col に border-bottom 追加) 【新機能】年度内月計チェックボックス - 背景・目的: 月単位の月計列を年度開始(4月)から選択月までの複数月計列に切り替えて 年度内の推移を一覧できるようにする。 - menubar 右上に「年度内月計」チェックボックスを追加 - チェック時のテーブルレイアウト: [カテゴリー][区分][資産元][年度合計][4月計][5月計]…[N月計][1日][2日]…[31日] - 年度合計列: チェック範囲内の全月合計値を表示 - 月計列の表示範囲: 選択月と現在月の遅い方まで(例: 4月選択・現在5月→4月計+5月計) - カレント月(選択中の月)のみ #eef 背景で強調、その他月・年度合計は背景なし - 実装: index.php に fetchMonthTotals() / YTDヘルパー関数群を追加、 renderCatBlock / renderSumBlock / renderPendingRows を YTD 対応に拡張 【その他修正】 - getChargers の権限チェックを getReport / getDetail と同様の CheckPermission('150') に統一 - .ytd-col CSS: border 2px solid #000、カレント月は .ytd-cur で背景 #eef デプロイ: 未実施(指示待ち) ------------------------------------ 2026-05-07〜08 letip/salesstock/buyingmng + pack_archive 重複問題対応 ------------------------------------ 【1. buyingmng Excel取込: 消費税行誤登録の修正】 目的: ウェルファン出荷実績Excel末尾の「消費税10%」行が発注明細として誤登録される事象の修正。 背景: - ウェルファンExcelの最終行は「消費税10%」など合計行で、品名=消費税表記、JAN=なし、単価=0、数量=空 等のメタデータ的な行 - 既存ロジックは「発注日」列が undefined になるまでループしていたが、消費税行も発注日が入っているため除外されず addBulkDetail に流れていた 修正内容: letip/salesstock/buyingmng/buyingmng.js(ウェルファンXLSXループ内に判定追加) if((price==0 || price=='' || price==null) && (productname.indexOf('消費税')!=-1 || jan=='')){ continue; } ロジック: 「単価0/空」AND「品名に消費税 OR JAN空」の場合に行をスキップ。 → 消費税行・送料行を除外しつつ、「消費税対応レジ用紙」のような単価>0の正当商品は残す。 検証: xlsx 0.17.0(buyingmng.htmlがCDN参照する版と同一)でNode.js上で再現テスト実装。 実ファイル(ウェルファン出荷実績_20260507.xlsx)で 修正前=5件(うち消費税1) → 修正後=4件、JAN/単価/数量不変。 エッジケース8件すべてPASS(消費税のみ、単価0、JAN空、送料、混在等)。 デプロイ: 完了(zsystem.jp:/Users/zadmin/Sites/letip/salesstock/buyingmng/buyingmng.js、md5一致)。 【2. pack_archive 重複問題の根本原因究明】 目的: 「pack_archive 作成プロセスが1日2回動作していないか」の確認依頼に端を発する全面調査。 調査結果: - cron は 0 0 * * * /Users/zadmin/Sites/letip/packbackup.php の1本のみ(重複起動なし) - packbackup.log でも各日1回実行のみ確認 - しかし pack_archive の divisioncode 別行数が 2026/04/03 を境に約9,300 → 約18,600(pack行数の2倍)に倍増 - 重複行は (divisioncode, packno, timestamp) 全カラム完全一致 根本原因(致命的なスキーマ不整合): - pack_archive.divisioncode は char(10) なのに、packbackup.php は '$timestamp 00:00:00'(19文字)を書き込もうとしていた - MySQL は10文字に切り詰めて格納 → 実データは '2026/05/07'(時刻なし) - 結果として: ・DELETE WHERE divisioncode='2026/05/07 00:00:00' → 格納値とマッチせず0件削除 ・REPLACE INTO pack_archive SELECT * FROM pack → pack_archive にPRIMARY/UNIQUE制約なしのため毎回追加(INSERT同等) ・UPDATE WHERE divisioncode='' → 切り詰め格納で '2026/05/07' に - 同日内で何らかの理由(手動実行 or Web経由のアクセス等)で2回目が走ると、DELETEが空振りで重ね追加 → 2倍化 ローカルテーブル(pack_test/pack_archive_test)で再現テスト実施し、現状ロジックでは「同日2回実行で6行(=2倍)」になることを実証。 スキーマ差分(pack_archive char系 vs pack varchar系)22カラムが該当。 【3. packbackup.php の修正】 目的: 上記DELETE/UPDATE文の不整合解消。新規重複の発生を停止。 修正内容: letip/packbackup.php $sql="DELETE FROM pack_archive WHERE divisioncode='$timestamp 00:00:00'"; → '$timestamp' $sql="UPDATE pack_archive SET divisioncode='$timestamp 00:00:00' ..."; → '$timestamp' 検証(ローカルテーブル): 修正後は同日2回実行でも DELETE が3件削除→REPLACEで3件追加→冪等。 デプロイ: 完了(md5: 5e2f75532f138bca9af32841cc7f1a40)。 動作確認: 5/8 0:00 cron実行で 2026/05/08 行数 = 9,311(単一セット、重複なし)を確認。 【4. pack_archive 既存重複データのクリーンアップ】 目的: 4/3〜5/7の34日分(1日約9,300行 × 2倍重複)を1日約9,300行に正常化。 手法(per-day、ロールバック容易): CREATE TEMPORARY TABLE pack_archive_dedup_tmp LIKE pack_archive; INSERT INTO pack_archive_dedup_tmp SELECT DISTINCT * FROM pack_archive WHERE divisioncode='YYYY/MM/DD'; DELETE FROM pack_archive WHERE divisioncode='YYYY/MM/DD'; INSERT INTO pack_archive SELECT * FROM pack_archive_dedup_tmp; 経緯: - 当初「全件 SELECT DISTINCT * 」で再構築する案を試みたが、5.4M行のtmpテーブル作成が18分超+他クエリ全ブロックの状態に → KILL - ユーザー判断「Time Machineバックアップあるので個別バックアップは省略」「日次バッチで」 - 緊急で必要な 4/01(重複なし、対応不要)と 5/01 を先に処理 - 残り32日分(4/04〜4/30、5/02〜5/07)を 5/7 22:41〜23:14 に夜間バッチで実行(カットオフ23:00→23:30に延長) - 各日 25秒〜2分、load 0.15〜0.61で安定 結果: - 全34日分の重複削除完了 - pack_archive 行数: 5,427,936 → 5,111,183(316,753行削減、約半分) - HAVING c>12000 の異常日は0件 スクリプト: /Users/zadmin/dedup_pack_archive.sh, dedup_pack_archive2.sh ログ: /Users/zadmin/dedup_progress_*.log 【5. pack_archive スキーマを pack に合わせる ALTER TABLE】 目的: 同種の不整合を将来発生させないため、pack_archive の char系カラムを pack の varchar系に揃える。 実施内容: 22カラム一括 ALTER TABLE(5/7 23:16〜5/8 00:27、所要1時間11分) divisioncode char(10) → varchar(32) packno char(10) → varchar(12) productcode/productname/locate/invoiceno/shipno/pullno/actualcode/assets/client/attention/comment/remark1/remark2 等 char→varchar orderno char(32) → varchar(64)(長さ拡張) uniquecode char(64) → varchar(64) preparedate datetime NOT NULL → デフォルト '0000-00-00 00:00:00' 追加 JAN varchar(13) → varchar(15) ALTER 中は packbackup(0:00 cron)が「Locked」でqueue状態だったが、ALTER完了後に自動再開。5/8分の記録は正常生成。 ⚠ 漏れ: standard カラム (char(64) のまま、pack側はvarchar(64))。 影響: pack側標準64文字値を pack_archive に書き込む際 char に切り詰め発生のみ(実害は最小)。後日対応保留。 【教訓】 - divisioncode/packno等 char(10) は19文字datetime文字列を黙って切り詰める。スキーマと書き込み文字列の長さ整合性は要確認 - ユニーク制約のないテーブルへの REPLACE INTO は INSERT 同等になるため期待動作と異なる - 大規模テーブル(5M行)の SELECT DISTINCT * は tmp テーブル化で全テーブルロックを引き起こす危険あり、per-batch化必須 - ALTER TABLE on MyISAM は変更カラム数に関わらず1回再書き出しなので、まとめて1ステートメントで実行するのが効率的