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.
- {django-bom-1.228/django_bom.egg-info → django_bom-1.238}/PKG-INFO +27 -20
- {django-bom-1.228 → django_bom-1.238}/README.md +7 -8
- {django-bom-1.228 → django_bom-1.238}/bom/admin.py +1 -0
- django_bom-1.238/bom/auth_backends.py +45 -0
- {django-bom-1.228 → django_bom-1.238}/bom/constants.py +2 -0
- {django-bom-1.228 → django_bom-1.238}/bom/csv_headers.py +1 -0
- {django-bom-1.228 → django_bom-1.238}/bom/forms.py +2 -1
- {django-bom-1.228 → django_bom-1.238}/bom/helpers.py +2 -1
- django_bom-1.238/bom/local_settings.py +35 -0
- django_bom-1.238/bom/migrations/0046_alter_sellerpart_unique_together.py +17 -0
- django_bom-1.238/bom/migrations/0047_sellerpart_seller_part_number.py +18 -0
- django_bom-1.238/bom/migrations/0048_rename_part_organization_number_class_bom_part_organiz_b333d6_idx_and_more.py +1017 -0
- django_bom-1.238/bom/migrations/0049_alter_assembly_id_alter_assemblysubparts_id_and_more.py +99 -0
- {django-bom-1.228 → django_bom-1.238}/bom/models.py +55 -80
- {django-bom-1.228 → django_bom-1.238}/bom/part_bom.py +1 -0
- django_bom-1.238/bom/settings.py +264 -0
- {django-bom-1.228 → django_bom-1.238}/bom/static/bom/css/style.css +11 -0
- django_bom-1.238/bom/static/bom/doc/test_full_bom.csv +37 -0
- django_bom-1.238/bom/templates/bom/account-delete.html +23 -0
- {django-bom-1.228 → django_bom-1.238}/bom/templates/bom/add-manufacturer-part.html +2 -5
- {django-bom-1.228 → django_bom-1.238}/bom/templates/bom/add-sellerpart.html +9 -5
- {django-bom-1.228 → django_bom-1.238}/bom/templates/bom/base-menu.html +10 -1
- {django-bom-1.228 → django_bom-1.238}/bom/templates/bom/bom-action-table.html +2 -2
- {django-bom-1.228 → django_bom-1.238}/bom/templates/bom/bom-form-modal.html +3 -2
- {django-bom-1.228 → django_bom-1.238}/bom/templates/bom/bom-form.html +1 -5
- django_bom-1.238/bom/templates/bom/bom-modal-add-users.html +49 -0
- {django-bom-1.228 → django_bom-1.238}/bom/templates/bom/bom-signup.html +0 -4
- {django-bom-1.228 → django_bom-1.238}/bom/templates/bom/components/bom-flat.html +2 -2
- {django-bom-1.228 → django_bom-1.238}/bom/templates/bom/components/bom-indented.html +3 -3
- {django-bom-1.228 → django_bom-1.238}/bom/templates/bom/components/manufacturer-part-list.html +6 -2
- {django-bom-1.228 → django_bom-1.238}/bom/templates/bom/components/seller-part-list.html +2 -1
- {django-bom-1.228 → django_bom-1.238}/bom/templates/bom/create-part.html +2 -5
- {django-bom-1.228 → django_bom-1.238}/bom/templates/bom/dashboard.html +6 -3
- {django-bom-1.228 → django_bom-1.238}/bom/templates/bom/edit-manufacturer-part.html +2 -5
- {django-bom-1.228 → django_bom-1.238}/bom/templates/bom/edit-part-class.html +2 -5
- {django-bom-1.228 → django_bom-1.238}/bom/templates/bom/edit-part.html +2 -6
- {django-bom-1.228 → django_bom-1.238}/bom/templates/bom/edit-user-meta.html +2 -5
- {django-bom-1.228 → django_bom-1.238}/bom/templates/bom/help.html +2 -9
- {django-bom-1.228 → django_bom-1.238}/bom/templates/bom/manufacturer-info.html +1 -2
- {django-bom-1.228 → django_bom-1.238}/bom/templates/bom/manufacturers.html +3 -2
- {django-bom-1.228 → django_bom-1.238}/bom/templates/bom/organization-create.html +2 -5
- {django-bom-1.228 → django_bom-1.238}/bom/templates/bom/part-info.html +3 -4
- {django-bom-1.228 → django_bom-1.238}/bom/templates/bom/part-revision-edit.html +2 -5
- {django-bom-1.228 → django_bom-1.238}/bom/templates/bom/part-revision-manage-bom.html +1 -2
- {django-bom-1.228 → django_bom-1.238}/bom/templates/bom/part-revision-new.html +2 -5
- {django-bom-1.228 → django_bom-1.238}/bom/templates/bom/part-revision-release.html +0 -7
- {django-bom-1.228 → django_bom-1.238}/bom/templates/bom/search-help.html +0 -4
- {django-bom-1.228 → django_bom-1.238}/bom/templates/bom/seller-info.html +1 -2
- {django-bom-1.228 → django_bom-1.238}/bom/templates/bom/sellers.html +3 -2
- {django-bom-1.228 → django_bom-1.238}/bom/templates/bom/settings.html +35 -32
- {django-bom-1.228 → django_bom-1.238}/bom/templates/bom/signup.html +1 -1
- {django-bom-1.228 → django_bom-1.238}/bom/templates/bom/upload-bom.html +0 -1
- {django-bom-1.228 → django_bom-1.238}/bom/templates/bom/upload-parts-help.html +3 -6
- {django-bom-1.228 → django_bom-1.238}/bom/templates/bom/upload-parts.html +0 -4
- {django-bom-1.228 → django_bom-1.238}/bom/tests.py +11 -6
- {django-bom-1.228 → django_bom-1.238}/bom/third_party_apis/mouser.py +1 -0
- {django-bom-1.228 → django_bom-1.238}/bom/urls.py +14 -8
- {django-bom-1.228 → django_bom-1.238}/bom/views/views.py +13 -7
- {django-bom-1.228 → django_bom-1.238/django_bom.egg-info}/PKG-INFO +27 -20
- {django-bom-1.228 → django_bom-1.238}/django_bom.egg-info/SOURCES.txt +8 -5
- django_bom-1.238/django_bom.egg-info/requires.txt +6 -0
- django_bom-1.238/pyproject.toml +70 -0
- django_bom-1.238/setup.cfg +4 -0
- django-bom-1.228/bom/local_settings.py +0 -41
- django-bom-1.228/bom/settings.py +0 -225
- django-bom-1.228/bom/static/.DS_Store +0 -0
- django-bom-1.228/bom/static/bom/.DS_Store +0 -0
- django-bom-1.228/bom/static/bom/doc/test_full_bom.csv +0 -36
- django-bom-1.228/bom/static/bom/img/.DS_Store +0 -0
- django-bom-1.228/django_bom.egg-info/requires.txt +0 -5
- django-bom-1.228/setup.cfg +0 -25
- django-bom-1.228/setup.py +0 -43
- {django-bom-1.228 → django_bom-1.238}/LICENSE +0 -0
- {django-bom-1.228 → django_bom-1.238}/MANIFEST.in +0 -0
- {django-bom-1.228 → django_bom-1.238}/bom/__init__.py +0 -0
- {django-bom-1.228 → django_bom-1.238}/bom/apps.py +0 -0
- {django-bom-1.228 → django_bom-1.238}/bom/base_classes.py +0 -0
- {django-bom-1.228 → django_bom-1.238}/bom/context_processors.py +0 -0
- {django-bom-1.228 → django_bom-1.238}/bom/decorators.py +0 -0
- {django-bom-1.228 → django_bom-1.238}/bom/form_fields.py +0 -0
- {django-bom-1.228 → django_bom-1.238}/bom/migrations/0001_initial.py +0 -0
- {django-bom-1.228 → django_bom-1.238}/bom/migrations/0002_auto_20180908_2151.py +0 -0
- {django-bom-1.228 → django_bom-1.238}/bom/migrations/0003_sellerpart_data_source.py +0 -0
- {django-bom-1.228 → django_bom-1.238}/bom/migrations/0004_auto_20180911_0011.py +0 -0
- {django-bom-1.228 → django_bom-1.238}/bom/migrations/0005_auto_20181007_1934.py +0 -0
- {django-bom-1.228 → django_bom-1.238}/bom/migrations/0006_auto_20181007_1949.py +0 -0
- {django-bom-1.228 → django_bom-1.238}/bom/migrations/0007_auto_20181009_0256.py +0 -0
- {django-bom-1.228 → django_bom-1.238}/bom/migrations/0008_auto_20181030_0427.py +0 -0
- {django-bom-1.228 → django_bom-1.238}/bom/migrations/0009_subpart_reference.py +0 -0
- {django-bom-1.228 → django_bom-1.238}/bom/migrations/0010_auto_20181202_0733.py +0 -0
- {django-bom-1.228 → django_bom-1.238}/bom/migrations/0011_auto_20181202_2113.py +0 -0
- {django-bom-1.228 → django_bom-1.238}/bom/migrations/0012_partchangehistory.py +0 -0
- {django-bom-1.228 → django_bom-1.238}/bom/migrations/0013_auto_20190222_1631.py +0 -0
- {django-bom-1.228 → django_bom-1.238}/bom/migrations/0014_auto_20190223_2353.py +0 -0
- {django-bom-1.228 → django_bom-1.238}/bom/migrations/0015_auto_20190303_1915.py +0 -0
- {django-bom-1.228 → django_bom-1.238}/bom/migrations/0016_auto_20190405_2308.py +0 -0
- {django-bom-1.228 → django_bom-1.238}/bom/migrations/0017_auto_20190616_1912.py +0 -0
- {django-bom-1.228 → django_bom-1.238}/bom/migrations/0018_auto_20190616_2143.py +0 -0
- {django-bom-1.228 → django_bom-1.238}/bom/migrations/0019_auto_20190624_1246.py +0 -0
- {django-bom-1.228 → django_bom-1.238}/bom/migrations/0020_auto_20190627_0207.py +0 -0
- {django-bom-1.228 → django_bom-1.238}/bom/migrations/0021_auto_20190627_0428.py +0 -0
- {django-bom-1.228 → django_bom-1.238}/bom/migrations/0022_auto_20190811_2140.py +0 -0
- {django-bom-1.228 → django_bom-1.238}/bom/migrations/0023_auto_20191205_2351.py +0 -0
- {django-bom-1.228 → django_bom-1.238}/bom/migrations/0024_auto_20191214_1342.py +0 -0
- {django-bom-1.228 → django_bom-1.238}/bom/migrations/0025_auto_20191221_1907.py +0 -0
- {django-bom-1.228 → django_bom-1.238}/bom/migrations/0026_auto_20191222_2258.py +0 -0
- {django-bom-1.228 → django_bom-1.238}/bom/migrations/0027_auto_20191222_2347.py +0 -0
- {django-bom-1.228 → django_bom-1.238}/bom/migrations/0028_partrevision_displayable_synopsis.py +0 -0
- {django-bom-1.228 → django_bom-1.238}/bom/migrations/0029_auto_20191231_1630.py +0 -0
- {django-bom-1.228 → django_bom-1.238}/bom/migrations/0030_auto_20200101_2253.py +0 -0
- {django-bom-1.228 → django_bom-1.238}/bom/migrations/0031_auto_20200104_1352.py +0 -0
- {django-bom-1.228 → django_bom-1.238}/bom/migrations/0032_auto_20200126_1806.py +0 -0
- {django-bom-1.228 → django_bom-1.238}/bom/migrations/0033_auto_20200203_0618.py +0 -0
- {django-bom-1.228 → django_bom-1.238}/bom/migrations/0034_auto_20200222_0359.py +0 -0
- {django-bom-1.228 → django_bom-1.238}/bom/migrations/0035_auto_20200303_0111.py +0 -0
- {django-bom-1.228 → django_bom-1.238}/bom/migrations/0036_auto_20200303_0538.py +0 -0
- {django-bom-1.228 → django_bom-1.238}/bom/migrations/0037_auto_20200405_1642.py +0 -0
- {django-bom-1.228 → django_bom-1.238}/bom/migrations/0038_auto_20200422_0504.py +0 -0
- {django-bom-1.228 → django_bom-1.238}/bom/migrations/0039_auto_20200929_2315.py +0 -0
- {django-bom-1.228 → django_bom-1.238}/bom/migrations/0040_alter_organization_currency.py +0 -0
- {django-bom-1.228 → django_bom-1.238}/bom/migrations/0041_organization_subscription_quantity.py +0 -0
- {django-bom-1.228 → django_bom-1.238}/bom/migrations/0042_auto_20210720_2137.py +0 -0
- {django-bom-1.228 → django_bom-1.238}/bom/migrations/0043_auto_20211123_0157.py +0 -0
- {django-bom-1.228 → django_bom-1.238}/bom/migrations/0044_auto_20220831_1241.py +0 -0
- {django-bom-1.228 → django_bom-1.238}/bom/migrations/0045_sellerpart_link.py +0 -0
- {django-bom-1.228 → django_bom-1.238}/bom/migrations/__init__.py +0 -0
- {django-bom-1.228 → django_bom-1.238}/bom/static/bom/css/dashboard.css +0 -0
- {django-bom-1.228 → django_bom-1.238}/bom/static/bom/css/jquery.treetable.css +0 -0
- {django-bom-1.228 → django_bom-1.238}/bom/static/bom/css/materialize.min.css +0 -0
- {django-bom-1.228 → django_bom-1.238}/bom/static/bom/css/part-info.css +0 -0
- {django-bom-1.228 → django_bom-1.238}/bom/static/bom/css/tablesorter-theme.materialize.css +0 -0
- {django-bom-1.228 → django_bom-1.238}/bom/static/bom/css/treetable-theme.css +0 -0
- {django-bom-1.228 → django_bom-1.238}/bom/static/bom/doc/sample_part_classes.csv +0 -0
- {django-bom-1.228 → django_bom-1.238}/bom/static/bom/doc/test_bom.csv +0 -0
- {django-bom-1.228 → django_bom-1.238}/bom/static/bom/doc/test_bom_5_intelligent.csv +0 -0
- {django-bom-1.228 → django_bom-1.238}/bom/static/bom/doc/test_new_parts.csv +0 -0
- {django-bom-1.228 → django_bom-1.238}/bom/static/bom/doc/test_new_parts_5_intelligent.csv +0 -0
- {django-bom-1.228 → django_bom-1.238}/bom/static/bom/img/_ionicons_svg_md-arrow-dropdown.svg +0 -0
- {django-bom-1.228 → django_bom-1.238}/bom/static/bom/img/_ionicons_svg_md-arrow-dropright.svg +0 -0
- {django-bom-1.228 → django_bom-1.238}/bom/static/bom/img/favicon.ico +0 -0
- {django-bom-1.228 → django_bom-1.238}/bom/static/bom/img/google/web/1x/btn_google_signin_dark_disabled_web.png +0 -0
- {django-bom-1.228 → django_bom-1.238}/bom/static/bom/img/google/web/1x/btn_google_signin_dark_focus_web.png +0 -0
- {django-bom-1.228 → django_bom-1.238}/bom/static/bom/img/google/web/1x/btn_google_signin_dark_normal_web.png +0 -0
- {django-bom-1.228 → django_bom-1.238}/bom/static/bom/img/google/web/1x/btn_google_signin_dark_pressed_web.png +0 -0
- {django-bom-1.228 → django_bom-1.238}/bom/static/bom/img/google/web/1x/btn_google_signin_light_disabled_web.png +0 -0
- {django-bom-1.228 → django_bom-1.238}/bom/static/bom/img/google/web/1x/btn_google_signin_light_focus_web.png +0 -0
- {django-bom-1.228 → django_bom-1.238}/bom/static/bom/img/google/web/1x/btn_google_signin_light_normal_web.png +0 -0
- {django-bom-1.228 → django_bom-1.238}/bom/static/bom/img/google/web/1x/btn_google_signin_light_pressed_web.png +0 -0
- {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
- {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
- {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
- {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
- {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
- {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
- {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
- {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
- {django-bom-1.228 → django_bom-1.238}/bom/static/bom/img/google/web/vector/btn_google_dark_disabled_ios.eps +0 -0
- {django-bom-1.228 → django_bom-1.238}/bom/static/bom/img/google/web/vector/btn_google_dark_disabled_ios.svg +0 -0
- {django-bom-1.228 → django_bom-1.238}/bom/static/bom/img/google/web/vector/btn_google_dark_focus_ios.eps +0 -0
- {django-bom-1.228 → django_bom-1.238}/bom/static/bom/img/google/web/vector/btn_google_dark_focus_ios.svg +0 -0
- {django-bom-1.228 → django_bom-1.238}/bom/static/bom/img/google/web/vector/btn_google_dark_normal_ios.eps +0 -0
- {django-bom-1.228 → django_bom-1.238}/bom/static/bom/img/google/web/vector/btn_google_dark_normal_ios.svg +0 -0
- {django-bom-1.228 → django_bom-1.238}/bom/static/bom/img/google/web/vector/btn_google_dark_pressed_ios.eps +0 -0
- {django-bom-1.228 → django_bom-1.238}/bom/static/bom/img/google/web/vector/btn_google_dark_pressed_ios.svg +0 -0
- {django-bom-1.228 → django_bom-1.238}/bom/static/bom/img/google/web/vector/btn_google_light_disabled_ios.eps +0 -0
- {django-bom-1.228 → django_bom-1.238}/bom/static/bom/img/google/web/vector/btn_google_light_disabled_ios.svg +0 -0
- {django-bom-1.228 → django_bom-1.238}/bom/static/bom/img/google/web/vector/btn_google_light_focus_ios.eps +0 -0
- {django-bom-1.228 → django_bom-1.238}/bom/static/bom/img/google/web/vector/btn_google_light_focus_ios.svg +0 -0
- {django-bom-1.228 → django_bom-1.238}/bom/static/bom/img/google/web/vector/btn_google_light_normal_ios.eps +0 -0
- {django-bom-1.228 → django_bom-1.238}/bom/static/bom/img/google/web/vector/btn_google_light_normal_ios.svg +0 -0
- {django-bom-1.228 → django_bom-1.238}/bom/static/bom/img/google/web/vector/btn_google_light_pressed_ios.eps +0 -0
- {django-bom-1.228 → django_bom-1.238}/bom/static/bom/img/google/web/vector/btn_google_light_pressed_ios.svg +0 -0
- {django-bom-1.228 → django_bom-1.238}/bom/static/bom/img/google_drive_logo.svg +0 -0
- {django-bom-1.228 → django_bom-1.238}/bom/static/bom/img/indabom.png +0 -0
- {django-bom-1.228 → django_bom-1.238}/bom/static/bom/img/mouser.png +0 -0
- {django-bom-1.228 → django_bom-1.238}/bom/static/bom/img/octopart_blue.svg +0 -0
- {django-bom-1.228 → django_bom-1.238}/bom/static/bom/js/jquery-3.4.1.min.js +0 -0
- {django-bom-1.228 → django_bom-1.238}/bom/static/bom/js/jquery.ba-floatingscrollbar.min.js +0 -0
- {django-bom-1.228 → django_bom-1.238}/bom/static/bom/js/jquery.treetable.js +0 -0
- {django-bom-1.228 → django_bom-1.238}/bom/static/bom/js/materialize.min.js +0 -0
- {django-bom-1.228 → django_bom-1.238}/bom/templates/bom/base.html +0 -0
- {django-bom-1.228 → django_bom-1.238}/bom/templates/bom/bom-action-btn.html +0 -0
- {django-bom-1.228 → django_bom-1.238}/bom/templates/bom/bom-base-menu.html +0 -0
- {django-bom-1.228 → django_bom-1.238}/bom/templates/bom/bom-base.html +0 -0
- {django-bom-1.228 → django_bom-1.238}/bom/templates/bom/dashboard-menu.html +0 -0
- {django-bom-1.228 → django_bom-1.238}/bom/templates/bom/nothing-to-see.html +0 -0
- {django-bom-1.228 → django_bom-1.238}/bom/templates/bom/part-revision-display.html +0 -0
- {django-bom-1.228 → django_bom-1.238}/bom/templates/bom/table_of_contents.html +0 -0
- {django-bom-1.228 → django_bom-1.238}/bom/templates/registration/login.html +0 -0
- {django-bom-1.228 → django_bom-1.238}/bom/third_party_apis/__init__.py +0 -0
- {django-bom-1.228 → django_bom-1.238}/bom/third_party_apis/base_api.py +0 -0
- {django-bom-1.228 → django_bom-1.238}/bom/third_party_apis/google_drive.py +0 -0
- {django-bom-1.228 → django_bom-1.238}/bom/third_party_apis/test_apis.py +0 -0
- {django-bom-1.228 → django_bom-1.238}/bom/utils.py +0 -0
- {django-bom-1.228 → django_bom-1.238}/bom/validators.py +0 -0
- {django-bom-1.228 → django_bom-1.238}/bom/views/__init__.py +0 -0
- {django-bom-1.228 → django_bom-1.238}/bom/views/json_views.py +0 -0
- {django-bom-1.228 → django_bom-1.238}/bom/wsgi.py +0 -0
- {django-bom-1.228 → django_bom-1.238}/django_bom.egg-info/dependency_links.txt +0 -0
- {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
|
+
Metadata-Version: 2.4
|
|
2
2
|
Name: django-bom
|
|
3
|
-
Version: 1.
|
|
3
|
+
Version: 1.238
|
|
4
4
|
Summary: A simple Django app to manage a bill of materials.
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
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 ::
|
|
10
|
+
Classifier: Framework :: Django :: 5
|
|
13
11
|
Classifier: Intended Audience :: Developers
|
|
14
|
-
Classifier: License :: OSI Approved ::
|
|
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
|
|
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
|

|
|
@@ -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
|
|
54
|
+
1. To start from scratch, install your pipenv using Python 3.12
|
|
45
55
|
```
|
|
46
|
-
|
|
47
|
-
|
|
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
|
-
|
|
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/).
|
|
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
|
-
|
|
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
|
|
22
|
+
1. To start from scratch, install your pipenv using Python 3.12
|
|
23
23
|
```
|
|
24
|
-
|
|
25
|
-
|
|
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
|
-
|
|
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/).
|
|
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
|
-
|
|
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
|
|
@@ -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
|
|
@@ -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=
|
|
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
|
+
]
|