feat(vendor): add contact info inheritance from company
Vendors can now override company contact information for specific branding. Fields are nullable - if null, value is inherited from parent company. Database changes: - Add vendor.contact_email, contact_phone, website, business_address, tax_number - All nullable (null = inherit from company) - Alembic migration: 28d44d503cac Model changes: - Add effective_* properties for resolved values - Add get_contact_info_with_inheritance() helper Schema changes: - VendorCreate: Optional contact fields for override at creation - VendorUpdate: Contact fields + reset_contact_to_company flag - VendorDetailResponse: Resolved values + *_inherited flags API changes: - GET/PUT vendor endpoints return resolved contact info - PUT accepts contact overrides (empty string = reset to inherit) - _build_vendor_detail_response helper for consistent responses Service changes: - admin_service.update_vendor handles reset_contact_to_company flag - Empty strings converted to None for inheritance 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -25,7 +25,8 @@ class VendorCreate(BaseModel):
|
||||
"""
|
||||
Schema for creating a new vendor (storefront/brand) under an existing company.
|
||||
|
||||
Business contact info is inherited from the parent company.
|
||||
Contact info is inherited from the parent company by default.
|
||||
Optionally, provide contact fields to override from the start.
|
||||
"""
|
||||
|
||||
# Parent company
|
||||
@@ -51,6 +52,13 @@ class VendorCreate(BaseModel):
|
||||
letzshop_csv_url_en: str | None = Field(None, description="English CSV URL")
|
||||
letzshop_csv_url_de: str | None = Field(None, description="German CSV URL")
|
||||
|
||||
# Contact Info (optional - if not provided, inherited from company)
|
||||
contact_email: str | None = Field(None, description="Override company contact email")
|
||||
contact_phone: str | None = Field(None, description="Override company contact phone")
|
||||
website: str | None = Field(None, description="Override company website")
|
||||
business_address: str | None = Field(None, description="Override company business address")
|
||||
tax_number: str | None = Field(None, description="Override company tax number")
|
||||
|
||||
@field_validator("subdomain")
|
||||
@classmethod
|
||||
def validate_subdomain(cls, v):
|
||||
@@ -72,8 +80,8 @@ class VendorUpdate(BaseModel):
|
||||
"""
|
||||
Schema for updating vendor information (Admin only).
|
||||
|
||||
Note: Business contact info (contact_email, etc.) is at the Company level.
|
||||
Use company update endpoints to modify those fields.
|
||||
Contact fields can be overridden at the vendor level.
|
||||
Set to null/empty to reset to company default (inherit).
|
||||
"""
|
||||
|
||||
# Basic Information
|
||||
@@ -90,6 +98,18 @@ class VendorUpdate(BaseModel):
|
||||
is_active: bool | None = None
|
||||
is_verified: bool | None = None
|
||||
|
||||
# Contact Info (set value to override, set to empty string to reset to inherit)
|
||||
contact_email: str | None = Field(None, description="Override company contact email")
|
||||
contact_phone: str | None = Field(None, description="Override company contact phone")
|
||||
website: str | None = Field(None, description="Override company website")
|
||||
business_address: str | None = Field(None, description="Override company business address")
|
||||
tax_number: str | None = Field(None, description="Override company tax number")
|
||||
|
||||
# Special flag to reset contact fields to inherit from company
|
||||
reset_contact_to_company: bool | None = Field(
|
||||
None, description="If true, reset all contact fields to inherit from company"
|
||||
)
|
||||
|
||||
@field_validator("subdomain")
|
||||
@classmethod
|
||||
def subdomain_lowercase(cls, v):
|
||||
@@ -135,16 +155,14 @@ class VendorResponse(BaseModel):
|
||||
|
||||
class VendorDetailResponse(VendorResponse):
|
||||
"""
|
||||
Extended vendor response including company information.
|
||||
Extended vendor response including company information and resolved contact info.
|
||||
|
||||
Includes company details like contact info and owner information.
|
||||
Contact fields show the effective value (vendor override or company default)
|
||||
with flags indicating if the value is inherited from the parent company.
|
||||
"""
|
||||
|
||||
# Company info
|
||||
company_name: str = Field(..., description="Name of the parent company")
|
||||
company_contact_email: str = Field(..., description="Company business contact email")
|
||||
company_contact_phone: str | None = Field(None, description="Company phone number")
|
||||
company_website: str | None = Field(None, description="Company website URL")
|
||||
|
||||
# Owner info (at company level)
|
||||
owner_email: str = Field(
|
||||
@@ -152,6 +170,25 @@ class VendorDetailResponse(VendorResponse):
|
||||
)
|
||||
owner_username: str = Field(..., description="Username of the company owner")
|
||||
|
||||
# Resolved contact info (vendor override or company default)
|
||||
contact_email: str | None = Field(None, description="Effective contact email")
|
||||
contact_phone: str | None = Field(None, description="Effective contact phone")
|
||||
website: str | None = Field(None, description="Effective website")
|
||||
business_address: str | None = Field(None, description="Effective business address")
|
||||
tax_number: str | None = Field(None, description="Effective tax number")
|
||||
|
||||
# Inheritance flags (True = value is inherited from company, not overridden)
|
||||
contact_email_inherited: bool = Field(False, description="True if contact_email is from company")
|
||||
contact_phone_inherited: bool = Field(False, description="True if contact_phone is from company")
|
||||
website_inherited: bool = Field(False, description="True if website is from company")
|
||||
business_address_inherited: bool = Field(False, description="True if business_address is from company")
|
||||
tax_number_inherited: bool = Field(False, description="True if tax_number is from company")
|
||||
|
||||
# Original company values (for reference in UI)
|
||||
company_contact_email: str | None = Field(None, description="Company's contact email")
|
||||
company_contact_phone: str | None = Field(None, description="Company's phone number")
|
||||
company_website: str | None = Field(None, description="Company's website URL")
|
||||
|
||||
|
||||
class VendorCreateResponse(VendorDetailResponse):
|
||||
"""
|
||||
|
||||
Reference in New Issue
Block a user