Coverage for src/backend/InvenTree/report/mixins.py: 90%

10 statements  

« prev     ^ index     » next       coverage.py v7.15.2, created at 2026-10-07 17:47 +0000

1"""Report mixin classes.""" 

2 

3from typing import Generic, TypedDict, TypeVar 

4 

5from django.db import models 

6 

7_Model = TypeVar('_Model', bound=models.Model, covariant=True) 

8 

9 

10class QuerySet(Generic[_Model]): 

11 """A custom QuerySet class used for type hinting in report context definitions. 

12 

13 This will later be replaced by django.db.models.QuerySet, but as 

14 django's QuerySet is not a generic class, we need to create our own to not 

15 loose type data. 

16 """ 

17 

18 

19class BaseReportContext(TypedDict): 

20 """Base context for a report model.""" 

21 

22 

23class InvenTreeReportMixin(models.Model): 

24 """A mixin class for adding report generation functionality to a model class. 

25 

26 In addition to exposing the model to the report generation interface, 

27 this mixin provides a hook for providing extra context information to the reports. 

28 """ 

29 

30 class Meta: 

31 """Metaclass options for this mixin.""" 

32 

33 abstract = True 

34 

35 def report_context(self) -> BaseReportContext: 

36 """Generate a dict of context data to provide to the reporting framework. 

37 

38 The default implementation returns an empty dict object. 

39 

40 This method must contain a type annotation, as it is used by the report generation framework 

41 to determine the type of context data that is provided to the report template. 

42 

43 Example: 

44 ```python 

45 class MyModelReportContext(BaseReportContext): 

46 my_field: str 

47 po: order.models.PurchaseOrder 

48 bom_items: report.mixins.QuerySet[part.models.BomItem] 

49 

50 class MyModel(report.mixins.InvenTreeReportMixin): 

51 ... 

52 def report_context(self) -> MyModelReportContext: 

53 return { 

54 'my_field': self.my_field, 

55 'po': self.po, 

56 } 

57 ``` 

58 """ 

59 return {}