183 lines
4.6 KiB
TypeScript
183 lines
4.6 KiB
TypeScript
import {
|
|
Entity,
|
|
PrimaryGeneratedColumn,
|
|
Column,
|
|
CreateDateColumn,
|
|
UpdateDateColumn,
|
|
Index,
|
|
} from 'typeorm';
|
|
|
|
export enum ShippingRateStatus {
|
|
ACTIVE = 'active',
|
|
INACTIVE = 'inactive',
|
|
}
|
|
|
|
export enum ShippingCalculation {
|
|
FLAT_RATE = 'flat_rate',
|
|
BY_WEIGHT = 'by_weight',
|
|
BY_PRICE = 'by_price',
|
|
BY_QUANTITY = 'by_quantity',
|
|
FREE = 'free',
|
|
CARRIER_CALCULATED = 'carrier_calculated',
|
|
}
|
|
|
|
@Entity('shipping_rates', { schema: 'retail' })
|
|
@Index(['tenantId', 'status'])
|
|
@Index(['tenantId', 'code'], { unique: true })
|
|
export class ShippingRate {
|
|
@PrimaryGeneratedColumn('uuid')
|
|
id: string;
|
|
|
|
@Column({ name: 'tenant_id', type: 'uuid' })
|
|
@Index()
|
|
tenantId: string;
|
|
|
|
@Column({ length: 20, unique: true })
|
|
code: string;
|
|
|
|
@Column({ length: 100 })
|
|
name: string;
|
|
|
|
@Column({ type: 'text', nullable: true })
|
|
description: string;
|
|
|
|
@Column({
|
|
type: 'enum',
|
|
enum: ShippingRateStatus,
|
|
default: ShippingRateStatus.ACTIVE,
|
|
})
|
|
status: ShippingRateStatus;
|
|
|
|
@Column({
|
|
name: 'calculation_type',
|
|
type: 'enum',
|
|
enum: ShippingCalculation,
|
|
default: ShippingCalculation.FLAT_RATE,
|
|
})
|
|
calculationType: ShippingCalculation;
|
|
|
|
// Flat rate
|
|
@Column({ name: 'flat_rate', type: 'decimal', precision: 15, scale: 2, nullable: true })
|
|
flatRate: number;
|
|
|
|
// Weight-based rates
|
|
@Column({ name: 'weight_rates', type: 'jsonb', nullable: true })
|
|
weightRates: {
|
|
minWeight: number;
|
|
maxWeight: number;
|
|
rate: number;
|
|
}[];
|
|
|
|
@Column({ name: 'weight_unit', length: 5, default: 'kg' })
|
|
weightUnit: string;
|
|
|
|
// Price-based rates
|
|
@Column({ name: 'price_rates', type: 'jsonb', nullable: true })
|
|
priceRates: {
|
|
minPrice: number;
|
|
maxPrice: number;
|
|
rate: number;
|
|
}[];
|
|
|
|
// Quantity-based rates
|
|
@Column({ name: 'quantity_rates', type: 'jsonb', nullable: true })
|
|
quantityRates: {
|
|
minQuantity: number;
|
|
maxQuantity: number;
|
|
rate: number;
|
|
}[];
|
|
|
|
// Free shipping threshold
|
|
@Column({ name: 'free_shipping_threshold', type: 'decimal', precision: 15, scale: 2, nullable: true })
|
|
freeShippingThreshold: number;
|
|
|
|
// Carrier integration
|
|
@Column({ name: 'carrier_code', length: 50, nullable: true })
|
|
carrierCode: string;
|
|
|
|
@Column({ name: 'carrier_name', length: 100, nullable: true })
|
|
carrierName: string;
|
|
|
|
@Column({ name: 'carrier_service', length: 50, nullable: true })
|
|
carrierService: string;
|
|
|
|
@Column({ name: 'carrier_api_config', type: 'jsonb', nullable: true })
|
|
carrierApiConfig: Record<string, any>;
|
|
|
|
// Delivery time
|
|
@Column({ name: 'min_delivery_days', type: 'int', nullable: true })
|
|
minDeliveryDays: number;
|
|
|
|
@Column({ name: 'max_delivery_days', type: 'int', nullable: true })
|
|
maxDeliveryDays: number;
|
|
|
|
@Column({ name: 'delivery_message', length: 255, nullable: true })
|
|
deliveryMessage: string;
|
|
|
|
// Geographic restrictions
|
|
@Column({ name: 'allowed_countries', type: 'jsonb', nullable: true })
|
|
allowedCountries: string[];
|
|
|
|
@Column({ name: 'allowed_states', type: 'jsonb', nullable: true })
|
|
allowedStates: string[];
|
|
|
|
@Column({ name: 'allowed_postal_codes', type: 'jsonb', nullable: true })
|
|
allowedPostalCodes: string[];
|
|
|
|
@Column({ name: 'excluded_postal_codes', type: 'jsonb', nullable: true })
|
|
excludedPostalCodes: string[];
|
|
|
|
// Product restrictions
|
|
@Column({ name: 'excluded_categories', type: 'jsonb', nullable: true })
|
|
excludedCategories: string[];
|
|
|
|
@Column({ name: 'excluded_products', type: 'jsonb', nullable: true })
|
|
excludedProducts: string[];
|
|
|
|
// Weight/dimension limits
|
|
@Column({ name: 'max_weight', type: 'decimal', precision: 10, scale: 4, nullable: true })
|
|
maxWeight: number;
|
|
|
|
@Column({ name: 'max_dimensions', type: 'jsonb', nullable: true })
|
|
maxDimensions: {
|
|
length: number;
|
|
width: number;
|
|
height: number;
|
|
unit: string;
|
|
};
|
|
|
|
// Customer restrictions
|
|
@Column({ name: 'customer_levels', type: 'jsonb', nullable: true })
|
|
customerLevels: string[];
|
|
|
|
// Tax
|
|
@Column({ name: 'is_taxable', type: 'boolean', default: true })
|
|
isTaxable: boolean;
|
|
|
|
@Column({ name: 'tax_rate', type: 'decimal', precision: 5, scale: 4, nullable: true })
|
|
taxRate: number;
|
|
|
|
// Display
|
|
@Column({ type: 'int', default: 0 })
|
|
priority: number;
|
|
|
|
@Column({ name: 'display_name', length: 100, nullable: true })
|
|
displayName: string;
|
|
|
|
@Column({ name: 'icon_url', length: 255, nullable: true })
|
|
iconUrl: string;
|
|
|
|
// Metadata
|
|
@Column({ type: 'jsonb', nullable: true })
|
|
metadata: Record<string, any>;
|
|
|
|
@CreateDateColumn({ name: 'created_at' })
|
|
createdAt: Date;
|
|
|
|
@UpdateDateColumn({ name: 'updated_at' })
|
|
updatedAt: Date;
|
|
|
|
@Column({ name: 'created_by', type: 'uuid', nullable: true })
|
|
createdBy: string;
|
|
}
|