django-bom 1.245__tar.gz → 1.252__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.245/django_bom.egg-info → django_bom-1.252}/PKG-INFO +1 -1
- {django_bom-1.245 → django_bom-1.252}/bom/admin.py +4 -2
- {django_bom-1.245 → django_bom-1.252}/bom/auth_backends.py +3 -1
- {django_bom-1.245 → django_bom-1.252}/bom/forms.py +4 -3
- django_bom-1.252/bom/migrations/0051_alter_manufacturer_organization_and_more.py +41 -0
- {django_bom-1.245 → django_bom-1.252}/bom/models.py +62 -19
- {django_bom-1.245 → django_bom-1.252}/bom/settings.py +2 -0
- {django_bom-1.245 → django_bom-1.252}/bom/templates/bom/organization-create.html +6 -3
- {django_bom-1.245 → django_bom-1.252}/bom/templates/bom/settings.html +1 -1
- {django_bom-1.245 → django_bom-1.252}/bom/views/json_views.py +2 -2
- {django_bom-1.245 → django_bom-1.252}/bom/views/views.py +15 -4
- {django_bom-1.245 → django_bom-1.252/django_bom.egg-info}/PKG-INFO +1 -1
- {django_bom-1.245 → django_bom-1.252}/django_bom.egg-info/SOURCES.txt +1 -0
- {django_bom-1.245 → django_bom-1.252}/pyproject.toml +1 -1
- {django_bom-1.245 → django_bom-1.252}/LICENSE +0 -0
- {django_bom-1.245 → django_bom-1.252}/MANIFEST.in +0 -0
- {django_bom-1.245 → django_bom-1.252}/README.md +0 -0
- {django_bom-1.245 → django_bom-1.252}/bom/__init__.py +0 -0
- {django_bom-1.245 → django_bom-1.252}/bom/apps.py +0 -0
- {django_bom-1.245 → django_bom-1.252}/bom/base_classes.py +0 -0
- {django_bom-1.245 → django_bom-1.252}/bom/constants.py +0 -0
- {django_bom-1.245 → django_bom-1.252}/bom/context_processors.py +0 -0
- {django_bom-1.245 → django_bom-1.252}/bom/csv_headers.py +0 -0
- {django_bom-1.245 → django_bom-1.252}/bom/decorators.py +0 -0
- {django_bom-1.245 → django_bom-1.252}/bom/form_fields.py +0 -0
- {django_bom-1.245 → django_bom-1.252}/bom/helpers.py +0 -0
- {django_bom-1.245 → django_bom-1.252}/bom/local_settings.py +0 -0
- {django_bom-1.245 → django_bom-1.252}/bom/migrations/0001_initial.py +0 -0
- {django_bom-1.245 → django_bom-1.252}/bom/migrations/0002_auto_20180908_2151.py +0 -0
- {django_bom-1.245 → django_bom-1.252}/bom/migrations/0003_sellerpart_data_source.py +0 -0
- {django_bom-1.245 → django_bom-1.252}/bom/migrations/0004_auto_20180911_0011.py +0 -0
- {django_bom-1.245 → django_bom-1.252}/bom/migrations/0005_auto_20181007_1934.py +0 -0
- {django_bom-1.245 → django_bom-1.252}/bom/migrations/0006_auto_20181007_1949.py +0 -0
- {django_bom-1.245 → django_bom-1.252}/bom/migrations/0007_auto_20181009_0256.py +0 -0
- {django_bom-1.245 → django_bom-1.252}/bom/migrations/0008_auto_20181030_0427.py +0 -0
- {django_bom-1.245 → django_bom-1.252}/bom/migrations/0009_subpart_reference.py +0 -0
- {django_bom-1.245 → django_bom-1.252}/bom/migrations/0010_auto_20181202_0733.py +0 -0
- {django_bom-1.245 → django_bom-1.252}/bom/migrations/0011_auto_20181202_2113.py +0 -0
- {django_bom-1.245 → django_bom-1.252}/bom/migrations/0012_partchangehistory.py +0 -0
- {django_bom-1.245 → django_bom-1.252}/bom/migrations/0013_auto_20190222_1631.py +0 -0
- {django_bom-1.245 → django_bom-1.252}/bom/migrations/0014_auto_20190223_2353.py +0 -0
- {django_bom-1.245 → django_bom-1.252}/bom/migrations/0015_auto_20190303_1915.py +0 -0
- {django_bom-1.245 → django_bom-1.252}/bom/migrations/0016_auto_20190405_2308.py +0 -0
- {django_bom-1.245 → django_bom-1.252}/bom/migrations/0017_auto_20190616_1912.py +0 -0
- {django_bom-1.245 → django_bom-1.252}/bom/migrations/0018_auto_20190616_2143.py +0 -0
- {django_bom-1.245 → django_bom-1.252}/bom/migrations/0019_auto_20190624_1246.py +0 -0
- {django_bom-1.245 → django_bom-1.252}/bom/migrations/0020_auto_20190627_0207.py +0 -0
- {django_bom-1.245 → django_bom-1.252}/bom/migrations/0021_auto_20190627_0428.py +0 -0
- {django_bom-1.245 → django_bom-1.252}/bom/migrations/0022_auto_20190811_2140.py +0 -0
- {django_bom-1.245 → django_bom-1.252}/bom/migrations/0023_auto_20191205_2351.py +0 -0
- {django_bom-1.245 → django_bom-1.252}/bom/migrations/0024_auto_20191214_1342.py +0 -0
- {django_bom-1.245 → django_bom-1.252}/bom/migrations/0025_auto_20191221_1907.py +0 -0
- {django_bom-1.245 → django_bom-1.252}/bom/migrations/0026_auto_20191222_2258.py +0 -0
- {django_bom-1.245 → django_bom-1.252}/bom/migrations/0027_auto_20191222_2347.py +0 -0
- {django_bom-1.245 → django_bom-1.252}/bom/migrations/0028_partrevision_displayable_synopsis.py +0 -0
- {django_bom-1.245 → django_bom-1.252}/bom/migrations/0029_auto_20191231_1630.py +0 -0
- {django_bom-1.245 → django_bom-1.252}/bom/migrations/0030_auto_20200101_2253.py +0 -0
- {django_bom-1.245 → django_bom-1.252}/bom/migrations/0031_auto_20200104_1352.py +0 -0
- {django_bom-1.245 → django_bom-1.252}/bom/migrations/0032_auto_20200126_1806.py +0 -0
- {django_bom-1.245 → django_bom-1.252}/bom/migrations/0033_auto_20200203_0618.py +0 -0
- {django_bom-1.245 → django_bom-1.252}/bom/migrations/0034_auto_20200222_0359.py +0 -0
- {django_bom-1.245 → django_bom-1.252}/bom/migrations/0035_auto_20200303_0111.py +0 -0
- {django_bom-1.245 → django_bom-1.252}/bom/migrations/0036_auto_20200303_0538.py +0 -0
- {django_bom-1.245 → django_bom-1.252}/bom/migrations/0037_auto_20200405_1642.py +0 -0
- {django_bom-1.245 → django_bom-1.252}/bom/migrations/0038_auto_20200422_0504.py +0 -0
- {django_bom-1.245 → django_bom-1.252}/bom/migrations/0039_auto_20200929_2315.py +0 -0
- {django_bom-1.245 → django_bom-1.252}/bom/migrations/0040_alter_organization_currency.py +0 -0
- {django_bom-1.245 → django_bom-1.252}/bom/migrations/0041_organization_subscription_quantity.py +0 -0
- {django_bom-1.245 → django_bom-1.252}/bom/migrations/0042_auto_20210720_2137.py +0 -0
- {django_bom-1.245 → django_bom-1.252}/bom/migrations/0043_auto_20211123_0157.py +0 -0
- {django_bom-1.245 → django_bom-1.252}/bom/migrations/0044_auto_20220831_1241.py +0 -0
- {django_bom-1.245 → django_bom-1.252}/bom/migrations/0045_sellerpart_link.py +0 -0
- {django_bom-1.245 → django_bom-1.252}/bom/migrations/0046_alter_sellerpart_unique_together.py +0 -0
- {django_bom-1.245 → django_bom-1.252}/bom/migrations/0047_sellerpart_seller_part_number.py +0 -0
- {django_bom-1.245 → django_bom-1.252}/bom/migrations/0048_rename_part_organization_number_class_bom_part_organiz_b333d6_idx_and_more.py +0 -0
- {django_bom-1.245 → django_bom-1.252}/bom/migrations/0049_alter_assembly_id_alter_assemblysubparts_id_and_more.py +0 -0
- {django_bom-1.245 → django_bom-1.252}/bom/migrations/0050_alter_organization_options.py +0 -0
- {django_bom-1.245 → django_bom-1.252}/bom/migrations/__init__.py +0 -0
- {django_bom-1.245 → django_bom-1.252}/bom/part_bom.py +0 -0
- {django_bom-1.245 → django_bom-1.252}/bom/static/bom/css/dashboard.css +0 -0
- {django_bom-1.245 → django_bom-1.252}/bom/static/bom/css/jquery.treetable.css +0 -0
- {django_bom-1.245 → django_bom-1.252}/bom/static/bom/css/materialize.min.css +0 -0
- {django_bom-1.245 → django_bom-1.252}/bom/static/bom/css/part-info.css +0 -0
- {django_bom-1.245 → django_bom-1.252}/bom/static/bom/css/style.css +0 -0
- {django_bom-1.245 → django_bom-1.252}/bom/static/bom/css/tablesorter-theme.materialize.css +0 -0
- {django_bom-1.245 → django_bom-1.252}/bom/static/bom/css/treetable-theme.css +0 -0
- {django_bom-1.245 → django_bom-1.252}/bom/static/bom/doc/sample_part_classes.csv +0 -0
- {django_bom-1.245 → django_bom-1.252}/bom/static/bom/doc/test_bom.csv +0 -0
- {django_bom-1.245 → django_bom-1.252}/bom/static/bom/doc/test_bom_5_intelligent.csv +0 -0
- {django_bom-1.245 → django_bom-1.252}/bom/static/bom/doc/test_full_bom.csv +0 -0
- {django_bom-1.245 → django_bom-1.252}/bom/static/bom/doc/test_new_parts.csv +0 -0
- {django_bom-1.245 → django_bom-1.252}/bom/static/bom/doc/test_new_parts_5_intelligent.csv +0 -0
- {django_bom-1.245 → django_bom-1.252}/bom/static/bom/img/_ionicons_svg_md-arrow-dropdown.svg +0 -0
- {django_bom-1.245 → django_bom-1.252}/bom/static/bom/img/_ionicons_svg_md-arrow-dropright.svg +0 -0
- {django_bom-1.245 → django_bom-1.252}/bom/static/bom/img/favicon.ico +0 -0
- {django_bom-1.245 → django_bom-1.252}/bom/static/bom/img/google/web/1x/btn_google_signin_dark_disabled_web.png +0 -0
- {django_bom-1.245 → django_bom-1.252}/bom/static/bom/img/google/web/1x/btn_google_signin_dark_focus_web.png +0 -0
- {django_bom-1.245 → django_bom-1.252}/bom/static/bom/img/google/web/1x/btn_google_signin_dark_normal_web.png +0 -0
- {django_bom-1.245 → django_bom-1.252}/bom/static/bom/img/google/web/1x/btn_google_signin_dark_pressed_web.png +0 -0
- {django_bom-1.245 → django_bom-1.252}/bom/static/bom/img/google/web/1x/btn_google_signin_light_disabled_web.png +0 -0
- {django_bom-1.245 → django_bom-1.252}/bom/static/bom/img/google/web/1x/btn_google_signin_light_focus_web.png +0 -0
- {django_bom-1.245 → django_bom-1.252}/bom/static/bom/img/google/web/1x/btn_google_signin_light_normal_web.png +0 -0
- {django_bom-1.245 → django_bom-1.252}/bom/static/bom/img/google/web/1x/btn_google_signin_light_pressed_web.png +0 -0
- {django_bom-1.245 → django_bom-1.252}/bom/static/bom/img/google/web/2x/btn_google_signin_dark_disabled_web@2x.png +0 -0
- {django_bom-1.245 → django_bom-1.252}/bom/static/bom/img/google/web/2x/btn_google_signin_dark_focus_web@2x.png +0 -0
- {django_bom-1.245 → django_bom-1.252}/bom/static/bom/img/google/web/2x/btn_google_signin_dark_normal_web@2x.png +0 -0
- {django_bom-1.245 → django_bom-1.252}/bom/static/bom/img/google/web/2x/btn_google_signin_dark_pressed_web@2x.png +0 -0
- {django_bom-1.245 → django_bom-1.252}/bom/static/bom/img/google/web/2x/btn_google_signin_light_disabled_web@2x.png +0 -0
- {django_bom-1.245 → django_bom-1.252}/bom/static/bom/img/google/web/2x/btn_google_signin_light_focus_web@2x.png +0 -0
- {django_bom-1.245 → django_bom-1.252}/bom/static/bom/img/google/web/2x/btn_google_signin_light_normal_web@2x.png +0 -0
- {django_bom-1.245 → django_bom-1.252}/bom/static/bom/img/google/web/2x/btn_google_signin_light_pressed_web@2x.png +0 -0
- {django_bom-1.245 → django_bom-1.252}/bom/static/bom/img/google/web/vector/btn_google_dark_disabled_ios.eps +0 -0
- {django_bom-1.245 → django_bom-1.252}/bom/static/bom/img/google/web/vector/btn_google_dark_disabled_ios.svg +0 -0
- {django_bom-1.245 → django_bom-1.252}/bom/static/bom/img/google/web/vector/btn_google_dark_focus_ios.eps +0 -0
- {django_bom-1.245 → django_bom-1.252}/bom/static/bom/img/google/web/vector/btn_google_dark_focus_ios.svg +0 -0
- {django_bom-1.245 → django_bom-1.252}/bom/static/bom/img/google/web/vector/btn_google_dark_normal_ios.eps +0 -0
- {django_bom-1.245 → django_bom-1.252}/bom/static/bom/img/google/web/vector/btn_google_dark_normal_ios.svg +0 -0
- {django_bom-1.245 → django_bom-1.252}/bom/static/bom/img/google/web/vector/btn_google_dark_pressed_ios.eps +0 -0
- {django_bom-1.245 → django_bom-1.252}/bom/static/bom/img/google/web/vector/btn_google_dark_pressed_ios.svg +0 -0
- {django_bom-1.245 → django_bom-1.252}/bom/static/bom/img/google/web/vector/btn_google_light_disabled_ios.eps +0 -0
- {django_bom-1.245 → django_bom-1.252}/bom/static/bom/img/google/web/vector/btn_google_light_disabled_ios.svg +0 -0
- {django_bom-1.245 → django_bom-1.252}/bom/static/bom/img/google/web/vector/btn_google_light_focus_ios.eps +0 -0
- {django_bom-1.245 → django_bom-1.252}/bom/static/bom/img/google/web/vector/btn_google_light_focus_ios.svg +0 -0
- {django_bom-1.245 → django_bom-1.252}/bom/static/bom/img/google/web/vector/btn_google_light_normal_ios.eps +0 -0
- {django_bom-1.245 → django_bom-1.252}/bom/static/bom/img/google/web/vector/btn_google_light_normal_ios.svg +0 -0
- {django_bom-1.245 → django_bom-1.252}/bom/static/bom/img/google/web/vector/btn_google_light_pressed_ios.eps +0 -0
- {django_bom-1.245 → django_bom-1.252}/bom/static/bom/img/google/web/vector/btn_google_light_pressed_ios.svg +0 -0
- {django_bom-1.245 → django_bom-1.252}/bom/static/bom/img/google_drive_logo.svg +0 -0
- {django_bom-1.245 → django_bom-1.252}/bom/static/bom/img/indabom.png +0 -0
- {django_bom-1.245 → django_bom-1.252}/bom/static/bom/img/mouser.png +0 -0
- {django_bom-1.245 → django_bom-1.252}/bom/static/bom/img/octopart_blue.svg +0 -0
- {django_bom-1.245 → django_bom-1.252}/bom/static/bom/js/jquery-3.4.1.min.js +0 -0
- {django_bom-1.245 → django_bom-1.252}/bom/static/bom/js/jquery.ba-floatingscrollbar.min.js +0 -0
- {django_bom-1.245 → django_bom-1.252}/bom/static/bom/js/jquery.treetable.js +0 -0
- {django_bom-1.245 → django_bom-1.252}/bom/static/bom/js/materialize.min.js +0 -0
- {django_bom-1.245 → django_bom-1.252}/bom/templates/bom/account-delete.html +0 -0
- {django_bom-1.245 → django_bom-1.252}/bom/templates/bom/add-manufacturer-part.html +0 -0
- {django_bom-1.245 → django_bom-1.252}/bom/templates/bom/add-sellerpart.html +0 -0
- {django_bom-1.245 → django_bom-1.252}/bom/templates/bom/base-menu.html +0 -0
- {django_bom-1.245 → django_bom-1.252}/bom/templates/bom/base.html +0 -0
- {django_bom-1.245 → django_bom-1.252}/bom/templates/bom/bom-action-btn.html +0 -0
- {django_bom-1.245 → django_bom-1.252}/bom/templates/bom/bom-action-table.html +0 -0
- {django_bom-1.245 → django_bom-1.252}/bom/templates/bom/bom-base-menu.html +0 -0
- {django_bom-1.245 → django_bom-1.252}/bom/templates/bom/bom-base.html +0 -0
- {django_bom-1.245 → django_bom-1.252}/bom/templates/bom/bom-form-modal.html +0 -0
- {django_bom-1.245 → django_bom-1.252}/bom/templates/bom/bom-form.html +0 -0
- {django_bom-1.245 → django_bom-1.252}/bom/templates/bom/bom-modal-add-users.html +0 -0
- {django_bom-1.245 → django_bom-1.252}/bom/templates/bom/bom-signup.html +0 -0
- {django_bom-1.245 → django_bom-1.252}/bom/templates/bom/components/bom-flat.html +0 -0
- {django_bom-1.245 → django_bom-1.252}/bom/templates/bom/components/bom-indented.html +0 -0
- {django_bom-1.245 → django_bom-1.252}/bom/templates/bom/components/manufacturer-part-list.html +0 -0
- {django_bom-1.245 → django_bom-1.252}/bom/templates/bom/components/seller-part-list.html +0 -0
- {django_bom-1.245 → django_bom-1.252}/bom/templates/bom/create-part.html +0 -0
- {django_bom-1.245 → django_bom-1.252}/bom/templates/bom/dashboard-menu.html +0 -0
- {django_bom-1.245 → django_bom-1.252}/bom/templates/bom/dashboard.html +0 -0
- {django_bom-1.245 → django_bom-1.252}/bom/templates/bom/edit-manufacturer-part.html +0 -0
- {django_bom-1.245 → django_bom-1.252}/bom/templates/bom/edit-part-class.html +0 -0
- {django_bom-1.245 → django_bom-1.252}/bom/templates/bom/edit-part.html +0 -0
- {django_bom-1.245 → django_bom-1.252}/bom/templates/bom/edit-user-meta.html +0 -0
- {django_bom-1.245 → django_bom-1.252}/bom/templates/bom/help.html +0 -0
- {django_bom-1.245 → django_bom-1.252}/bom/templates/bom/manufacturer-info.html +0 -0
- {django_bom-1.245 → django_bom-1.252}/bom/templates/bom/manufacturers.html +0 -0
- {django_bom-1.245 → django_bom-1.252}/bom/templates/bom/nothing-to-see.html +0 -0
- {django_bom-1.245 → django_bom-1.252}/bom/templates/bom/part-info.html +0 -0
- {django_bom-1.245 → django_bom-1.252}/bom/templates/bom/part-revision-display.html +0 -0
- {django_bom-1.245 → django_bom-1.252}/bom/templates/bom/part-revision-edit.html +0 -0
- {django_bom-1.245 → django_bom-1.252}/bom/templates/bom/part-revision-manage-bom.html +0 -0
- {django_bom-1.245 → django_bom-1.252}/bom/templates/bom/part-revision-new.html +0 -0
- {django_bom-1.245 → django_bom-1.252}/bom/templates/bom/part-revision-release.html +0 -0
- {django_bom-1.245 → django_bom-1.252}/bom/templates/bom/search-help.html +0 -0
- {django_bom-1.245 → django_bom-1.252}/bom/templates/bom/seller-info.html +0 -0
- {django_bom-1.245 → django_bom-1.252}/bom/templates/bom/sellers.html +0 -0
- {django_bom-1.245 → django_bom-1.252}/bom/templates/bom/signup.html +0 -0
- {django_bom-1.245 → django_bom-1.252}/bom/templates/bom/subscription_panel.html +0 -0
- {django_bom-1.245 → django_bom-1.252}/bom/templates/bom/table_of_contents.html +0 -0
- {django_bom-1.245 → django_bom-1.252}/bom/templates/bom/upload-bom.html +0 -0
- {django_bom-1.245 → django_bom-1.252}/bom/templates/bom/upload-parts-help.html +0 -0
- {django_bom-1.245 → django_bom-1.252}/bom/templates/bom/upload-parts.html +0 -0
- {django_bom-1.245 → django_bom-1.252}/bom/templates/registration/login.html +0 -0
- {django_bom-1.245 → django_bom-1.252}/bom/tests.py +0 -0
- {django_bom-1.245 → django_bom-1.252}/bom/third_party_apis/__init__.py +0 -0
- {django_bom-1.245 → django_bom-1.252}/bom/third_party_apis/base_api.py +0 -0
- {django_bom-1.245 → django_bom-1.252}/bom/third_party_apis/google_drive.py +0 -0
- {django_bom-1.245 → django_bom-1.252}/bom/third_party_apis/mouser.py +0 -0
- {django_bom-1.245 → django_bom-1.252}/bom/third_party_apis/test_apis.py +0 -0
- {django_bom-1.245 → django_bom-1.252}/bom/urls.py +0 -0
- {django_bom-1.245 → django_bom-1.252}/bom/utils.py +0 -0
- {django_bom-1.245 → django_bom-1.252}/bom/validators.py +0 -0
- {django_bom-1.245 → django_bom-1.252}/bom/views/__init__.py +0 -0
- {django_bom-1.245 → django_bom-1.252}/bom/wsgi.py +0 -0
- {django_bom-1.245 → django_bom-1.252}/django_bom.egg-info/dependency_links.txt +0 -0
- {django_bom-1.245 → django_bom-1.252}/django_bom.egg-info/requires.txt +0 -0
- {django_bom-1.245 → django_bom-1.252}/django_bom.egg-info/top_level.txt +0 -0
- {django_bom-1.245 → django_bom-1.252}/setup.cfg +0 -0
|
@@ -6,17 +6,19 @@ from .models import (
|
|
|
6
6
|
Assembly,
|
|
7
7
|
Manufacturer,
|
|
8
8
|
ManufacturerPart,
|
|
9
|
-
Organization,
|
|
10
9
|
Part,
|
|
11
10
|
PartClass,
|
|
12
11
|
PartRevision,
|
|
13
12
|
Seller,
|
|
14
13
|
SellerPart,
|
|
15
14
|
Subpart,
|
|
16
|
-
|
|
15
|
+
get_organization_model,
|
|
16
|
+
get_user_meta_model
|
|
17
17
|
)
|
|
18
18
|
|
|
19
19
|
User = get_user_model()
|
|
20
|
+
UserMeta = get_user_meta_model()
|
|
21
|
+
Organization = get_organization_model()
|
|
20
22
|
|
|
21
23
|
class UserMetaInline(admin.TabularInline):
|
|
22
24
|
model = UserMeta
|
|
@@ -39,7 +39,6 @@ from .models import (
|
|
|
39
39
|
AssemblySubparts,
|
|
40
40
|
Manufacturer,
|
|
41
41
|
ManufacturerPart,
|
|
42
|
-
Organization,
|
|
43
42
|
Part,
|
|
44
43
|
PartClass,
|
|
45
44
|
PartRevision,
|
|
@@ -47,7 +46,8 @@ from .models import (
|
|
|
47
46
|
SellerPart,
|
|
48
47
|
Subpart,
|
|
49
48
|
User,
|
|
50
|
-
|
|
49
|
+
get_user_meta_model,
|
|
50
|
+
get_organization_model,
|
|
51
51
|
)
|
|
52
52
|
from .utils import (
|
|
53
53
|
listify_string,
|
|
@@ -56,7 +56,8 @@ from .utils import (
|
|
|
56
56
|
from .validators import alphanumeric
|
|
57
57
|
|
|
58
58
|
logger = logging.getLogger(__name__)
|
|
59
|
-
|
|
59
|
+
Organization = get_organization_model()
|
|
60
|
+
UserMeta = get_user_meta_model()
|
|
60
61
|
|
|
61
62
|
class UserModelChoiceField(forms.ModelChoiceField):
|
|
62
63
|
def label_from_instance(self, user):
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
# Generated by Django 5.2.8 on 2026-01-04 00:59
|
|
2
|
+
|
|
3
|
+
import django.db.models.deletion
|
|
4
|
+
from django.conf import settings
|
|
5
|
+
from django.db import migrations, models
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
class Migration(migrations.Migration):
|
|
9
|
+
|
|
10
|
+
dependencies = [
|
|
11
|
+
('bom', '0050_alter_organization_options'),
|
|
12
|
+
migrations.swappable_dependency(settings.BOM_ORGANIZATION_MODEL),
|
|
13
|
+
]
|
|
14
|
+
|
|
15
|
+
operations = [
|
|
16
|
+
migrations.AlterField(
|
|
17
|
+
model_name='manufacturer',
|
|
18
|
+
name='organization',
|
|
19
|
+
field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to=settings.BOM_ORGANIZATION_MODEL),
|
|
20
|
+
),
|
|
21
|
+
migrations.AlterField(
|
|
22
|
+
model_name='part',
|
|
23
|
+
name='organization',
|
|
24
|
+
field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to=settings.BOM_ORGANIZATION_MODEL),
|
|
25
|
+
),
|
|
26
|
+
migrations.AlterField(
|
|
27
|
+
model_name='partclass',
|
|
28
|
+
name='organization',
|
|
29
|
+
field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to=settings.BOM_ORGANIZATION_MODEL),
|
|
30
|
+
),
|
|
31
|
+
migrations.AlterField(
|
|
32
|
+
model_name='seller',
|
|
33
|
+
name='organization',
|
|
34
|
+
field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to=settings.BOM_ORGANIZATION_MODEL),
|
|
35
|
+
),
|
|
36
|
+
migrations.AlterField(
|
|
37
|
+
model_name='usermeta',
|
|
38
|
+
name='organization',
|
|
39
|
+
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to=settings.BOM_ORGANIZATION_MODEL),
|
|
40
|
+
),
|
|
41
|
+
]
|
|
@@ -2,6 +2,7 @@ from __future__ import unicode_literals
|
|
|
2
2
|
|
|
3
3
|
import logging
|
|
4
4
|
|
|
5
|
+
from django.apps import apps
|
|
5
6
|
from django.conf import settings
|
|
6
7
|
from django.contrib.auth import get_user_model
|
|
7
8
|
from django.core.cache import cache
|
|
@@ -23,32 +24,54 @@ logger = logging.getLogger(__name__)
|
|
|
23
24
|
User = get_user_model()
|
|
24
25
|
|
|
25
26
|
|
|
27
|
+
def get_user_meta_model():
|
|
28
|
+
from django.apps import apps
|
|
29
|
+
from django.conf import settings
|
|
30
|
+
return apps.get_model(settings.BOM_USER_META_MODEL)
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
def get_organization_model():
|
|
34
|
+
from django.apps import apps
|
|
35
|
+
from django.conf import settings
|
|
36
|
+
return apps.get_model(settings.BOM_ORGANIZATION_MODEL)
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
def _user_meta(self, organization=None):
|
|
40
|
+
from django.apps import apps
|
|
41
|
+
from django.conf import settings
|
|
42
|
+
UserMetaModel = apps.get_model(settings.BOM_USER_META_MODEL)
|
|
43
|
+
meta, created = UserMetaModel.objects.get_or_create(
|
|
44
|
+
user=self,
|
|
45
|
+
defaults={'organization': organization}
|
|
46
|
+
)
|
|
47
|
+
return meta
|
|
48
|
+
|
|
49
|
+
|
|
26
50
|
class OrganizationScopedModel(models.Model):
|
|
27
|
-
organization = models.ForeignKey(
|
|
51
|
+
organization = models.ForeignKey(settings.BOM_ORGANIZATION_MODEL, on_delete=models.CASCADE, db_index=True)
|
|
28
52
|
|
|
29
53
|
class Meta:
|
|
30
54
|
abstract = True
|
|
31
55
|
|
|
32
56
|
|
|
33
|
-
class
|
|
57
|
+
class AbstractOrganization(models.Model):
|
|
34
58
|
name = models.CharField(max_length=255, default=None)
|
|
35
|
-
subscription = models.CharField(max_length=1, choices=SUBSCRIPTION_TYPES)
|
|
36
|
-
subscription_quantity = models.IntegerField(default=0)
|
|
37
59
|
owner = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE)
|
|
38
60
|
number_scheme = models.CharField(max_length=1, choices=NUMBER_SCHEMES, default=NUMBER_SCHEME_SEMI_INTELLIGENT)
|
|
39
61
|
number_class_code_len = models.PositiveIntegerField(default=NUMBER_CLASS_CODE_LEN_DEFAULT,
|
|
40
|
-
validators=[MinValueValidator(NUMBER_CLASS_CODE_LEN_MIN),
|
|
62
|
+
validators=[MinValueValidator(NUMBER_CLASS_CODE_LEN_MIN),
|
|
63
|
+
MaxValueValidator(NUMBER_CLASS_CODE_LEN_MAX)])
|
|
41
64
|
number_item_len = models.PositiveIntegerField(default=NUMBER_ITEM_LEN_DEFAULT,
|
|
42
|
-
validators=[MinValueValidator(NUMBER_ITEM_LEN_MIN),
|
|
65
|
+
validators=[MinValueValidator(NUMBER_ITEM_LEN_MIN),
|
|
66
|
+
MaxValueValidator(NUMBER_ITEM_LEN_MAX)])
|
|
43
67
|
number_variation_len = models.PositiveIntegerField(default=NUMBER_VARIATION_LEN_DEFAULT,
|
|
44
|
-
validators=[MinValueValidator(NUMBER_VARIATION_LEN_MIN),
|
|
68
|
+
validators=[MinValueValidator(NUMBER_VARIATION_LEN_MIN),
|
|
69
|
+
MaxValueValidator(NUMBER_VARIATION_LEN_MAX)])
|
|
45
70
|
google_drive_parent = models.CharField(max_length=128, blank=True, default=None, null=True)
|
|
46
71
|
currency = CurrencyField(max_length=3, choices=CURRENCY_CHOICES, default='USD')
|
|
47
72
|
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
("manage_members", "Can manage organization members"),
|
|
51
|
-
)
|
|
73
|
+
subscription = models.CharField(max_length=1, choices=SUBSCRIPTION_TYPES)
|
|
74
|
+
subscription_quantity = models.IntegerField(default=0)
|
|
52
75
|
|
|
53
76
|
def number_cs(self):
|
|
54
77
|
return "C" * self.number_class_code_len
|
|
@@ -76,13 +99,25 @@ class Organization(models.Model):
|
|
|
76
99
|
return self.owner.email
|
|
77
100
|
|
|
78
101
|
def save(self, *args, **kwargs):
|
|
79
|
-
super(
|
|
80
|
-
SellerPart.objects.filter(seller__organization=self).update(unit_cost_currency=self.currency,
|
|
102
|
+
super(AbstractOrganization, self).save()
|
|
103
|
+
SellerPart.objects.filter(seller__organization=self).update(unit_cost_currency=self.currency,
|
|
104
|
+
nre_cost_currency=self.currency)
|
|
81
105
|
|
|
106
|
+
class Meta:
|
|
107
|
+
abstract = True
|
|
108
|
+
|
|
109
|
+
|
|
110
|
+
class Organization(AbstractOrganization):
|
|
111
|
+
class Meta:
|
|
112
|
+
swappable = 'BOM_ORGANIZATION_MODEL'
|
|
113
|
+
permissions = (
|
|
114
|
+
("manage_members", "Can manage organization members"),
|
|
115
|
+
)
|
|
82
116
|
|
|
83
|
-
|
|
117
|
+
|
|
118
|
+
class AbstractUserMeta(models.Model):
|
|
84
119
|
user = models.OneToOneField(settings.AUTH_USER_MODEL, db_index=True, on_delete=models.CASCADE)
|
|
85
|
-
organization = models.ForeignKey(
|
|
120
|
+
organization = models.ForeignKey(settings.BOM_ORGANIZATION_MODEL, blank=True, null=True, on_delete=models.CASCADE)
|
|
86
121
|
role = models.CharField(max_length=1, choices=ROLE_TYPES)
|
|
87
122
|
|
|
88
123
|
def get_or_create_organization(self):
|
|
@@ -92,7 +127,9 @@ class UserMeta(models.Model):
|
|
|
92
127
|
else:
|
|
93
128
|
org_name = self.user.first_name + ' ' + self.user.last_name
|
|
94
129
|
|
|
95
|
-
|
|
130
|
+
OrganizationModel = apps.get_model(settings.BOM_ORGANIZATION_MODEL)
|
|
131
|
+
organization, created = OrganizationModel.objects.get_or_create(owner=self.user, defaults={'name': org_name,
|
|
132
|
+
'subscription': 'F'})
|
|
96
133
|
|
|
97
134
|
self.organization = organization
|
|
98
135
|
self.role = 'A'
|
|
@@ -109,10 +146,13 @@ class UserMeta(models.Model):
|
|
|
109
146
|
def is_organization_owner(self) -> bool:
|
|
110
147
|
return self.organization.owner == self.user if self.organization else False
|
|
111
148
|
|
|
112
|
-
|
|
113
|
-
|
|
149
|
+
class Meta:
|
|
150
|
+
abstract = True
|
|
114
151
|
|
|
115
|
-
|
|
152
|
+
|
|
153
|
+
class UserMeta(AbstractUserMeta):
|
|
154
|
+
class Meta:
|
|
155
|
+
swappable = 'BOM_USER_META_MODEL'
|
|
116
156
|
|
|
117
157
|
|
|
118
158
|
class PartClass(OrganizationScopedModel):
|
|
@@ -730,3 +770,6 @@ class SellerPart(models.Model, AsDictModel):
|
|
|
730
770
|
|
|
731
771
|
def __str__(self):
|
|
732
772
|
return u'%s' % (self.manufacturer_part.part.full_part_number() + ' ' + self.seller.name)
|
|
773
|
+
|
|
774
|
+
|
|
775
|
+
User.add_to_class('bom_profile', _user_meta)
|
|
@@ -40,9 +40,12 @@
|
|
|
40
40
|
|
|
41
41
|
<div id="join-organization" style="display: none;">
|
|
42
42
|
<h3 class="center">Join an existing Organization</h3>
|
|
43
|
-
<h5 class="center" style="padding-top: 36px;">To join an existing organization, you must provide
|
|
44
|
-
|
|
45
|
-
|
|
43
|
+
<h5 class="center" style="padding-top: 36px;">To join an existing organization, you must provide your
|
|
44
|
+
username (not e-mail) to your IndaBOM organization owner. <br><br>Your username is
|
|
45
|
+
<b>{{ user.username }}</b>
|
|
46
|
+
click
|
|
47
|
+
<a href="mailto:?subject=Add me to your IndaBOM Organization&body=Hi,%0D%0A%0D%0APlease add me to your IndaBOM organization. To do so, log in, go to Settings > Organization and add me via my username {{ user.username }}">here</a>
|
|
48
|
+
to send an e-mail to your organization owner with instructions.</h5>
|
|
46
49
|
<br><br>
|
|
47
50
|
<p class="center">Oops! I meant to <a class="modal-trigger" onclick="resetView()">create a new organization</a>.</p>
|
|
48
51
|
</div>
|
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
|
|
8
8
|
{% block content %}
|
|
9
9
|
<div class="row container-app">
|
|
10
|
-
<div class="col
|
|
10
|
+
<div class="col s12 l8 offset-l2">
|
|
11
11
|
<ul id="tabs" class="tabs tabs-fixed-width">
|
|
12
12
|
<li class="tab"><a id="user-tab" href="#user">User</a></li>
|
|
13
13
|
<li class="tab"><a id="indabom-tab" href="#indabom">IndaBOM</a></li>
|
|
@@ -5,9 +5,9 @@ from django.shortcuts import get_object_or_404
|
|
|
5
5
|
from django.utils.decorators import method_decorator
|
|
6
6
|
from django.views import View
|
|
7
7
|
|
|
8
|
-
from bom.models import
|
|
9
|
-
from bom.third_party_apis.mouser import Mouser
|
|
8
|
+
from bom.models import PartRevision
|
|
10
9
|
from bom.third_party_apis.base_api import BaseApiError
|
|
10
|
+
from bom.third_party_apis.mouser import Mouser
|
|
11
11
|
|
|
12
12
|
|
|
13
13
|
class BomJsonResponse(View):
|
|
@@ -69,11 +69,12 @@ from bom.models import (
|
|
|
69
69
|
SellerPart,
|
|
70
70
|
Subpart,
|
|
71
71
|
User,
|
|
72
|
-
|
|
72
|
+
get_user_meta_model
|
|
73
73
|
)
|
|
74
74
|
from bom.utils import check_references_for_duplicates, listify_string, prep_for_sorting_nicely
|
|
75
75
|
|
|
76
76
|
logger = logging.getLogger(__name__)
|
|
77
|
+
UserMeta = get_user_meta_model()
|
|
77
78
|
BOM_LOGIN_URL = getattr(settings, "BOM_LOGIN_URL", None) or settings.LOGIN_URL
|
|
78
79
|
|
|
79
80
|
def form_error_messages(form_errors) -> [str]:
|
|
@@ -400,8 +401,13 @@ def bom_settings(request, tab_anchor=None):
|
|
|
400
401
|
added_user_profile = user_add_form.save()
|
|
401
402
|
messages.info(request, f"Added {added_user_profile.user.first_name} {added_user_profile.user.last_name} to your organization.")
|
|
402
403
|
else:
|
|
403
|
-
|
|
404
|
-
|
|
404
|
+
for field, errors in user_add_form.errors.items():
|
|
405
|
+
for error in errors:
|
|
406
|
+
messages.error(request, f"{field.capitalize()}: {error}")
|
|
407
|
+
users_in_organization.all()
|
|
408
|
+
users_in_organization_count = users_in_organization.count()
|
|
409
|
+
has_member_capacity = users_in_organization_count < organization.subscription_quantity
|
|
410
|
+
seats_available = max(organization.subscription_quantity - users_in_organization_count, 0)
|
|
405
411
|
elif 'clear-add-user' in request.POST:
|
|
406
412
|
tab_anchor = ORGANIZATION_TAB
|
|
407
413
|
user_add_form = UserAddForm()
|
|
@@ -421,7 +427,10 @@ def bom_settings(request, tab_anchor=None):
|
|
|
421
427
|
user_meta.save()
|
|
422
428
|
except UserMeta.DoesNotExist:
|
|
423
429
|
messages.error(request, "No user found with given id {}.".format(user_meta_id))
|
|
424
|
-
|
|
430
|
+
users_in_organization.all()
|
|
431
|
+
users_in_organization_count = users_in_organization.count()
|
|
432
|
+
has_member_capacity = users_in_organization_count < organization.subscription_quantity
|
|
433
|
+
seats_available = max(organization.subscription_quantity - users_in_organization_count, 0)
|
|
425
434
|
elif 'submit-edit-organization' in request.POST:
|
|
426
435
|
tab_anchor = ORGANIZATION_TAB
|
|
427
436
|
organization_form = OrganizationFormEditSettings(request.POST, instance=organization, user=user)
|
|
@@ -521,6 +530,8 @@ def bom_settings(request, tab_anchor=None):
|
|
|
521
530
|
profile.save()
|
|
522
531
|
if users_in_organization == 0:
|
|
523
532
|
organization.delete()
|
|
533
|
+
else:
|
|
534
|
+
messages.warning(request, "No action was taken because no form field was submitted.")
|
|
524
535
|
|
|
525
536
|
user_form = UserForm(instance=user)
|
|
526
537
|
user_add_form = UserAddForm()
|
|
@@ -73,6 +73,7 @@ bom/migrations/0047_sellerpart_seller_part_number.py
|
|
|
73
73
|
bom/migrations/0048_rename_part_organization_number_class_bom_part_organiz_b333d6_idx_and_more.py
|
|
74
74
|
bom/migrations/0049_alter_assembly_id_alter_assemblysubparts_id_and_more.py
|
|
75
75
|
bom/migrations/0050_alter_organization_options.py
|
|
76
|
+
bom/migrations/0051_alter_manufacturer_organization_and_more.py
|
|
76
77
|
bom/migrations/__init__.py
|
|
77
78
|
bom/static/bom/css/dashboard.css
|
|
78
79
|
bom/static/bom/css/jquery.treetable.css
|
|
@@ -7,7 +7,7 @@ build-backend = "setuptools.build_meta"
|
|
|
7
7
|
|
|
8
8
|
[project]
|
|
9
9
|
name = "django-bom"
|
|
10
|
-
version = "1.
|
|
10
|
+
version = "1.252"
|
|
11
11
|
description = "A simple Django app to manage a bill of materials."
|
|
12
12
|
readme = {file = "README.md", content-type = "text/markdown"}
|
|
13
13
|
requires-python = ">=3.10"
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{django_bom-1.245 → django_bom-1.252}/bom/migrations/0028_partrevision_displayable_synopsis.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{django_bom-1.245 → django_bom-1.252}/bom/migrations/0041_organization_subscription_quantity.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{django_bom-1.245 → django_bom-1.252}/bom/migrations/0046_alter_sellerpart_unique_together.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{django_bom-1.245 → django_bom-1.252}/bom/static/bom/img/_ionicons_svg_md-arrow-dropdown.svg
RENAMED
|
File without changes
|
{django_bom-1.245 → django_bom-1.252}/bom/static/bom/img/_ionicons_svg_md-arrow-dropright.svg
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{django_bom-1.245 → django_bom-1.252}/bom/templates/bom/components/manufacturer-part-list.html
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|