django-bom 1.262__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.

Potentially problematic release.


This version of django-bom might be problematic. Click here for more details.

Files changed (191) hide show
  1. bom/__init__.py +1 -0
  2. bom/admin.py +207 -0
  3. bom/apps.py +8 -0
  4. bom/auth_backends.py +47 -0
  5. bom/base_classes.py +31 -0
  6. bom/constants.py +217 -0
  7. bom/context_processors.py +9 -0
  8. bom/csv_headers.py +252 -0
  9. bom/decorators.py +32 -0
  10. bom/form_fields.py +59 -0
  11. bom/forms.py +1328 -0
  12. bom/helpers.py +367 -0
  13. bom/local_settings.py +35 -0
  14. bom/migrations/0001_initial.py +135 -0
  15. bom/migrations/0002_auto_20180908_2151.py +24 -0
  16. bom/migrations/0003_sellerpart_data_source.py +18 -0
  17. bom/migrations/0004_auto_20180911_0011.py +18 -0
  18. bom/migrations/0005_auto_20181007_1934.py +56 -0
  19. bom/migrations/0006_auto_20181007_1949.py +41 -0
  20. bom/migrations/0007_auto_20181009_0256.py +19 -0
  21. bom/migrations/0008_auto_20181030_0427.py +19 -0
  22. bom/migrations/0009_subpart_reference.py +18 -0
  23. bom/migrations/0010_auto_20181202_0733.py +23 -0
  24. bom/migrations/0011_auto_20181202_2113.py +22 -0
  25. bom/migrations/0012_partchangehistory.py +30 -0
  26. bom/migrations/0013_auto_20190222_1631.py +19 -0
  27. bom/migrations/0014_auto_20190223_2353.py +18 -0
  28. bom/migrations/0015_auto_20190303_1915.py +136 -0
  29. bom/migrations/0016_auto_20190405_2308.py +58 -0
  30. bom/migrations/0017_auto_20190616_1912.py +19 -0
  31. bom/migrations/0018_auto_20190616_2143.py +24 -0
  32. bom/migrations/0019_auto_20190624_1246.py +45 -0
  33. bom/migrations/0020_auto_20190627_0207.py +38 -0
  34. bom/migrations/0021_auto_20190627_0428.py +23 -0
  35. bom/migrations/0022_auto_20190811_2140.py +35 -0
  36. bom/migrations/0023_auto_20191205_2351.py +255 -0
  37. bom/migrations/0024_auto_20191214_1342.py +89 -0
  38. bom/migrations/0025_auto_20191221_1907.py +38 -0
  39. bom/migrations/0026_auto_20191222_2258.py +22 -0
  40. bom/migrations/0027_auto_20191222_2347.py +17 -0
  41. bom/migrations/0028_partrevision_displayable_synopsis.py +74 -0
  42. bom/migrations/0029_auto_20191231_1630.py +23 -0
  43. bom/migrations/0030_auto_20200101_2253.py +22 -0
  44. bom/migrations/0031_auto_20200104_1352.py +38 -0
  45. bom/migrations/0032_auto_20200126_1806.py +27 -0
  46. bom/migrations/0033_auto_20200203_0618.py +29 -0
  47. bom/migrations/0034_auto_20200222_0359.py +30 -0
  48. bom/migrations/0035_auto_20200303_0111.py +34 -0
  49. bom/migrations/0036_auto_20200303_0538.py +17 -0
  50. bom/migrations/0037_auto_20200405_1642.py +44 -0
  51. bom/migrations/0038_auto_20200422_0504.py +19 -0
  52. bom/migrations/0039_auto_20200929_2315.py +41 -0
  53. bom/migrations/0040_alter_organization_currency.py +19 -0
  54. bom/migrations/0041_organization_subscription_quantity.py +18 -0
  55. bom/migrations/0042_auto_20210720_2137.py +23 -0
  56. bom/migrations/0043_auto_20211123_0157.py +24 -0
  57. bom/migrations/0044_auto_20220831_1241.py +23 -0
  58. bom/migrations/0045_sellerpart_link.py +18 -0
  59. bom/migrations/0046_alter_sellerpart_unique_together.py +17 -0
  60. bom/migrations/0047_sellerpart_seller_part_number.py +18 -0
  61. bom/migrations/0048_rename_part_organization_number_class_bom_part_organiz_b333d6_idx_and_more.py +1017 -0
  62. bom/migrations/0049_alter_assembly_id_alter_assemblysubparts_id_and_more.py +99 -0
  63. bom/migrations/0050_alter_organization_options.py +17 -0
  64. bom/migrations/0051_alter_manufacturer_organization_and_more.py +41 -0
  65. bom/migrations/0052_remove_partrevision_attribute_and_more.py +584 -0
  66. bom/migrations/__init__.py +0 -0
  67. bom/models.py +886 -0
  68. bom/part_bom.py +192 -0
  69. bom/settings.py +262 -0
  70. bom/static/bom/css/dashboard.css +17 -0
  71. bom/static/bom/css/jquery.treetable.css +28 -0
  72. bom/static/bom/css/materialize.min.css +13 -0
  73. bom/static/bom/css/part-info.css +15 -0
  74. bom/static/bom/css/style.css +482 -0
  75. bom/static/bom/css/tablesorter-theme.materialize.css +176 -0
  76. bom/static/bom/css/treetable-theme.css +42 -0
  77. bom/static/bom/doc/sample_part_classes.csv +38 -0
  78. bom/static/bom/doc/test_bom.csv +6 -0
  79. bom/static/bom/doc/test_bom_5_intelligent.csv +4 -0
  80. bom/static/bom/doc/test_full_bom.csv +37 -0
  81. bom/static/bom/doc/test_new_parts.csv +5 -0
  82. bom/static/bom/doc/test_new_parts_5_intelligent.csv +5 -0
  83. bom/static/bom/img/_ionicons_svg_md-arrow-dropdown.svg +1 -0
  84. bom/static/bom/img/_ionicons_svg_md-arrow-dropright.svg +1 -0
  85. bom/static/bom/img/favicon.ico +0 -0
  86. bom/static/bom/img/google/web/1x/btn_google_signin_dark_disabled_web.png +0 -0
  87. bom/static/bom/img/google/web/1x/btn_google_signin_dark_focus_web.png +0 -0
  88. bom/static/bom/img/google/web/1x/btn_google_signin_dark_normal_web.png +0 -0
  89. bom/static/bom/img/google/web/1x/btn_google_signin_dark_pressed_web.png +0 -0
  90. bom/static/bom/img/google/web/1x/btn_google_signin_light_disabled_web.png +0 -0
  91. bom/static/bom/img/google/web/1x/btn_google_signin_light_focus_web.png +0 -0
  92. bom/static/bom/img/google/web/1x/btn_google_signin_light_normal_web.png +0 -0
  93. bom/static/bom/img/google/web/1x/btn_google_signin_light_pressed_web.png +0 -0
  94. bom/static/bom/img/google/web/2x/btn_google_signin_dark_disabled_web@2x.png +0 -0
  95. bom/static/bom/img/google/web/2x/btn_google_signin_dark_focus_web@2x.png +0 -0
  96. bom/static/bom/img/google/web/2x/btn_google_signin_dark_normal_web@2x.png +0 -0
  97. bom/static/bom/img/google/web/2x/btn_google_signin_dark_pressed_web@2x.png +0 -0
  98. bom/static/bom/img/google/web/2x/btn_google_signin_light_disabled_web@2x.png +0 -0
  99. bom/static/bom/img/google/web/2x/btn_google_signin_light_focus_web@2x.png +0 -0
  100. bom/static/bom/img/google/web/2x/btn_google_signin_light_normal_web@2x.png +0 -0
  101. bom/static/bom/img/google/web/2x/btn_google_signin_light_pressed_web@2x.png +0 -0
  102. bom/static/bom/img/google/web/vector/btn_google_dark_disabled_ios.eps +814 -0
  103. bom/static/bom/img/google/web/vector/btn_google_dark_disabled_ios.svg +24 -0
  104. bom/static/bom/img/google/web/vector/btn_google_dark_focus_ios.eps +1866 -0
  105. bom/static/bom/img/google/web/vector/btn_google_dark_focus_ios.svg +51 -0
  106. bom/static/bom/img/google/web/vector/btn_google_dark_normal_ios.eps +1031 -0
  107. bom/static/bom/img/google/web/vector/btn_google_dark_normal_ios.svg +50 -0
  108. bom/static/bom/img/google/web/vector/btn_google_dark_pressed_ios.eps +1031 -0
  109. bom/static/bom/img/google/web/vector/btn_google_dark_pressed_ios.svg +50 -0
  110. bom/static/bom/img/google/web/vector/btn_google_light_disabled_ios.eps +814 -0
  111. bom/static/bom/img/google/web/vector/btn_google_light_disabled_ios.svg +24 -0
  112. bom/static/bom/img/google/web/vector/btn_google_light_focus_ios.eps +1837 -0
  113. bom/static/bom/img/google/web/vector/btn_google_light_focus_ios.svg +44 -0
  114. bom/static/bom/img/google/web/vector/btn_google_light_normal_ios.eps +1002 -0
  115. bom/static/bom/img/google/web/vector/btn_google_light_normal_ios.svg +43 -0
  116. bom/static/bom/img/google/web/vector/btn_google_light_pressed_ios.eps +1002 -0
  117. bom/static/bom/img/google/web/vector/btn_google_light_pressed_ios.svg +43 -0
  118. bom/static/bom/img/google_drive_logo.svg +1 -0
  119. bom/static/bom/img/indabom.png +0 -0
  120. bom/static/bom/img/mouser.png +0 -0
  121. bom/static/bom/img/octopart_blue.svg +19 -0
  122. bom/static/bom/js/formset-handler.js +65 -0
  123. bom/static/bom/js/jquery-3.4.1.min.js +2 -0
  124. bom/static/bom/js/jquery.ba-floatingscrollbar.min.js +10 -0
  125. bom/static/bom/js/jquery.treetable.js +629 -0
  126. bom/static/bom/js/materialize.min.js +6 -0
  127. bom/templates/bom/account-delete.html +23 -0
  128. bom/templates/bom/add-manufacturer-part.html +66 -0
  129. bom/templates/bom/add-sellerpart.html +93 -0
  130. bom/templates/bom/base-menu.html +16 -0
  131. bom/templates/bom/base.html +129 -0
  132. bom/templates/bom/bom-action-btn.html +23 -0
  133. bom/templates/bom/bom-action-table.html +57 -0
  134. bom/templates/bom/bom-base-menu.html +6 -0
  135. bom/templates/bom/bom-base.html +24 -0
  136. bom/templates/bom/bom-form-modal.html +36 -0
  137. bom/templates/bom/bom-form.html +30 -0
  138. bom/templates/bom/bom-modal-add-users.html +49 -0
  139. bom/templates/bom/bom-signup.html +12 -0
  140. bom/templates/bom/components/bom-flat.html +131 -0
  141. bom/templates/bom/components/bom-indented.html +237 -0
  142. bom/templates/bom/components/manufacturer-part-list.html +270 -0
  143. bom/templates/bom/components/seller-part-list.html +62 -0
  144. bom/templates/bom/create-part.html +65 -0
  145. bom/templates/bom/dashboard-menu.html +15 -0
  146. bom/templates/bom/dashboard.html +303 -0
  147. bom/templates/bom/edit-manufacturer-part.html +72 -0
  148. bom/templates/bom/edit-part-class.html +120 -0
  149. bom/templates/bom/edit-part.html +67 -0
  150. bom/templates/bom/edit-quantity-of-measure.html +119 -0
  151. bom/templates/bom/edit-user-meta.html +70 -0
  152. bom/templates/bom/help.html +1356 -0
  153. bom/templates/bom/manufacturer-info.html +82 -0
  154. bom/templates/bom/manufacturers.html +97 -0
  155. bom/templates/bom/nothing-to-see.html +15 -0
  156. bom/templates/bom/organization-create.html +135 -0
  157. bom/templates/bom/part-info.html +448 -0
  158. bom/templates/bom/part-revision-display.html +50 -0
  159. bom/templates/bom/part-revision-edit.html +39 -0
  160. bom/templates/bom/part-revision-manage-bom.html +115 -0
  161. bom/templates/bom/part-revision-new.html +57 -0
  162. bom/templates/bom/part-revision-release.html +41 -0
  163. bom/templates/bom/search-help.html +101 -0
  164. bom/templates/bom/seller-info.html +82 -0
  165. bom/templates/bom/sellers.html +97 -0
  166. bom/templates/bom/settings.html +734 -0
  167. bom/templates/bom/signup.html +28 -0
  168. bom/templates/bom/subscription_panel.html +16 -0
  169. bom/templates/bom/table_of_contents.html +47 -0
  170. bom/templates/bom/upload-bom.html +111 -0
  171. bom/templates/bom/upload-parts-help.html +103 -0
  172. bom/templates/bom/upload-parts.html +50 -0
  173. bom/templates/registration/login.html +39 -0
  174. bom/tests.py +1592 -0
  175. bom/third_party_apis/__init__.py +0 -0
  176. bom/third_party_apis/base_api.py +51 -0
  177. bom/third_party_apis/google_drive.py +166 -0
  178. bom/third_party_apis/mouser.py +132 -0
  179. bom/third_party_apis/test_apis.py +24 -0
  180. bom/urls.py +100 -0
  181. bom/utils.py +228 -0
  182. bom/validators.py +23 -0
  183. bom/views/__init__.py +0 -0
  184. bom/views/json_views.py +55 -0
  185. bom/views/views.py +1773 -0
  186. bom/wsgi.py +16 -0
  187. django_bom-1.262.dist-info/METADATA +206 -0
  188. django_bom-1.262.dist-info/RECORD +191 -0
  189. django_bom-1.262.dist-info/WHEEL +5 -0
  190. django_bom-1.262.dist-info/licenses/LICENSE +674 -0
  191. django_bom-1.262.dist-info/top_level.txt +1 -0
