83 lines
3.4 KiB
JavaScript
83 lines
3.4 KiB
JavaScript
const mongoose = require("mongoose"), Schema = mongoose.Schema,
|
|
{ UserTypes, InvCreateOption, InvoiceStatus, CostingItemType, Units } = require("../helpers/constants"),
|
|
Currencies = require("../helpers/currencies"),
|
|
env = require("../helpers/env");
|
|
|
|
|
|
const clientSchema = new Schema({
|
|
billTo: { type: Schema.Types.ObjectId, ref: UserTypes.CLIENT, required: true },
|
|
code: { type: String, required: false },
|
|
logo: { type: String, required: false, get: (logo) => logo ? `${env.INV_IMG_VIR_DIR}/${logo}` : undefined },
|
|
split: { type: String, required: true },
|
|
subTotal: { type: String, required: true },
|
|
paymentTerm: { type: Number, required: false },
|
|
discount: { type: String, required: false },
|
|
taxRate: { type: String, required: false },
|
|
amountPaid: { type: String, required: false },
|
|
amountDue: { type: String, required: false },
|
|
note: { type: String, required: false }
|
|
}, { _id: false, toJSON: { getters: true }, toObject: { getters: true }, versionKey: false });
|
|
|
|
const jobSchema = new Schema({
|
|
job: { type: Schema.Types.Number, ref: "Job" },
|
|
name: { type: String, required: false },
|
|
totalAmount: { type: String, required: true },
|
|
costings: {
|
|
billableArea: { type: Number, min: 0, required: false },
|
|
billableAmount: { type: Number, min: 0, require: false },
|
|
currency: { type: String, enum: Object.keys(Currencies), require: false },
|
|
items: [
|
|
{
|
|
item: { type: Schema.Types.ObjectId, ref: 'costing_items', require: false },
|
|
name: { type: String, require: false },
|
|
price: { type: Number, min: 0, require: false },
|
|
quantity: { type: Number, min: 0, require: false },
|
|
type: { type: Number, enum: Object.values(CostingItemType), require: false },
|
|
unit: { type: Number, enum: Object.values(Units), require: false },
|
|
},
|
|
],
|
|
},
|
|
}, { _id: false, toJSON: { getters: true }, toObject: { getters: true }, versionKey: false });
|
|
|
|
const schema = new Schema({
|
|
code: { type: String, required: true },
|
|
companyName: { type: String, required: false },
|
|
address: { type: String, required: false },
|
|
logo: { type: String, required: false, get: (logo) => logo ? `${env.INV_IMG_VIR_DIR}/${logo}` : undefined },
|
|
currency: { type: String, required: true },
|
|
poNumber: { type: String, required: false },
|
|
dueDate: { type: Date, required: true },
|
|
openDate: { type: Date, required: true },
|
|
paidAt: { type: Date, required: false },
|
|
note: { type: String, required: false },
|
|
paymentTerm: { type: Number, required: false },
|
|
|
|
createOp: {
|
|
type: String,
|
|
enum: Object.values(InvCreateOption),
|
|
message: "{VALUE} for invoice 'createOp' is not supported",
|
|
default: InvCreateOption.Option1,
|
|
},
|
|
|
|
status: {
|
|
type: String,
|
|
enum: Object.values(InvoiceStatus),
|
|
message: "{VALUE} for invoice 'status' is not supported",
|
|
default: InvoiceStatus.Draft,
|
|
},
|
|
|
|
jobs: [jobSchema, { id: false }],
|
|
|
|
clients: [clientSchema, { id: false }],
|
|
|
|
// Applicator userId. This is for performance optimization when querying
|
|
byPuid: { type: Schema.Types.ObjectId, ref: UserTypes.APP, required: true, index: true },
|
|
|
|
createdBy: { type: Schema.Types.ObjectId, ref: 'User', required: false },
|
|
updatedBy: { type: Schema.Types.ObjectId, ref: 'User', required: false }
|
|
}, { timestamps: true, toJSON: { getters: true, id: false }, toObject: { getters: true, id: false } });
|
|
|
|
schema.index({ status: 1, openDate: 1 });
|
|
|
|
module.exports = mongoose.model("Invoice", schema);
|