django-bom 1.228__tar.gz → 1.238__tar.gz

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.
Files changed (200) hide show
  1. {django-bom-1.228/django_bom.egg-info → django_bom-1.238}/PKG-INFO +27 -20
  2. {django-bom-1.228 → django_bom-1.238}/README.md +7 -8
  3. {django-bom-1.228 → django_bom-1.238}/bom/admin.py +1 -0
  4. django_bom-1.238/bom/auth_backends.py +45 -0
  5. {django-bom-1.228 → django_bom-1.238}/bom/constants.py +2 -0
  6. {django-bom-1.228 → django_bom-1.238}/bom/csv_headers.py +1 -0
  7. {django-bom-1.228 → django_bom-1.238}/bom/forms.py +2 -1
  8. {django-bom-1.228 → django_bom-1.238}/bom/helpers.py +2 -1
  9. django_bom-1.238/bom/local_settings.py +35 -0
  10. django_bom-1.238/bom/migrations/0046_alter_sellerpart_unique_together.py +17 -0
  11. django_bom-1.238/bom/migrations/0047_sellerpart_seller_part_number.py +18 -0
  12. django_bom-1.238/bom/migrations/0048_rename_part_organization_number_class_bom_part_organiz_b333d6_idx_and_more.py +1017 -0
  13. django_bom-1.238/bom/migrations/0049_alter_assembly_id_alter_assemblysubparts_id_and_more.py +99 -0
  14. {django-bom-1.228 → django_bom-1.238}/bom/models.py +55 -80
  15. {django-bom-1.228 → django_bom-1.238}/bom/part_bom.py +1 -0
  16. django_bom-1.238/bom/settings.py +264 -0
  17. {django-bom-1.228 → django_bom-1.238}/bom/static/bom/css/style.css +11 -0
  18. django_bom-1.238/bom/static/bom/doc/test_full_bom.csv +37 -0
  19. django_bom-1.238/bom/templates/bom/account-delete.html +23 -0
  20. {django-bom-1.228 → django_bom-1.238}/bom/templates/bom/add-manufacturer-part.html +2 -5
  21. {django-bom-1.228 → django_bom-1.238}/bom/templates/bom/add-sellerpart.html +9 -5
  22. {django-bom-1.228 → django_bom-1.238}/bom/templates/bom/base-menu.html +10 -1
  23. {django-bom-1.228 → django_bom-1.238}/bom/templates/bom/bom-action-table.html +2 -2
  24. {django-bom-1.228 → django_bom-1.238}/bom/templates/bom/bom-form-modal.html +3 -2
  25. {django-bom-1.228 → django_bom-1.238}/bom/templates/bom/bom-form.html +1 -5
  26. django_bom-1.238/bom/templates/bom/bom-modal-add-users.html +49 -0
  27. {django-bom-1.228 → django_bom-1.238}/bom/templates/bom/bom-signup.html +0 -4
  28. {django-bom-1.228 → django_bom-1.238}/bom/templates/bom/components/bom-flat.html +2 -2
  29. {django-bom-1.228 → django_bom-1.238}/bom/templates/bom/components/bom-indented.html +3 -3
  30. {django-bom-1.228 → django_bom-1.238}/bom/templates/bom/components/manufacturer-part-list.html +6 -2
  31. {django-bom-1.228 → django_bom-1.238}/bom/templates/bom/components/seller-part-list.html +2 -1
  32. {django-bom-1.228 → django_bom-1.238}/bom/templates/bom/create-part.html +2 -5
  33. {django-bom-1.228 → django_bom-1.238}/bom/templates/bom/dashboard.html +6 -3
  34. {django-bom-1.228 → django_bom-1.238}/bom/templates/bom/edit-manufacturer-part.html +2 -5
  35. {django-bom-1.228 → django_bom-1.238}/bom/templates/bom/edit-part-class.html +2 -5
  36. {django-bom-1.228 → django_bom-1.238}/bom/templates/bom/edit-part.html +2 -6
  37. {django-bom-1.228 → django_bom-1.238}/bom/templates/bom/edit-user-meta.html +2 -5
  38. {django-bom-1.228 → django_bom-1.238}/bom/templates/bom/help.html +2 -9
  39. {django-bom-1.228 → django_bom-1.238}/bom/templates/bom/manufacturer-info.html +1 -2
  40. {django-bom-1.228 → django_bom-1.238}/bom/templates/bom/manufacturers.html +3 -2
  41. {django-bom-1.228 → django_bom-1.238}/bom/templates/bom/organization-create.html +2 -5
  42. {django-bom-1.228 → django_bom-1.238}/bom/templates/bom/part-info.html +3 -4
  43. {django-bom-1.228 → django_bom-1.238}/bom/templates/bom/part-revision-edit.html +2 -5
  44. {django-bom-1.228 → django_bom-1.238}/bom/templates/bom/part-revision-manage-bom.html +1 -2
  45. {django-bom-1.228 → django_bom-1.238}/bom/templates/bom/part-revision-new.html +2 -5
  46. {django-bom-1.228 → django_bom-1.238}/bom/templates/bom/part-revision-release.html +0 -7
  47. {django-bom-1.228 → django_bom-1.238}/bom/templates/bom/search-help.html +0 -4
  48. {django-bom-1.228 → django_bom-1.238}/bom/templates/bom/seller-info.html +1 -2
  49. {django-bom-1.228 → django_bom-1.238}/bom/templates/bom/sellers.html +3 -2
  50. {django-bom-1.228 → django_bom-1.238}/bom/templates/bom/settings.html +35 -32
  51. {django-bom-1.228 → django_bom-1.238}/bom/templates/bom/signup.html +1 -1
  52. {django-bom-1.228 → django_bom-1.238}/bom/templates/bom/upload-bom.html +0 -1
  53. {django-bom-1.228 → django_bom-1.238}/bom/templates/bom/upload-parts-help.html +3 -6
  54. {django-bom-1.228 → django_bom-1.238}/bom/templates/bom/upload-parts.html +0 -4
  55. {django-bom-1.228 → django_bom-1.238}/bom/tests.py +11 -6
  56. {django-bom-1.228 → django_bom-1.238}/bom/third_party_apis/mouser.py +1 -0
  57. {django-bom-1.228 → django_bom-1.238}/bom/urls.py +14 -8
  58. {django-bom-1.228 → django_bom-1.238}/bom/views/views.py +13 -7
  59. {django-bom-1.228 → django_bom-1.238/django_bom.egg-info}/PKG-INFO +27 -20
  60. {django-bom-1.228 → django_bom-1.238}/django_bom.egg-info/SOURCES.txt +8 -5
  61. django_bom-1.238/django_bom.egg-info/requires.txt +6 -0
  62. django_bom-1.238/pyproject.toml +70 -0
  63. django_bom-1.238/setup.cfg +4 -0
  64. django-bom-1.228/bom/local_settings.py +0 -41
  65. django-bom-1.228/bom/settings.py +0 -225
  66. django-bom-1.228/bom/static/.DS_Store +0 -0
  67. django-bom-1.228/bom/static/bom/.DS_Store +0 -0
  68. django-bom-1.228/bom/static/bom/doc/test_full_bom.csv +0 -36
  69. django-bom-1.228/bom/static/bom/img/.DS_Store +0 -0
  70. django-bom-1.228/django_bom.egg-info/requires.txt +0 -5
  71. django-bom-1.228/setup.cfg +0 -25
  72. django-bom-1.228/setup.py +0 -43
  73. {django-bom-1.228 → django_bom-1.238}/LICENSE +0 -0
  74. {django-bom-1.228 → django_bom-1.238}/MANIFEST.in +0 -0
  75. {django-bom-1.228 → django_bom-1.238}/bom/__init__.py +0 -0
  76. {django-bom-1.228 → django_bom-1.238}/bom/apps.py +0 -0
  77. {django-bom-1.228 → django_bom-1.238}/bom/base_classes.py +0 -0
  78. {django-bom-1.228 → django_bom-1.238}/bom/context_processors.py +0 -0
  79. {django-bom-1.228 → django_bom-1.238}/bom/decorators.py +0 -0
  80. {django-bom-1.228 → django_bom-1.238}/bom/form_fields.py +0 -0
  81. {django-bom-1.228 → django_bom-1.238}/bom/migrations/0001_initial.py +0 -0
  82. {django-bom-1.228 → django_bom-1.238}/bom/migrations/0002_auto_20180908_2151.py +0 -0
  83. {django-bom-1.228 → django_bom-1.238}/bom/migrations/0003_sellerpart_data_source.py +0 -0
  84. {django-bom-1.228 → django_bom-1.238}/bom/migrations/0004_auto_20180911_0011.py +0 -0
  85. {django-bom-1.228 → django_bom-1.238}/bom/migrations/0005_auto_20181007_1934.py +0 -0
  86. {django-bom-1.228 → django_bom-1.238}/bom/migrations/0006_auto_20181007_1949.py +0 -0
  87. {django-bom-1.228 → django_bom-1.238}/bom/migrations/0007_auto_20181009_0256.py +0 -0
  88. {django-bom-1.228 → django_bom-1.238}/bom/migrations/0008_auto_20181030_0427.py +0 -0
  89. {django-bom-1.228 → django_bom-1.238}/bom/migrations/0009_subpart_reference.py +0 -0
  90. {django-bom-1.228 → django_bom-1.238}/bom/migrations/0010_auto_20181202_0733.py +0 -0
  91. {django-bom-1.228 → django_bom-1.238}/bom/migrations/0011_auto_20181202_2113.py +0 -0
  92. {django-bom-1.228 → django_bom-1.238}/bom/migrations/0012_partchangehistory.py +0 -0
  93. {django-bom-1.228 → django_bom-1.238}/bom/migrations/0013_auto_20190222_1631.py +0 -0
  94. {django-bom-1.228 → django_bom-1.238}/bom/migrations/0014_auto_20190223_2353.py +0 -0
  95. {django-bom-1.228 → django_bom-1.238}/bom/migrations/0015_auto_20190303_1915.py +0 -0
  96. {django-bom-1.228 → django_bom-1.238}/bom/migrations/0016_auto_20190405_2308.py +0 -0
  97. {django-bom-1.228 → django_bom-1.238}/bom/migrations/0017_auto_20190616_1912.py +0 -0
  98. {django-bom-1.228 → django_bom-1.238}/bom/migrations/0018_auto_20190616_2143.py +0 -0
  99. {django-bom-1.228 → django_bom-1.238}/bom/migrations/0019_auto_20190624_1246.py +0 -0
  100. {django-bom-1.228 → django_bom-1.238}/bom/migrations/0020_auto_20190627_0207.py +0 -0
  101. {django-bom-1.228 → django_bom-1.238}/bom/migrations/0021_auto_20190627_0428.py +0 -0
  102. {django-bom-1.228 → django_bom-1.238}/bom/migrations/0022_auto_20190811_2140.py +0 -0
  103. {django-bom-1.228 → django_bom-1.238}/bom/migrations/0023_auto_20191205_2351.py +0 -0
  104. {django-bom-1.228 → django_bom-1.238}/bom/migrations/0024_auto_20191214_1342.py +0 -0
  105. {django-bom-1.228 → django_bom-1.238}/bom/migrations/0025_auto_20191221_1907.py +0 -0
  106. {django-bom-1.228 → django_bom-1.238}/bom/migrations/0026_auto_20191222_2258.py +0 -0
  107. {django-bom-1.228 → django_bom-1.238}/bom/migrations/0027_auto_20191222_2347.py +0 -0
  108. {django-bom-1.228 → django_bom-1.238}/bom/migrations/0028_partrevision_displayable_synopsis.py +0 -0
  109. {django-bom-1.228 → django_bom-1.238}/bom/migrations/0029_auto_20191231_1630.py +0 -0
  110. {django-bom-1.228 → django_bom-1.238}/bom/migrations/0030_auto_20200101_2253.py +0 -0
  111. {django-bom-1.228 → django_bom-1.238}/bom/migrations/0031_auto_20200104_1352.py +0 -0
  112. {django-bom-1.228 → django_bom-1.238}/bom/migrations/0032_auto_20200126_1806.py +0 -0
  113. {django-bom-1.228 → django_bom-1.238}/bom/migrations/0033_auto_20200203_0618.py +0 -0
  114. {django-bom-1.228 → django_bom-1.238}/bom/migrations/0034_auto_20200222_0359.py +0 -0
  115. {django-bom-1.228 → django_bom-1.238}/bom/migrations/0035_auto_20200303_0111.py +0 -0
  116. {django-bom-1.228 → django_bom-1.238}/bom/migrations/0036_auto_20200303_0538.py +0 -0
  117. {django-bom-1.228 → django_bom-1.238}/bom/migrations/0037_auto_20200405_1642.py +0 -0
  118. {django-bom-1.228 → django_bom-1.238}/bom/migrations/0038_auto_20200422_0504.py +0 -0
  119. {django-bom-1.228 → django_bom-1.238}/bom/migrations/0039_auto_20200929_2315.py +0 -0
  120. {django-bom-1.228 → django_bom-1.238}/bom/migrations/0040_alter_organization_currency.py +0 -0
  121. {django-bom-1.228 → django_bom-1.238}/bom/migrations/0041_organization_subscription_quantity.py +0 -0
  122. {django-bom-1.228 → django_bom-1.238}/bom/migrations/0042_auto_20210720_2137.py +0 -0
  123. {django-bom-1.228 → django_bom-1.238}/bom/migrations/0043_auto_20211123_0157.py +0 -0
  124. {django-bom-1.228 → django_bom-1.238}/bom/migrations/0044_auto_20220831_1241.py +0 -0
  125. {django-bom-1.228 → django_bom-1.238}/bom/migrations/0045_sellerpart_link.py +0 -0
  126. {django-bom-1.228 → django_bom-1.238}/bom/migrations/__init__.py +0 -0
  127. {django-bom-1.228 → django_bom-1.238}/bom/static/bom/css/dashboard.css +0 -0
  128. {django-bom-1.228 → django_bom-1.238}/bom/static/bom/css/jquery.treetable.css +0 -0
  129. {django-bom-1.228 → django_bom-1.238}/bom/static/bom/css/materialize.min.css +0 -0
  130. {django-bom-1.228 → django_bom-1.238}/bom/static/bom/css/part-info.css +0 -0
  131. {django-bom-1.228 → django_bom-1.238}/bom/static/bom/css/tablesorter-theme.materialize.css +0 -0
  132. {django-bom-1.228 → django_bom-1.238}/bom/static/bom/css/treetable-theme.css +0 -0
  133. {django-bom-1.228 → django_bom-1.238}/bom/static/bom/doc/sample_part_classes.csv +0 -0
  134. {django-bom-1.228 → django_bom-1.238}/bom/static/bom/doc/test_bom.csv +0 -0
  135. {django-bom-1.228 → django_bom-1.238}/bom/static/bom/doc/test_bom_5_intelligent.csv +0 -0
  136. {django-bom-1.228 → django_bom-1.238}/bom/static/bom/doc/test_new_parts.csv +0 -0
  137. {django-bom-1.228 → django_bom-1.238}/bom/static/bom/doc/test_new_parts_5_intelligent.csv +0 -0
  138. {django-bom-1.228 → django_bom-1.238}/bom/static/bom/img/_ionicons_svg_md-arrow-dropdown.svg +0 -0
  139. {django-bom-1.228 → django_bom-1.238}/bom/static/bom/img/_ionicons_svg_md-arrow-dropright.svg +0 -0
  140. {django-bom-1.228 → django_bom-1.238}/bom/static/bom/img/favicon.ico +0 -0
  141. {django-bom-1.228 → django_bom-1.238}/bom/static/bom/img/google/web/1x/btn_google_signin_dark_disabled_web.png +0 -0
  142. {django-bom-1.228 → django_bom-1.238}/bom/static/bom/img/google/web/1x/btn_google_signin_dark_focus_web.png +0 -0
  143. {django-bom-1.228 → django_bom-1.238}/bom/static/bom/img/google/web/1x/btn_google_signin_dark_normal_web.png +0 -0
  144. {django-bom-1.228 → django_bom-1.238}/bom/static/bom/img/google/web/1x/btn_google_signin_dark_pressed_web.png +0 -0
  145. {django-bom-1.228 → django_bom-1.238}/bom/static/bom/img/google/web/1x/btn_google_signin_light_disabled_web.png +0 -0
  146. {django-bom-1.228 → django_bom-1.238}/bom/static/bom/img/google/web/1x/btn_google_signin_light_focus_web.png +0 -0
  147. {django-bom-1.228 → django_bom-1.238}/bom/static/bom/img/google/web/1x/btn_google_signin_light_normal_web.png +0 -0
  148. {django-bom-1.228 → django_bom-1.238}/bom/static/bom/img/google/web/1x/btn_google_signin_light_pressed_web.png +0 -0
  149. {django-bom-1.228 → django_bom-1.238}/bom/static/bom/img/google/web/2x/btn_google_signin_dark_disabled_web@2x.png +0 -0
  150. {django-bom-1.228 → django_bom-1.238}/bom/static/bom/img/google/web/2x/btn_google_signin_dark_focus_web@2x.png +0 -0
  151. {django-bom-1.228 → django_bom-1.238}/bom/static/bom/img/google/web/2x/btn_google_signin_dark_normal_web@2x.png +0 -0
  152. {django-bom-1.228 → django_bom-1.238}/bom/static/bom/img/google/web/2x/btn_google_signin_dark_pressed_web@2x.png +0 -0
  153. {django-bom-1.228 → django_bom-1.238}/bom/static/bom/img/google/web/2x/btn_google_signin_light_disabled_web@2x.png +0 -0
  154. {django-bom-1.228 → django_bom-1.238}/bom/static/bom/img/google/web/2x/btn_google_signin_light_focus_web@2x.png +0 -0
  155. {django-bom-1.228 → django_bom-1.238}/bom/static/bom/img/google/web/2x/btn_google_signin_light_normal_web@2x.png +0 -0
  156. {django-bom-1.228 → django_bom-1.238}/bom/static/bom/img/google/web/2x/btn_google_signin_light_pressed_web@2x.png +0 -0
  157. {django-bom-1.228 → django_bom-1.238}/bom/static/bom/img/google/web/vector/btn_google_dark_disabled_ios.eps +0 -0
  158. {django-bom-1.228 → django_bom-1.238}/bom/static/bom/img/google/web/vector/btn_google_dark_disabled_ios.svg +0 -0
  159. {django-bom-1.228 → django_bom-1.238}/bom/static/bom/img/google/web/vector/btn_google_dark_focus_ios.eps +0 -0
  160. {django-bom-1.228 → django_bom-1.238}/bom/static/bom/img/google/web/vector/btn_google_dark_focus_ios.svg +0 -0
  161. {django-bom-1.228 → django_bom-1.238}/bom/static/bom/img/google/web/vector/btn_google_dark_normal_ios.eps +0 -0
  162. {django-bom-1.228 → django_bom-1.238}/bom/static/bom/img/google/web/vector/btn_google_dark_normal_ios.svg +0 -0
  163. {django-bom-1.228 → django_bom-1.238}/bom/static/bom/img/google/web/vector/btn_google_dark_pressed_ios.eps +0 -0
  164. {django-bom-1.228 → django_bom-1.238}/bom/static/bom/img/google/web/vector/btn_google_dark_pressed_ios.svg +0 -0
  165. {django-bom-1.228 → django_bom-1.238}/bom/static/bom/img/google/web/vector/btn_google_light_disabled_ios.eps +0 -0
  166. {django-bom-1.228 → django_bom-1.238}/bom/static/bom/img/google/web/vector/btn_google_light_disabled_ios.svg +0 -0
  167. {django-bom-1.228 → django_bom-1.238}/bom/static/bom/img/google/web/vector/btn_google_light_focus_ios.eps +0 -0
  168. {django-bom-1.228 → django_bom-1.238}/bom/static/bom/img/google/web/vector/btn_google_light_focus_ios.svg +0 -0
  169. {django-bom-1.228 → django_bom-1.238}/bom/static/bom/img/google/web/vector/btn_google_light_normal_ios.eps +0 -0
  170. {django-bom-1.228 → django_bom-1.238}/bom/static/bom/img/google/web/vector/btn_google_light_normal_ios.svg +0 -0
  171. {django-bom-1.228 → django_bom-1.238}/bom/static/bom/img/google/web/vector/btn_google_light_pressed_ios.eps +0 -0
  172. {django-bom-1.228 → django_bom-1.238}/bom/static/bom/img/google/web/vector/btn_google_light_pressed_ios.svg +0 -0
  173. {django-bom-1.228 → django_bom-1.238}/bom/static/bom/img/google_drive_logo.svg +0 -0
  174. {django-bom-1.228 → django_bom-1.238}/bom/static/bom/img/indabom.png +0 -0
  175. {django-bom-1.228 → django_bom-1.238}/bom/static/bom/img/mouser.png +0 -0
  176. {django-bom-1.228 → django_bom-1.238}/bom/static/bom/img/octopart_blue.svg +0 -0
  177. {django-bom-1.228 → django_bom-1.238}/bom/static/bom/js/jquery-3.4.1.min.js +0 -0
  178. {django-bom-1.228 → django_bom-1.238}/bom/static/bom/js/jquery.ba-floatingscrollbar.min.js +0 -0
  179. {django-bom-1.228 → django_bom-1.238}/bom/static/bom/js/jquery.treetable.js +0 -0
  180. {django-bom-1.228 → django_bom-1.238}/bom/static/bom/js/materialize.min.js +0 -0
  181. {django-bom-1.228 → django_bom-1.238}/bom/templates/bom/base.html +0 -0
  182. {django-bom-1.228 → django_bom-1.238}/bom/templates/bom/bom-action-btn.html +0 -0
  183. {django-bom-1.228 → django_bom-1.238}/bom/templates/bom/bom-base-menu.html +0 -0
  184. {django-bom-1.228 → django_bom-1.238}/bom/templates/bom/bom-base.html +0 -0
  185. {django-bom-1.228 → django_bom-1.238}/bom/templates/bom/dashboard-menu.html +0 -0
  186. {django-bom-1.228 → django_bom-1.238}/bom/templates/bom/nothing-to-see.html +0 -0
  187. {django-bom-1.228 → django_bom-1.238}/bom/templates/bom/part-revision-display.html +0 -0
  188. {django-bom-1.228 → django_bom-1.238}/bom/templates/bom/table_of_contents.html +0 -0
  189. {django-bom-1.228 → django_bom-1.238}/bom/templates/registration/login.html +0 -0
  190. {django-bom-1.228 → django_bom-1.238}/bom/third_party_apis/__init__.py +0 -0
  191. {django-bom-1.228 → django_bom-1.238}/bom/third_party_apis/base_api.py +0 -0
  192. {django-bom-1.228 → django_bom-1.238}/bom/third_party_apis/google_drive.py +0 -0
  193. {django-bom-1.228 → django_bom-1.238}/bom/third_party_apis/test_apis.py +0 -0
  194. {django-bom-1.228 → django_bom-1.238}/bom/utils.py +0 -0
  195. {django-bom-1.228 → django_bom-1.238}/bom/validators.py +0 -0
  196. {django-bom-1.228 → django_bom-1.238}/bom/views/__init__.py +0 -0
  197. {django-bom-1.228 → django_bom-1.238}/bom/views/json_views.py +0 -0
  198. {django-bom-1.228 → django_bom-1.238}/bom/wsgi.py +0 -0
  199. {django-bom-1.228 → django_bom-1.238}/django_bom.egg-info/dependency_links.txt +0 -0
  200. {django-bom-1.228 → django_bom-1.238}/django_bom.egg-info/top_level.txt +0 -0
