• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

inventree / InvenTree / 4565318358

pending completion
4565318358

push

github

Oliver Walters
Refactored status codes in javascript

11 of 11 new or added lines in 1 file covered. (100.0%)

26495 of 30111 relevant lines covered (87.99%)

0.88 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

76.51
/InvenTree/InvenTree/status_codes.py
1
"""Status codes for InvenTree."""
2

3
from django.utils.translation import gettext_lazy as _
1✔
4

5

6
class StatusCode:
1✔
7
    """Base class for representing a set of StatusCodes.
8

9
    This is used to map a set of integer values to text.
10
    """
11

12
    colors = {}
1✔
13

14
    @classmethod
1✔
15
    def render(cls, key, large=False):
1✔
16
        """Render the value as a HTML label."""
17
        # If the key cannot be found, pass it back
18
        if key not in cls.options.keys():
1✔
19
            return key
×
20

21
        value = cls.options.get(key, key)
1✔
22
        color = cls.colors.get(key, 'secondary')
1✔
23

24
        span_class = f'badge rounded-pill bg-{color}'
1✔
25

26
        return "<span class='{cl}'>{value}</span>".format(
1✔
27
            cl=span_class,
28
            value=value
29
        )
30

31
    @classmethod
1✔
32
    def list(cls):
1✔
33
        """Return the StatusCode options as a list of mapped key / value items."""
34
        return list(cls.dict().values())
×
35

36
    @classmethod
1✔
37
    def text(cls, key):
1✔
38
        """Text for supplied status code."""
39
        return cls.options.get(key, None)
×
40

41
    @classmethod
1✔
42
    def items(cls):
1✔
43
        """All status code items."""
44
        return cls.options.items()
1✔
45

46
    @classmethod
1✔
47
    def keys(cls):
1✔
48
        """All status code keys."""
49
        return cls.options.keys()
×
50

51
    @classmethod
1✔
52
    def labels(cls):
1✔
53
        """All status code labels."""
54
        return cls.options.values()
×
55

56
    @classmethod
1✔
57
    def names(cls):
1✔
58
        """Return a map of all 'names' of status codes in this class
59

60
        Will return a dict object, with the attribute name indexed to the integer value.
61

62
        e.g.
63
        {
64
            'PENDING': 10,
65
            'IN_PROGRESS': 20,
66
        }
67
        """
68
        keys = cls.keys()
×
69
        status_names = {}
×
70

71
        for d in dir(cls):
×
72
            if d.startswith('_'):
×
73
                continue
×
74
            if d != d.upper():
×
75
                continue
×
76

77
            value = getattr(cls, d, None)
×
78

79
            if value is None:
×
80
                continue
×
81
            if callable(value):
×
82
                continue
×
83
            if type(value) != int:
×
84
                continue
×
85
            if value not in keys:
×
86
                continue
×
87

88
            status_names[d] = value
×
89

90
        return status_names
×
91

92
    @classmethod
1✔
93
    def dict(cls):
1✔
94
        """Return a dict representation containing all required information"""
95
        values = {}
×
96

97
        for name, value, in cls.names().items():
×
98
            entry = {
×
99
                'key': value,
100
                'name': name,
101
                'label': cls.label(value),
102
            }
103

104
            if hasattr(cls, 'colors'):
×
105
                if color := cls.colors.get(value, None):
×
106
                    entry['color'] = color
×
107

108
            values[name] = entry
×
109

110
        return values
×
111

112
    @classmethod
1✔
113
    def label(cls, value):
1✔
114
        """Return the status code label associated with the provided value."""
115
        return cls.options.get(value, value)
1✔
116

117
    @classmethod
1✔
118
    def value(cls, label):
1✔
119
        """Return the value associated with the provided label."""
120
        for k in cls.options.keys():
×
121
            if cls.options[k].lower() == label.lower():
×
122
                return k
×
123

124
        raise ValueError("Label not found")
×
125

126

127
class PurchaseOrderStatus(StatusCode):
1✔
128
    """Defines a set of status codes for a PurchaseOrder."""
129

130
    # Order status codes
131
    PENDING = 10  # Order is pending (not yet placed)
1✔
132
    PLACED = 20  # Order has been placed with supplier
1✔
133
    COMPLETE = 30  # Order has been completed
1✔
134
    CANCELLED = 40  # Order was cancelled
1✔
135
    LOST = 50  # Order was lost
1✔
136
    RETURNED = 60  # Order was returned
1✔
137

138
    options = {
1✔
139
        PENDING: _("Pending"),
140
        PLACED: _("Placed"),
141
        COMPLETE: _("Complete"),
142
        CANCELLED: _("Cancelled"),
143
        LOST: _("Lost"),
144
        RETURNED: _("Returned"),
145
    }
146

147
    colors = {
1✔
148
        PENDING: 'secondary',
149
        PLACED: 'primary',
150
        COMPLETE: 'success',
151
        CANCELLED: 'danger',
152
        LOST: 'warning',
153
        RETURNED: 'warning',
154
    }
