Files
ubicloud/views/project/invoice.erb
Junhao Li a876d6d52c Add billing check and free quota for AI inference
Provide free quota for AI inference. Projects without valid billing info
will have requests rejected after the free quota is exhausted.
2025-02-18 11:51:51 -05:00

147 lines
6.9 KiB
Plaintext

<% @page_title = "#{@invoice_data[:name]} Invoice" %>
<%== part(
"components/page_header",
breadcrumbs: [
%w[Projects /project],
[@project_data[:name], @project_data[:path]],
["Billing", "#{@project_data[:path]}/billing"],
["#{@invoice_data[:name]} Invoice", "#"]
],
right_items: [
part("components/button", text: "View PDF", link: "#{request.url}?pdf=1", attributes: {target: "_blank"})
]
) %>
<div class="grid gap-6">
<!-- Invoice Card -->
<div class="overflow-hidden rounded-lg shadow ring-1 ring-black ring-opacity-5 bg-white divide-y divide-gray-200">
<div class="px-4 py-5 sm:p-6">
<% if @invoice_data[:status] == "current" %>
<div class="flex justify-between items-baseline text-gray-800">
<div class="text-4xl font-semibold">Current Usage Summary</div>
<div class="text-right text-3xl"><%= @invoice_data[:begin_time] %> to <%= @invoice_data[:end_time] %></div>
</div>
<h3 class="text-lg text-gray-500">
This invoice will be finalized on the first day of next month.
</h3>
<% else %>
<div class="flex justify-between">
<div>
<img class="h-8 w-auto" src="/logo-primary.png" alt="Ubicloud">
<address class="mt-4 not-italic text-gray-800">
<% if @invoice_data[:issuer_name] %>
<span class="font-semibold"><%= @invoice_data[:issuer_name] %></span><br>
<% end %>
<%= @invoice_data[:issuer_address] %>,<br>
<%= @invoice_data[:issuer_city] %>,
<%= @invoice_data[:issuer_state] %>
<%= @invoice_data[:issuer_postal_code] %>,<br>
<%= @invoice_data[:issuer_country] %><br>
</address>
</div>
<div class="text-right">
<h2 class="text-3xl font-semibold text-gray-800">
Invoice for <%= @invoice_data[:name] %>
</h2>
<span class="mt-1 block text-gray-500">#<%= @invoice_data[:invoice_number] %></span>
</div>
</div>
<div class="mt-8 grid grid-cols-2 gap-3">
<div>
<h3 class="text-lg font-semibold text-gray-800">Bill to:</h3>
<h3 class="text-lg font-semibold text-gray-800">
<%= @invoice_data[:billing_name] %>
<% if @invoice_data[:company_name] %>
- <%= @invoice_data[:company_name] %>
<% end %>
</h3>
<address class="mt-2 not-italic text-gray-500">
<% if @invoice_data[:tax_id] %>
Tax ID: <%= @invoice_data[:tax_id] %> <br>
<% end %>
<%= @invoice_data[:billing_address] %>,<br>
<%= @invoice_data[:billing_city] %>,
<%= @invoice_data[:billing_state] %>
<%= @invoice_data[:billing_postal_code] %>,<br>
<%= @invoice_data[:billing_country] %><br>
</address>
</div>
<div class="text-right space-y-2">
<div class="grid grid-cols-1 gap-2">
<dl class="grid grid-cols-5 gap-x-3">
<dt class="col-span-3 font-semibold text-gray-800">Invoice date:</dt>
<dd class="col-span-2 text-gray-500"><%= @invoice_data[:date] %></dd>
</dl>
<dl class="grid grid-cols-5 gap-x-3">
<dt class="col-span-3 font-semibold text-gray-800">Due date:</dt>
<dd class="col-span-2 text-gray-500"><%= @invoice_data[:date] %></dd>
</dl>
</div>
</div>
</div>
<% end %>
<div class="mt-6">
<table class="min-w-full divide-y divide-gray-300 border border-gray-200">
<thead class="bg-gray-50">
<tr>
<th scope="col" class="py-3 pl-4 pr-3 text-left text-sm font-semibold text-gray-900 sm:pl-6">RESOURCE</th>
<th scope="col" class="px-3 py-3 text-left text-sm font-semibold text-gray-900">DESCRIPTION</th>
<th scope="col" class="px-3 py-3 text-right text-sm font-semibold text-gray-900">USAGE</th>
<th scope="col" class="py-3 pl-3 pr-4 text-right text-sm font-semibold text-gray-900 sm:pr-6">AMOUNT</th>
</tr>
</thead>
<tbody class="divide-y divide-gray-200 bg-white">
<% if @invoice_data[:items].count > 0 %>
<% @invoice_data[:items].each do |item| %>
<tr>
<td class="whitespace-nowrap py-3 pl-4 pr-3 text-sm font-medium text-gray-900 sm:pl-6" scope="row"><%= item[:name] %></td>
<td class="whitespace-nowrap px-3 py-3 text-sm text-gray-500"><%= item[:description] %></td>
<td class="whitespace-nowrap px-3 py-3 text-sm text-gray-500 text-right"><%= item[:usage] %></td>
<td class="whitespace-nowrap py-3 pl-3 pr-4 text-right text-sm text-gray-500 sm:pr-6"><%= item[:cost_humanized] %></td>
</tr>
<% end %>
<% else %>
<tr>
<td colspan="4" class="whitespace-nowrap px-3 py-3 text-center font-medium text-gray-900">No resources</td>
</tr>
<% end %>
</tbody>
</table>
<div class="mt-8 flex justify-end">
<div class="grid gap-2 text-right">
<dl class="grid grid-cols-3 gap-x-3">
<dt class="text-right font-semibold text-gray-800 col-span-2">Subtotal:</dt>
<dd class="text-gray-500"><%= @invoice_data[:subtotal] %></dd>
</dl>
<% if @invoice_data[:discount] != "$0.00" %>
<dl class="grid grid-cols-3 gap-x-3">
<dt class="text-right font-semibold text-gray-800 col-span-2">Discount:</dt>
<dd class="text-gray-500" id="invoice-discount">-<%= @invoice_data[:discount] %></dd>
</dl>
<% end %>
<% if @invoice_data[:credit] != "$0.00" %>
<dl class="grid grid-cols-3 gap-x-3">
<dt class="text-right font-semibold text-gray-800 col-span-2">Credit:</dt>
<dd class="text-gray-500" id="invoice-credit">-<%= @invoice_data[:credit] %></dd>
</dl>
<% end %>
<% if @invoice_data[:free_inference_tokens_credit] != "$0.00" %>
<dl class="grid grid-cols-3 gap-x-3">
<dt class="text-right font-semibold text-gray-800 col-span-2">Free Inference Tokens:</dt>
<dd class="text-gray-500" id="invoice-free-inference-tokens">-<%= @invoice_data[:free_inference_tokens_credit] %></dd>
</dl>
<% end %>
<dl class="grid grid-cols-3 gap-x-3 text-2xl">
<dt class="text-right font-semibold text-gray-800 col-span-2">Total:</dt>
<dd class="text-gray-500"><%= @invoice_data[:total] %></dd>
</dl>
</div>
</div>
</div>
</div>
</div>
</div>