django-bom 1.252__py3-none-any.whl → 1.258__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.
- bom/admin.py +52 -12
- bom/constants.py +7 -0
- bom/csv_headers.py +22 -44
- bom/forms.py +966 -1019
- bom/helpers.py +79 -4
- bom/migrations/0052_remove_partrevision_attribute_and_more.py +584 -0
- bom/models.py +191 -80
- bom/static/bom/css/style.css +19 -0
- bom/static/bom/js/formset-handler.js +65 -0
- bom/templates/bom/edit-part-class.html +98 -11
- bom/templates/bom/edit-quantity-of-measure.html +119 -0
- bom/templates/bom/edit-user-meta.html +58 -26
- bom/templates/bom/part-info.html +10 -1
- bom/templates/bom/part-revision-display.html +22 -159
- bom/templates/bom/settings.html +138 -11
- bom/tests.py +117 -31
- bom/urls.py +6 -0
- bom/views/views.py +179 -42
- {django_bom-1.252.dist-info → django_bom-1.258.dist-info}/METADATA +1 -1
- {django_bom-1.252.dist-info → django_bom-1.258.dist-info}/RECORD +23 -20
- {django_bom-1.252.dist-info → django_bom-1.258.dist-info}/WHEEL +0 -0
- {django_bom-1.252.dist-info → django_bom-1.258.dist-info}/licenses/LICENSE +0 -0
- {django_bom-1.252.dist-info → django_bom-1.258.dist-info}/top_level.txt +0 -0
bom/views/views.py
CHANGED
|
@@ -47,10 +47,14 @@ from bom.forms import (
|
|
|
47
47
|
PartInfoForm,
|
|
48
48
|
PartRevisionForm,
|
|
49
49
|
PartRevisionNewForm,
|
|
50
|
+
PartRevisionPropertyDefinitionForm,
|
|
51
|
+
PartRevisionPropertyDefinitionFormSet,
|
|
52
|
+
QuantityOfMeasureForm,
|
|
50
53
|
Seller,
|
|
51
54
|
SellerForm,
|
|
52
55
|
SellerPartForm,
|
|
53
56
|
SubpartForm,
|
|
57
|
+
UnitDefinitionFormSet,
|
|
54
58
|
UploadBOMForm,
|
|
55
59
|
UserAddForm,
|
|
56
60
|
UserCreateForm,
|
|
@@ -66,8 +70,11 @@ from bom.models import (
|
|
|
66
70
|
Part,
|
|
67
71
|
PartClass,
|
|
68
72
|
PartRevision,
|
|
73
|
+
PartRevisionPropertyDefinition,
|
|
74
|
+
QuantityOfMeasure,
|
|
69
75
|
SellerPart,
|
|
70
76
|
Subpart,
|
|
77
|
+
UnitDefinition,
|
|
71
78
|
User,
|
|
72
79
|
get_user_meta_model
|
|
73
80
|
)
|
|
@@ -245,7 +252,7 @@ def home(request):
|
|
|
245
252
|
for field_name in csv_headers.get_default_all():
|
|
246
253
|
if field_name not in csv_headers.get_defaults_list(['part_number', 'part_category', 'part_synopsis', 'part_revision', 'part_manufacturer', 'part_manufacturer_part_number', ]
|
|
247
254
|
+ seller_csv_headers.get_default_all()):
|
|
248
|
-
attr =
|
|
255
|
+
attr = part_rev.get_field_value(field_name)
|
|
249
256
|
row.update({csv_headers.get_default(field_name): attr if attr is not None else ''})
|
|
250
257
|
else:
|
|
251
258
|
row = {
|
|
@@ -258,7 +265,7 @@ def home(request):
|
|
|
258
265
|
for field_name in csv_headers.get_default_all():
|
|
259
266
|
if field_name not in csv_headers.get_defaults_list(['part_number', 'part_synopsis', 'part_revision', 'part_manufacturer', 'part_manufacturer_part_number', ]
|
|
260
267
|
+ seller_csv_headers.get_default_all()):
|
|
261
|
-
attr =
|
|
268
|
+
attr = part_rev.get_field_value(field_name)
|
|
262
269
|
row.update({csv_headers.get_default(field_name): attr if attr is not None else ''})
|
|
263
270
|
|
|
264
271
|
sellerparts = part_rev.part.seller_parts()
|
|
@@ -356,6 +363,9 @@ def bom_settings(request, tab_anchor=None):
|
|
|
356
363
|
name = 'settings'
|
|
357
364
|
|
|
358
365
|
part_classes = PartClass.objects.all().filter(organization=organization)
|
|
366
|
+
property_definitions = PartRevisionPropertyDefinition.objects.available_to(organization=organization).order_by(
|
|
367
|
+
'name')
|
|
368
|
+
quantities_of_measure = QuantityOfMeasure.objects.available_to(organization=organization).order_by('name')
|
|
359
369
|
|
|
360
370
|
users_in_organization = User.objects.filter(
|
|
361
371
|
id__in=UserMeta.objects.filter(organization=organization).values_list('user', flat=True)).order_by(
|
|
@@ -395,6 +405,9 @@ def bom_settings(request, tab_anchor=None):
|
|
|
395
405
|
messages.error(request, "You need a Pro subscription to add users.")
|
|
396
406
|
elif not user_can_manage_members:
|
|
397
407
|
messages.error(request, "You are not allowed to manage users, contact your organization admin.")
|
|
408
|
+
elif not has_member_capacity:
|
|
409
|
+
messages.error(request,
|
|
410
|
+
"You have reached your organization's member capacity. Manage subscription to add more members.")
|
|
398
411
|
else:
|
|
399
412
|
user_add_form = UserAddForm(request.POST, organization=organization)
|
|
400
413
|
if user_add_form.is_valid():
|
|
@@ -708,29 +721,19 @@ def seller_delete(request, seller_id):
|
|
|
708
721
|
|
|
709
722
|
@login_required(login_url=BOM_LOGIN_URL)
|
|
710
723
|
def user_meta_edit(request, user_meta_id):
|
|
711
|
-
user = request.user
|
|
712
|
-
profile = user.bom_profile()
|
|
713
|
-
organization = profile.organization
|
|
714
|
-
|
|
715
724
|
user_meta = get_object_or_404(UserMeta, pk=user_meta_id)
|
|
716
|
-
|
|
717
|
-
|
|
725
|
+
user = user_meta.user
|
|
726
|
+
organization = user_meta.organization
|
|
727
|
+
title = f'Manage Member'
|
|
718
728
|
|
|
719
729
|
if request.method == 'POST':
|
|
720
|
-
|
|
721
|
-
if
|
|
722
|
-
|
|
723
|
-
|
|
724
|
-
user_meta_user_form.save()
|
|
725
|
-
user_meta_form.save()
|
|
726
|
-
return HttpResponseRedirect(reverse('bom:settings', kwargs={'tab_anchor': 'organization'}))
|
|
727
|
-
|
|
730
|
+
form = UserAddForm(request.POST, instance=user_meta, organization=organization, exclude_username=True)
|
|
731
|
+
if form.is_valid():
|
|
732
|
+
form.save()
|
|
733
|
+
return HttpResponseRedirect(reverse('bom:settings', kwargs={'tab_anchor': 'organization'}))
|
|
728
734
|
return TemplateResponse(request, 'bom/edit-user-meta.html', locals())
|
|
729
|
-
|
|
730
735
|
else:
|
|
731
|
-
|
|
732
|
-
user_meta_form = UserMetaForm(instance=user_meta, organization=organization)
|
|
733
|
-
|
|
736
|
+
form = UserAddForm(instance=user_meta, organization=organization, exclude_username=True)
|
|
734
737
|
return TemplateResponse(request, 'bom/edit-user-meta.html', locals())
|
|
735
738
|
|
|
736
739
|
|
|
@@ -951,7 +954,7 @@ def upload_bom(request):
|
|
|
951
954
|
else:
|
|
952
955
|
messages.error(request, upload_bom_form.errors)
|
|
953
956
|
else:
|
|
954
|
-
upload_bom_form = UploadBOMForm(initial={'organization': organization})
|
|
957
|
+
upload_bom_form = UploadBOMForm(organization=organization, initial={'organization': organization})
|
|
955
958
|
bom_csv_form = BOMCSVForm()
|
|
956
959
|
|
|
957
960
|
return TemplateResponse(request, 'bom/upload-bom.html', locals())
|
|
@@ -1030,22 +1033,15 @@ def export_part_list(request):
|
|
|
1030
1033
|
'number_item',
|
|
1031
1034
|
'number_variation')
|
|
1032
1035
|
|
|
1033
|
-
fieldnames = [
|
|
1034
|
-
'part_number',
|
|
1035
|
-
'part_synopsis',
|
|
1036
|
-
'part_revision',
|
|
1037
|
-
'part_manufacturer',
|
|
1038
|
-
'part_manufacturer_part_number',
|
|
1039
|
-
]
|
|
1040
|
-
|
|
1041
1036
|
csv_headers = organization.part_list_csv_headers()
|
|
1042
|
-
writer = csv.DictWriter(response, fieldnames=
|
|
1037
|
+
writer = csv.DictWriter(response, fieldnames=csv_headers.get_default_all())
|
|
1043
1038
|
writer.writeheader()
|
|
1044
1039
|
for item in parts:
|
|
1045
1040
|
try:
|
|
1041
|
+
latest_rev = item.latest()
|
|
1046
1042
|
row = {
|
|
1047
1043
|
csv_headers.get_default('part_number'): item.full_part_number(),
|
|
1048
|
-
csv_headers.get_default('part_revision'):
|
|
1044
|
+
csv_headers.get_default('part_revision'): latest_rev.revision if latest_rev else '',
|
|
1049
1045
|
csv_headers.get_default('part_manufacturer'): item.primary_manufacturer_part.manufacturer.name if item.primary_manufacturer_part is not None and item.primary_manufacturer_part.manufacturer is not None else '',
|
|
1050
1046
|
csv_headers.get_default('part_manufacturer_part_number'): item.primary_manufacturer_part.manufacturer_part_number if item.primary_manufacturer_part is not None and item.primary_manufacturer_part.manufacturer is not None else '',
|
|
1051
1047
|
}
|
|
@@ -1053,7 +1049,7 @@ def export_part_list(request):
|
|
|
1053
1049
|
if field_name not in csv_headers.get_defaults_list(
|
|
1054
1050
|
['part_number', 'part_category', 'part_synopsis', 'part_revision', 'part_manufacturer',
|
|
1055
1051
|
'part_manufacturer_part_number', ]):
|
|
1056
|
-
attr =
|
|
1052
|
+
attr = latest_rev.get_field_value(field_name) if latest_rev else None
|
|
1057
1053
|
row.update({csv_headers.get_default(field_name): attr if attr is not None else ''})
|
|
1058
1054
|
writer.writerow({k: smart_str(v) for k, v in row.items()})
|
|
1059
1055
|
|
|
@@ -1082,7 +1078,7 @@ def create_part(request):
|
|
|
1082
1078
|
part_form = PartForm(request.POST, organization=organization)
|
|
1083
1079
|
manufacturer_form = ManufacturerForm(request.POST)
|
|
1084
1080
|
manufacturer_part_form = ManufacturerPartForm(request.POST, organization=organization)
|
|
1085
|
-
part_revision_form = PartRevisionForm(request.POST)
|
|
1081
|
+
part_revision_form = PartRevisionForm(request.POST, organization=organization)
|
|
1086
1082
|
# Checking if part form is valid checks for number uniqueness
|
|
1087
1083
|
if part_form.is_valid() and manufacturer_form.is_valid() and manufacturer_part_form.is_valid():
|
|
1088
1084
|
mpn = manufacturer_part_form.cleaned_data['manufacturer_part_number']
|
|
@@ -1107,6 +1103,8 @@ def create_part(request):
|
|
|
1107
1103
|
new_part.number_class = None
|
|
1108
1104
|
new_part.number_variation = None
|
|
1109
1105
|
|
|
1106
|
+
part_revision_form = PartRevisionForm(request.POST, part_class=new_part.number_class,
|
|
1107
|
+
organization=organization)
|
|
1110
1108
|
if part_revision_form.is_valid():
|
|
1111
1109
|
# Save the Part before the PartRevision, as this will again check for part
|
|
1112
1110
|
# number uniqueness. This way if someone else(s) working concurrently is also
|
|
@@ -1117,7 +1115,8 @@ def create_part(request):
|
|
|
1117
1115
|
pr.part = new_part # Associate PartRevision with Part
|
|
1118
1116
|
pr.save()
|
|
1119
1117
|
except IntegrityError as err:
|
|
1120
|
-
messages.error(request, "Error! Already created a part with part number {0}-{1}-{
|
|
1118
|
+
messages.error(request, "Error! Already created a part with part number {0}-{1}-{2}}".format(
|
|
1119
|
+
new_part.number_class.code, new_part.number_item, new_part.number_variation))
|
|
1121
1120
|
return TemplateResponse(request, 'bom/create-part.html', locals())
|
|
1122
1121
|
else:
|
|
1123
1122
|
messages.error(request, part_revision_form.errors)
|
|
@@ -1137,7 +1136,8 @@ def create_part(request):
|
|
|
1137
1136
|
else:
|
|
1138
1137
|
# Initialize organization in the form's model and in the form itself:
|
|
1139
1138
|
part_form = PartForm(initial={'organization': organization}, organization=organization)
|
|
1140
|
-
part_revision_form = PartRevisionForm(initial={'revision': 1, 'organization': organization}
|
|
1139
|
+
part_revision_form = PartRevisionForm(initial={'revision': 1, 'organization': organization},
|
|
1140
|
+
organization=organization)
|
|
1141
1141
|
manufacturer_form = ManufacturerForm(initial={'organization': organization})
|
|
1142
1142
|
manufacturer_part_form = ManufacturerPartForm(organization=organization)
|
|
1143
1143
|
|
|
@@ -1277,6 +1277,117 @@ def remove_subpart(request, part_id, part_revision_id, subpart_id):
|
|
|
1277
1277
|
reverse('bom:part-manage-bom', kwargs={'part_id': part_id, 'part_revision_id': part_revision_id}))
|
|
1278
1278
|
|
|
1279
1279
|
|
|
1280
|
+
@login_required(login_url=BOM_LOGIN_URL)
|
|
1281
|
+
def property_definition_edit(request, property_definition_id=None):
|
|
1282
|
+
user = request.user
|
|
1283
|
+
profile = user.bom_profile()
|
|
1284
|
+
organization = profile.organization
|
|
1285
|
+
|
|
1286
|
+
if property_definition_id:
|
|
1287
|
+
property_definition = get_object_or_404(PartRevisionPropertyDefinition, pk=property_definition_id)
|
|
1288
|
+
if property_definition.organization != organization:
|
|
1289
|
+
messages.error(request, "Can't access a property definition that is not yours!")
|
|
1290
|
+
return HttpResponseRedirect(reverse('bom:settings', kwargs={'tab_anchor': 'indabom'}))
|
|
1291
|
+
title = f'Edit Property Definition {property_definition.name}'
|
|
1292
|
+
else:
|
|
1293
|
+
property_definition = None
|
|
1294
|
+
title = 'Add Property Definition'
|
|
1295
|
+
|
|
1296
|
+
if request.method == 'POST':
|
|
1297
|
+
form = PartRevisionPropertyDefinitionForm(request.POST, instance=property_definition, organization=organization)
|
|
1298
|
+
if form.is_valid():
|
|
1299
|
+
property_definition = form.save(commit=False)
|
|
1300
|
+
property_definition.organization = organization
|
|
1301
|
+
property_definition.save()
|
|
1302
|
+
return HttpResponseRedirect(reverse('bom:settings', kwargs={'tab_anchor': 'indabom'}))
|
|
1303
|
+
else:
|
|
1304
|
+
form = PartRevisionPropertyDefinitionForm(instance=property_definition, organization=organization)
|
|
1305
|
+
|
|
1306
|
+
return TemplateResponse(request, 'bom/bom-form.html', locals())
|
|
1307
|
+
|
|
1308
|
+
|
|
1309
|
+
@login_required(login_url=BOM_LOGIN_URL)
|
|
1310
|
+
@organization_admin
|
|
1311
|
+
def property_definition_delete(request, property_definition_id):
|
|
1312
|
+
user = request.user
|
|
1313
|
+
profile = user.bom_profile()
|
|
1314
|
+
organization = profile.organization
|
|
1315
|
+
property_definition = get_object_or_404(PartRevisionPropertyDefinition, pk=property_definition_id)
|
|
1316
|
+
if property_definition.organization != organization:
|
|
1317
|
+
messages.error(request, "Can't delete a property definition that is not yours!")
|
|
1318
|
+
else:
|
|
1319
|
+
property_definition.delete()
|
|
1320
|
+
return HttpResponseRedirect(reverse('bom:settings', kwargs={'tab_anchor': 'indabom'}))
|
|
1321
|
+
|
|
1322
|
+
|
|
1323
|
+
@login_required(login_url=BOM_LOGIN_URL)
|
|
1324
|
+
def quantity_of_measure_edit(request, quantity_of_measure_id=None):
|
|
1325
|
+
user = request.user
|
|
1326
|
+
profile = user.bom_profile()
|
|
1327
|
+
organization = profile.organization
|
|
1328
|
+
|
|
1329
|
+
if quantity_of_measure_id:
|
|
1330
|
+
quantity_of_measure = get_object_or_404(QuantityOfMeasure, pk=quantity_of_measure_id)
|
|
1331
|
+
if quantity_of_measure.organization != organization:
|
|
1332
|
+
messages.error(request, "Can't access a quantity of measure that is not yours!")
|
|
1333
|
+
return HttpResponseRedirect(reverse('bom:settings', kwargs={'tab_anchor': 'indabom'}))
|
|
1334
|
+
title = f'Edit Quantity of Measure {quantity_of_measure.name}'
|
|
1335
|
+
else:
|
|
1336
|
+
quantity_of_measure = None
|
|
1337
|
+
title = 'Add Quantity of Measure'
|
|
1338
|
+
|
|
1339
|
+
if request.method == 'POST':
|
|
1340
|
+
form = QuantityOfMeasureForm(request.POST, instance=quantity_of_measure, organization=organization)
|
|
1341
|
+
unit_formset = UnitDefinitionFormSet(
|
|
1342
|
+
request.POST,
|
|
1343
|
+
queryset=quantity_of_measure.units.all() if quantity_of_measure else UnitDefinition.objects.none(),
|
|
1344
|
+
form_kwargs={'organization': organization},
|
|
1345
|
+
prefix='units'
|
|
1346
|
+
)
|
|
1347
|
+
|
|
1348
|
+
if form.is_valid() and unit_formset.is_valid():
|
|
1349
|
+
quantity_of_measure = form.save()
|
|
1350
|
+
units = unit_formset.save(commit=False)
|
|
1351
|
+
base_multipliers = [float(unit.base_multiplier) for unit in units]
|
|
1352
|
+
if 1.0 not in base_multipliers:
|
|
1353
|
+
messages.error(request, "Must have a base multiplier of 1.0 for at least 1 unit.")
|
|
1354
|
+
return TemplateResponse(request, 'bom/edit-quantity-of-measure.html', locals())
|
|
1355
|
+
|
|
1356
|
+
for unit in units:
|
|
1357
|
+
unit.organization = organization
|
|
1358
|
+
unit.quantity_of_measure = quantity_of_measure
|
|
1359
|
+
unit.save()
|
|
1360
|
+
for obj in unit_formset.deleted_objects:
|
|
1361
|
+
obj.delete()
|
|
1362
|
+
return HttpResponseRedirect(reverse('bom:settings', kwargs={'tab_anchor': 'indabom'}))
|
|
1363
|
+
else:
|
|
1364
|
+
messages.error(request, form.errors)
|
|
1365
|
+
messages.error(request, unit_formset.errors)
|
|
1366
|
+
else:
|
|
1367
|
+
form = QuantityOfMeasureForm(instance=quantity_of_measure, organization=organization)
|
|
1368
|
+
unit_formset = UnitDefinitionFormSet(
|
|
1369
|
+
queryset=quantity_of_measure.units.all() if quantity_of_measure else UnitDefinition.objects.none(),
|
|
1370
|
+
form_kwargs={'organization': organization},
|
|
1371
|
+
prefix='units'
|
|
1372
|
+
)
|
|
1373
|
+
|
|
1374
|
+
return TemplateResponse(request, 'bom/edit-quantity-of-measure.html', locals())
|
|
1375
|
+
|
|
1376
|
+
|
|
1377
|
+
@login_required(login_url=BOM_LOGIN_URL)
|
|
1378
|
+
@organization_admin
|
|
1379
|
+
def quantity_of_measure_delete(request, quantity_of_measure_id):
|
|
1380
|
+
user = request.user
|
|
1381
|
+
profile = user.bom_profile()
|
|
1382
|
+
organization = profile.organization
|
|
1383
|
+
quantity_of_measure = get_object_or_404(QuantityOfMeasure, pk=quantity_of_measure_id)
|
|
1384
|
+
if quantity_of_measure.organization != organization:
|
|
1385
|
+
messages.error(request, "Can't delete a quantity of measure that is not yours!")
|
|
1386
|
+
else:
|
|
1387
|
+
quantity_of_measure.delete()
|
|
1388
|
+
return HttpResponseRedirect(reverse('bom:settings', kwargs={'tab_anchor': 'indabom'}))
|
|
1389
|
+
|
|
1390
|
+
|
|
1280
1391
|
@login_required(login_url=BOM_LOGIN_URL)
|
|
1281
1392
|
def part_class_edit(request, part_class_id):
|
|
1282
1393
|
user = request.user
|
|
@@ -1288,15 +1399,40 @@ def part_class_edit(request, part_class_id):
|
|
|
1288
1399
|
|
|
1289
1400
|
if request.method == 'POST':
|
|
1290
1401
|
part_class_form = PartClassForm(request.POST, instance=part_class, organization=organization)
|
|
1291
|
-
|
|
1292
|
-
|
|
1402
|
+
property_definitions_formset = PartRevisionPropertyDefinitionFormSet(
|
|
1403
|
+
request.POST,
|
|
1404
|
+
form_kwargs={'organization': organization},
|
|
1405
|
+
prefix='prop-def'
|
|
1406
|
+
)
|
|
1407
|
+
|
|
1408
|
+
if part_class_form.is_valid() and property_definitions_formset.is_valid():
|
|
1409
|
+
part_class = part_class_form.save()
|
|
1410
|
+
|
|
1411
|
+
# Clear current associations and re-add from formset
|
|
1412
|
+
part_class.property_definitions.clear()
|
|
1413
|
+
for form in property_definitions_formset:
|
|
1414
|
+
if form.cleaned_data and not form.cleaned_data.get('DELETE'):
|
|
1415
|
+
definition = form.cleaned_data.get('property_definition')
|
|
1416
|
+
if definition:
|
|
1417
|
+
part_class.property_definitions.add(definition)
|
|
1418
|
+
|
|
1293
1419
|
return HttpResponseRedirect(reverse('bom:settings', kwargs={'tab_anchor': 'indabom'}))
|
|
1294
1420
|
|
|
1295
1421
|
else:
|
|
1422
|
+
if not part_class_form.is_valid():
|
|
1423
|
+
messages.error(request, part_class_form.errors)
|
|
1424
|
+
if not property_definitions_formset.is_valid():
|
|
1425
|
+
messages.error(request, property_definitions_formset.errors)
|
|
1296
1426
|
return TemplateResponse(request, 'bom/edit-part-class.html', locals())
|
|
1297
1427
|
|
|
1298
1428
|
else:
|
|
1299
1429
|
part_class_form = PartClassForm(instance=part_class, organization=organization)
|
|
1430
|
+
initial = [{'property_definition': pd} for pd in part_class.property_definitions.all().order_by('name')]
|
|
1431
|
+
property_definitions_formset = PartRevisionPropertyDefinitionFormSet(
|
|
1432
|
+
initial=initial,
|
|
1433
|
+
form_kwargs={'organization': organization},
|
|
1434
|
+
prefix='prop-def',
|
|
1435
|
+
)
|
|
1300
1436
|
|
|
1301
1437
|
return TemplateResponse(request, 'bom/edit-part-class.html', locals())
|
|
1302
1438
|
|
|
@@ -1547,7 +1683,8 @@ def part_revision_new(request, part_id):
|
|
|
1547
1683
|
used_part_revisions = all_used_in_prs.filter(configuration='W')
|
|
1548
1684
|
|
|
1549
1685
|
if request.method == 'POST':
|
|
1550
|
-
part_revision_new_form = PartRevisionNewForm(request.POST, part=part, revision=next_revision_number,
|
|
1686
|
+
part_revision_new_form = PartRevisionNewForm(request.POST, part=part, revision=next_revision_number,
|
|
1687
|
+
assembly=latest_revision.assembly, organization=organization)
|
|
1551
1688
|
if part_revision_new_form.is_valid():
|
|
1552
1689
|
new_part_revision = part_revision_new_form.save()
|
|
1553
1690
|
|
|
@@ -1579,9 +1716,9 @@ def part_revision_new(request, part_id):
|
|
|
1579
1716
|
if latest_revision:
|
|
1580
1717
|
messages.info(request, 'New revision automatically incremented to `{}` from your last revision `{}`.'.format(next_revision_number, latest_revision.revision))
|
|
1581
1718
|
latest_revision.revision = next_revision_number # use updated object to populate form but don't save changes
|
|
1582
|
-
part_revision_new_form = PartRevisionNewForm(instance=latest_revision)
|
|
1719
|
+
part_revision_new_form = PartRevisionNewForm(instance=latest_revision, organization=organization)
|
|
1583
1720
|
else:
|
|
1584
|
-
part_revision_new_form = PartRevisionNewForm()
|
|
1721
|
+
part_revision_new_form = PartRevisionNewForm(organization=organization)
|
|
1585
1722
|
|
|
1586
1723
|
return TemplateResponse(request, 'bom/part-revision-new.html', locals())
|
|
1587
1724
|
|
|
@@ -1599,12 +1736,12 @@ def part_revision_edit(request, part_id, part_revision_id):
|
|
|
1599
1736
|
action = reverse('bom:part-revision-edit', kwargs={'part_id': part_id, 'part_revision_id': part_revision_id})
|
|
1600
1737
|
|
|
1601
1738
|
if request.method == 'POST':
|
|
1602
|
-
form = PartRevisionForm(request.POST, instance=part_revision)
|
|
1739
|
+
form = PartRevisionForm(request.POST, instance=part_revision, organization=organization)
|
|
1603
1740
|
if form.is_valid():
|
|
1604
1741
|
form.save()
|
|
1605
1742
|
return HttpResponseRedirect(reverse('bom:part-info', kwargs={'part_id': part_id}))
|
|
1606
1743
|
else:
|
|
1607
|
-
form = PartRevisionForm(instance=part_revision)
|
|
1744
|
+
form = PartRevisionForm(instance=part_revision, organization=organization)
|
|
1608
1745
|
|
|
1609
1746
|
return TemplateResponse(request, 'bom/part-revision-edit.html', locals())
|
|
1610
1747
|
|
|
@@ -1,21 +1,21 @@
|
|
|
1
1
|
bom/__init__.py,sha256=HuvSMR9cYQcppTZGD0XjUVUBtHWwWMh1yMQzk_2wTS4,41
|
|
2
|
-
bom/admin.py,sha256=
|
|
2
|
+
bom/admin.py,sha256=MmCa4X9J5aKNbQTrfyLnDdoIt9MrlS3rI1sN9EkhsIs,5892
|
|
3
3
|
bom/apps.py,sha256=TJMUTSX1h2genPwCq6SN6g1fhrrSmjEXGg2zQFa_ryM,147
|
|
4
4
|
bom/auth_backends.py,sha256=Xj3MCUJg3r9M4v1c8wrxC3lwpE5F8_2_HD5s9M_5Rms,1480
|
|
5
5
|
bom/base_classes.py,sha256=CrWD7wlIkwYb90VoGcVOcw2WoQszRrCje-Re5d_UW1Q,1183
|
|
6
|
-
bom/constants.py,sha256=
|
|
6
|
+
bom/constants.py,sha256=Vs3-s1_ej8hDMlq5YC01vZXs1TECuPe9sn834UierLI,4666
|
|
7
7
|
bom/context_processors.py,sha256=OxMVCqxGtRoHR7aJfTs6xANpxJQzBDUIuNTG1f_Xjoo,312
|
|
8
|
-
bom/csv_headers.py,sha256=
|
|
8
|
+
bom/csv_headers.py,sha256=0WLvgchbTtW_9ya3UC_qL5hv7muuklf_vtoMNBFAOoc,11468
|
|
9
9
|
bom/decorators.py,sha256=fCK-lxJTBp3LEdZtKMyQg5hRqxQm5RJny9eb7oyjbtE,1233
|
|
10
10
|
bom/form_fields.py,sha256=tLqchl0j8izBCZnm82NMyHpQV6EuGgCjCl5lrnGR2V0,2816
|
|
11
|
-
bom/forms.py,sha256=
|
|
12
|
-
bom/helpers.py,sha256=
|
|
11
|
+
bom/forms.py,sha256=_hsEdhyr2QDQ-Ei7ZRcv4N9s4lmbYR4xT5-NhyJ8rB4,57312
|
|
12
|
+
bom/helpers.py,sha256=jzwNDgD-4htdJfWWjNy8ZhVqfdgSxhNpsFn6kDpC5UU,20172
|
|
13
13
|
bom/local_settings.py,sha256=yE4aupIquCWsFms44qoCrRrlIyM3sqpOkiwyj1WLxI8,820
|
|
14
|
-
bom/models.py,sha256=
|
|
14
|
+
bom/models.py,sha256=dzvhU68hu5Wam4RvD3e75dcsqsbVmBWVe8vi57w40hQ,38424
|
|
15
15
|
bom/part_bom.py,sha256=30HYAKAEhtadiM9tk6vgCQnn7gNJeuXbzF5gXvMvKG4,8720
|
|
16
16
|
bom/settings.py,sha256=aBg0PHaK9NvNZNmfnPrU4-kp2GQeeAGMB_EVvMoAmJs,8197
|
|
17
|
-
bom/tests.py,sha256=
|
|
18
|
-
bom/urls.py,sha256=
|
|
17
|
+
bom/tests.py,sha256=Grn2aoXR7AnoVJ9Wa_stgkofk94WS7sPcVKWxpelvY0,73980
|
|
18
|
+
bom/urls.py,sha256=7yjQ7ONydqZHHFHd9jWThEu_03r3LyDcVJ-BGYNy6LQ,7589
|
|
19
19
|
bom/utils.py,sha256=z_2jACSkRc0hsc0mdR8tOK10KiSDeM0a6rXIpztPDuA,7302
|
|
20
20
|
bom/validators.py,sha256=tiQYIblITCOwb8m1kfs_CFmFnJofCtFzqENlxBuGL7Y,872
|
|
21
21
|
bom/wsgi.py,sha256=-2oAfSSVdNFCjxaKXcPp-JL_K8AhVClzls6OC_ZI1Jc,380
|
|
@@ -70,12 +70,13 @@ bom/migrations/0048_rename_part_organization_number_class_bom_part_organiz_b333d
|
|
|
70
70
|
bom/migrations/0049_alter_assembly_id_alter_assemblysubparts_id_and_more.py,sha256=l1q5BCNVYWD6Ngf9pGzYq1hQMvvshmdFlm33On63YNc,3247
|
|
71
71
|
bom/migrations/0050_alter_organization_options.py,sha256=n-YGAoUdUxYdh5NY0Zpz2T4CWEOR7tDjSFFk-KZD_tw,432
|
|
72
72
|
bom/migrations/0051_alter_manufacturer_organization_and_more.py,sha256=xjnkZhEgsJDsfK9leBPxxQ2oG_Qf2FdrttTx-lldmjw,1539
|
|
73
|
+
bom/migrations/0052_remove_partrevision_attribute_and_more.py,sha256=WxRL6J8pepMfyuATUj7blr_1LG8Lf1ZdK_kLN1F_F-o,31364
|
|
73
74
|
bom/migrations/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
74
75
|
bom/static/bom/css/dashboard.css,sha256=saLXUpnVRjsV9HNdsmQD4Eq-zBlm8R2YePhvoc1uifk,245
|
|
75
76
|
bom/static/bom/css/jquery.treetable.css,sha256=H37aGBAAFP3R6v08nui9gKSdLE2VGsGsmlttrIImzfE,652
|
|
76
77
|
bom/static/bom/css/materialize.min.css,sha256=OweaP_Ic6rsV-lysfyS4h-LM6sRwuO3euTYfr6M124g,141841
|
|
77
78
|
bom/static/bom/css/part-info.css,sha256=xQ6zJXHLStwU76UVoYxjG-MjdQzFRwg-jANqrj_KFS0,252
|
|
78
|
-
bom/static/bom/css/style.css,sha256=
|
|
79
|
+
bom/static/bom/css/style.css,sha256=NARNKKTNIE-3CU2Glcqbs8fzfedRhbRzIFSRza_bT6I,6737
|
|
79
80
|
bom/static/bom/css/tablesorter-theme.materialize.css,sha256=S7DYXb4vdqdDSUouZ8aIbAxIpemhIzFfeRySdnvvSlc,7435
|
|
80
81
|
bom/static/bom/css/treetable-theme.css,sha256=RxMklK-XfcF90gxekH3IULmyr7_HRA0TdNz_9Xjxuro,24013
|
|
81
82
|
bom/static/bom/doc/sample_part_classes.csv,sha256=nAWhBV9KtHSejLUKD7OKKtbkfUYCeLgCwze9BPstiFo,1694
|
|
@@ -123,6 +124,7 @@ bom/static/bom/img/google/web/vector/btn_google_light_normal_ios.eps,sha256=xZ8g
|
|
|
123
124
|
bom/static/bom/img/google/web/vector/btn_google_light_normal_ios.svg,sha256=Rk6WGzHe0lGJGEyWiN6lTusosfK8ubtqSdf0ZzuWLBE,4358
|
|
124
125
|
bom/static/bom/img/google/web/vector/btn_google_light_pressed_ios.eps,sha256=WUvJDjV62btGu5W1SkKE6juGMOHnA62JJ_0p8C_eOnw,26107
|
|
125
126
|
bom/static/bom/img/google/web/vector/btn_google_light_pressed_ios.svg,sha256=CR9QqAnt_NVL2YweEZe4fN6kQ6QQ31nZHxSmwqVs1t0,4360
|
|
127
|
+
bom/static/bom/js/formset-handler.js,sha256=eEFRa1Sln5Uj7P660_nLDcIHr-mri3SewB89Pr0CwPA,2389
|
|
126
128
|
bom/static/bom/js/jquery-3.4.1.min.js,sha256=CSXorXvZcTkaix6Yvo6HppcZGetbYMGWSFlBw8HfCJo,88145
|
|
127
129
|
bom/static/bom/js/jquery.ba-floatingscrollbar.min.js,sha256=NptA5rS2zjhkcu26WQJtMr34psHYzUYRsLrSziTusgg,1271
|
|
128
130
|
bom/static/bom/js/jquery.treetable.js,sha256=JEXnh_LuKYxk8CUIT1anQ4es4nfOqC0bds_NjsbMBUI,16611
|
|
@@ -144,16 +146,17 @@ bom/templates/bom/create-part.html,sha256=UjHx6rkPJl-BRt9gKs5zB3s5Y4vrImDTuD25lv
|
|
|
144
146
|
bom/templates/bom/dashboard-menu.html,sha256=4MnFSw0x4w7R0CsSwEDFP3FuZVBFxVChIHr58l3rpSk,799
|
|
145
147
|
bom/templates/bom/dashboard.html,sha256=m-jGdf4aeIcQqbdqSTwzRCIoLldiIIUQrfM-zRJgyvU,16314
|
|
146
148
|
bom/templates/bom/edit-manufacturer-part.html,sha256=4WagGptcVtYCxW1zWvHGeaZSc-0qqEKDRHFyKarqIjU,3518
|
|
147
|
-
bom/templates/bom/edit-part-class.html,sha256=
|
|
149
|
+
bom/templates/bom/edit-part-class.html,sha256=1DV8_bQiYuxYUuqMT2SsKDI4UWnnZnEx5EU7Nw7KJlw,5757
|
|
148
150
|
bom/templates/bom/edit-part.html,sha256=bGfBI3X8eb7iLy_nYDPQRP2CKyp4tNO2-vjakx-_YiM,3051
|
|
149
|
-
bom/templates/bom/edit-
|
|
151
|
+
bom/templates/bom/edit-quantity-of-measure.html,sha256=79ftu8klYrryj3JrSPEQ3Up5NLh2Qbf4qHp_8qZm5aM,5975
|
|
152
|
+
bom/templates/bom/edit-user-meta.html,sha256=Z4iMA0OErrvVNHbFjLuq7tpO5f6C9ovDpI8-zhC6oX0,3489
|
|
150
153
|
bom/templates/bom/help.html,sha256=hi16fwtVqeWP3Vb3vOpLSKx0ioB1MODJ8lkh6bczfiM,83247
|
|
151
154
|
bom/templates/bom/manufacturer-info.html,sha256=jR98qXONqquEeda92djQgmFfmJiC8jbsGgyXuzJY100,3742
|
|
152
155
|
bom/templates/bom/manufacturers.html,sha256=3ZF8Up-IiAvR6CCmrj_92qPPh7vKrVQaEN05KKX2yrA,5550
|
|
153
156
|
bom/templates/bom/nothing-to-see.html,sha256=cRspNAHlSfv7KjQwp34gANhVqQbXzfFpqtRSm6NoV9s,657
|
|
154
157
|
bom/templates/bom/organization-create.html,sha256=yLrEJH8BlD-W1USk8pYAzTvr-Qw9ZM5rBGYO3n6lCu0,7982
|
|
155
|
-
bom/templates/bom/part-info.html,sha256=
|
|
156
|
-
bom/templates/bom/part-revision-display.html,sha256=
|
|
158
|
+
bom/templates/bom/part-info.html,sha256=236TZ6yTvR5LCravYiuKgzL_CB6nXrd0_C299gvQF8U,26051
|
|
159
|
+
bom/templates/bom/part-revision-display.html,sha256=f5o-9cjGBz7KPp8ubSiUiFNa2tWzHqSKSe3rC7smR6A,1414
|
|
157
160
|
bom/templates/bom/part-revision-edit.html,sha256=gOWiRd8Vq0z912_fI9UtBC0yYkcF_lruMQfAWN4kqw0,1624
|
|
158
161
|
bom/templates/bom/part-revision-manage-bom.html,sha256=Nd1CIANnCwYU5KzijlIDfKTXjXqrDOeuwmGOk-CYyrY,5073
|
|
159
162
|
bom/templates/bom/part-revision-new.html,sha256=BMgKBNmFkrsimqSeviP1Rn3huOB_0kfK-77oIyqwItw,2691
|
|
@@ -161,7 +164,7 @@ bom/templates/bom/part-revision-release.html,sha256=voG7wmYc1Cm3e_H1IasvQcPuyqnn
|
|
|
161
164
|
bom/templates/bom/search-help.html,sha256=Wh_tXBJtz0bznk0F1C7OSdRhMe2qpOs9NMCBb2i0CFI,4398
|
|
162
165
|
bom/templates/bom/seller-info.html,sha256=MACsHMYQXMWfRslXuvh9hD2z28VXzVi0DSy4yg7WQMk,3595
|
|
163
166
|
bom/templates/bom/sellers.html,sha256=6ut7LwRMGUKYB4BRjiSpDBP9BGgqT7nxpNQpUVWDvkw,5412
|
|
164
|
-
bom/templates/bom/settings.html,sha256=
|
|
167
|
+
bom/templates/bom/settings.html,sha256=g7PhrtbQSf7VRK6pDTPUxUr-PjCLzrJyUErno2pDekY,36184
|
|
165
168
|
bom/templates/bom/signup.html,sha256=tB_x7q3IufSNXsd9Dfh8fdWpkiWSGH2_Zgw749B1PaU,884
|
|
166
169
|
bom/templates/bom/subscription_panel.html,sha256=Ute49APwiXONQW2z0AApJRaSwnwtsYt3_opn0bW5BX8,843
|
|
167
170
|
bom/templates/bom/table_of_contents.html,sha256=7wXWOfmVkk5Itjax5x1PE-g5QjxqmYBr7RW8NgtGRng,1763
|
|
@@ -180,9 +183,9 @@ bom/third_party_apis/mouser.py,sha256=q2-p0k2n-LNel_QRlfak0kAXT-9hh59k_Pt51PTG09
|
|
|
180
183
|
bom/third_party_apis/test_apis.py,sha256=2W0jtTisGTmktC7l556pn9-pZYseTQmmQfo6_4uP4Dc,679
|
|
181
184
|
bom/views/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
182
185
|
bom/views/json_views.py,sha256=LK3-njLZrILLqZxCuE-_sUEC2z2GBxQFRysX67-h14c,2334
|
|
183
|
-
bom/views/views.py,sha256=
|
|
184
|
-
django_bom-1.
|
|
185
|
-
django_bom-1.
|
|
186
|
-
django_bom-1.
|
|
187
|
-
django_bom-1.
|
|
188
|
-
django_bom-1.
|
|
186
|
+
bom/views/views.py,sha256=rYEtIPEJMu1rFSNUARcBlJUe8NgBKoHxl38VWYb8htY,80320
|
|
187
|
+
django_bom-1.258.dist-info/licenses/LICENSE,sha256=OXLcl0T2SZ8Pmy2_dmlvKuetivmyPd5m1q-Gyd-zaYY,35149
|
|
188
|
+
django_bom-1.258.dist-info/METADATA,sha256=_PsObL9U6JRTrbBLHd-cqFKPLPW9e3kj4zT4lxBhxT0,7558
|
|
189
|
+
django_bom-1.258.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
|
190
|
+
django_bom-1.258.dist-info/top_level.txt,sha256=6zytg4lnnobI96dO-ZEadPOCslrrFmf4t2Pnv-y8x0Y,4
|
|
191
|
+
django_bom-1.258.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|