タイムトラッキングから請求書へ:作業記録をブランドPDFに変換するアプリ
プロジェクトの作業時間を記録し、請求書にまとめてクライアント向けのブランド入りPDFを生成するタイムトラッキング→請求書アプリを構築する方法。

何を作るかと、なぜ重要か
タイムトラッキングから請求書へのアプリはよくある混乱を解消します:作業時間がカレンダー、チャット、メモに散在してしまい、請求日になると人手で月の履歴を組み立て直さなければならないことが多いです。ここでミスが起きます:請求漏れ、誤った単価、重複行、合計が合わない、など。
このアプリは時間単位で請求する人向けです:複数クライアントを抱えるフリーランス、同じプロジェクトに複数人が時間を記録するエージェンシー、クライアントや部署に時間を請求する社内チームなど。
目標は実用的であること:プロジェクトごとに作業記録を取りまとめ、請求書レコードにまとめ、クライアントが理解できるブランド入りPDFを生成すること。ワークフローが安定すれば、請求は月次の慌てる作業ではなくなります。
「まずはシンプルに」を守るポイントはだいたい次の通りです:
- 時間を記録する一つの方法(日付、プロジェクト、時間、メモ)
- 単一のレートルール(プロジェクト別か人別)
- クライアントごと期間ごとの1つの請求書
- ロゴや事業情報の入った1つのPDFレイアウト
- 明確なステータス(Draft、Ready、Sent、Paid)
小さなシナリオ:2人のスタジオが「Client A - Website Updates」の時間を追跡します。各人が週の間にエントリを記録し、金曜にそのプロジェクトと日付範囲で請求書を作成すると、アプリがエントリを請求行に変換し、再入力なしで送れるPDFができあがります。
AppMasterのようなノーコードプラットフォームを使う場合、受注前にデータモデルとワークフローを正しく設計してから、領収書や多通貨、割引、承認などの追加機能を足すと良いでしょう。コアのフローが速く、正確で、壊れにくければ、後からの拡張は簡単です。
最初に入れるコア機能(最初に除外すべきもの)
小さな初期版で「送信可能な請求書」まで持っていきましょう。フォーカスするのは3点:時間の記録、時間をわかりやすい請求行にすること、そしてクライアントが疑問なく読めるPDFを作ることです。
最初は次のレコードを用意します(後で名前は変えられますが構造が重要です):Client、Project、Time Entry、Invoice、Invoice Line。
請求フローは請求レコードの単一のステータスフィールドでシンプルに保ちます。Draft、Ready、Sent、Paid は多くのチームで長く使えます。
毎週実際に起きる操作に合わせたアクションを用意しましょう:
- 時間を記録(手動入力は通常、構築が早く修正もしやすい)
- 時間を承認(「Approved」ステータスだけでも可)
- 承認済みの時間から請求書を作成
- PDFをエクスポート
「ブランド入り」は派手である必要はありません。安定感と信頼感です:ロゴ、事業情報、請求番号と日付、明瞭な合計、支払い指示。
最初は税金、割引、多通貨、添付ファイルは後回しにしましょう。これらは便利ですが端数処理や法域ルール、為替、ファイル保存といった例外が増え、最初のリリースを遅らせます。
データモデル:必要なレコードと重要なフィールド
タイムトラッキング→請求アプリはデータモデル次第で成功が決まります。小さく予測可能に保ち、合計が常に約束通りになるように設計してください。
最小限のテーブルセットは通常こうなります:
- クライアント(Client):名称、請求先メール、請求先住所、デフォルト通貨、支払条件(例:Net 14)
- プロジェクト(Project):client_id、プロジェクト名、デフォルト時給(任意)、有効フラグ
- 作業記録(Time entry):project_id、担当者(名前またはuser_id)、日付、作業時間(hours)、説明、rate_at_time、請求対象か否か(billable)、
invoiced_invoice_id(請求されるまでは空) - 請求書(Invoice):client_id、project_id(任意)、請求番号、発行日、支払期日、ステータス、小計、税額、合計
レートはアプリでややこしくなりがちです。どれか一つの方針に決めて守ってください:プロジェクト単位のレート、担当者ごとのレート、またはタスク/サービスごとの固定レート。
デフォルトレートをプロジェクトや担当者に保存する場合でも、エントリ生成時(または承認時)に実際のレートを各作業記録の rate_at_time にコピーして保存してください。レートが後で変わっても当時の事実を保持でき、請求書は作業が行われた時点の内容を反映します。
作業記録には別のステータスを省略して invoiced_invoice_id が空かどうかで判断することが多いです。請求書側のステータスは厳密に:Draft、Ready、Sent、Paid(必要なら Void を追加)にしておくと管理しやすいです。
AppMasterでは Data Designer が PostgreSQL にきれいにマッピングされ、関係を重複させずに明確に保つのが簡単です。
プロジェクトごとに作業記録を取る(シンプルなUX)
時間記録が楽かどうかでアプリの採用が決まります。最初のバージョンは退屈でも速く:1画面、1つの主要アクション、選択肢をできるだけ減らしてください。
最初は1つの取得方法に絞るのが良いです。手動入力が最初は勝ちます。誰にでも動作し、レビューがしやすいからです。タイマーは後から、実際の使われ方を見てから追加しましょう。タイマーを入れる場合でも、停止漏れ分の手動編集は許可してください。
請求品質を守るフィールドは必須にします:
- プロジェクト(またはクライアント+プロジェクト)
- 日付
- 作業時間(時間と分)
- 短い説明(クライアントが認識できるもの)
- 担当者(複数人が記録する場合)
丸めルールは早めに決めてください。信頼と合計に影響します。一般的な方法は6分刻み(0.1時間)。各エントリごとに丸めるのか日次合計で丸めるのかを明示しましょう。エントリごとに丸める方が説明と監査が簡単です。
請求に複数人が携わる場合は軽い承認ステップを追加してください。実務的には:承認済みになったらデフォルトで編集不可にします。変更が必要な場合はマネージャーロールで再オープンして誰が何を変更したかを記録します。
作業を請求行に変換する(ロールアップルール)
ロールアップは生のログをクライアントが理解できる請求行に変える処理です。ルールはシンプルで再現性のあるものにして、生成される請求書を信頼できるようにしてください。
まず1つの操作から始めます:クライアントと日付範囲を選び、未請求の作業記録だけを引き出す。これが二重請求を防ぐガードレールです。クライアントやプロジェクトが入っていないエントリは「請求準備完了ではない」とみなし、修正されるまでロールアップに含めません。
どうやってエントリを請求行にまとめるか
グルーピングの仕方で行数が変わり、クライアントのレビューしやすさにも影響します。デフォルトを決め、必要ならオプションの切り替えを一つ用意してください。
一般的なグルーピングオプション:
- プロジェクト別
- 担当者別(レートが異なる場合に有用)
- 日別や週別
- タスク/カテゴリ別(デザイン vs 開発)
何を選んでも、各行は次を表示すべきです:わかりやすいラベル、合計時間、レート、行の金額。レートが変わる可能性があるなら、各エントリに保存された rate_at_time(または適用開始日を持つレートテーブル)を使って計算してください。現在のレート1つで計算してはいけません。
請求済みにマークする(行き詰まらない方法)
エントリを請求書に追加したら、各作業記録に請求書IDを保存してください。これが監査トレイルになり、同じエントリが再度引かれるのを防ぎます。
修正は必ず起きます。請求書から行を外す場合は履歴を消さないでください。影響を受けた作業記録の請求IDを外し(invoice IDをクリア)、合計を再算出し「誤ったプロジェクトのため2.0hを削除」などの短いメモを残します。
AppMasterでは、未請求エントリのクエリ、グルーピング、請求行作成、各エントリへ請求参照を更新するという一連のビジネスプロセスにフィットします。
請求書レコード:合計、番号付け、ステータス
請求書レコードは後で送信・追跡・監査するためのコンテナです。プロジェクト名やデフォルトレートが編集されても請求書自体は安定しているべきです。
実用的な請求ヘッダーには次を含めます:
- 請求番号(ユニークで人間が読みやすい形式)
- 発行日と支払期日
- 請求先(クライアント名、請求先住所、必要なら税ID)
- メモ(支払い指示や短い挨拶)
- 通貨(国際請求するなら保存した為替レートをオプションで)
合計は予測可能に保ちます。小計は請求行の合計、そこから割引(固定額または割合)を適用し、税(通常は割引後の小計に対して)を計算して最終合計を保存します。使った正確な税率と割引値は保存して、後で再現できるようにしてください。
請求番号は凝る必要はありません。パターンを決めて守ることが重要です:連番(000123)、年度別(2026-00123)、クライアント接頭辞+番号(ACME-014)など。整合性の方が見た目の完璧さより重要です。
ステータスはコミュニケーションと内部統制に焦点を当てます:
- Draft(編集可、未送信)
- Ready(合計ロック)
- Sent(クライアントへ共有済み)
- Paid(入金確認済み)
- Overdue(期日超過)
- Void(キャンセル、履歴のため保持)
クライアントが読みやすいブランド入りPDFを生成する
良い請求PDFは2つの質問に素早く答えます:何を請求しているのか、どう支払えば良いか。PDFは必ず請求書レコードから生成してください(生の作業記録からではなく)。そうすることでドキュメントは請求番号、合計、ステータスと常に一致します。
クライアントは通常、次のブロックを期待します:
- ヘッダー(事業名、請求番号、請求日)
- クライアント情報(会社、担当者名、請求先住所、必要なら税ID)
- 行項目(説明、数量または時間、単価、行合計)
- 合計(小計、税、割引、総合計)
- 支払い条件(支払期日、受け付ける支払方法、遅延料金の注意など)
ブランディングは重要ですが、可読性の方が優先です。アクセントカラーは1色、フォントは読みやすいものにし、合計が一目でわかるようにします。
レイアウトの問題は実データで現れます。長い説明や30行以上の項目でテストしてください。ページをまたぐ場合は列ヘッダが繰り返されるか、合計ブロックが分離されないかを確認します。
AppMasterでPDFを生成する場合、PDFは請求書の成果物として保存し、請求レコードにファイル参照と生成タイムスタンプやバージョンを保存しておくと便利です。これでクライアントに再送するときに同じドキュメントを簡単に送れます。
ステップバイステップの構築計画(ノーコードワークフロー)
「事実の源(source of truth)」を決めます。作業記録は生の事実、請求書は送付して監査できるスナップショットです。
1) まずデータを設計する
テーブルとリレーションを作り、基本が安定したらいくつかの品質フィールドを追加します:
- Clients
- Projects
- Time Entries
- Invoices
- Invoice Lines
2) 2つのシンプルな画面を作る
UIは最小限に:
- 作業記録フォーム:プロジェクト、日付、時間、メモ、保存
- 請求レビュー:クライアント、期間、行、合計、ステータス
管理とレビューにはWeb UIがあれば十分なことが多いです。外出先でログを取る人が多ければ後でモバイル画面を追加します。
3) ロールアップロジックを自動化する
フロー例:クライアント+日付範囲を選択、未請求エントリを取得、グループ化、請求行を作成。請求エントリは請求書が承認されて Ready に移るまで billed とマークしない、というルールが安全です。
4) PDFを生成して保存する
請求ヘッダー、クライアント情報、行をテンプレートに流し込み「PDF生成」アクションを追加し、出力を請求書レコードに保存します。
例:週次ログからクライアント向け請求書へ
3人のエージェンシーがクライアント Northstar Co を一社持ち、2週間にわたって Website Refresh と Monthly Support の二つのプロジェクトを請求します。チームは Alex(デザイン)、Priya(開発)、Sam(PM)。全員が日次でクライアント、プロジェクト、日付、短いメモを選んで時間を記録します。
毎日エントリは Draft として保存され、金曜に Sam が「今週、Northstar Co」でフィルタしたレビュー画面を開き、メモを修正し(例:「Hero」→「Homepage hero」)、請求可否を確認して週をロックします。
その週のサンプルエントリ:
| Date | Person | Project | Hours | Note |
|---|---|---|---|---|
| Mon | Priya | Website Refresh | 2.5 | Header layout fixes |
| Tue | Alex | Website Refresh | 3.0 | New homepage mock |
| Tue | Sam | Monthly Support | 1.0 | Client call |
| Wed | Priya | Website Refresh | 4.0 | Contact form logic |
| Thu | Alex | Monthly Support | 1.5 | Banner update |
| Thu | Priya | Monthly Support | 2.0 | Email template tweak |
| Fri | Sam | Website Refresh | 1.0 | QA and handoff |
Samが「Create invoice」をクリックすると、アプリは単純なルールでエントリを請求行にまとめます:プロジェクトとレートでグループ化、時間を合算、短い説明を持ってくる。結果、請求書には3行になります:
| Line | Description | Qty | Rate | Amount |
|---|---|---|---|---|
| 1 | Website Refresh (Design) | 3.0 hrs | $120 | $360 |
| 2 | Website Refresh (Development/PM) | 7.5 hrs | $140 | $1,050 |
| 3 | Monthly Support | 4.5 hrs | $110 | $495 |
システムは請求番号(例:NS-2026-014)を割り当て、小計と税を計算しステータスを Ready に設定します。もう一押しでブランド入りPDF(ロゴ、クライアント住所、行明細、合計、支払いメモ)が生成され、送信後はステータスが Sent に更新され、基になっている作業記録には請求済みフラグが付いて二重請求を防ぎます。
よくあるミスと回避法
多くの問題は算数のミスではなくワークフローの問題です。
請求済み作業をロックしない。 編集や再選択が可能だといずれ二重請求が起きます。各作業記録に請求書参照を持たせ、請求準備画面から請求済みを隠すことで解決します。
レート変更で履歴を書き換える。 「現在の」プロジェクトやユーザーレートだけで計算すると古い請求が変わってしまいます。各エントリに有効レートを rate_at_time として保存してください。
承認済み作業を監査なしで編集する。 編集には「承認者」「承認日時」「変更理由の短いメモ」を残すようにしてください。
実データで壊れるPDFテンプレート。 長い説明や多数の行、桁数の大きい金額でテンプレートが崩れることがあります。
簡単な対策:
- 説明の最大長を設定し、溢れた分はノート欄へ移す
- 折り返しを許可し、30行以上でテストする
- ヘッダーをコンパクトにしてテーブルの領域を確保する
- 数値形式(通貨、小数)を統一する
あいまいなステータスフロー。 ルールがないと二重送付や送付忘れが起きます。
シンプルで安全なフローは:Draft → Ready → Sent → Paid。ロールアップは Draft のときのみ許可し、合計がロックされた Ready のときだけPDF生成を許可するようにします。
短いチェックリストと実務的な次の一手
請求を送る前に素早くレビューすると、最も一般的なミスを防げます:合計間違い、詳細不足、画面では問題ないが印刷で崩れるPDFなど。
送信前チェック:
- クライアント情報が完全か(正式名称、請求先住所、正しい担当)
- 請求期間が正しい(開始日と終了日が作業に一致している)
- 合計が一貫している(小計、税、総合計がエントリ、レート、丸めと合う)
- 作業の抜けや重複がない(未請求が残っていない、同じ作業が重複していない)
- 運用フィールドが整っている(ユニークな請求番号、正しいステータス、請求書にPDF保存済み)
次にPDFをプリントする目でプレビューします。ロゴの位置、長い住所、テーブルの折り返し、ページ区切りをチェックしてください。短い請求(1〜2行)と長い請求(20行以上)の両方でテストします。
基本が安定したら次へ進めます:
- メールテンプレートで請求書を送信する
- Stripe等を接続して入金で自動的にPaidにする
- レート編集、時間承認、ステータス変更をできるロールを設定する
コアを素早く作って反復したいなら、AppMasterは実用的な選択肢です。データベース、ビジネスロジック、PDF生成が揃っており、要件が変わってもコードを再生成して作り直さずに対応できます。
今週一つだけ改善するとしたら、「未請求の時間が見落とされない仕組み」を作ってください。それだけで数時間を節約し、収入を守れます。
よくある質問
まず全ての作業記録にプロジェクト、日付、作業時間、短い説明があることを確認します。次にクライアントと日付範囲を選んで、未請求のエントリだけを引き出し、それらを請求行にグループ化して、請求書スナップショットからPDFを生成します。
基本的に5つのレコードを使います:Client、Project、Time Entry、Invoice、Invoice Line。各作業記録には rate_at_time を含め、請求履歴を一貫して保つために invoiced_invoice_id への参照を持たせます。
作業が行われた時点で使われたレートを各作業記録に保存してください(例:rate_at_time)。デフォルトレートはプロジェクトや担当者に置けますが、請求は保存されたレートを使って計算し、過去の請求が後から変わらないようにします。
ルールを一つ決めて徹底し、プロセスで可視化してください。一般的には6分刻み(0.1時間)で各エントリを丸める方法が監査しやすく、請求合計が予測しやすくなります。
請求書に1つのステータスフィールドを持たせ、シンプルに保ちます:Draft(下書き)、Ready(確定、合計ロック済み)、Sent(送信済み)、Paid(入金済み)。キャンセルが必要なら Void を追加してください。ルール例:ロールアップは下書き時のみ、合計は Ready でロック。
請求作成時は invoiced_invoice_id が空の作業記録だけを引き出すフィルタを使い、エントリを請求書に紐付けたらそのフィールドを設定します。加えて、請求準備画面では既に請求済みの作業を表示しないようにします。
請求書は請求書レコードからPDFを生成してください(生の作業記録からではなく)。ヘッダー、クライアント情報、行項目、合計、支払い指示を含め、長い説明や30行以上の検証を行ってレイアウトが崩れないかを確認します。
履歴を削除しないでください。影響を受けた作業記録の請求参照を外し(invoice参照をクリア)、請求行と合計を再生成し、短い修正メモを残していつ何が変更されたか説明できるようにします。
まずは手動入力から始めるのが早いです。タイマーは後から追加できますが、停止漏れや編集といった例外が増えるため、コアワークフローが安定してから導入するのが現実的です。
初期はコアフローに絞ってください:作業記録の取得、承認・ロック、未請求作業からの請求作成、PDF生成。税金、複数通貨、割引、添付ファイルは最初はスキップすると早く出せます。


