Skip to content

Add store-scoped customer & address attribute management to Grand.Web.Store#722

Merged
KrzysztofPajak merged 2 commits into
developfrom
feature/store-customer-address-attributes
Jul 4, 2026
Merged

Add store-scoped customer & address attribute management to Grand.Web.Store#722
KrzysztofPajak merged 2 commits into
developfrom
feature/store-customer-address-attributes

Conversation

@KrzysztofPajak

Copy link
Copy Markdown
Member

Summary

Store owners can manage their own Customer attributes and Address attributes in Grand.Web.Store. They see only global attributes (read-only preview) and attributes belonging to their store (full CRUD). Attributes limited to other stores are hidden and access is blocked at the controller level. The Stores / LimitedToStores fields are hidden in the store panel and set automatically to the staff store.

Changes

  • Domain: CustomerAttribute and AddressAttribute implement IStoreLinkEntity (LimitedToStores + Stores) — existing documents remain global by default, no migration needed
  • Services: GetAllCustomerAttributes(storeId) / GetAllAddressAttributes(storeId) overloads with per-store cache keys, respecting AccessControlConfig.IgnoreStoreLimitations
  • Storefront: registration/account and address forms render only current-store attributes; GetAttributeWarnings(attrs, storeId) parser overloads so a required attribute of another store no longer blocks registration/checkout in the current store
  • Admin: Stores selector added to customer/address attribute forms (same as ContactAttributes)
  • Grand.Web.Store: new CustomerAttributeController and AddressAttributeController with full view sets, following the ContactAttribute pattern from Add store-scoped contact attribute management to Grand.Web.Store #710 (IsGlobalAttribute preview mode, ownership checks via AccessToEntityByStore)
  • Resources: new limitedtostores and globalreadonly translation keys

Tests

  • Solution builds clean; all related test projects pass (Customers, Common, Web, Store, Mapping, Admin)
  • Updated service ctors in tests (new AccessControlConfig param), parser mocks and Verify snapshots

🤖 Generated with Claude Code

….Store

Store owners can create, edit and delete their own customer attributes
and address attributes. Global attributes are visible in read-only
preview mode; attributes limited to other stores are hidden and access
is blocked at the controller level.

- CustomerAttribute and AddressAttribute implement IStoreLinkEntity
  (LimitedToStores + Stores)
- GetAllCustomerAttributes(storeId) / GetAllAddressAttributes(storeId)
  service overloads with per-store cache keys
- Storefront handlers and validators filter attributes by current store;
  GetAttributeWarnings(attrs, storeId) parser overloads so required
  attributes of other stores do not block registration/checkout
