tango-api-schema 2.6.48 → 2.6.49
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/index.js +268 -268
- package/package.json +1 -1
- package/schema/bankTransaction.model.js +94 -94
- package/schema/billing.model.js +135 -135
- package/schema/client.model.js +4 -0
- package/schema/estimate.model.js +89 -89
- package/schema/invoice.model.js +156 -156
- package/schema/paymentAccount.model.js +60 -60
- package/schema/paymentReminder.model.js +46 -46
- package/schema/purchaseOrder.model.js +59 -59
- package/schema/regionKey.model.js +31 -31
- package/schema/transaction.model.js +54 -54
package/schema/invoice.model.js
CHANGED
|
@@ -1,157 +1,157 @@
|
|
|
1
|
-
import mongoose from 'mongoose';
|
|
2
|
-
|
|
3
|
-
const invoiceSchema = new mongoose.Schema(
|
|
4
|
-
{
|
|
5
|
-
clientId: {
|
|
6
|
-
type:String
|
|
7
|
-
},
|
|
8
|
-
invoice: {
|
|
9
|
-
type:String,
|
|
10
|
-
},
|
|
11
|
-
invoiceIndex: {
|
|
12
|
-
type:String,
|
|
13
|
-
},
|
|
14
|
-
stores: {
|
|
15
|
-
type:Number
|
|
16
|
-
},
|
|
17
|
-
// For TINV (advance quarterly/half-yearly/yearly) invoices: the actual
|
|
18
|
-
// list of stores covered, captured at generation time, with each store's
|
|
19
|
-
// products and their working days.
|
|
20
|
-
storeDetails: [
|
|
21
|
-
{
|
|
22
|
-
storeId: { type: String },
|
|
23
|
-
storeName: { type: String },
|
|
24
|
-
products: [
|
|
25
|
-
{
|
|
26
|
-
productName: { type: String },
|
|
27
|
-
workingdays: { type: Number },
|
|
28
|
-
},
|
|
29
|
-
],
|
|
30
|
-
},
|
|
31
|
-
],
|
|
32
|
-
companyName:{
|
|
33
|
-
type:String,
|
|
34
|
-
},
|
|
35
|
-
monthOfbilling:{
|
|
36
|
-
type:String,
|
|
37
|
-
},
|
|
38
|
-
companyAddress:{
|
|
39
|
-
type:String,
|
|
40
|
-
},
|
|
41
|
-
PlaceOfSupply: {
|
|
42
|
-
type:String,
|
|
43
|
-
},
|
|
44
|
-
GSTNumber: {
|
|
45
|
-
type:String,
|
|
46
|
-
},
|
|
47
|
-
products:{
|
|
48
|
-
type:Array
|
|
49
|
-
},
|
|
50
|
-
tax:{
|
|
51
|
-
type:Array
|
|
52
|
-
},
|
|
53
|
-
amount:{
|
|
54
|
-
type:Number
|
|
55
|
-
},
|
|
56
|
-
totalAmount:{
|
|
57
|
-
type:Number
|
|
58
|
-
},
|
|
59
|
-
paymentMethod:{
|
|
60
|
-
type:String
|
|
61
|
-
},
|
|
62
|
-
status:{
|
|
63
|
-
type:String,
|
|
64
|
-
default:'pendingCsm',
|
|
65
|
-
enum:['pendingCsm','pendingFinance','pendingApproval','approved']
|
|
66
|
-
},
|
|
67
|
-
receivedAmount:{
|
|
68
|
-
type:Number
|
|
69
|
-
},
|
|
70
|
-
billingDate:{
|
|
71
|
-
type:Date
|
|
72
|
-
},
|
|
73
|
-
dueDate:{
|
|
74
|
-
type:Date
|
|
75
|
-
},
|
|
76
|
-
paymentTerm:{
|
|
77
|
-
type:Number
|
|
78
|
-
},
|
|
79
|
-
paidDate:{
|
|
80
|
-
type:Date
|
|
81
|
-
},
|
|
82
|
-
paymentType: {
|
|
83
|
-
type:String,
|
|
84
|
-
enum: ['online','banktransfer']
|
|
85
|
-
},
|
|
86
|
-
paymentReferenceId: {
|
|
87
|
-
type:String
|
|
88
|
-
},
|
|
89
|
-
fromDate:{
|
|
90
|
-
type:Date
|
|
91
|
-
},
|
|
92
|
-
toDate:{
|
|
93
|
-
type:Date
|
|
94
|
-
},
|
|
95
|
-
currency: {
|
|
96
|
-
type:String
|
|
97
|
-
},
|
|
98
|
-
orderId: {
|
|
99
|
-
type:String
|
|
100
|
-
},
|
|
101
|
-
groupName: {
|
|
102
|
-
type:String
|
|
103
|
-
},
|
|
104
|
-
groupId: {
|
|
105
|
-
type:String
|
|
106
|
-
},
|
|
107
|
-
// Purchase order this invoice is mapped to (reduces the PO's remaining
|
|
108
|
-
// balance). Empty when the invoice isn't tied to a PO.
|
|
109
|
-
purchaseOrderNumber: {
|
|
110
|
-
type:String
|
|
111
|
-
},
|
|
112
|
-
discountAmount: {
|
|
113
|
-
type:Number
|
|
114
|
-
},
|
|
115
|
-
discountPercentage: {
|
|
116
|
-
type:Number
|
|
117
|
-
},
|
|
118
|
-
paymentStatus:{
|
|
119
|
-
type:String,
|
|
120
|
-
default:'unpaid',
|
|
121
|
-
// 'partial' = paidAmount > 0 && paidAmount < totalAmount.
|
|
122
|
-
// Server derives this in recordPayment so the value stays in sync.
|
|
123
|
-
enum: ['paid','unpaid','partial']
|
|
124
|
-
},
|
|
125
|
-
// Running total of all payments recorded against this invoice. Sum of
|
|
126
|
-
// paymentHistory[].amount; persisted for easy querying / display so
|
|
127
|
-
// the frontend doesn't need to re-sum every render.
|
|
128
|
-
paidAmount:{
|
|
129
|
-
type:Number,
|
|
130
|
-
default:0
|
|
131
|
-
},
|
|
132
|
-
// Append-only audit trail. Each entry is one payment received from
|
|
133
|
-
// the client. recordedAt is server-set; the rest comes from the form.
|
|
134
|
-
paymentHistory:[{
|
|
135
|
-
amount:{type:Number, required:true},
|
|
136
|
-
date:{type:Date, required:true},
|
|
137
|
-
method:{type:String, enum:['banktransfer','upi','cheque','card','cash','other']},
|
|
138
|
-
reference:{type:String},
|
|
139
|
-
notes:{type:String},
|
|
140
|
-
recordedBy:{type:String},
|
|
141
|
-
recordedAt:{type:Date, default:Date.now}
|
|
142
|
-
}],
|
|
143
|
-
advanceInvoice:{
|
|
144
|
-
type:Boolean,
|
|
145
|
-
default:false
|
|
146
|
-
},
|
|
147
|
-
tempIndex:{ type:Number },
|
|
148
|
-
advancePeriod:{ type:String },
|
|
149
|
-
advanceMonths:{ type:Number },
|
|
150
|
-
},{
|
|
151
|
-
strict: true,
|
|
152
|
-
versionKey: false,
|
|
153
|
-
timestamps: true,
|
|
154
|
-
}
|
|
155
|
-
)
|
|
156
|
-
|
|
1
|
+
import mongoose from 'mongoose';
|
|
2
|
+
|
|
3
|
+
const invoiceSchema = new mongoose.Schema(
|
|
4
|
+
{
|
|
5
|
+
clientId: {
|
|
6
|
+
type:String
|
|
7
|
+
},
|
|
8
|
+
invoice: {
|
|
9
|
+
type:String,
|
|
10
|
+
},
|
|
11
|
+
invoiceIndex: {
|
|
12
|
+
type:String,
|
|
13
|
+
},
|
|
14
|
+
stores: {
|
|
15
|
+
type:Number
|
|
16
|
+
},
|
|
17
|
+
// For TINV (advance quarterly/half-yearly/yearly) invoices: the actual
|
|
18
|
+
// list of stores covered, captured at generation time, with each store's
|
|
19
|
+
// products and their working days.
|
|
20
|
+
storeDetails: [
|
|
21
|
+
{
|
|
22
|
+
storeId: { type: String },
|
|
23
|
+
storeName: { type: String },
|
|
24
|
+
products: [
|
|
25
|
+
{
|
|
26
|
+
productName: { type: String },
|
|
27
|
+
workingdays: { type: Number },
|
|
28
|
+
},
|
|
29
|
+
],
|
|
30
|
+
},
|
|
31
|
+
],
|
|
32
|
+
companyName:{
|
|
33
|
+
type:String,
|
|
34
|
+
},
|
|
35
|
+
monthOfbilling:{
|
|
36
|
+
type:String,
|
|
37
|
+
},
|
|
38
|
+
companyAddress:{
|
|
39
|
+
type:String,
|
|
40
|
+
},
|
|
41
|
+
PlaceOfSupply: {
|
|
42
|
+
type:String,
|
|
43
|
+
},
|
|
44
|
+
GSTNumber: {
|
|
45
|
+
type:String,
|
|
46
|
+
},
|
|
47
|
+
products:{
|
|
48
|
+
type:Array
|
|
49
|
+
},
|
|
50
|
+
tax:{
|
|
51
|
+
type:Array
|
|
52
|
+
},
|
|
53
|
+
amount:{
|
|
54
|
+
type:Number
|
|
55
|
+
},
|
|
56
|
+
totalAmount:{
|
|
57
|
+
type:Number
|
|
58
|
+
},
|
|
59
|
+
paymentMethod:{
|
|
60
|
+
type:String
|
|
61
|
+
},
|
|
62
|
+
status:{
|
|
63
|
+
type:String,
|
|
64
|
+
default:'pendingCsm',
|
|
65
|
+
enum:['pendingCsm','pendingFinance','pendingApproval','approved']
|
|
66
|
+
},
|
|
67
|
+
receivedAmount:{
|
|
68
|
+
type:Number
|
|
69
|
+
},
|
|
70
|
+
billingDate:{
|
|
71
|
+
type:Date
|
|
72
|
+
},
|
|
73
|
+
dueDate:{
|
|
74
|
+
type:Date
|
|
75
|
+
},
|
|
76
|
+
paymentTerm:{
|
|
77
|
+
type:Number
|
|
78
|
+
},
|
|
79
|
+
paidDate:{
|
|
80
|
+
type:Date
|
|
81
|
+
},
|
|
82
|
+
paymentType: {
|
|
83
|
+
type:String,
|
|
84
|
+
enum: ['online','banktransfer']
|
|
85
|
+
},
|
|
86
|
+
paymentReferenceId: {
|
|
87
|
+
type:String
|
|
88
|
+
},
|
|
89
|
+
fromDate:{
|
|
90
|
+
type:Date
|
|
91
|
+
},
|
|
92
|
+
toDate:{
|
|
93
|
+
type:Date
|
|
94
|
+
},
|
|
95
|
+
currency: {
|
|
96
|
+
type:String
|
|
97
|
+
},
|
|
98
|
+
orderId: {
|
|
99
|
+
type:String
|
|
100
|
+
},
|
|
101
|
+
groupName: {
|
|
102
|
+
type:String
|
|
103
|
+
},
|
|
104
|
+
groupId: {
|
|
105
|
+
type:String
|
|
106
|
+
},
|
|
107
|
+
// Purchase order this invoice is mapped to (reduces the PO's remaining
|
|
108
|
+
// balance). Empty when the invoice isn't tied to a PO.
|
|
109
|
+
purchaseOrderNumber: {
|
|
110
|
+
type:String
|
|
111
|
+
},
|
|
112
|
+
discountAmount: {
|
|
113
|
+
type:Number
|
|
114
|
+
},
|
|
115
|
+
discountPercentage: {
|
|
116
|
+
type:Number
|
|
117
|
+
},
|
|
118
|
+
paymentStatus:{
|
|
119
|
+
type:String,
|
|
120
|
+
default:'unpaid',
|
|
121
|
+
// 'partial' = paidAmount > 0 && paidAmount < totalAmount.
|
|
122
|
+
// Server derives this in recordPayment so the value stays in sync.
|
|
123
|
+
enum: ['paid','unpaid','partial']
|
|
124
|
+
},
|
|
125
|
+
// Running total of all payments recorded against this invoice. Sum of
|
|
126
|
+
// paymentHistory[].amount; persisted for easy querying / display so
|
|
127
|
+
// the frontend doesn't need to re-sum every render.
|
|
128
|
+
paidAmount:{
|
|
129
|
+
type:Number,
|
|
130
|
+
default:0
|
|
131
|
+
},
|
|
132
|
+
// Append-only audit trail. Each entry is one payment received from
|
|
133
|
+
// the client. recordedAt is server-set; the rest comes from the form.
|
|
134
|
+
paymentHistory:[{
|
|
135
|
+
amount:{type:Number, required:true},
|
|
136
|
+
date:{type:Date, required:true},
|
|
137
|
+
method:{type:String, enum:['banktransfer','upi','cheque','card','cash','other']},
|
|
138
|
+
reference:{type:String},
|
|
139
|
+
notes:{type:String},
|
|
140
|
+
recordedBy:{type:String},
|
|
141
|
+
recordedAt:{type:Date, default:Date.now}
|
|
142
|
+
}],
|
|
143
|
+
advanceInvoice:{
|
|
144
|
+
type:Boolean,
|
|
145
|
+
default:false
|
|
146
|
+
},
|
|
147
|
+
tempIndex:{ type:Number },
|
|
148
|
+
advancePeriod:{ type:String },
|
|
149
|
+
advanceMonths:{ type:Number },
|
|
150
|
+
},{
|
|
151
|
+
strict: true,
|
|
152
|
+
versionKey: false,
|
|
153
|
+
timestamps: true,
|
|
154
|
+
}
|
|
155
|
+
)
|
|
156
|
+
|
|
157
157
|
export default mongoose.model('invoice', invoiceSchema);
|
|
@@ -1,61 +1,61 @@
|
|
|
1
|
-
import mongoose from 'mongoose';
|
|
2
|
-
|
|
3
|
-
const paymentAccountSchema = new mongoose.Schema(
|
|
4
|
-
{
|
|
5
|
-
clientId: {
|
|
6
|
-
type: String,
|
|
7
|
-
required: true,
|
|
8
|
-
unique: true,
|
|
9
|
-
},
|
|
10
|
-
customerId:{
|
|
11
|
-
type: String,
|
|
12
|
-
required: true,
|
|
13
|
-
unique: true,
|
|
14
|
-
},
|
|
15
|
-
virtualAccId:{
|
|
16
|
-
type: String,
|
|
17
|
-
required: true,
|
|
18
|
-
unique: true,
|
|
19
|
-
},
|
|
20
|
-
bankAccId:{
|
|
21
|
-
type: String,
|
|
22
|
-
required: true,
|
|
23
|
-
unique: true,
|
|
24
|
-
},
|
|
25
|
-
accountNumber:{
|
|
26
|
-
type: String,
|
|
27
|
-
required: true,
|
|
28
|
-
unique: true,
|
|
29
|
-
},
|
|
30
|
-
paymentType:{
|
|
31
|
-
type: String,
|
|
32
|
-
},
|
|
33
|
-
status:{
|
|
34
|
-
type: String,
|
|
35
|
-
},
|
|
36
|
-
ifsc: {
|
|
37
|
-
type: String,
|
|
38
|
-
},
|
|
39
|
-
swiftCode:{
|
|
40
|
-
type: String,
|
|
41
|
-
},
|
|
42
|
-
branch:{
|
|
43
|
-
type: String,
|
|
44
|
-
},
|
|
45
|
-
credit:{
|
|
46
|
-
type: Number,
|
|
47
|
-
default:0
|
|
48
|
-
},
|
|
49
|
-
currency: {
|
|
50
|
-
type: String,
|
|
51
|
-
enum: [ 'dollar', 'inr', 'singaporedollar', 'euro', 'aed' ],
|
|
52
|
-
},
|
|
53
|
-
},
|
|
54
|
-
{
|
|
55
|
-
strict: true,
|
|
56
|
-
versionKey: false,
|
|
57
|
-
timestamps: true,
|
|
58
|
-
},
|
|
59
|
-
);
|
|
60
|
-
|
|
1
|
+
import mongoose from 'mongoose';
|
|
2
|
+
|
|
3
|
+
const paymentAccountSchema = new mongoose.Schema(
|
|
4
|
+
{
|
|
5
|
+
clientId: {
|
|
6
|
+
type: String,
|
|
7
|
+
required: true,
|
|
8
|
+
unique: true,
|
|
9
|
+
},
|
|
10
|
+
customerId:{
|
|
11
|
+
type: String,
|
|
12
|
+
required: true,
|
|
13
|
+
unique: true,
|
|
14
|
+
},
|
|
15
|
+
virtualAccId:{
|
|
16
|
+
type: String,
|
|
17
|
+
required: true,
|
|
18
|
+
unique: true,
|
|
19
|
+
},
|
|
20
|
+
bankAccId:{
|
|
21
|
+
type: String,
|
|
22
|
+
required: true,
|
|
23
|
+
unique: true,
|
|
24
|
+
},
|
|
25
|
+
accountNumber:{
|
|
26
|
+
type: String,
|
|
27
|
+
required: true,
|
|
28
|
+
unique: true,
|
|
29
|
+
},
|
|
30
|
+
paymentType:{
|
|
31
|
+
type: String,
|
|
32
|
+
},
|
|
33
|
+
status:{
|
|
34
|
+
type: String,
|
|
35
|
+
},
|
|
36
|
+
ifsc: {
|
|
37
|
+
type: String,
|
|
38
|
+
},
|
|
39
|
+
swiftCode:{
|
|
40
|
+
type: String,
|
|
41
|
+
},
|
|
42
|
+
branch:{
|
|
43
|
+
type: String,
|
|
44
|
+
},
|
|
45
|
+
credit:{
|
|
46
|
+
type: Number,
|
|
47
|
+
default:0
|
|
48
|
+
},
|
|
49
|
+
currency: {
|
|
50
|
+
type: String,
|
|
51
|
+
enum: [ 'dollar', 'inr', 'singaporedollar', 'euro', 'aed' ],
|
|
52
|
+
},
|
|
53
|
+
},
|
|
54
|
+
{
|
|
55
|
+
strict: true,
|
|
56
|
+
versionKey: false,
|
|
57
|
+
timestamps: true,
|
|
58
|
+
},
|
|
59
|
+
);
|
|
60
|
+
|
|
61
61
|
export default mongoose.model( 'paymentAccount', paymentAccountSchema);
|
|
@@ -1,47 +1,47 @@
|
|
|
1
|
-
import mongoose from 'mongoose';
|
|
2
|
-
|
|
3
|
-
// Payment reminder configuration per client (brand). One document per
|
|
4
|
-
// clientId, driving which reminder emails go out and to whom. Stored in its
|
|
5
|
-
// own `paymentreminders` collection.
|
|
6
|
-
const paymentReminderSchema = new mongoose.Schema(
|
|
7
|
-
{
|
|
8
|
-
clientId: {
|
|
9
|
-
type: String,
|
|
10
|
-
index: true,
|
|
11
|
-
},
|
|
12
|
-
// Recipients for all reminder emails on this brand.
|
|
13
|
-
reminderEmails: {
|
|
14
|
-
type: [ String ],
|
|
15
|
-
default: [],
|
|
16
|
-
},
|
|
17
|
-
// Predefined reminder templates the team can toggle. preDue carries a
|
|
18
|
-
// configurable lead time; the rest fire on fixed rules.
|
|
19
|
-
templates: {
|
|
20
|
-
preDue: {
|
|
21
|
-
enabled: { type: Boolean, default: true },
|
|
22
|
-
daysBefore: { type: Number, default: 3, min: 1, max: 365 },
|
|
23
|
-
},
|
|
24
|
-
onDue: {
|
|
25
|
-
enabled: { type: Boolean, default: true },
|
|
26
|
-
},
|
|
27
|
-
onHold: {
|
|
28
|
-
enabled: { type: Boolean, default: true },
|
|
29
|
-
},
|
|
30
|
-
suspend: {
|
|
31
|
-
enabled: { type: Boolean, default: true },
|
|
32
|
-
},
|
|
33
|
-
deactivated: {
|
|
34
|
-
enabled: { type: Boolean, default: false },
|
|
35
|
-
},
|
|
36
|
-
},
|
|
37
|
-
updatedBy: {
|
|
38
|
-
type: String,
|
|
39
|
-
},
|
|
40
|
-
}, {
|
|
41
|
-
strict: true,
|
|
42
|
-
versionKey: false,
|
|
43
|
-
timestamps: true,
|
|
44
|
-
}
|
|
45
|
-
);
|
|
46
|
-
|
|
1
|
+
import mongoose from 'mongoose';
|
|
2
|
+
|
|
3
|
+
// Payment reminder configuration per client (brand). One document per
|
|
4
|
+
// clientId, driving which reminder emails go out and to whom. Stored in its
|
|
5
|
+
// own `paymentreminders` collection.
|
|
6
|
+
const paymentReminderSchema = new mongoose.Schema(
|
|
7
|
+
{
|
|
8
|
+
clientId: {
|
|
9
|
+
type: String,
|
|
10
|
+
index: true,
|
|
11
|
+
},
|
|
12
|
+
// Recipients for all reminder emails on this brand.
|
|
13
|
+
reminderEmails: {
|
|
14
|
+
type: [ String ],
|
|
15
|
+
default: [],
|
|
16
|
+
},
|
|
17
|
+
// Predefined reminder templates the team can toggle. preDue carries a
|
|
18
|
+
// configurable lead time; the rest fire on fixed rules.
|
|
19
|
+
templates: {
|
|
20
|
+
preDue: {
|
|
21
|
+
enabled: { type: Boolean, default: true },
|
|
22
|
+
daysBefore: { type: Number, default: 3, min: 1, max: 365 },
|
|
23
|
+
},
|
|
24
|
+
onDue: {
|
|
25
|
+
enabled: { type: Boolean, default: true },
|
|
26
|
+
},
|
|
27
|
+
onHold: {
|
|
28
|
+
enabled: { type: Boolean, default: true },
|
|
29
|
+
},
|
|
30
|
+
suspend: {
|
|
31
|
+
enabled: { type: Boolean, default: true },
|
|
32
|
+
},
|
|
33
|
+
deactivated: {
|
|
34
|
+
enabled: { type: Boolean, default: false },
|
|
35
|
+
},
|
|
36
|
+
},
|
|
37
|
+
updatedBy: {
|
|
38
|
+
type: String,
|
|
39
|
+
},
|
|
40
|
+
}, {
|
|
41
|
+
strict: true,
|
|
42
|
+
versionKey: false,
|
|
43
|
+
timestamps: true,
|
|
44
|
+
}
|
|
45
|
+
);
|
|
46
|
+
|
|
47
47
|
export default mongoose.model( 'paymentreminder', paymentReminderSchema );
|
|
@@ -1,60 +1,60 @@
|
|
|
1
|
-
import mongoose from 'mongoose';
|
|
2
|
-
|
|
3
|
-
// Purchase Orders per brand (clientId). totalAmount is the original PO value and
|
|
4
|
-
// never changes; remainingAmount decreases as invoices are mapped to this PO.
|
|
5
|
-
// `usage` keeps an audit trail of which invoices consumed how much.
|
|
6
|
-
const purchaseOrderSchema = new mongoose.Schema(
|
|
7
|
-
{
|
|
8
|
-
clientId: {
|
|
9
|
-
type: String,
|
|
10
|
-
index: true,
|
|
11
|
-
},
|
|
12
|
-
companyName: {
|
|
13
|
-
type: String,
|
|
14
|
-
},
|
|
15
|
-
purchaseOrderNumber: {
|
|
16
|
-
type: String,
|
|
17
|
-
},
|
|
18
|
-
// Original PO value (immutable once created).
|
|
19
|
-
totalAmount: {
|
|
20
|
-
type: Number,
|
|
21
|
-
default: 0,
|
|
22
|
-
},
|
|
23
|
-
// Decreases as invoices are mapped; starts equal to totalAmount.
|
|
24
|
-
remainingAmount: {
|
|
25
|
-
type: Number,
|
|
26
|
-
default: 0,
|
|
27
|
-
},
|
|
28
|
-
date: {
|
|
29
|
-
type: Date,
|
|
30
|
-
},
|
|
31
|
-
// Stored S3 path (assets bucket) of the uploaded PO PDF, if any.
|
|
32
|
-
pdfPath: {
|
|
33
|
-
type: String,
|
|
34
|
-
},
|
|
35
|
-
// open -> partiallyUsed -> fullyUsed (derived from remainingAmount).
|
|
36
|
-
status: {
|
|
37
|
-
type: String,
|
|
38
|
-
enum: [ 'open', 'partiallyUsed', 'fullyUsed' ],
|
|
39
|
-
default: 'open',
|
|
40
|
-
},
|
|
41
|
-
// Invoices that consumed this PO. One entry per mapping.
|
|
42
|
-
usage: [
|
|
43
|
-
{
|
|
44
|
-
invoice: { type: String },
|
|
45
|
-
amount: { type: Number },
|
|
46
|
-
mappedAt: { type: Date },
|
|
47
|
-
mappedBy: { type: String },
|
|
48
|
-
},
|
|
49
|
-
],
|
|
50
|
-
createdBy: {
|
|
51
|
-
type: String,
|
|
52
|
-
},
|
|
53
|
-
}, {
|
|
54
|
-
strict: true,
|
|
55
|
-
versionKey: false,
|
|
56
|
-
timestamps: true,
|
|
57
|
-
},
|
|
58
|
-
);
|
|
59
|
-
|
|
1
|
+
import mongoose from 'mongoose';
|
|
2
|
+
|
|
3
|
+
// Purchase Orders per brand (clientId). totalAmount is the original PO value and
|
|
4
|
+
// never changes; remainingAmount decreases as invoices are mapped to this PO.
|
|
5
|
+
// `usage` keeps an audit trail of which invoices consumed how much.
|
|
6
|
+
const purchaseOrderSchema = new mongoose.Schema(
|
|
7
|
+
{
|
|
8
|
+
clientId: {
|
|
9
|
+
type: String,
|
|
10
|
+
index: true,
|
|
11
|
+
},
|
|
12
|
+
companyName: {
|
|
13
|
+
type: String,
|
|
14
|
+
},
|
|
15
|
+
purchaseOrderNumber: {
|
|
16
|
+
type: String,
|
|
17
|
+
},
|
|
18
|
+
// Original PO value (immutable once created).
|
|
19
|
+
totalAmount: {
|
|
20
|
+
type: Number,
|
|
21
|
+
default: 0,
|
|
22
|
+
},
|
|
23
|
+
// Decreases as invoices are mapped; starts equal to totalAmount.
|
|
24
|
+
remainingAmount: {
|
|
25
|
+
type: Number,
|
|
26
|
+
default: 0,
|
|
27
|
+
},
|
|
28
|
+
date: {
|
|
29
|
+
type: Date,
|
|
30
|
+
},
|
|
31
|
+
// Stored S3 path (assets bucket) of the uploaded PO PDF, if any.
|
|
32
|
+
pdfPath: {
|
|
33
|
+
type: String,
|
|
34
|
+
},
|
|
35
|
+
// open -> partiallyUsed -> fullyUsed (derived from remainingAmount).
|
|
36
|
+
status: {
|
|
37
|
+
type: String,
|
|
38
|
+
enum: [ 'open', 'partiallyUsed', 'fullyUsed' ],
|
|
39
|
+
default: 'open',
|
|
40
|
+
},
|
|
41
|
+
// Invoices that consumed this PO. One entry per mapping.
|
|
42
|
+
usage: [
|
|
43
|
+
{
|
|
44
|
+
invoice: { type: String },
|
|
45
|
+
amount: { type: Number },
|
|
46
|
+
mappedAt: { type: Date },
|
|
47
|
+
mappedBy: { type: String },
|
|
48
|
+
},
|
|
49
|
+
],
|
|
50
|
+
createdBy: {
|
|
51
|
+
type: String,
|
|
52
|
+
},
|
|
53
|
+
}, {
|
|
54
|
+
strict: true,
|
|
55
|
+
versionKey: false,
|
|
56
|
+
timestamps: true,
|
|
57
|
+
},
|
|
58
|
+
);
|
|
59
|
+
|
|
60
60
|
export default mongoose.model( 'purchaseorder', purchaseOrderSchema );
|