Add lookup tables, payment methods, tax exemptions, and processor link APIs
Replace unit_status and item_condition pgEnums with company-scoped lookup tables that support custom values. Add account_payment_method table, tax_exemption table with approve/revoke workflow, and CRUD routes for processor links. Validate inventory unit status/condition against lookup tables at service layer.
This commit is contained in:
@@ -6,12 +6,14 @@ import {
|
||||
jsonb,
|
||||
timestamp,
|
||||
boolean,
|
||||
integer,
|
||||
date,
|
||||
pgEnum,
|
||||
} from 'drizzle-orm/pg-core'
|
||||
import { companies } from './stores.js'
|
||||
|
||||
export const billingModeEnum = pgEnum('billing_mode', ['consolidated', 'split'])
|
||||
export const taxExemptStatusEnum = pgEnum('tax_exempt_status', ['none', 'pending', 'approved'])
|
||||
|
||||
export const accounts = pgTable('account', {
|
||||
id: uuid('id').primaryKey().defaultRandom(),
|
||||
@@ -77,6 +79,54 @@ export const accountProcessorLinks = pgTable('account_processor_link', {
|
||||
export type AccountProcessorLink = typeof accountProcessorLinks.$inferSelect
|
||||
export type AccountProcessorLinkInsert = typeof accountProcessorLinks.$inferInsert
|
||||
|
||||
export const accountPaymentMethods = pgTable('account_payment_method', {
|
||||
id: uuid('id').primaryKey().defaultRandom(),
|
||||
accountId: uuid('account_id')
|
||||
.notNull()
|
||||
.references(() => accounts.id),
|
||||
companyId: uuid('company_id')
|
||||
.notNull()
|
||||
.references(() => companies.id),
|
||||
processor: processorEnum('processor').notNull(),
|
||||
processorPaymentMethodId: varchar('processor_payment_method_id', { length: 255 }).notNull(),
|
||||
cardBrand: varchar('card_brand', { length: 50 }),
|
||||
lastFour: varchar('last_four', { length: 4 }),
|
||||
expMonth: integer('exp_month'),
|
||||
expYear: integer('exp_year'),
|
||||
isDefault: boolean('is_default').notNull().default(false),
|
||||
requiresUpdate: boolean('requires_update').notNull().default(false),
|
||||
createdAt: timestamp('created_at', { withTimezone: true }).notNull().defaultNow(),
|
||||
})
|
||||
|
||||
export type AccountPaymentMethod = typeof accountPaymentMethods.$inferSelect
|
||||
export type AccountPaymentMethodInsert = typeof accountPaymentMethods.$inferInsert
|
||||
|
||||
export const taxExemptions = pgTable('tax_exemption', {
|
||||
id: uuid('id').primaryKey().defaultRandom(),
|
||||
accountId: uuid('account_id')
|
||||
.notNull()
|
||||
.references(() => accounts.id),
|
||||
companyId: uuid('company_id')
|
||||
.notNull()
|
||||
.references(() => companies.id),
|
||||
status: taxExemptStatusEnum('status').notNull().default('pending'),
|
||||
certificateNumber: varchar('certificate_number', { length: 255 }).notNull(),
|
||||
certificateType: varchar('certificate_type', { length: 100 }),
|
||||
issuingState: varchar('issuing_state', { length: 2 }),
|
||||
expiresAt: date('expires_at'),
|
||||
approvedBy: uuid('approved_by'),
|
||||
approvedAt: timestamp('approved_at', { withTimezone: true }),
|
||||
revokedBy: uuid('revoked_by'),
|
||||
revokedAt: timestamp('revoked_at', { withTimezone: true }),
|
||||
revokedReason: text('revoked_reason'),
|
||||
notes: text('notes'),
|
||||
createdAt: timestamp('created_at', { withTimezone: true }).notNull().defaultNow(),
|
||||
updatedAt: timestamp('updated_at', { withTimezone: true }).notNull().defaultNow(),
|
||||
})
|
||||
|
||||
export type TaxExemption = typeof taxExemptions.$inferSelect
|
||||
export type TaxExemptionInsert = typeof taxExemptions.$inferInsert
|
||||
|
||||
export type Account = typeof accounts.$inferSelect
|
||||
export type AccountInsert = typeof accounts.$inferInsert
|
||||
export type Member = typeof members.$inferSelect
|
||||
|
||||
Reference in New Issue
Block a user