Logo

dev-resources.site

for different kinds of informations.

Develop a Simple PDF Invoicing App for your Business with CASE

Published at
10/2/2023
Categories
crud
pdf
typescript
dashboard
Author
bd_perez
Categories
4 categories in total
crud
open
pdf
open
typescript
open
dashboard
open
Author
8 person written this
bd_perez
open
Develop a Simple PDF Invoicing App for your Business with CASE

In our example, we want to develop a simple invoicing web app as fast as possible for our business. 💰💰💰

For that motive, we are going to use CASE, a simple tool to quickly generate dashboards and add our own custom logic.

This simple guide will follow 4 steps:

  1. Install CASE
  2. Generate entities
  3. Add properties
  4. Generate a PDF on invoice creation

1. Install CASE

Let's start generating the app with this simple command ✨✨

npx create-case-app my-invoicing-app
Enter fullscreen mode Exit fullscreen mode

CASE dashboard login page

This will launch your invoicing app on your browser. You can go to the my-invoicing-app folder and open the folder with your favorite IDE.

That's it for the install.

2. Generate entities

Our project will need 2 entities: a Customer and an Invoice. Invoices belongs to Customers, and a Customer can have many invoices.

The command to generate a new entity is straightforward:

npm run case:entity customer
Enter fullscreen mode Exit fullscreen mode

and the second one:

npm run case:entity invoice
Enter fullscreen mode Exit fullscreen mode

You should see that the customer.entity.ts and the invoice.entity.ts files have been created ! Check out the UI to see those entities in action.

3. Add properties

By default, entities only come with a name property. We are going to add more to it. Let's start with the customers:

// entites/customer.entity.ts

@Entity({
  nameSingular: "customer",
  namePlural: "customers",
  propIdentifier: "name",
  slug: "customers",
})
export class Customer extends CaseEntity {

  // Customer logo.
  @Prop({
    type: PropType.Image,
  })
  logo: string;

  // Customer name.
  @Prop({
    type: PropType.Text,
    seed: () => faker.company.name(),
  })
  name: string;

  // Customer address with a nice seeder for the dummy data.
  @Prop({
    type: PropType.Text,
    seed: () =>
      faker.location.streetAddress() +
      ", " +
      faker.location.city() +
      ", " +
      faker.location.state() +
      " " +
      faker.location.zipCode(),
  })
  address: string;
}

Enter fullscreen mode Exit fullscreen mode

The @Prop decorator is getting:

Let's go with the invoices now:

// entities/invoice.entity.ts

@Entity({
  nameSingular: "invoice",
  namePlural: "invoices",
  propIdentifier: "label",
  slug: "invoices",
})
export class Invoice extends CaseEntity {
  @Prop({
    type: PropType.Text,
  })
  label: string;

  @Prop({
    type: PropType.Date,
    label: "Issue Date",
  })
  issueDate: string;

  // Represents the relation with the Customer entity.
  @Prop({
    type: PropType.Relation,
    options: {
      entity: Customer,
    },
  })
  customer: Customer;

  // PropType.Currency accepts all currencies, default is USD.
  @Prop({
    type: PropType.Currency,
  })
  amount: number;

  @Prop({
    type: PropType.Currency,
  })
  taxes: number;

  // This prop will store the path of the generated PDF file.
  @Prop({
    type: PropType.File,
    options: {
      isHiddenInCreateEdit: true,
    },
  })
  path: string;
}
Enter fullscreen mode Exit fullscreen mode

Now that our props are filled, we can add some dummy data to see it in action:

npm run seed
Enter fullscreen mode Exit fullscreen mode

This will generate a bunch of customers and invoices with the dummy properties. As you can see, we did not specify a seed function for all of those props, by default CASE tries to generate a mock data that corresponds to your type.

Form to create an invoice

4. Generate PDF on insert

Last but not least, we need to generate a PDF on save and store its path as the invoice.path.

We are going to use the @BeforeInsert() decorator that triggers a function just before our item is inserted to the database:

// entities/invoice.entity.ts

