inventree-manufacturing-costs 0.1.0__py3-none-any.whl

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.
@@ -0,0 +1,102 @@
1
+ Metadata-Version: 2.4
2
+ Name: inventree-manufacturing-costs
3
+ Version: 0.1.0
4
+ Summary: Capture part manufacturing costs
5
+ Home-page: https://github.com/SchrodingersGat/inventree-manufacturing-costs
6
+ Author: Oliver Walters
7
+ Author-email: oliver.henry.walters@gmail.com
8
+ License: MIT
9
+ Keywords: inventree plugin
10
+ Classifier: Programming Language :: Python :: 3
11
+ Classifier: Operating System :: OS Independent
12
+ Classifier: Framework :: InvenTree
13
+ Requires-Python: >=3.9
14
+ Description-Content-Type: text/markdown
15
+ License-File: LICENSE
16
+ Dynamic: author
17
+ Dynamic: author-email
18
+ Dynamic: classifier
19
+ Dynamic: description
20
+ Dynamic: description-content-type
21
+ Dynamic: home-page
22
+ Dynamic: keywords
23
+ Dynamic: license
24
+ Dynamic: license-file
25
+ Dynamic: requires-python
26
+ Dynamic: summary
27
+
28
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
29
+ [![PyPI](https://img.shields.io/pypi/v/inventree-manufacturing-costs)](https://pypi.org/project/inventree-manufacturing-costs/)
30
+ ![PEP](https://github.com/SchrodingersGat/inventree-manufacturing-costs/actions/workflows/ci.yaml/badge.svg)
31
+
32
+
33
+ # InvenTree Manufacturing Costs
34
+
35
+ An [InvenTree](https://inventree.org) plugin for capturing and managing manufacturing costs.
36
+
37
+ ## Description
38
+
39
+ InvenTree provides tracking of raw material costs via Bills of Materials (BOMs). However, there are a number of additional costs associated with manufacturing a part which are not captured in the BOM structure. This plugin provides a framework for capturing and managing these additional costs, which may include:
40
+
41
+ - Labor costs
42
+ - Machine costs
43
+ - Overhead costs
44
+ - Processing costs
45
+ - Other miscellaneous costs
46
+
47
+ These costs are typically not captured in the BOM structure, but are important for accurate cost accounting and pricing.
48
+
49
+ ### Manufacturing Rate
50
+
51
+ Multiple pre-defined manufacturing rates can be created, which capture the cost per unit time for a given process. For example, a CNC machine may have a cost of $50 per hour, while a manual assembly process may have a labor cost of $20 per hour.
52
+
53
+ These rates can be stored in the database, and assigned to specific manufacturing cost entries. This is useful for capturing recurring costs associated with time-based processes, and allows for easy updating of rates as costs change over time.
54
+
55
+ ### Manufacturing Cost
56
+
57
+ A manufacturing cost captures a specific cost associated with the manufacturing of a particular assembly. This may include labor costs, machine costs, overhead costs, or other miscellaneous costs.
58
+
59
+ Each manufacturing cost may be associated with a specific manufacturing rate, allowing the cost to be calculated based on the rate required for the process. Alternatively, a fixed cost may be specified directly.
60
+
61
+ ## Installation
62
+
63
+ ### Via User Interface
64
+
65
+ The simplest way to install this plugin is from the InvenTree plugin interface. Enter the plugin name (`inventree-manufacturing-costs`) and click the `Install` button:
66
+
67
+ ![Install Plugin](docs/img/install.png)
68
+
69
+ ### Command Line
70
+
71
+ To install manually via the command line, run the following command (ensuring you have access to the appropriate Python environment):
72
+
73
+ ```bash
74
+ pip install -U inventree-manufacturing-costs
75
+ ```
76
+
77
+ *Note: After the plugin is installed, it must be activated via the InvenTree plugin interface.*
78
+
79
+ ## Usage
80
+
81
+ ### Manufacturing Rates
82
+
83
+ To manage manufacturing rates, navigate to the "Manufacturing Rates" section in the InvenTree admin center. Here, you can create, edit, and delete manufacturing rates as needed:
84
+
85
+ ![Manufacturing Rates](docs/img/manufacturing_rates.png)
86
+
87
+ ### Manufacturing Costs
88
+
89
+ Manufacturing costs are associated with specified assemblies. To view or edit manufacturing costs for a specific part, navigate to the part detail page and select the "Manufacturing Costs" tab:
90
+
91
+ ![Manufacturing Costs](docs/img/manufacturing_costs.png)
92
+
93
+ Note that this table only displays the manufacturing costs directly associated with the selected assembly. Costs associated with sub-assemblies are not displayed here - however these costs are included when exporting manufacturing costs (see below).
94
+
95
+ ### Exporting Manufacturing Costs
96
+
97
+ Manufacturing costs can be exported to a CSV file for further analysis or reporting. To export manufacturing costs, click the "Export" button on the "Manufacturing Costs" tab for the desired assembly.
98
+
99
+ Exporting manufacturing costs will include all costs associated with the selected assembly, as well as manufacturing costs associated with any sub-assemblies.
100
+
101
+ This information can be used (in association with BOM cost information) to calculate the total cost of manufacturing a given assembly.
102
+
@@ -0,0 +1,25 @@
1
+ inventree_manufacturing_costs-0.1.0.dist-info/licenses/LICENSE,sha256=4YPRs7DCPobmZTuCAvlCstDV6C-5y2i1h10ZoLJEVIQ,1113
2
+ manufacturing_costs/__init__.py,sha256=AamVBjEe3jzcFGrwK_0mC4sI1NjzOOLvT9k7BvLzj7E,50
3
+ manufacturing_costs/admin.py,sha256=bMGhhEY8hVv3i4uBL2ojxYJ_3zwyj1lvsoIQE2LA6yE,573
4
+ manufacturing_costs/apps.py,sha256=unF9_8OIa3uFSXqg5V0Nvn9np1FRNhJ5YT6D27m3SBA,349
5
+ manufacturing_costs/core.py,sha256=vlNKEQW351o4pRNokAMUi2QL51PyF5bX-1uNmd6ODNQ,3691
6
+ manufacturing_costs/models.py,sha256=mGa2ZMqjb_k5Uzu2DH71fNDUX1CoC9ld-XQKnlBK-yk,4563
7
+ manufacturing_costs/serializers.py,sha256=2YwgJUt-ptw8wkHQekrVqLU5yKz6c-kBj701sqfRfpU,3824
8
+ manufacturing_costs/views.py,sha256=zfuge8Ld6Ao-G9LRf4FbtNu1E3DzuoY19xElRjtK4IE,8049
9
+ manufacturing_costs/migrations/0001_initial.py,sha256=yd-Jqj3I9tyA_2EgDtFwUIXigjasbalMv_VlLDv0G-k,5938
10
+ manufacturing_costs/migrations/0002_remove_manufacturingcost_amortization_and_more.py,sha256=6ussQD7A-ermRPSC_0vhykVJTvPXIx-91GfyMv9vs8Y,1317
11
+ manufacturing_costs/migrations/0003_manufacturingcost_description.py,sha256=IWpOnkF1MFEg1Y-89k0i9risrbkfOyt8padmsqgZek8,612
12
+ manufacturing_costs/migrations/0004_manufacturingcost_active_manufacturingcost_inherited.py,sha256=T9irGk3uyOWK92kBuyzGZ1xg0smiUAa4fNGcZhoPknY,879
13
+ manufacturing_costs/migrations/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
14
+ manufacturing_costs/static/AdminPanel.js,sha256=ewTLiqoVmV-SHgh6Ik5ldHirgFgVh-kyXEvga89s4Gs,6517
15
+ manufacturing_costs/static/AdminPanel.js.map,sha256=v-no9UGHO4fLsRq7Gx0o2Z4ZspkdFxnKk12c6ylpfMs,10264
16
+ manufacturing_costs/static/PartPanel.js,sha256=7NWGEfo4zIivOGsYq5k8mIVlQWgM7Th0cH-vhE_Ucfs,13452
17
+ manufacturing_costs/static/PartPanel.js.map,sha256=QKi7esyDSTRziwR8YIucVIV5DrjdyvooMOwGQww5WOs,22449
18
+ manufacturing_costs/static/.vite/manifest.json,sha256=sPjDhV7inyCutMv5CdF4L1eJ-aAY9dluFawTqNn_fLs,469
19
+ manufacturing_costs/static/assets/index-BjwOiYns.js,sha256=-kOOgzd0zZYg5BhUnvpmwWr3rsWaT0Jcb2eqqD2v39o,133966
20
+ manufacturing_costs/static/assets/index-BjwOiYns.js.map,sha256=CbVdlj6F8RLHq_BC5pMKsDp-dIL2YKJKdOhklbGNNg4,261945
21
+ inventree_manufacturing_costs-0.1.0.dist-info/METADATA,sha256=6RevFyqJEH1nVAAE9g26Y-GJkzgSJ4Iyaj7CaOEIU0w,4613
22
+ inventree_manufacturing_costs-0.1.0.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
23
+ inventree_manufacturing_costs-0.1.0.dist-info/entry_points.txt,sha256=17UEkeIVDI3oA1Z2mCotfEgBkVCmwjCsc5lYja9Wvgc,85
24
+ inventree_manufacturing_costs-0.1.0.dist-info/top_level.txt,sha256=eKb1KtNZpbFJo_iKMuZSjmnfqdSmp0-C3_Iw79RO3NY,20
25
+ inventree_manufacturing_costs-0.1.0.dist-info/RECORD,,
@@ -0,0 +1,5 @@
1
+ Wheel-Version: 1.0
2
+ Generator: setuptools (80.9.0)
3
+ Root-Is-Purelib: true
4
+ Tag: py3-none-any
5
+
@@ -0,0 +1,2 @@
1
+ [inventree_plugins]
2
+ ManufacturingCosts = manufacturing_costs.core:ManufacturingCosts
@@ -0,0 +1,21 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2025 Oliver Walters <oliver.henry.walters@gmail.com>
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in
13
+ all copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
+ THE SOFTWARE.
@@ -0,0 +1 @@
1
+ manufacturing_costs
@@ -0,0 +1,3 @@
1
+ # -*- coding: utf-8 -*-
2
+
3
+ PLUGIN_VERSION = "0.1.0"
@@ -0,0 +1,23 @@
1
+ """Admin site configuration for the ManufacturingCosts plugin."""
2
+
3
+ from django.contrib import admin
4
+
5
+ from .models import ManufacturingRate, ManufacturingCost
6
+
7
+
8
+ @admin.register(ManufacturingRate)
9
+ class ManufacturingRateAdmin(admin.ModelAdmin):
10
+ """Admin interface for the ManufacturingRate."""
11
+
12
+ list_display = ("name", "description", "price")
13
+
14
+
15
+ @admin.register(ManufacturingCost)
16
+ class ManufacturingCostAdmin(admin.ModelAdmin):
17
+ """Admin interface for the ManufacturingCost model."""
18
+
19
+ list_display = (
20
+ "part",
21
+ "rate",
22
+ "quantity",
23
+ )
@@ -0,0 +1,13 @@
1
+ """Django config for the ManufacturingCosts plugin."""
2
+
3
+ from django.apps import AppConfig
4
+
5
+
6
+ class ManufacturingCostsConfig(AppConfig):
7
+ """Config class for the ManufacturingCosts plugin."""
8
+
9
+ name = "manufacturing_costs"
10
+
11
+ def ready(self):
12
+ """This function is called whenever the ManufacturingCosts plugin is loaded."""
13
+ ...
@@ -0,0 +1,118 @@
1
+ """Capture part manufacturing costs"""
2
+
3
+ from django.contrib.auth.models import Group
4
+ from django.utils.translation import gettext_lazy as _
5
+
6
+ from plugin import InvenTreePlugin
7
+
8
+ from plugin.mixins import AppMixin, SettingsMixin, UrlsMixin, UserInterfaceMixin
9
+
10
+ from . import PLUGIN_VERSION
11
+
12
+
13
+ class ManufacturingCosts(
14
+ AppMixin, SettingsMixin, UrlsMixin, UserInterfaceMixin, InvenTreePlugin
15
+ ):
16
+ """ManufacturingCosts - custom InvenTree plugin."""
17
+
18
+ # Plugin metadata
19
+ TITLE = "Manufacturing Costs"
20
+ NAME = "ManufacturingCosts"
21
+ SLUG = "manufacturing-costs"
22
+ DESCRIPTION = "Capture part manufacturing costs"
23
+ VERSION = PLUGIN_VERSION
24
+
25
+ # Additional project information
26
+ AUTHOR = "Oliver Walters"
27
+ WEBSITE = "https://github.com/SchrodingersGat/inventree-manufacturing-costs"
28
+ LICENSE = "MIT"
29
+
30
+ MIN_VERSION = "0.18.0"
31
+
32
+ # Plugin settings (from SettingsMixin)
33
+ SETTINGS = {
34
+ "USER_GROUP": {
35
+ "name": _("Allowed Group"),
36
+ "description": _(
37
+ "The user group that is allowed to view manufacturing costs"
38
+ ),
39
+ "model": "auth.group",
40
+ }
41
+ }
42
+
43
+ def setup_urls(self):
44
+ """Configure custom URL endpoints for this plugin."""
45
+ from .views import construct_urls
46
+
47
+ return construct_urls()
48
+
49
+ def is_user_allowed(self, request):
50
+ """Check if the user is allowed to view manufacturing costs."""
51
+ if user_group_id := self.get_setting("USER_GROUP", backup_value=None):
52
+ user_group = Group.objects.filter(id=user_group_id).first()
53
+
54
+ if user_group is not None and user_group not in request.user.groups.all():
55
+ return False
56
+
57
+ return True
58
+
59
+ def get_part_panels(self, part_id: int, request):
60
+ """Return the custom part panel component for this plugin."""
61
+
62
+ from part.models import Part
63
+
64
+ if not part_id:
65
+ return []
66
+
67
+ try:
68
+ instance = Part.objects.get(pk=part_id)
69
+ except (Part.DoesNotExist, ValueError):
70
+ return []
71
+
72
+ if not instance.assembly:
73
+ # If the part is not an assembly, do not display the panel
74
+ return []
75
+
76
+ return [
77
+ {
78
+ "key": "manufacturing-costs",
79
+ "title": "Manufacturing Costs",
80
+ "description": "Part manufacturing costs",
81
+ "icon": "ti:clock-dollar:outline",
82
+ "source": self.plugin_static_file("PartPanel.js:renderPartPanel"),
83
+ }
84
+ ]
85
+
86
+ def get_admin_panels(self, request):
87
+ """Return the custom admin panel component for this plugin."""
88
+
89
+ return [
90
+ {
91
+ "key": "manufacturing-costs",
92
+ "title": "Manufacturing Rates",
93
+ "description": "Part manufacturing rates",
94
+ "icon": "ti:clock-dollar:outline",
95
+ "source": self.plugin_static_file("AdminPanel.js:renderAdminPanel"),
96
+ }
97
+ ]
98
+
99
+ # Custom UI panels
100
+ def get_ui_panels(self, request, context: dict, **kwargs):
101
+ """Return a list of custom panels to be rendered in the InvenTree user interface."""
102
+
103
+ # Check if user is allowed to view this plugin
104
+ if not self.is_user_allowed(request):
105
+ return []
106
+
107
+ target_model = context.get("target_model", None)
108
+ target_id = context.get("target_id", None)
109
+
110
+ if target_model == "admincenter":
111
+ return self.get_admin_panels(request)
112
+
113
+ if target_model == "part":
114
+ target_id = context.get("target_id", None)
115
+ return self.get_part_panels(target_id, request)
116
+
117
+ # Nothing to do
118
+ return []
@@ -0,0 +1,163 @@
1
+ # Generated by Django 4.2.22 on 2025-07-09 06:11
2
+
3
+ import InvenTree.fields
4
+ import django.core.validators
5
+ from django.db import migrations, models
6
+ import django.db.models.deletion
7
+ import djmoney.models.fields
8
+ import djmoney.models.validators
9
+
10
+
11
+ class Migration(migrations.Migration):
12
+ initial = True
13
+
14
+ dependencies = []
15
+
16
+ operations = [
17
+ migrations.CreateModel(
18
+ name="ManufacturingRate",
19
+ fields=[
20
+ (
21
+ "id",
22
+ models.AutoField(
23
+ auto_created=True,
24
+ primary_key=True,
25
+ serialize=False,
26
+ verbose_name="ID",
27
+ ),
28
+ ),
29
+ (
30
+ "name",
31
+ models.CharField(
32
+ help_text="Name of the manufacturing rate",
33
+ max_length=100,
34
+ unique=True,
35
+ verbose_name="Name",
36
+ ),
37
+ ),
38
+ (
39
+ "description",
40
+ models.CharField(
41
+ help_text="Description of the manufacturing rate",
42
+ max_length=200,
43
+ verbose_name="Description",
44
+ ),
45
+ ),
46
+ (
47
+ "units",
48
+ models.CharField(
49
+ blank=True,
50
+ help_text="Units for the manufacturing rate",
51
+ max_length=50,
52
+ verbose_name="Units",
53
+ ),
54
+ ),
55
+ (
56
+ "price_currency",
57
+ djmoney.models.fields.CurrencyField(
58
+ choices=[], default="", editable=False, max_length=3
59
+ ),
60
+ ),
61
+ (
62
+ "price",
63
+ InvenTree.fields.InvenTreeModelMoneyField(
64
+ currency_choices=[],
65
+ decimal_places=6,
66
+ default_currency="",
67
+ help_text="Manufacturing rate cost",
68
+ max_digits=19,
69
+ validators=[djmoney.models.validators.MinMoneyValidator(0)],
70
+ verbose_name="Cost",
71
+ ),
72
+ ),
73
+ ],
74
+ ),
75
+ migrations.CreateModel(
76
+ name="ManufacturingCost",
77
+ fields=[
78
+ (
79
+ "id",
80
+ models.AutoField(
81
+ auto_created=True,
82
+ primary_key=True,
83
+ serialize=False,
84
+ verbose_name="ID",
85
+ ),
86
+ ),
87
+ (
88
+ "quantity",
89
+ models.DecimalField(
90
+ decimal_places=6,
91
+ default=1,
92
+ help_text="Quantity of the part for which this cost applies",
93
+ max_digits=19,
94
+ verbose_name="Quantity",
95
+ ),
96
+ ),
97
+ (
98
+ "unit_cost_currency",
99
+ djmoney.models.fields.CurrencyField(
100
+ choices=[], default="", editable=False, max_length=3, null=True
101
+ ),
102
+ ),
103
+ (
104
+ "unit_cost",
105
+ InvenTree.fields.InvenTreeModelMoneyField(
106
+ blank=True,
107
+ currency_choices=[],
108
+ decimal_places=6,
109
+ default_currency="",
110
+ help_text="Cost of manufacturing this part",
111
+ max_digits=19,
112
+ null=True,
113
+ validators=[djmoney.models.validators.MinMoneyValidator(0)],
114
+ verbose_name="Cost",
115
+ ),
116
+ ),
117
+ (
118
+ "notes",
119
+ models.CharField(
120
+ blank=True,
121
+ help_text="Additional notes about this manufacturing cost",
122
+ max_length=200,
123
+ verbose_name="Notes",
124
+ ),
125
+ ),
126
+ (
127
+ "amortization",
128
+ models.PositiveIntegerField(
129
+ default=1,
130
+ help_text="Part quantity over which the cost is amortized",
131
+ validators=[
132
+ django.core.validators.MinValueValidator(
133
+ 1, "Amortization quantity must be at least 1"
134
+ )
135
+ ],
136
+ verbose_name="Amortization Quantity",
137
+ ),
138
+ ),
139
+ (
140
+ "part",
141
+ models.ForeignKey(
142
+ help_text="The part associated with this manufacturing cost",
143
+ on_delete=django.db.models.deletion.CASCADE,
144
+ related_name="manufacturing_costs",
145
+ to="part.part",
146
+ verbose_name="Part",
147
+ ),
148
+ ),
149
+ (
150
+ "rate",
151
+ models.ForeignKey(
152
+ help_text="The manufacturing rate used for this cost",
153
+ null=True,
154
+ blank=True,
155
+ on_delete=django.db.models.deletion.CASCADE,
156
+ related_name="manufacturing_costs",
157
+ to="manufacturing_costs.manufacturingrate",
158
+ verbose_name="Manufacturing Rate",
159
+ ),
160
+ ),
161
+ ],
162
+ ),
163
+ ]
@@ -0,0 +1,43 @@
1
+ # Generated by Django 4.2.23 on 2025-09-02 11:14
2
+
3
+ from django.conf import settings
4
+ from django.db import migrations, models
5
+ import django.db.models.deletion
6
+
7
+
8
+ class Migration(migrations.Migration):
9
+ dependencies = [
10
+ migrations.swappable_dependency(settings.AUTH_USER_MODEL),
11
+ ("manufacturing_costs", "0001_initial"),
12
+ ]
13
+
14
+ operations = [
15
+ migrations.RemoveField(
16
+ model_name="manufacturingcost",
17
+ name="amortization",
18
+ ),
19
+ migrations.AddField(
20
+ model_name="manufacturingcost",
21
+ name="updated",
22
+ field=models.DateTimeField(
23
+ blank=True,
24
+ default=None,
25
+ help_text="Timestamp of last update",
26
+ null=True,
27
+ verbose_name="Updated",
28
+ ),
29
+ ),
30
+ migrations.AddField(
31
+ model_name="manufacturingcost",
32
+ name="updated_by",
33
+ field=models.ForeignKey(
34
+ blank=True,
35
+ help_text="User who last updated this object",
36
+ null=True,
37
+ on_delete=django.db.models.deletion.SET_NULL,
38
+ related_name="%(class)s_updated",
39
+ to=settings.AUTH_USER_MODEL,
40
+ verbose_name="Update By",
41
+ ),
42
+ ),
43
+ ]
@@ -0,0 +1,22 @@
1
+ # Generated by Django 4.2.23 on 2025-09-02 11:31
2
+
3
+ from django.db import migrations, models
4
+
5
+
6
+ class Migration(migrations.Migration):
7
+ dependencies = [
8
+ ("manufacturing_costs", "0002_remove_manufacturingcost_amortization_and_more"),
9
+ ]
10
+
11
+ operations = [
12
+ migrations.AddField(
13
+ model_name="manufacturingcost",
14
+ name="description",
15
+ field=models.CharField(
16
+ blank=True,
17
+ help_text="Description of this manufacturing cost",
18
+ max_length=200,
19
+ verbose_name="Description",
20
+ ),
21
+ ),
22
+ ]
@@ -0,0 +1,31 @@
1
+ # Generated by Django 5.2.8 on 2025-11-11 08:43
2
+
3
+ from django.db import migrations, models
4
+
5
+
6
+ class Migration(migrations.Migration):
7
+
8
+ dependencies = [
9
+ ("manufacturing_costs", "0003_manufacturingcost_description"),
10
+ ]
11
+
12
+ operations = [
13
+ migrations.AddField(
14
+ model_name="manufacturingcost",
15
+ name="active",
16
+ field=models.BooleanField(
17
+ default=True,
18
+ help_text="Is this manufacturing cost active?",
19
+ verbose_name="Active",
20
+ ),
21
+ ),
22
+ migrations.AddField(
23
+ model_name="manufacturingcost",
24
+ name="inherited",
25
+ field=models.BooleanField(
26
+ default=False,
27
+ help_text="Is this manufacturing cost inherited by variant parts?",
28
+ verbose_name="Inherited",
29
+ ),
30
+ ),
31
+ ]
File without changes