155

156
    # Open orders
157
    OPEN = [
1✔
158
        PENDING,
159
        PLACED,
160
    ]
161

162
    # Failed orders
163
    FAILED = [
1✔
164
        CANCELLED,
165
        LOST,
166
        RETURNED
167
    ]
168

169

170
class SalesOrderStatus(StatusCode):
1✔
171
    """Defines a set of status codes for a SalesOrder."""
172

173
    PENDING = 10  # Order is pending
1✔
174
    SHIPPED = 20  # Order has been shipped to customer
1✔
175
    CANCELLED = 40  # Order has been cancelled
1✔
176
    LOST = 50  # Order was lost
1✔
177
    RETURNED = 60  # Order was returned
1✔
178

179
    options = {
1✔
180
        PENDING: _("Pending"),
181
        SHIPPED: _("Shipped"),
182
        CANCELLED: _("Cancelled"),
183
        LOST: _("Lost"),
184
        RETURNED: _("Returned"),
185
    }
186

187
    colors = {
1✔
188
        PENDING: 'secondary',
189
        SHIPPED: 'success',
190
        CANCELLED: 'danger',
191
        LOST: 'warning',
192
        RETURNED: 'warning',
193
    }
194

195
    # Open orders
196
    OPEN = [
1✔
197
        PENDING,
198
    ]
199

200
    # Completed orders
201
    COMPLETE = [
1✔
202
        SHIPPED,
203
    ]
204

205

206
class StockStatus(StatusCode):
1✔
207
    """Status codes for Stock."""
208

209
    OK = 10  # Item is OK
1✔
210
    ATTENTION = 50  # Item requires attention
1✔
211
    DAMAGED = 55  # Item is damaged
1✔
212
    DESTROYED = 60  # Item is destroyed
1✔
213
    REJECTED = 65  # Item is rejected
1✔
214
    LOST = 70  # Item has been lost
1✔
215
    QUARANTINED = 75  # Item has been quarantined and is unavailable
1✔
216
    RETURNED = 85  # Item has been returned from a customer
1✔
217

218
    options = {
1✔
219
        OK: _("OK"),
220
        ATTENTION: _("Attention needed"),
221
        DAMAGED: _("Damaged"),
222
        DESTROYED: _("Destroyed"),
223
        LOST: _("Lost"),
224
        REJECTED: _("Rejected"),
225
        QUARANTINED: _("Quarantined"),
226
        RETURNED: _("Returned"),
227
    }
228

229
    colors = {
1✔
230
        OK: 'success',
231
        ATTENTION: 'warning',
232
        DAMAGED: 'danger',
233
        DESTROYED: 'danger',
234
        LOST: 'dark',
235
        REJECTED: 'danger',
236
        QUARANTINED: 'info'
237
    }
238

239
    # The following codes correspond to parts that are 'available' or 'in stock'
240
    AVAILABLE_CODES = [
1✔
241
        OK,
242
        ATTENTION,
243
        DAMAGED,
244
        RETURNED,
245
    ]
246

247

248
class StockHistoryCode(StatusCode):
1✔
249
    """Status codes for StockHistory."""
250

251
    LEGACY = 0
1✔
252

253
    CREATED = 1
1✔
254

255
    # Manual editing operations
256
    EDITED = 5
1✔
257
    ASSIGNED_SERIAL = 6
1✔
258

259
    # Manual stock operations
260
    STOCK_COUNT = 10
1✔
261
    STOCK_ADD = 11
1✔
262
    STOCK_REMOVE = 12
1✔
263

264
    # Location operations
265
    STOCK_MOVE = 20
1✔
266

267
    # Installation operations
268
    INSTALLED_INTO_ASSEMBLY = 30
1✔
269
    REMOVED_FROM_ASSEMBLY = 31
1✔
270

271
    INSTALLED_CHILD_ITEM = 35
1✔
272
    REMOVED_CHILD_ITEM = 36
1✔
273

274
    # Stock splitting operations
275
    SPLIT_FROM_PARENT = 40
1✔
276
    SPLIT_CHILD_ITEM = 42
1✔
277

278
    # Stock merging operations
279
    MERGED_STOCK_ITEMS = 45
1✔
280

281
    # Convert stock item to variant
282
    CONVERTED_TO_VARIANT = 48
1✔
283

284
    # Build order codes
285
    BUILD_OUTPUT_CREATED = 50
1✔
286
    BUILD_OUTPUT_COMPLETED = 55
1✔
287
    BUILD_CONSUMED = 57
1✔
288

289
    # Sales order codes
290
    SHIPPED_AGAINST_SALES_ORDER = 60
1✔
291

292
    # Purchase order codes
293
    RECEIVED_AGAINST_PURCHASE_ORDER = 70
1✔
294

295
    # Return order codes
296
    RETURNED_AGAINST_RETURN_ORDER = 80
1✔
297

298
    # Customer actions
299
    SENT_TO_CUSTOMER = 100
1✔
300
    RETURNED_FROM_CUSTOMER = 105
