背景・実現したいこと
Aアプリ一覧のレコード毎にボタンを設置しました。
仕入登録ボタンを押すと、Bアプリ用に連番付与しPOST→Aアプリの未納を完納へPUTします。
簡単なロジックは下記のイメージです。
①まず、”いいえ”を選択した場合、処理を終了させたいのですが、今は、はいの処理も走ってしまいキャンセルできていません。
②連番、完納チェックのエラーがキャッチ出来るようにしたいです。
③下記エラーの対処方法で、
Uncaught (in promise)の発生条件と抑制方法 を参考にしてみたのですが、どのように修正すればいいのか分かりませんでした。
JavaScript自体独学で素人なのですが、PromiseやsweetAlert2もまだまだ理解できていない部分も多く、ご迷惑お掛けしますが、ご教示いただけると幸いです。
利用したソースコード
(() => {
"use strict";
kintone.events.on('app.record.index.show', function (event) {
//viewId、ログインユーザー条件設定
const userName = kintone.getLoginUser().name;
if (userName !== "〇〇〇〇") {
console.log(userName);
return;
} else if (event.viewId !== 9999999) {
console.log(2);
return;
}
console.log(3);
const field = 'field_for_button'; //管理者用フィールド
const records = event.records;
let element = kintone.app.getFieldElements(field);
//管理者用フィールドへボタンを配置
for (let i in records) {
let rec_id = records[i].$id.value;
$(`
<button id="button_${rec_id}" class="kintoneplugin-button-dialog-ok" name='${rec_id}'>
${records[i]['ボタン表示内容'].value}
</button>
`)
.appendTo(element[i]);
}
$('.kintoneplugin-button-dialog-ok').on('click', function (e) {
const id = $(this).attr('name');
let record = "";
for (let i in records) {
if (records[i].$id.value == id) {
record = records[i];
//確認ダイアログ
Swal.fire({
title: '登録確認',
text: '仕入伝票へ登録しますか?',
icon: 'warning',
showCancelButton: true,
confirmButtonColor: '#3085d6',
cancelButtonColor: '#d33',
confirmButtonText: '実行する',
cancelButtonText: 'キャンセル',
//reverseButtons: true //確認キャンセルボタン位置逆転
}).then((result) => {
//キャンセル時
if (result.isDismissed) {
//何もしない
Swal.fire(
'キャンセル',
'キャンセルしました。',
'error',
);
console.log('キャンセルが選択されました。');
return event;
}
const postRecords = [];
const url = kintone.api.url('/k/v1/records.json', true)
const query = {
"app": 80,
"query": 'order by 仕入No desc limit 1'
//"query": '仕入No like "S-2021" order by 仕入No desc limit 1' //前期分として
};
return kintone.api(url, 'GET', query).then(function (resp) {
//ここに連番処理
const splitNumber = resp.records[0]['仕入No'].value.split('-'); // => ['S', '2022', '0001']
let serialNumber = Number(splitNumber[2]); // => 1
//console.log(splitNumber);
const recRecords = [];
let subTable = record.発注詳細.value;
serialNumber++; // => 2,3,4 ...
// => S-2022-0002,S-2022-0003,S-2022-0004...
const newSerialNumber = ['S', '2022', ('000' + serialNumber).slice(-4)].join('-');
// サブテーブル分ループ
subTable.forEach(function (eachRow) {
let tableA = eachRow.value.商品名.value;
let tableB = eachRow.value.数量.value;
let tableC = eachRow.value.単位.value;
let tableD = eachRow.value.単価.value;
let tableE = eachRow.value.摘要.value;
//サブテーブル生成
recRecords.push({
"value": {
"商品名": { "value": tableA },
"数量": { "value": tableB },
"単位": { "value": tableC },
"単価": { "value": tableD },
"摘要": { "value": tableE }
}
});
})
//レコード生成
postRecords.push({
"仕入先": { value: record.発注先.value },
"仕入日": { value: record.発注日.value },
"仕入No": { value: newSerialNumber }, //ここを連番にしたい
"発注No": { value: record.発注No.value },
"担当者": { value: record.担当者.value },
"仕入詳細": { value: recRecords },
"工番": { value: record.工番.value },
"科目名": { value: record.科目名.value }
});
const postParams = {
app: 80,
records: postRecords
};
//仕入伝票へpost
return kintone.api(kintone.api.url('/k/v1/records.json', true), 'POST', postParams, (resp) => {
// success
console.log(resp);
});
});
}).then(() => {
const params = {
app: event.appId,
query: kintone.app.getQuery()
}
const record_array = []
//仕入伝票へpostしたレコードの"納入チェック"フィールドを"完納"へ更新する
return kintone.api('/k/v1/records', 'GET', params, function (resp) {
const records = resp.records;
records.forEach(function (record) {
const record_obj = {
"id": record['レコード番号']['value'],
"record": {
"納入チェック": {
"value": "未納"
}
}
}
record_array.push(record_obj)
})
const put_params = {
app: event.appId,
records: record_array
}
return kintone.api('/k/v1/records', 'PUT', put_params, function (resp) {
//window.confirm('登録完了!' + '\n発注No : ' + orderNumber + '\n発注先 : ' + orderTarget + '\n合計 : ' + orderTotal);
const orderNumber = record.発注No.value;
const orderTarget = record.発注先.value;
const orderTotal = record.合計.value;
Swal.fire({
title: '登録',
html: '登録完了!<br>発注No : ' + orderNumber + '<br>発注先 : ' + orderTarget + '<br>合計 : ' + orderTotal,
icon: 'success'
});
// 画面リロード
//location.reload();
return event;
});
});
}).then(() => {
return event;
}).catch((error) => {
event.error = error.message;
Swal.fire(
'エラー',
'エラーが発生しました。\n' + error.message,
'success'
);
console.log(error);
return event;
});
}
};
console.log(record);
console.log(record['発注No'].value);
});
});
})();
4件のコメント
渡邉祐子 さん
キャンセルの処理で return event; をしてしまうことで
次のthenの処理が移ってしまってるんだと思います。
return event; ではなく、 throw new Error('Cancelled'); でエラーをスローしてしまって、最後の記載されてる catch 処理でキャンセルメッセージを表示すると良いかなと思いました。
細谷 崇様
早速のご回答ありがとうございます。
いいえの場合は、処理をキャンセルさせることができました。
エラー処理についてですが、完納チェック(PUT)まで正常に完了したら、登録完了!を出すはずが、エラーの場合でも表示されてしまいます。
Promiseにより、PUTエラーでcatchに飛ぶと思っていたのですが、どこかにif分などが必要でしょうか?
渡邉祐子 様
以下のページの「Promiseを利用する(複数回)」の部分を読んでみると良いかなーと思いました。
https://cybozudev.zendesk.com/hc/ja/articles/360023047852-kintone%E3%81%AB%E3%81%8A%E3%81%91%E3%82%8BPromise%E3%81%AE%E6%9B%B8%E3%81%8D%E6%96%B9%E3%81%AE%E5%9F%BA%E6%9C%AC
現在、渡邊様のコードはコールバック形式とPromise形式が混ざって記載されており、複雑になっています。上記ページに書いてるようにPromise形式に統一した方が不具合も起こりづらいかなーと思います。
の部分がコールバック形式になっているので、PUTのエラーになっても最後に書かれてるcatch処理に飛ばないのかなーと思いました。
にして、正常処理は次のthen処理で記載する、エラーの場合はcatch処理で処理をするようにすると良いのかなと。
PUTのところ以外のGETやPOSTの部分もPromise形式にされた方がコードもスッキリするかなと思います。
細谷 崇様
ご回答遅くなり申し訳ありません。
又、ご丁寧な解説ありがとうございます。
まだコールバック関数とPromise形式の違いがぼんやりしていていますが、勉強しつつ修正していこうと思います。
貴重なお時間ありがとうございます。