Passed
Push — master ( a5409b...86219b )
by Emil
03:02
created

v2/models/orders.js   A

Complexity

Total Complexity 36
Complexity/F 1.89

Size

Lines of Code 299
Function Count 19

Duplication

Duplicated Lines 76
Ratio 25.42 %

Test Coverage

Coverage 87.3%

Importance

Changes 0
Metric Value
wmc 36
eloc 207
mnd 17
bc 17
fnc 19
dl 76
loc 299
ccs 55
cts 63
cp 0.873
rs 9.52
bpm 0.8947
cpm 1.8947
noi 7
c 0
b 0
f 0

How to fix   Duplicated Code   

Duplicated Code

Duplicate code is one of the most pungent code smells. A rule that is often used is to re-structure code once it is duplicated in three or more places.

Common duplication problems, and corresponding solutions are:

1 1
const db = require("../db/database.js");
2
3 1
const orders = {
4
    dataFields: "o.ROWID as id, customerName as name," +
5
        " customerAddress as address," +
6
        " customerZip as zip, customerCity as city," +
7
        " customerCountry as country, s.status, s.id as status_id",
8
9
    orderItemsDataFields: "oi.productId as product_id, oi.amount," +
10
        " p.articleNumber as article_number, p.productName as name," +
11
        " p.productDescription as description, p.productSpecifiers as specifiers," +
12
        " p.stock, p.location, (p.price/100) as price",
13
14
    getAllOrders: function(
15
        res,
16
        apiKey,
17
        status=200,
18
        prependData={},
19
        range=false,
20
    ) {
21 6
        let returnedOrders = { data: []};
22
23 6
        var allOrdersSQL = "SELECT " + orders.dataFields +
24
            " FROM orders o INNER JOIN status s ON s.id = o.statusId" +
25
            " WHERE o.apiKey = ?";
26
27 6
        if (range) {
28 3
            allOrdersSQL += " AND (o.ROWID >= " +
29
                range.min +
30
                " AND o.ROWID <= " +
31
                range.max +
32
                ")";
33
        }
34
35 6
        db.all(
36
            allOrdersSQL,
37
            apiKey,
38
            function (err, orderRows) {
39 6
                if (err) {
40
                    return res.status(500).json({
41
                        errors: {
42
                            status: 500,
43
                            source: "/orders",
44
                            title: "Database error",
45
                            detail: err.message
46
                        }
47
                    });
48
                }
49
50 6
                if (orderRows.length === 0) {
51 2
                    return res.status(status).json(returnedOrders);
52
                }
53
54 4
                return orders.getOrderItems(
55
                    res,
56
                    orderRows,
57
                    apiKey,
58
                    status,
59
                    returnedOrders,
60
                    prependData
61
                );
62
            });
63
    },
64
65
    getOrderItems: function(
66
        res,
67
        orderRows,
68
        apiKey,
69
        status,
70
        returnedOrders,
71
        prependData
72
    ) {
73 5
        orderRows.forEach(function(order) {
74 14
            db.all("SELECT " + orders.orderItemsDataFields +
75
                " FROM order_items oi" +
76
                " INNER JOIN products p ON oi.productId=p.ROWID" +
77
                " AND oi.apiKey=p.apiKey" +
78
                " WHERE oi.apiKey = ? AND oi.orderId = ?",
79
            apiKey,
80
            order.id,
81
            function (err, orderItemRows) {
82 14
                if (err) {
83
                    return res.status(500).json({
84
                        errors: {
85
                            status: 500,
86
                            source: "/orders order_items",
87
                            title: "Database error",
88
                            detail: err.message
89
                        }
90
                    });
91
                }
92
93 14
                order.order_items = orderItemRows;
94 14
                returnedOrders.data.push(order);
95
96 14
                if (returnedOrders.data.length === orderRows.length) {
97 5
                    returnedOrders.data.sort(function (a, b) {
98 12
                        return a.id - b.id;
99
                    });
100
101 5
                    if (status > 200) {
102 3
                        prependData.data.orders = returnedOrders.data;
103
104 3
                        return res.status(status).json(prependData);
105
                    }
106
107 2
                    return res.status(status).json(returnedOrders);
108
                }
109
            });
110
        });
111
    },
112
113
    getOrder: function(res, apiKey, orderId, status=200) {
114 10
        if (Number.isInteger(parseInt(orderId))) {
115 9
            db.get("SELECT " + orders.dataFields +
116
                " FROM orders o INNER JOIN status s ON s.id = o.statusId" +
117
                " WHERE o.apiKey = ? AND o.ROWID = ?",
118
            apiKey,
119
            orderId, (err, order) => {
120 9
                if (err) {
121
                    return res.status(500).json({
122
                        errors: {
123
                            status: 500,
124
                            source: "/order/" + orderId,
125
                            title: "Database error",
126
                            detail: err.message
127
                        }
128
                    });
129
                }
130
131 9
                if (order === undefined) {
132 1
                    return res.status(status).json({ data: {} });
133
                }
134
135 8
                order.order_items = [];
136 8
                db.each("SELECT " + orders.orderItemsDataFields + " FROM order_items oi " +
137
                    " INNER JOIN products p ON oi.productId=p.ROWID" +
138
                    " AND oi.apiKey=p.apiKey" +
139
                    " WHERE oi.apiKey = ? AND oi.orderId = ?",
140
                apiKey,
141
                order.id, (err, orderItemRow) => {
142 2
                    if (err) {
143
                        return res.status(500).json({
144
                            errors: {
145
                                status: 500,
146
                                source: "/order/" + orderId + " order_items",
147
                                title: "Database error",
148
                                detail: err.message
149
                            }
150
                        });
151
                    }
152
153 2
                    order.order_items.push(orderItemRow);
154
                }, function () {
155 8
                    return res.status(status).json({ data: order });
156
                });
157
            });
158
        } else {
159 1
            return res.status(400).json({
160
                errors: {
161
                    status: 400,
162
                    detail: "Required attribute order id " +
163
                        " is not an integer."
164
                }
165
            });
166
        }
167
    },
168
169
    searchOrder: function(res, apiKey, query, status=200) {
170 2
        const searchQuery = "%" + query + "%";
171 2
        let returnedOrders = { data: []};
172
173 2
        db.all("SELECT " + orders.dataFields +
174
            " FROM orders o INNER JOIN status s ON s.id = o.statusId" +
175
            " WHERE o.apiKey = ? AND" +
176
            "(customerName LIKE ? OR customerAddress LIKE ? OR customerZip LIKE ?" +
177
            " OR customerCity LIKE ? OR customerCountry LIKE ?)",
178
        apiKey,
179
        searchQuery,
180
        searchQuery,
181
        searchQuery,
182
        searchQuery,
183
        searchQuery, (err, orderRows) => {
184 2
            if (err) {
185
                return res.status(500).json({
186
                    errors: {
187
                        status: 500,
188
                        source: "/order/search/" + query,
189
                        title: "Database error",
190
                        detail: err.message
191
                    }
192
                });
193
            }
194
195 2
            if (orderRows.length === 0) {
196 1
                return res.status(status).json(returnedOrders);
197
            }
198
199 1
            return orders.getOrderItems(
200
                res,
201
                orderRows,
202
                apiKey,
203
                status,
204
                returnedOrders
205
            );
206
        });
207
    },
208
209
    addOrder: function(res, body) {
210 4
        db.run("INSERT INTO orders (customerName, customerAddress, customerZip," +
211
            " customerCity, customerCountry, statusId, apiKey) VALUES (?, ?, ?, ?, ?, ?, ?)",
212
        body.name,
213
        body.address,
214
        body.zip,
215
        body.city,
216
        body.country,
217
        body.status_id || 100,
218
        body.api_key,
219
        function(err) {
220 4
            if (err) {
221 1
                return res.status(500).json({
222
                    errors: {
223
                        status: 500,
224
                        source: "POST /order",
225
                        title: "Database error",
226
                        detail: err.message
227
                    }
228
                });
229
            }
230
231 3
            return orders.getOrder(res, body.api_key, this.lastID, 201);
232
        });
233
    },
234
235
    updateOrder: function(res, body) {
236 2
        if (Number.isInteger(parseInt(body.id))) {
237 1
            db.run("UPDATE orders SET customerName = ?," +
238
                " customerAddress = ?, customerZip = ?," +
239
                " customerCity = ?, customerCountry = ?, statusId = ?" +
240
                " WHERE apiKey = ? AND ROWID = ?",
241
            body.name,
242
            body.address,
243
            body.zip,
244
            body.city,
245
            body.country,
246
            body.status_id || 100,
247
            body.api_key,
248
            body.id, (err) => {
249 2
                if (err) {
250
                    return res.status(500).json({
251
                        errors: {
252
                            status: 500,
253
                            source: "PUT /order",
254
                            title: "Database error",
255
                            detail: err.message
256
                        }
257
                    });
258
                }
259
260 1
                return res.status(204).send();
261
            });
262
        } else {
263 1
            return res.status(400).json({
264
                errors: {
265
                    status: 400,
266
                    detail: "Required attribute order id (id) " +
267
                        " was not included in the request."
268
                }
269
            });
270
        }
271
    },
272
273
    deleteOrder: function(res, body) {
274 2
        if (Number.isInteger(parseInt(body.id))) {
275 1
            db.run("DELETE FROM orders WHERE apiKey = ? AND ROWID = ?",
276
                body.api_key,
277
                body.id, (err) => {
278 2
                    if (err) {
279
                        return res.status(500).json({
280
                            errors: {
281
                                status: 500,
282
                                source: "DELETE /order",
283
                                title: "Database error",
284
                                detail: err.message
285
                            }
286
                        });
287
                    }
288
289 1
                    db.run("DELETE FROM order_items WHERE apiKey = ? AND orderId = ?",
290
                        body.api_key,
291
                        body.id, (err) => {
292 2
                            if (err) {
293
                                return res.status(500).json({
294
                                    errors: {
295
                                        status: 500,
296
                                        source: "DELETE /order order_items",
297
                                        title: "Database error",
298
                                        detail: err.message
299
                                    }
300
                                });
301
                            }
302
303 1
                            return res.status(204).send();
304
                        });
305
                });
306
        } else {
307 1
            return res.status(400).json({
308
                errors: {
309
                    status: 400,
310
                    detail: "Required attribute order id (id) " +
311
                        " was not included in the request."
312
                }
313
            });
314
        }
315
    }
316
};
317
318
module.exports = orders;
319