Coverage for src/backend/InvenTree/plugin/builtin/events/auto_issue_orders.py: 30%

53 statements  

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

1"""Plugin to automatically issue orders on the assigned target date.""" 

2 

3from django.utils.translation import gettext_lazy as _ 

4 

5import structlog 

6 

7from InvenTree.helpers import current_date 

8from plugin import InvenTreePlugin 

9from plugin.mixins import ScheduleMixin, SettingsMixin 

10 

11logger = structlog.get_logger('inventree') 

12 

13 

14class AutoIssueOrdersPlugin(ScheduleMixin, SettingsMixin, InvenTreePlugin): 

15 """Plugin to automatically issue orders on the assigned target date.""" 

16 

17 NAME = _('Auto Issue Orders') 

18 SLUG = 'autoiissueorders' 

19 AUTHOR = _('InvenTree contributors') 

20 DESCRIPTION = _('Automatically issue orders on the assigned target date') 

21 VERSION = '1.0.0' 

22 

23 # Set the scheduled tasks for this plugin 

24 SCHEDULED_TASKS = { 

25 'auto_issue_orders': {'func': 'auto_issue_orders', 'schedule': 'D'} 

26 } 

27 

28 SETTINGS = { 

29 'AUTO_ISSUE_BUILD_ORDERS': { 

30 'name': _('Auto Issue Build Orders'), 

31 'description': _( 

32 'Automatically issue build orders on the assigned target date' 

33 ), 

34 'validator': bool, 

35 'default': True, 

36 }, 

37 'AUTO_ISSUE_PURCHASE_ORDERS': { 

38 'name': _('Auto Issue Purchase Orders'), 

39 'description': _( 

40 'Automatically issue purchase orders on the assigned target date' 

41 ), 

42 'validator': bool, 

43 'default': True, 

44 }, 

45 'AUTO_ISSUE_SALES_ORDERS': { 

46 'name': _('Auto Issue Sales Orders'), 

47 'description': _( 

48 'Automatically issue sales orders on the assigned target date' 

49 ), 

50 'validator': bool, 

51 'default': True, 

52 }, 

53 'AUTO_ISSUE_RETURN_ORDERS': { 

54 'name': _('Auto Issue Return Orders'), 

55 'description': _( 

56 'Automatically issue return orders on the assigned target date' 

57 ), 

58 'validator': bool, 

59 'default': True, 

60 }, 

61 'ISSUE_BACKDATED_ORDERS': { 

62 'name': _('Issue Backdated Orders'), 

63 'description': _('Automatically issue orders that are backdated'), 

64 'validator': bool, 

65 'default': False, 

66 }, 

67 } 

68 

69 def auto_issue_orders(self): 

70 """Automatically issue orders on the assigned target date.""" 

71 if self.get_setting('AUTO_ISSUE_BUILD_ORDERS', backup_value=True): 

72 self.auto_issue_build_orders() 

73 

74 if self.get_setting('AUTO_ISSUE_PURCHASE_ORDERS', backup_value=True): 

75 self.auto_issue_purchase_orders() 

76 

77 if self.get_setting('AUTO_ISSUE_SALES_ORDERS', backup_value=True): 

78 self.auto_issue_sales_orders() 

79 

80 if self.get_setting('AUTO_ISSUE_RETURN_ORDERS', backup_value=True): 

81 self.auto_issue_return_orders() 

82 

83 def issue_func(self, model, status: int, func_name: str = 'issue_order'): 

84 """Helper function to issue orders of a given model and status.""" 

85 orders = model.objects.filter(status=status) 

86 orders = orders.filter(target_date__isnull=False) 

87 

88 if self.get_setting('ISSUE_BACKDATED_ORDERS', backup_value=False): 

89 orders = orders.filter(target_date__lte=current_date()) 

90 else: 

91 orders = orders.filter(target_date=current_date()) 

92 

93 if orders.count() == 0: 

94 return 

95 

96 logger.info('Auto-issuing %d orders for %s', orders.count(), model.__name__) 

97 

98 for order in orders: 

99 try: 

100 getattr(order, func_name)() 

101 except Exception as e: 

102 logger.error('Failed to issue order %s: %s', order.pk, e) 

103 

104 def auto_issue_build_orders(self): 

105 """Automatically issue build orders on the assigned target date.""" 

106 from build.models import Build 

107 from build.status_codes import BuildStatus 

108 

109 self.issue_func(Build, BuildStatus.PENDING, func_name='issue_build') 

110 

111 def auto_issue_purchase_orders(self): 

112 """Automatically issue purchase orders on the assigned target date.""" 

113 from order.models import PurchaseOrder 

114 from order.status_codes import PurchaseOrderStatus 

115 

116 self.issue_func(PurchaseOrder, PurchaseOrderStatus.PENDING) 

117 

118 def auto_issue_sales_orders(self): 

119 """Automatically issue sales orders on the assigned target date.""" 

120 from order.models import SalesOrder 

121 from order.status_codes import SalesOrderStatus 

122 

123 self.issue_func(SalesOrder, SalesOrderStatus.PENDING) 

124 

125 def auto_issue_return_orders(self): 

126 """Automatically issue return orders on the assigned target date.""" 

127 from order.models import ReturnOrder 

128 from order.status_codes import ReturnOrderStatus 

129 

130 self.issue_func(ReturnOrder, ReturnOrderStatus.PENDING)