@@ -1,24 +1,34 @@
1
- Metadata-Version: 2.1
1
+ Metadata-Version: 2.4
2
2
  Name: django-bom
3
- Version: 1.228
3
+ Version: 1.238
4
4
  Summary: A simple Django app to manage a bill of materials.
5
- Home-page: https://www.indabom.com/
6
- Author: Mike Kasparian
7
- Author-email: mpkasp@gmail.com
8
- License: GPL 3.0 License
9
- Platform: UNKNOWN
5
+ Author-email: Mike Kasparian <mpkasp@gmail.com>
6
+ License: GPL-3.0-only
7
+ Project-URL: Homepage, https://www.indabom.com/
10
8
  Classifier: Environment :: Web Environment
11
9
  Classifier: Framework :: Django
12
- Classifier: Framework :: Django :: 3.1
10
+ Classifier: Framework :: Django :: 5
13
11
  Classifier: Intended Audience :: Developers
14
- Classifier: License :: OSI Approved :: MIT License
12
+ Classifier: License :: OSI Approved :: GNU General Public License v3 (GPLv3)
15
13
  Classifier: Operating System :: OS Independent
16
14
  Classifier: Programming Language :: Python
17
- Classifier: Programming Language :: Python :: 3.7
15
+ Classifier: Programming Language :: Python :: 3
16
+ Classifier: Programming Language :: Python :: 3.10
17
+ Classifier: Programming Language :: Python :: 3.11
18
+ Classifier: Programming Language :: Python :: 3.12
19
+ Classifier: Programming Language :: Python :: 3 :: Only
18
20
  Classifier: Topic :: Internet :: WWW/HTTP
