組織取得
概要¶
APIを使用して組織の内容を取得することができます。
事前準備¶
APIの操作を行う前にAPIキーの作成を実施してください。
リクエスト¶
下記のリクエスト形式で、jsonデータを送信します。
| 設定項目 | 値 |
|---|---|
| HTTPメソッド | POST |
| Content-Type | application/json |
| 文字コード | UTF-8 |
| URL | http://{サーバ名}/api/depts/get (※1) |
| Body | 以下のjsonデータを参考のこと。詳細は「JSONデータレイアウト:共通」、「JSONデータレイアウト:View」を参照してください。 |
(※1){サーバ名}の部分は、適宜、環境に合わせて編集してください。
pleasanter.netの場合は以下の形式になります。
https://pleasanter.net/fs/api/depts/get
組織情報を取得する場合¶
JSON¶
条件を指定して一致する組織情報を取得する場合¶
JSON¶
{
"ApiVersion": 1.1,
"ApiKey": "1ao3ea5kDH2335sar529UY...",
"View": {
"ColumnFilterHash": {
"Groups": "[1,2]"
}
}
}
上の例は、グループIDが1または2のグループに含まれる組織が取得されます。
レスポンス¶
下記の形式のjsonデータが返却されます。
Response部分のデータのレイアウトは「JSONデータレイアウト:Dept」を参照してください。
また、拡張項目(ClassHash/NumHash/DateHash/DescriptionHash/CheckHash)を含めて取得できます。取得できる項目の詳細は「拡張項目」を参照してください。
JSON¶
{
"StatusCode": 200,
"Response": {
"Offset": 0,
"PageSize": 200,
"TotalCount": 1,
"Data": [
{
"TenantId": 1,
"DeptId": 1,
"Ver": 1,
"DeptCode": "1234",
"DeptName": "システム開発部",
"Body": "",
"Disabled": false,
"Comments": "[]",
"Creator": 1,
"Updator": 1,
"CreatedTime": "2023-04-01T12:00:00",
"UpdatedTime": "2023-08-15T12:00:00",
"ApiVersion": 1.1,
"ClassHash": {
},
"NumHash": {
},
"DateHash": {
},
"DescriptionHash": {
},
"CheckHash": {
},
"AttachmentsHash": {
}
}
]
}
}
サンプルコード¶
Note
コード内の【 ... 】は適宜修正してください。
1. 組織の新設・廃止・名称変更を検知して、棚卸テーブルへ書き込む
組織取得APIで全組織を取得し、「棚卸テーブル」に保存した前回の状態と比べて、新設・廃止・名称変更があった組織のみを棚卸テーブルへ書き込みます。棚卸テーブルの通知(作成後・更新後)と組み合わせると、組織の変更があったときに限ってメールが届きます。変更が無い組織は書き込まないため、通知も届きません。
実務での使いどころ¶
組織の新設・統合・廃止のあと、組織を選択肢やアクセス権に使っているテーブルの設定の直し忘れを防ぎたい場面に使えます。組織の管理画面では今の組織の一覧は見られますが、前回から何が変わったかを知らせる機能はありません。夜間などに定期的に実行しておけば、変更があったときに気づけます。
事前準備¶
1:「棚卸テーブル」(記録テーブル)を作成し、以下の項目を有効化してください。
| 項目コード | 内容 |
|---|---|
| 分類A(ClassA) | 組織名 |
| 分類B(ClassB) | 組織コード(突合のキー) |
| 分類C(ClassC) | 検知した変更(新設/廃止/再開/名称変更) |
| 分類D(ClassD) | 変更前の組織名(名称変更のときのみ) |
| チェックA(CheckA) | 無効 |
| 日付A(DateA) | 検知日時 |
2:「棚卸テーブル」の「テーブルの管理 > 通知」で、通知を作成し、「作成後」と「更新後」にチェックしてください。
3:サンプルコードのBASE_URL・API_KEY・INVENTORY_SITE_IDを書き替えてください。APIキーは、全組織を取得できるテナント管理者のものを使います。
Python¶
# ==========================================================
# 組織マスタの棚卸:組織取得APIで全組織を取得し、棚卸テーブルに保存した前回の状態と比べて、
# 新設・廃止・名称変更があった組織だけを棚卸テーブルへ書き込みます。
# 棚卸テーブルの通知(作成後・更新後)と組み合わせると、組織の変更があったときだけメールが届きます。
# 変更が無い組織は書き込まないため、通知も届きません。
# ==========================================================
import datetime
import requests
# ===== 設定 =====
# APIキーは、全組織を取得できるテナント管理者のものを使ってください
BASE_URL = "【URL】"
API_KEY = "【APIキー】"
INVENTORY_SITE_ID = "【棚卸テーブルのサイトID】"
PAGE_SIZE = 200 # 1回の取得件数
BULK_UPSERT_MAX = 10000 # bulkupsertで1回に送れる件数の上限(General.jsonの既定値)
DEPT_CODE_COLUMN = "ClassB" # 組織コード(突合のキー)
DEPT_NAME_COLUMN = "ClassA" # 組織名
CHANGE_COLUMN = "ClassC" # 検知した変更(新設/廃止/再開/名称変更)
OLD_NAME_COLUMN = "ClassD" # 変更前の組織名(名称変更のときのみ)
DISABLED_COLUMN = "CheckA" # 無効(廃止)
DETECTED_AT_COLUMN = "DateA" # 検知日時
def api_post(path, payload):
"""Pleasanter APIへPOSTし、レスポンスのJSONを返す"""
response = requests.post(
f"{BASE_URL}{path}",
json={"ApiVersion": 1.1, "ApiKey": API_KEY, **payload},
headers={"Content-Type": "application/json"},
timeout=60,
)
response.raise_for_status()
return response.json()
def fetch_all(path):
"""取得件数に応じてOffsetを進めながら、全件を取得する"""
rows = []
while True:
body = api_post(path, {"Offset": len(rows), "PageSize": PAGE_SIZE})
page = body["Response"]["Data"]
rows.extend(page)
if len(page) == 0 or len(rows) >= body["Response"]["TotalCount"]:
return rows
def load_last_state():
"""棚卸テーブルに保存した前回の状態を、組織コードごとに返す"""
state = {}
for record in fetch_all(f"/api/items/{INVENTORY_SITE_ID}/get"):
class_hash = record.get("ClassHash") or {}
code = class_hash.get(DEPT_CODE_COLUMN)
if code:
state[code] = {
"name": class_hash.get(DEPT_NAME_COLUMN, ""),
"disabled": bool((record.get("CheckHash") or {}).get(DISABLED_COLUMN)),
}
return state
def detect_changes(dept, last):
"""前回の状態と比べて、変更の種類のリストを返す(変更が無ければ空)"""
if last is None:
return ["新設"]
changes = []
if dept["Disabled"] and not last["disabled"]:
changes.append("廃止")
if not dept["Disabled"] and last["disabled"]:
changes.append("再開")
if dept["DeptName"] != last["name"]:
changes.append("名称変更")
return changes
def build_bulk_data(depts, last_state, now):
"""変更があった組織のみを、bulkupsert用のData配列にする"""
data = []
for dept in depts:
code = dept.get("DeptCode")
if not code:
print(f"組織コードが空のため対象外:{dept['DeptName']}(組織ID:{dept['DeptId']})")
continue
last = last_state.get(code)
changes = detect_changes(dept, last)
if not changes:
continue
old_name = last["name"] if "名称変更" in changes else ""
data.append({
"Title": dept["DeptName"],
"ClassHash": {
DEPT_CODE_COLUMN: code,
DEPT_NAME_COLUMN: dept["DeptName"],
CHANGE_COLUMN: "・".join(changes),
OLD_NAME_COLUMN: old_name,
},
"CheckHash": {DISABLED_COLUMN: bool(dept["Disabled"])},
"DateHash": {DETECTED_AT_COLUMN: now.isoformat()},
})
print(f"{code} {dept['DeptName']}:{'・'.join(changes)}")
return data
def bulk_upsert(data):
"""組織コードをキーに、BULK_UPSERT_MAX件ずつ作成・更新する"""
for i in range(0, len(data), BULK_UPSERT_MAX):
api_post(f"/api/items/{INVENTORY_SITE_ID}/bulkupsert", {
"Keys": [DEPT_CODE_COLUMN],
"KeyNotFoundCreate": True,
"Data": data[i:i + BULK_UPSERT_MAX],
})
def main():
now = datetime.datetime.now()
depts = fetch_all("/api/depts/get")
data = build_bulk_data(depts, load_last_state(), now)
if data:
bulk_upsert(data)
print(f"組織 {len(depts)} 件のうち、変更があった {len(data)} 件を棚卸テーブルへ書き込みました。")
if __name__ == "__main__":
main()
注記¶
- 初めて実行したときは、すべての組織が「新設」として書き込まれ、組織の数と同じ件数の通知が届きます。初回は通知を無効にしておき、2回目から有効にしてください。
- 組織コードが空の組織は、突合のキーが無いため対象外です。
- 組織の階層(親子関係)の変更は検知しません。
エラー時の確認事項¶
・API使用時の注意点やエラーが発生する場合の確認事項
・FAQ:変更後の設定ファイルやAPIリクエスト(JSON形式)が正しく認識されない場合の確認事項
仕様変更について¶
※ 2019年10月よりAPIの仕様が一部変更となりました。
- 分類, 数値, 日付, 説明, チェック項目はjsonにそのまま記載する方法から「~Hash」の中に記載する方法へ変更されました。
※ 2018年11月よりAPIの仕様が一部変更となりました。
- URLの形式が '/pleasanter/api_items/xxxx' から '/pleasanter/api/items/xxxx' に変更されました。
- Content-Type の指定が'application/x-www-form-urlencoded' から 'application/json'に変更されました。
