受発注・請求 秘書|受注が来たら“選ぶだけ”で見積書・請求書のPDF【応用編その3】

受発注・請求 秘書|選ぶだけで、請求書になる(アイキャッチ) つまずき帳

お金の書類で一番こわいのは、間違いに自分で気づけないこと

「お見積りをお願いできますか」——その一通が来るたびに、わたしの夜が少しずつ削れていきました。

Excelのテンプレを開いて、前回の見積書をコピーして、宛名を打ち直す。取引先の住所と振込先を、また別のファイルからコピペする。品名と数量を入れて、単価を確かめて、消費税を電卓で叩く。10%の品と8%の品が混じった案件では、「あれ、これ軽減税率だっけ」と手が止まる。番号は前回の続きでいいんだっけと、過去のフォルダをさかのぼる。

ようやく見積書ができても、今度は同じことを請求書でもう一度。宛名、住所、振込先、品目、税額、番号——同じ情報を、書類の種類が変わるたびに、何度も何度も打ち直す。一件ずつは小さな作業です。でも注文が増えるほど、この「打ち直し」が積もって、気づけば日付が変わっている。

そして、いちばんこわいのはここです。お金の書類で本当に怖いのは、間違えること自体ではなく、間違いに自分で気づけなくなることでした。疲れた頭で打った金額が、ほんとうに合っているのか。送ってしまったあとで「桁がひとつ多かった」と気づく——その想像だけで、また手が止まる。

——もし、いま胸のどこかに思い当たるものがあるなら。この先は、あなたのための回かもしれません。

結果から言います = 受注が来たら、選んでボタンひとつで見積書・請求書がPDFになる

いまは、その「打ち直しの夜」が、ずいぶん軽くなりました。やることは、ほとんどありません。

注文が入ると、スプレッドシートの「受注台帳」に、1行が増えます。その行を選んで、メニューから「選択行から 見積書PDF」を押す。それだけで、宛名も住所も品目も金額も、消費税まできちんと入った見積書が、PDFになってDriveに保存されます。お客さまが「お願いします」となったら、今度は同じ行を選んで「選択行から 請求書PDF」。番号も自動で振られ、振込先も支払期限も入った請求書が、また1枚できあがります。

電卓は、もう叩きません。番号も、自分で管理しません。宛名の打ち直しも、ありません。わたしがやるのは「どの注文の、どの書類を作るか」を選んで、ボタンを押すこと。 あとは、秘書が決まった形で、決まった手順の計算で、書類に変えてくれます。

正直に言うと、今回もわたしはコードを一行も書いていません。書いたのはAIで、わたしがやったのは、できあがったものを貼り付けて、一度だけ許可して、自社の情報を表に書き込んだだけ。それが、このブログのやり方です。

先に、この秘書の全体像を1枚にまとめておきます。今回(核)で触るのは上半分の“お金の一本道”=受注→見積→請求→入金→領収。在庫や集計は、同じコードのまま育てる編で解説していきます。

受発注・請求 秘書の全体像
受発注秘書メニュー(受発注・請求 秘書)

用意するもの = たった4ステップ

この秘書を動かすまでにやることは、4つだけです。順番にいきましょう。どれも、コードを読む必要はありません。

① AIにプロンプトを貼って、コードを作ってもらう

この秘書の中身(コード)は、自分では書きません。ChatGPTやGeminiのような対話AI(チャット相手)に、決まった「お願い文」を丸ごとコピペして頼むだけです。

その「お願い文(プロンプト)」は長いので、この記事の後半「AIに渡すプロンプト(全文)」に、まるごと載せてあります。 そこまで読み進めたら、枠の中をまるごとコピーして対話AIに貼り、送るだけ。AIが「コピーして貼ればそのまま動く完成形のコード」を返してくれます(プロンプトの中身を、あなたが読んで理解する必要は、まったくありません)。

返ってきたコードは、スプレッドシートの裏側に貼り付けます。貼り付ける場所は、スプレッドシートの上のメニューから[拡張機能]→[Apps Script]を開いたところ。その開き方と、初回だけ出る許可の画面は、許可画面の回に写真つきでまとめてあります。一度通れば、次からは出ません。

② 最初に一度「初期化(シートを作る)」を押す

コードを貼っただけでは、まだ何も起きません。最初に一度、メニューから「初期化」を押して、必要なシートを作ってもらいます。 ここが操作の起点です。

スプレッドシートに戻ると、上のメニューに「受発注秘書」が増えています(出ていなければ、一度ページを再読み込み)。これを開いて、「初期化(シートを作る)」を押してください。これだけで、次の6枚のシートが自動でできあがります。

  • 受注台帳:注文1件=1行。書類づくりの“表紙”
  • 明細:注文された品(品名・数量・単価)が並ぶ場所。金額の“ほんとうの中身”はここ
  • 商品マスタ:よく出す品の名前と単価を登録しておく場所(単価の出どころ)
  • 取引先マスタ:取引先の宛名・住所・メールを登録しておく場所(あとでメール下書きの宛先が自動で入る伏線)
  • 自社情報:あなたの会社の情報(次の③で埋めます)
  • 採番:見積・請求などの番号を内部で管理する場所(触らなくてOK)

ひとつ安心材料を。この初期化は「無ければ作る」だけです。すでに同じ名前のシートがあれば、何もしません。あなたの既存のデータを、消したり上書きしたりはしません。

③ 自社情報シートを埋める

初期化でできた「自社情報」シートを開きます。ここは、見積書・請求書に印字される「あなたの会社の情報」を並べる場所。縦に「項目」と「値」が並んでいるので、値の側を、自分のものに書き換えるだけです。

