コンテンツにスキップ

組織更新

概要

APIを使用して組織を更新することができます。

事前準備

  • APIの操作を行う前にAPIキーの作成を実施してください。
  • この機能を実行するための API キーを払い出すユーザにはテナント管理者権限が付与されている必要があります。

リクエスト

下記のリクエスト形式で、jsonデータを送信します。

設定項目 値
HTTPメソッド POST
Content-Type application/json
文字コード UTF-8
URL http://{サーバ名}/api/depts/{組織ID}/update(※1)
Body 以下のjsonデータを参考のこと

(※1){サーバ名}、{組織ID}の部分は、適宜、環境に合わせて編集してください。
  pleasanter.netの場合は以下の形式になります。
  https://pleasanter.net/fs/api/depts/{組織ID}/update

設定値

設定値はスクリプトの$p.apiDeptsUpdateでも指定できます。

パラメータ名 型 必須 概要
ApiVersion decimal APIのバージョン。
ApiKey string ○1 事前に作成したAPIキー。
JSONデータレイアウト object ○ 更新する組織の情報。詳細は「JSONデータレイアウト:Dept」を参照
JSON
{
    "ApiVersion": 1.1,
    "ApiKey": "8s63Aiigd98h51Dfda7951...",
    "DeptCode": "[更新後の組織の組織コード]",
    "DeptName": "[更新後の組織の名前]",
    "Body": "[更新後の組織の説明]",
    "ClassHash": {
        "ClassA": "test-class-column"
    },
    "NumHash": {
        "NumA": 100
    },
    "DateHash": {
        "DateA": "2026-08-19"
    },
    "DescriptionHash": {
        "DescriptionA": "補足説明"
    },
    "CheckHash": {
        "CheckA": true
    }
}

レスポンス

下記の形式のjsonデータが返却されます。

JSON
{
    "Id": 12345,
    "StatusCode": 200,
    "Message": "\" 組織コード \" を更新しました。"
}

サンプルコード

Note

コード内の【 ... 】は適宜修正してください。

1. 人事CSVを正として組織マスタを同期し、廃止組織は削除せず無効化する

人事システムが出力した組織CSV(組織コード・組織名)を読み込み、現在プリザンターに登録されている組織と突合します。CSVにあってプリザンターに無い組織は新規作成し、組織名が異なる組織は更新します。プリザンターにあってCSVから消えた組織は、削除せず無効化します。

実務での使いどころ

組織改編で部門が廃止されたとき、プリザンター側の組織を削除してしまうと、次の問題が起こります。

  • 過去レコードの作成者・担当者に紐づく所属表示が失われる
  • その組織を指定していたサイトの権限設定や、分類項目の選択肢設定が壊れる
  • 誤って削除した場合、組織IDは復元できません(再作成すると別IDになります)

無効化であれば、新規の選択肢には出さずに過去データとの紐づけを保てます。組織改編は年度替わりに毎年発生するため、この判断が運用の安定性を左右します。

事前準備

1:テナント管理者権限のAPIキーを用意してください(組織操作APIの前提です)。
2:人事システム側から、以下の形式のCSVファイルを出力してください(毎回、全組織をフルで出力する形式である必要があります。差分のみを出力する形式の場合、CSVに無い=廃止と正しく判定できません)。

列名 内容
dept_code 組織コード。プリザンターの組織コードと突合するキー
dept_name 組織名
remark 説明(任意)

3:下記サンプルコードのAPI_KEY・DEPTS_CSVを環境にあわせて書き換えてください。

Python
import csv
from pathlib import Path

import requests

# ==============================
# Pleasanter 接続設定
# ==============================

BASE_URL = "【URL】"
API_KEY = "【APIキー】"

API_VERSION = 1.1

# ==============================
# ファイル設定(環境にあわせ適宜変更してください)
# ==============================
INPUT_DIR = Path("./input")
DEPTS_CSV = INPUT_DIR / "depts.csv"

# True の場合、実際の更新は行わず対象だけを出力する
DRY_RUN = False


# ==============================
# CSV入力設定(環境にあわせ適宜変更してください)
# ==============================
def read_csv(path):
    with open(path, "r", encoding="utf-8-sig", newline="") as f:
        return [
            {k.strip(): (v or "").strip() for k, v in row.items()}
            for row in csv.DictReader(f)
        ]


# ==============================
# Pleasanter API操作
# ==============================
def post_json(url, payload):
    r = requests.post(
        url,
        json=payload,
        headers={"Content-Type": "application/json"},
        timeout=60,
    )
    r.raise_for_status()
    return r.json()