@BeforeInsert()
generatePDF() {
  // We need a feature that generates a PDF based on our values and that stores it in the disk and returns the path.
  this.path = generateInvoiceInPDF({
      reference: this.reference,
      label: this.label,
      issueDate: this.issueDate,
      customerName: this._relations.customer.name,
      customerAddress: this._relations.customer.address,
      amount: this.amount,
      taxes: this.taxes
  })
}
Enter fullscreen mode Exit fullscreen mode

Let's create that generateInvoiceInPDF() function !

We are going to use the jspdf package to create the PDF files. Let's create a utils/pdf.ts file with this content:

// utils/pdf.ts

import { jsPDF } from "jspdf";
import * as fs from "fs";

export const saveInvoiceInPDF = (content: {
  reference: string;
  label: string;
  issueDate: string;
  customerName: string;
  customerAddress: string;
  amount: number;
  taxes: number;
}): string => {
  var doc = new jsPDF();

  // Title.
  doc.setFontSize(28);
  doc.text(`Invoice: ${content.reference}`, 20, 25);

  // Other content.
  const fontSize: number = 14;
  const x: number = 35;
  doc.setFontSize(fontSize);

  doc.text(content.label, 20, x);
  doc.text(content.customerName, 20, x + fontSize);
  doc.text(content.customerAddress, 20, x + fontSize * 2);
  doc.text(content.issueDate, 20, x + fontSize * 3);
  doc.text(`Amount: ${content.amount}`, 20, x + fontSize * 4);
  doc.text(`Taxes: ${content.taxes}`, 20, x + fontSize * 5);

  var data = doc.output();

  const storagePath = "./public/storage";
  const path = `/invoices/${content.reference}.pdf`;

  fs.writeFileSync(storagePath + path, data, "binary");

  return path;
};
Enter fullscreen mode Exit fullscreen mode

This code is producing a basic PDF will the invoice information. I am not digging to much on that part in this tutorial but if you want to create a nice PDF, checkout jspdf doc or you can even get directly invoice templates for it.

You can find all that code in the Github repo of this project, Enjoy your coding !

Wanna give some ❤️ ?

If you enjoyed this tutorial and developing with CASE, Star us on Github and like or share this post ! We are actively looking for CASE testers and users to improve our project !

dashboard Article's
30 articles in total
Favicon
Prometheus Instance Exposed
Favicon
Designing Beautiful Dashboard Layouts with Tailwind CSS
Favicon
Unlock 1 Billion NYC Taxi Rides: A Step-by-Step Guide
Favicon
Create a Warehouse Dashboard In 3 Steps
Favicon
Case Study:- SaaS Dashboard Design
Favicon
Dicas para criação de dashboards de monitoramento no Kibana
Favicon
Create an E-commerce Dashboard In 3 Steps
Favicon
Deploy a lightweight BI solution with your first dashboard in 5 steps
Favicon
Déployer une solution de BI légère avec son premier dashboard en 5 étapes
Favicon
Crafting My Perfect Home Assistant Dashboard
Favicon
Building a Real-Time IoT Dashboard with HarperDB and Node.js
Favicon
Power BI Dashboard: Ultimate Tool for Dynamic Data Visualization and Storytelling
Favicon
Dashboard Estratégico X Dashboard Operacional
Favicon
Whatsapp Webhook Setup and Nodejs Code Example
Favicon
Better tools make good work -- learn to use the research environment to analyze trading principles
Favicon
My Experience Learning Go, next steps
Favicon
Kaiadmin Lite - Free Bootstrap 5 Admin Dashboard
Favicon
Copy & Paste React Components for Dashboards
Favicon
Tailwind Dashboard Template Free Starter
Favicon
Code-Along: How to Develop a REST API Dashboard
Favicon
Portfolio Showcase?
Favicon
7 Premium Tailwind Dashboard Admin Templates for 2024
Favicon
Real-time data visualization and alerts using Redis TimeSeries, Grafana and Slack.
Favicon
Salesforce Reports & Dashboards Best Practices
Favicon
11 Best Tailwind Dashboard Template For 2024
Favicon
Web Dashboard GUI for Kafka Cluster Monitoring
Favicon
Develop a Simple PDF Invoicing App for your Business with CASE
Favicon
Top Benefits of Using Core App Dashboard
Favicon
Awesome Free Bootstrap Admin Dashboards.
Favicon
Creating your first React Native table vs DronaHQ table! which one is easy?

Featured ones: