picker-db 3.4.0

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.
Files changed (43) hide show
  1. package/.editorconfig +8 -0
  2. package/.eslintignore +9 -0
  3. package/.eslintrc.json +35 -0
  4. package/.nvmrc +1 -0
  5. package/.vscode/settings.json +11 -0
  6. package/README.md +21 -0
  7. package/bitbucket-pipelines.yml +24 -0
  8. package/constants.js +420 -0
  9. package/index.js +5 -0
  10. package/lib/Logger/index.js +45 -0
  11. package/lib/Mongo/index.js +126 -0
  12. package/modules/picker/index.js +259 -0
  13. package/modules/picker/models/identityCounter.js +15 -0
  14. package/modules/picker/models/index.js +50 -0
  15. package/modules/picker/schemas/address.js +74 -0
  16. package/modules/picker/schemas/adminSetting.js +125 -0
  17. package/modules/picker/schemas/balanceTransaction.js +132 -0
  18. package/modules/picker/schemas/bill.js +70 -0
  19. package/modules/picker/schemas/bookingProduct.js +50 -0
  20. package/modules/picker/schemas/bookings.js +699 -0
  21. package/modules/picker/schemas/business.js +231 -0
  22. package/modules/picker/schemas/businessCategory.js +61 -0
  23. package/modules/picker/schemas/customer.js +28 -0
  24. package/modules/picker/schemas/driver.js +162 -0
  25. package/modules/picker/schemas/fareSettings.js +122 -0
  26. package/modules/picker/schemas/fraudBooking.js +21 -0
  27. package/modules/picker/schemas/identityCounter.js +10 -0
  28. package/modules/picker/schemas/kmRange.js +27 -0
  29. package/modules/picker/schemas/massDelivery.js +119 -0
  30. package/modules/picker/schemas/notification.js +76 -0
  31. package/modules/picker/schemas/paymentezCustomer.js +41 -0
  32. package/modules/picker/schemas/paymentezTransaction.js +67 -0
  33. package/modules/picker/schemas/preference.js +40 -0
  34. package/modules/picker/schemas/pricingDetails.js +90 -0
  35. package/modules/picker/schemas/referralUsage.js +33 -0
  36. package/modules/picker/schemas/region.js +75 -0
  37. package/modules/picker/schemas/review.js +42 -0
  38. package/modules/picker/schemas/session.js +25 -0
  39. package/modules/picker/schemas/superRegion.js +41 -0
  40. package/modules/picker/schemas/user.js +337 -0
  41. package/package.json +29 -0
  42. package/playground/testConnection.js +24 -0
  43. package/playground/testService.js +27 -0