# ==============================
# 組織取得
# ==============================
def get_depts():
    data = post_json(
        f"{BASE_URL}/api/depts/get",
        {"ApiVersion": API_VERSION, "ApiKey": API_KEY},
    )
    return {
        row["DeptCode"]: row
        for row in data.get("Response", {}).get("Data", [])
        if row.get("DeptCode")
    }


# ==============================
# 組織の作成
# ==============================
def create_dept(dept_row):
    payload = {
        "ApiVersion": API_VERSION,
        "ApiKey": API_KEY,
        "DeptCode": dept_row["dept_code"],
        "DeptName": dept_row["dept_name"],
        "Body": dept_row.get("remark", ""),
    }
    if DRY_RUN:
        print(f"[CREATE(dry-run)] {dept_row['dept_code']} {dept_row['dept_name']}")
        return
    post_json(f"{BASE_URL}/api/depts/create", payload)
    print(f"[CREATE] {dept_row['dept_code']} {dept_row['dept_name']}")


# ==============================
# 組織名・説明の更新
# ==============================
def update_dept(dept_id, dept_row):
    payload = {
        "ApiVersion": API_VERSION,
        "ApiKey": API_KEY,
        "DeptName": dept_row["dept_name"],
        "Body": dept_row.get("remark", ""),
    }
    if DRY_RUN:
        print(f"[UPDATE(dry-run)] {dept_row['dept_code']} {dept_row['dept_name']}")
        return
    post_json(f"{BASE_URL}/api/depts/{dept_id}/update", payload)
    print(f"[UPDATE] {dept_row['dept_code']} {dept_row['dept_name']}")


# ==============================
# 組織の無効化(CSVから消えた組織)
# ==============================
def disable_dept(dept_code, dept_id):
    payload = {
        "ApiVersion": API_VERSION,
        "ApiKey": API_KEY,
        "Disabled": True,
    }
    if DRY_RUN:
        print(f"[DISABLE(dry-run)] {dept_code}")
        return
    post_json(f"{BASE_URL}/api/depts/{dept_id}/update", payload)
    print(f"[DISABLE] {dept_code}")


# ==============================
# 更新要否の判定
# ==============================
def needs_update(existing_dept, dept_row):
    if existing_dept.get("DeptName") != dept_row["dept_name"]:
        return True
    if (existing_dept.get("Body") or "") != dept_row.get("remark", ""):
        return True
    return False


# ==============================
# メイン処理
# ==============================
def main():
    dept_rows = read_csv(DEPTS_CSV)
    depts_by_code = {row["dept_code"]: row for row in dept_rows}

    existing_depts = get_depts()

    counts = {"created": 0, "updated": 0, "disabled": 0, "unchanged": 0}

    # CSVにある組織を作成/更新
    for dept_row in dept_rows:
        dept_code = dept_row["dept_code"]
        existing = existing_depts.get(dept_code)

        if existing is None:
            create_dept(dept_row)
            counts["created"] += 1
        elif needs_update(existing, dept_row):
            update_dept(existing["DeptId"], dept_row)
            counts["updated"] += 1
        else:
            counts["unchanged"] += 1

    # CSVから消えた組織を無効化(既に無効化済みのものは対象外)
    for dept_code, existing in existing_depts.items():
        if dept_code in depts_by_code:
            continue
        if existing.get("Disabled"):
            continue
        disable_dept(dept_code, existing["DeptId"])
        counts["disabled"] += 1

    print("=== 結果 ===")
    print(f"作成: {counts['created']}件")
    print(f"更新: {counts['updated']}件")
    print(f"無効化: {counts['disabled']}件")
    print(f"変更なし: {counts['unchanged']}件")


if __name__ == "__main__":
    main()

Disabled(無効化)はマニュアルに記載の無い項目です。導入前に、使用するバージョンで同様に動作するか確認してください。

対応バージョン

対応バージョン 内容
1.5.8.0 以降 拡張項目をAPIで更新する機能を追加

エラー時の確認事項

・API使用時の注意点やエラーが発生する場合の確認事項
・FAQ:変更後の設定ファイルやAPIリクエスト(JSON形式)が正しく認識されない場合の確認事項


  1. APIキーはAPIでは指定必須。スクリプトおよびサーバスクリプトは任意指定で、指定した場合はAPIキーのユーザの権限で処理を実行。 ↩