項目 何を入れるか
会社名/屋号書類に出る発行者名
郵便番号・住所・電話・メール書類のあなたの連絡先
振込先請求書に載る振込口座
支払期限「請求書発行月の翌月末」など
税の扱い「外税」のみ(後述)
インボイス対応ON / OFF(既定は OFF
登録番号インボイスONのとき必須(T+数字13桁)
端数処理消費税の丸め方(切捨/四捨五入/切上)

ここで出てくる言葉を、先に最小限だけ説明しておきます。

  • 外税 =「税抜きの単価で品を積み上げて、あとから消費税を足す」やり方です。逆に税込み単価で扱う「内税」には、この秘書は対応していません(理由は後ろの「正直にできないこと」で)。
  • インボイス(適格請求書) = 税務署に登録した事業者だけが出せる、消費税の登録番号入りの請求書のこと。

設定のポイントは2つだけ。インボイスを出したい人は「インボイス対応」を ON にして、すぐ下の「登録番号」に自分の登録番号(T+数字13桁)を入れること。インボイスがまだの人は、OFF のままで大丈夫です(ふつうの請求書が出ます)。もうひとつ、消費税の端数の丸め方は「端数処理」で選べます(既定は切捨)。

④ フォームを接続する(注文の主入口)

最後に、注文の入口を用意します。注文を受け取る一番ラクな形は、Googleフォームです。お客さまや自分がフォームに入力して送信すると、受注台帳に自動で1行が増える——その配線をします。

メニューの「フォームを接続(送信→受注台帳)」を押すと、フォームのURL(編集画面のURL)を聞かれます。ここで貼るのは、ブラウザのアドレス欄が .../edit で終わっているURL(お客さまが回答する公開URLではなく、自分が編集する画面のURL)です。これを貼って「OK」を押せば、接続完了。以後、フォームが送信されるたびに、受注台帳に1行、自動で記録されていきます。

フォームの質問は「取引先名/品名/数量/単価/希望納期/件名/備考」を含めておくと、秘書がそれぞれの欄を自動で見分けて振り分けます。品名・数量・単価は、1行に1品ずつ書けば、複数の品にも対応します。

——これで、準備はおしまいです。注文が「フォームから1行」入ってくるところから、書類づくりが始まります。

AIに渡すプロンプト(全文・中身は読まなくて大丈夫)

この秘書の中身(コード)は、自分では書きません。下の枠をまるごとコピーして、対話AI(ChatGPTやGeminiのような相手)に貼って送るだけ。すると、AIが「コピーして貼ればそのまま動く完成形のコード」を返してくれます。

——先に正直に言っておきます。枠の中は、けっこう長くて、見慣れない専門用語(GAS/PDF/LockService/スクリプトプロパティ…)もたくさん並びます。でも、あなたが読んで理解する必要は、まったくありません。 あれは全部、AIへの「お願いごと」です。長いのは、「やってほしいこと」と「やってほしくないこと」を正直に念押ししているから。意味の分からない文字列が出てきても、どうか手を止めずに、枠ごと一度にコピーして、貼ってください(途中で切らないのがコツです)。

あなたはGoogle Apps Script(GAS)の熟練エンジニアです。これから指示する仕様を満たす「自分専用の受発注・請求 秘書」のGASを、コピーして貼ればそのまま動く完成形で書いてください。専門用語の説明は不要です。コードと、コード内の日本語コメント(非エンジニアにも分かる代弁口調・誇大表現なし・正直)だけを返してください。冒頭に長い前置きはいりません。コメントは実際のコードの動きと必ず一致させ、「やる」と書いて実装しない死にコメントは残さないでください。仕様が多いので、下の【章】を上から順に、ひとつのスクリプトとして全部実装してください。

【作るもの(一言)】
スプレッドシートに紐づくGAS。個人事業・小規模事業者の「受注→見積→納品→請求→入金」を、シート+GAS+AI(Gemini)で半自動化する。注文を受注台帳に集約し、見積書・納品書・請求書・領収書をPDFで作り、消費税・インボイス(適格請求書)に対応し、在庫を引当・出庫し、売上と未請求・未入金を集計する。AIがやるのは「注文メールから項目を抜き出す」抽出だけ。税額・売上・在庫などの数値はすべてコードが決定論的に計算する(AIは数字に一切関与しない)。

【絶対にやらないこと(正直に。コメントにも明記)】
– メールを自動送信しない。見積・請求・督促のメールは Gmail の「下書き」を作るところまで(GmailApp.createDraft のみ。sendEmail はしない=誤送信・個人情報流出・送信枠浪費を防ぐ)。例外は在庫アラートだけで、これは自分宛て(自社メール)にのみ送る=顧客には絶対に送らない。
– 送金・決済・口座振替は一切扱わない。入金消込は台帳に「入金日・入金額」を記録するだけ。
– 内税(税込)モードは作らない。外税のみ(フェーズ2送り)。自社情報の「税の扱い」は『外税』しか選べないプルダウンにし、もしシートを直接書き換えて内税にしても、書類生成は中止する(外税計算で過大請求になるのを防ぐ)。
– PDFに画像(ロゴ・印影)は埋め込まない(HTML→PDF変換で不安定なため。フェーズ2送り)。自社情報にURL欄だけ用意し、書類本体は table+インラインstyle だけで作る。
– 情報の真偽判定はしない。税区分は簡易対応で、要否は顧問税理士/国税庁の最新情報で確認する前提(全書類のフッターに注記を入れる)。
– 破壊的操作はしない(読む・書き足す・新規シート/PDFを作るだけ)。初期化は「未存在のシートだけ」を作り、既にあるシートには一切触らない(破壊ゼロ)。集計・グラフ・売上グラフのシートだけは clearContents で書き直してよい(読み取り専用ビューのため)。PDF化のとき同名の古いファイルをゴミ箱に送るのは可だが、それ以外の既存ファイルには触れない。

【秘密情報(直書き禁止)】
GeminiのAPIキーは PropertiesService.getScriptProperties() から読む。プロパティ名は GEMINI_API_KEY を正とし、古い名前でも無言で劣化しないよう getProperty('GEMINI_API_KEY') || getProperty('GEMINI_KEY') の順で読む。記事・コード・コメントで案内する名前は GEMINI_API_KEY に統一する。キー未設定でも、メール取込以外(フォーム取込・帳票・在庫・集計)は全部動くこと(AIは抽出専用なので、未設定なら抽出を諦めて『要確認』で行を残すだけ)。

【Geminiの呼び方と$0で収まる守り】
– モデルは gemini-2.5-flash(無料枠)。URLは https://generativelanguage.googleapis.com/v1beta/models/gemini-2.5-flash:generateContent 、ヘッダは { 'x-goog-api-key': GEMINI_API_KEY }、generationConfig で responseMimeType:'application/json' を指定しJSONで返させる(出力を安定させるため temperature:0、maxOutputTokens:512 も固定する)。muteHttpExceptions:true で受け、HTTP 429(順番待ち)と500番台(混雑・サーバ側エラー)は 10秒→20秒→30秒 とバックオフを伸ばしながら最大4回やり直す。返り値は “`json を除いてから JSON.parse し、失敗時は抽出を空にして素のまま残す。
– 1回の実行でGeminiを呼ぶのは上限10回まで(安全定数 const GEMINI_上限=10; を置き、余力を関数 Gemini余力あり() で判定して超えそうなら残りは次回に回す)。メール取込は1実行あたり最大20件。AIは「メール本文からの項目抽出」だけに使い、税額・売上・在庫・PDFの数値計算には一切使わない(これらは全部コードの決定論的計算)。

────────────────────────────────────────
【章1|基盤シート(初期化が未存在時だけ作る・既存破壊ゼロ)】
────────────────────────────────────────
関数 初期化_必要シート() が、下の作成関数を順に呼ぶ:作る_受注台帳/作る_明細/作る_商品マスタ/作る_取引先マスタ/作る_自社情報/作る_採番/作る_在庫/作る_在庫履歴。各 作る_* は、そのシートが既にあれば何もせず即 return(既存は一切壊さない)。onOpen の冒頭でも 初期化_必要シート() を try で1回呼ぶ。

■受注台帳(先頭タブ・23列・1受注=1行・列定数を持つ)
列順を固定:受注ID/受付日時/入口/状態/取引先/敬称/取引先メール/件名(用途)/希望納期/税抜計/消費税計/税込計/見積番号/納品番号/請求番号/見積PDF/納品PDF/請求PDF/請求日/入金日/入金額/備考/元メールID(回答ID)。
・受注IDは主キー(明細のA列=受注IDと一致)。元メールID列は、メール入口の二重取込を防ぐ冪等キー。
・入口はプルダウン2値『フォーム/メール』。状態はプルダウン7値(下の章6の遷移)。敬称はプルダウン『御中/様』。
・税抜計/消費税計/税込計は「明細を合算して書き戻した結果」=直接編集しない派生値。
・サンプルを1行だけ入れる(受注ID=R-DEMO-0001=採番空間の外にして本番の連番とぶつけない)。投入後に 受注合計再計算 を1回呼んでおく。

■明細(10列・1品=1行・列定数を持つ・真実は明細側)
受注ID/行番号/品名/数量/単位/単価(税抜)/税率(プルダウン 10%/8%)/軽減対象(チェックボックス)/金額(税抜)/備考。
・読み取りは行位置ではなく受注IDで突合する(明細を読む=受注IDで絞り、行番号で並べ替えて返す)。並べ替え・行ズレに強くする。
・金額(税抜)=Math.round(数量×単価) を明細書き込み時に1回だけ確定し、以後は丸めない。
・台帳の税抜計/消費税計/税込計は、この明細から章7の税計算で算出して書き戻す(書類ごとに独自計算しない=食い違い防止)。
・サンプル受注(R-DEMO-0001)に紐づく明細を2行入れる。

────────────────────────────────────────
【章2|各マスタ(セルを埋めるだけ)と自社情報】
────────────────────────────────────────
■商品マスタ(5列):品名/定価(税抜)/軽減税率対象(チェックボックス)/単位/備考。明細の品名と一致させると、単価・単位・軽減フラグの初期値になる(明細側で上書きでき、明細が優先)。ヘルパ 商品辞書() が {品名:{定価,軽減,単位}} を返す。

■取引先マスタ(7列):取引先名/敬称(御中/様)/郵便番号/住所/担当者/メール/備考。ヘルパ 取引先辞書() が参照。メールは下書きの宛先に使うが、自動送信はしない。

■自社情報(縦持ち・項目/値の2列):会社名/屋号・郵便番号・住所・電話・メール・振込先・支払期限・インボイス対応(ON/OFFプルダウン・既定OFF)・登録番号・端数処理(切捨/四捨五入/切上プルダウン・既定切捨)・税の扱い(プルダウンは『外税』のみ=内税は選べない)・ロゴURL・印影URL。
・ヘルパ 自社設定(キー) でキー参照、インボイスON() は 自社設定('インボイス対応')==='ON'。
・後付けで「在庫アラート通知(ON/OFF・既定OFF)」の行を、関数 在庫_自社アラート行を保証() が冪等に追加する(既にあれば足さない)。

────────────────────────────────────────
【章3|採番(表示はシート・実体はスクリプトプロパティ+ロックで原子化)】
────────────────────────────────────────
■採番シート(4列):種類/接頭辞/年度/現在連番。行は 受注=R・見積=Q・納品=D・請求=I・領収=RC・発注=PO。これは「表示用の台帳」に過ぎない。
■ヘルパ 文書番号(種別):LockService の ScriptLock で原子化し、年度別キー SEQ_<種別>_<年> をスクリプトプロパティでインクリメントする(同時実行の番号衝突・歯抜けを防ぐ。シートのカウンタは直接incrementせず、反映表示にだけ使う)。採番シートへ反映で表示も更新する。形式は『接頭-YYYY-NNNN』(NNNNは4桁ゼロ詰め、例 I-2026-0007)。暦年でリセット(4月始まりにしたいなら年計算だけ差し替え)。

────────────────────────────────────────
【章4|帳票PDF(見積/納品/請求/領収・HTML→PDF・画像なし)】
────────────────────────────────────────
■生成前バリデーション(どの書類も共通・PDFを作る前に止める)
・内税ガード:自社設定('税の扱い')==='内税' なら中止(外税計算による過大請求を防ぐ)。
・単価が0以下(負値含む)や数量が負の明細があれば中止(マスタ定価か明細単価の入力を促す)。
・請求書で、かつインボイスON のときは、登録番号が ^T\d{13}$ に合致しなければ中止(不正な適格請求書を出さない)。ヘルパ 登録番号検証 を使う。

■番号とHTML
・番号は既にあれば再利用、無ければ章3で採番(再生成しても請求番号などは不変)。
・HTMLは table+インラインstyle だけで組む(span も使わない/flex・grid・class・<style>・position・float・画像・絵文字は使わない)。font-family は 'serif'/'sans-serif' のみ。金額は右寄せで ¥+3桁区切り。軽減税率対象の品は、品名の末尾に全角「※」をテキストで付ける(色や記号画像は使わない)。差し込む可変値はすべて esc() でHTMLエスケープする。
・共通部品を関数に切る:書類ヘッダHTML/宛名HTML(『{取引先} {敬称}』)/明細テーブルHTML/合計ブロックHTML/発行者ブロックHTML/凡例フッターHTML/書類ラッパHTML。書類ごとの本体は 見積HTML/納品HTML/請求HTML/領収HTML。
・PDF化は HTMLをPDF保存:Utilities.newBlob(html,'text/html').getAs('application/pdf') で変換し、Drive上の専用フォルダ「受発注 書類」へ保存(無ければ作成)。同名の古いファイルは先にゴミ箱へ送ってから保存する。
・メニューからの入口:書類_見積/書類_納品/書類_請求 は 書類を作る(種別) を呼ぶ。書類_領収 は専用関数。いずれも受注台帳でアクティブな行=受注IDを起点にし、ヘッダ行や未選択なら中止する。

■インボイスON/OFFで「印字」だけ切り替える(計算は不変)
・請求書の題字:ON『適格請求書』/OFF『御請求書』。
・発行者ブロックHTML(登録番号を出すか):ONのときだけ登録番号を印字。
・合計ブロックHTML(計, 税率別消費税を出すか):ONのときだけ税率別の消費税額を印字(OFFは区分記載相当=登録番号・税率別税額を省くが、税率別小計と税込総額は出す)。額が0の税率行は省略。
・請求書は冒頭に「ご請求金額 ¥… (税込)」を大きく囲んで出し、振込先・支払期限を載せる。見積書は希望納期を載せ税率別消費税額を出す。納品書は税率別消費税額を省略可(区分小計+総額)。

■状態は「前進だけ」更新(巻き戻し禁止)
ヘルパ 状態を前進:現状態の順序インデックスが目標より小さいときだけ書き換える。失注や空からは目標へ再開してよいが、進んだ状態を戻さない。見積→『見積中』、納品→『納品済』+章8の 在庫_出庫、請求→『請求済』+請求日(未記入のときだけ)をセット。各処理の末尾で必ず 受注合計再計算 を呼ぶ。

■領収書(書類_領収)
・入金日・入金額が記録済みであることを要求(無ければ入金消込を案内して中止)。インボイスON時は登録番号検証。
・領収HTMLは領収金額・但し書きを出す。ONかつ満額入金なら税率別内訳(適格簡易請求書相当)を載せ、一部入金なら内訳は出さず請求書参照を案内(領収額と矛盾させない)。PDF生成に失敗したら「番号は欠番」と明示する。

■フッター注記(全書類・コード固定文字列)
・取引年月日注記(発行日を取引年月日として記載する旨。請求書フッターで明示)。
・税注記(簡易対応・要否は顧問税理士/国税庁の最新情報で確認、の固定文)を全書類フッターに連結。

────────────────────────────────────────
【章5|受注取込(フォーム=主入口/メール=補助入口)】
────────────────────────────────────────
■フォーム(受注確定として入る)
・onフォーム送信(e):冒頭で初期化→フォーム回答ID(e)(回答ID→namedValuesのタイムスタンプ→書込行番号 の順で冪等キーを決める。接頭 F-)を取り、既出なら何もしない。フォーム値を取り出す(e) がラベルの正規表現(取引先/品名/数量/単価/納期/件名/備考)で各値に振り分ける。フォーム明細をパース は、品名・数量・単価を行内改行で複数品にzipし、品名が空の行はオブジェクトごとスキップして行ズレを防ぐ。
・受注IDを採番→新規受注行→台帳に追記→明細を展開→受注合計再計算。フォーム送信=受注確定なので状態は『受注』で入れ、章8の 在庫_引当 を呼ぶ(在庫でエラーが出ても受注取込は落とさない=try の空catchで握る)。例外時は『(エラー)』行を状態『要確認』で残す。
・フォームを接続:フォームの編集URL/IDを受け、フォームID抽出 でIDを取り onFormSubmit のインストール型トリガーを作る(既に接続済みなら重複作成しないようガード)。

■メール(必ず『要確認』で入る=人の確認前提)
・メール取込(silent):Gmailを label:注文 is:unread で検索(最大20件=メール取込_最大件数)。各スレッドは先頭メッセージ1通を対象にする。既に処理済みのメールIDはスキップして既読化。本文を Gemini余力あり() の範囲で メール抽出(本文は先頭4000字に切り詰めてからAIへ渡す=$0/トークン節約。JSONのみを返させ、読み取れない項目は空/0、推測補完は禁止というプロンプト)。抽出に失敗したら、差出人名から取引先を推定し、本文先頭200字を備考に残す(落とさない設計)。
・メール由来は必ず状態『要確認』で投入する。抽出に品名があれば明細を展開し受注合計再計算。
・メール取込_手動 はメニュー用。メール取込トリガー有効化 は メール取込_定期 を30分間隔のインストール型トリガーで作る(重複ガード)。単純トリガーは外部取得の権限が出ないので、必ずインストール型で作る。

────────────────────────────────────────
【章6|状態遷移(受注台帳・プルダウン7値)】
────────────────────────────────────────
状態は『要確認 → 見積中 → 受注 → 納品済 → 請求済 → 入金済』。どの状態からでも『失注』へ行ける(取消・不成立)。見積を出さない取引も多いので『見積中→受注』は必須経路にしない。フォーム入口は最初から『受注』、メール入口は『要確認』。状態は集計の絞り込みキー(未請求=受注/納品済、未入金=請求済)なので自由入力でなくプルダウン固定。書類発行による更新は章4の 状態を前進 のみ(巻き戻さない)。

────────────────────────────────────────
【章7|インボイス税計算(外税固定・税率別区分・1回丸め)】
────────────────────────────────────────
不可侵の3原則:(1)金額は全て整数円・内部に小数円を残さない。(2)消費税の端数処理は『税率ごとに区分合計した後、税率ごとに1回だけ』丸める(明細行ごとに消費税を出して丸めて足すのは禁止)。(3)インボイスON/OFFで計算は変えない(変わるのは印字だけ・税額は常に内部計算)。

ヘルパ 税計算(明細, 端数法):
区分 = {10:0, 8:0}
明細ごとに 区分[ 軽減対象?8:10 ] に 金額(税抜)(=Math.round(数量×単価))を足す
税率10・8それぞれで 税額[税率] = 丸め(区分[税率]×税率/100, 端数法) ← ここで税率ごとに1回だけ丸める
税抜計=Σ区分/消費税計=Σ税額/税込計=税抜計+消費税計
ヘルパ 丸め(額,法):四捨五入=Math.round/切上=Math.ceil/既定 切捨=Math.floor。
軽減対象は税率8%として集計する。受注合計再計算 がこの結果を台帳J/K/Lへ書き戻す。登録番号検証 は ^T\d{13}$。
(検算例:105円×3行=315円・10%は「区分合算→1回丸め」で消費税31円。明細ごと丸めだと30円。法令準拠の1回丸めを採る。)

────────────────────────────────────────
【章8|在庫(品名キー・履歴が冪等の根拠・LockServiceで直列化)】
────────────────────────────────────────
■在庫シート(10列・列定数):品名/現在庫数/引当数/利用可能/発注点/状態/最終更新/棚卸実数(任意)/備考/入荷予定。初期行は商品マスタの品名で作る(現在庫0・発注点0。ただしデモ在庫として 精密部品A=[現在庫50,発注点20]/梱包材(食品用)=[100,30] は実値)。ヘルパ 在庫マップ() が {品名:{行,現在庫,引当,発注点,入荷予定}}。
■在庫履歴シート(9列・列定数・追記専用=冪等の根拠):日時/種別/品名/数量/関連受注ID/関連伝票/操作後 現在庫/操作後 引当/メモ。種別=入庫/引当/引当解除/出庫/棚卸調整/発注。

■状態判定 在庫状態文字(現,引,点):発注点>0 の品だけが発注管理の対象。欠品(現≤0)>要発注(利用可能=現−引≤点)>適正。発注点0の品(サービス・送料等)は『—』『適正』で、発注書・アラート・集計の対象外。

■中核 在庫を動かす(品名, d現在庫, d引当, 種別, 受注ID, 伝票, メモ):先に在庫履歴を1行記録してから在庫セルを更新する(途中で失敗しても「履歴あり・セル未更新」の安全側に倒れ、履歴ベースの冪等ガードが二重計上を防ぐ)。利用可能・状態・最終更新も更新。引当はマイナスにしない。
■直列化:在庫の read-modify-write は 在庫ロック取得(LockService の ScriptLock・tryLock 20秒)で排他する(同時フォーム送信のロストアップデート・重複行・判定と更新の割り込みを防ぐ)。
■冪等の根拠は在庫履歴:出庫済か/出庫済_品目(品名単位)/純引当(Σ引当−Σ引当解除)/受注の純引当総量/純引当品名一覧 を履歴から算出する。

・在庫_引当(受注ID):出庫済ならスキップ。明細の必要数から既引当を差し引いた不足分だけ予約(部分引当後の再実行・明細追加に追従=冪等)。
・在庫_引当解除_実行:履歴上で純引当>0 の全品名を解除(品名変更・削除後も取りこぼさない)。出庫済なら何もしない。在庫_失注 から呼び、状態を『失注』へ直接セット(単線フロー外)。
・在庫_出庫(受注ID):納品=実出庫。失注受注は出庫しない。品名単位に集約し、現在庫を出荷数ぶん減らし、予約していた引当を1回だけ解放(出庫済_品目 で品名単位に冪等=再発行・部分失敗の再実行でも二重出庫しない)。章4の納品書発行から呼ばれる。
・在庫_受注確定:状態を『受注』へ前進+在庫_引当+再計算。引当できたら発注点チェック。
・在庫_失注:在庫_引当解除_実行 を呼ぶ。
・在庫_入庫を登録:品名・数量・メモをプロンプトで受け、在庫を動かす(…'入庫')+在庫_入荷予定を消し込む(発注書で立てた入荷予定を消込)。
・在庫_棚卸を反映:在庫シートの棚卸実数列を読み、非数値は反映せず欄も残す(誤って現在庫を0にしない)。差分を『棚卸調整』として履歴記録し現在庫へ反映、反映できた行だけ欄をクリア。
・在庫_発注点チェック(silent):要発注・欠品を集計。自社情報『在庫アラート通知』がONなら自社メール(自分宛て)にだけ通知する(顧客には絶対に送らない)。
・書類_発注:要発注品リスト(推奨発注数=発注点の2倍まで戻す目安、発注点0なら最低1、入荷予定で足りる品は除外)から 発注HTML をPDF化。採番・PDF生成・入荷予定加算を同一ロック区間で原子的に行い、ロック失敗・PDF失敗時は何も確定させない(番号歯抜け・二重発注・嘘の成功表示を防ぐ)。在庫_入荷予定を加算 は履歴に『発注』行を残す(現在庫・引当は不変)。
・マイグレーション:在庫_入荷予定ヘッダを保証(旧9列シートに入荷予定列10の見出しを冪等付与)、在庫_再構築(後付け・商品マスタ品名の不足行追加・全行の利用可能/状態を再計算)。

────────────────────────────────────────
【章9|入金消込・督促(送信せず・人の承認前提)】
────────────────────────────────────────
■入金_消込:既に入金日があれば上書き確認。請求未発行ガード=請求番号・請求日が両方空なら中止(売上集計/グラフ/CSVが請求日基準なので整合を強制)。状態が請求済/入金済でなければ続行確認。入金日(空=今日)・入金額(空=請求税込計)を記録し、状態を『入金済』へ前進。請求額との差を過不足として表示。
■送信_督促下書き:入金済なら不要として中止、請求済以外は続行確認。経過日数(請求日からの日数・不正/空は-1)を算出し 督促本文(丁寧文・行き違い配慮)で createDraft。経過日数は0以上のときだけ本文に明記し、-1(請求日不明)のときは経過行を出さない。請求書PDFがあれば添付(失敗時は手動添付を案内)。自動送信しない。
■メール下書き(見積/請求):送信_見積下書き/送信_請求下書き は 送信_書類下書き(種別) を呼ぶ。先にPDFが作成済みであることを要求し、DriveからPDFを取得して GmailApp.createDraft で下書きだけ作る。宛先は 取引先メール→マスタ→手入力プロンプト の順。本文は メール本文テンプレ(請求時は税込金額・支払期限を記載)。ダイアログで「自動送信はしません(誤送信防止)」と明示する。

────────────────────────────────────────
【章10|集計・月次グラフ・CSV(請求日ベース・読み取り専用)】
────────────────────────────────────────
■集計を出す:集計シートを clearContents してから、ブロック構成で書き出す(今月売上/取引先別売上/未請求一覧/未入金一覧/在庫の要発注一覧)。請求日ベースで、状態が請求済・入金済のものだけ計上。今月売上=請求日が当月かつ請求済/入金済。取引先別売上=降順。未請求=状態が受注/納品済。未入金=状態が請求済を経過日数の降順(督促優先・不明は-1で安定ソート=「(請求日不明)」表示)。Gemini は使わない(決定論的集計)。
■グラフ_月次売上:請求済・入金済を請求日で月別集計し、直近12ヶ月を売上グラフシート(列『月/売上(税込)』)へ clearContents して書き出し、既存チャートを全て消してから ColumnChart を挿入。
■CSV_書き出し:対象年月(空=全期間)を受け、請求済・入金済の確定データをCSV化し、Drive「受発注 書類」フォルダ(帳票PDFと同じ)へ保存。ヘルパ csvセル で数式インジェクション対策(先頭が = + – @ タブ 改行 のセルは ' を前置して無害化)+カンマ/改行/引用符のエスケープ。UTF-8 BOM付(先頭に BOM を付与)でExcelの文字化けを防ぐ。

────────────────────────────────────────
【章11|メニュー(onOpen)とセットアップ補助】
────────────────────────────────────────
onOpen は冒頭で 初期化_必要シート() を try で実行し、メニュー「受発注秘書」を作る。トップ項目:初期化(シートを作る)→初期化_必要シート/注文メールを今すぐ取込(要確認で追加)→メール取込_手動/注文メールの定期チェックを有効化→メール取込トリガー有効化/フォームを接続(送信→受注台帳)→フォームを接続/選択行から 見積書PDF→書類_見積/納品書PDF→書類_納品/請求書PDF→書類_請求/領収書PDF→書類_領収/見積書を添付してメール下書き→送信_見積下書き/請求書を添付してメール下書き→送信_請求下書き/選択行に督促メール下書き(未入金)→送信_督促下書き/選択行を入金済にする(入金消込)→入金_消込/選択行の合計を再計算→再計算_選択行/今月の売上・未請求・未入金を集計→集計を出す/月次売上グラフを作成→グラフ_月次売上/会計用CSVを書き出す→CSV_書き出し/シートの見た目を整える→整える(受注台帳/明細/各マスタ/採番/在庫/在庫履歴のヘッダ帯のみ整え、読み取り専用ビューの集計・売上グラフは触らない)。
在庫サブメニュー(addSubMenu('在庫')):選択行を受注確定(在庫を引当)→在庫_受注確定/選択行を失注(在庫の引当を解除)→在庫_失注/入庫(仕入・入荷)を登録→在庫_入庫を登録/棚卸の実数を反映→在庫_棚卸を反映/発注が必要な在庫を確認→在庫_発注点チェック/発注が必要な品の発注書PDF→書類_発注/在庫シートを作る/整える→在庫_再構築。
(メニュー外のセットアップ:セットアップ_注文受付フォーム作成と接続=注文受付フォームを生成しトリガー接続/セットアップ_ダミーデータ投入=自社情報をインボイスON・登録番号T付きにし商品・取引先を追記。メール取込_定期 はトリガー専用、onフォーム送信 はフォーム送信トリガー専用。)

【小道具】esc(s)/三桁(n)/和日付(d)/整数化(v)/ymd(d) など。コメントは必ず実装と一致させ、死にコメントを残さないこと。

以上の仕様を満たす完成コードを、コピーして貼ればそのまま動く形で出力してください。

実際に、1件つくってみる

言葉だけだとピンと来ないので、注文が1件入ってから請求書ができるまでを、順に追ってみます。

まず試すなら、自分でフォームに1件、テスト注文を入れてみるのが最短です(お客さまを待つ必要はありません)。フォームを作るのがまだなら、後述の「メール取込」で試すこともできます。

1. フォームから注文が入る。 フォームを送信すると、受注台帳に1行増えます。取引先名・件名・希望納期が入り、状態は「受注」。同時に、注文された品が「明細」シートに展開されます。

2. 明細を見る。 受注台帳の1行は「この注文の表紙」です。中身(どの品を、いくつ、いくらで)は、「明細」シートに並びます。受注台帳の合計欄(税抜計・消費税計・税込計)は、この明細を合算した“結果”が自動で入るだけ。ほんとうの中身は、いつも明細側にあります。

受注台帳と明細(同じ受注IDで突合)

3. 見積書PDFを作る。 受注台帳でその注文の行を選び、メニュー「選択行から 見積書PDF」を押します。宛名・件名・品目・金額・消費税まで入った見積書が、PDFになってDriveの「受発注 書類」フォルダに保存されます。番号(Q-2026-0001 のような形)も自動で振られます。

4. 請求書PDFを作る。 お客さまの了承が取れたら、同じ行を選んで「選択行から 請求書PDF」。今度は請求書ができます。冒頭に「ご請求金額 ¥◯◯(税込)」が大きく囲まれ、振込先と支払期限も載ります。請求番号も自動採番(I-2026-0001 のような形。※見積と請求は別々の連番なので、番号は揃っていなくても正常です)。

5. インボイスをONにしているなら、適格請求書になる。 自社情報の「インボイス対応」を ON にして登録番号を入れてあれば、請求書の題字が「適格請求書」になり、登録番号と、税率別(10%・8%)の消費税額がきちんと印字されます。OFFのままなら、ふつうの「御請求書」が出ます。どちらでも、計算そのものは変わりません(変わるのは“印字”だけ)。

適格請求書PDF(税率別消費税・登録番号入り)

ここまでで、「注文フォーム → 受注台帳 → 明細 → 見積書PDF → 請求書PDF」が、ひとつながりになりました。打ち直しは、どこにもありません。

ただし——初めて使う一件目だけは、出てきた金額を必ず自分で検算してから使ってください。 秘書の計算手順はいつも同じですが、「いつも同じ」と「いつも正しい」は別のことです。最初の一度だけ、税抜・消費税・税込が手元の電卓と合うか確かめておけば、あとは安心して任せられます。

メールでの注文も、取りこぼさない(補助の入口)

注文がいつもフォームから来るとは限りません。「メールで見積依頼が来た」——そういう日もあります。そのために、補助の入口も用意してあります。

注文メールに、Gmailで「注文」というラベルを付けておきます。メニューの「注文メールを今すぐ取込(要確認で追加)」を押すと、ラベルの付いた未読メールから、AIが取引先名・品名・数量などを読み取って、受注台帳に1行足してくれます。

ただし——ここが大事なところ。メールから入った注文は、必ず状態が「要確認」で入ります。 メールの文面は人それぞれ書き方が違うので、AIの読み取りが完璧とは限らない。だから「いったん仮置きしました。中身を人の目で確かめてください」という状態で、止めてあります。読み取れなかったときも、行を捨てたりはせず、メールの差出人と本文の冒頭を備考に残して「手で直してください」と残します。取りこぼさず、でも勝手に確定もしない。 メールはあくまで“補助の入口”です。注文の本線は、フォームのほうがおすすめです。

見積書や請求書を、メールの“下書き”まで作る(送信はしません)

できあがった見積書・請求書PDFは、メールに添付して送るところまで——いえ、「下書き」を作るところまで、秘書が手伝います。

メニューの「見積書を添付してメール下書き」「請求書を添付してメール下書き」を押すと、Gmailに下書きができます。宛先(取引先マスタに登録があれば自動)、件名、ていねいな本文、そしてPDFの添付まで、ぜんぶ揃った状態で。

でも——秘書は、自分でメールを送りません。 作るのは下書きまで。最後に内容を確かめて「送信」を押すのは、あなたです。これはわざとです。 お金の絡む書類を、宛先を間違えたまま自動で飛ばしてしまったら、取り返しがつきません。だから、最後のひと押しだけは、必ず人の手に残してあります。

裏側のしくみ(ここは読み飛ばしてOK)

ここは、仕組みに興味がある人だけ、のぞいてください。読み飛ばしても、秘書はちゃんと動きます。

  • 消費税は「税率ごとにまとめてから、1回だけ」丸めます。 品ごとに消費税を出して丸めて足し算すると、1円ずれることがあります。だからこの秘書は、まず10%の品だけ、8%の品だけ、と税率ごとに税抜きを合計してから、その合計に対して税率ごとに一度だけ端数処理をします(これが法令の考え方に沿った計算です)。
  • 番号は、同じ番号が二重に振られないようにしてあります。 見積・請求・受注…それぞれに年度別の連番を、内部で安全に管理しています(順番待ちのしくみ=ロックを噛ませて、同じ番号が二重に出ないようにしています)。一度振った請求番号は、書類を作り直しても変わりません。なお、まれにPDFの作成に失敗すると、その番号が1つ飛ぶこと(欠番)はあります——番号が連続していなくても、二重になっていなければ問題ありません。
  • 真実は、いつも「明細」側にあります。 受注台帳の合計欄は、明細を合算した“結果の表示”にすぎません。だから書類ごとに金額を別々に計算して食い違う、ということが起きません。どの書類も、同じ明細から、同じ手順で金額を出します。
  • AIは、数字に一切タッチしません。 この秘書でAIが手伝うのは、「メール本文から注文の項目を読み取る」抽出だけ。税額・合計・番号といった数字の計算は、すべてコードが決まった手順で行います(AIに足し算をさせたりはしません)。だから金額は、何度作っても同じ結果になります——ただし、これは「計算がブレない」という意味であって、「税区分まで正しい」という保証ではありません。そこは最後に人と専門家が確かめる前提です。

大事なのは、この秘書がやっているのは、基本的に「読む・書き足す・新しく作る」だけだということ。既にあるシートを消したり、上書きしたりはしません。注文を記録し、明細を並べ、書類を作る。あなたのデータに、まず傷を付けない設計です。(※受注が確定すると、裏で在庫の「予約」だけは静かに進みますが、その話は次回の育てる編②で。)

そして、もう一度だけ。「データが壊れない」ことと、「請求金額が間違っていない」ことは、別の話です。 前者は設計で守れますが、後者の最終確認だけは、人の目に残してあります。

正直にできないこと(先に言っておきます)

このブログのやり方として、できないことは先に正直に言います。この秘書にも、はっきりした限界があります。

  • 外税のみです(内税には対応していません)。 金額は「税抜き単価で積んで、あとから消費税を足す」外税方式だけ。税込み単価で扱う「内税」モードは、このフェーズでは作っていません(無理に内税で運用すると過大請求になりかねないので、設定でも内税を選べないようにしてあります)。
  • PDFに、ロゴや印影などの画像は入りません。 書類は文字と罫線だけで組んでいます(HTMLからPDFに変換するとき、画像が崩れやすいため)。ロゴ・印影は、次のフェーズ送りです。
  • 金額の“正しさ”そのものは、保証しません。 計算の手順は決まっていますが、税区分の当てはめ(軽減税率かどうか等)が正しいかは別問題。初回は必ず検算し、対外に出す前に金額を確かめてください。
  • メールは“下書き”止まりで、自動送信はしません。 見積・請求・督促のメールは、Gmailの下書きを作るところまで。最後に送るのは、必ずあなたの手で(誤送信を防ぐためです)。
  • 送金・決済は、いっさい扱いません。 入金の記録はできても、お金そのものを動かす機能は持っていません。口座振替や決済は対象外です。
  • 税区分の最終判断は、しません。 軽減税率かどうか、インボイスの要否——このあたりは簡易対応です。すべての書類のフッターに「正確な要否は顧問税理士・国税庁の最新情報でご確認ください」と入れてあります。最後は、専門家と公式情報で確かめてください。

——書類を作ってくれる相手が、こうして自分の限界を正直に申告してくれること。それ自体が、わたしはいちばん信頼できるところだと思っています。

次回予告:受注の“その先”を、ひとつずつ秘書に任せていく

ここまでで、「注文が来たら、選んでボタンひとつで見積書・請求書PDF」までが、できるようになりました。でも、お金が動く業務は、請求書を送って終わりではありません。じつはこの秘書は、その“先”の道具も、もう中に持っています。これから、ひとつずつ解説していきます。

  • 育てる編①:入金消込・督促・領収。 「あの請求、入金まだ?」を見張り、督促メールの下書きを作り、入金が済んだら領収書を出すところまで。
  • 育てる編②:在庫の引当と出庫。 受注した瞬間に在庫を押さえ、納品で実際に在庫を減らす。二重に売ってしまう恐怖を、秘書が引き受けます。
  • 育てる編③:発注点チェックと発注書。 在庫が減ったら「そろそろ仕入れて」と教えてくれて、発注書PDFまで。
  • 育てる編④:集計・月次グラフ・会計CSV。 「今月いくら売れた? 未入金は?」を毎月まとめ、確定申告前のCSVづくりまで。

どれも、追加でコードを貼り直す必要はありません。 主要な部品は、もう今回貼ったコードに入っています。次回からは「メニューのこの項目を押すだけ」の解説です。コードが書けなくても、AIに任せて、ちゃんと同じところへたどり着けます。受注から請求まで、一本の道がつながった——ここまで手を動かせたあなたなら、もう、この続きも越えていけます。


※本書類の税区分・記載は一般的な実務整理に基づく簡易対応です。真偽・税区分は判定していません。最後は、元記事および顧問税理士・国税庁の最新情報でご確認ください。コードは、一行も書いていません。


このシリーズのこれまで:創刊号(入口)記事01:フォーム回答をメールで受け取る記事02:フォーム回答をLINEに即時通知記事03:フォーム回答を毎朝自動集計してLINEに通知記事04:名簿から差し込みメールを一斉送信記事05:長いGmailをAIで3行+やることリストに記事06:毎朝、未読メールを自動で要約して1通に記事07:たまった自由記述を、AIでテーマ別に分類・集計記事08:登録キーワードのニュースを、毎朝LINEに応用編その1:AI秘書「ぽけっと手帳」(全体像)応用編その2:リサーチ秘書(追いたい分野のニュースが毎朝1通)育てる編①:ためた見出しに"質問"できる(台帳Q&A)育てる編②:「医療も追って」で集める分野を増減(設定変更)育てる編③:「今週どうだった?」でためた台帳を週次まとめ育てる編④:「地図にして」でためた見出しを放射状の地図に(見出しマップ)育てる編⑤:「再エネ政策を追いたい」で検索語まで含む設定をAIが設計(設定アシスタント・完結)応用編その3:受発注・請求 秘書(受注が来たら、選ぶだけで見積書・請求書のPDFに)(この記事)受発注 育てる編①:入金消込・督促・領収書PDF受発注 育てる編②:受注した瞬間に在庫を押さえる受発注 育てる編③:発注点アラートと発注書PDF受発注 育てる編④:月次集計・売上グラフ・会計CSV(最終回)基礎編:URLひとつで“自分の申込ページ”を作る(Webアプリ)基礎編:申し込まれた瞬間に、確認メールが自動で返る基礎編:申し込んだら、控えのPDFが自動で届く基礎編:申込の控えが、勝手にドライブへ積み上がっていく基礎編:申込のひとことを、届いた瞬間にAIが仕分ける基礎編:誰も画面を開いていないのに、毎朝まとめが届く基礎編:申込が来た瞬間、ポケットのLINEが鳴る(最終回)応用編その4:申込・予約 秘書(満席の瞬間、ページが自分から閉まる)申込・予約 育てる編①:キャンセル待ちと自動繰り上げ申込・予約 育てる編②:承認制とお断り下書き申込・予約 育てる編③:前日リマインダーと毎朝まとめ申込・予約 育てる編④:管理ページ(最終回)

#GAS #請求書 #見積書 #インボイス #業務効率化 #コピペOK

コメント

タイトルとURLをコピーしました