Refactor database schemas and enhance inventory management
All checks were successful
farmcontrol/farmcontrol-ws/pipeline/head This commit looks good
All checks were successful
farmcontrol/farmcontrol-ws/pipeline/head This commit looks good
- Removed unnecessary logging in the `getFilter` function to streamline query processing. - Updated the `models` export to include new policy models for payment, fulfillment, and return, enhancing schema flexibility. - Enhanced the `partStock` schema with a default state for `type` and added a `postedAt` field for better tracking. - Introduced a new `marketplaceMappingSchema` in the `productCategory` schema to manage marketplace references. - Updated the `taxRate` schema to include `jurisdiction` and `shippingAndHandlingTaxed` fields for improved tax management. - Enhanced the `listing` and `listingVariant` schemas with new states and policy references to support additional business logic.
This commit is contained in:
parent
4109523f59
commit
cdc7b860ac
@ -900,7 +900,6 @@ async function getFilter(query, allowedFilters, parse = true, model = null) {
|
|||||||
for (const key of ['sortProperty', 'sortOrder', 'page', 'limit']) {
|
for (const key of ['sortProperty', 'sortOrder', 'page', 'limit']) {
|
||||||
if (key in queryClean) delete queryClean[key];
|
if (key in queryClean) delete queryClean[key];
|
||||||
}
|
}
|
||||||
logger.info('queryExcludingSortAndOrder', queryClean);
|
|
||||||
if (
|
if (
|
||||||
!parse &&
|
!parse &&
|
||||||
queryClean['order._id'] !== undefined &&
|
queryClean['order._id'] !== undefined &&
|
||||||
|
|||||||
25
src/database/schemas/finance/paymentpolicy.schema.js
Normal file
25
src/database/schemas/finance/paymentpolicy.schema.js
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
import mongoose from 'mongoose';
|
||||||
|
import { generateId } from '../../utils.js';
|
||||||
|
import { marketplaceSyncMappingSchema } from '../sales/marketplaceMapping.schema.js';
|
||||||
|
|
||||||
|
const paymentPolicySchema = new mongoose.Schema(
|
||||||
|
{
|
||||||
|
_reference: { type: String, default: () => generateId()() },
|
||||||
|
name: { type: String, required: true },
|
||||||
|
description: { type: String, required: false },
|
||||||
|
immediatePay: { type: Boolean, required: false, default: true },
|
||||||
|
paymentInstructions: { type: String, required: false },
|
||||||
|
marketplaces: { type: [marketplaceSyncMappingSchema()], default: [] },
|
||||||
|
},
|
||||||
|
{ timestamps: true }
|
||||||
|
);
|
||||||
|
|
||||||
|
paymentPolicySchema.index({ name: 'text', description: 'text', paymentInstructions: 'text' });
|
||||||
|
|
||||||
|
paymentPolicySchema.virtual('id').get(function () {
|
||||||
|
return this._id;
|
||||||
|
});
|
||||||
|
|
||||||
|
paymentPolicySchema.set('toJSON', { virtuals: true });
|
||||||
|
|
||||||
|
export const paymentPolicyModel = mongoose.model('paymentPolicy', paymentPolicySchema);
|
||||||
@ -1,16 +1,16 @@
|
|||||||
import mongoose from 'mongoose';
|
import mongoose from 'mongoose';
|
||||||
import { generateId } from '../../utils.js';
|
import { generateId } from '../../utils.js';
|
||||||
const { Schema } = mongoose;
|
|
||||||
import { aggregateRollups, aggregateRollupsHistory, editObject } from '../../database.js';
|
import { aggregateRollups, aggregateRollupsHistory, editObject } from '../../database.js';
|
||||||
|
|
||||||
// Define the main partStock schema
|
// Define the main partStock schema
|
||||||
const partStockSchema = new Schema(
|
const partStockSchema = new mongoose.Schema(
|
||||||
{
|
{
|
||||||
_reference: { type: String, default: () => generateId()() },
|
_reference: { type: String, default: () => generateId()() },
|
||||||
state: {
|
state: {
|
||||||
type: { type: String, required: true },
|
type: { type: String, required: true, default: 'draft' },
|
||||||
progress: { type: Number, required: false },
|
progress: { type: Number, required: false },
|
||||||
},
|
},
|
||||||
|
postedAt: { type: Date, required: false },
|
||||||
part: { type: mongoose.Schema.Types.ObjectId, ref: 'part', required: true },
|
part: { type: mongoose.Schema.Types.ObjectId, ref: 'part', required: true },
|
||||||
partSku: { type: mongoose.Schema.Types.ObjectId, ref: 'partSku', required: true },
|
partSku: { type: mongoose.Schema.Types.ObjectId, ref: 'partSku', required: true },
|
||||||
stockLocation: {
|
stockLocation: {
|
||||||
@ -25,13 +25,11 @@ const partStockSchema = new Schema(
|
|||||||
timestamp: { type: Date, default: Date.now },
|
timestamp: { type: Date, default: Date.now },
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
sourceType: { type: String, required: true },
|
|
||||||
source: { type: Schema.Types.ObjectId, refPath: 'sourceType', required: true },
|
|
||||||
},
|
},
|
||||||
{ timestamps: true }
|
{ timestamps: true }
|
||||||
);
|
);
|
||||||
|
|
||||||
partStockSchema.index({ sourceType: 'text', 'state.type': 'text' });
|
partStockSchema.index({ 'state.type': 'text' });
|
||||||
|
|
||||||
partStockSchema.pre('validate', async function () {
|
partStockSchema.pre('validate', async function () {
|
||||||
if (!this.part && this.partSku) {
|
if (!this.part && this.partSku) {
|
||||||
@ -46,6 +44,11 @@ const rollupConfigs = [
|
|||||||
filter: {},
|
filter: {},
|
||||||
rollups: [{ name: 'totalCurrentQuantity', property: 'currentQuantity', operation: 'sum' }],
|
rollups: [{ name: 'totalCurrentQuantity', property: 'currentQuantity', operation: 'sum' }],
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
name: 'draft',
|
||||||
|
filter: { 'state.type': 'draft' },
|
||||||
|
rollups: [{ name: 'draft', property: 'state.type', operation: 'count' }],
|
||||||
|
},
|
||||||
{
|
{
|
||||||
name: 'new',
|
name: 'new',
|
||||||
filter: { 'state.type': 'new' },
|
filter: { 'state.type': 'new' },
|
||||||
|
|||||||
@ -1,10 +1,20 @@
|
|||||||
import mongoose from 'mongoose';
|
import mongoose from 'mongoose';
|
||||||
import { generateId } from '../../utils.js';
|
import { generateId } from '../../utils.js';
|
||||||
|
const { Schema } = mongoose;
|
||||||
|
|
||||||
|
const marketplaceMappingSchema = new mongoose.Schema(
|
||||||
|
{
|
||||||
|
marketplace: { type: Schema.Types.ObjectId, ref: 'marketplace', required: true },
|
||||||
|
externalReference: { type: String, required: false },
|
||||||
|
},
|
||||||
|
{ _id: true }
|
||||||
|
);
|
||||||
|
|
||||||
const productCategorySchema = new mongoose.Schema(
|
const productCategorySchema = new mongoose.Schema(
|
||||||
{
|
{
|
||||||
_reference: { type: String, default: () => generateId()() },
|
_reference: { type: String, default: () => generateId()() },
|
||||||
name: { required: true, type: String },
|
name: { required: true, type: String },
|
||||||
|
marketplaces: { type: [marketplaceMappingSchema], default: [] },
|
||||||
},
|
},
|
||||||
{ timestamps: true }
|
{ timestamps: true }
|
||||||
);
|
);
|
||||||
|
|||||||
@ -1,5 +1,6 @@
|
|||||||
import mongoose from 'mongoose';
|
import mongoose from 'mongoose';
|
||||||
import { generateId } from '../../utils.js';
|
import { generateId } from '../../utils.js';
|
||||||
|
import { marketplaceSyncMappingSchema } from '../sales/marketplaceMapping.schema.js';
|
||||||
|
|
||||||
const taxRateSchema = new mongoose.Schema(
|
const taxRateSchema = new mongoose.Schema(
|
||||||
{
|
{
|
||||||
@ -10,8 +11,11 @@ const taxRateSchema = new mongoose.Schema(
|
|||||||
active: { required: true, type: Boolean, default: true },
|
active: { required: true, type: Boolean, default: true },
|
||||||
description: { required: false, type: String },
|
description: { required: false, type: String },
|
||||||
country: { required: false, type: String },
|
country: { required: false, type: String },
|
||||||
|
jurisdiction: { required: false, type: String },
|
||||||
|
shippingAndHandlingTaxed: { required: false, type: Boolean, default: false },
|
||||||
effectiveFrom: { required: false, type: Date },
|
effectiveFrom: { required: false, type: Date },
|
||||||
effectiveTo: { required: false, type: Date },
|
effectiveTo: { required: false, type: Date },
|
||||||
|
marketplaces: { type: [marketplaceSyncMappingSchema()], default: [] },
|
||||||
},
|
},
|
||||||
{ timestamps: true }
|
{ timestamps: true }
|
||||||
);
|
);
|
||||||
|
|||||||
@ -50,365 +50,79 @@ import { listingModel } from './sales/listing.schema.js';
|
|||||||
import { listingVarientModel } from './sales/listingvarient.schema.js';
|
import { listingVarientModel } from './sales/listingvarient.schema.js';
|
||||||
import { marketplaceEventModel } from './sales/marketplaceevent.schema.js';
|
import { marketplaceEventModel } from './sales/marketplaceevent.schema.js';
|
||||||
import { paymentModel } from './finance/payment.schema.js';
|
import { paymentModel } from './finance/payment.schema.js';
|
||||||
|
import { paymentPolicyModel } from './finance/paymentpolicy.schema.js';
|
||||||
|
import { fulfillmentPolicyModel } from './sales/fulfillmentpolicy.schema.js';
|
||||||
|
import { returnPolicyModel } from './sales/returnpolicy.schema.js';
|
||||||
|
|
||||||
// Map prefixes to models and id fields
|
function modelEntry(getModel, type, label) {
|
||||||
|
return {
|
||||||
|
get model() {
|
||||||
|
return getModel();
|
||||||
|
},
|
||||||
|
idField: '_id',
|
||||||
|
type,
|
||||||
|
referenceField: '_reference',
|
||||||
|
label,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
// Map prefixes to models and id fields.
|
||||||
|
// Model getters are lazy so circular ESM imports (schema -> utils -> models -> schema)
|
||||||
|
// do not read bindings that are still in the temporal dead zone.
|
||||||
export const models = {
|
export const models = {
|
||||||
PRN: {
|
PRN: modelEntry(() => printerModel, 'printer', 'Printer'),
|
||||||
model: printerModel,
|
PPF: modelEntry(() => printerProfileModel, 'printerProfile', 'Printer Profile'),
|
||||||
idField: '_id',
|
FPF: modelEntry(() => filamentProfileModel, 'filamentProfile', 'Filament Profile'),
|
||||||
type: 'printer',
|
FIL: modelEntry(() => filamentModel, 'filament', 'Filament'),
|
||||||
referenceField: '_reference',
|
FSU: modelEntry(() => filamentSkuModel, 'filamentSku', 'Filament SKU'),
|
||||||
label: 'Printer',
|
GCF: modelEntry(() => gcodeFileModel, 'gcodeFile', 'G-Code File'),
|
||||||
},
|
JOB: modelEntry(() => jobModel, 'job', 'Job'),
|
||||||
PPF: {
|
PRT: modelEntry(() => partModel, 'part', 'Part'),
|
||||||
model: printerProfileModel,
|
PSU: modelEntry(() => partSkuModel, 'partSku', 'Part SKU'),
|
||||||
idField: '_id',
|
PRD: modelEntry(() => productModel, 'product', 'Product'),
|
||||||
type: 'printerProfile',
|
PCG: modelEntry(() => productCategoryModel, 'productCategory', 'Product Category'),
|
||||||
referenceField: '_reference',
|
SKU: modelEntry(() => productSkuModel, 'productSku', 'Product SKU'),
|
||||||
label: 'Printer Profile',
|
VEN: modelEntry(() => vendorModel, 'vendor', 'Vendor'),
|
||||||
},
|
MAT: modelEntry(() => materialModel, 'material', 'Material'),
|
||||||
FPF: {
|
SJB: modelEntry(() => subJobModel, 'subJob', 'Sub Job'),
|
||||||
model: filamentProfileModel,
|
FLS: modelEntry(() => filamentStockModel, 'filamentStock', 'Filament Stock'),
|
||||||
idField: '_id',
|
SEV: modelEntry(() => stockEventModel, 'stockEvent', 'Stock Event'),
|
||||||
type: 'filamentProfile',
|
SAU: modelEntry(() => stockAuditModel, 'stockAudit', 'Stock Audit'),
|
||||||
referenceField: '_reference',
|
PTS: modelEntry(() => partStockModel, 'partStock', 'Part Stock'),
|
||||||
label: 'Filament Profile',
|
PDS: modelEntry(() => productStockModel, 'productStock', 'Product Stock'),
|
||||||
},
|
SLN: modelEntry(() => stockLocationModel, 'stockLocation', 'Stock Location'),
|
||||||
FIL: {
|
STT: modelEntry(() => stockTransferModel, 'stockTransfer', 'Stock Transfer'),
|
||||||
model: filamentModel,
|
ADL: modelEntry(() => auditLogModel, 'auditLog', 'Audit Log'),
|
||||||
idField: '_id',
|
USR: modelEntry(() => userModel, 'user', 'User'),
|
||||||
type: 'filament',
|
UGP: modelEntry(() => userGroupModel, 'userGroup', 'User Group'),
|
||||||
referenceField: '_reference',
|
PMS: modelEntry(() => permissionSettingModel, 'permissionSetting', 'Permission Settings'),
|
||||||
label: 'Filament',
|
APP: modelEntry(() => appPasswordModel, 'appPassword', 'App Password'),
|
||||||
},
|
NTY: modelEntry(() => noteTypeModel, 'noteType', 'Note Type'),
|
||||||
FSU: {
|
NTE: modelEntry(() => noteModel, 'note', 'Note'),
|
||||||
model: filamentSkuModel,
|
NTF: modelEntry(() => notificationModel, 'notification', 'Notification'),
|
||||||
idField: '_id',
|
ONF: modelEntry(() => userNotifierModel, 'userNotifier', 'User Notifier'),
|
||||||
type: 'filamentSku',
|
DSZ: modelEntry(() => documentSizeModel, 'documentSize', 'Document Size'),
|
||||||
referenceField: '_reference',
|
DTP: modelEntry(() => documentTemplateModel, 'documentTemplate', 'Document Template'),
|
||||||
label: 'Filament SKU',
|
DPR: modelEntry(() => documentPrinterModel, 'documentPrinter', 'Document Printer'),
|
||||||
},
|
DJB: modelEntry(() => documentJobModel, 'documentJob', 'Document Job'),
|
||||||
GCF: {
|
HST: modelEntry(() => hostModel, 'host', 'Host'),
|
||||||
model: gcodeFileModel,
|
FLE: modelEntry(() => fileModel, 'file', 'File'),
|
||||||
idField: '_id',
|
POR: modelEntry(() => purchaseOrderModel, 'purchaseOrder', 'Purchase Order'),
|
||||||
type: 'gcodeFile',
|
ODI: modelEntry(() => orderItemModel, 'orderItem', 'Order Item'),
|
||||||
referenceField: '_reference',
|
COS: modelEntry(() => courierServiceModel, 'courierService', 'Courier Service'),
|
||||||
label: 'G-Code File',
|
COR: modelEntry(() => courierModel, 'courier', 'Courier'),
|
||||||
},
|
TXR: modelEntry(() => taxRateModel, 'taxRate', 'Tax Rate'),
|
||||||
JOB: { model: jobModel, idField: '_id', type: 'job', referenceField: '_reference', label: 'Job' },
|
TXD: modelEntry(() => taxRecordModel, 'taxRecord', 'Tax Record'),
|
||||||
PRT: {
|
SHP: modelEntry(() => shipmentModel, 'shipment', 'Shipment'),
|
||||||
model: partModel,
|
INV: modelEntry(() => invoiceModel, 'invoice', 'Invoice'),
|
||||||
idField: '_id',
|
CLI: modelEntry(() => clientModel, 'client', 'Client'),
|
||||||
type: 'part',
|
SOR: modelEntry(() => salesOrderModel, 'salesOrder', 'Sales Order'),
|
||||||
referenceField: '_reference',
|
MKT: modelEntry(() => marketplaceModel, 'marketplace', 'Marketplace'),
|
||||||
label: 'Part',
|
LST: modelEntry(() => listingModel, 'listing', 'Listing'),
|
||||||
},
|
LVR: modelEntry(() => listingVarientModel, 'listingVarient', 'Listing Varient'),
|
||||||
PSU: {
|
MKE: modelEntry(() => marketplaceEventModel, 'marketplaceEvent', 'Marketplace Event'),
|
||||||
model: partSkuModel,
|
PAY: modelEntry(() => paymentModel, 'payment', 'Payment'),
|
||||||
idField: '_id',
|
PPL: modelEntry(() => paymentPolicyModel, 'paymentPolicy', 'Payment Policy'),
|
||||||
type: 'partSku',
|
FPL: modelEntry(() => fulfillmentPolicyModel, 'fulfillmentPolicy', 'Fulfillment Policy'),
|
||||||
referenceField: '_reference',
|
RPL: modelEntry(() => returnPolicyModel, 'returnPolicy', 'Return Policy'),
|
||||||
label: 'Part SKU',
|
|
||||||
},
|
|
||||||
PRD: {
|
|
||||||
model: productModel,
|
|
||||||
idField: '_id',
|
|
||||||
type: 'product',
|
|
||||||
referenceField: '_reference',
|
|
||||||
label: 'Product',
|
|
||||||
},
|
|
||||||
PCG: {
|
|
||||||
model: productCategoryModel,
|
|
||||||
idField: '_id',
|
|
||||||
type: 'productCategory',
|
|
||||||
referenceField: '_reference',
|
|
||||||
label: 'Product Category',
|
|
||||||
},
|
|
||||||
SKU: {
|
|
||||||
model: productSkuModel,
|
|
||||||
idField: '_id',
|
|
||||||
type: 'productSku',
|
|
||||||
referenceField: '_reference',
|
|
||||||
label: 'Product SKU',
|
|
||||||
},
|
|
||||||
VEN: {
|
|
||||||
model: vendorModel,
|
|
||||||
idField: '_id',
|
|
||||||
type: 'vendor',
|
|
||||||
referenceField: '_reference',
|
|
||||||
label: 'Vendor',
|
|
||||||
},
|
|
||||||
MAT: {
|
|
||||||
model: materialModel,
|
|
||||||
idField: '_id',
|
|
||||||
type: 'material',
|
|
||||||
referenceField: '_reference',
|
|
||||||
label: 'Material',
|
|
||||||
},
|
|
||||||
SJB: {
|
|
||||||
model: subJobModel,
|
|
||||||
idField: '_id',
|
|
||||||
type: 'subJob',
|
|
||||||
referenceField: '_reference',
|
|
||||||
label: 'Sub Job',
|
|
||||||
},
|
|
||||||
FLS: {
|
|
||||||
model: filamentStockModel,
|
|
||||||
idField: '_id',
|
|
||||||
type: 'filamentStock',
|
|
||||||
referenceField: '_reference',
|
|
||||||
label: 'Filament Stock',
|
|
||||||
},
|
|
||||||
SEV: {
|
|
||||||
model: stockEventModel,
|
|
||||||
idField: '_id',
|
|
||||||
type: 'stockEvent',
|
|
||||||
referenceField: '_reference',
|
|
||||||
label: 'Stock Event',
|
|
||||||
},
|
|
||||||
SAU: {
|
|
||||||
model: stockAuditModel,
|
|
||||||
idField: '_id',
|
|
||||||
type: 'stockAudit',
|
|
||||||
referenceField: '_reference',
|
|
||||||
label: 'Stock Audit',
|
|
||||||
},
|
|
||||||
PTS: {
|
|
||||||
model: partStockModel,
|
|
||||||
idField: '_id',
|
|
||||||
type: 'partStock',
|
|
||||||
referenceField: '_reference',
|
|
||||||
label: 'Part Stock',
|
|
||||||
},
|
|
||||||
PDS: {
|
|
||||||
model: productStockModel,
|
|
||||||
idField: '_id',
|
|
||||||
type: 'productStock',
|
|
||||||
referenceField: '_reference',
|
|
||||||
label: 'Product Stock',
|
|
||||||
},
|
|
||||||
SLN: {
|
|
||||||
model: stockLocationModel,
|
|
||||||
idField: '_id',
|
|
||||||
type: 'stockLocation',
|
|
||||||
referenceField: '_reference',
|
|
||||||
label: 'Stock Location',
|
|
||||||
},
|
|
||||||
STT: {
|
|
||||||
model: stockTransferModel,
|
|
||||||
idField: '_id',
|
|
||||||
type: 'stockTransfer',
|
|
||||||
referenceField: '_reference',
|
|
||||||
label: 'Stock Transfer',
|
|
||||||
},
|
|
||||||
ADL: {
|
|
||||||
model: auditLogModel,
|
|
||||||
idField: '_id',
|
|
||||||
type: 'auditLog',
|
|
||||||
referenceField: '_reference',
|
|
||||||
label: 'Audit Log',
|
|
||||||
},
|
|
||||||
USR: {
|
|
||||||
model: userModel,
|
|
||||||
idField: '_id',
|
|
||||||
type: 'user',
|
|
||||||
referenceField: '_reference',
|
|
||||||
label: 'User',
|
|
||||||
},
|
|
||||||
UGP: {
|
|
||||||
model: userGroupModel,
|
|
||||||
idField: '_id',
|
|
||||||
type: 'userGroup',
|
|
||||||
referenceField: '_reference',
|
|
||||||
label: 'User Group',
|
|
||||||
},
|
|
||||||
PMS: {
|
|
||||||
model: permissionSettingModel,
|
|
||||||
idField: '_id',
|
|
||||||
type: 'permissionSetting',
|
|
||||||
referenceField: '_reference',
|
|
||||||
label: 'Permission Settings',
|
|
||||||
},
|
|
||||||
APP: {
|
|
||||||
model: appPasswordModel,
|
|
||||||
idField: '_id',
|
|
||||||
type: 'appPassword',
|
|
||||||
referenceField: '_reference',
|
|
||||||
label: 'App Password',
|
|
||||||
},
|
|
||||||
NTY: {
|
|
||||||
model: noteTypeModel,
|
|
||||||
idField: '_id',
|
|
||||||
type: 'noteType',
|
|
||||||
referenceField: '_reference',
|
|
||||||
label: 'Note Type',
|
|
||||||
},
|
|
||||||
NTE: {
|
|
||||||
model: noteModel,
|
|
||||||
idField: '_id',
|
|
||||||
type: 'note',
|
|
||||||
referenceField: '_reference',
|
|
||||||
label: 'Note',
|
|
||||||
},
|
|
||||||
NTF: {
|
|
||||||
model: notificationModel,
|
|
||||||
idField: '_id',
|
|
||||||
type: 'notification',
|
|
||||||
label: 'Notification',
|
|
||||||
referenceField: '_reference',
|
|
||||||
},
|
|
||||||
ONF: {
|
|
||||||
model: userNotifierModel,
|
|
||||||
idField: '_id',
|
|
||||||
type: 'userNotifier',
|
|
||||||
label: 'User Notifier',
|
|
||||||
referenceField: '_reference',
|
|
||||||
},
|
|
||||||
DSZ: {
|
|
||||||
model: documentSizeModel,
|
|
||||||
idField: '_id',
|
|
||||||
type: 'documentSize',
|
|
||||||
label: 'Document Size',
|
|
||||||
referenceField: '_reference',
|
|
||||||
},
|
|
||||||
DTP: {
|
|
||||||
model: documentTemplateModel,
|
|
||||||
idField: '_id',
|
|
||||||
type: 'documentTemplate',
|
|
||||||
label: 'Document Template',
|
|
||||||
referenceField: '_reference',
|
|
||||||
},
|
|
||||||
DPR: {
|
|
||||||
model: documentPrinterModel,
|
|
||||||
idField: '_id',
|
|
||||||
type: 'documentPrinter',
|
|
||||||
label: 'Document Printer',
|
|
||||||
referenceField: '_reference',
|
|
||||||
},
|
|
||||||
DJB: {
|
|
||||||
model: documentJobModel,
|
|
||||||
idField: '_id',
|
|
||||||
type: 'documentJob',
|
|
||||||
label: 'Document Job',
|
|
||||||
referenceField: '_reference',
|
|
||||||
},
|
|
||||||
HST: {
|
|
||||||
model: hostModel,
|
|
||||||
idField: '_id',
|
|
||||||
type: 'host',
|
|
||||||
referenceField: '_reference',
|
|
||||||
label: 'Host',
|
|
||||||
},
|
|
||||||
FLE: {
|
|
||||||
model: fileModel,
|
|
||||||
idField: '_id',
|
|
||||||
type: 'file',
|
|
||||||
referenceField: '_reference',
|
|
||||||
label: 'File',
|
|
||||||
},
|
|
||||||
POR: {
|
|
||||||
model: purchaseOrderModel,
|
|
||||||
idField: '_id',
|
|
||||||
type: 'purchaseOrder',
|
|
||||||
label: 'Purchase Order',
|
|
||||||
referenceField: '_reference',
|
|
||||||
},
|
|
||||||
ODI: {
|
|
||||||
model: orderItemModel,
|
|
||||||
idField: '_id',
|
|
||||||
type: 'orderItem',
|
|
||||||
label: 'Order Item',
|
|
||||||
referenceField: '_reference',
|
|
||||||
},
|
|
||||||
COS: {
|
|
||||||
model: courierServiceModel,
|
|
||||||
idField: '_id',
|
|
||||||
type: 'courierService',
|
|
||||||
label: 'Courier Service',
|
|
||||||
referenceField: '_reference',
|
|
||||||
},
|
|
||||||
COR: {
|
|
||||||
model: courierModel,
|
|
||||||
idField: '_id',
|
|
||||||
type: 'courier',
|
|
||||||
label: 'Courier',
|
|
||||||
referenceField: '_reference',
|
|
||||||
},
|
|
||||||
TXR: {
|
|
||||||
model: taxRateModel,
|
|
||||||
idField: '_id',
|
|
||||||
type: 'taxRate',
|
|
||||||
label: 'Tax Rate',
|
|
||||||
referenceField: '_reference',
|
|
||||||
},
|
|
||||||
TXD: {
|
|
||||||
model: taxRecordModel,
|
|
||||||
idField: '_id',
|
|
||||||
type: 'taxRecord',
|
|
||||||
label: 'Tax Record',
|
|
||||||
referenceField: '_reference',
|
|
||||||
},
|
|
||||||
SHP: {
|
|
||||||
model: shipmentModel,
|
|
||||||
idField: '_id',
|
|
||||||
type: 'shipment',
|
|
||||||
label: 'Shipment',
|
|
||||||
referenceField: '_reference',
|
|
||||||
},
|
|
||||||
INV: {
|
|
||||||
model: invoiceModel,
|
|
||||||
idField: '_id',
|
|
||||||
type: 'invoice',
|
|
||||||
label: 'Invoice',
|
|
||||||
referenceField: '_reference',
|
|
||||||
},
|
|
||||||
CLI: {
|
|
||||||
model: clientModel,
|
|
||||||
idField: '_id',
|
|
||||||
type: 'client',
|
|
||||||
label: 'Client',
|
|
||||||
referenceField: '_reference',
|
|
||||||
},
|
|
||||||
SOR: {
|
|
||||||
model: salesOrderModel,
|
|
||||||
idField: '_id',
|
|
||||||
type: 'salesOrder',
|
|
||||||
label: 'Sales Order',
|
|
||||||
referenceField: '_reference',
|
|
||||||
},
|
|
||||||
MKT: {
|
|
||||||
model: marketplaceModel,
|
|
||||||
idField: '_id',
|
|
||||||
type: 'marketplace',
|
|
||||||
label: 'Marketplace',
|
|
||||||
referenceField: '_reference',
|
|
||||||
},
|
|
||||||
LST: {
|
|
||||||
model: listingModel,
|
|
||||||
idField: '_id',
|
|
||||||
type: 'listing',
|
|
||||||
label: 'Listing',
|
|
||||||
referenceField: '_reference',
|
|
||||||
},
|
|
||||||
LVR: {
|
|
||||||
model: listingVarientModel,
|
|
||||||
idField: '_id',
|
|
||||||
type: 'listingVarient',
|
|
||||||
label: 'Listing Varient',
|
|
||||||
referenceField: '_reference',
|
|
||||||
},
|
|
||||||
MKE: {
|
|
||||||
model: marketplaceEventModel,
|
|
||||||
idField: '_id',
|
|
||||||
type: 'marketplaceEvent',
|
|
||||||
label: 'Marketplace Event',
|
|
||||||
referenceField: '_reference',
|
|
||||||
},
|
|
||||||
PAY: {
|
|
||||||
model: paymentModel,
|
|
||||||
idField: '_id',
|
|
||||||
type: 'payment',
|
|
||||||
label: 'Payment',
|
|
||||||
referenceField: '_reference',
|
|
||||||
},
|
|
||||||
};
|
};
|
||||||
|
|||||||
31
src/database/schemas/sales/fulfillmentpolicy.schema.js
Normal file
31
src/database/schemas/sales/fulfillmentpolicy.schema.js
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
import mongoose from 'mongoose';
|
||||||
|
import { generateId } from '../../utils.js';
|
||||||
|
import { marketplaceSyncMappingSchema } from './marketplaceMapping.schema.js';
|
||||||
|
|
||||||
|
const { Schema } = mongoose;
|
||||||
|
|
||||||
|
const fulfillmentPolicySchema = new Schema(
|
||||||
|
{
|
||||||
|
_reference: { type: String, default: () => generateId()() },
|
||||||
|
name: { type: String, required: true },
|
||||||
|
description: { type: String, required: false },
|
||||||
|
handlingTime: { type: Number, required: false, default: 1 },
|
||||||
|
localPickup: { type: Boolean, required: false, default: false },
|
||||||
|
globalShipping: { type: Boolean, required: false, default: false },
|
||||||
|
freightShipping: { type: Boolean, required: false, default: false },
|
||||||
|
pickupDropOff: { type: Boolean, required: false, default: false },
|
||||||
|
courierServices: [{ type: Schema.Types.ObjectId, ref: 'courierService', required: false }],
|
||||||
|
marketplaces: { type: [marketplaceSyncMappingSchema()], default: [] },
|
||||||
|
},
|
||||||
|
{ timestamps: true }
|
||||||
|
);
|
||||||
|
|
||||||
|
fulfillmentPolicySchema.index({ name: 'text', description: 'text' });
|
||||||
|
|
||||||
|
fulfillmentPolicySchema.virtual('id').get(function () {
|
||||||
|
return this._id;
|
||||||
|
});
|
||||||
|
|
||||||
|
fulfillmentPolicySchema.set('toJSON', { virtuals: true });
|
||||||
|
|
||||||
|
export const fulfillmentPolicyModel = mongoose.model('fulfillmentPolicy', fulfillmentPolicySchema);
|
||||||
@ -1,6 +1,12 @@
|
|||||||
import mongoose from 'mongoose';
|
import mongoose from 'mongoose';
|
||||||
import { generateId } from '../../utils.js';
|
import { generateId } from '../../utils.js';
|
||||||
import { editObject, newObject, deleteObject, aggregateRollups, aggregateRollupsHistory } from '../../database.js';
|
import {
|
||||||
|
editObject,
|
||||||
|
newObject,
|
||||||
|
deleteObject,
|
||||||
|
aggregateRollups,
|
||||||
|
aggregateRollupsHistory,
|
||||||
|
} from '../../database.js';
|
||||||
const { Schema } = mongoose;
|
const { Schema } = mongoose;
|
||||||
|
|
||||||
const listingSchema = new Schema(
|
const listingSchema = new Schema(
|
||||||
@ -14,13 +20,24 @@ const listingSchema = new Schema(
|
|||||||
state: {
|
state: {
|
||||||
type: {
|
type: {
|
||||||
type: String,
|
type: String,
|
||||||
enum: ['draft', 'active', 'inactive', 'deleted', 'suspended', 'syncing'],
|
enum: [
|
||||||
|
'draft',
|
||||||
|
'active',
|
||||||
|
'inactive',
|
||||||
|
'deleted',
|
||||||
|
'suspended',
|
||||||
|
'syncing',
|
||||||
|
'publishing',
|
||||||
|
'unpublishing',
|
||||||
|
],
|
||||||
default: 'draft',
|
default: 'draft',
|
||||||
},
|
},
|
||||||
|
progress: { type: Number, required: false },
|
||||||
message: { type: String, required: false },
|
message: { type: String, required: false },
|
||||||
},
|
},
|
||||||
url: { type: String, required: false },
|
url: { type: String, required: false },
|
||||||
description: { type: String, required: false },
|
description: { type: String, required: false },
|
||||||
|
listingImages: [{ type: Schema.Types.ObjectId, ref: 'file', required: false }],
|
||||||
externalReference: { type: String, required: false },
|
externalReference: { type: String, required: false },
|
||||||
price: { type: Number, required: false },
|
price: { type: Number, required: false },
|
||||||
currency: { type: String, required: false },
|
currency: { type: String, required: false },
|
||||||
@ -51,6 +68,9 @@ const listingSchema = new Schema(
|
|||||||
required: false,
|
required: false,
|
||||||
},
|
},
|
||||||
courierServices: [{ type: Schema.Types.ObjectId, ref: 'courierService', required: true }],
|
courierServices: [{ type: Schema.Types.ObjectId, ref: 'courierService', required: true }],
|
||||||
|
fulfillmentPolicy: { type: Schema.Types.ObjectId, ref: 'fulfillmentPolicy', required: false },
|
||||||
|
paymentPolicy: { type: Schema.Types.ObjectId, ref: 'paymentPolicy', required: false },
|
||||||
|
returnPolicy: { type: Schema.Types.ObjectId, ref: 'returnPolicy', required: false },
|
||||||
},
|
},
|
||||||
{ timestamps: true }
|
{ timestamps: true }
|
||||||
);
|
);
|
||||||
@ -192,6 +212,16 @@ const rollupConfigs = [
|
|||||||
filter: { 'state.type': 'syncing' },
|
filter: { 'state.type': 'syncing' },
|
||||||
rollups: [{ name: 'syncing', property: 'state.type', operation: 'count' }],
|
rollups: [{ name: 'syncing', property: 'state.type', operation: 'count' }],
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
name: 'publishing',
|
||||||
|
filter: { 'state.type': 'publishing' },
|
||||||
|
rollups: [{ name: 'publishing', property: 'state.type', operation: 'count' }],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'unpublishing',
|
||||||
|
filter: { 'state.type': 'unpublishing' },
|
||||||
|
rollups: [{ name: 'unpublishing', property: 'state.type', operation: 'count' }],
|
||||||
|
},
|
||||||
{
|
{
|
||||||
name: 'suspended',
|
name: 'suspended',
|
||||||
filter: { 'state.type': 'suspended' },
|
filter: { 'state.type': 'suspended' },
|
||||||
|
|||||||
@ -9,16 +9,34 @@ const toId = (value) => {
|
|||||||
return String(value);
|
return String(value);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const listingVarientAspectSchema = new Schema(
|
||||||
|
{
|
||||||
|
name: { type: String, required: true },
|
||||||
|
value: { type: String, required: true },
|
||||||
|
},
|
||||||
|
{ _id: true }
|
||||||
|
);
|
||||||
|
|
||||||
const listingVarientSchema = new Schema(
|
const listingVarientSchema = new Schema(
|
||||||
{
|
{
|
||||||
_reference: { type: String, default: () => generateId()() },
|
_reference: { type: String, default: () => generateId()() },
|
||||||
listing: { type: Schema.Types.ObjectId, ref: 'listing', required: true },
|
listing: { type: Schema.Types.ObjectId, ref: 'listing', required: true },
|
||||||
product: { type: Schema.Types.ObjectId, ref: 'product', required: false },
|
product: { type: Schema.Types.ObjectId, ref: 'product', required: false },
|
||||||
productSku: { type: Schema.Types.ObjectId, ref: 'productSku', required: false },
|
productSku: { type: Schema.Types.ObjectId, ref: 'productSku', required: false },
|
||||||
|
aspects: { type: [listingVarientAspectSchema], default: [] },
|
||||||
state: {
|
state: {
|
||||||
type: {
|
type: {
|
||||||
type: String,
|
type: String,
|
||||||
enum: ['draft', 'active', 'inactive', 'deleted', 'suspended', 'syncing'],
|
enum: [
|
||||||
|
'draft',
|
||||||
|
'active',
|
||||||
|
'inactive',
|
||||||
|
'deleted',
|
||||||
|
'suspended',
|
||||||
|
'syncing',
|
||||||
|
'publishing',
|
||||||
|
'unpublishing',
|
||||||
|
],
|
||||||
default: 'draft',
|
default: 'draft',
|
||||||
},
|
},
|
||||||
message: { type: String, required: false },
|
message: { type: String, required: false },
|
||||||
@ -29,6 +47,7 @@ const listingVarientSchema = new Schema(
|
|||||||
priceTaxRate: { type: Schema.Types.ObjectId, ref: 'taxRate', required: false },
|
priceTaxRate: { type: Schema.Types.ObjectId, ref: 'taxRate', required: false },
|
||||||
priceWithTax: { type: Number, required: false },
|
priceWithTax: { type: Number, required: false },
|
||||||
lastSyncedAt: { type: Date, required: false },
|
lastSyncedAt: { type: Date, required: false },
|
||||||
|
listingImages: [{ type: Schema.Types.ObjectId, ref: 'file', required: false }],
|
||||||
stockQuantity: { type: Number, required: false, default: 0 },
|
stockQuantity: { type: Number, required: false, default: 0 },
|
||||||
},
|
},
|
||||||
{ timestamps: true }
|
{ timestamps: true }
|
||||||
|
|||||||
@ -24,8 +24,24 @@ const marketplaceSchema = new mongoose.Schema(
|
|||||||
},
|
},
|
||||||
// Provider-specific API configuration (flexible for eBay, Etsy, TikTok Shop)
|
// Provider-specific API configuration (flexible for eBay, Etsy, TikTok Shop)
|
||||||
config: { type: mongoose.Schema.Types.Mixed, default: {} },
|
config: { type: mongoose.Schema.Types.Mixed, default: {} },
|
||||||
|
defaultFulfillmentPolicy: {
|
||||||
|
type: mongoose.Schema.Types.ObjectId,
|
||||||
|
ref: 'fulfillmentPolicy',
|
||||||
|
required: false,
|
||||||
|
},
|
||||||
|
defaultPaymentPolicy: {
|
||||||
|
type: mongoose.Schema.Types.ObjectId,
|
||||||
|
ref: 'paymentPolicy',
|
||||||
|
required: false,
|
||||||
|
},
|
||||||
|
defaultReturnPolicy: {
|
||||||
|
type: mongoose.Schema.Types.ObjectId,
|
||||||
|
ref: 'returnPolicy',
|
||||||
|
required: false,
|
||||||
|
},
|
||||||
eBay: {
|
eBay: {
|
||||||
availableShippingServices: { type: [String], default: [] },
|
availableShippingServices: { type: [String], default: [] },
|
||||||
|
categoryReferences: { type: [mongoose.Schema.Types.Mixed], default: [] },
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{ timestamps: true }
|
{ timestamps: true }
|
||||||
|
|||||||
23
src/database/schemas/sales/marketplaceMapping.schema.js
Normal file
23
src/database/schemas/sales/marketplaceMapping.schema.js
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
import mongoose from 'mongoose';
|
||||||
|
|
||||||
|
const { Schema } = mongoose;
|
||||||
|
|
||||||
|
export const MARKETPLACE_MAPPING_STATES = ['pending', 'syncing', 'ready', 'failed'];
|
||||||
|
|
||||||
|
export function marketplaceSyncMappingSchema() {
|
||||||
|
return new Schema(
|
||||||
|
{
|
||||||
|
marketplace: { type: Schema.Types.ObjectId, ref: 'marketplace', required: true },
|
||||||
|
externalReference: { type: String, required: false },
|
||||||
|
state: {
|
||||||
|
type: {
|
||||||
|
type: String,
|
||||||
|
enum: MARKETPLACE_MAPPING_STATES,
|
||||||
|
default: 'pending',
|
||||||
|
},
|
||||||
|
message: { type: String, required: false },
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{ _id: true }
|
||||||
|
);
|
||||||
|
}
|
||||||
46
src/database/schemas/sales/returnpolicy.schema.js
Normal file
46
src/database/schemas/sales/returnpolicy.schema.js
Normal file
@ -0,0 +1,46 @@
|
|||||||
|
import mongoose from 'mongoose';
|
||||||
|
import { generateId } from '../../utils.js';
|
||||||
|
import { marketplaceSyncMappingSchema } from './marketplaceMapping.schema.js';
|
||||||
|
|
||||||
|
const returnPolicySchema = new mongoose.Schema(
|
||||||
|
{
|
||||||
|
_reference: { type: String, default: () => generateId()() },
|
||||||
|
name: { type: String, required: true },
|
||||||
|
description: { type: String, required: false },
|
||||||
|
returnsAccepted: { type: Boolean, required: true, default: true },
|
||||||
|
returnPeriodDays: { type: Number, required: false, default: 30 },
|
||||||
|
returnShippingCostPayer: {
|
||||||
|
type: String,
|
||||||
|
enum: ['buyer', 'seller'],
|
||||||
|
required: false,
|
||||||
|
default: 'buyer',
|
||||||
|
},
|
||||||
|
refundMethod: {
|
||||||
|
type: String,
|
||||||
|
enum: ['moneyBack', 'merchandiseCredit'],
|
||||||
|
required: false,
|
||||||
|
default: 'moneyBack',
|
||||||
|
},
|
||||||
|
restockingFeePercentage: { type: Number, required: false },
|
||||||
|
returnInstructions: { type: String, required: false },
|
||||||
|
internationalReturnsAccepted: { type: Boolean, required: false },
|
||||||
|
internationalReturnPeriodDays: { type: Number, required: false },
|
||||||
|
internationalReturnShippingCostPayer: {
|
||||||
|
type: String,
|
||||||
|
enum: ['buyer', 'seller'],
|
||||||
|
required: false,
|
||||||
|
},
|
||||||
|
marketplaces: { type: [marketplaceSyncMappingSchema()], default: [] },
|
||||||
|
},
|
||||||
|
{ timestamps: true }
|
||||||
|
);
|
||||||
|
|
||||||
|
returnPolicySchema.index({ name: 'text', description: 'text', returnInstructions: 'text' });
|
||||||
|
|
||||||
|
returnPolicySchema.virtual('id').get(function () {
|
||||||
|
return this._id;
|
||||||
|
});
|
||||||
|
|
||||||
|
returnPolicySchema.set('toJSON', { virtuals: true });
|
||||||
|
|
||||||
|
export const returnPolicyModel = mongoose.model('returnPolicy', returnPolicySchema);
|
||||||
Loading…
x
Reference in New Issue
Block a user