bom/__init__.py ADDED
@@ -0,0 +1 @@
1
+ default_app_config = 'bom.apps.BomConfig'
bom/admin.py ADDED
@@ -0,0 +1,207 @@
1
+ from django.conf import settings
2
+ from django.contrib import admin
3
+ from django.contrib.auth import get_user_model
4
+ from django.contrib.auth.admin import UserAdmin
5
+
6
+ from .models import (
7
+ Assembly,
8
+ Manufacturer,
9
+ ManufacturerPart,
10
+ Part,
11
+ PartClass,
12
+ PartRevision,
13
+ PartRevisionProperty,
14
+ PartRevisionPropertyDefinition,
15
+ Seller,
16
+ SellerPart,
17
+ Subpart,
18
+ UnitDefinition,
19
+ QuantityOfMeasure,
20
+ get_organization_model,
21
+ get_user_meta_model
22
+ )
23
+
24
+ User = get_user_model()
25
+ UserMeta = get_user_meta_model()
26
+ Organization = get_organization_model()
27
+
28
+ class UserMetaInline(admin.TabularInline):
29
+ model = UserMeta
30
+ verbose_name = 'BOM User Meta'
31
+ raw_id_fields = ('organization',)
32
+ can_delete = False
33
+
34
+
35
+ class OrganizationAdmin(admin.ModelAdmin):
36
+ list_display = ('name',)
37
+
38
+
39
+ class SubpartInline(admin.TabularInline):
40
+ model = Subpart
41
+ fk_name = 'part_revision'
42
+ raw_id_fields = ('part_revision',)
43
+ # readonly_fields = ('get_full_part_number', )
44
+ #
45
+ # def get_full_part_number(self, obj):
46
+ # return obj.assembly_subpart.part.full_part_number()
47
+ # get_full_part_number.short_description = 'PartNumber'
48
+
49
+
50
+ class SellerAdmin(admin.ModelAdmin):
51
+ list_display = ('name',)
52
+
53
+
54
+ class SellerPartAdmin(admin.ModelAdmin):
55
+ list_display = (
56
+ 'manufacturer_part',
57
+ 'seller',
58
+ 'seller_part_number',
59
+ 'minimum_order_quantity',
60
+ 'minimum_pack_quantity',
61
+ 'unit_cost',
62
+ 'lead_time_days',
63
+ 'nre_cost',
64
+ 'ncnr')
65
+
66
+
67
+ class SellerPartAdminInline(admin.TabularInline):
68
+ model = SellerPart
69
+ raw_id_fields = ('seller', 'manufacturer_part',)
70
+
71
+
72
+ class ManufacturerPartAdmin(admin.ModelAdmin):
73
+ list_display = (
74
+ 'manufacturer_part_number',
75
+ 'manufacturer',
76
+ 'part',)
77
+ raw_id_fields = ('manufacturer', 'part',)
78
+ inlines = [
79
+ SellerPartAdminInline,
80
+ ]
81
+
82
+
83
+ class ManufacturerPartAdminInline(admin.TabularInline):
84
+ model = ManufacturerPart
85
+ raw_id_fields = ('part', 'manufacturer',)
86
+
87
+
88
+ class PartClassAdmin(admin.ModelAdmin):
89
+ list_display = ('code', 'name', 'comment',)
90
+
91
+
92
+ class PartRevisionAdminInline(admin.TabularInline):
93
+ model = PartRevision
94
+ extra = 0
95
+ raw_id_fields = ('assembly',)
96
+ readonly_fields = ('timestamp',)
97
+ show_change_link = True
98
+
99
+
100
+ class PartAdmin(admin.ModelAdmin):
101
+ ordering = ('organization', 'number_class__code', 'number_item', 'number_variation')
102
+ readonly_fields = ('get_full_part_number',)
103
+ list_display = (
104
+ 'organization',
105
+ 'get_full_part_number',
106
+ )
107
+ list_filter = ('organization', 'number_class',)
108
+ raw_id_fields = ('number_class', 'primary_manufacturer_part',)
109
+ inlines = [
110
+ PartRevisionAdminInline,
111
+ ManufacturerPartAdminInline,
112
+ ]
113
+
114
+ def get_full_part_number(self, obj):
115
+ return obj.full_part_number()
116
+
117
+ get_full_part_number.short_description = 'PartNumber'
118
+ get_full_part_number.admin_order_field = 'number_class__part_number'
119
+
120
+
121
+ class QuantityOfMeasureAdmin(admin.ModelAdmin):
122
+ list_display = ('name', 'organization')
123
+ list_filter = ('organization',)
124
+
125
+
126
+ class PartRevisionPropertyInline(admin.TabularInline):
127
+ model = PartRevisionProperty
128
+ extra = 1
129
+ raw_id_fields = ('property_definition', 'part_revision', 'unit_definition')
130
+
131
+
132
+ class PartRevisionAdmin(admin.ModelAdmin):
133
+ list_display = ('part', 'revision', 'description', 'get_assembly_size', 'timestamp',)
134
+ raw_id_fields = ('assembly',)
135
+ readonly_fields = ('timestamp',)
136
+ inlines = [PartRevisionPropertyInline]
137
+
138
+ def get_assembly_size(self, obj):
139
+ return None if obj.assembly is None else obj.assembly.subparts.count()
140
+
141
+ get_assembly_size.short_description = 'AssemblySize'
142
+
143
+
144
+ class ManufacturerAdmin(admin.ModelAdmin):
145
+ list_display = ('name', 'organization',)
146
+
147
+
148
+ class SubpartAdmin(admin.ModelAdmin):
149
+ list_display = ('part_revision', 'count', 'reference',)
150
+
151
+
152
+ class SubpartsInline(admin.TabularInline):
153
+ model = Assembly.subparts.through
154
+ raw_id_fields = ('subpart',)
155
+
156
+
157
+ class AssemblyAdmin(admin.ModelAdmin):
158
+ list_display = ('id',)
159
+ exclude = ('subparts',)
160
+ inlines = [
161
+ SubpartsInline,
162
+ ]
163
+
164
+
165
+ class UnitDefinitionAdmin(admin.ModelAdmin):
166
+ list_display = ('name', 'symbol', 'quantity_of_measure', 'base_multiplier', 'organization')
167
+ list_filter = ('organization',)
168
+
169
+
170
+ class PartRevisionPropertyDefinitionAdmin(admin.ModelAdmin):
171
+ list_display = ('code', 'name', 'type', 'organization', 'quantity_of_measure')
172
+ list_filter = ('organization',)
173
+
174
+
175
+ if settings.BOM_USER_META_MODEL == 'bom.UserMeta':
176
+ current_user_admin = admin.site._registry.get(User)
177
+
178
+ if current_user_admin:
179
+ user_admin_class = current_user_admin.__class__
180
+ existing_inlines = list(user_admin_class.inlines or [])
181
+ if UserMetaInline not in existing_inlines:
182
+ existing_inlines.append(UserMetaInline)
183
+ user_admin_class.inlines = existing_inlines
184
+ else:
185
+ class BomUserAdmin(UserAdmin):
186
+ inlines = [UserMetaInline]
187
+
188
+
189
+ admin.site.register(User, BomUserAdmin)
190
+
191
+ if settings.BOM_ORGANIZATION_MODEL == 'bom.Organization':
192
+ from .models import Organization
193
+
194
+ admin.site.register(Organization, OrganizationAdmin)
195
+
196
+ admin.site.register(Seller, SellerAdmin)
197
+ admin.site.register(SellerPart, SellerPartAdmin)
198
+ admin.site.register(ManufacturerPart, ManufacturerPartAdmin)
199
+ admin.site.register(PartClass, PartClassAdmin)
200
+ admin.site.register(Part, PartAdmin)
201
+ admin.site.register(PartRevision, PartRevisionAdmin)
202
+ admin.site.register(Manufacturer, ManufacturerAdmin)
203
+ admin.site.register(Assembly, AssemblyAdmin)
204
+ admin.site.register(Subpart, SubpartAdmin)
205
+ admin.site.register(UnitDefinition, UnitDefinitionAdmin)
206
+ admin.site.register(PartRevisionPropertyDefinition, PartRevisionPropertyDefinitionAdmin)
207
+ admin.site.register(QuantityOfMeasure, QuantityOfMeasureAdmin)
bom/apps.py ADDED
@@ -0,0 +1,8 @@
1
+ from __future__ import unicode_literals
2
+
3
+ from django.apps import AppConfig
4
+
5
+
6
+ class BomConfig(AppConfig):
7
+ name = 'bom'
8
+ mouser_api_key = None
bom/auth_backends.py ADDED
@@ -0,0 +1,47 @@
1
+ from typing import Optional
2
+
3
+ from . import constants
4
+ from .models import get_organization_model
5
+
6
+ Organization = get_organization_model()
7
+
8
+
9
+ class OrganizationPermissionBackend:
10
+ """
11
+ Object-level permission backend for django-bom.
12
+
13
+ - Uses Django's has_perm(user, perm, obj) to evaluate permissions tied to an Organization.
14
+ - Superusers are granted all permissions.
15
+ - For `bom.manage_members`: User must be owner or admin within the organization.
16
+ """
17
+
18
+ def authenticate(self, request, **credentials): # pragma: no cover - not used for auth
19
+ return None
20
+
21
+ def has_perm(self, user_obj, perm: str, obj: Optional[object] = None):
22
+ # Only handle our specific object-level permission. Let other backends process others.
23
+ if not user_obj or not user_obj.is_authenticated:
24
+ return False
25
+
26
+ if user_obj.is_superuser:
27
+ return True
28
+
29
+ if perm != 'bom.manage_members':
30
+ return None
31
+
32
+ if obj is None or not isinstance(obj, Organization):
33
+ return False
34
+
35
+ profile = user_obj.bom_profile()
36
+ if not profile or profile.organization_id != obj.id:
37
+ return False
38
+
39
+ if obj.subscription != constants.SUBSCRIPTION_TYPE_PRO:
40
+ return False
41
+
42
+ is_owner = obj.owner_id == user_obj.id
43
+ is_admin = getattr(profile, 'role', None) == constants.ROLE_TYPE_ADMIN
44
+ if not (is_owner or is_admin):
45
+ return False
46
+
47
+ return True
bom/base_classes.py ADDED
@@ -0,0 +1,31 @@
1
+ from collections import OrderedDict
2
+ from django.forms.models import model_to_dict
3
+
4
+
5
+ class AsDictModel:
6
+ def as_dict(self):
7
+ try:
8
+ return model_to_dict(self)
9
+ except (TypeError, AttributeError):
10
+ return dict(self)
11
+
12
+ def __iter__(self):
13
+ for key in dir(self):
14
+ if not key.startswith("_") and not key == "objects":
15
+ value = getattr(self, key)
16
+ if not callable(value):
17
+ if isinstance(value, (dict, OrderedDict)):
18
+ for subkey, subvalue in value.items():
19
+ try:
20
+ value[subkey] = subvalue.as_dict()
21
+ except AttributeError:
22
+ pass
23
+ yield key, value
24
+ else:
25
+ try:
26
+ yield key, value.as_dict()
27
+ except AttributeError:
28
+ if isinstance(value, (int, float, complex, bool)):
29
+ yield key, value
30
+ else:
31
+ yield key, str(value)
bom/constants.py ADDED
@@ -0,0 +1,217 @@
1
+ NO_CHOICE = ('', '-----')
2
+
3
+ SUBSCRIPTION_TYPE_FREE = 'F'
4
+ SUBSCRIPTION_TYPE_PRO = 'P'
5
+ SUBSCRIPTION_TYPES = ((SUBSCRIPTION_TYPE_FREE, 'Free'), (SUBSCRIPTION_TYPE_PRO, 'Pro'),)
6
+
7
+ ROLE_TYPE_ADMIN = 'A'
8
+ ROLE_TYPE_VIEWER = 'V'
9
+ ROLE_TYPES = ((ROLE_TYPE_ADMIN, 'Admin'), (ROLE_TYPE_VIEWER, 'Viewer'),)
10
+
11
+ CONFIGURATION_TYPE_RELEASED = 'R'
12
+ CONFIGURATION_TYPE_WORKING = 'W'
13
+ CONFIGURATION_TYPES = ((CONFIGURATION_TYPE_RELEASED, 'Released'), (CONFIGURATION_TYPE_WORKING, 'Working'),)
14
+
15
+ NUMBER_SCHEME_INTELLIGENT = 'I'
16
+ NUMBER_SCHEME_SEMI_INTELLIGENT = 'S'
17
+ NUMBER_SCHEMES = ((NUMBER_SCHEME_INTELLIGENT, 'Intelligent'), (NUMBER_SCHEME_SEMI_INTELLIGENT, 'Semi-Intelligent'),)
18
+
19
+ NUMBER_CLASS_CODE_LEN_MIN = 2
20
+ NUMBER_CLASS_CODE_LEN_MAX = 16
21
+ NUMBER_CLASS_CODE_LEN_DEFAULT = 3
22
+ NUMBER_ITEM_LEN_MIN = 3
23
+ NUMBER_ITEM_LEN_MAX = 128
24
+ NUMBER_ITEM_LEN_DEFAULT = 4
25
+ NUMBER_VARIATION_LEN_MIN = 0
26
+ NUMBER_VARIATION_LEN_MAX = 16
27
+ NUMBER_VARIATION_LEN_DEFAULT = 2
28
+
29
+ DATA_SOURCE_OCTOPART = 'octopart'
30
+ DATA_SOURCE_MOUSER = 'mouser'
31
+ DATA_SOURCES = (
32
+ NO_CHOICE,
33
+ (DATA_SOURCE_OCTOPART, 'octopart'),
34
+ (DATA_SOURCE_MOUSER, 'mouser'),
35
+ )
36
+
37
+ PART_REVISION_PROPERTY_TYPE_STRING = 'S'
38
+ PART_REVISION_PROPERTY_TYPE_DECIMAL = 'D'
39
+ PART_REVISION_PROPERTY_TYPE_BOOLEAN = 'B'
40
+ PART_REVISION_PROPERTY_TYPES = ((PART_REVISION_PROPERTY_TYPE_STRING, 'String'),
41
+ (PART_REVISION_PROPERTY_TYPE_DECIMAL, 'Number'),
42
+ (PART_REVISION_PROPERTY_TYPE_BOOLEAN, 'Boolean'),)
43
+
44
+ VALUE_UNITS = (
45
+ NO_CHOICE,
46
+ ('Ohms', '\u03A9'),
47
+ ('mOhms', 'm\u03A9'),
48
+ ('kOhms', 'k\u03A9'),
49
+ ('MOhms', 'M\u03A9'),
50
+ ('F', 'F'),
51
+ ('pF', 'pF'),
52
+ ('nF', 'nF'),
53
+ ('uF', '\u03BCF'),
54
+ ('V', 'V'),
55
+ ('uV', '\u03BCV'),
56
+ ('mV', 'mV'),
57
+ ('A', 'A'),
58
+ ('uA', '\u03BCA'),
59
+ ('mA', 'mA'),
60
+ ('C', '\u00B0C'),
61
+ ('F', '\u00B0F'),
62
+ ('H', 'H'),
63
+ ('nH', 'nH'),
64
+ ('mH', 'mH'),
65
+ ('uH', '\u03BCH'),
66
+ ('Hz', 'Hz'),
67
+ ('kHz', 'kHz'),
68
+ ('MHz', 'MHz'),
69
+ ('GHz', 'GHz'),
70
+ ('Other', 'Other'),
71
+ )
72
+
73
+ PACKAGE_TYPES = (
74
+ NO_CHOICE,
75
+ ('0201 smd', '0201 smd'),
76
+ ('0402 smd', '0402 smd'),
77
+ ('0603 smd', '0603 smd'),
78
+ ('0805 smd', '0805 smd'),
79
+ ('1206 smd', '1206 smd'),
80
+ ('1210 smd', '1210 smd'),
81
+ ('1812 smd', '1812 smd'),
82
+ ('2010 smd', '2010 smd'),
83
+ ('2512 smd', '2512 smd'),
84
+ ('1/8 radial', '1/8 radial'),
85
+ ('1/4 radial', '1/4 radial'),
86
+ ('1/2 radial', '1/2 radial'),
87
+ ('Size A', 'Size A'),
88
+ ('Size B', 'Size B'),
89
+ ('Size C', 'Size C'),
90
+ ('Size D', 'Size D'),
91
+ ('Size E', 'Size E'),
92
+ ('SOT-23', 'SOT-23'),
93
+ ('SOT-223', 'SOT-233'),
94
+ ('DIL', 'DIL'),
95
+ ('SOP', 'SOP'),
96
+ ('SOIC', 'SOIC'),
97
+ ('QFN', 'QFN'),
98
+ ('QFP', 'QFP'),
99
+ ('QFT', 'QFT'),
100
+ ('PLCC', 'PLCC'),
101
+ ('VGA', 'VGA'),
102
+ ('BGA', 'BGA'),
103
+ ('CSP', 'CSP'),
104
+ ('Other', 'Other'),
105
+ )
106
+
107
+ DISTANCE_UNITS = (
108
+ NO_CHOICE,
109
+ ('mil', 'mil'),
110
+ ('in', 'in'),
111
+ ('ft', 'ft'),
112
+ ('yd', 'yd'),
113
+ ('km', 'km'),
114
+ ('m', 'm'),
115
+ ('cm', 'cm'),
116
+ ('mm', 'mm'),
117
+ ('um', '\u03BCm'),
118
+ ('nm', 'nm'),
119
+ ('Other', 'Other'),
120
+ )
121
+
122
+ WEIGHT_UNITS = (
123
+ NO_CHOICE,
124
+ ('mg', 'mg'),
125
+ ('g', 'g'),
126
+ ('kg', 'kg'),
127
+ ('oz', 'oz'),
128
+ ('lb', 'lb'),
129
+ ('Other', 'Other'),
130
+ )
131
+
132
+ TEMPERATURE_UNITS = (
133
+ NO_CHOICE,
134
+ ('C', '\u00B0C'),
135
+ ('F', '\u00B0F'),
136
+ ('Other', 'Other'),
137
+ )
138
+
139
+ WAVELENGTH_UNITS = (
140
+ NO_CHOICE,
141
+ ('km', 'km'),
142
+ ('m', 'm'),
143
+ ('cm', 'cm'),
144
+ ('mm', 'mm'),
145
+ ('um', '\u03BCm'),
146
+ ('nm', 'nm'),
147
+ ('A', '\u212B'),
148
+ ('Other', 'Other'),
149
+ )
150
+
151
+ FREQUENCY_UNITS = (
152
+ NO_CHOICE,
153
+ ('Hz', 'Hz'),
154
+ ('kHz', 'kHz'),
155
+ ('MHz', 'MHz'),
156
+ ('GHz', 'GHz'),
157
+ ('Other', 'Other'),
158
+ )
159
+
160
+ MEMORY_UNITS = (
161
+ NO_CHOICE,
162
+ ('KB', 'KB'),
163
+ ('MB', 'MB'),
164
+ ('GB', 'GB'),
165
+ ('TB', 'TB'),
166
+ ('Other', 'Other'),
167
+ )
168
+
169
+ INTERFACE_TYPES = (
170
+ NO_CHOICE,
171
+ ('I2C', 'I2C'),
172
+ ('SPI', 'SPI'),
173
+ ('CAN', 'CAN'),
174
+ ('One-Wire', '1-Wire'),
175
+ ('RS485', 'RS-485'),
176
+ ('RS232', 'RS-232'),
177
+ ('WiFi', 'Wi-Fi'),
178
+ ('4G', '4G'),
179
+ ('BT', 'Bluetooth'),
180
+ ('BTLE', 'Bluetooth LE'),
181
+ ('Z_Wave', 'Z-Wave'),
182
+ ('Zigbee', 'Zigbee'),
183
+ ('LAN', 'LAN'),
184
+ ('USB', 'USB'),
185
+ ('HDMI', 'HDMI'),
186
+ ('Other', 'Other'),
187
+ )
188
+
189
+ POWER_UNITS = (
190
+ NO_CHOICE,
191
+ ('W', 'W'),
192
+ ('uW', '\u03BCW'),
193
+ ('mW', 'mW'),
194
+ ('kW', 'kW'),
195
+ ('MW', 'MW'),
196
+ ('Other', 'Other'),
197
+ )
198
+
199
+ VOLTAGE_UNITS = (
200
+ NO_CHOICE,
201
+ ('V', 'V'),
202
+ ('uV', '\u03BCV'),
203
+ ('mV', 'mV'),
204
+ ('kV', 'kV'),
205
+ ('MV', 'MV'),
206
+ ('Other', 'Other'),
207
+ )
208
+
209
+ CURRENT_UNITS = (
210
+ NO_CHOICE,
211
+ ('A', 'A'),
212
+ ('uA', '\u03BCV'),
213
+ ('mA', 'mA'),
214
+ ('kA', 'kA'),
215
+ ('MA', 'MA'),
216
+ ('Other', 'Other'),
217
+ )
@@ -0,0 +1,9 @@
1
+ from django.conf import settings # import the settings file
2
+
3
+
4
+ def bom_config(request):
5
+ base_template = 'bom/base.html'
6
+ if settings.BOM_CONFIG:
7
+ if 'base_template' in settings.BOM_CONFIG:
8
+ base_template = settings.BOM_CONFIG['base_template']
9
+ return {'BASE_TEMPLATE': base_template}