19
21
  Classifier: Topic :: Internet :: WWW/HTTP :: Dynamic Content
22
+ Requires-Python: >=3.10
20
23
  Description-Content-Type: text/markdown
21
24
  License-File: LICENSE
25
+ Requires-Dist: Django<5.3,>=5.2
26
+ Requires-Dist: social-auth-app-django<6,>=5
27
+ Requires-Dist: social-auth-core<6,>=4
28
+ Requires-Dist: google-api-python-client>=2
29
+ Requires-Dist: django-materializecss-form
30
+ Requires-Dist: django-money<5,>=3
31
+ Dynamic: license-file
22
32
 
23
33
  # BOM
24
34
  ![](https://github.com/mpkasp/django-bom/workflows/Django%20CI/badge.svg)
@@ -41,16 +51,15 @@ If you already have a django project, you can skip to [Add Django Bom To Your Ap
41
51
  * [Installation pitfalls](#installation-pitfalls)
42
52
 
43
53
  ## Start From Scratch: Add to a new Django project
44
- 1. To start from scratch we recommend setting up a virtual environment
54
+ 1. To start from scratch, install your pipenv using Python 3.12
45
55
  ```
46
- virtualenv -p python3 mysite
47
- cd mysite
48
- source bin/activate
56
+ pipenv --python 3.12
57
+ pipenv shell
49
58
  ```
50
59
 
51
60
  2. From here install django, and set up your project.
52
61
  ```
53
- pip install django
62
+ pipenv install django
54
63
  django-admin startproject mysite
55
64
  cd mysite
56
65
  python manage.py migrate
@@ -60,7 +69,7 @@ python manage.py createsuperuser # make a user for your development environment
60
69
  3. Continue on to [Add Django Bom To Your App](#add-django-bom-to-your-app).
61
70
 
62
71
  ## Add Django Bom To Your App
63
- django-bom is a [reusable django application](https://docs.djangoproject.com/en/1.11/intro/reusable-apps/). If you don't already have a django project, you can follow some quick steps below to get up and running, or read about creating your first django app [here](https://docs.djangoproject.com/en/1.11/intro/tutorial01/). Note that django-bom currently supports python 2.7.
72
+ django-bom is a [reusable django application](https://docs.djangoproject.com/en/1.11/intro/reusable-apps/). If you don't already have a django project, you can follow some quick steps below to get up and running, or read about creating your first django app [here](https://docs.djangoproject.com/en/1.11/intro/tutorial01/).
64
73
 
65
74
  ```
66
75
  pip install django-bom
@@ -110,7 +119,7 @@ TEMPLATES = [
110
119
  and
111
120
 
112
121
  ```
113
- BOM_CONFIG = {}
122
+ BOM_CONFIG = {'standalone_mode': False}
114
123
  ```
115
124
 
116
125
  4. Run `python manage.py migrate` to create the bom models.
@@ -132,7 +141,7 @@ source bin/activate
132
141
  2. From here install django, and set up your project.
133
142
  ```
134
143
  git clone https://github.com/mpkasp/django-bom.git
135
- pip install -r requirements.txt
144
+ pipenv install
136
145
  python manage.py migrate
137
146
  cp bom/local_settings.py.example bom/local_settings.py
138
147
  python manage.py runserver
@@ -195,5 +204,3 @@ You may get an error during your `pip install -r requirements.txt` related to sq
195
204
 
196
205
  #### Cryptography
197
206
  Sometimes you'll have issues installing cryptography, if this is the case you may just need to set up some environment variables. This [stackoverflow](https://stackoverflow.com/questions/46288737/error-while-installing-sqlite-using-pip-on-python-2-7-13) may help.
198
-
199
-
@@ -19,16 +19,15 @@ If you already have a django project, you can skip to [Add Django Bom To Your Ap
19
19
  * [Installation pitfalls](#installation-pitfalls)
20
20
 
21
21
  ## Start From Scratch: Add to a new Django project
22
- 1. To start from scratch we recommend setting up a virtual environment
22
+ 1. To start from scratch, install your pipenv using Python 3.12
23
23
  ```
24
- virtualenv -p python3 mysite
25
- cd mysite
26
- source bin/activate
24
+ pipenv --python 3.12
25
+ pipenv shell
27
26
  ```
28
27
 
29
28
  2. From here install django, and set up your project.
30
29
  ```
31
- pip install django
30
+ pipenv install django
32
31
  django-admin startproject mysite
33
32
  cd mysite
34
33
  python manage.py migrate
@@ -38,7 +37,7 @@ python manage.py createsuperuser # make a user for your development environment
38
37
  3. Continue on to [Add Django Bom To Your App](#add-django-bom-to-your-app).
39
38
 
40
39
  ## Add Django Bom To Your App
41
- django-bom is a [reusable django application](https://docs.djangoproject.com/en/1.11/intro/reusable-apps/). If you don't already have a django project, you can follow some quick steps below to get up and running, or read about creating your first django app [here](https://docs.djangoproject.com/en/1.11/intro/tutorial01/). Note that django-bom currently supports python 2.7.
40
+ django-bom is a [reusable django application](https://docs.djangoproject.com/en/1.11/intro/reusable-apps/). If you don't already have a django project, you can follow some quick steps below to get up and running, or read about creating your first django app [here](https://docs.djangoproject.com/en/1.11/intro/tutorial01/).
42
41
 
43
42
  ```
44
43
  pip install django-bom
@@ -88,7 +87,7 @@ TEMPLATES = [
88
87
  and
89
88
 
90
89
  ```
91
- BOM_CONFIG = {}
90
+ BOM_CONFIG = {'standalone_mode': False}
92
91
  ```
93
92
 
94
93
  4. Run `python manage.py migrate` to create the bom models.
@@ -110,7 +109,7 @@ source bin/activate
110
109
  2. From here install django, and set up your project.
111
110
  ```
112
111
  git clone https://github.com/mpkasp/django-bom.git
113
- pip install -r requirements.txt
112
+ pipenv install
114
113
  python manage.py migrate
115
114
  cp bom/local_settings.py.example bom/local_settings.py
116
115
  python manage.py runserver
@@ -52,6 +52,7 @@ class SellerPartAdmin(admin.ModelAdmin):
52
52
  list_display = (
53
53
  'manufacturer_part',
54
54
  'seller',
55
+ 'seller_part_number',
55
56
  'minimum_order_quantity',
56
57
  'minimum_pack_quantity',
57
58
  'unit_cost',
@@ -0,0 +1,45 @@
1
+ from typing import Optional
2
+
3
+ from . import constants
4
+ from .models import Organization
5
+
6
+
7
+ class OrganizationPermissionBackend:
8
+ """
9
+ Object-level permission backend for django-bom.
10
+
11
+ - Uses Django's has_perm(user, perm, obj) to evaluate permissions tied to an Organization.
12
+ - Superusers are granted all permissions.
13
+ - For `bom.manage_members`: User must be owner or admin within the organization.
14
+ """
15
+
16
+ def authenticate(self, request, **credentials): # pragma: no cover - not used for auth
17
+ return None
18
+
19
+ def has_perm(self, user_obj, perm: str, obj: Optional[object] = None):
20
+ # Only handle our specific object-level permission. Let other backends process others.
21
+ if not user_obj or not user_obj.is_authenticated:
22
+ return False
23
+
24
+ if user_obj.is_superuser:
25
+ return True
26
+
27
+ if perm != 'bom.manage_members':
28
+ return None
29
+
30
+ if obj is None or not isinstance(obj, Organization):
31
+ return False
32
+
33
+ profile = user_obj.bom_profile()
34
+ if not profile or profile.organization_id != obj.id:
35
+ return False
36
+
37
+ if obj.subscription != constants.SUBSCRIPTION_TYPE_PRO:
38
+ return False
39
+
40
+ is_owner = obj.owner_id == user_obj.id
41
+ is_admin = getattr(profile, 'role', None) == constants.ROLE_TYPE_ADMIN
42
+ if not (is_owner or is_admin):
43
+ return False
44
+
45
+ return True
@@ -92,6 +92,8 @@ PACKAGE_TYPES = (
92
92
  ('QFT', 'QFT'),
93
93
  ('PLCC', 'PLCC'),
94
94
  ('VGA', 'VGA'),
95
+ ('BGA', 'BGA'),
96
+ ('CSP', 'CSP'),
95
97
  ('Other', 'Other'),
96
98
  )
97
99
 
@@ -172,6 +172,7 @@ class ManufacturerPartCSVHeaders(CSVHeaders):
172
172
  class SellerPartCSVHeaders(CSVHeaders):
173
173
  all_headers_defns = [
174
174
  CSVHeader('seller', name_options=['part_seller', 'part_seller_name', ]),
175
+ CSVHeader('seller_part_number', name_options=['seller_pn', 'spn', 'pn', 'part_seller_part_number', 'seller_part_number', ]),
175
176
  CSVHeader('unit_cost', name_options=['seller_part_unit_cost', 'unit_cost', 'part_cost', ]),
176
177
  CSVHeader('minimum_order_quantity', name_options=['minimum_order_quantity', 'moq', 'part_moq', ]),
177
178
  CSVHeader('nre_cost', name_options=['part_nre', 'part_nre_cost', 'nre', 'nre_cost', ]),
@@ -571,6 +571,7 @@ class PartCSVForm(forms.Form):
571
571
  value = csv_headers.get_val_from_row(part_data, 'value')
572
572
  value_units = csv_headers.get_val_from_row(part_data, 'value_units')
573
573
  seller_name = csv_headers.get_val_from_row(part_data, 'seller')
574
+ seller_part_number = csv_headers.get_val_from_row(part_data, 'seller_part_number')
574
575
  unit_cost = csv_headers.get_val_from_row(part_data, 'unit_cost')
575
576
  nre_cost = csv_headers.get_val_from_row(part_data, 'part_nre_cost')
576
577
  moq = csv_headers.get_val_from_row(part_data, 'moq')
@@ -746,7 +747,7 @@ class PartCSVForm(forms.Form):
746
747
 
747
748
  if seller_name and unit_cost and nre_cost:
748
749
  seller, created = Seller.objects.get_or_create(name__iexact=seller_name, organization=self.organization, defaults={'name': seller_name})
749
- seller_part, created = SellerPart.objects.get_or_create(manufacturer_part=manufacturer_part, seller=seller, unit_cost=unit_cost, nre_cost=nre_cost, minimum_order_quantity=moq, minimum_pack_quantity=mpq)
750
+ seller_part, created = SellerPart.objects.get_or_create(manufacturer_part=manufacturer_part, seller=seller, seller_part_number=seller_part_number, unit_cost=unit_cost, nre_cost=nre_cost, minimum_order_quantity=moq, minimum_pack_quantity=mpq)
750
751
 
751
752
  self.successes.append("Part {0} on row {1} created.".format(part.full_part_number(), row_count))
752
753
  else:
@@ -191,7 +191,8 @@ def create_some_fake_parts(organization):
191
191
 
192
192
  (s1, s2, s3) = create_some_fake_sellers(organization=organization)
193
193
 
194
- create_a_fake_seller_part(s1, mp1, moq=1, mpq=1, unit_cost=0, lead_time_days=None, nre_cost=0,)
194
+ create_a_fake_seller_part(s1, mp1, moq=0, mpq=1, unit_cost=0, lead_time_days=None, nre_cost=0,)
195
+ create_a_fake_seller_part(s1, mp1, moq=1, mpq=2, unit_cost=10, lead_time_days=None, nre_cost=0, )
195
196
  create_a_fake_seller_part(s1, mp1, moq=1, mpq=1, unit_cost=1.2, lead_time_days=20, nre_cost=500)
196
197
  create_a_fake_seller_part(s2, mp1, moq=1000, mpq=5000, unit_cost=0.1005, lead_time_days=7, nre_cost=0)
197
198
  create_a_fake_seller_part(s2, mp2, moq=200, mpq=200, unit_cost=0.5, lead_time_days=47, nre_cost=1)
@@ -0,0 +1,35 @@
1
+ from pathlib import Path
2
+
3
+ BASE_DIR = Path(__file__).resolve().parent.parent
4
+
5
+ # SECURITY WARNING: keep the secret key used in production secret!
6
+ SECRET_KEY = 'supersecretkey'
7
+
8
+ # SECURITY WARNING: don't run with debug turned on in production!
9
+ DEBUG = True
10
+
11
+ ALLOWED_HOSTS = ['*']
12
+
13
+ BOM_CONFIG = {
14
+ 'mouser_api_key': 'secretkey',
15
+ 'admin_dashboard': {
16
+ 'enable_autocomplete': False,
17
+ 'page_size': 50,
18
+ }
19
+ }
20
+
21
+ # google GoogleOAuth
22
+ SOCIAL_AUTH_GOOGLE_OAUTH2_KEY = 'secretkey'
23
+ SOCIAL_AUTH_GOOGLE_OAUTH2_SECRET = 'secretkey'
24
+
25
+ # Database
26
+ # https://docs.djangoproject.com/en/1.10/ref/settings/#databases
27
+
28
+ DATABASES = {
29
+ 'default': {
30
+ 'ENGINE': 'django.db.backends.sqlite3',
31
+ 'NAME': BASE_DIR / 'db.sqlite3',
32
+ }
33
+ }
34
+
35
+ FIXER_ACCESS_KEY = 'secretkey from fixer.io' # for exchange rate conversions
@@ -0,0 +1,17 @@
1
+ # Generated by Django 3.2.16 on 2023-01-29 21:57
2
+
3
+ from django.db import migrations
4
+
5
+
6
+ class Migration(migrations.Migration):
7
+
8
+ dependencies = [
9
+ ('bom', '0045_sellerpart_link'),
10
+ ]
11
+
12
+ operations = [
13
+ migrations.AlterUniqueTogether(
14
+ name='sellerpart',
15
+ unique_together=set(),
16
+ ),
17
+ ]
@@ -0,0 +1,18 @@
1
+ # Generated by Django 3.2.16 on 2023-03-07 17:07
2
+
3
+ from django.db import migrations, models
4
+
5
+
6
+ class Migration(migrations.Migration):
7
+
8
+ dependencies = [
9
+ ('bom', '0046_alter_sellerpart_unique_together'),
10
+ ]
11
+
12
+ operations = [
13
+ migrations.AddField(
14
+ model_name='sellerpart',
15
+ name='seller_part_number',
16
+ field=models.CharField(blank=True, default='', max_length=64, null=True),
17
+ ),
18
+ ]