django-bom 1.228__tar.gz → 1.255__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.
Potentially problematic release.
This version of django-bom might be problematic. Click here for more details.
- {django-bom-1.228/django_bom.egg-info → django_bom-1.255}/PKG-INFO +27 -20
- {django-bom-1.228 → django_bom-1.255}/README.md +7 -8
- {django-bom-1.228 → django_bom-1.255}/bom/admin.py +27 -14
- django_bom-1.255/bom/auth_backends.py +47 -0
- {django-bom-1.228 → django_bom-1.255}/bom/constants.py +2 -0
- {django-bom-1.228 → django_bom-1.255}/bom/csv_headers.py +1 -0
- {django-bom-1.228 → django_bom-1.255}/bom/forms.py +11 -28
- {django-bom-1.228 → django_bom-1.255}/bom/helpers.py +2 -1
- django_bom-1.255/bom/local_settings.py +35 -0
- django_bom-1.255/bom/migrations/0046_alter_sellerpart_unique_together.py +17 -0
- django_bom-1.255/bom/migrations/0047_sellerpart_seller_part_number.py +18 -0
- django_bom-1.255/bom/migrations/0048_rename_part_organization_number_class_bom_part_organiz_b333d6_idx_and_more.py +1017 -0
- django_bom-1.255/bom/migrations/0049_alter_assembly_id_alter_assemblysubparts_id_and_more.py +99 -0
- django_bom-1.255/bom/migrations/0050_alter_organization_options.py +17 -0
- django_bom-1.255/bom/migrations/0051_alter_manufacturer_organization_and_more.py +41 -0
- {django-bom-1.228 → django_bom-1.255}/bom/models.py +112 -94
- {django-bom-1.228 → django_bom-1.255}/bom/part_bom.py +1 -0
- django_bom-1.255/bom/settings.py +262 -0
- {django-bom-1.228 → django_bom-1.255}/bom/static/bom/css/style.css +96 -5
- django_bom-1.255/bom/static/bom/doc/test_full_bom.csv +37 -0
- django_bom-1.255/bom/templates/bom/account-delete.html +23 -0
- {django-bom-1.228 → django_bom-1.255}/bom/templates/bom/add-manufacturer-part.html +2 -5
- {django-bom-1.228 → django_bom-1.255}/bom/templates/bom/add-sellerpart.html +9 -5
- {django-bom-1.228 → django_bom-1.255}/bom/templates/bom/base-menu.html +10 -1
- {django-bom-1.228 → django_bom-1.255}/bom/templates/bom/bom-action-table.html +2 -2
- {django-bom-1.228 → django_bom-1.255}/bom/templates/bom/bom-form-modal.html +3 -2
- {django-bom-1.228 → django_bom-1.255}/bom/templates/bom/bom-form.html +1 -5
- django_bom-1.255/bom/templates/bom/bom-modal-add-users.html +49 -0
- {django-bom-1.228 → django_bom-1.255}/bom/templates/bom/bom-signup.html +0 -4
- {django-bom-1.228 → django_bom-1.255}/bom/templates/bom/components/bom-flat.html +2 -2
- {django-bom-1.228 → django_bom-1.255}/bom/templates/bom/components/bom-indented.html +3 -3
- {django-bom-1.228 → django_bom-1.255}/bom/templates/bom/components/manufacturer-part-list.html +6 -2
- {django-bom-1.228 → django_bom-1.255}/bom/templates/bom/components/seller-part-list.html +2 -1
- {django-bom-1.228 → django_bom-1.255}/bom/templates/bom/create-part.html +2 -5
- {django-bom-1.228 → django_bom-1.255}/bom/templates/bom/dashboard.html +6 -3
- {django-bom-1.228 → django_bom-1.255}/bom/templates/bom/edit-manufacturer-part.html +2 -5
- {django-bom-1.228 → django_bom-1.255}/bom/templates/bom/edit-part-class.html +2 -5
- {django-bom-1.228 → django_bom-1.255}/bom/templates/bom/edit-part.html +2 -6
- {django-bom-1.228 → django_bom-1.255}/bom/templates/bom/edit-user-meta.html +2 -5
- {django-bom-1.228 → django_bom-1.255}/bom/templates/bom/help.html +2 -9
- {django-bom-1.228 → django_bom-1.255}/bom/templates/bom/manufacturer-info.html +1 -2
- {django-bom-1.228 → django_bom-1.255}/bom/templates/bom/manufacturers.html +3 -2
- {django-bom-1.228 → django_bom-1.255}/bom/templates/bom/organization-create.html +8 -8
- {django-bom-1.228 → django_bom-1.255}/bom/templates/bom/part-info.html +3 -4
- {django-bom-1.228 → django_bom-1.255}/bom/templates/bom/part-revision-edit.html +2 -5
- {django-bom-1.228 → django_bom-1.255}/bom/templates/bom/part-revision-manage-bom.html +1 -2
- {django-bom-1.228 → django_bom-1.255}/bom/templates/bom/part-revision-new.html +2 -5
- {django-bom-1.228 → django_bom-1.255}/bom/templates/bom/part-revision-release.html +0 -7
- {django-bom-1.228 → django_bom-1.255}/bom/templates/bom/search-help.html +0 -4
- {django-bom-1.228 → django_bom-1.255}/bom/templates/bom/seller-info.html +1 -2
- {django-bom-1.228 → django_bom-1.255}/bom/templates/bom/sellers.html +3 -2
- django_bom-1.255/bom/templates/bom/settings.html +465 -0
- {django-bom-1.228 → django_bom-1.255}/bom/templates/bom/signup.html +1 -1
- django_bom-1.255/bom/templates/bom/subscription_panel.html +16 -0
- {django-bom-1.228 → django_bom-1.255}/bom/templates/bom/upload-bom.html +0 -1
- {django-bom-1.228 → django_bom-1.255}/bom/templates/bom/upload-parts-help.html +3 -6
- {django-bom-1.228 → django_bom-1.255}/bom/templates/bom/upload-parts.html +0 -4
- {django-bom-1.228 → django_bom-1.255}/bom/tests.py +11 -6
- {django-bom-1.228 → django_bom-1.255}/bom/third_party_apis/mouser.py +1 -0
- {django-bom-1.228 → django_bom-1.255}/bom/urls.py +14 -8
- {django-bom-1.228 → django_bom-1.255}/bom/views/json_views.py +2 -2
- {django-bom-1.228 → django_bom-1.255}/bom/views/views.py +35 -14
- {django-bom-1.228 → django_bom-1.255/django_bom.egg-info}/PKG-INFO +27 -20
- {django-bom-1.228 → django_bom-1.255}/django_bom.egg-info/SOURCES.txt +11 -5
- django_bom-1.255/django_bom.egg-info/requires.txt +6 -0
- django_bom-1.255/pyproject.toml +70 -0
- django_bom-1.255/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/bom/templates/bom/settings.html +0 -395
- 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.255}/LICENSE +0 -0
- {django-bom-1.228 → django_bom-1.255}/MANIFEST.in +0 -0
- {django-bom-1.228 → django_bom-1.255}/bom/__init__.py +0 -0
- {django-bom-1.228 → django_bom-1.255}/bom/apps.py +0 -0
- {django-bom-1.228 → django_bom-1.255}/bom/base_classes.py +0 -0
- {django-bom-1.228 → django_bom-1.255}/bom/context_processors.py +0 -0
- {django-bom-1.228 → django_bom-1.255}/bom/decorators.py +0 -0
- {django-bom-1.228 → django_bom-1.255}/bom/form_fields.py +0 -0
- {django-bom-1.228 → django_bom-1.255}/bom/migrations/0001_initial.py +0 -0
- {django-bom-1.228 → django_bom-1.255}/bom/migrations/0002_auto_20180908_2151.py +0 -0
- {django-bom-1.228 → django_bom-1.255}/bom/migrations/0003_sellerpart_data_source.py +0 -0
- {django-bom-1.228 → django_bom-1.255}/bom/migrations/0004_auto_20180911_0011.py +0 -0
- {django-bom-1.228 → django_bom-1.255}/bom/migrations/0005_auto_20181007_1934.py +0 -0
- {django-bom-1.228 → django_bom-1.255}/bom/migrations/0006_auto_20181007_1949.py +0 -0
- {django-bom-1.228 → django_bom-1.255}/bom/migrations/0007_auto_20181009_0256.py +0 -0
- {django-bom-1.228 → django_bom-1.255}/bom/migrations/0008_auto_20181030_0427.py +0 -0
- {django-bom-1.228 → django_bom-1.255}/bom/migrations/0009_subpart_reference.py +0 -0
- {django-bom-1.228 → django_bom-1.255}/bom/migrations/0010_auto_20181202_0733.py +0 -0
- {django-bom-1.228 → django_bom-1.255}/bom/migrations/0011_auto_20181202_2113.py +0 -0
- {django-bom-1.228 → django_bom-1.255}/bom/migrations/0012_partchangehistory.py +0 -0
- {django-bom-1.228 → django_bom-1.255}/bom/migrations/0013_auto_20190222_1631.py +0 -0
- {django-bom-1.228 → django_bom-1.255}/bom/migrations/0014_auto_20190223_2353.py +0 -0
- {django-bom-1.228 → django_bom-1.255}/bom/migrations/0015_auto_20190303_1915.py +0 -0
- {django-bom-1.228 → django_bom-1.255}/bom/migrations/0016_auto_20190405_2308.py +0 -0
- {django-bom-1.228 → django_bom-1.255}/bom/migrations/0017_auto_20190616_1912.py +0 -0
- {django-bom-1.228 → django_bom-1.255}/bom/migrations/0018_auto_20190616_2143.py +0 -0
- {django-bom-1.228 → django_bom-1.255}/bom/migrations/0019_auto_20190624_1246.py +0 -0
- {django-bom-1.228 → django_bom-1.255}/bom/migrations/0020_auto_20190627_0207.py +0 -0
- {django-bom-1.228 → django_bom-1.255}/bom/migrations/0021_auto_20190627_0428.py +0 -0
- {django-bom-1.228 → django_bom-1.255}/bom/migrations/0022_auto_20190811_2140.py +0 -0
- {django-bom-1.228 → django_bom-1.255}/bom/migrations/0023_auto_20191205_2351.py +0 -0
- {django-bom-1.228 → django_bom-1.255}/bom/migrations/0024_auto_20191214_1342.py +0 -0
- {django-bom-1.228 → django_bom-1.255}/bom/migrations/0025_auto_20191221_1907.py +0 -0
- {django-bom-1.228 → django_bom-1.255}/bom/migrations/0026_auto_20191222_2258.py +0 -0
- {django-bom-1.228 → django_bom-1.255}/bom/migrations/0027_auto_20191222_2347.py +0 -0
- {django-bom-1.228 → django_bom-1.255}/bom/migrations/0028_partrevision_displayable_synopsis.py +0 -0
- {django-bom-1.228 → django_bom-1.255}/bom/migrations/0029_auto_20191231_1630.py +0 -0
- {django-bom-1.228 → django_bom-1.255}/bom/migrations/0030_auto_20200101_2253.py +0 -0
- {django-bom-1.228 → django_bom-1.255}/bom/migrations/0031_auto_20200104_1352.py +0 -0
- {django-bom-1.228 → django_bom-1.255}/bom/migrations/0032_auto_20200126_1806.py +0 -0
- {django-bom-1.228 → django_bom-1.255}/bom/migrations/0033_auto_20200203_0618.py +0 -0
- {django-bom-1.228 → django_bom-1.255}/bom/migrations/0034_auto_20200222_0359.py +0 -0
- {django-bom-1.228 → django_bom-1.255}/bom/migrations/0035_auto_20200303_0111.py +0 -0
- {django-bom-1.228 → django_bom-1.255}/bom/migrations/0036_auto_20200303_0538.py +0 -0
- {django-bom-1.228 → django_bom-1.255}/bom/migrations/0037_auto_20200405_1642.py +0 -0
- {django-bom-1.228 → django_bom-1.255}/bom/migrations/0038_auto_20200422_0504.py +0 -0
- {django-bom-1.228 → django_bom-1.255}/bom/migrations/0039_auto_20200929_2315.py +0 -0
- {django-bom-1.228 → django_bom-1.255}/bom/migrations/0040_alter_organization_currency.py +0 -0
- {django-bom-1.228 → django_bom-1.255}/bom/migrations/0041_organization_subscription_quantity.py +0 -0
- {django-bom-1.228 → django_bom-1.255}/bom/migrations/0042_auto_20210720_2137.py +0 -0
- {django-bom-1.228 → django_bom-1.255}/bom/migrations/0043_auto_20211123_0157.py +0 -0
- {django-bom-1.228 → django_bom-1.255}/bom/migrations/0044_auto_20220831_1241.py +0 -0
- {django-bom-1.228 → django_bom-1.255}/bom/migrations/0045_sellerpart_link.py +0 -0
- {django-bom-1.228 → django_bom-1.255}/bom/migrations/__init__.py +0 -0
- {django-bom-1.228 → django_bom-1.255}/bom/static/bom/css/dashboard.css +0 -0
- {django-bom-1.228 → django_bom-1.255}/bom/static/bom/css/jquery.treetable.css +0 -0
- {django-bom-1.228 → django_bom-1.255}/bom/static/bom/css/materialize.min.css +0 -0
- {django-bom-1.228 → django_bom-1.255}/bom/static/bom/css/part-info.css +0 -0
- {django-bom-1.228 → django_bom-1.255}/bom/static/bom/css/tablesorter-theme.materialize.css +0 -0
- {django-bom-1.228 → django_bom-1.255}/bom/static/bom/css/treetable-theme.css +0 -0
- {django-bom-1.228 → django_bom-1.255}/bom/static/bom/doc/sample_part_classes.csv +0 -0
- {django-bom-1.228 → django_bom-1.255}/bom/static/bom/doc/test_bom.csv +0 -0
- {django-bom-1.228 → django_bom-1.255}/bom/static/bom/doc/test_bom_5_intelligent.csv +0 -0
- {django-bom-1.228 → django_bom-1.255}/bom/static/bom/doc/test_new_parts.csv +0 -0
- {django-bom-1.228 → django_bom-1.255}/bom/static/bom/doc/test_new_parts_5_intelligent.csv +0 -0
- {django-bom-1.228 → django_bom-1.255}/bom/static/bom/img/_ionicons_svg_md-arrow-dropdown.svg +0 -0
- {django-bom-1.228 → django_bom-1.255}/bom/static/bom/img/_ionicons_svg_md-arrow-dropright.svg +0 -0
- {django-bom-1.228 → django_bom-1.255}/bom/static/bom/img/favicon.ico +0 -0
- {django-bom-1.228 → django_bom-1.255}/bom/static/bom/img/google/web/1x/btn_google_signin_dark_disabled_web.png +0 -0
- {django-bom-1.228 → django_bom-1.255}/bom/static/bom/img/google/web/1x/btn_google_signin_dark_focus_web.png +0 -0
- {django-bom-1.228 → django_bom-1.255}/bom/static/bom/img/google/web/1x/btn_google_signin_dark_normal_web.png +0 -0
- {django-bom-1.228 → django_bom-1.255}/bom/static/bom/img/google/web/1x/btn_google_signin_dark_pressed_web.png +0 -0
- {django-bom-1.228 → django_bom-1.255}/bom/static/bom/img/google/web/1x/btn_google_signin_light_disabled_web.png +0 -0
- {django-bom-1.228 → django_bom-1.255}/bom/static/bom/img/google/web/1x/btn_google_signin_light_focus_web.png +0 -0
- {django-bom-1.228 → django_bom-1.255}/bom/static/bom/img/google/web/1x/btn_google_signin_light_normal_web.png +0 -0
- {django-bom-1.228 → django_bom-1.255}/bom/static/bom/img/google/web/1x/btn_google_signin_light_pressed_web.png +0 -0
- {django-bom-1.228 → django_bom-1.255}/bom/static/bom/img/google/web/2x/btn_google_signin_dark_disabled_web@2x.png +0 -0
- {django-bom-1.228 → django_bom-1.255}/bom/static/bom/img/google/web/2x/btn_google_signin_dark_focus_web@2x.png +0 -0
- {django-bom-1.228 → django_bom-1.255}/bom/static/bom/img/google/web/2x/btn_google_signin_dark_normal_web@2x.png +0 -0
- {django-bom-1.228 → django_bom-1.255}/bom/static/bom/img/google/web/2x/btn_google_signin_dark_pressed_web@2x.png +0 -0
- {django-bom-1.228 → django_bom-1.255}/bom/static/bom/img/google/web/2x/btn_google_signin_light_disabled_web@2x.png +0 -0
- {django-bom-1.228 → django_bom-1.255}/bom/static/bom/img/google/web/2x/btn_google_signin_light_focus_web@2x.png +0 -0
- {django-bom-1.228 → django_bom-1.255}/bom/static/bom/img/google/web/2x/btn_google_signin_light_normal_web@2x.png +0 -0
- {django-bom-1.228 → django_bom-1.255}/bom/static/bom/img/google/web/2x/btn_google_signin_light_pressed_web@2x.png +0 -0
- {django-bom-1.228 → django_bom-1.255}/bom/static/bom/img/google/web/vector/btn_google_dark_disabled_ios.eps +0 -0
- {django-bom-1.228 → django_bom-1.255}/bom/static/bom/img/google/web/vector/btn_google_dark_disabled_ios.svg +0 -0
- {django-bom-1.228 → django_bom-1.255}/bom/static/bom/img/google/web/vector/btn_google_dark_focus_ios.eps +0 -0
- {django-bom-1.228 → django_bom-1.255}/bom/static/bom/img/google/web/vector/btn_google_dark_focus_ios.svg +0 -0
- {django-bom-1.228 → django_bom-1.255}/bom/static/bom/img/google/web/vector/btn_google_dark_normal_ios.eps +0 -0
- {django-bom-1.228 → django_bom-1.255}/bom/static/bom/img/google/web/vector/btn_google_dark_normal_ios.svg +0 -0
- {django-bom-1.228 → django_bom-1.255}/bom/static/bom/img/google/web/vector/btn_google_dark_pressed_ios.eps +0 -0
- {django-bom-1.228 → django_bom-1.255}/bom/static/bom/img/google/web/vector/btn_google_dark_pressed_ios.svg +0 -0
- {django-bom-1.228 → django_bom-1.255}/bom/static/bom/img/google/web/vector/btn_google_light_disabled_ios.eps +0 -0
- {django-bom-1.228 → django_bom-1.255}/bom/static/bom/img/google/web/vector/btn_google_light_disabled_ios.svg +0 -0
- {django-bom-1.228 → django_bom-1.255}/bom/static/bom/img/google/web/vector/btn_google_light_focus_ios.eps +0 -0
- {django-bom-1.228 → django_bom-1.255}/bom/static/bom/img/google/web/vector/btn_google_light_focus_ios.svg +0 -0
- {django-bom-1.228 → django_bom-1.255}/bom/static/bom/img/google/web/vector/btn_google_light_normal_ios.eps +0 -0
- {django-bom-1.228 → django_bom-1.255}/bom/static/bom/img/google/web/vector/btn_google_light_normal_ios.svg +0 -0
- {django-bom-1.228 → django_bom-1.255}/bom/static/bom/img/google/web/vector/btn_google_light_pressed_ios.eps +0 -0
- {django-bom-1.228 → django_bom-1.255}/bom/static/bom/img/google/web/vector/btn_google_light_pressed_ios.svg +0 -0
- {django-bom-1.228 → django_bom-1.255}/bom/static/bom/img/google_drive_logo.svg +0 -0
- {django-bom-1.228 → django_bom-1.255}/bom/static/bom/img/indabom.png +0 -0
- {django-bom-1.228 → django_bom-1.255}/bom/static/bom/img/mouser.png +0 -0
- {django-bom-1.228 → django_bom-1.255}/bom/static/bom/img/octopart_blue.svg +0 -0
- {django-bom-1.228 → django_bom-1.255}/bom/static/bom/js/jquery-3.4.1.min.js +0 -0
- {django-bom-1.228 → django_bom-1.255}/bom/static/bom/js/jquery.ba-floatingscrollbar.min.js +0 -0
- {django-bom-1.228 → django_bom-1.255}/bom/static/bom/js/jquery.treetable.js +0 -0
- {django-bom-1.228 → django_bom-1.255}/bom/static/bom/js/materialize.min.js +0 -0
- {django-bom-1.228 → django_bom-1.255}/bom/templates/bom/base.html +0 -0
- {django-bom-1.228 → django_bom-1.255}/bom/templates/bom/bom-action-btn.html +0 -0
- {django-bom-1.228 → django_bom-1.255}/bom/templates/bom/bom-base-menu.html +0 -0
- {django-bom-1.228 → django_bom-1.255}/bom/templates/bom/bom-base.html +0 -0
- {django-bom-1.228 → django_bom-1.255}/bom/templates/bom/dashboard-menu.html +0 -0
- {django-bom-1.228 → django_bom-1.255}/bom/templates/bom/nothing-to-see.html +0 -0
- {django-bom-1.228 → django_bom-1.255}/bom/templates/bom/part-revision-display.html +0 -0
- {django-bom-1.228 → django_bom-1.255}/bom/templates/bom/table_of_contents.html +0 -0
- {django-bom-1.228 → django_bom-1.255}/bom/templates/registration/login.html +0 -0
- {django-bom-1.228 → django_bom-1.255}/bom/third_party_apis/__init__.py +0 -0
- {django-bom-1.228 → django_bom-1.255}/bom/third_party_apis/base_api.py +0 -0
- {django-bom-1.228 → django_bom-1.255}/bom/third_party_apis/google_drive.py +0 -0
- {django-bom-1.228 → django_bom-1.255}/bom/third_party_apis/test_apis.py +0 -0
- {django-bom-1.228 → django_bom-1.255}/bom/utils.py +0 -0
- {django-bom-1.228 → django_bom-1.255}/bom/validators.py +0 -0
- {django-bom-1.228 → django_bom-1.255}/bom/views/__init__.py +0 -0
- {django-bom-1.228 → django_bom-1.255}/bom/wsgi.py +0 -0
- {django-bom-1.228 → django_bom-1.255}/django_bom.egg-info/dependency_links.txt +0 -0
- {django-bom-1.228 → django_bom-1.255}/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.255
|
|
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
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
from django.conf import settings
|
|
1
2
|
from django.contrib import admin
|
|
2
3
|
from django.contrib.auth import get_user_model
|
|
3
4
|
from django.contrib.auth.admin import UserAdmin
|
|
@@ -6,29 +7,27 @@ from .models import (
|
|
|
6
7
|
Assembly,
|
|
7
8
|
Manufacturer,
|
|
8
9
|
ManufacturerPart,
|
|
9
|
-
Organization,
|
|
10
10
|
Part,
|
|
11
11
|
PartClass,
|
|
12
12
|
PartRevision,
|
|
13
13
|
Seller,
|
|
14
14
|
SellerPart,
|
|
15
15
|
Subpart,
|
|
16
|
-
|
|
16
|
+
get_organization_model,
|
|
17
|
+
get_user_meta_model
|
|
17
18
|
)
|
|
18
19
|
|
|
19
|
-
|
|
20
20
|
User = get_user_model()
|
|
21
|
+
UserMeta = get_user_meta_model()
|
|
22
|
+
Organization = get_organization_model()
|
|
21
23
|
|
|
22
24
|
class UserMetaInline(admin.TabularInline):
|
|
23
25
|
model = UserMeta
|
|
26
|
+
verbose_name = 'BOM User Meta'
|
|
24
27
|
raw_id_fields = ('organization',)
|
|
25
28
|
can_delete = False
|
|
26
29
|
|
|
27
30
|
|
|
28
|
-
class UserAdmin(UserAdmin):
|
|
29
|
-
inlines = (UserMetaInline,)
|
|
30
|
-
|
|
31
|
-
|
|
32
31
|
class OrganizationAdmin(admin.ModelAdmin):
|
|
33
32
|
list_display = ('name',)
|
|
34
33
|
|
|
@@ -52,6 +51,7 @@ class SellerPartAdmin(admin.ModelAdmin):
|
|
|
52
51
|
list_display = (
|
|
53
52
|
'manufacturer_part',
|
|
54
53
|
'seller',
|
|
54
|
+
'seller_part_number',
|
|
55
55
|
'minimum_order_quantity',
|
|
56
56
|
'minimum_pack_quantity',
|
|
57
57
|
'unit_cost',
|
|
@@ -141,14 +141,27 @@ class AssemblyAdmin(admin.ModelAdmin):
|
|
|
141
141
|
]
|
|
142
142
|
|
|
143
143
|
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
144
|
+
if settings.BOM_USER_META_MODEL == 'bom.UserMeta':
|
|
145
|
+
current_user_admin = admin.site._registry.get(User)
|
|
146
|
+
|
|
147
|
+
if current_user_admin:
|
|
148
|
+
user_admin_class = current_user_admin.__class__
|
|
149
|
+
existing_inlines = list(user_admin_class.inlines or [])
|
|
150
|
+
if UserMetaInline not in existing_inlines:
|
|
151
|
+
existing_inlines.append(UserMetaInline)
|
|
152
|
+
user_admin_class.inlines = existing_inlines
|
|
153
|
+
else:
|
|
154
|
+
class BomUserAdmin(UserAdmin):
|
|
155
|
+
inlines = [UserMetaInline]
|
|
156
|
+
|
|
157
|
+
|
|
158
|
+
admin.site.register(User, BomUserAdmin)
|
|
159
|
+
|
|
160
|
+
if settings.BOM_ORGANIZATION_MODEL == 'bom.Organization':
|
|
161
|
+
from .models import Organization
|
|
162
|
+
|
|
163
|
+
admin.site.register(Organization, OrganizationAdmin)
|
|
149
164
|
|
|
150
|
-
admin.site.register(User, UserAdmin)
|
|
151
|
-
admin.site.register(Organization, OrganizationAdmin)
|
|
152
165
|
admin.site.register(Seller, SellerAdmin)
|
|
153
166
|
admin.site.register(SellerPart, SellerPartAdmin)
|
|
154
167
|
admin.site.register(ManufacturerPart, ManufacturerPartAdmin)
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
from typing import Optional
|
|
2
|
+
|
|
3
|
+
from . import constants
|
|
4
|
+
from .models import get_organization_model
|
|
5
|
+
|
|
6
|
+
Organization = get_organization_model()
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
class OrganizationPermissionBackend:
|
|
10
|
+
"""
|
|
11
|
+
Object-level permission backend for django-bom.
|
|
12
|
+
|
|
13
|
+
- Uses Django's has_perm(user, perm, obj) to evaluate permissions tied to an Organization.
|
|
14
|
+
- Superusers are granted all permissions.
|
|
15
|
+
- For `bom.manage_members`: User must be owner or admin within the organization.
|
|
16
|
+
"""
|
|
17
|
+
|
|
18
|
+
def authenticate(self, request, **credentials): # pragma: no cover - not used for auth
|
|
19
|
+
return None
|
|
20
|
+
|
|
21
|
+
def has_perm(self, user_obj, perm: str, obj: Optional[object] = None):
|
|
22
|
+
# Only handle our specific object-level permission. Let other backends process others.
|
|
23
|
+
if not user_obj or not user_obj.is_authenticated:
|
|
24
|
+
return False
|
|
25
|
+
|
|
26
|
+
if user_obj.is_superuser:
|
|
27
|
+
return True
|
|
28
|
+
|
|
29
|
+
if perm != 'bom.manage_members':
|
|
30
|
+
return None
|
|
31
|
+
|
|
32
|
+
if obj is None or not isinstance(obj, Organization):
|
|
33
|
+
return False
|
|
34
|
+
|
|
35
|
+
profile = user_obj.bom_profile()
|
|
36
|
+
if not profile or profile.organization_id != obj.id:
|
|
37
|
+
return False
|
|
38
|
+
|
|
39
|
+
if obj.subscription != constants.SUBSCRIPTION_TYPE_PRO:
|
|
40
|
+
return False
|
|
41
|
+
|
|
42
|
+
is_owner = obj.owner_id == user_obj.id
|
|
43
|
+
is_admin = getattr(profile, 'role', None) == constants.ROLE_TYPE_ADMIN
|
|
44
|
+
if not (is_owner or is_admin):
|
|
45
|
+
return False
|
|
46
|
+
|
|
47
|
+
return True
|
|
@@ -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', ]),
|
|
@@ -1,41 +1,27 @@
|
|
|
1
1
|
import codecs
|
|
2
2
|
import csv
|
|
3
3
|
import logging
|
|
4
|
-
from typing import Type, TypeVar
|
|
5
4
|
|
|
6
5
|
from django import forms
|
|
7
6
|
from django.contrib.auth.forms import UserCreationForm
|
|
8
7
|
from django.core.exceptions import ValidationError
|
|
9
|
-
from django.core.validators import MaxLengthValidator,
|
|
8
|
+
from django.core.validators import MaxLengthValidator, MinLengthValidator
|
|
10
9
|
from django.db import IntegrityError
|
|
11
10
|
from django.forms.models import model_to_dict
|
|
12
11
|
from django.utils.translation import gettext_lazy as _
|
|
13
|
-
|
|
14
12
|
from djmoney.money import Money
|
|
15
13
|
|
|
16
14
|
from .constants import (
|
|
17
|
-
CONFIGURATION_TYPES,
|
|
18
15
|
CURRENT_UNITS,
|
|
19
16
|
DISTANCE_UNITS,
|
|
20
17
|
FREQUENCY_UNITS,
|
|
21
18
|
INTERFACE_TYPES,
|
|
22
19
|
MEMORY_UNITS,
|
|
23
|
-
NUMBER_CLASS_CODE_LEN_DEFAULT,
|
|
24
|
-
NUMBER_CLASS_CODE_LEN_MAX,
|
|
25
|
-
NUMBER_CLASS_CODE_LEN_MIN,
|
|
26
|
-
NUMBER_ITEM_LEN_DEFAULT,
|
|
27
|
-
NUMBER_ITEM_LEN_MAX,
|
|
28
|
-
NUMBER_ITEM_LEN_MIN,
|
|
29
20
|
NUMBER_SCHEME_INTELLIGENT,
|
|
30
21
|
NUMBER_SCHEME_SEMI_INTELLIGENT,
|
|
31
|
-
NUMBER_VARIATION_LEN_DEFAULT,
|
|
32
|
-
NUMBER_VARIATION_LEN_MAX,
|
|
33
|
-
NUMBER_VARIATION_LEN_MIN,
|
|
34
22
|
PACKAGE_TYPES,
|
|
35
23
|
POWER_UNITS,
|
|
36
24
|
ROLE_TYPE_VIEWER,
|
|
37
|
-
ROLE_TYPES,
|
|
38
|
-
SUBSCRIPTION_TYPES,
|
|
39
25
|
TEMPERATURE_UNITS,
|
|
40
26
|
VALUE_UNITS,
|
|
41
27
|
VOLTAGE_UNITS,
|
|
@@ -43,11 +29,9 @@ from .constants import (
|
|
|
43
29
|
WEIGHT_UNITS,
|
|
44
30
|
)
|
|
45
31
|
from .csv_headers import (
|
|
46
|
-
BOMFlatCSVHeaders,
|
|
47
32
|
BOMIndentedCSVHeaders,
|
|
48
33
|
CSVHeaderError,
|
|
49
34
|
PartClassesCSVHeaders,
|
|
50
|
-
PartsListCSVHeaders,
|
|
51
35
|
)
|
|
52
36
|
from .form_fields import AutocompleteTextInput
|
|
53
37
|
from .models import (
|
|
@@ -55,7 +39,6 @@ from .models import (
|
|
|
55
39
|
AssemblySubparts,
|
|
56
40
|
Manufacturer,
|
|
57
41
|
ManufacturerPart,
|
|
58
|
-
Organization,
|
|
59
42
|
Part,
|
|
60
43
|
PartClass,
|
|
61
44
|
PartRevision,
|
|
@@ -63,20 +46,18 @@ from .models import (
|
|
|
63
46
|
SellerPart,
|
|
64
47
|
Subpart,
|
|
65
48
|
User,
|
|
66
|
-
|
|
49
|
+
get_user_meta_model,
|
|
50
|
+
get_organization_model,
|
|
67
51
|
)
|
|
68
52
|
from .utils import (
|
|
69
|
-
check_references_for_duplicates,
|
|
70
|
-
get_from_dict,
|
|
71
53
|
listify_string,
|
|
72
|
-
prep_for_sorting_nicely,
|
|
73
54
|
stringify_list,
|
|
74
55
|
)
|
|
75
|
-
from .validators import alphanumeric
|
|
76
|
-
|
|
56
|
+
from .validators import alphanumeric
|
|
77
57
|
|
|
78
58
|
logger = logging.getLogger(__name__)
|
|
79
|
-
|
|
59
|
+
Organization = get_organization_model()
|
|
60
|
+
UserMeta = get_user_meta_model()
|
|
80
61
|
|
|
81
62
|
class UserModelChoiceField(forms.ModelChoiceField):
|
|
82
63
|
def label_from_instance(self, user):
|
|
@@ -205,7 +186,8 @@ class OrganizationCreateForm(forms.ModelForm):
|
|
|
205
186
|
class OrganizationForm(forms.ModelForm):
|
|
206
187
|
class Meta:
|
|
207
188
|
model = Organization
|
|
208
|
-
exclude = ['owner', 'subscription', 'subscription_quantity', 'google_drive_parent', 'number_scheme', ]
|
|
189
|
+
# exclude = ['owner', 'subscription', 'subscription_quantity', 'google_drive_parent', 'number_scheme', ]
|
|
190
|
+
fields = ['name', 'number_class_code_len', 'number_item_len', 'number_variation_len', ]
|
|
209
191
|
labels = {
|
|
210
192
|
"name": "Organization Name",
|
|
211
193
|
"number_class_code_len": "Number Class Code Length (C)",
|
|
@@ -230,7 +212,7 @@ class OrganizationFormEditSettings(OrganizationForm):
|
|
|
230
212
|
|
|
231
213
|
class Meta:
|
|
232
214
|
model = Organization
|
|
233
|
-
|
|
215
|
+
fields = ['name', 'owner', 'currency']
|
|
234
216
|
labels = {
|
|
235
217
|
"name": "Organization Name",
|
|
236
218
|
}
|
|
@@ -571,6 +553,7 @@ class PartCSVForm(forms.Form):
|
|
|
571
553
|
value = csv_headers.get_val_from_row(part_data, 'value')
|
|
572
554
|
value_units = csv_headers.get_val_from_row(part_data, 'value_units')
|
|
573
555
|
seller_name = csv_headers.get_val_from_row(part_data, 'seller')
|
|
556
|
+
seller_part_number = csv_headers.get_val_from_row(part_data, 'seller_part_number')
|
|
574
557
|
unit_cost = csv_headers.get_val_from_row(part_data, 'unit_cost')
|
|
575
558
|
nre_cost = csv_headers.get_val_from_row(part_data, 'part_nre_cost')
|
|
576
559
|
moq = csv_headers.get_val_from_row(part_data, 'moq')
|
|
@@ -746,7 +729,7 @@ class PartCSVForm(forms.Form):
|
|
|
746
729
|
|
|
747
730
|
if seller_name and unit_cost and nre_cost:
|
|
748
731
|
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)
|
|
732
|
+
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
733
|
|
|
751
734
|
self.successes.append("Part {0} on row {1} created.".format(part.full_part_number(), row_count))
|
|
752
735
|
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
|
+
]
|