UNPKG

@ryanforever/invoice-generator

Version:

invoice-generator API wrapper

222 lines (152 loc) 4.88 kB
const Logger = require("@ryanforever/logger").v4 const fs = require("fs") const path = require("path") const kindof = require("kind-of") const _ = require("underscore") const dayjs = require("dayjs") const Axios = require("axios") const util = require("util") const inflection = require("inflection") const logger = new Logger(__filename, {debug: true}) const label = input => inflection.titleize(inflection.underscore(input)) let timetamp1 = `YYMMDD` function InvoiceGenerator(config = {}) { const logger = new Logger(__filename, {debug: config.debug ?? false}) const key = config.key const defaultName = config.name const defaultAddress = config.address const defaultPhone = config.phone const defaultPaymentTerm = config.paymentTerm || 30 const defaultNotes = config.notes const defaultLogo = config.logo if (!key) throw new Error(`missing api key`) this.defaults = { name: defaultName, address: defaultAddress, phone: defaultPhone, paymentTerm: defaultPaymentTerm, logo: defaultLogo, notes: defaultNotes } const axios = Axios.create({ baseURL: "https://invoice-generator.com", headers: { Authorization: `Bearer ${key}` } }) this.generate = async function(input = {}, save) { logger.debug(`generate`) input.fromName = input.fromName || defaultName input.fromAddress = input.fromAddress || defaultAddress input.fromPhone = input.fromPhone || defaultPhone input.dueIn = input.dueIn || defaultPaymentTerm input.notes = input.notes || defaultNotes input.logo = input.logo || defaultLogo let invoice = new Invoice(input) // logger.log(invoice) let res = await axios.post("/", invoice, { responseType: 'arraybuffer', reponseEncoding: 'binary', }).catch(err => { logger.error(err.response.data) throw new Error(err) }) // logger.log(res) let data = res.data // const byteArray = new TextEncoder().encode(data) // const buffer = Buffer.from(byteArray.buffer, "utf8") if (save) fs.writeFileSync("../output/test.pdf", data, "binary") return {invoice, data} } } function Invoice(data = {}) { let dateFormat1 = "DD MMM YYYY" // to/from let fromName = data.fromName let fromAddress = data.fromAddress let fromPhone = data.fromPhone let fromEmail = data.fromEmail let toName = data.toName || data.clientName let toAddress = data.toAddress || data.clientAddress let toPhone = data.toPhone || data.clientPhone let toEmail = data.toEmail || data.clientEmail let title = data.title let from = concat(fromName, fromAddress, fromPhone, fromEmail) let to = concat(toName, toAddress, toPhone, toEmail) let items = [] let inputItems = data.items || data.item if (inputItems) { if (kindof(inputItems) == "array") items = inputItems.map(x => new Item(x)) else if (kindof(inputItems) == "object") items.push(new Item(inputItems)) } // DATE STUFF let date if (data.date) date = dayjs(data.date).format(dateFormat1) else date = date = dayjs().format(dateFormat1) let dueDate let dueIn = data.dueIn if (data.dueIn) { if (kindof(dueIn) !== "number") throw new Error(`dueIn must be a number that represents # of days from invoice date`) dueDate = dayjs(date).add(dueIn, "days").format(dateFormat1) } // SET CUSTOM FIELDS let customFields = { // title: data.title, "#": data.invoiceNumber || data.number // invoiceNumber: data.invoiceNumber, } let custom_fields = [] for (let [name, value] of Object.entries(customFields)) { if (!value) continue custom_fields.push({name: label(name), value}) } if (data.fields && kindof(data.fields) == "object") { for (let [name, value] of Object.entries(data.fields)) { if (!value) continue custom_fields.push({name: label(name), value}) } } // SET MAIN FIELDS let fields = { // number: data.title, logo: data.logo, from, to, ship_to: data.ship_to || data.shipTo, date, due_date: dueDate, notes: undefined, terms: undefined, payment_terms: undefined, custom_fields, } for (let [key, val] of Object.entries(data)) { if (fields.hasOwnProperty(key)) fields[key] = val } this.logo = data.logo this.from = from || data.from this.to = to || data.to this.ship_to = data.shipTo || data.ship_to this.date = date this.due_date = dueDate this.number = data.title this.notes = undefined this.terms = undefined this.payment_terms = undefined this.custom_fields = custom_fields this.invoice_number_title = "" fields.items = items Object.assign(this, fields) } function Item(input = {}) { this.name = input.name this.quantity = input.quantity || input.qty this.unit_cost = input.unitCost || input.cost || input.rate this.description = input.description || input.comment } function concat(...args) { args = args.filter(x => x) if (!args.length) return undefined else return args.join("\n") } module.exports = InvoiceGenerator