1✔
301

302
    options = {
1✔
303
        LEGACY: _('Legacy stock tracking entry'),
304

305
        CREATED: _('Stock item created'),
306

307
        EDITED: _('Edited stock item'),
308
        ASSIGNED_SERIAL: _('Assigned serial number'),
309

310
        STOCK_COUNT: _('Stock counted'),
311
        STOCK_ADD: _('Stock manually added'),
312
        STOCK_REMOVE: _('Stock manually removed'),
313

314
        STOCK_MOVE: _('Location changed'),
315

316
        INSTALLED_INTO_ASSEMBLY: _('Installed into assembly'),
317
        REMOVED_FROM_ASSEMBLY: _('Removed from assembly'),
318

319
        INSTALLED_CHILD_ITEM: _('Installed component item'),
320
        REMOVED_CHILD_ITEM: _('Removed component item'),
321

322
        SPLIT_FROM_PARENT: _('Split from parent item'),
323
        SPLIT_CHILD_ITEM: _('Split child item'),
324

325
        MERGED_STOCK_ITEMS: _('Merged stock items'),
326

327
        CONVERTED_TO_VARIANT: _('Converted to variant'),
328

329
        SENT_TO_CUSTOMER: _('Sent to customer'),
330
        RETURNED_FROM_CUSTOMER: _('Returned from customer'),
331

332
        BUILD_OUTPUT_CREATED: _('Build order output created'),
333
        BUILD_OUTPUT_COMPLETED: _('Build order output completed'),
334
        BUILD_CONSUMED: _('Consumed by build order'),
335

336
        SHIPPED_AGAINST_SALES_ORDER: _("Shipped against Sales Order"),
337

338
        RECEIVED_AGAINST_PURCHASE_ORDER: _('Received against Purchase Order'),
339

340
        RETURNED_AGAINST_RETURN_ORDER: _('Returned against Return Order'),
341
    }
342

343

344
class BuildStatus(StatusCode):
1✔
345
    """Build status codes."""
346

347
    PENDING = 10  # Build is pending / active
1✔
348
    PRODUCTION = 20  # BuildOrder is in production
1✔
349
    CANCELLED = 30  # Build was cancelled
1✔
350
    COMPLETE = 40  # Build is complete
1✔
351

352
    options = {
1✔
353
        PENDING: _("Pending"),
354
        PRODUCTION: _("Production"),
355
        CANCELLED: _("Cancelled"),
356
        COMPLETE: _("Complete"),
357
    }
358

359
    colors = {
1✔
360
        PENDING: 'secondary',
361
        PRODUCTION: 'primary',
362
        COMPLETE: 'success',
363
        CANCELLED: 'danger',
364
    }
365

366
    ACTIVE_CODES = [
1✔
367
        PENDING,
368
        PRODUCTION,
369
    ]
370

371

372
class ReturnOrderStatus(StatusCode):
1✔
373
    """Defines a set of status codes for a ReturnOrder"""
374

375
    # Order is pending, waiting for receipt of items
376
    PENDING = 10
1✔
377

378
    # Items have been received, and are being inspected
379
    IN_PROGRESS = 20
1✔
380

381
    COMPLETE = 30
1✔
382
    CANCELLED = 40
1✔
383

384
    OPEN = [
1✔
385
        PENDING,
386
        IN_PROGRESS,
387
    ]
388

389
    options = {
1✔
390
        PENDING: _("Pending"),
391
        IN_PROGRESS: _("In Progress"),
392
        COMPLETE: _("Complete"),
393
        CANCELLED: _("Cancelled"),
394
    }
395

396
    colors = {
1✔
397
        PENDING: 'secondary',
398
        IN_PROGRESS: 'primary',
399
        COMPLETE: 'success',
400
        CANCELLED: 'danger',
401
    }
402

403

404
class ReturnOrderLineStatus(StatusCode):
1✔
405
    """Defines a set of status codes for a ReturnOrderLineItem"""
406

407
    PENDING = 10
1✔
408

409
    # Item is to be returned to customer, no other action
410
    RETURN = 20
1✔
411

412
    # Item is to be repaired, and returned to customer
413
    REPAIR = 30
1✔
414

415
    # Item is to be replaced (new item shipped)
416
    REPLACE = 40
1✔
417

418
    # Item is to be refunded (cannot be repaired)
419
    REFUND = 50
1✔
420

421
    # Item is rejected
422
    REJECT = 60
1✔
423

424
    options = {
1✔
425
        PENDING: _('Pending'),
426
        RETURN: _('Return'),
427
        REPAIR: _('Repair'),
428
        REFUND: _('Refund'),
429
        REPLACE: _('Replace'),
430
        REJECT: _('Reject')
431
    }
432

433
    colors = {
1✔
434
        PENDING: 'secondary',
435
        RETURN: 'success',
436
        REPAIR: 'primary',
437
        REFUND: 'info',
438
        REPLACE: 'warning',
439
        REJECT: 'danger',
440
    }
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc