Salesforce Commerce Cloudでのカスタムオブジェクトの作成およびデータ操作

# はじめに
Salesforce Commerce Cloud（以下SFCC）でのDBのテーブルという概念は、
システムオブジェクトとカスタムオブジェクトと呼ばれております。
Salesforceの構築をしたことがない人には聞きなれない名称だと思います。
SFCCでテーブル作成する場合は、まずカスタムオブジェクトを作成することになります。

* システムオブジェクト・・・標準で設定されているテーブル情報
* カスタムオブジェクト・・・拡張して利用できるテーブル情報

またSFCCでは、SQLを利用することがなく、
B2C Commerce APIというシステム（カスタム）オブジェクトへアクセスするためのライブラリを呼び出してテーブル情報のCRUD操作を実行できます。

# カスタムオブジェクトの作成手順
* 「管理 > サイトの開発 > カスタムオブジェクトタイプ」メニューを選択
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/377903/744e7a04-8814-1bd6-0464-77966334537b.png)
* 「新規」ボタンを押下し、新規カスタムオブジェクトを作成（以下のように入力）
  - ID（カスタムオブジェクト名のKey）：CustomObjectSample
  - 主キー属性（プライマリキー）：customObjectSampleId
  - データのレプリケーション：レプリケーション不可
  - 保持範囲：サイト
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/377903/de47d14c-acda-f8af-9d77-0104c9f9a0a0.png)
* 「属性定義」タブにてフィールドを作成

# カスタムオブジェクトのデータ新規登録方法
* use strict について
  - https://qiita.com/tadnakam/items/700bd526b33f8f92702a

```javascript:CustomObjectPage.js
'use strict';
var server = require('server');
var CustomObjectMgr = require('dw/object/CustomObjectMgr');
var Logger = require('dw/system/Logger');

// POSTメソッドに対応するfunction
server.post('Registration', function (req, res, next) {
    var Transaction = require('dw/system/Transaction');
    Transaction.begin();
    try {
        var customObjectSampleId = 'NO00000001';
        // カスタムオブジェクトのモデルを生成する際はKeyとなるIDと主キーを引数とする
        var NewCustomObjectSample = CustomObjectMgr.createCustomObject('CustomObjectSample', customObjectSampleId);
        // カスタムオブジェクト作成時に属性定義に整数型として追加したフィールド
	NewCustomObjectSample.custom.customerNo = 00000001;
        // カスタムオブジェクト作成時に属性定義に文字列型として追加したフィールド
	NewCustomObjectSample.custom.customerName = 'HogeHoge';
        Transaction.commit();
    } catch (e) {
        Logger.error(e)
        Transaction.rollback();
    }
    return next();
});

// ルーティング設定
module.exports = server.exports();
```

# カスタムオブジェクトデータの取得方法
```javascript:CustomObjectPage.js
'use strict';
var server = require('server');
var CustomObjectMgr = require('dw/object/CustomObjectMgr');

// GETメソッドに対応するfunction
server.get('List', function (req, res, next) {
    // CustomObjectSampleという名称のカスタムオブジェクトの全データを取得
    var CustomObjectSamples = CustomObjectMgr.getAllCustomObjects('CustomObjectSample');

    // sample/sampleList.ismlテンプレートの呼び出し
    res.render('sample/sampleList', {
    	CustomObjectSamples: CustomObjectSamples
    });
    return next();
});

// ルーティング設定
module.exports = server.exports();
```

# カスタムオブジェクトのデータ削除方法
```javascript:CustomObjectPage.js
'use strict';
var server = require('server');
var CustomObjectMgr = require('dw/object/CustomObjectMgr');
var Logger = require('dw/system/Logger');

// GETメソッドに対応するfunction
server.get('Delete', function (req, res, next) {
    var customObjectSampleId = '00000001';
    var DeleteCustomObjectSample = CustomObjectMgr.getCustomObject('CustomObjectSample', customObjectSampleId);
    if (DeleteCustomObjectSample) {
        var Transaction = require('dw/system/Transaction');
        Transaction.begin();
        try {
            // カスタムオブジェクトの削除（物理削除）はオブジェクト型を引数とする
            CustomObjectMgr.remove(DeleteCustomObjectSample);
            Transaction.commit();
        } catch (e) {
            Logger.error(e);
            Transaction.rollback();
        }
    }
    return next();
});

// ルーティング設定
module.exports = server.exports();
```

# カスタムオブジェクトのデータ編集方法
```javascript:CustomObjectPage.js
'use strict';
var server = require('server');
var CustomObjectMgr = require('dw/object/CustomObjectMgr');
var Logger = require('dw/system/Logger');

// POSTメソッドに対応するfunction
server.post('Update', function (req, res, next) {
    var customObjectSampleId = 'NO00000001';
    var EditCustomObejectSample = CustomObjectMgr.getCustomObject('CustomObejectSample', customObjectSampleId);
    if (EditCustomObejectSample) {
        var Transaction = require('dw/system/Transaction');
        Transaction.begin();
        try {
            EditCustomObejectSample.custom.customerNo = 00000002;
            EditCustomObejectSample.custom.customerName = 'FugaFuga';
            Transaction.commit();
        } catch(e) {
	    Logger.error(e);
            Transaction.rollback();
        }
    }
    return next();
});

// ルーティング設定
module.exports = server.exports();
```

# まとめ
* カスタムオブジェクトの操作には必ずTransactionを利用する必要がある
* カスタムオブジェクト一覧を取得するのにはレスポンスの観点からgetAllCustomObjects()を使用せずwhere句等指定できるfunctionを利用する方がよさそう
* カスタムオブジェクトのフィールドにアクセスする際は「{カスタムオブジェクト変数名}.custom.{フィールド名}」とcustomをつけないとアクセスできない