組織更新
概要¶
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¶
サンプルコード¶
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形式)が正しく認識されない場合の確認事項
-
APIキーはAPIでは指定必須。スクリプトおよびサーバスクリプトは任意指定で、指定した場合はAPIキーのユーザの権限で処理を実行。 ↩
