GAS x マネーフォワードクラウドのAPIを使って請求書作成を自動化する方法④(請求書の明細作成編)

投稿日: 2024-08-19

業務効率化

エンジニアリング

請求書作成の自動化完成まで、もう少しです!

前回の振り返りと今回やっていくこと

前回までで、請求書の作成処理まで作成しました。

現状はまだ明細を追加できていないため、請求金額は0円となってしまっています。

前回の記事を確認したい方はこちら

https://maeshiiii.com/posts/automated-billing-3

今回の記事で前回作成した請求書に明細を追加して、請求金額を正しく表示させられるようにしましょう。

今回やっていくこと

今回の記事でやっていくことは、以下の2点です。

  • 勤怠管理スプレッドシートから前月の稼動時間を取得する。
  • 作成した請求書に品目の明細部分を追加する。

Frame_3690.png

作成する請求書の内容を確認

今回作成する請求書の明細に載せる情報を確認しておきましょう。

載せる情報は以下の通りです。

  • 品目
  • 単価
  • 数量
  • 単位

※請求金額などは自動計算してくれるので、こちらで渡す必要はありません。

マネーフォワードクラウドで品目を追加する

まずは請求書に載せる品目の情報をマネーフォワードクラウドに登録しましょう。

マネーフォワードクラウドに登録しておくことで、品目のIDを指定するだけで、請求書に必要な情報を載せてくれます。

  1. マネーフォワードクラウドの品目一覧ページにアクセスする。

  2. 画面右側にある「品目を追加」をクリックする。

    Untitled.png

  3. 品目の情報を入力して、「追加」する。

    Untitled.png

  4. 品目を追加できた、作成した品目の編集ボタンをクリックする。

  5. 編集ページのURLのhttps://…id=の後ろの文字列が品目IDになります。このIDを使うので、GASのスクリプトプロパティに登録しましょう。

    https://invoice.moneyforward.com/items?action=edit&id=[品目ID]
  6. GASの左側メニュー「プロジェクトの設定」からスクリプトエディタを編集し、プロパティを追加しましょう。プロパティをITEM_ID にして、上記品目IDを値に設定します。

    ※品目を複数追加したい場合は、ITEM_ID_AAAITEM_ID_BBBのようにプロパティ名を分けて、それぞれマネーフォワードクラウドで作成した品目IDをスクリプトエディタに登録してください。

  7. スクリプトプロパティを保存したら、エディタに戻り、 ITEM_ID: PROPERTIES.getProperty('ITEM_ID'), という1行を追加します。

    ※こちらも複数の品目を追加したい場合は、複数行を追加しましょう。

    function getScriptProperties_() { const PROPERTIES = PropertiesService.getScriptProperties(); return { CLIENT_ID: PROPERTIES.getProperty('CLIENT_ID'), CLIENT_SECRET: PROPERTIES.getProperty('CLIENT_SECRET'), DEPARTMENT_ID: PROPERTIES.getProperty('DEPARTMENT_ID'), ITEM_ID_PRODUCTION: PROPERTIES.getProperty('ITEM_ID'), // 追加箇所 }; }

これで品目IDを処理の中で利用する準備が整いました!

稼動時間を勤怠管理スプレッドシートから取得する

明細を請求書に載せるには、前月に稼働した時間を数量として載せる必要があります。この時間は、勤怠管理スプレッドシートから取得するようにします。

この勤怠管理シートでは、月毎にシートが分かれており、「YYYY年MM月」というシート名にしています。またその月の稼動時間合計が「B1」セルに計算される仕組みになっています。そのため、該当月のB1セルの値を取得する処理を書きます。

前回書いたコードの下に、以下のコードを貼り付けてください。

function getSpreadsheet_(lastMonth) { const PROPERTIES = getScriptProperties_(); const spreadSheet = SpreadsheetApp.getActiveSpreadsheet(); const sheet = spreadSheet.getSheetByName(lastMonth); const items = [ { itemId: PROPERTIES.ITEM_ID, quantity: sheet.getRange('B1').getValue().toFixed(2) } ]; return items; }
複数の品目を分けて稼動時間を取得したい場合

※AAAという品目の稼動時間をB1セルで、BBBという品目の稼動時間をB2セルで管理している場合のコードにしています。

function getSpreadsheet_(lastMonth) { const PROPERTIES = getScriptProperties_(); const spreadSheet = SpreadsheetApp.getActiveSpreadsheet(); const sheet = spreadSheet.getSheetByName(lastMonth); const items = [ { itemId: PROPERTIES.ITEM_ID_AAA, quantity: sheet.getRange('B1').getValue().toFixed(2) }, { itemId: PROPERTIES.ITEM_ID_BBB, quantity: sheet.getRange('B2').getValue().toFixed(2) } ]; return items; }
【補足】上記コードの解説

これまで同様に年月を利用するので、引数で受け取れるようにしています。

また初めにスクリプトプロパティの値の取得をしています。

function getSpreadsheet_(lastMonth) { const PROPERTIES = getScriptProperties_(); }

スプレッドシートの引数で受け取った年月と一致するシート名を取得しています。

function getSpreadsheet_(lastMonth) { const PROPERTIES = getScriptProperties_(); const spreadSheet = SpreadsheetApp.getActiveSpreadsheet(); const sheet = spreadSheet.getSheetByName(lastMonth); //前月にあたる「YYYY年MM月」というシート名を取得する }

itemsという品目IDと稼動時間をオブジェクトにして、配列を定義しています。

なお、今回はtoFixed(2)とすることで、小数点以下第2位までを取得するようにしています。

function getSpreadsheet_(lastMonth) { const PROPERTIES = getScriptProperties_(); const spreadSheet = SpreadsheetApp.getActiveSpreadsheet(); const sheet = spreadSheet.getSheetByName(lastMonth); const items = [ { itemId: PROPERTIES.ITEM_ID, quantity: sheet.getRange('B1').getValue().toFixed(2) } ]; return items; // 品目IDと稼動時間をオブジェクトの配列にして返す }

この関数をstart() で呼び出すようにします。

function start() { try { auth_(); const lastMonth = getLastMonth_(); const billingId = createNewBilling_(lastMonth); const items = getSpreadsheet_(lastMonth); // 追加箇所 } catch (error) { logError('請求書の自動作成にエラーが発生しました。:', error); } }

これで勤怠管理スプレッドシートから稼動時間を取得することができました。

請求書に明細を追加する

それでは請求書に対して明細を追加する処理を書いていきましょう。

前回書いたコードの下に、以下のコードを貼り付けてください。

function addBillingItems_(billingId, items) { try { const url = 'https://invoice.moneyforward.com/api/v3/billings/' + billingId + '/items'; items.forEach(function(item) { Logger.log(item); const options = { method: 'POST', headers: { 'Content-Type': 'application/json', Authorization: 'Bearer ' + getService_().getAccessToken() }, payload: JSON.stringify({ item_id: item.itemId, quantity: item.quantity }) }; UrlFetchApp.fetch(url, options); }); } catch (error) { Logger.log('Error in addBillingItems_ function: ' + error.message); throw error; } }
【補足】上記コードの解説

請求書の明細を作成する上で必要となる情報を引数で受け取るようにしています。

  1. billingId:これは請求書作成処理(createNewBilling_())で作成された請求書に対して明細を追加するので、請求書IDを渡しています。
  2. items:これは品目と稼動時間がセットになったオブジェクトです。上記のgetSpreadsheet_()で取得したものです。
function addBillingItems_(billingId, items) { try { } catch (error) { Logger.log('Error in addBillingItems_ function: ' + error.message); throw error; } }

urlには、マネーフォワードクラウドAPIの明細を作成するAPIを指定しています。(詳細は公式サイトを確認ください。)

今回は品目が複数あっても追加できるようにしているので、引数で受け取ったitemsをforEachで繰り返し処理することで、1件ずつ品目を追加するようにしています。

1件ずつ繰り返す処理の中で、各品目のIDと数量を指定し、fetchしています。数量以外の情報は、マネーフォワードクラウドに登録されている情報を請求書に載せてくれます。

function addBillingItems_(billingId, items) { try { const url = 'https://invoice.moneyforward.com/api/v3/billings/' + billingId + '/items'; items.forEach(function(item) { Logger.log(item); const options = { method: 'POST', headers: { 'Content-Type': 'application/json', Authorization: 'Bearer ' + getService_().getAccessToken() }, payload: JSON.stringify({ item_id: item.itemId, quantity: item.quantity }) }; UrlFetchApp.fetch(url, options); }); } catch (error) { Logger.log('Error in addBillingItems_ function: ' + error.message); throw error; } }

この関数をstart() で呼び出すようにします。

function start() { try { auth_(); const lastMonth = getLastMonth_(); const billingId = createNewBilling_(lastMonth); const items = getSpreadsheet_(lastMonth); addBillingItems_(billingId, items); // 追加箇所 } catch (error) { logError('請求書の自動作成にエラーが発生しました。:', error); } }

処理を呼び出す

これで準備が整ったので、start()を実行してみましょう。ここまでうまく書けていれば、マネーフォワードクラウドの方で請求書が明細まで作成できるはずです。

うまく動作できていれば請求書作成処理は完成です!

最後の記事では、請求書作成処理を決まった時間に自動で実行されるようにするということを行なっていきます。

https://maeshiiii.com/posts/automated-billing-5

ここまでお疲れ様でした!

←ホームに戻る