Refactored shipment schema to include new fields and methods for handling order types and tax calculations.
This commit is contained in:
parent
5545452b0c
commit
c750b1a573
@ -1,43 +1,108 @@
|
|||||||
import mongoose from 'mongoose';
|
import mongoose from 'mongoose';
|
||||||
import { generateId } from '../../utils.js';
|
import { generateId } from '../../utils.js';
|
||||||
const { Schema } = mongoose;
|
const { Schema } = mongoose;
|
||||||
|
import { purchaseOrderModel } from './purchaseorder.schema.js';
|
||||||
const shipmentItemSchema = new Schema({
|
import { taxRateModel } from '../management/taxrate.schema.js';
|
||||||
itemType: { type: String, required: true },
|
import { aggregateRollups, editObject, getObject } from '../../database.js';
|
||||||
item: { type: Schema.Types.ObjectId, refPath: 'itemType', required: true },
|
|
||||||
quantity: { type: Number, required: true },
|
|
||||||
itemCost: { type: Number, required: true },
|
|
||||||
totalCost: { type: Number, required: true },
|
|
||||||
totalCostWithTax: { type: Number, required: true },
|
|
||||||
taxRate: { type: Schema.Types.ObjectId, ref: 'taxRate', required: false },
|
|
||||||
});
|
|
||||||
|
|
||||||
const shipmentSchema = new Schema(
|
const shipmentSchema = new Schema(
|
||||||
{
|
{
|
||||||
_reference: { type: String, default: () => generateId()() },
|
_reference: { type: String, default: () => generateId()() },
|
||||||
purchaseOrder: { type: Schema.Types.ObjectId, ref: 'purchaseOrder', required: true },
|
orderType: { type: String, required: true },
|
||||||
vendor: { type: Schema.Types.ObjectId, ref: 'vendor', required: true },
|
order: { type: Schema.Types.ObjectId, refPath: 'orderType', required: true },
|
||||||
courierService: { type: Schema.Types.ObjectId, ref: 'courierService', required: false },
|
courierService: { type: Schema.Types.ObjectId, ref: 'courierService', required: false },
|
||||||
trackingNumber: { type: String, required: false },
|
trackingNumber: { type: String, required: false },
|
||||||
items: [shipmentItemSchema],
|
amount: { type: Number, required: true },
|
||||||
cost: { net: { type: Number, required: true }, gross: { type: Number, required: true } },
|
amountWithTax: { type: Number, required: true },
|
||||||
shippedDate: { type: Date, required: false },
|
taxRate: { type: Schema.Types.ObjectId, ref: 'taxRate', required: false },
|
||||||
expectedDeliveryDate: { type: Date, required: false },
|
shippedAt: { type: Date, required: false },
|
||||||
actualDeliveryDate: { type: Date, required: false },
|
expectedAt: { type: Date, required: false },
|
||||||
|
deliveredAt: { type: Date, required: false },
|
||||||
|
cancelledAt: { type: Date, required: false },
|
||||||
state: {
|
state: {
|
||||||
type: {
|
type: {
|
||||||
type: String,
|
type: String,
|
||||||
required: true,
|
required: true,
|
||||||
default: 'pending',
|
|
||||||
enum: ['pending', 'shipped', 'in_transit', 'delivered', 'cancelled'],
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
notes: { type: String },
|
|
||||||
timestamp: { type: Date, default: Date.now },
|
|
||||||
},
|
},
|
||||||
{ timestamps: true }
|
{ timestamps: true }
|
||||||
);
|
);
|
||||||
|
|
||||||
|
shipmentSchema.statics.recalculate = async function (shipment, user) {
|
||||||
|
// Only purchase orders are supported for now
|
||||||
|
if (shipment.orderType !== 'purchaseOrder') {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const orderId = shipment.order?._id || shipment.order;
|
||||||
|
if (!orderId) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var taxRate = shipment.taxRate;
|
||||||
|
|
||||||
|
if (shipment.taxRate?._id && Object.keys(shipment.taxRate).length == 1) {
|
||||||
|
taxRate = await getObject({
|
||||||
|
model: taxRateModel,
|
||||||
|
id: shipment.taxRate._id,
|
||||||
|
cached: true,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
const amountWithTax = shipment.amount * (1 + (taxRate?.rate || 0) / 100);
|
||||||
|
await editObject({
|
||||||
|
model: shipmentModel,
|
||||||
|
id: shipment._id,
|
||||||
|
updateData: {
|
||||||
|
amountWithTax: amountWithTax,
|
||||||
|
},
|
||||||
|
user,
|
||||||
|
recalculate: false,
|
||||||
|
});
|
||||||
|
|
||||||
|
const rollupResults = await aggregateRollups({
|
||||||
|
model: this,
|
||||||
|
baseFilter: {
|
||||||
|
order: new mongoose.Types.ObjectId(orderId),
|
||||||
|
orderType: shipment.orderType,
|
||||||
|
},
|
||||||
|
rollupConfigs: [
|
||||||
|
{
|
||||||
|
name: 'shipmentTotals',
|
||||||
|
rollups: [
|
||||||
|
{ name: 'amount', property: 'amount', operation: 'sum' },
|
||||||
|
{ name: 'amountWithTax', property: 'amountWithTax', operation: 'sum' },
|
||||||
|
],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
});
|
||||||
|
|
||||||
|
const totals = rollupResults.shipmentTotals || {};
|
||||||
|
const totalShippingAmount = totals.amount.sum?.toFixed(2) || 0;
|
||||||
|
const totalShippingAmountWithTax = totals.amountWithTax.sum?.toFixed(2) || 0;
|
||||||
|
|
||||||
|
const purchaseOrder = await getObject({
|
||||||
|
model: purchaseOrderModel,
|
||||||
|
id: orderId,
|
||||||
|
cached: true,
|
||||||
|
});
|
||||||
|
|
||||||
|
const grandTotalAmount =
|
||||||
|
parseFloat(purchaseOrder.totalAmountWithTax || 0) + parseFloat(totalShippingAmountWithTax || 0);
|
||||||
|
await editObject({
|
||||||
|
model: purchaseOrderModel,
|
||||||
|
id: orderId,
|
||||||
|
updateData: {
|
||||||
|
shippingAmount: parseFloat(totalShippingAmount).toFixed(2),
|
||||||
|
shippingAmountWithTax: parseFloat(totalShippingAmountWithTax).toFixed(2),
|
||||||
|
grandTotalAmount: parseFloat(grandTotalAmount).toFixed(2),
|
||||||
|
},
|
||||||
|
user,
|
||||||
|
recalculate: false,
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
// Add virtual id getter
|
// Add virtual id getter
|
||||||
shipmentSchema.virtual('id').get(function () {
|
shipmentSchema.virtual('id').get(function () {
|
||||||
return this._id;
|
return this._id;
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user