{
  "display_name": "在庫調整インポート",
  "description": "在庫の調整（棚卸結果反映、初期在庫登録等）をCSVで一括処理。調整数（増減値）を入力する方式。",
  "processor_class": "App\\Services\\Logic\\User\\CsvImport\\SingleTable\\InventoryAdjustmentImportProcessor",
  "call_process_row": false,
  "import_behavior": "all_or_nothing",
  "supported_modes": ["insert"],
  "fields": {
    "product_code": {
      "label": "商品コード",
      "type": "string",
      "required": true,
      "max_length": 40,
      "validation_rules": [
        "required",
        "string",
        "max:40"
      ],
      "description": "調整対象の商品コード"
    },
    "warehouse_code": {
      "label": "倉庫コード",
      "type": "string",
      "required": true,
      "max_length": 20,
      "validation_rules": [
        "required",
        "string",
        "max:20"
      ],
      "description": "調整対象の倉庫コード"
    },
    "lot_number": {
      "label": "ロット番号",
      "type": "string",
      "required": false,
      "max_length": 50,
      "validation_rules": [
        "string",
        "max:50"
      ],
      "description": "ロット番号（BE品の場合は必須）"
    },
    "expiration_date": {
      "label": "賞味期限",
      "type": "date",
      "required": false,
      "format": "Y-m-d",
      "validation_rules": [
        "date"
      ],
      "description": "賞味期限（BE品の場合は必須、YYYY-MM-DD形式）"
    },
    "adjustment_quantity": {
      "label": "調整数",
      "type": "decimal",
      "required": true,
      "validation_rules": [
        "required",
        "numeric"
      ],
      "description": "調整する数量（正数=入庫/在庫増加、負数=出庫/在庫減少）"
    },
    "reason": {
      "label": "調整理由",
      "type": "string",
      "required": false,
      "max_length": 500,
      "validation_rules": [
        "string",
        "max:500"
      ],
      "description": "調整理由（任意）"
    }
  },
  "foreign_key_mappings": {
    "product_code": {
      "reference_table": "products",
      "reference_key_column": "product_code",
      "reference_value_column": "id",
      "required": true,
      "error_message": "商品コード「{value}」が商品マスタに存在しません"
    },
    "warehouse_code": {
      "reference_table": "warehouses",
      "reference_key_column": "warehouse_code",
      "reference_value_column": "id",
      "required": true,
      "error_message": "倉庫コード「{value}」が倉庫マスタに存在しません"
    }
  },
  "code_padding": {
    "product_code": 8,
    "warehouse_code": 3
  },
  "business_rules": {
    "be_product_expiration_required": {
      "rule": "if product_type=2 AND stock_control_type=1 then expiration_date required",
      "error_message": "BE品の場合、賞味期限は必須です"
    },
    "negative_after_quantity_check": {
      "rule": "current_quantity + adjustment_quantity >= 0",
      "error_message": "調整後在庫がマイナス（{after_quantity}）になります。調整数を確認してください"
    },
    "allocation_check": {
      "rule": "current_quantity + adjustment_quantity >= allocated_quantity",
      "error_message": "調整後在庫数（{after_quantity}）が引当済み数量（{allocated_quantity}）を下回っています"
    }
  },
  "error_codes": {
    "E001": {
      "type": "format",
      "message": "必須カラム「{column}」がCSVに含まれていません"
    },
    "E002": {
      "type": "master",
      "message": "商品コード「{code}」が見つかりません"
    },
    "E003": {
      "type": "master",
      "message": "倉庫コード「{code}」が見つかりません"
    },
    "E004": {
      "type": "lot",
      "message": "BE品のため賞味期限は必須です"
    },
    "E005": {
      "type": "quantity",
      "message": "調整数は数値で指定してください"
    },
    "E006": {
      "type": "allocation",
      "message": "調整後在庫数（{after_quantity}）が引当済み数量（{allocated_quantity}）を下回っています"
    },
    "E010": {
      "type": "quantity",
      "message": "調整後在庫がマイナス（{after_quantity}）になります。調整数を確認してください"
    },
    "E011": {
      "type": "duplicate",
      "message": "同じ商品・倉庫・ロットの行が{row_number}行目にもあります。1行にまとめてください"
    }
  },
  "csv_format_example": {
    "description": "在庫調整用CSVフォーマット。調整数は正数=入庫、負数=出庫。BE品はロット番号・賞味期限が必須。",
    "headers": [
      "商品コード",
      "倉庫コード",
      "ロット番号",
      "賞味期限",
      "調整数",
      "調整理由"
    ],
    "sample_data": [
      ["GT-101", "WH01", "", "", "100", "初期在庫登録（入庫）"],
      ["GT-201", "WH01", "LOT2025001", "2025-06-30", "-50", "棚卸差異（出庫）"],
      ["GT-301", "WH02", "", "", "0", "変更なし確認"]
    ]
  }
}
