メインコンテンツへスキップ
見出し画像

契約はどの資産を守るか(ast_contract)


    前回の記事で、資産の台帳 alm_asset を実機で読みました。資産には「いつ・いくらで・誰が買い、誰に割り当てるか」という調達の情報が乗りますが、その資産が「どのベンダとの、いつからいつまでの契約で守られているか」は alm_asset 単体には入りません。これを持つのが契約のテーブル ast_contract です。

    ServiceNow では、リース・保守・ライセンスといった契約を ast_contract という1つの基底テーブルで管理し、契約が守る資産(alm_asset)を中間テーブルで結びつけます。この記事は、実機の ast_contract を起点にします。State(draft / active / expired / cancelled)、契約期間(starts / ends)、種別の持ち方(sys_class_name)、そして Asset との紐づけ(clm_m2m_contract_asset)を順番に確認します。

    ServiceNow の Incident は触ったことがある管理者・開発者を想定しています。前回 alm_asset を読んだうえで「契約はどのテーブルに、どう資産とつながって入っているのか」を確認したい人が対象です。

    この記事で分かること

    • ast_contract がルート基底テーブルで、直下に Service Contract / Lease / Warranty の3クラスを持つこと

    • State が draft / active / expired / cancelled の4値で、終了日(ends)と連動して動くこと

    • 契約と資産は直接ではなく中間テーブル clm_m2m_contract_asset(Asset Covered)で多対多に結びつくこと

    • contract_model と vendor_contract が今回の PDI で必須だったこと

    • 更新(renewable / renewal_date / renewal_options)とコスト(total_cost / monthly_cost / yearly_cost)の持ち方

    • 実機で確認するときに見るべき一覧URL

    この記事の内容は ServiceNow の PDI(Personal Developer Instance)Zurich(ズーリッヒ)リリースの OOTB(初期設定)で確認した個人メモです。本番環境やカスタマイズ済み環境では、クラス構成・フィールド・状態設定の内容が異なる場合があります。


    契約管理(Contract Management)とは

    契約管理は、組織が結んだ契約(リース・保守・サポート・ソフトウェアライセンスなど)を、相手・期間・金額・更新条件とともに登録し、期限切れや更新を取りこぼさないように管理する仕組みです。資産管理(alm_asset)が「モノ」の台帳なのに対し、契約管理は「そのモノを守る取り決め」の台帳にあたります。

    ServiceNow では、この契約を格納する中心テーブルが ast_contract です。公式の Contract Management では、ast_contract をプラットフォーム上の契約の基底レコードと位置づけ、IT Asset Management の一部として説明しています。

    契約と資産は別テーブルで持ち、その間を中間テーブルでつなぎます。


    画像

    今回確認した PDI(Zurich / OOTB)では、契約フォームの「Assets Covered」関連リストの実体が clm_m2m_contract_asset で、その行が contract(ast_contract)と asset(alm_asset)の両方を参照していました。1つの契約が複数の資産を守り、1つの資産が複数の契約に守られることもあります。そのため、両者は中間テーブルを挟んだ多対多になります。


    ast_contract は契約クラス階層のルート

    ast_contract は継承元を持たないルート基底テーブルで、直下に3つの子クラスを持ちます。


    画像

    今回確認した PDI(Zurich / OOTB)では、ast_contract は super_class(継承元)が空のルート基底テーブルで、直下の子クラスは3件でした。

    • ast_service(Service Contract) … サービス・保守の契約

    • ast_lease(Lease) … リース契約

    • ast_warranty(Warranty) … 保証契約

    契約の「種別」は、選択肢フィールドではなくクラス(テーブル)で表します。フォーム上で「Contract type」と表示される項目の実体は sys_class_name で、その契約がどのクラスのレコードかを示します。type や contract_type という choice フィールドを探すと空(選択肢なし)でした。種別を増やす設計が、選択肢の追加ではなくテーブル継承で行われている点が alm_asset の子クラス(alm_hardware など)と同じ作りです。

    なお今回の PDI では、ast_service / ast_lease / ast_warranty の3クラスはレコード0件で、111件の契約はすべて基底 ast_contract(sys_class_name=ast_contract)として登録されていました。OOTB のサンプルデータが基底クラスに寄っているためで、子クラスを使うかどうかは運用次第です。

    クラス階層は、次のURLで確認できます(先頭の <YourInstance> は自分のインスタンスに置き換えてください)。

    https://<YourInstance>/sys_db_object_list.do?sysparm_query=super_class.name=ast_contract

    ast_contract の主なフィールド

    ast_contract は、契約に共通する項目を持ちます。役割で分けると、識別・相手・期間・状態・コスト・更新に整理できます。


    画像

    押さえておきたいのは次の点です。

    契約の相手と期間

    • contract_model → cmdb_model(必須) … 契約のモデル(ひな型)。今回の PDI では必須でした。フォームでは「Contract model」と表示され、サンプルでは Software License などが入っていました。

    • vendor_contract(Contract number・必須) … ベンダ側が発番した契約番号。ServiceNow 側の number(CNTR…)とは別に、相手方の番号を持ちます。

    • starts / ends(Start date / End date) … 契約期間。State の自動遷移と関わります(後述)。

    • vendor / customer → core_company … 契約の相手(ベンダ)と顧客。どちらも会社テーブル core_company を参照します。

    コストと更新

    • total_cost / monthly_cost / yearly_cost … 契約のコスト。月額・年額・総額を別々に持てます。

    • renewable / renewal_date / renewal_options … 自動更新するか、更新の開始日、更新期間(1/2/3 Years)。

    • parent_contract → ast_contract … 親契約(自己参照)。契約の親子関係を持てます。

    種別・支払い周期・契約の管理者

    • license_type(Agreement type)/ payment_schedule(Payment schedule) … 契約の種別(Enterprise / Subscription / SaaS など)と支払い周期(Daily 〜 Annually)を選択肢で持ちます。

    • contract_administrator / approver / business_owner → sys_user … 契約の管理者・承認者・事業責任者を、それぞれ別のユーザー参照として持てます。po_number や cost_center、location といった経理・組織側の情報も同じレコードにまとまっています。

    全フィールドは、次のURLで一覧できます。

    https://<YourInstance>/sys_dictionary_list.do?sysparm_query=name=ast_contract^elementISNOTEMPTY


    画像

    今回の PDI では、ast_contract の固有フィールド(dictionary エントリ)は66件でした。


    契約の状態(State と期間の連動)

    ast_contract の State は draft / active / expired / cancelled の4値で、終了日(ends)を過ぎると Expired へ動きます。


    画像

    件数の内訳

    今回確認した PDI(Zurich / OOTB)では、state の有効な選択肢は次の4種でした(value = label)。


    画像

    111件の内訳は expired が77件と最も多く、active は8件でした。OOTB のサンプル契約は終了日が過去のものが多く、期限切れが大半を占めます。

    State がどう動くかは、フィールド値だけでは決まりません。公式の Contract life cycle では、契約の状態遷移を担う仕組みとして、毎日動く処理が契約の承認状況と日付を見て State を変える、と説明されています。承認済みで開始日に達した契約を Active にし、Active の契約が終了日に達したら Expired にする、という流れです。今回の記事では State の値と件数の確認にとどめ、その遷移を発火させる Scheduled Job や Business Rule の内部ロジックには踏み込みません(検証範囲外)。

    substate という一段細かい状態

    substate(Substate)は、state に依存する従属(dependent)選択肢でした。awaiting_review / under_review / approved / renewal_approved のほか、extension_active / renewal_active / rejected / renewal_rejected / extension_approved / extension_rejected など、確認できた値だけで10種類あります。同じ value が複数の state にぶら下がるため、state とセットで読む前提になります。

    State の選択肢は、次のURLで一覧できます。

    https://<YourInstance>/sys_choice_list.do?sysparm_query=name=ast_contract^element=state^inactive=false^ORDERBYsequence


    画像

    契約フォームを開くと、State・期間・Contract model・Vendor が上部に、Financial / Renewal / Terms and Conditions のタブが中段に、そして Assets Covered などの関連リストが下部に並びます。


    画像

    契約と資産の紐づけ(clm_m2m_contract_asset)

    契約と資産は、ast_contract から alm_asset を直接参照するのではなく、中間テーブル clm_m2m_contract_asset を挟んで結びつきます。


    画像

    主な連携テーブル

    今回の PDI で確認した主な連携先は次のとおりです。いずれもテーブルの存在を確認しています。

    • clm_m2m_contract_asset(Asset Covered) … 契約が守る資産。contract → ast_contract、asset → alm_asset の2参照を持つ中間テーブル。今回の PDI では397行ありました。

    • clm_m2m_contract_user(Users Covered) … 契約が対象とするユーザ。今回の PDI では80行。

    • cmdb_model(Product Model) … contract_model の参照先(必須)。

    • core_company(Company) … vendor / customer の参照先。

    • cmn_cost_center(Cost Center) … cost_center の参照先。

    • clm_condition_checker(Condition Checker) … expiration の参照先。期限の条件判定に使われるテーブル。

    • ast_contract 自身 … parent_contract の参照先(契約の親子)。

    • clm_m2m_rate_card_asset / clm_m2m_contract_and_terms … それぞれ Rate Card 向けの Asset Covered、Terms and Conditions 用の中間テーブルです。今回の PDI にも存在を確認しましたが、件数までは確認していません。

    中間テーブルを挟むのは、1つの契約が複数の資産を守り、1つの資産が複数の契約(保守とリースなど)に守られることがあるためです。直接参照では1対多しか表せませんが、clm_m2m_contract_asset を挟むことで多対多を表現できます。同じ作りが Users Covered(clm_m2m_contract_user)にもあり、契約はユーザに対しても多対多で結びつきます。

    Asset Covered の紐づけは、次のURLで確認できます。

    https://<YourInstance>/clm_m2m_contract_asset_list.do

    ast_contract に関わる周辺機能

    ast_contract の動きも、フィールド定義だけでは決まりません。State の遷移や更新の処理は Business Rule、フォーム制御は Client Script / UI Policy、操作は UI Action、権限は ACL が関係します。


    画像

    今回確認した PDI(Zurich / OOTB・active 中心・2026-06-22 確認)では、ast_contract に Business Rule 16件・Client Script 11件・UI Policy 4件・UI Action 10件・Notification 1件、Access Control はテーブル8件+フィールド36件が紐づいていました。State の自動遷移は Business Rule(公式ドキュメントでいう Manage Contract Lifecycle 系)と Scheduled Job が組み合わさって動くため、件数構造の確認にとどめ、内部の発火条件には踏み込みません。

    ここで数えているのは ast_contract(基底)に直接紐づく設定だけです。子クラス(ast_service など)や中間テーブルにも固有の設定があり、契約の挙動はそれらが合わさって決まります。基底だけを見て全体を判断しないようにします。

    自分のインスタンスでは、次のURLで各一覧を開けます。

    Business Rules : https://<YourInstance>/sys_script_list.do?sysparm_query=collection=ast_contract^active=true
    UI Actions     : https://<YourInstance>/sys_ui_action_list.do?sysparm_query=table=ast_contract
    Access Controls: https://<YourInstance>/sys_security_acl_list.do?sysparm_query=nameSTARTSWITHast_contract

    ServiceNow における ast_contract テーブルのポイント

    • 今回の PDI では、ast_contract は 継承元を持たないルート基底テーブル でした。直下に ast_service / ast_lease / ast_warranty の3クラスを持ちます。契約の種別はクラス(sys_class_name)で表し、type のような選択肢フィールドは持ちません。

    • State は draft / active / expired / cancelled の4値 で、終了日(ends)と連動して Expired へ動きます。111件のうち expired が77件と大半でした。

    • 契約と資産は直接参照ではなく、中間テーブル clm_m2m_contract_asset(Asset Covered)で多対多 に結びつきます。今回の PDI では397行ありました。

    • contract_model → cmdb_model と vendor_contract は今回の PDI で必須でした。

    • 更新(renewable / renewal_date / renewal_options)とコスト(total_cost / monthly_cost / yearly_cost)を契約レコードが持ちます。

    • State の自動遷移を発火させる Scheduled Job / Business Rule の内部ロジックは実装差があるため、本記事では構造(階層・フィールド・状態・件数・紐づき)の確認にとどめます。

    ast_contract を調べるときは、契約レコード単体ではなく、Asset Covered(clm_m2m_contract_asset)でつながる alm_asset、contract_model でつながる cmdb_model をセットで見ることを意識します。


    実機で気づいたこと

    • 最初は Contract type のような選択肢フィールドを探しましたが、実機の ast_contract には type や contract_type という選択肢自体が存在しませんでした。契約の種別は sys_class_name、つまりテーブル継承で表す作りで、しかも今回の PDI では111件すべてが子クラスを使わず基底 ast_contract のままでした。種別を切り替える器(ast_service / ast_lease / ast_warranty)は用意されているのに、デモデータでは誰も使っていない状態です。

    • フォームを開くまでは、契約の管理項目は Vendor とコストくらいだと思っていました。実際には contract_administrator / approver / business_owner という3つの別々の sys_user 参照があり、管理者・承認者・事業責任者を個別に記録できる作りでした。契約1件に複数の役割を割り当てる設計は、単純な資産台帳というより稟議・承認のワークフローに近い発想に見えます。

    • State(draft / active / expired / cancelled)は4値だけで単純に見えましたが、その下にぶら下がる substate は10種類ほどありました。画面の State 欄だけを見ていても、契約が更新申請中なのか却下されたのかまでは分かりません。トラブル調査では substate まで開いて確認したほうがよさそうです。


    次に読むなら

    次に確認するなら、State の自動遷移を担う Scheduled Job(Contract: Run Condition Checks)と Business Rule(Manage Contract Lifecycle)の動き、clm_condition_checker による期限判定の中身、契約更新ワークフロー(renewal)、そしてソフトウェアライセンス契約と Software Asset Management の連携です。これらは本記事の「状態」「周辺機能」で確認した仕組みの先にあたります。

    前提として、資産の台帳(alm_asset)を先に押さえると理解しやすいので、前回の「ServiceNow の資産管理テーブル alm_asset を実機で確認する:CI との関係・継承・状態の見方」も合わせて読むことをおすすめします。


    用語

    • PDI:Personal Developer Instance(無料の検証用インスタンス)

    • OOTB:Out of the Box(初期設定のまま)

    • 契約(Contract):ast_contract。期間・コスト・更新条件を持つ取り決めのレコード

    • Asset Covered:契約が守る資産。中間テーブル clm_m2m_contract_asset で表す

    • 中間テーブル(m2m):多対多を表すためのつなぎテーブル(テーブル名接頭辞 clm_m2m_)

    • 従属選択肢(dependent choice):親フィールドの値ごとに選べる候補が変わる選択肢(substate が該当)

    自分の環境で確認するときのURL

    先頭に自分のインスタンスを付けると、同じ画面が開けます。

    テーブル定義       : sys_db_object_list.do?sysparm_query=name=ast_contract
    直接の子クラス      : sys_db_object_list.do?sysparm_query=super_class.name=ast_contract
    フィールド一覧      : sys_dictionary_list.do?sysparm_query=name=ast_contract^elementISNOTEMPTY
    state 選択肢        : sys_choice_list.do?sysparm_query=name=ast_contract^element=state^inactive=false^ORDERBYsequence
    State でグループ化   : ast_contract_list.do?sysparm_query=GROUPBYstate
    Asset Covered       : clm_m2m_contract_asset_list.do

    検証範囲とおことわり

    • 確認した範囲:ast_contract の階層(ルート基底・直接の子3クラス)、固有フィールド数(66)、state(draft / active / expired / cancelled の4)と件数(draft 25 / active 8 / expired 77 / cancelled 1)、substate(従属選択肢)、starts / ends、contract_model(必須)/ vendor_contract(必須)、vendor / customer の参照先、clm_m2m_contract_asset(asset → alm_asset)の存在と件数(397)、レコード件数(111)、周辺設定件数、renewable / ratecard 件数。すべて PDI(Zurich / 2026-06-22 確認)の OOTB で取得しています。

    • 確認していない範囲:State を自動遷移させる Scheduled Job / Business Rule(Manage Contract Lifecycle・Contract: Run Condition Checks)の内部ロジックと発火条件、clm_condition_checker による条件判定の中身、契約更新ワークフロー(renewal)の動作、コスト(total_cost と monthly / yearly)の計算関係、Life Cycle Stage の運用、子クラス(ast_service / ast_lease / ast_warranty)固有のフィールド、契約と資産・コストが実データでどう連動するかの突合。

    今回は PDI の OOTB(初期設定)を前提に、テーブルの構造を確認しました。実環境では、既存のカスタマイズによってフィールドや設定の数・内容が変わります。

     
     
    ServiceNowのPDI(Personal Developer Instance)を実機で観察して、Noteに記事を書いています 実装・運用・教育の現場視点で淡々と記録中です リクエストがあればその記事も書きます 個人の観察日記です

    あなたへのおすすめ