Added purchase orders and couriers.
This commit is contained in:
parent
82d47e08a2
commit
944ad34f89
@ -20,6 +20,7 @@ import {
|
|||||||
materialRoutes,
|
materialRoutes,
|
||||||
partStockRoutes,
|
partStockRoutes,
|
||||||
filamentStockRoutes,
|
filamentStockRoutes,
|
||||||
|
purchaseOrderRoutes,
|
||||||
stockAuditRoutes,
|
stockAuditRoutes,
|
||||||
stockEventRoutes,
|
stockEventRoutes,
|
||||||
auditLogRoutes,
|
auditLogRoutes,
|
||||||
@ -30,6 +31,8 @@ import {
|
|||||||
documentTemplatesRoutes,
|
documentTemplatesRoutes,
|
||||||
documentPrintersRoutes,
|
documentPrintersRoutes,
|
||||||
documentJobsRoutes,
|
documentJobsRoutes,
|
||||||
|
courierRoutes,
|
||||||
|
courierServiceRoutes,
|
||||||
} from './routes/index.js';
|
} from './routes/index.js';
|
||||||
import path from 'path';
|
import path from 'path';
|
||||||
import * as fs from 'fs';
|
import * as fs from 'fs';
|
||||||
@ -123,6 +126,7 @@ app.use('/vendors', vendorRoutes);
|
|||||||
app.use('/materials', materialRoutes);
|
app.use('/materials', materialRoutes);
|
||||||
app.use('/partstocks', partStockRoutes);
|
app.use('/partstocks', partStockRoutes);
|
||||||
app.use('/filamentstocks', filamentStockRoutes);
|
app.use('/filamentstocks', filamentStockRoutes);
|
||||||
|
app.use('/purchaseorders', purchaseOrderRoutes);
|
||||||
app.use('/stockevents', stockEventRoutes);
|
app.use('/stockevents', stockEventRoutes);
|
||||||
app.use('/stockaudits', stockAuditRoutes);
|
app.use('/stockaudits', stockAuditRoutes);
|
||||||
app.use('/auditlogs', auditLogRoutes);
|
app.use('/auditlogs', auditLogRoutes);
|
||||||
@ -131,6 +135,8 @@ app.use('/documentsizes', documentSizesRoutes);
|
|||||||
app.use('/documenttemplates', documentTemplatesRoutes);
|
app.use('/documenttemplates', documentTemplatesRoutes);
|
||||||
app.use('/documentprinters', documentPrintersRoutes);
|
app.use('/documentprinters', documentPrintersRoutes);
|
||||||
app.use('/documentjobs', documentJobsRoutes);
|
app.use('/documentjobs', documentJobsRoutes);
|
||||||
|
app.use('/couriers', courierRoutes);
|
||||||
|
app.use('/courierservices', courierServiceRoutes);
|
||||||
app.use('/notes', noteRoutes);
|
app.use('/notes', noteRoutes);
|
||||||
|
|
||||||
if (process.env.SCHEDULE_HOUR) {
|
if (process.env.SCHEDULE_HOUR) {
|
||||||
|
|||||||
@ -14,6 +14,7 @@ import vendorRoutes from './management/vendors.js';
|
|||||||
import materialRoutes from './management/materials.js';
|
import materialRoutes from './management/materials.js';
|
||||||
import partStockRoutes from './inventory/partstocks.js';
|
import partStockRoutes from './inventory/partstocks.js';
|
||||||
import filamentStockRoutes from './inventory/filamentstocks.js';
|
import filamentStockRoutes from './inventory/filamentstocks.js';
|
||||||
|
import purchaseOrderRoutes from './inventory/purchaseorders.js';
|
||||||
import stockEventRoutes from './inventory/stockevents.js';
|
import stockEventRoutes from './inventory/stockevents.js';
|
||||||
import stockAuditRoutes from './inventory/stockaudits.js';
|
import stockAuditRoutes from './inventory/stockaudits.js';
|
||||||
import auditLogRoutes from './management/auditlogs.js';
|
import auditLogRoutes from './management/auditlogs.js';
|
||||||
@ -22,6 +23,8 @@ import documentSizesRoutes from './management/documentsizes.js';
|
|||||||
import documentTemplatesRoutes from './management/documenttemplates.js';
|
import documentTemplatesRoutes from './management/documenttemplates.js';
|
||||||
import documentPrintersRoutes from './management/documentprinters.js';
|
import documentPrintersRoutes from './management/documentprinters.js';
|
||||||
import documentJobsRoutes from './management/documentjobs.js';
|
import documentJobsRoutes from './management/documentjobs.js';
|
||||||
|
import courierRoutes from './management/courier.js';
|
||||||
|
import courierServiceRoutes from './management/courierservice.js';
|
||||||
import noteRoutes from './misc/notes.js';
|
import noteRoutes from './misc/notes.js';
|
||||||
|
|
||||||
export {
|
export {
|
||||||
@ -41,6 +44,7 @@ export {
|
|||||||
materialRoutes,
|
materialRoutes,
|
||||||
partStockRoutes,
|
partStockRoutes,
|
||||||
filamentStockRoutes,
|
filamentStockRoutes,
|
||||||
|
purchaseOrderRoutes,
|
||||||
stockEventRoutes,
|
stockEventRoutes,
|
||||||
stockAuditRoutes,
|
stockAuditRoutes,
|
||||||
auditLogRoutes,
|
auditLogRoutes,
|
||||||
@ -50,4 +54,6 @@ export {
|
|||||||
documentTemplatesRoutes,
|
documentTemplatesRoutes,
|
||||||
documentPrintersRoutes,
|
documentPrintersRoutes,
|
||||||
documentJobsRoutes,
|
documentJobsRoutes,
|
||||||
|
courierRoutes,
|
||||||
|
courierServiceRoutes,
|
||||||
};
|
};
|
||||||
|
|||||||
50
src/routes/inventory/purchaseorders.js
Normal file
50
src/routes/inventory/purchaseorders.js
Normal file
@ -0,0 +1,50 @@
|
|||||||
|
import express from 'express';
|
||||||
|
import { isAuthenticated } from '../../keycloak.js';
|
||||||
|
import { getFilter, convertPropertiesString } from '../../utils.js';
|
||||||
|
|
||||||
|
const router = express.Router();
|
||||||
|
import {
|
||||||
|
listPurchaseOrdersRouteHandler,
|
||||||
|
getPurchaseOrderRouteHandler,
|
||||||
|
editPurchaseOrderRouteHandler,
|
||||||
|
newPurchaseOrderRouteHandler,
|
||||||
|
deletePurchaseOrderRouteHandler,
|
||||||
|
listPurchaseOrdersByPropertiesRouteHandler,
|
||||||
|
} from '../../services/inventory/purchaseorders.js';
|
||||||
|
|
||||||
|
// list of purchase orders
|
||||||
|
router.get('/', isAuthenticated, (req, res) => {
|
||||||
|
const { page, limit, property, search, sort, order } = req.query;
|
||||||
|
const allowedFilters = ['vendor', 'state', 'value', 'vendor._id'];
|
||||||
|
const filter = getFilter(req.query, allowedFilters);
|
||||||
|
listPurchaseOrdersRouteHandler(req, res, page, limit, property, filter, search, sort, order);
|
||||||
|
});
|
||||||
|
|
||||||
|
router.get('/properties', isAuthenticated, (req, res) => {
|
||||||
|
let properties = convertPropertiesString(req.query.properties);
|
||||||
|
const allowedFilters = ['vendor', 'state.type', 'value', 'vendor._id'];
|
||||||
|
const filter = getFilter(req.query, allowedFilters, false);
|
||||||
|
var masterFilter = {};
|
||||||
|
if (req.query.masterFilter) {
|
||||||
|
masterFilter = JSON.parse(req.query.masterFilter);
|
||||||
|
}
|
||||||
|
listPurchaseOrdersByPropertiesRouteHandler(req, res, properties, filter, masterFilter);
|
||||||
|
});
|
||||||
|
|
||||||
|
router.post('/', isAuthenticated, (req, res) => {
|
||||||
|
newPurchaseOrderRouteHandler(req, res);
|
||||||
|
});
|
||||||
|
|
||||||
|
router.get('/:id', isAuthenticated, (req, res) => {
|
||||||
|
getPurchaseOrderRouteHandler(req, res);
|
||||||
|
});
|
||||||
|
|
||||||
|
router.put('/:id', isAuthenticated, async (req, res) => {
|
||||||
|
editPurchaseOrderRouteHandler(req, res);
|
||||||
|
});
|
||||||
|
|
||||||
|
router.delete('/:id', isAuthenticated, async (req, res) => {
|
||||||
|
deletePurchaseOrderRouteHandler(req, res);
|
||||||
|
});
|
||||||
|
|
||||||
|
export default router;
|
||||||
46
src/routes/management/courier.js
Normal file
46
src/routes/management/courier.js
Normal file
@ -0,0 +1,46 @@
|
|||||||
|
import express from 'express';
|
||||||
|
import { isAuthenticated } from '../../keycloak.js';
|
||||||
|
import { getFilter, convertPropertiesString } from '../../utils.js';
|
||||||
|
|
||||||
|
const router = express.Router();
|
||||||
|
import {
|
||||||
|
listCouriersRouteHandler,
|
||||||
|
getCourierRouteHandler,
|
||||||
|
editCourierRouteHandler,
|
||||||
|
newCourierRouteHandler,
|
||||||
|
deleteCourierRouteHandler,
|
||||||
|
listCouriersByPropertiesRouteHandler,
|
||||||
|
} from '../../services/management/courier.js';
|
||||||
|
|
||||||
|
// list of couriers
|
||||||
|
router.get('/', isAuthenticated, (req, res) => {
|
||||||
|
const { page, limit, property, search, sort, order } = req.query;
|
||||||
|
const allowedFilters = ['name', 'website', 'email', 'phone', 'contact', 'country'];
|
||||||
|
const filter = getFilter(req.query, allowedFilters);
|
||||||
|
listCouriersRouteHandler(req, res, page, limit, property, filter, search, sort, order);
|
||||||
|
});
|
||||||
|
|
||||||
|
router.get('/properties', isAuthenticated, (req, res) => {
|
||||||
|
let properties = convertPropertiesString(req.query.properties);
|
||||||
|
const allowedFilters = ['name', 'website', 'email', 'phone', 'contact', 'country'];
|
||||||
|
const filter = getFilter(req.query, allowedFilters, false);
|
||||||
|
listCouriersByPropertiesRouteHandler(req, res, properties, filter);
|
||||||
|
});
|
||||||
|
|
||||||
|
router.post('/', isAuthenticated, (req, res) => {
|
||||||
|
newCourierRouteHandler(req, res);
|
||||||
|
});
|
||||||
|
|
||||||
|
router.get('/:id', isAuthenticated, (req, res) => {
|
||||||
|
getCourierRouteHandler(req, res);
|
||||||
|
});
|
||||||
|
|
||||||
|
router.put('/:id', isAuthenticated, async (req, res) => {
|
||||||
|
editCourierRouteHandler(req, res);
|
||||||
|
});
|
||||||
|
|
||||||
|
router.delete('/:id', isAuthenticated, async (req, res) => {
|
||||||
|
deleteCourierRouteHandler(req, res);
|
||||||
|
});
|
||||||
|
|
||||||
|
export default router;
|
||||||
46
src/routes/management/courierservice.js
Normal file
46
src/routes/management/courierservice.js
Normal file
@ -0,0 +1,46 @@
|
|||||||
|
import express from 'express';
|
||||||
|
import { isAuthenticated } from '../../keycloak.js';
|
||||||
|
import { getFilter, convertPropertiesString } from '../../utils.js';
|
||||||
|
|
||||||
|
const router = express.Router();
|
||||||
|
import {
|
||||||
|
listCourierServicesRouteHandler,
|
||||||
|
getCourierServiceRouteHandler,
|
||||||
|
editCourierServiceRouteHandler,
|
||||||
|
newCourierServiceRouteHandler,
|
||||||
|
deleteCourierServiceRouteHandler,
|
||||||
|
listCourierServicesByPropertiesRouteHandler,
|
||||||
|
} from '../../services/management/courierservice.js';
|
||||||
|
|
||||||
|
// list of courier services
|
||||||
|
router.get('/', isAuthenticated, (req, res) => {
|
||||||
|
const { page, limit, property, search, sort, order } = req.query;
|
||||||
|
const allowedFilters = ['courier._id', 'name', 'active', 'deliveryTime'];
|
||||||
|
const filter = getFilter(req.query, allowedFilters);
|
||||||
|
listCourierServicesRouteHandler(req, res, page, limit, property, filter, search, sort, order);
|
||||||
|
});
|
||||||
|
|
||||||
|
router.get('/properties', isAuthenticated, (req, res) => {
|
||||||
|
let properties = convertPropertiesString(req.query.properties);
|
||||||
|
const allowedFilters = ['courier._id', 'name', 'active', 'deliveryTime', 'courier'];
|
||||||
|
const filter = getFilter(req.query, allowedFilters, false);
|
||||||
|
listCourierServicesByPropertiesRouteHandler(req, res, properties, filter);
|
||||||
|
});
|
||||||
|
|
||||||
|
router.post('/', isAuthenticated, (req, res) => {
|
||||||
|
newCourierServiceRouteHandler(req, res);
|
||||||
|
});
|
||||||
|
|
||||||
|
router.get('/:id', isAuthenticated, (req, res) => {
|
||||||
|
getCourierServiceRouteHandler(req, res);
|
||||||
|
});
|
||||||
|
|
||||||
|
router.put('/:id', isAuthenticated, async (req, res) => {
|
||||||
|
editCourierServiceRouteHandler(req, res);
|
||||||
|
});
|
||||||
|
|
||||||
|
router.delete('/:id', isAuthenticated, async (req, res) => {
|
||||||
|
deleteCourierServiceRouteHandler(req, res);
|
||||||
|
});
|
||||||
|
|
||||||
|
export default router;
|
||||||
@ -15,7 +15,7 @@ import {
|
|||||||
// list of parts
|
// list of parts
|
||||||
router.get('/', isAuthenticated, (req, res) => {
|
router.get('/', isAuthenticated, (req, res) => {
|
||||||
const { page, limit, property, search, sort, order } = req.query;
|
const { page, limit, property, search, sort, order } = req.query;
|
||||||
const allowedFilters = ['product._id', '_id', 'name', 'globalPrice'];
|
const allowedFilters = ['product._id', '_id', 'name'];
|
||||||
const filter = getFilter(req.query, allowedFilters);
|
const filter = getFilter(req.query, allowedFilters);
|
||||||
listPartsRouteHandler(req, res, page, limit, property, filter, search, sort, order);
|
listPartsRouteHandler(req, res, page, limit, property, filter, search, sort, order);
|
||||||
});
|
});
|
||||||
|
|||||||
@ -2,32 +2,23 @@ import mongoose from 'mongoose';
|
|||||||
import { generateId } from '../../utils.js';
|
import { generateId } from '../../utils.js';
|
||||||
const { Schema } = mongoose;
|
const { Schema } = mongoose;
|
||||||
|
|
||||||
|
const itemSchema = new Schema({
|
||||||
|
itemType: { type: String, required: true },
|
||||||
|
item: { type: Schema.Types.ObjectId, refPath: 'itemType', required: true },
|
||||||
|
quantity: { type: Number, required: true },
|
||||||
|
price: { type: Number, required: true },
|
||||||
|
});
|
||||||
|
|
||||||
const purchaseOrderSchema = new Schema(
|
const purchaseOrderSchema = new Schema(
|
||||||
{
|
{
|
||||||
_reference: { type: String, default: () => generateId()() },
|
_reference: { type: String, default: () => generateId()() },
|
||||||
value: { type: Number, required: true },
|
cost: { net: { type: Number, required: true }, gross: { type: Number, required: true } },
|
||||||
unit: { type: String, required: true },
|
items: [itemSchema],
|
||||||
parent: {
|
|
||||||
type: Schema.Types.ObjectId,
|
|
||||||
refPath: 'parentType',
|
|
||||||
required: true,
|
|
||||||
},
|
|
||||||
parentType: {
|
|
||||||
type: String,
|
|
||||||
required: true,
|
|
||||||
enum: ['filamentStock', 'partStock', 'productStock'], // Add other models as needed
|
|
||||||
},
|
|
||||||
owner: {
|
|
||||||
type: Schema.Types.ObjectId,
|
|
||||||
refPath: 'ownerType',
|
|
||||||
required: true,
|
|
||||||
},
|
|
||||||
ownerType: {
|
|
||||||
type: String,
|
|
||||||
required: true,
|
|
||||||
enum: ['user', 'subJob', 'stockAudit'],
|
|
||||||
},
|
|
||||||
timestamp: { type: Date, default: Date.now },
|
timestamp: { type: Date, default: Date.now },
|
||||||
|
vendor: { type: Schema.Types.ObjectId, ref: 'vendor', required: true },
|
||||||
|
state: {
|
||||||
|
type: { type: String, required: true, default: 'draft' },
|
||||||
|
},
|
||||||
},
|
},
|
||||||
{ timestamps: true }
|
{ timestamps: true }
|
||||||
);
|
);
|
||||||
|
|||||||
23
src/schemas/management/courier.schema.js
Normal file
23
src/schemas/management/courier.schema.js
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
import mongoose from 'mongoose';
|
||||||
|
import { generateId } from '../../utils.js';
|
||||||
|
|
||||||
|
const courierSchema = new mongoose.Schema(
|
||||||
|
{
|
||||||
|
_reference: { type: String, default: () => generateId()() },
|
||||||
|
name: { required: true, type: String },
|
||||||
|
website: { required: false, type: String },
|
||||||
|
email: { required: false, type: String },
|
||||||
|
phone: { required: false, type: String },
|
||||||
|
contact: { required: false, type: String },
|
||||||
|
country: { required: false, type: String },
|
||||||
|
},
|
||||||
|
{ timestamps: true }
|
||||||
|
);
|
||||||
|
|
||||||
|
courierSchema.virtual('id').get(function () {
|
||||||
|
return this._id;
|
||||||
|
});
|
||||||
|
|
||||||
|
courierSchema.set('toJSON', { virtuals: true });
|
||||||
|
|
||||||
|
export const courierModel = mongoose.model('courier', courierSchema);
|
||||||
24
src/schemas/management/courierservice.schema.js
Normal file
24
src/schemas/management/courierservice.schema.js
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
import mongoose from 'mongoose';
|
||||||
|
import { generateId } from '../../utils.js';
|
||||||
|
const { Schema } = mongoose;
|
||||||
|
|
||||||
|
const courierServiceSchema = new mongoose.Schema(
|
||||||
|
{
|
||||||
|
_reference: { type: String, default: () => generateId()() },
|
||||||
|
name: { required: true, type: String },
|
||||||
|
courier: { type: Schema.Types.ObjectId, ref: 'courier', required: true },
|
||||||
|
active: { required: true, type: Boolean },
|
||||||
|
tracked: { required: true, type: Boolean },
|
||||||
|
deliveryTime: { required: true, type: Number },
|
||||||
|
website: { required: false, type: String },
|
||||||
|
},
|
||||||
|
{ timestamps: true }
|
||||||
|
);
|
||||||
|
|
||||||
|
courierServiceSchema.virtual('id').get(function () {
|
||||||
|
return this._id;
|
||||||
|
});
|
||||||
|
|
||||||
|
courierServiceSchema.set('toJSON', { virtuals: true });
|
||||||
|
|
||||||
|
export const courierServiceModel = mongoose.model('courierService', courierServiceSchema);
|
||||||
@ -8,9 +8,9 @@ const partSchema = new Schema(
|
|||||||
_reference: { type: String, default: () => generateId()() },
|
_reference: { type: String, default: () => generateId()() },
|
||||||
name: { type: String, required: true },
|
name: { type: String, required: true },
|
||||||
fileName: { type: String, required: false },
|
fileName: { type: String, required: false },
|
||||||
globalPricing: { type: Boolean, default: true },
|
|
||||||
priceMode: { type: String, default: 'margin' },
|
priceMode: { type: String, default: 'margin' },
|
||||||
amount: { type: Number, required: false },
|
price: { type: Number, required: true },
|
||||||
|
cost: { type: Number, required: true },
|
||||||
margin: { type: Number, required: false },
|
margin: { type: Number, required: false },
|
||||||
vendor: { type: Schema.Types.ObjectId, ref: 'vendor', required: true },
|
vendor: { type: Schema.Types.ObjectId, ref: 'vendor', required: true },
|
||||||
file: { type: mongoose.SchemaTypes.ObjectId, ref: 'file', required: false },
|
file: { type: mongoose.SchemaTypes.ObjectId, ref: 'file', required: false },
|
||||||
|
|||||||
0
src/schemas/sales/salesorder.schema.js
Normal file
0
src/schemas/sales/salesorder.schema.js
Normal file
163
src/services/inventory/purchaseorders.js
Normal file
163
src/services/inventory/purchaseorders.js
Normal file
@ -0,0 +1,163 @@
|
|||||||
|
import dotenv from 'dotenv';
|
||||||
|
import { purchaseOrderModel } from '../../schemas/inventory/purchaseorder.schema.js';
|
||||||
|
import log4js from 'log4js';
|
||||||
|
import mongoose from 'mongoose';
|
||||||
|
import {
|
||||||
|
deleteObject,
|
||||||
|
listObjects,
|
||||||
|
getObject,
|
||||||
|
editObject,
|
||||||
|
newObject,
|
||||||
|
listObjectsByProperties,
|
||||||
|
} from '../../database/database.js';
|
||||||
|
dotenv.config();
|
||||||
|
|
||||||
|
const logger = log4js.getLogger('Purchase Orders');
|
||||||
|
logger.level = process.env.LOG_LEVEL;
|
||||||
|
|
||||||
|
export const listPurchaseOrdersRouteHandler = async (
|
||||||
|
req,
|
||||||
|
res,
|
||||||
|
page = 1,
|
||||||
|
limit = 25,
|
||||||
|
property = '',
|
||||||
|
filter = {},
|
||||||
|
search = '',
|
||||||
|
sort = '',
|
||||||
|
order = 'ascend'
|
||||||
|
) => {
|
||||||
|
const result = await listObjects({
|
||||||
|
model: purchaseOrderModel,
|
||||||
|
page,
|
||||||
|
limit,
|
||||||
|
property,
|
||||||
|
filter,
|
||||||
|
search,
|
||||||
|
sort,
|
||||||
|
order,
|
||||||
|
populate: ['vendor'],
|
||||||
|
});
|
||||||
|
|
||||||
|
if (result?.error) {
|
||||||
|
logger.error('Error listing purchase orders.');
|
||||||
|
res.status(result.code).send(result);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
logger.debug(`List of purchase orders (Page ${page}, Limit ${limit}). Count: ${result.length}`);
|
||||||
|
res.send(result);
|
||||||
|
};
|
||||||
|
|
||||||
|
export const listPurchaseOrdersByPropertiesRouteHandler = async (
|
||||||
|
req,
|
||||||
|
res,
|
||||||
|
properties = '',
|
||||||
|
filter = {},
|
||||||
|
masterFilter = {}
|
||||||
|
) => {
|
||||||
|
const result = await listObjectsByProperties({
|
||||||
|
model: purchaseOrderModel,
|
||||||
|
properties,
|
||||||
|
filter,
|
||||||
|
populate: ['vendor'],
|
||||||
|
masterFilter,
|
||||||
|
});
|
||||||
|
|
||||||
|
if (result?.error) {
|
||||||
|
logger.error('Error listing purchase orders.');
|
||||||
|
res.status(result.code).send(result);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
logger.debug(`List of purchase orders. Count: ${result.length}`);
|
||||||
|
res.send(result);
|
||||||
|
};
|
||||||
|
|
||||||
|
export const getPurchaseOrderRouteHandler = async (req, res) => {
|
||||||
|
const id = req.params.id;
|
||||||
|
const result = await getObject({
|
||||||
|
model: purchaseOrderModel,
|
||||||
|
id,
|
||||||
|
populate: ['vendor', 'items.item'],
|
||||||
|
});
|
||||||
|
if (result?.error) {
|
||||||
|
logger.warn(`Purchase Order not found with supplied id.`);
|
||||||
|
return res.status(result.code).send(result);
|
||||||
|
}
|
||||||
|
logger.debug(`Retreived purchase order with ID: ${id}`);
|
||||||
|
res.send(result);
|
||||||
|
};
|
||||||
|
|
||||||
|
export const editPurchaseOrderRouteHandler = async (req, res) => {
|
||||||
|
// Get ID from params
|
||||||
|
const id = new mongoose.Types.ObjectId(req.params.id);
|
||||||
|
|
||||||
|
logger.trace(`Purchase Order with ID: ${id}`);
|
||||||
|
|
||||||
|
const updateData = {
|
||||||
|
updatedAt: new Date(),
|
||||||
|
vendor: req.body.vendor,
|
||||||
|
items: req.body.items,
|
||||||
|
cost: req.body.cost,
|
||||||
|
};
|
||||||
|
// Create audit log before updating
|
||||||
|
const result = await editObject({
|
||||||
|
model: purchaseOrderModel,
|
||||||
|
id,
|
||||||
|
updateData,
|
||||||
|
user: req.user,
|
||||||
|
});
|
||||||
|
|
||||||
|
if (result.error) {
|
||||||
|
logger.error('Error editing purchase order:', result.error);
|
||||||
|
res.status(result).send(result);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
logger.debug(`Edited purchase order with ID: ${id}`);
|
||||||
|
|
||||||
|
res.send(result);
|
||||||
|
};
|
||||||
|
|
||||||
|
export const newPurchaseOrderRouteHandler = async (req, res) => {
|
||||||
|
const newData = {
|
||||||
|
updatedAt: new Date(),
|
||||||
|
vendor: req.body.vendor,
|
||||||
|
items: req.body.items,
|
||||||
|
cost: req.body.cost,
|
||||||
|
};
|
||||||
|
const result = await newObject({
|
||||||
|
model: purchaseOrderModel,
|
||||||
|
newData,
|
||||||
|
user: req.user,
|
||||||
|
});
|
||||||
|
if (result.error) {
|
||||||
|
logger.error('No purchase order created:', result.error);
|
||||||
|
return res.status(result.code).send(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
logger.debug(`New purchase order with ID: ${result._id}`);
|
||||||
|
|
||||||
|
res.send(result);
|
||||||
|
};
|
||||||
|
|
||||||
|
export const deletePurchaseOrderRouteHandler = async (req, res) => {
|
||||||
|
// Get ID from params
|
||||||
|
const id = new mongoose.Types.ObjectId(req.params.id);
|
||||||
|
|
||||||
|
logger.trace(`Purchase Order with ID: ${id}`);
|
||||||
|
|
||||||
|
const result = await deleteObject({
|
||||||
|
model: purchaseOrderModel,
|
||||||
|
id,
|
||||||
|
user: req.user,
|
||||||
|
});
|
||||||
|
if (result.error) {
|
||||||
|
logger.error('No purchase order deleted:', result.error);
|
||||||
|
return res.status(result.code).send(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
logger.debug(`Deleted purchase order with ID: ${result._id}`);
|
||||||
|
|
||||||
|
res.send(result);
|
||||||
|
};
|
||||||
164
src/services/management/courier.js
Normal file
164
src/services/management/courier.js
Normal file
@ -0,0 +1,164 @@
|
|||||||
|
import dotenv from 'dotenv';
|
||||||
|
import { courierModel } from '../../schemas/management/courier.schema.js';
|
||||||
|
import log4js from 'log4js';
|
||||||
|
import mongoose from 'mongoose';
|
||||||
|
import {
|
||||||
|
deleteObject,
|
||||||
|
listObjects,
|
||||||
|
getObject,
|
||||||
|
editObject,
|
||||||
|
newObject,
|
||||||
|
listObjectsByProperties,
|
||||||
|
} from '../../database/database.js';
|
||||||
|
dotenv.config();
|
||||||
|
|
||||||
|
const logger = log4js.getLogger('Couriers');
|
||||||
|
logger.level = process.env.LOG_LEVEL;
|
||||||
|
|
||||||
|
export const listCouriersRouteHandler = async (
|
||||||
|
req,
|
||||||
|
res,
|
||||||
|
page = 1,
|
||||||
|
limit = 25,
|
||||||
|
property = '',
|
||||||
|
filter = {},
|
||||||
|
search = '',
|
||||||
|
sort = '',
|
||||||
|
order = 'ascend'
|
||||||
|
) => {
|
||||||
|
const result = await listObjects({
|
||||||
|
model: courierModel,
|
||||||
|
page,
|
||||||
|
limit,
|
||||||
|
property,
|
||||||
|
filter,
|
||||||
|
search,
|
||||||
|
sort,
|
||||||
|
order,
|
||||||
|
});
|
||||||
|
|
||||||
|
if (result?.error) {
|
||||||
|
logger.error('Error listing couriers.');
|
||||||
|
res.status(result.code).send(result);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
logger.debug(`List of couriers (Page ${page}, Limit ${limit}). Count: ${result.length}.`);
|
||||||
|
res.send(result);
|
||||||
|
};
|
||||||
|
|
||||||
|
export const listCouriersByPropertiesRouteHandler = async (
|
||||||
|
req,
|
||||||
|
res,
|
||||||
|
properties = '',
|
||||||
|
filter = {}
|
||||||
|
) => {
|
||||||
|
const result = await listObjectsByProperties({
|
||||||
|
model: courierModel,
|
||||||
|
properties,
|
||||||
|
filter,
|
||||||
|
});
|
||||||
|
|
||||||
|
if (result?.error) {
|
||||||
|
logger.error('Error listing couriers.');
|
||||||
|
res.status(result.code).send(result);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
logger.debug(`List of couriers. Count: ${result.length}`);
|
||||||
|
res.send(result);
|
||||||
|
};
|
||||||
|
|
||||||
|
export const getCourierRouteHandler = async (req, res) => {
|
||||||
|
const id = req.params.id;
|
||||||
|
const result = await getObject({
|
||||||
|
model: courierModel,
|
||||||
|
id,
|
||||||
|
});
|
||||||
|
if (result?.error) {
|
||||||
|
logger.warn(`Courier not found with supplied id.`);
|
||||||
|
return res.status(result.code).send(result);
|
||||||
|
}
|
||||||
|
logger.debug(`Retreived courier with ID: ${id}`);
|
||||||
|
res.send(result);
|
||||||
|
};
|
||||||
|
|
||||||
|
export const editCourierRouteHandler = async (req, res) => {
|
||||||
|
// Get ID from params
|
||||||
|
const id = new mongoose.Types.ObjectId(req.params.id);
|
||||||
|
|
||||||
|
logger.trace(`Courier with ID: ${id}`);
|
||||||
|
|
||||||
|
const updateData = {
|
||||||
|
updatedAt: new Date(),
|
||||||
|
contact: req.body?.contact,
|
||||||
|
country: req.body?.country,
|
||||||
|
name: req.body?.name,
|
||||||
|
website: req.body?.website,
|
||||||
|
phone: req.body?.phone,
|
||||||
|
email: req.body?.email,
|
||||||
|
};
|
||||||
|
// Create audit log before updating
|
||||||
|
const result = await editObject({
|
||||||
|
model: courierModel,
|
||||||
|
id,
|
||||||
|
updateData,
|
||||||
|
user: req.user,
|
||||||
|
});
|
||||||
|
|
||||||
|
if (result.error) {
|
||||||
|
logger.error('Error editing courier:', result.error);
|
||||||
|
res.status(result).send(result);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
logger.debug(`Edited courier with ID: ${id}`);
|
||||||
|
|
||||||
|
res.send(result);
|
||||||
|
};
|
||||||
|
|
||||||
|
export const newCourierRouteHandler = async (req, res) => {
|
||||||
|
const newData = {
|
||||||
|
updatedAt: new Date(),
|
||||||
|
contact: req.body?.contact,
|
||||||
|
country: req.body?.country,
|
||||||
|
name: req.body?.name,
|
||||||
|
website: req.body?.website,
|
||||||
|
phone: req.body?.phone,
|
||||||
|
email: req.body?.email,
|
||||||
|
};
|
||||||
|
const result = await newObject({
|
||||||
|
model: courierModel,
|
||||||
|
newData,
|
||||||
|
user: req.user,
|
||||||
|
});
|
||||||
|
if (result.error) {
|
||||||
|
logger.error('No courier created:', result.error);
|
||||||
|
return res.status(result.code).send(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
logger.debug(`New courier with ID: ${result._id}`);
|
||||||
|
|
||||||
|
res.send(result);
|
||||||
|
};
|
||||||
|
|
||||||
|
export const deleteCourierRouteHandler = async (req, res) => {
|
||||||
|
// Get ID from params
|
||||||
|
const id = new mongoose.Types.ObjectId(req.params.id);
|
||||||
|
|
||||||
|
logger.trace(`Courier with ID: ${id}`);
|
||||||
|
|
||||||
|
const result = await deleteObject({
|
||||||
|
model: courierModel,
|
||||||
|
id,
|
||||||
|
user: req.user,
|
||||||
|
});
|
||||||
|
if (result.error) {
|
||||||
|
logger.error('No courier deleted:', result.error);
|
||||||
|
return res.status(result.code).send(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
logger.debug(`Deleted courier with ID: ${result._id}`);
|
||||||
|
|
||||||
|
res.send(result);
|
||||||
|
};
|
||||||
167
src/services/management/courierservice.js
Normal file
167
src/services/management/courierservice.js
Normal file
@ -0,0 +1,167 @@
|
|||||||
|
import dotenv from 'dotenv';
|
||||||
|
import { courierServiceModel } from '../../schemas/management/courierservice.schema.js';
|
||||||
|
import log4js from 'log4js';
|
||||||
|
import mongoose from 'mongoose';
|
||||||
|
import {
|
||||||
|
deleteObject,
|
||||||
|
listObjects,
|
||||||
|
getObject,
|
||||||
|
editObject,
|
||||||
|
newObject,
|
||||||
|
listObjectsByProperties,
|
||||||
|
} from '../../database/database.js';
|
||||||
|
dotenv.config();
|
||||||
|
|
||||||
|
const logger = log4js.getLogger('CourierServices');
|
||||||
|
logger.level = process.env.LOG_LEVEL;
|
||||||
|
|
||||||
|
export const listCourierServicesRouteHandler = async (
|
||||||
|
req,
|
||||||
|
res,
|
||||||
|
page = 1,
|
||||||
|
limit = 25,
|
||||||
|
property = '',
|
||||||
|
filter = {},
|
||||||
|
search = '',
|
||||||
|
sort = '',
|
||||||
|
order = 'ascend'
|
||||||
|
) => {
|
||||||
|
const result = await listObjects({
|
||||||
|
model: courierServiceModel,
|
||||||
|
page,
|
||||||
|
limit,
|
||||||
|
property,
|
||||||
|
filter,
|
||||||
|
search,
|
||||||
|
sort,
|
||||||
|
order,
|
||||||
|
populate: ['courier'],
|
||||||
|
});
|
||||||
|
|
||||||
|
if (result?.error) {
|
||||||
|
logger.error('Error listing courier services.');
|
||||||
|
res.status(result.code).send(result);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
logger.debug(`List of courier services (Page ${page}, Limit ${limit}). Count: ${result.length}.`);
|
||||||
|
res.send(result);
|
||||||
|
};
|
||||||
|
|
||||||
|
export const listCourierServicesByPropertiesRouteHandler = async (
|
||||||
|
req,
|
||||||
|
res,
|
||||||
|
properties = '',
|
||||||
|
filter = {}
|
||||||
|
) => {
|
||||||
|
const result = await listObjectsByProperties({
|
||||||
|
model: courierServiceModel,
|
||||||
|
properties,
|
||||||
|
filter,
|
||||||
|
populate: ['courier'],
|
||||||
|
});
|
||||||
|
|
||||||
|
if (result?.error) {
|
||||||
|
logger.error('Error listing courier services.');
|
||||||
|
res.status(result.code).send(result);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
logger.debug(`List of courier services. Count: ${result.length}`);
|
||||||
|
res.send(result);
|
||||||
|
};
|
||||||
|
|
||||||
|
export const getCourierServiceRouteHandler = async (req, res) => {
|
||||||
|
const id = req.params.id;
|
||||||
|
const result = await getObject({
|
||||||
|
model: courierServiceModel,
|
||||||
|
id,
|
||||||
|
populate: ['courier'],
|
||||||
|
});
|
||||||
|
if (result?.error) {
|
||||||
|
logger.warn(`Courier service not found with supplied id.`);
|
||||||
|
return res.status(result.code).send(result);
|
||||||
|
}
|
||||||
|
logger.debug(`Retreived courier service with ID: ${id}`);
|
||||||
|
res.send(result);
|
||||||
|
};
|
||||||
|
|
||||||
|
export const editCourierServiceRouteHandler = async (req, res) => {
|
||||||
|
// Get ID from params
|
||||||
|
const id = new mongoose.Types.ObjectId(req.params.id);
|
||||||
|
|
||||||
|
logger.trace(`Courier service with ID: ${id}`);
|
||||||
|
|
||||||
|
const updateData = {
|
||||||
|
updatedAt: new Date(),
|
||||||
|
courier: req.body?.courier,
|
||||||
|
website: req.body?.website,
|
||||||
|
deliveryTime: req.body?.deliveryTime,
|
||||||
|
active: req.body?.active,
|
||||||
|
tracked: req.body?.tracked,
|
||||||
|
name: req.body?.name,
|
||||||
|
};
|
||||||
|
// Create audit log before updating
|
||||||
|
const result = await editObject({
|
||||||
|
model: courierServiceModel,
|
||||||
|
id,
|
||||||
|
updateData,
|
||||||
|
user: req.user,
|
||||||
|
});
|
||||||
|
|
||||||
|
if (result.error) {
|
||||||
|
logger.error('Error editing courier service:', result.error);
|
||||||
|
res.status(result).send(result);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
logger.debug(`Edited courier service with ID: ${id}`);
|
||||||
|
|
||||||
|
res.send(result);
|
||||||
|
};
|
||||||
|
|
||||||
|
export const newCourierServiceRouteHandler = async (req, res) => {
|
||||||
|
const newData = {
|
||||||
|
updatedAt: new Date(),
|
||||||
|
courier: req.body?.courier,
|
||||||
|
website: req.body?.website,
|
||||||
|
deliveryTime: req.body?.deliveryTime,
|
||||||
|
active: req.body?.active,
|
||||||
|
tracked: req.body?.tracked,
|
||||||
|
name: req.body?.name,
|
||||||
|
};
|
||||||
|
const result = await newObject({
|
||||||
|
model: courierServiceModel,
|
||||||
|
newData,
|
||||||
|
user: req.user,
|
||||||
|
});
|
||||||
|
if (result.error) {
|
||||||
|
logger.error('No courier service created:', result.error);
|
||||||
|
return res.status(result.code).send(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
logger.debug(`New courier service with ID: ${result._id}`);
|
||||||
|
|
||||||
|
res.send(result);
|
||||||
|
};
|
||||||
|
|
||||||
|
export const deleteCourierServiceRouteHandler = async (req, res) => {
|
||||||
|
// Get ID from params
|
||||||
|
const id = new mongoose.Types.ObjectId(req.params.id);
|
||||||
|
|
||||||
|
logger.trace(`Courier service with ID: ${id}`);
|
||||||
|
|
||||||
|
const result = await deleteObject({
|
||||||
|
model: courierServiceModel,
|
||||||
|
id,
|
||||||
|
user: req.user,
|
||||||
|
});
|
||||||
|
if (result.error) {
|
||||||
|
logger.error('No courier service deleted:', result.error);
|
||||||
|
return res.status(result.code).send(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
logger.debug(`Deleted courier service with ID: ${result._id}`);
|
||||||
|
|
||||||
|
res.send(result);
|
||||||
|
};
|
||||||
@ -90,11 +90,11 @@ export const editPartRouteHandler = async (req, res) => {
|
|||||||
const updateData = {
|
const updateData = {
|
||||||
updatedAt: new Date(),
|
updatedAt: new Date(),
|
||||||
name: req.body?.name,
|
name: req.body?.name,
|
||||||
globalPricing: req.body.globalPricing,
|
|
||||||
file: req.body?.file,
|
file: req.body?.file,
|
||||||
vendor: req.body?.vendor,
|
vendor: req.body?.vendor,
|
||||||
margin: req.body?.margin,
|
margin: req.body?.margin,
|
||||||
amount: req.body?.amount,
|
price: req.body?.price,
|
||||||
|
cost: req.body?.cost,
|
||||||
priceMode: req.body?.priceMode,
|
priceMode: req.body?.priceMode,
|
||||||
};
|
};
|
||||||
// Create audit log before updating
|
// Create audit log before updating
|
||||||
@ -120,11 +120,11 @@ export const newPartRouteHandler = async (req, res) => {
|
|||||||
const newData = {
|
const newData = {
|
||||||
updatedAt: new Date(),
|
updatedAt: new Date(),
|
||||||
name: req.body?.name,
|
name: req.body?.name,
|
||||||
globalPricing: req.body.globalPricing,
|
|
||||||
file: req.body?.file,
|
file: req.body?.file,
|
||||||
vendor: req.body?.vendor,
|
vendor: req.body?.vendor,
|
||||||
margin: req.body?.margin,
|
margin: req.body?.margin,
|
||||||
amount: req.body?.amount,
|
price: req.body?.price,
|
||||||
|
cost: req.body?.cost,
|
||||||
priceMode: req.body?.priceMode,
|
priceMode: req.body?.priceMode,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@ -7,6 +7,7 @@ import { partModel } from '../../schemas/management/part.schema.js';
|
|||||||
import { productModel } from '../../schemas/management/product.schema.js';
|
import { productModel } from '../../schemas/management/product.schema.js';
|
||||||
import { vendorModel } from '../../schemas/management/vendor.schema.js';
|
import { vendorModel } from '../../schemas/management/vendor.schema.js';
|
||||||
import { filamentStockModel } from '../../schemas/inventory/filamentstock.schema.js';
|
import { filamentStockModel } from '../../schemas/inventory/filamentstock.schema.js';
|
||||||
|
import { purchaseOrderModel } from '../../schemas/inventory/purchaseorder.schema.js';
|
||||||
import { stockEventModel } from '../../schemas/inventory/stockevent.schema.js';
|
import { stockEventModel } from '../../schemas/inventory/stockevent.schema.js';
|
||||||
import { stockAuditModel } from '../../schemas/inventory/stockaudit.schema.js';
|
import { stockAuditModel } from '../../schemas/inventory/stockaudit.schema.js';
|
||||||
import { partStockModel } from '../../schemas/inventory/partstock.schema.js';
|
import { partStockModel } from '../../schemas/inventory/partstock.schema.js';
|
||||||
@ -20,6 +21,8 @@ import { hostModel } from '../../schemas/management/host.schema.js';
|
|||||||
import { documentPrinterModel } from '../../schemas/management/documentprinter.schema.js';
|
import { documentPrinterModel } from '../../schemas/management/documentprinter.schema.js';
|
||||||
import { documentJobModel } from '../../schemas/management/documentjob.schema.js';
|
import { documentJobModel } from '../../schemas/management/documentjob.schema.js';
|
||||||
import { fileModel } from '../../schemas/management/file.schema.js';
|
import { fileModel } from '../../schemas/management/file.schema.js';
|
||||||
|
import { courierServiceModel } from '../../schemas/management/courierservice.schema.js';
|
||||||
|
import { courierModel } from '../../schemas/management/courier.schema.js';
|
||||||
|
|
||||||
// Map prefixes to models and id fields
|
// Map prefixes to models and id fields
|
||||||
const PREFIX_MODEL_MAP = {
|
const PREFIX_MODEL_MAP = {
|
||||||
@ -46,6 +49,9 @@ const PREFIX_MODEL_MAP = {
|
|||||||
DJB: { model: documentJobModel, idField: '_id', type: 'documentJob' },
|
DJB: { model: documentJobModel, idField: '_id', type: 'documentJob' },
|
||||||
HST: { model: hostModel, idField: '_id', type: 'host' },
|
HST: { model: hostModel, idField: '_id', type: 'host' },
|
||||||
FLE: { model: fileModel, idField: '_id', type: 'file' },
|
FLE: { model: fileModel, idField: '_id', type: 'file' },
|
||||||
|
POR: { model: purchaseOrderModel, idField: '_id', type: 'purchaseOrder' },
|
||||||
|
COS: { model: courierServiceModel, idField: '_id', type: 'courierService' },
|
||||||
|
COR: { model: courierModel, idField: '_id', type: 'courier' },
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user