- Admin: Stores selector on customer/address attribute forms
- Grand.Web.Store: CustomerAttributeController + AddressAttributeController
  with views following the ContactAttribute pattern (PR #710); Stores field
  hidden and auto-set to the staff store
- New translation resources (limitedtostores, globalreadonly)

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Copilot AI review requested due to automatic review settings July 4, 2026 17:03

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

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 GrandNode’s multi-store attribute system by adding store-scoped Customer Attributes and Address Attributes management to Grand.Web.Store, and updating storefront/service-layer parsing + validation so attributes are filtered/validated against the current store.

Changes:

  • Add IStoreLinkEntity store-linking (LimitedToStores + Stores) to CustomerAttribute and AddressAttribute, plus admin UI support for selecting stores.
  • Introduce store-aware service/parser overloads and update web handlers/validators to fetch and validate only the current-store attributes.
  • Add Grand.Web.Store controllers, models, validators, AutoMapper profiles, and full view sets to enable store-manager CRUD for store-owned attributes and read-only preview for global ones.

Reviewed changes

Copilot reviewed 61 out of 62 changed files in this pull request and generated 5 comments.

Show a summary per file
File Description
src/Web/Grand.Web/Validators/Orders/MerchandiseReturnValidator.cs Pass current store id into address-attribute warning validation.
src/Web/Grand.Web/Validators/Customer/RegisterValidator.cs Pass store id into customer-attribute warning validation during registration.
src/Web/Grand.Web/Validators/Customer/CustomerInfoValidator.cs Pass store id into customer-attribute warning validation during profile update.
src/Web/Grand.Web/Validators/Customer/CustomerAddressEditValidator.cs Thread IContextAccessor into nested address validation for store-scoped warnings.
src/Web/Grand.Web/Validators/Customer/CheckoutShippingAddressValidator.cs Thread IContextAccessor into shipping address validation for store-scoped warnings.
src/Web/Grand.Web/Validators/Customer/CheckoutBillingAddressValidator.cs Thread IContextAccessor into billing address validation for store-scoped warnings.
src/Web/Grand.Web/Validators/Common/AddressValidator.cs Validate address attributes’ required-ness with current store id.
src/Web/Grand.Web/Features/Handlers/Customers/GetParseCustomAttributesHandler.cs Parse customer attributes using store-filtered attribute list.
src/Web/Grand.Web/Features/Handlers/Customers/GetCustomAttributesHandler.cs Build customer attribute models from store-filtered attribute list.
src/Web/Grand.Web/Features/Handlers/Common/GetParseCustomAddressAttributesHandler.cs Parse address attributes using store-filtered attribute list.
src/Web/Grand.Web/Features/Handlers/Common/GetAddressModelHandler.cs Render custom address attributes using store-filtered attribute list when store provided.
src/Web/Grand.Web/Commands/Handler/Customers/CustomerRegisteredCommandHandler.cs Validate default address required attributes using the registration store id.
src/Web/Grand.Web.Store/Validators/CustomerAttributeStoreValidator.cs Store-panel validator wrapper that reuses the base admin-shared validator.
src/Web/Grand.Web.Store/Validators/AddressAttributeStoreValidator.cs Store-panel validator wrapper that reuses the base admin-shared validator.
src/Web/Grand.Web.Store/Models/Customers/CustomerAttributeStoreModel.cs Store-panel model adds IsGlobalAttribute (read-only preview mode).
src/Web/Grand.Web.Store/Models/Common/AddressAttributeStoreModel.cs Store-panel model adds IsGlobalAttribute (read-only preview mode).
src/Web/Grand.Web.Store/Mapper/CustomerAttributeStoreProfile.cs AutoMapper profile for CustomerAttribute → store-panel model mapping.
src/Web/Grand.Web.Store/Mapper/AddressAttributeStoreProfile.cs AutoMapper profile for AddressAttribute → store-panel model mapping.
src/Web/Grand.Web.Store/Controllers/CustomerAttributeController.cs New store-panel CRUD controller with store visibility/ownership checks and value management.
src/Web/Grand.Web.Store/Controllers/AddressAttributeController.cs New store-panel CRUD controller with store visibility/ownership checks and value management.
src/Web/Grand.Web.Store/Areas/Store/Views/CustomerAttribute/ValueEditPopup.cshtml Popup UI for editing customer attribute values.
src/Web/Grand.Web.Store/Areas/Store/Views/CustomerAttribute/ValueCreatePopup.cshtml Popup UI for creating customer attribute values.
src/Web/Grand.Web.Store/Areas/Store/Views/CustomerAttribute/Partials/CreateOrUpdateValue.cshtml Shared partial for customer attribute value create/edit form.
src/Web/Grand.Web.Store/Areas/Store/Views/CustomerAttribute/Partials/CreateOrUpdate.TabValues.cshtml Customer attribute values grid + add/edit/delete UI (with read-only mode handling).
src/Web/Grand.Web.Store/Areas/Store/Views/CustomerAttribute/Partials/CreateOrUpdate.TabInfo.cshtml Customer attribute edit UI for info tab (with read-only mode handling).
src/Web/Grand.Web.Store/Areas/Store/Views/CustomerAttribute/Partials/CreateOrUpdate.cshtml Tabstrip composition for customer attribute create/edit.
src/Web/Grand.Web.Store/Areas/Store/Views/CustomerAttribute/List.cshtml Customer attributes list grid in store panel.
src/Web/Grand.Web.Store/Areas/Store/Views/CustomerAttribute/Edit.cshtml Customer attribute edit page with read-only global preview messaging.
src/Web/Grand.Web.Store/Areas/Store/Views/CustomerAttribute/Create.cshtml Customer attribute create page in store panel.
src/Web/Grand.Web.Store/Areas/Store/Views/AddressAttribute/ValueEditPopup.cshtml Popup UI for editing address attribute values.
src/Web/Grand.Web.Store/Areas/Store/Views/AddressAttribute/ValueCreatePopup.cshtml Popup UI for creating address attribute values.
src/Web/Grand.Web.Store/Areas/Store/Views/AddressAttribute/Partials/CreateOrUpdateValue.cshtml Shared partial for address attribute value create/edit form.
src/Web/Grand.Web.Store/Areas/Store/Views/AddressAttribute/Partials/CreateOrUpdate.TabValues.cshtml Address attribute values grid + add/edit/delete UI (with read-only mode handling).
src/Web/Grand.Web.Store/Areas/Store/Views/AddressAttribute/Partials/CreateOrUpdate.TabInfo.cshtml Address attribute edit UI for info tab (with read-only mode handling).
src/Web/Grand.Web.Store/Areas/Store/Views/AddressAttribute/Partials/CreateOrUpdate.cshtml Tabstrip composition for address attribute create/edit.
src/Web/Grand.Web.Store/Areas/Store/Views/AddressAttribute/List.cshtml Address attributes list grid in store panel.
src/Web/Grand.Web.Store/Areas/Store/Views/AddressAttribute/Edit.cshtml Address attribute edit page with read-only global preview messaging.
src/Web/Grand.Web.Store/Areas/Store/Views/AddressAttribute/Create.cshtml Address attribute create page in store panel.
src/Web/Grand.Web.Store/Areas/Store/Views/_ViewImports.cshtml Add store-panel model namespaces for attribute views.
src/Web/Grand.Web.AdminShared/Models/Customers/CustomerAttributeModel.cs Add Stores and implement IStoreLinkModel for admin/shared model.
src/Web/Grand.Web.AdminShared/Models/Common/AddressAttributeModel.cs Add Stores and implement IStoreLinkModel for admin/shared model.
src/Web/Grand.Web.AdminShared/Mapper/CustomerAttributeProfile.cs Map LimitedToStores from Stores for customer attributes.
src/Web/Grand.Web.AdminShared/Mapper/AddressAttributeProfile.cs Map LimitedToStores from Stores for address attributes.
src/Web/Grand.Web.Admin/Areas/Admin/Views/CustomerAttribute/Partials/CreateOrUpdate.TabInfo.cshtml Add Stores selector UI to admin customer attribute edit view.
src/Web/Grand.Web.Admin/Areas/Admin/Views/AddressAttribute/Partials/CreateOrUpdate.TabInfo.cshtml Add Stores selector UI to admin address attribute edit view.
src/Tests/Grand.Web.Tests/Validators/Customer/CustomerValidatorsStoreScopingTests.cs Update mocks for new storeId overload on attribute warning APIs.
src/Tests/Grand.Mapping.Tests/AdminShared/CustomerMappingTests.CustomerAttributeModel_ToDomain.verified.txt Snapshot update for LimitedToStores mapping output.
src/Tests/Grand.Mapping.Tests/AdminShared/CommonMappingTests.AddressAttributeModel_ToDomain.verified.txt Snapshot update for LimitedToStores mapping output.
src/Tests/Grand.Business.Customers.Tests/Services/CustomerAttributeServiceTests.cs Update service ctor tests for new AccessControlConfig dependency.
src/Tests/Grand.Business.Customers.Tests/Services/CustomerAttributeParserTests.cs Update parser tests for store-aware attribute service call.
src/Tests/Grand.Business.Common.Tests/Services/Addresses/AddressAttributeServiceTests.cs Update service ctor tests for new AccessControlConfig dependency.
src/Core/Grand.Domain/Customers/CustomerAttribute.cs Add store-link properties and implement IStoreLinkEntity.
src/Core/Grand.Domain/Common/AddressAttribute.cs Add store-link properties and implement IStoreLinkEntity.
src/Business/Grand.Business.Customers/Services/CustomerAttributeService.cs Add store-filtered GetAllCustomerAttributes(storeId) with per-store cache keys + IgnoreStoreLimitations support.
src/Business/Grand.Business.Customers/Services/CustomerAttributeParser.cs Add store-aware GetAttributeWarnings(..., storeId) overload to validate required attrs per store.
src/Business/Grand.Business.Core/Interfaces/Customers/ICustomerAttributeService.cs Add storeId overload for retrieving customer attributes.
src/Business/Grand.Business.Core/Interfaces/Customers/ICustomerAttributeParser.cs Add storeId overload for attribute warnings.
src/Business/Grand.Business.Core/Interfaces/Common/Addresses/IAddressAttributeService.cs Add storeId overload for retrieving address attributes.
src/Business/Grand.Business.Core/Interfaces/Common/Addresses/IAddressAttributeParser.cs Add storeId overload for attribute warnings.
src/Business/Grand.Business.Common/Services/Addresses/AddressAttributeService.cs Add store-filtered GetAllAddressAttributes(storeId) with per-store cache keys + IgnoreStoreLimitations support.
src/Business/Grand.Business.Common/Services/Addresses/AddressAttributeParser.cs Add store-aware GetAttributeWarnings(..., storeId) overload to validate required attrs per store.

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

Comment thread src/Web/Grand.Web/Validators/Customer/RegisterValidator.cs Outdated
Comment thread src/Web/Grand.Web/Validators/Customer/CustomerInfoValidator.cs Outdated
Comment thread src/Web/Grand.Web.Store/Controllers/CustomerAttributeController.cs
Comment thread src/Web/Grand.Web.Store/Controllers/AddressAttributeController.cs
Comment thread src/Web/Grand.Web.Store/Controllers/AddressAttributeController.cs
- RegisterValidator/CustomerInfoValidator: always scope attribute
  validation to the current store instead of the per-store-identity
  storeId, which is empty when RegisterCustomersPerStore is disabled
- Store CustomerAttribute/AddressAttribute Edit POST: repopulate
  Locales when redisplaying the form after a validation failure
- Store ValueDelete endpoints: return a structured DataSourceResult
  error instead of throwing (500) when the value id is not found

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 61 out of 62 changed files in this pull request and generated 2 comments.

Comment thread src/Web/Grand.Web.Store/Controllers/CustomerAttributeController.cs
Comment thread src/Web/Grand.Web.Store/Controllers/AddressAttributeController.cs
@sonarqubecloud

sonarqubecloud Bot commented Jul 4, 2026

Copy link
Copy Markdown

Quality Gate Failed Quality Gate failed

Failed conditions
5.5% Coverage on New Code (required ≥ 80%)
23.5% Duplication on New Code (required ≤ 3%)

See analysis details on SonarQube Cloud

@KrzysztofPajak KrzysztofPajak merged commit bf8825a into develop Jul 4, 2026
7 of 10 checks passed
@KrzysztofPajak KrzysztofPajak deleted the feature/store-customer-address-attributes branch July 4, 2026 18:31
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants