使っているクラウドなどの小ネタ Advent Calendar 2024 1日目
ジョブカンのテーブル形式の部分をSalesforceの子オブジェクトとして処理したいです。
複数レコードにも対応できればと思います。
Yoomでこの部分を確認すると以下のようなJsonが格納されています。始めはフローだけで処理しようと思っていたのですがJsonなのでこの部分はApexのコードを書いてフローから呼び出すことにします。
[[{"column_number":"0", "value":"収入印紙"},{"column_number":"1", "value":"600 円 × 5 枚 = 3,000"}]]
-
[{"column_number":"0", "value":"収入印紙"},{"column_number":"1", "value":"600 円 × 5 枚 = 3,000"}]というリスト型をさらにリスト変数に追加することで複数のレコードを表現しています。
-
[{"column_number":"0", "value":"収入印紙"},{"column_number":"1", "value":"600 円 × 5 枚 = 3,000"}]は{"column_number":"0", "value":"収入印紙"}の変数をリスト変数にしています。
ということで、まずは{"column_number":"0", "value":"収入印紙"}のクラスを定義します。
このクラス
public class colval01 {
public Integer column_number;
public String value;
}
2の部分は以下のように表現できます。
List<colval01>
1の部分は以下のように表現できます。
List<List<colval01>>
これでJsonの表現方法が分かったので指定された型にデシリアライズします。
List<colval01> l = (List<colval01>)JSON.deserializeStrict('['+resBody.replaceAll('=>',':') +']' ,List<colval01>.class);
これで複数件のレコードとしてSaleforce側でも処理できるはずですが...
さて、2回目のyoom側の処理を実施してテストをするとデシリアライズでエラーですね。おかしいなぁ。YoomからのJsonは先程テストに使ったJsonとは違う?と思って確かめてみると
{"column_number"=>"0", "value"=>"収入印紙"},{"column_number"=>"1", "value"=>"600 円 × 5 枚 = 3,000"}
えええ、[[]]がないしJsonに似ているけど違う :が=>になっている。どの言語の表記だろうか?PHPとも少し違うかな
仕方ないので強制的に文字列を変換します。また二重のList型にしないで、colval01のList型として使用します。column_numberとvalueの組み合わせが2回続けば1つのデータの塊と判断して処理をします。
List<colval01> l = (List<colval01>)JSON.deserializeStrict('['+resBody.replaceAll('=>',':') +']' ,List<colval01>.class);
最終的には以下のような処理にしました。
@InvocableMethod(label='JSON_deserialize')
public static List<List<String>> test001(List<List<String>> inputString) {
List<hiyoumeisai__c> insertList = new List<hiyoumeisai__c>();
String resBody = inputString[0][0];
List<colval01> l = (List<colval01>)JSON.deserializeStrict('['+resBody.replaceAll('=>',':') +']' ,List<colval01>.class);
List<List<colval01>> ll = new List<List<colval01>>();
List<colval01> l2 = new List<colval01>();
Integer count = 0;
for (colval01 m : l) {
count = count + 1;
Integer remainder = math.mod(count, 2);
if (remainder == 1) {
l2.clear();
l2.add(m);
system.debug(Logginglevel.INFO,count + '=====> ' + l2 );
}
if (remainder == 0) {
l2.add(m);
system.debug(Logginglevel.INFO,count + '=====> ' + l2 );
//ll.add(L2);
String formula = l2[1].value;
List<String> formulas = formula.split('=');
system.debug(Logginglevel.INFO,'=====> ' + formulas[1].replaceAll(',','') );
hiyoumeisai__c m2 = new hiyoumeisai__c();
m2.hiyou__c = inputString[0][1];//Id
m2.Field01__c = l2[0].value;
m2.Field02__c = l2[1].value;
m2.amount__c = Decimal.valueOf(formulas[1].replaceAll(',','').trim());
insertList.add(m2);
}
}
if (insertList.size() > 0) insert insertList;
List<List<String>> rLists = new List<List<String>>();
List<String> rList = new List<String>();
rList.add('ok');
rLists.add(rList);
system.debug(Logginglevel.INFO,'out =====> ' + rLists.size() );
return rLists;
}
このエラーでも悩みました。
おまけ:テストクラス
@isTest
public class jobcan_tools3_test {
// *************************************************
// ジョブカンの費用明細の変換処理 test Apex
// K.Otsubo 2024/10/25
// Jsonフォーマットからの変換
// *************************************************
static testMethod void test_main(){
User u = fkd_User.createTestUser();
Test.startTest();
// 作成したユーザで処理を実行
System.runAs(u){
//テストデータ作成
hiyou__c h = new hiyou__c ();
h.Name = '037_切手・印紙申請書';
h.iString__c = '{"column_number"=>"0", "value"=>"収入印紙"},{"column_number"=>"1", "value"=>"4,000 円 × 1 枚 = 4,000"}';
h.st_total__c ='4,000 円';
h.total__c = 4000;
//DataType__cを指定しないことでフローに処理させない。Apexだけを起動させる
insert h;
List<List<String>> inputStrings = new List<List<String>>();
List<String> inputString = new List<String>();
inputString.add(h.iString__c);
inputString.add(h.Id);
inputStrings.add(inputString);
List<List<String>> retList = jobcan_tools3.test001(inputStrings);
List<hiyou__c> hList = [select Id,total__c from hiyou__c where Id =: h.Id];
ystem.assertEquals(hList[0].total__c,4000);
}
Test.stopTest();
}
}