mirror of
https://github.com/xtr-dev/payload-billing.git
synced 2025-12-11 03:13:25 +00:00
fix: Improve invoice customer data handling and validation
- Make customerInfo fields conditionally required based on customer relationship - Add admin UI conditional visibility to hide embedded fields when relationship exists - Fix address field naming inconsistency (postal_code -> postalCode) - Update types to properly reflect optional customerInfo/billingAddress - Add validation to ensure either customer relationship or embedded info is provided 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -71,7 +71,7 @@ export function createCustomersCollection(slug: string = 'customers'): Collectio
|
|||||||
label: 'State/Province',
|
label: 'State/Province',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: 'postal_code',
|
name: 'postalCode',
|
||||||
type: 'text',
|
type: 'text',
|
||||||
label: 'Postal Code',
|
label: 'Postal Code',
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -55,6 +55,7 @@ export function createInvoicesCollection(
|
|||||||
type: 'group',
|
type: 'group',
|
||||||
admin: {
|
admin: {
|
||||||
description: 'Customer billing information',
|
description: 'Customer billing information',
|
||||||
|
condition: customerCollectionSlug ? (data: InvoiceData) => !data.customer : undefined,
|
||||||
},
|
},
|
||||||
fields: [
|
fields: [
|
||||||
{
|
{
|
||||||
@@ -63,7 +64,7 @@ export function createInvoicesCollection(
|
|||||||
admin: {
|
admin: {
|
||||||
description: 'Customer name',
|
description: 'Customer name',
|
||||||
},
|
},
|
||||||
required: true,
|
required: !customerCollectionSlug,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: 'email',
|
name: 'email',
|
||||||
@@ -71,7 +72,7 @@ export function createInvoicesCollection(
|
|||||||
admin: {
|
admin: {
|
||||||
description: 'Customer email address',
|
description: 'Customer email address',
|
||||||
},
|
},
|
||||||
required: true,
|
required: !customerCollectionSlug,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: 'phone',
|
name: 'phone',
|
||||||
@@ -101,6 +102,7 @@ export function createInvoicesCollection(
|
|||||||
type: 'group',
|
type: 'group',
|
||||||
admin: {
|
admin: {
|
||||||
description: 'Billing address',
|
description: 'Billing address',
|
||||||
|
condition: customerCollectionSlug ? (data: InvoiceData) => !data.customer : undefined,
|
||||||
},
|
},
|
||||||
fields: [
|
fields: [
|
||||||
{
|
{
|
||||||
@@ -109,7 +111,7 @@ export function createInvoicesCollection(
|
|||||||
admin: {
|
admin: {
|
||||||
description: 'Address line 1',
|
description: 'Address line 1',
|
||||||
},
|
},
|
||||||
required: true,
|
required: !customerCollectionSlug,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: 'line2',
|
name: 'line2',
|
||||||
@@ -121,7 +123,7 @@ export function createInvoicesCollection(
|
|||||||
{
|
{
|
||||||
name: 'city',
|
name: 'city',
|
||||||
type: 'text',
|
type: 'text',
|
||||||
required: true,
|
required: !customerCollectionSlug,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: 'state',
|
name: 'state',
|
||||||
@@ -136,7 +138,7 @@ export function createInvoicesCollection(
|
|||||||
admin: {
|
admin: {
|
||||||
description: 'Postal or ZIP code',
|
description: 'Postal or ZIP code',
|
||||||
},
|
},
|
||||||
required: true,
|
required: !customerCollectionSlug,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: 'country',
|
name: 'country',
|
||||||
@@ -145,7 +147,7 @@ export function createInvoicesCollection(
|
|||||||
description: 'Country code (e.g., US, GB)',
|
description: 'Country code (e.g., US, GB)',
|
||||||
},
|
},
|
||||||
maxLength: 2,
|
maxLength: 2,
|
||||||
required: true,
|
required: !customerCollectionSlug,
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
@@ -329,6 +331,18 @@ export function createInvoicesCollection(
|
|||||||
],
|
],
|
||||||
beforeValidate: [
|
beforeValidate: [
|
||||||
({ data }: CollectionBeforeValidateHook<InvoiceData>) => {
|
({ data }: CollectionBeforeValidateHook<InvoiceData>) => {
|
||||||
|
if (!data) return
|
||||||
|
|
||||||
|
// Validate customer data: either relationship or embedded info must be provided
|
||||||
|
if (customerCollectionSlug && !data.customer && (!data.customerInfo?.name || !data.customerInfo?.email)) {
|
||||||
|
throw new Error('Either select a customer or provide customer information')
|
||||||
|
}
|
||||||
|
|
||||||
|
// If no customer collection, ensure customer info is provided
|
||||||
|
if (!customerCollectionSlug && (!data.customerInfo?.name || !data.customerInfo?.email)) {
|
||||||
|
throw new Error('Customer name and email are required')
|
||||||
|
}
|
||||||
|
|
||||||
if (data && data.items && Array.isArray(data.items)) {
|
if (data && data.items && Array.isArray(data.items)) {
|
||||||
// Calculate totals for each line item
|
// Calculate totals for each line item
|
||||||
data.items = data.items.map((item: InvoiceItemData) => ({
|
data.items = data.items.map((item: InvoiceItemData) => ({
|
||||||
|
|||||||
@@ -140,7 +140,7 @@ export interface CustomerRecord {
|
|||||||
country?: string
|
country?: string
|
||||||
line1?: string
|
line1?: string
|
||||||
line2?: string
|
line2?: string
|
||||||
postal_code?: string
|
postalCode?: string
|
||||||
state?: string
|
state?: string
|
||||||
}
|
}
|
||||||
createdAt: string
|
createdAt: string
|
||||||
|
|||||||
@@ -97,7 +97,7 @@ export interface CustomerData {
|
|||||||
country?: string
|
country?: string
|
||||||
line1?: string
|
line1?: string
|
||||||
line2?: string
|
line2?: string
|
||||||
postal_code?: string
|
postalCode?: string
|
||||||
state?: string
|
state?: string
|
||||||
}
|
}
|
||||||
email?: string
|
email?: string
|
||||||
@@ -142,15 +142,15 @@ export interface InvoiceDocument extends InvoiceData {
|
|||||||
amount: number
|
amount: number
|
||||||
createdAt: string
|
createdAt: string
|
||||||
currency: string
|
currency: string
|
||||||
customer?: string // Now optional
|
customer?: string // Optional relationship
|
||||||
customerInfo: {
|
customerInfo?: { // Optional when customer relationship exists
|
||||||
company?: string
|
company?: string
|
||||||
email: string
|
email: string
|
||||||
name: string
|
name: string
|
||||||
phone?: string
|
phone?: string
|
||||||
taxId?: string
|
taxId?: string
|
||||||
}
|
}
|
||||||
billingAddress: {
|
billingAddress?: { // Optional when customer relationship exists
|
||||||
city: string
|
city: string
|
||||||
country: string
|
country: string
|
||||||
line1: string
|
line1: string
|
||||||
|
|||||||
Reference in New Issue
Block a user