Skip to content

[change] Delivery address#12056

Open
SchrodingersGat wants to merge 24 commits into
inventree:masterfrom
SchrodingersGat:delivery-address
Open

[change] Delivery address#12056
SchrodingersGat wants to merge 24 commits into
inventree:masterfrom
SchrodingersGat:delivery-address

Conversation

@SchrodingersGat
Copy link
Copy Markdown
Member

@SchrodingersGat SchrodingersGat commented May 31, 2026

This PR expands the functionality of the "Address" model, allowing it to be used to represent internal addresses (not just addresses associated with external companies).

This is an alternative approach to the one suggested in #9768

Relates Issues

Breaking Change

This is a "slightly" breaking change - in that the Address model no longer is definitely linked to a Company instance. Any external code which expects an Address to always link to a Company model will need to be updated

Changes

  • Address.company is now nullable; addresses with no linked company are "internal addresses" representing your own sites
  • Internal addresses are managed from the Admin Center (staff only) under a new Addresses panel
  • Purchase Orders, Return Orders, and Transfer Orders now use an internal address for their address field; the picker is filtered to internal addresses only
  • Sales Orders are unchanged — they continue to use a customer-linked address
  • If no explicit address is set on a PO/RO/TO, the primary internal address is used as the fallback (mirrors the existing company primary-address fallback on Sales Orders)
  • New ?internal=true/false filter on the address list API endpoint
  • order_address property updated for all order types to reflect the internal/external split
  • Unit tests added for address field validation on all four order types (PO, SO, RO, TO) via the API, and for the order_address fallback behaviour
  • Documentation updated: new Internal Addresses section in the company concepts page, including fallback address behaviour for both internal and external orders

@SchrodingersGat SchrodingersGat added this to the 1.4.0 milestone May 31, 2026
@SchrodingersGat SchrodingersGat added order Related to purchase orders / sales orders api Relates to the API breaking Indicates a major update or change which breaks compatibility User Interface Related to the frontend / User Interface labels May 31, 2026
@netlify
Copy link
Copy Markdown

netlify Bot commented May 31, 2026

Deploy Preview for inventree-web-pui-preview ready!

Name Link
🔨 Latest commit 2c8d511
🔍 Latest deploy log https://app.netlify.com/projects/inventree-web-pui-preview/deploys/6a1d733fb737b200080b5025
😎 Deploy Preview https://deploy-preview-12056--inventree-web-pui-preview.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.
Lighthouse
Lighthouse
1 paths audited
Performance: 93 (🟢 up 2 from production)
Accessibility: 82 (no change from production)
Best Practices: 100 (no change from production)
SEO: 78 (no change from production)
PWA: -
View the detailed breakdown and full score reports
🤖 Make changes Run an agent on this branch

To edit notification comments on pull requests, go to your Netlify project configuration.

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR extends the company address model to support internal organization addresses and updates order address behavior so PO/RO/TO use internal addresses while SO remains customer-address based.

Changes:

  • Allows Address.company to be nullable and adds internal-address filtering.
  • Updates order validation/fallback behavior and frontend address pickers for PO/RO/TO.
  • Adds tests, migrations, changelog entries, and documentation for internal addresses.

Reviewed changes

Copilot reviewed 16 out of 16 changed files in this pull request and generated 6 comments.

Show a summary per file
File Description
src/backend/InvenTree/company/models.py Makes address company optional for internal addresses.
src/backend/InvenTree/company/api.py Adds the internal address list filter.
src/backend/InvenTree/company/migrations/0080_alter_address_company.py Migrates address company FK to nullable.
src/backend/InvenTree/order/models.py Adds internal/external order address validation and fallback behavior.
src/backend/InvenTree/order/migrations/0120_alter_purchaseorder_address_and_more.py Updates order address field help text.
src/backend/InvenTree/order/tests.py Tests internal address fallback behavior.
src/backend/InvenTree/order/test_sales_order.py Extends Sales Order address validation tests.
src/backend/InvenTree/order/test_api.py Adds API validation tests for order address fields.
src/frontend/src/tables/company/AddressTable.tsx Supports internal address table mode.
src/frontend/src/pages/Index/Settings/AdminCenter/Index.tsx Adds Admin Center address management panel.
src/frontend/src/pages/company/CompanyDetail.tsx Updates the company address panel icon.
src/frontend/src/forms/PurchaseOrderForms.tsx Filters purchase order address choices to internal addresses.
src/frontend/src/forms/ReturnOrderForms.tsx Filters return order address choices to internal addresses.
src/frontend/src/forms/TransferOrderForms.tsx Adds transfer order address field filtered to internal addresses.
docs/docs/concepts/company.md Documents internal addresses and order address fallback behavior.
CHANGELOG.md Records the internal address feature and breaking behavior change.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread src/backend/InvenTree/company/api.py
Comment thread src/backend/InvenTree/company/api.py
Comment thread src/backend/InvenTree/company/api.py
Comment thread docs/docs/concepts/company.md Outdated
Comment thread CHANGELOG.md Outdated
Comment thread CHANGELOG.md Outdated
@codecov
Copy link
Copy Markdown

