TTRAVELOGACCOUNTS PLATFORM
DRAFT INVOICE

Create an invoice

Draft saved in this browser.

Balance due

Invoice details

01 / DETAILS

Bill to

02 / CUSTOMER

Items & services

03 / ITEMS

Invoice totals

04 / TOTALS

TCS is applied once to the invoice total after GST: (subtotal + CGST + SGST + IGST) × invoice TCS rate.

LIVE PREVIEWA4 · Print ready

Choose “Save as PDF” in the print dialog. For a clean invoice, turn off browser headers and footers.

Delete invoice?

Delete from saved invoices? This cannot be undone.

Select tax code

Share invoice

A4 · PDF document

Download PDF

Cloud sync

TRAVELOG · travelog-itinerary

One company workspace for every device. Invoices, purchases, payments, receipts, banks, customers, items and tax codes save automatically and appear wherever you open the updated app.

Live backup will start after cloud sync.

Cloud setup · same Firebase as Itinerary Builder

Uses the existing travelog-itinerary Firestore project directly, without Authentication or a separate Storage bucket. Invoice records use itineraryBuilder/crmState/invoiceStudio, separate from itinerary records.

If the existing itinerary rules cover all workspace subcollections, no rule change is needed. If access is denied, add this scoped rule inside the existing Firestore documents block and preserve all itinerary rules.

Like the reference app, this setup allows visitors with the app to access the shared records.

// Add inside match /databases/{database}/documents only if existing
// itinerary workspace rules do not already cover its subcollections.
match /itineraryBuilder/crmState/invoiceStudio/{recordId} {
  allow read: if true;
  allow create, update: if
    (recordId == 'manifest' && request.resource.data.schemaVersion == 3
      && request.resource.data.settings is map && request.resource.data.revision is int)
    || (recordId == 'invoiceCounter' && request.resource.data.next is int
      && request.resource.data.next >= 18)
    || (recordId == 'backup' && request.resource.data.payload is string
      && request.resource.data.payload.size() <= 900000)
    || (request.resource.data.type in ['invoices','payments','purchases','outgoingPayments','expenses','banks','customers','taxes','catalog','purchaseCatalog','suppliers']
      && request.resource.data.data is map);
  allow delete: if !(recordId in ['manifest','invoiceCounter','backup']);
}