const Joi = require('joi'); Joi.objectId = require('joi-objectid')(Joi); const { validateInputRequest, authRoles } = require('../middlewares/validate'); const { InvoiceStatus, ExportType, jobInvoiceViewRoles, jobInvoiceEditRoles, InvCreateOption } = require('../helpers/constants'); module.exports = function (app) { const router = require('express').Router(), invoiceCtl = require('../controllers/invoice'); // On routes that end in /invoice router.route('/') .get(authRoles(jobInvoiceViewRoles), invoiceCtl.getInvoices_get) .post(authRoles(jobInvoiceEditRoles), validateInputRequest(createInvoiceSchema), invoiceCtl.createInvoice_post); router.route('/getPrintInformation') .get(authRoles(jobInvoiceViewRoles), validateInputRequest(getPrintInformationSchema), invoiceCtl.getPrintInformation_get); router.route('/exportInvoices') .get(authRoles(jobInvoiceViewRoles), validateInputRequest(exportInvoicesSchema), invoiceCtl.exportInvoices_get); // On routes that end in /invoices/: router.route('/:id') .get(authRoles(jobInvoiceViewRoles), validateInputRequest(getInvoiceByIdSchema, 'params'), invoiceCtl.getInvoiceById_get) .put(authRoles(jobInvoiceEditRoles), validateInputRequest(getInvoiceByIdSchema, 'params'), validateInputRequest(updateInvoiceSchema), invoiceCtl.updateInvoiceById_put) .delete(authRoles(jobInvoiceEditRoles), invoiceCtl.deleteInvoiceById); router.route('/deleteInvoices') .post(authRoles(jobInvoiceEditRoles), validateInputRequest(deleteInvoicesSchema), invoiceCtl.deleteInvoices); app.use('/api/invoices', router); }; const commonInvoiceSchema = { poNumber: Joi.string().max(100).allow(null, '').optional(), note: Joi.string().allow(null, '').optional(), paymentTerm: Joi.number().optional(), createOp: Joi.string().valid(...Object.values(InvCreateOption)).optional(), status: Joi.string().valid(...Object.values(InvoiceStatus)).optional(), }; const clientInvoiceItemSchema = { billTo: Joi.string().required(), logo: Joi.string().allow(null, '').optional(), split: Joi.string().required(), subTotal: Joi.string().required(), paymentTerm: Joi.number().optional(), discount: Joi.string().optional(), taxRate: Joi.string().optional(), amountPaid: Joi.string().optional(), amountDue: Joi.string().optional(), note: Joi.string().allow(null, '').optional(), }; const jobCostingSchema = { job: Joi.number().required(), name: Joi.string().optional(), totalAmount: Joi.string().required(), costings: Joi.object({ billableArea: Joi.number().allow(null).optional(), billableAmount: Joi.number().allow(null).optional(), currency: Joi.string().optional(), items: Joi.array().items({ item: Joi.string().required(), name: Joi.string().optional(), price: Joi.number().optional(), quantity: Joi.number().optional(), type: Joi.number().optional(), unit: Joi.number().optional(), }), }), }; const jobCostingsSchema = Joi.array().min(1).items(jobCostingSchema); const createInvoiceSchema = Joi.object({ ...commonInvoiceSchema, companyName: Joi.string().optional(), address: Joi.string().optional(), logo: Joi.string().optional(), currency: Joi.string().required(), dueDate: Joi.date().iso().required(), openDate: Joi.date().iso().required(), jobs: jobCostingsSchema.required(), clients: Joi.array().min(1).items(clientInvoiceItemSchema).required(), }); const updateInvoiceSchema = Joi.object({ ...commonInvoiceSchema, openDate: Joi.date().iso().optional(), dueDate: Joi.date().iso().optional(), jobs: jobCostingsSchema.optional(), clients: Joi.array() .min(1) .items({ code: Joi.string().optional(), ...clientInvoiceItemSchema }) .optional(), }); const deleteInvoicesSchema = Joi.object({ invoiceIds: Joi.array().min(1).items(Joi.objectId()).required(), }); const getInvoiceByIdSchema = Joi.object({ id: Joi.objectId().required() }); const getPrintInformationSchema = Joi.object({ invoiceId: Joi.objectId().required(), clientId: Joi.objectId().required(), }); const exportInvoicesSchema = Joi.object({ invoiceIds: Joi.array().min(1).items(Joi.objectId()).required(), exportType: Joi.string().valid(...Object.values(ExportType)).required(), });