Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions clients/apps/web/src/components/Orders/DownloadInvoice.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -341,6 +341,7 @@ const DownloadInvoice = ({
country={country}
value={field.value || ''}
onChange={field.onChange}
disabled={order.paid}
/>
<FormMessage />
</>
Expand All @@ -361,6 +362,7 @@ const DownloadInvoice = ({
value={field.value || undefined}
onChange={field.onChange}
allowedCountries={enums.addressInputCountryValues}
disabled={order.paid}
/>
<FormMessage />
</>
Expand Down
11 changes: 9 additions & 2 deletions clients/packages/ui/src/components/atoms/CountryPicker.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ const CountryPicker = ({
className,
itemClassName,
contentClassName,
disabled,
}: {
allowedCountries: readonly string[]
value?: string
Expand All @@ -36,11 +37,17 @@ const CountryPicker = ({
className?: string
itemClassName?: string
contentClassName?: string
disabled?: boolean
}) => {
const countryMap = getCountryList(allowedCountries as TCountryCode[])
return (
<Select onValueChange={onChange} value={value} autoComplete={autoComplete}>
<SelectTrigger className={className}>
<Select
onValueChange={onChange}
value={value}
autoComplete={autoComplete}
disabled={disabled}
>
<SelectTrigger className={className} disabled={disabled}>
<SelectValue
placeholder="Country"
// Avoids issues due to browser automatic translation
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,7 @@ const CountryStatePicker = ({
autoComplete,
itemClassName,
contentClassName,
disabled,
}: {
className?: string
contentClassName?: string
Expand All @@ -92,6 +93,7 @@ const CountryStatePicker = ({
onChange: (value: string) => void
country?: string
autoComplete?: string
disabled?: boolean
}) => {
if (country === 'US' || country === 'CA') {
const states = country === 'US' ? US_STATES : CA_PROVINCES
Expand All @@ -100,8 +102,9 @@ const CountryStatePicker = ({
onValueChange={onChange}
value={value}
autoComplete={autoComplete}
disabled={disabled}
>
<SelectTrigger className={className}>
<SelectTrigger className={className} disabled={disabled}>
<SelectValue
placeholder={country === 'US' ? 'State' : 'Province'}
// Avoids issues due to browser automatic translation
Expand Down Expand Up @@ -133,6 +136,7 @@ const CountryStatePicker = ({
placeholder="State / Province"
value={value}
onChange={(e) => onChange(e.target.value)}
disabled={disabled}
/>
)
}
Expand Down
38 changes: 37 additions & 1 deletion server/polar/order/service.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@
from polar.event.service import event as event_service
from polar.event.system import OrderPaidMetadata, SystemEvent, build_system_event
from polar.eventstream.service import publish as eventstream_publish
from polar.exceptions import PolarError
from polar.exceptions import PolarError, PolarRequestValidationError
from polar.file.s3 import S3_SERVICES
from polar.held_balance.service import held_balance as held_balance_service
from polar.integrations.stripe.service import stripe as stripe_service
Expand Down Expand Up @@ -339,6 +339,42 @@ async def update(
order: Order,
order_update: OrderUpdate | CustomerOrderUpdate,
) -> Order:
# Validate that country/state cannot be changed after order is paid
# because VAT was calculated based on the original address
if order.paid and order_update.billing_address is not None:
new_address = order_update.billing_address
existing_address = order.billing_address

new_country = str(new_address.country) if new_address else None
new_state = new_address.state if new_address else None
existing_country = (
str(existing_address.country) if existing_address else None
)
existing_state = existing_address.state if existing_address else None

if new_country != existing_country:
raise PolarRequestValidationError(
[
{
"type": "value_error",
"loc": ("body", "billing_address", "country"),
"msg": "Cannot change country after order is paid.",
"input": new_country,
}
]
)
if new_state != existing_state:
raise PolarRequestValidationError(
[
{
"type": "value_error",
"loc": ("body", "billing_address", "state"),
"msg": "Cannot change state after order is paid.",
"input": new_state,
}
]
)

repository = OrderRepository.from_session(session)
order = await repository.update(
order, update_dict=order_update.model_dump(exclude_unset=True)
Expand Down
Loading