codecov Bot commented May 31, 2026

Codecov Report

❌ Patch coverage is 95.97990% with 8 lines in your changes missing coverage. Please review.
✅ Project coverage is 91.45%. Comparing base (d38af61) to head (2c8d511).

Additional details and impacted files
@@            Coverage Diff             @@
##           master   #12056      +/-   ##
==========================================
+ Coverage   91.43%   91.45%   +0.02%     
==========================================
  Files         975      977       +2     
  Lines       52154    52346     +192     
==========================================
+ Hits        47685    47873     +188     
- Misses       4469     4473       +4     
Flag Coverage Δ
backend 90.47% <95.97%> (+0.02%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

Components Coverage Δ
Backend Apps 91.79% <95.95%> (+0.02%) ⬆️
Backend General 93.38% <ø> (ø)
Frontend ∅ <ø> (∅)
🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@matmair
Copy link
Copy Markdown
Member

matmair commented May 31, 2026

this will probably break a few plugins; can we move the change in the company link to 2.0?

def _require_staff_for_internal_address(request, address_company) -> None:
"""Raise PermissionDenied if the address is internal and the user is not staff."""
if address_company is None and not request.user.is_staff:
raise PermissionDenied(_('Only staff users can modify internal addresses'))
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this forces ppl to use staff accounts - which are well-known sources for security issues; imo this should be a seperate permissions

@matmair
Copy link
Copy Markdown
Member

matmair commented May 31, 2026

Having looked deeper at it: this is a huge breaking change; I do not really understand why we are breaking every existing PO, RO, TO effectively - the value-add of this feature is blurry to me at best.

@SchrodingersGat
Copy link
Copy Markdown
Member Author

So currently, PO / RO / TO - all specify addresses incorrectly (IMO):

Purchase Order

  • Must specify an address linked to the supplier - NOT the delivery address of the org using InvenTree

Return Order

  • Must specify an address linked to the customer - NOT the return address of the org using InvenTree

Transfer Order

  • Not linked to a company at all
  • However the "address" field here must be linked to a Company

I think that in each of these cases having an "internal" address (not linked to any Company) would make more sense, right?

@SchrodingersGat SchrodingersGat modified the milestones: 1.4.0, 1.5.0 Jun 1, 2026
@wolflu05
Copy link
Copy Markdown
Member

wolflu05 commented Jun 1, 2026

Sorry I have no real opinion on this, since I am not really using the addresses, but this may be a big breaking change for some other plugin developers. Just an idea, why cant we create an "Internal Company" and add adresses there? Then instead of company name in system settings we can select the internal company?

@matmair
Copy link
Copy Markdown
Member

matmair commented Jun 1, 2026

I think this solution with an internal flag that fundamentally changes validation and breaking the meaning of existing date entries is not a slight change; it changes how whole integration flows would need to work.

IMO a suggestion to solve the stated problems should not change the meaning of existing data fields without even warning the users.
For POs this would mean adding a new field delivery address and renaming the label and helper text of the current field to supplier adress. The new field could map to a helper property target_field that is exposed by any type of order for keeping a similar python api on all orders.
For ROs the same but names return address(new) and customer address.

For TOs either limit it to addresses that are additionally flagged as internal or add a system setting that enables admins to select if they want non-internal addresses to be allowed for TOs. TOs were not shipped in a stable so changing stuff there does not worry me.

Additionally, I think it would make sense to add a way to have one or more "internal" companies (marked with a flag or setting) - packaging/shipping slips still need company information and this would keep the python API interfaces stable

@SchrodingersGat
Copy link
Copy Markdown
Member Author

Clearly we will need to think carefully about how this is implemented. I'm happy to support "internal" companies (and thus linked addresses) if we all feel that's a cleaner approach

@SchrodingersGat SchrodingersGat modified the milestones: 1.5.0, 2.0.0 Jun 3, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

api Relates to the API breaking Indicates a major update or change which breaks compatibility order Related to purchase orders / sales orders User Interface Related to the frontend / User Interface

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[FR] Delivery Address on Purchase Orders

4 participants