发票是经营业务的重要方面,并且拥有有效的发票系统可以极大地简化操作。
随着技术的进步,开发人员现在可以访问功能强大的API,从而简化了创建和发送发票的过程。这样的API就是NOVU API,它使开发人员能够构建强大且功能丰富的发票应用程序。
在本文中,我们将探讨NOVU API的功能以及如何利用它来创建全堆栈发票应用程序。
我们将构建一个全幕发票应用程序,以通过电子邮件创建和发送发票给客户。此应用程序将对初创企业,企业主和自由职业者有用。
应用功能
发票创建:
该应用程序提供了一个用于创建发票的用户友好界面。
用户可以输入相关详细信息,例如客户的姓名,计费信息,项目描述,数量,价格和注释。
发票发送:
发票应用程序集成了NOVU API,使用户可以通过电子邮件直接向客户发送PDF格式发票。
编辑发票功能:
为了满足不断变化的要求或更正,应用程序包含了编辑发票功能。
这是使用完整代码实现的应用程序回购的链接-REPO
这是应用程序演示的链接-Novo Invoice
这是应用程序最终外观的屏幕截图:
前端页面:
发票创建视图:
创建的发票视图:
样品发票:
了解Novu API:
NOVU API是一个统一的交付API,允许开发人员无缝地向客户发送发票作为电子邮件。您可以在Novu Website上找到有关它的更多信息。 Yoy还可以在文档上读取Here
它提供了一个直接的集成过程,为希望将发票功能纳入其应用程序的开发人员来说是一个绝佳的选择。
API处理电子邮件交付的复杂性,以确保发票可靠地到达客户的收件箱。
我们将用于开发本应用程序的技术是:
- react js -library用于构建用户界面
- axios-浏览器和node.js 的基于承诺的HTTP客户端
- React -Router-启用Web应用程序中动态路由的实现。
- tailwind CSS-公用事业第一CSS框架。
-
novu/node-简单的组件和API,用于在一个地方管理所有通信渠道:电子邮件,短信,直接和推送
-
express js-灵活的node.js Web应用程序框架,为Web和移动应用程序提供了强大的功能集。
-
html -pdf -html到使用phantomjs
的PDF转换器
-
mongoose-提供基于模型的直接,基于模式的解决方案
-
node.js-跨平台,后端JavaScript运行时环境,在V8引擎上运行并在Web浏览器外执行JavaScript代码。
让我们开始建造。
为我们的项目创建一个文件夹。将其命名为novu-invoice
,也可以将其命名为您喜欢的任何东西。
现在,我们将首先构建应用程序的API或后端。
在刚刚创建另一个文件夹的Novu Invoice文件夹中。命名为backend
。
在后端文件夹中打开命令行,然后输入:
npm init --y
启动我们的API应用程序。
package.json
文件将自动为您生成。
您的软件包文件应该看起来像这样 -
{
"name": "backend",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"keywords": [],
"author": "",
"license": "ISC"
}
设置服务器:
通过运行此命令来安装此项目所需的必要依赖项:
npm i npm i express mongoose cors html-pdf moment pdfkit uuid @novu/node dotenv nodemon
.
这将安装我们将为此项目所需的所有依赖项。
在您的backend
文件夹中,创建一个文件。通过添加以下代码:
在这里,我们导入Express.js模块,这是Node.js的Web应用程序框架。它使我们能够创建可靠且可扩展的Web应用程序。
然后,我们使用代码-const app = express();
然后,我们在应用程序中添加了中间件。在这种情况下,express.json()
用于解析传入的JSON数据。这使我们可以轻松地处理应用程序路线中的JSON有效载荷。
我们为根URL(“/”)设置了一个简单的路由,以便在对root URL提出get请求时,执行回调函数(req,res)=> {...}。
,最后,我们指定了一个端口,服务器将在该端口上侦听传入的请求。
在这种情况下,它设置为端口5000。App.listen()函数启动服务器并在指定的端口上听。
服务器运行后,它将将消息记录到控制台,指示该应用程序正在运行以及在哪个端口上。
通过在脚本部分中添加此开始脚本-"start": "nodemon app.js"
来更新您的软件包。您的软件包。json文件现在看起来像这样。
要启动服务器,运行命令-npm start
这将在您的命令上显示该服务器正在工作。
建立数据库连接:
现在,让我们实现一个数据库连接到我们的应用程序。
在您的根目录中,创建一个文件。将其命名DB.JS,并在内部添加以下代码:
在此代码中,我们使用Mongoose建立了与MongoDB数据库的连接,Mongoose是一个流行的MongoDB对象建模工具。
。首先,我们导入了猫鼬模块。然后,我们定义一个称为connectToDatabase
的异步函数。
我们使用mongoose.connect()方法建立了与MongoDB数据库的连接。将连接字符串作为参数提供,该参数存储在Mongodb_uri环境变量中。
如果数据库连接成功,我们将成功消息记录到控制台。
我们导出了connectToDatabase
函数,允许应用程序的其他部分导入并使用它。
在您的app.js文件中,导入connecttodatabase函数并调用它。将以下代码添加您的app.js文件:
const connecttodatabase = require(“ ./ db”);
.......
connectTodatabase();
您的app.js
文件现在应该看起来像这样:
现在创建一个file.name it .env
在您的根目录上,并添加以下代码:
MONGODB_URI = mongodb://localhost:27017/novu-invoice
我们创建的.ENV文件是为应用程序安全地管理配置变量或特定环境的设置。
它允许我们将敏感或环境特定的配置与应用程序代码分开
请确保使用MongoDB Compass在本地设置MongoDB数据库(您可以使用MongoDB Atlas
在云上进行here或在云上进行设置。我们已经安装了Nodemon,该库有助于自动重新启动我们的服务器。如果您之前终止该过程,也可以运行npm start
。
如果一切正常,您应该在指示数据库已成功连接的控制台中看到它。
实施数据库模型:
现在让我们实现我们的数据库模型。
在您的项目目录中创建一个文件夹。命名IT模型。在此文件夹中,创建一个文件。将其命名为invoiceModel.js
并添加以下代码:
在此代码中,我们从Mongoose库中导入了必要的模块。
const invoiceSchema = new Schema({
// Schema properties and their types
});
在这里,我们使用架构对象创建了一个名为invoiceSchema
的新的杂种架构。该模式定义了存储在MongoDB集合中的“发票”文档的结构和属性。
然后,我们定义发票模式的属性。每个属性对应于“发票”文档中的字段。
这些属性可以具有多种类型,例如日期,字符串或数字。 items
属性是一个包含具有itemName
,unitPrice
和quantity
的属性的对象。
createdAt
property是一个特殊字段,自动分配了创建新文档的当前日期和时间。
module.exports = model('Invoice', invoiceSchema);
在这里,我们导出了“发票”架构的蒙古模型。该模型函数用于从发票Chema创建模型。
为模型提供了一个名称为“发票”,该名称对应于MongoDB集合名称。然后,导出的模型可用于在“发票”集合上执行数据库操作。
实施发票控制器:
创建一个文件夹并将其命名为控制器。在控制器文件夹中,创建一个文件。将其命名为invoiceController.js
和以下代码:
在这里,我们需要模型目录中的杂种库和发票模型。
然后,我们定义一个称为createInvoice
的函数,该函数处理发票的创建。
它从请求主体中提取必要的数据,使用前缀“ Inv”生成随机的6位发票号,然后使用InvoIceModel创建新的发票。
然后将新发票作为JSON响应发送,并带有201(创建)的状态代码。
我们定义了另一个功能来处理发票的编辑。
它从请求参数中提取发票ID和请求主体的发票数据。
然后检查提供的发票ID是否是有效的mongodb对象ID。如果没有,它将发送404响应,并带有消息“没有该ID的发票”。
如果ID有效,则使用InvoIceModel的findByIdAndUpdate
方法,传递ID,发票数据和选项{new:true}来返回更新的发票。然后将更新的发票作为JSON响应发送。
实施路由:
要实现我们的路线,创建一个文件夹。命名它路由。在其中,创建一个file.name it invoiceRoute.js
并添加以下代码:
在此代码中,我们从控制器文件夹中导入Express库和其他控制器功能。
控制器功能处理用于创建和编辑发票的逻辑。
我们通过调用express.router()创建了快速路由器的实例。路由器允许我们为特定的HTTP方法定义路由,并将相应的控制器功能附加到它们。
我们使用路由器定义以下路线:
邮政 /
- 此路线用于创建新的发票。它调用
createInvoice
控制器函数。
补丁 /ID
- 此路由用于根据ID参数更新现有的发票。它调用
editInvoice
控制器函数。
现在让我们在app.js文件中使用我们的路线。
在您的app.js文件中,通过像这样的
const invoiceRoutes = require('./routes/invoiceRoute')
并这样使用:
app.use('/api/invoices', invoiceRoutes);
您的app.js
文件现在应该看起来像这样:
设计发票模板:
在本节中,我们将设计发票的外观。
在您的项目文件夹中,创建一个文件夹。命名文档。在文档文件夹中创建一个文件。将其命名为index.js
并添加以下代码:
在此代码中,我们基本上定义了一个称为pdfTemplate
的JavaScript函数,该函数为我们的发票生成HTML模板。
pdftemplate函数将对象作为一个参数,其中包含与发票相关的各种属性,例如名称,phonenumber,电子邮件,注释,项目,项目,duedate,eardueddate,earkueddate,totalQuantity,totalquantity,totalAmount和InvoiceNumber。
它使用这些属性填充发票模板。
然后可以使用返回的HTML模板生成PDF文档或以HTML格式显示发票。
确实要确保您导入或需要app.js
文件中的发票模板:
实施Novu API:
novu提供了一个统一的API,可以简单地通过多个渠道发送通知,包括应用程序内,推送,电子邮件,SMS和聊天。
使用Novu,您可以创建自定义工作流并为每个频道定义条件,以确保以最有效的方式传递通知。您可以在其Official Doc中阅读有关Novu API的更多信息。
您需要注册Novu account才能开始
设置帐户后,下一步涉及在“工作流”选项卡中创建工作流程。
在这里,我们在触发器下方添加了电子邮件事件,通过将其拖动并将其拖放为每当触发通知时就会发生的事件。
因此,我们正在设置一个用于发送电子邮件的工作,因为我们想作为电子邮件发送发票。
单击您刚刚添加的电子邮件频道并填写所需的信息,然后单击“更新”按钮以节省更改:
转到您在novu仪表板上的静止设置选项卡,复制API键,然后将其添加到您的环境变量中:
NOVU_API_KEY= your-novu-api
。用您的Novu
api键替换值。
我们将添加到实施中的另一件事是trigger_name。我们将通过单击“工作流”选项卡并找到这样的设置区域来获得此信息:
在这种情况下,TRIGGER_NAME
是我们的标识符ISinvoice-notification
。复制您的标识符并将其保存在某个地方。您将需要它进行实施。
现在让我们实现Novu API。但是在此之前,让我们需要一些我们将使用的依赖项。将以下内容添加到您的app.js
文件
const { Novu } = require('@novu/node');
const pdf = require('html-pdf');
const cors = require('cors');
const fs = require('fs');
const pdfTemplate = require('./document/index');
//启用CORS中间件
app.use(cors());
在上面的此代码中,我们导入了几个node.js模块: @novu/node,html-pdf,cors,fs和一个自定义模块pdftemplate。
然后,我们使用此代码添加了CORS中间件:
app.use(cors());
该应用程序可以启用CORS并允许来自不同域的交叉原始请求。
添加以这样的pdf发送发票的逻辑:
在此代码中,我们定义一个对象options
,其属性格式设置为“ A4”。使用HTML-PDF库生成PDF文档时使用这些选项。在这种情况下,指定了A4格式。
app.post('/send-pdf', (req, res) => { ... });
然后,我们为/send-pdf
端点设置了一个邮政请求的路由处理程序。
我们在通过邮政请求访问端点时聆听传入请求并执行提供的回调功能。
const { email } = req.body;
我们使用破坏分配从请求正文中提取了电子邮件属性。
pdf.create(pdfTemplate(req.body), options).toFile('invoice.pdf', (err) => { ... });
我们使用pdfTemplate
函数以及前面定义的选项生成了PDF文档。
我们用请求主体执行了pdfTemplate
函数。生成的PDF文档保存到名为“ Invoice.pdf”的文件。
const novu = new Novu(process.env.NOVU_API_KEY);
在上面的此代码中,我们创建了一个Novu
对象的新实例,该实例是从 @Novu/Node模块引入的。
novu.trigger('invoice-notification', { ... });
在这里,我们调用the novu
对象的触发方法,将“发票通知”作为第一个参数和一个包含通知详细信息的对象作为第二个参数。 (请记住将标识符替换为您先前保存的trigger_name或标识符。
详细信息包括收件人的订户ID和电子邮件地址,以及代表PDF格式发票的附件对象。
它使用fs.readFileSync
读取PDF文件的内容,并将其转换为base64编码的字符串,然后将其附加到有效载荷上。
我们基本上完成的是处理邮政请求以生成PDF发票,将其保存到文件并使用Novu
对象触发通知。
您的app.js
最终应该看起来像这样:
我们已经完成了Novu发票项目的后端。您可以使用这样的邮递员测试端点: