Enhance order item schema with new fields for state management, shipment tracking, and tax calculations. Introduce rollup statistics and history methods for improved data aggregation and reporting.
This commit is contained in:
parent
75e5079479
commit
9c4b73da67
@ -1,6 +1,12 @@
|
||||
import mongoose from 'mongoose';
|
||||
import { purchaseOrderModel } from './purchaseorder.schema.js';
|
||||
import { aggregateRollups, editObject } from '../../database.js';
|
||||
import { taxRateModel } from '../management/taxrate.schema.js';
|
||||
import {
|
||||
aggregateRollups,
|
||||
aggregateRollupsHistory,
|
||||
editObject,
|
||||
getObject,
|
||||
} from '../../database.js';
|
||||
import { generateId } from '../../utils.js';
|
||||
const { Schema } = mongoose;
|
||||
|
||||
@ -8,20 +14,64 @@ const orderItemSchema = new Schema(
|
||||
{
|
||||
_reference: { type: String, default: () => generateId()() },
|
||||
orderType: { type: String, required: true },
|
||||
state: {
|
||||
type: { type: String, required: true, default: 'draft' },
|
||||
},
|
||||
order: { type: Schema.Types.ObjectId, refPath: 'orderType', required: true },
|
||||
itemType: { type: String, required: true },
|
||||
item: { type: Schema.Types.ObjectId, refPath: 'itemType', required: true },
|
||||
syncAmount: { type: String, required: true, default: null },
|
||||
syncAmount: { type: String, required: false, default: null },
|
||||
itemAmount: { type: Number, required: true },
|
||||
quantity: { type: Number, required: true },
|
||||
totalAmount: { type: Number, required: true },
|
||||
taxRate: { type: Schema.Types.ObjectId, ref: 'taxRate', required: false },
|
||||
totalAmountWithTax: { type: Number, required: true },
|
||||
timestamp: { type: Date, default: Date.now },
|
||||
shipment: { type: Schema.Types.ObjectId, ref: 'shipment', required: false },
|
||||
orderedAt: { type: Date, required: false },
|
||||
receivedAt: { type: Date, required: false },
|
||||
},
|
||||
{ timestamps: true }
|
||||
);
|
||||
|
||||
const rollupConfigs = [
|
||||
{
|
||||
name: 'shipped',
|
||||
filter: { 'state.type': 'shipped' },
|
||||
rollups: [{ name: 'shipped', property: 'state.type', operation: 'count' }],
|
||||
},
|
||||
{
|
||||
name: 'received',
|
||||
filter: { 'state.type': 'received' },
|
||||
rollups: [{ name: 'received', property: 'state.type', operation: 'count' }],
|
||||
},
|
||||
];
|
||||
|
||||
orderItemSchema.statics.stats = async function () {
|
||||
const results = await aggregateRollups({
|
||||
model: this,
|
||||
baseFilter: {},
|
||||
rollupConfigs: rollupConfigs,
|
||||
});
|
||||
|
||||
console.log(results);
|
||||
|
||||
// Transform the results to match the expected format
|
||||
return results;
|
||||
};
|
||||
|
||||
orderItemSchema.statics.history = async function (from, to) {
|
||||
const results = await aggregateRollupsHistory({
|
||||
model: this,
|
||||
startDate: from,
|
||||
endDate: to,
|
||||
rollupConfigs: rollupConfigs,
|
||||
});
|
||||
|
||||
// Return time-series data array
|
||||
return results;
|
||||
};
|
||||
|
||||
orderItemSchema.statics.recalculate = async function (orderItem, user) {
|
||||
// Only purchase orders are supported for now
|
||||
if (orderItem.orderType !== 'purchaseOrder') {
|
||||
@ -33,6 +83,29 @@ orderItemSchema.statics.recalculate = async function (orderItem, user) {
|
||||
return;
|
||||
}
|
||||
|
||||
var taxRate = orderItem.taxRate;
|
||||
|
||||
if (orderItem.taxRate?._id && Object.keys(orderItem.taxRate).length == 1) {
|
||||
taxRate = await getObject({
|
||||
model: taxRateModel,
|
||||
id: orderItem.taxRate._id,
|
||||
cached: true,
|
||||
});
|
||||
}
|
||||
|
||||
const orderTotalAmount = orderItem.itemAmount * orderItem.quantity;
|
||||
const orderTotalAmountWithTax = orderTotalAmount * (1 + (taxRate?.rate || 0) / 100);
|
||||
await editObject({
|
||||
model: orderItemModel,
|
||||
id: orderItem._id,
|
||||
updateData: {
|
||||
totalAmount: orderTotalAmount,
|
||||
totalAmountWithTax: orderTotalAmountWithTax,
|
||||
},
|
||||
user,
|
||||
recalculate: false,
|
||||
});
|
||||
|
||||
const rollupResults = await aggregateRollups({
|
||||
model: this,
|
||||
baseFilter: {
|
||||
@ -51,21 +124,60 @@ orderItemSchema.statics.recalculate = async function (orderItem, user) {
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
name: 'overallCount',
|
||||
rollups: [{ name: 'overallCount', property: '_id', operation: 'count' }],
|
||||
},
|
||||
...rollupConfigs,
|
||||
],
|
||||
});
|
||||
|
||||
console.log('rollupResults', rollupResults);
|
||||
|
||||
const totals = rollupResults.orderTotals || {};
|
||||
const totalAmount = totals.totalAmount.sum?.toFixed(2) || 0;
|
||||
const totalAmountWithTax = totals.totalAmountWithTax.sum?.toFixed(2) || 0;
|
||||
|
||||
const purchaseOrder = await getObject({
|
||||
model: purchaseOrderModel,
|
||||
id: orderId,
|
||||
cached: true,
|
||||
});
|
||||
|
||||
const grandTotalAmount =
|
||||
parseFloat(totalAmountWithTax || 0) + parseFloat(purchaseOrder.shippingAmountWithTax || 0);
|
||||
|
||||
var updateData = {
|
||||
totalAmount: parseFloat(totalAmount).toFixed(2),
|
||||
totalAmountWithTax: parseFloat(totalAmountWithTax).toFixed(2),
|
||||
totalTaxAmount: parseFloat((totalAmountWithTax - totalAmount).toFixed(2)),
|
||||
grandTotalAmount: parseFloat(grandTotalAmount).toFixed(2),
|
||||
};
|
||||
|
||||
const overallCount = rollupResults.overallCount.count || 0;
|
||||
const shippedCount = rollupResults.shipped.count || 0;
|
||||
const receivedCount = rollupResults.received.count || 0;
|
||||
|
||||
if (shippedCount > 0 && shippedCount < overallCount) {
|
||||
updateData = { ...updateData, state: { type: 'partiallyShipped' } };
|
||||
}
|
||||
|
||||
if (shippedCount > 0 && shippedCount == overallCount) {
|
||||
updateData = { ...updateData, state: { type: 'shipped' } };
|
||||
}
|
||||
|
||||
if (receivedCount > 0 && receivedCount < overallCount) {
|
||||
updateData = { ...updateData, state: { type: 'partiallyReceived' } };
|
||||
}
|
||||
|
||||
if (receivedCount > 0 && receivedCount == overallCount) {
|
||||
updateData = { ...updateData, state: { type: 'received' } };
|
||||
}
|
||||
|
||||
await editObject({
|
||||
model: purchaseOrderModel,
|
||||
id: orderId,
|
||||
updateData: {
|
||||
totalAmount: parseFloat(totalAmount),
|
||||
totalAmountWithTax: parseFloat(totalAmountWithTax),
|
||||
totalTaxAmount: parseFloat(totalAmountWithTax - totalAmount),
|
||||
},
|
||||
updateData: updateData,
|
||||
user,
|
||||
});
|
||||
};
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user