@@ -0,0 +1,259 @@
1
+ const dbModels = require("./models");
2
+ const Mongo = require("../../lib/Mongo");
3
+
4
+ /**
5
+ * Class representing a connection to Picker's mongoDB database
6
+ */
7
+ class PickerMongoDBService {
8
+ /**
9
+ * Initializes a connection to the selected database
10
+ * @param {object} config
11
+ */
12
+ constructor (config = {}) {
13
+ this.connection = new Mongo(config);
14
+ }
15
+
16
+ /**
17
+ * Connects to the database and loads all PickerMongoDB models
18
+ */
19
+ async connect () {
20
+ const connection = await this.connection.getConnection();
21
+ this.models = dbModels(connection);
22
+ }
23
+
24
+ async disconnect () {
25
+ this.connection.disconnect();
26
+ }
27
+
28
+ /**
29
+ * Wrapper around 'save' method
30
+ * @description Inserts a document in the database
31
+ * @param {string} modelName Name of the model for this operation
32
+ * @param {object} objToSave Document information to save
33
+ * @returns {Promise<object[]>}
34
+ */
35
+ async createData (modelName, objToSave) {
36
+ return new Promise((resolve, reject) => {
37
+ const data = new this.models[modelName](objToSave);
38
+ data.save(objToSave, (err, res) => {
39
+ if (err) {
40
+ return reject(err);
41
+ }
42
+ return resolve(res);
43
+ });
44
+ });
45
+ }
46
+
47
+ /**
48
+ * Wrapper around 'find' method
49
+ * @description Returns all documents that match the query
50
+ * @param {string} modelName Name of the model for this operation
51
+ * @param {object} criteria Query
52
+ * @param {object} projection Model's field to return from this query
53
+ * @param {object} options Query options
54
+ * @returns {Promise<object[]>}
55
+ */
56
+ async getDataAsync (modelName, criteria = {}, projection = {}, options = {}) {
57
+ return new Promise((resolve, reject) => {
58
+ this.models[modelName].find(criteria, projection, options, (err, res) => {
59
+ if (err) {
60
+ return reject(err);
61
+ }
62
+ return resolve(res);
63
+ });
64
+ });
65
+ }
66
+
67
+ /**
68
+ * Wrapper around 'find' method with 'populate'
69
+ * @description Returns all documents that match the query with the populated fields
70
+ * @param {string} modelName Name of the model for this operation
71
+ * @param {object} criteria Query
72
+ * @param {object} projection Model's field to return from this query
73
+ * @param {object} options Query options
74
+ * @param {*} populateModel
75
+ * @returns {Promise<object[]>}
76
+ */
77
+ async getDataPopulateAsync (modelName, criteria, projection, options, populateModel) {
78
+ return new Promise((resolve, reject) => {
79
+ this.models[modelName].find(criteria, projection, options).populate(populateModel).exec((err, res) => {
80
+ if (err) {
81
+ return reject(err);
82
+ }
83
+ return resolve(res);
84
+ });
85
+ });
86
+ }
87
+
88
+ /**
89
+ * Wrapper around 'findOne' method
90
+ * @description Returns the first document that matches the query
91
+ * @param {string} modelName Name of the model for this operation
92
+ * @param {object} criteria Query
93
+ * @param {object} projection Model's field to return from this query
94
+ * @param {object} options Query options
95
+ * @returns {Promise<object>}
96
+ */
97
+ async getFirstMatch (modelName, criteria, projection, options) {
98
+ return new Promise((resolve, reject) => {
99
+ this.models[modelName].findOne(criteria, projection, options, (err, res) => {
100
+ if (err) {
101
+ return reject(err);
102
+ }
103
+ return resolve(res);
104
+ });
105
+ });
106
+ }
107
+
108
+ /**
109
+ * Wrapper around 'findOne' method with 'populate'
110
+ * @description Returns the first document that matches the query with the populated fields
111
+ * @param {string} modelName Name of the model for this operation
112
+ * @param {object} criteria Query
113
+ * @param {object} projection Model's field to return from this query
114
+ * @param {object} options Query options
115
+ * @param {*} populateModel
116
+ * @returns {Promise<object>}
117
+ */
118
+ async getFirstMatchPopulate (modelName, criteria, projection, options, populateModel) {
119
+ return new Promise((resolve, reject) => {
120
+ this.models[modelName].findOne(criteria, projection, options).populate(populateModel).exec((err, res) => {
121
+ if (err) {
122
+ return reject(err);
123
+ }
124
+ return resolve(res);
125
+ });
126
+ });
127
+ }
128
+
129
+ /**
130
+ * Wrapper around 'findOneAndUpdate' method
131
+ * @description Updates the first document that matches the query
132
+ * @param {string} modelName Name of the model for this operation
133
+ * @param {object} criteria Query
134
+ * @param {object} dataToSet Update to execute
135
+ * @param {object} options Query options
136
+ * @returns {Promise<object>}
137
+ */
138
+ async updateData (modelName, criteria, dataToSet, options) {
139
+ return new Promise((resolve, reject) => {
140
+ this.models[modelName].findOneAndUpdate(criteria, dataToSet, options, (err, res) => {
141
+ if (err) {
142
+ return reject(err);
143
+ }
144
+ return resolve(res);
145
+ });
146
+ });
147
+ }
148
+
149
+ /**
150
+ * Wrapper around 'update' method
151
+ * @description Updates all the documents that match the query
152
+ * @param {string} modelName Name of the model for this operation
153
+ * @param {object} criteria Query
154
+ * @param {object} dataToSet Update to execute
155
+ * @param {object} options Query options
156
+ * @returns {Promise<object>}
157
+ */
158
+ async updateMultiple (modelName, criteria, dataToSet, options = {}) {
159
+ options.multi = true;
160
+ return new Promise((resolve, reject) => {
161
+ this.models[modelName].update(criteria, dataToSet, options, (err, res) => {
162
+ if (err) {
163
+ return reject(err);
164
+ }
165
+ return resolve(res);
166
+ });
167
+ });
168
+ }
169
+
170
+ /**
171
+ * Wrapper around 'findOneAndRemove' method
172
+ * @description Deletes the first document that matches the query
173
+ * @param {string} modelName Name of the model for this operation
174
+ * @param {object} criteria Query
175
+ * @returns {Promise<object[]>}
176
+ */
177
+ async deleteData (modelName, criteria) {
178
+ return new Promise((resolve, reject) => {
179
+ this.models[modelName].findOneAndRemove(criteria, (err, res) => {
180
+ if (err) {
181
+ return reject(err);
182
+ }
183
+ return resolve(res);
184
+ });
185
+ });
186
+ }
187
+
188
+ /**
189
+ * Wrapper around 'deleteMany' method
190
+ * @description Deletes all the documents that match the query
191
+ * @param {string} modelName Name of the model for this operation
192
+ * @param {object} criteria Query
193
+ * @returns {Promise<object[]>}
194
+ */
195
+ async deleteMany (modelName, criteria) {
196
+ return new Promise((resolve, reject) => {
197
+ this.models[modelName].deleteMany(criteria, (err, res) => {
198
+ if (err) {
199
+ return reject(err);
200
+ }
201
+ return resolve(res);
202
+ });
203
+ });
204
+ }
205
+
206
+ /**
207
+ * Wrapper around 'count' method
208
+ * @description Counts all the documents that match the query
209
+ * @param {string} modelName Name of the model for this operation
210
+ * @param {object} criteria Query
211
+ * @returns {Promise<object[]>}
212
+ */
213
+ async countData (modelName, criteria) {
214
+ return new Promise((resolve, reject) => {
215
+ this.models[modelName].count(criteria, (err, res) => {
216
+ if (err) {
217
+ return reject(err);
218
+ }
219
+ return resolve(res);
220
+ });
221
+ });
222
+ }
223
+
224
+ /**
225
+ * Wrapper around 'aggregate' method
226
+ * @param {string} modelName Name of the model for this operation
227
+ * @param {object[]} pipeline
228
+ * @returns {Promise<object[]>}
229
+ */
230
+ async aggregateData (modelName, pipeline) {
231
+ return new Promise((resolve, reject) => {
232
+ this.models[modelName].aggregate(pipeline).exec((err, res) => {
233
+ if (err) {
234
+ return reject(err);
235
+ }
236
+ return resolve(res);
237
+ });
238
+ });
239
+ }
240
+
241
+ /**
242
+ * Wrapper around 'aggregate' method using a cursor
243
+ * @param {string} modelName Name of the model for this operation
244
+ * @param {object[]} pipeline
245
+ * @returns {Promise<object[]>}
246
+ */
247
+ async aggregateDataCursor (modelName, pipeline) {
248
+ return new Promise((resolve, reject) => {
249
+ this.models[modelName].aggregate(pipeline).allowDiskUse(true).cursor({ batchSize: 2000 }).exec((err, res) => {
250
+ if (err) {
251
+ return reject(err);
252
+ }
253
+ return resolve(res);
254
+ });
255
+ });
256
+ }
257
+ }
258
+
259
+ module.exports = PickerMongoDBService;
@@ -0,0 +1,15 @@
1
+ const schema = require("../schemas/identityCounter");
2
+
3
+ let model;
4
+
5
+ const getModel = (connection) => {
6
+ if (model) {
7
+ return model;
8
+ }
9
+ model = connection.model("IdentityCounter", schema(connection));
10
+ return model;
11
+ };
12
+
13
+ module.exports = {
14
+ getModel,
15
+ };
@@ -0,0 +1,50 @@
1
+ const UserSchema = require("../schemas/user");
2
+ const CustomerSchema = require("../schemas/customer");
3
+ const DriverSchema = require("../schemas/driver");
4
+ const BusinessSchema = require("../schemas/business");
5
+ const BookingSchema = require("../schemas/bookings");
6
+ const SessionSchema = require("../schemas/session");
7
+ const NotificationSchema = require("../schemas/notification");
8
+ const BusinessCategorySchema = require("../schemas/businessCategory");
9
+ const BalanceTransactionSchema = require("../schemas/balanceTransaction");
10
+ const FareSettingSchema = require("../schemas/fareSettings");
11
+ const RegionSchema = require("../schemas/region");
12
+ const SuperRegionSchema = require("../schemas/superRegion");
13
+ const AddressSchema = require("../schemas/address");
14
+ const MassDeliverySchema = require("../schemas/massDelivery");
15
+ const BillSchema = require("../schemas/bill");
16
+ const FraudBookingSchema = require("../schemas/fraudBooking");
17
+ const AdminSettingSchema = require("../schemas/adminSetting");
18
+ const PaymentezTransactionSchema = require("../schemas/paymentezTransaction");
19
+ const PaymentezCustomerSchema = require("../schemas/paymentezCustomer");
20
+ const PreferenceSchema = require("../schemas/preference");
21
+ const ReferralUsageSchema = require("../schemas/referralUsage");
22
+ const ReviewSchema = require("../schemas/review");
23
+
24
+ /** @param {import("mongoose")} connection */
25
+ module.exports = (connection) => {
26
+ return {
27
+ Bookings: connection.model("Bookings", BookingSchema(connection)),
28
+ User: connection.model("User", UserSchema(connection)),
29
+ Business: connection.model("Business", BusinessSchema(connection)),
30
+ Driver: connection.model("Driver", DriverSchema(connection)),
31
+ Customer: connection.model("Customer", CustomerSchema(connection)),
32
+ Session: connection.model("Session", SessionSchema(connection)),
33
+ Notification: connection.model("Notification", NotificationSchema(connection)),
34
+ BusinessCategory: connection.model("BusinessCategory", BusinessCategorySchema(connection)),
35
+ BalanceTransaction: connection.model("BalanceTransaction", BalanceTransactionSchema(connection)),
36
+ Fares: connection.model("Fares", FareSettingSchema(connection)),
37
+ SuperRegion: connection.model("SuperRegion", SuperRegionSchema(connection)),
38
+ Region: connection.model("Region", RegionSchema(connection)),
39
+ Address: connection.model("Address", AddressSchema(connection)),
40
+ MassDelivery: connection.model("MassDelivery", MassDeliverySchema(connection)),
41
+ Bill: connection.model("Bill", BillSchema(connection)),
42
+ FraudBooking: connection.model("FraudBooking", FraudBookingSchema(connection)),
43
+ AdminSetting: connection.model("AdminSetting", AdminSettingSchema(connection)),
44
+ PaymentezTransaction: connection.model("PaymentezTransaction", PaymentezTransactionSchema(connection)),
45
+ PaymentezCustomer: connection.model("PaymentezCustomer", PaymentezCustomerSchema(connection)),
46
+ Preference: connection.model("Preference", PreferenceSchema(connection)),
47
+ ReferralUsage: connection.model("ReferralUsage", ReferralUsageSchema(connection)),
48
+ Review: connection.model("Review", ReviewSchema(connection)),
49
+ };
50
+ };
@@ -0,0 +1,74 @@
1
+ const { ADDRESS_TYPES } = require("../../../constants");
2
+
3
+ /** @param {import("mongoose")} connection */
4
+ module.exports = (connection) => {
5
+ const AddressSchema = new connection.base.Schema({
6
+ companyName: {
7
+ type: String,
8
+ },
9
+ companyAddress: {
10
+ type: String,
11
+ },
12
+ latitude: {
13
+ type: Number,
14
+ default: null,
15
+ },
16
+ longitude: {
17
+ type: Number,
18
+ default: null,
19
+ },
20
+ city: {
21
+ type: String,
22
+ default: null,
23
+ },
24
+ state: {
25
+ type: String,
26
+ default: null,
27
+ },
28
+ zipCode: {
29
+ type: String,
30
+ default: null,
31
+ },
32
+ addressType: {
33
+ type: String,
34
+ enum: [
35
+ ADDRESS_TYPES.SELF,
36
+ ADDRESS_TYPES.DELIVERY,
37
+ ADDRESS_TYPES.PICKUP,
38
+ ],
39
+ },
40
+ type: {
41
+ type: String,
42
+ enum: [
43
+ ADDRESS_TYPES.HOME,
44
+ ADDRESS_TYPES.OFFICE,
45
+ ADDRESS_TYPES.OTHERS,
46
+ ],
47
+ default: ADDRESS_TYPES.HOME,
48
+ },
49
+ // For booking pick and delivery addresses only
50
+ customerID: {
51
+ type: connection.base.Schema.ObjectId,
52
+ ref: "Customer",
53
+ default: null,
54
+ },
55
+ isValidAddress: {
56
+ type: Number,
57
+ default: 1,
58
+ },
59
+ placeID: {
60
+ type: String,
61
+ default: null,
62
+ },
63
+ title: {
64
+ type: String,
65
+ default: null,
66
+ },
67
+ fullAddress: {
68
+ type: String,
69
+ default: null,
70
+ },
71
+ }, { timestamps: true });
72
+
73
+ return AddressSchema;
74
+ };
@@ -0,0 +1,125 @@
1
+
2
+ const { PAYMENT } = require("../../../constants").DRIVER;
3
+
4
+ /** @param {import("mongoose")} connection */
5
+ module.exports = (connection) => {
6
+ const RegionSchema = new connection.base.Schema({
7
+ otpExpiresIn: {
8
+ type: Number,
9
+ default: 300,
10
+ },
11
+ linkExpiresIn: {
12
+ type: Number,
13
+ default: 300,
14
+ },
15
+ deleteTrackingData: {
16
+ type: Number,
17
+ default: 1,
18
+ },
19
+ webMultiSession: {
20
+ type: Boolean,
21
+ default: true,
22
+ },
23
+ deviceMultiSession: {
24
+ type: Boolean,
25
+ default: false,
26
+ },
27
+ adminTokenExpireTime: {
28
+ type: Number,
29
+ default: 30,
30
+ },
31
+ userTokenExpireTime: {
32
+ type: Number,
33
+ default: 43200,
34
+ },
35
+ referralSchemeType: {
36
+ type: String,
37
+ },
38
+ isSpecial: {
39
+ type: Boolean,
40
+ default: true,
41
+ },
42
+ distanceToDelivery: {
43
+ type: Boolean,
44
+ default: 200,
45
+ }, // In meters,
46
+ minBatteryPercentage: {
47
+ type: Number,
48
+ default: 30,
49
+ }, // Indicates the minimum percentage by which a picker may accept a booking request
50
+ pickerCommission: {
51
+ type: Number,
52
+ default: 40,
53
+ }, // From the totalFee, over the minimum promised, the percentage corresponded to the picker
54
+ minDeviceTokenFlag: {
55
+ type: Number,
56
+ default: 2,
57
+ }, // Number of users with the same deviceToken to raise a flag
58
+ payment: {
59
+ type: {
60
+ type: String,
61
+ enum: [
62
+ PAYMENT.PERCENTAGE,
63
+ PAYMENT.ABSOLUTE,
64
+ PAYMENT.OVER_MINIMUM,
65
+ ],
66
+ default: PAYMENT.ABSOLUTE,
67
+ },
68
+ value: {
69
+ type: Number,
70
+ default: 4,
71
+ },
72
+ },
73
+ searchExpirationTimeMP: {
74
+ type: Number,
75
+ }, // Expiration time of the driver search in MP
76
+ avgPickupTimeMinutes: {
77
+ type: Number,
78
+ },
79
+ timeIntervals: [{
80
+ text: { type: String },
81
+ value: { type: Number },
82
+ index: { type: Number },
83
+ }],
84
+ averagePointATime: {
85
+ type: Number,
86
+ default: 20,
87
+ }, // In minutes
88
+ cancellationTime: {
89
+ type: Number,
90
+ min: 0,
91
+ default: 180, // 180 seconds = 3 minutes
92
+ }, // In seconds
93
+ availableDriverCancellation: {
94
+ type: Boolean,
95
+ default: false,
96
+ },
97
+ addCardLinkExpiresIn: {
98
+ type: Number,
99
+ default: 300,
100
+ },
101
+ maxDeliveryDistanceMKT: {
102
+ type: Number,
103
+ default: 10,
104
+ }, // In kms
105
+ shopOrderRequestPercentage: {
106
+ type: Number,
107
+ default: 15,
108
+ }, // In percentage %
109
+ kmRangeCommissionFee: [{
110
+ min: { type: Number },
111
+ max: { type: Number },
112
+ commission: { type: Number },
113
+ }],
114
+ driverExtraCommission: {
115
+ type: Number,
116
+ default: 0,
117
+ }, // Extra commission to charge the picker after a completed booking
118
+ highDemandThreshold: {
119
+ type: Number,
120
+ min: 0,
121
+ },
122
+ }, { timestamps: true });
123
+
124
+ return RegionSchema;
125
+ };
@@ -0,0 +1,132 @@
1
+ const _ = require("lodash");
2
+
3
+ const { PAYMENT_METHODS } = require("../../../constants");
4
+ const { TYPE, STATUS, SELECTED_REASONS } = require("../../../constants").TRANSACTION;
5
+
6
+ const { getModel } = require("../models/identityCounter");
7
+
8
+ /** @param {import("mongoose")} connection */
9
+ module.exports = (connection) => {
10
+ const IdentityCounterModel = getModel(connection);
11
+
12
+ const BalanceTransactionSchema = new connection.base.Schema({
13
+ transactionID: {
14
+ type: Number,
15
+ index: true,
16
+ },
17
+ type: {
18
+ type: String,
19
+ enum: _.values(TYPE),
20
+ required: true,
21
+ },
22
+ amount: {
23
+ type: Number,
24
+ required: true,
25
+ },
26
+ driver: {
27
+ type: connection.base.Schema.ObjectId,
28
+ ref: "User",
29
+ default: null,
30
+ },
31
+ business: {
32
+ type: connection.base.Schema.ObjectId,
33
+ ref: "User",
34
+ default: null,
35
+ },
36
+ description: {
37
+ type: String,
38
+ },
39
+ date: {
40
+ type: Date,
41
+ required: true,
42
+ },
43
+ bookingID: {
44
+ type: connection.base.Schema.ObjectId,
45
+ ref: "Bookings",
46
+ default: null,
47
+ },
48
+ paymentMethod: {
49
+ type: String,
50
+ enum: [
51
+ PAYMENT_METHODS.CARD.INDEX,
52
+ PAYMENT_METHODS.CASH.INDEX,
53
+ PAYMENT_METHODS.BILLING_CARD.INDEX,
54
+ PAYMENT_METHODS.BILLING_TRANSFER.INDEX,
55
+ ],
56
+ default: PAYMENT_METHODS.NONE,
57
+ },
58
+ status: {
59
+ type: String,
60
+ enum: _.values(STATUS),
61
+ default: STATUS.REALIZED,
62
+ },
63
+ registeredBy: {
64
+ type: connection.base.Schema.ObjectId,
65
+ ref: "User",
66
+ default: null,
67
+ },
68
+ approvedBy: {
69
+ type: connection.base.Schema.ObjectId,
70
+ ref: "User",
71
+ default: null,
72
+ },
73
+ linkedTo: [{
74
+ balanceTransaction: {
75
+ type: connection.base.Schema.ObjectId,
76
+ ref: "BalanceTransaction",
77
+ },
78
+ idToShow: {
79
+ type: String,
80
+ },
81
+ }],
82
+ isLinked: {
83
+ type: Boolean,
84
+ default: false,
85
+ }, // Shows if this transaction has already been linked by a DEPOSIT. Only valid for ITEM transactions
86
+ bankTransactionID: {
87
+ type: String,
88
+ }, // The transactionID from the deposit made
89
+ bankName: {
90
+ type: String,
91
+ },
92
+ authCode: {
93
+ type: String,
94
+ },
95
+ corporateID: {
96
+ type: String,
97
+ },
98
+ selectedReason: {
99
+ type: String,
100
+ enum: _.values(SELECTED_REASONS),
101
+ },
102
+ rechargeImage: {
103
+ thumbnail: {
104
+ type: String,
105
+ default: null,
106
+ },
107
+ original: {
108
+ type: String,
109
+ default: null,
110
+ },
111
+ },
112
+ }, { timestamps: true });
113
+
114
+ BalanceTransactionSchema.pre("save", function (next) {
115
+ if (!this.isNew) {
116
+ return next();
117
+ }
118
+ const doc = this;
119
+ const query = { model: "BalanceTransaction" };
120
+ const update = { $inc: { count: 1 } };
121
+ const options = { new: true };
122
+ IdentityCounterModel.findOneAndUpdate(query, update, options, function (error, counter) {
123
+ if (error) {
124
+ return next(error);
125
+ }
126
+ doc.transactionID = counter.count;
127
+ next();
128
+ });
129
+ });
130
+
131
+ return BalanceTransactionSchema;
132
+ };