// Procurement & Trading Domain // Contains Procurement, Contract, Harvest, and related trading models // Procurement-specific Enums enum ProcurementStatus { PENDING QUALITY_ASSESSMENT APPROVED REJECTED IN_TRANSIT DELIVERED INVOICED PAID COMPLETED CANCELLED PARTIALLY_REJECTED } enum AgreementType { PURCHASE_AGREEMENT SUPPLY_CONTRACT EXCLUSIVE_SUPPLY SEASONAL_CONTRACT FORWARD_CONTRACT SPOT_CONTRACT CONSIGNMENT PARTNERSHIP } enum ContractStatus { DRAFT PENDING_REVIEW PENDING_SIGNATURE ACTIVE FULFILLED EXPIRED TERMINATED CANCELLED BREACH RENEWED } enum ProcurementAttachmentType { PRODUCT_PHOTO QUALITY_ASSESSMENT_PHOTO WEIGHING_PHOTO PACKAGING_PHOTO LOADING_PHOTO DELIVERY_PHOTO CONTRACT_DOCUMENT INVOICE RECEIPT PAYMENT_PROOF QUALITY_CERTIFICATE TRANSPORT_DOCUMENT REJECTION_PHOTO SIGNATURE_DOCUMENT OTHER_DOCUMENT } // Procurement Models model Harvest { id String @id @default(cuid()) farmerId String farmId String plotId String? variantId String quantity Decimal // in kg harvestDate DateTime qualityGrade QualityGrade waterContent Decimal? // percentage density Decimal? // kg/m3 notes String? createdAt DateTime @default(now()) updatedAt DateTime @updatedAt // Relations farmer Farmer @relation(fields: [farmerId], references: [id]) farm Farm @relation(fields: [farmId], references: [id]) plot Plot? @relation(fields: [plotId], references: [id]) variant ProductVariant @relation(fields: [variantId], references: [id]) procurement Procurement? modifiers HarvestModifier[] @@index([farmerId, farmId]) @@index([harvestDate]) @@index([variantId]) @@index([qualityGrade]) @@index([plotId]) @@map("harvests") } model Procurement { id String @id @default(cuid()) procurementCode String @unique farmerId String buyerId String? harvestId String @unique variantId String // Quantity and quality details quantity Decimal // in kg qualityGrade QualityGrade waterContent Decimal? // percentage density Decimal? // kg/m3 // Pricing details basePrice Decimal // price per kg premiumRate Decimal @default(0) // percentage totalPrice Decimal transportCost Decimal? @default(0) processingCost Decimal? @default(0) finalAmount Decimal // total amount to be paid // Location and logistics pickupLocation String? deliveryLocation String? pickupDate DateTime? deliveryDate DateTime? transportMethod String? // truck, motorcycle, etc. // Quality assessment assessedBy String? // quality assessor ID assessmentDate DateTime? assessmentNotes String? rejectedQuantity Decimal? @default(0) rejectionReason String? // Payment details paymentMethod PaymentMethod? paymentReference String? bankAccount String? // Status and tracking status ProcurementStatus @default(PENDING) procurementDate DateTime @default(now()) approvedDate DateTime? approvedBy String? // admin ID who approved paymentDate DateTime? completedDate DateTime? // Documentation contractId String? // link to formal contract contractNumber String? invoiceNumber String? receiptNumber String? notes String? createdAt DateTime @default(now()) updatedAt DateTime @updatedAt // Relations farmer Farmer @relation(fields: [farmerId], references: [id]) buyer Buyer? @relation(fields: [buyerId], references: [id]) harvest Harvest @relation(fields: [harvestId], references: [id]) variant ProductVariant @relation(fields: [variantId], references: [id]) contract Contract? @relation(fields: [contractId], references: [id]) attachments ProcurementAttachment[] @@index([procurementCode]) @@index([farmerId, buyerId]) @@index([status]) @@index([procurementDate]) @@index([variantId]) @@index([qualityGrade]) @@index([paymentMethod]) @@map("procurements") } model Contract { id String @id @default(cuid()) contractNumber String @unique farmerId String buyerId String productId String? variantId String? // Contract terms title String description String? contractType AgreementType @default(PURCHASE_AGREEMENT) // Pricing and quantity agreedPrice Decimal // price per unit minimumQuantity Decimal? maximumQuantity Decimal? totalValue Decimal? unit String @default("kg") // Quality specifications qualityGrade QualityGrade? qualityRequirements String? // Timeline startDate DateTime endDate DateTime deliverySchedule String? // delivery frequency/schedule // Payment terms paymentTerms String? // payment conditions paymentMethod PaymentMethod? advancePayment Decimal? @default(0) advancePercentage Decimal? @default(0) // Legal and compliance terms String? // full terms and conditions penalties String? // penalty clauses forcemajeure String? // force majeure clause governingLaw String? // applicable law // Status and tracking status ContractStatus @default(DRAFT) signedDate DateTime? signedByFarmer Boolean @default(false) signedByBuyer Boolean @default(false) farmerSignature String? // signature data or URL buyerSignature String? // signature data or URL witnessName String? witnessSignature String? // Performance tracking totalDelivered Decimal? @default(0) totalPaid Decimal? @default(0) deliveryCount Int @default(0) // Renewal and amendments renewalDate DateTime? amendmentCount Int @default(0) parentContractId String? // for contract renewals // Documentation documentUrl String? // contract document attachmentUrls String[] // supporting documents notes String? createdAt DateTime @default(now()) updatedAt DateTime @updatedAt // Relations farmer Farmer @relation(fields: [farmerId], references: [id]) buyer Buyer @relation(fields: [buyerId], references: [id]) product Product? @relation(fields: [productId], references: [id]) variant ProductVariant? @relation(fields: [variantId], references: [id]) parentContract Contract? @relation("ContractRenewal", fields: [parentContractId], references: [id]) renewalContracts Contract[] @relation("ContractRenewal") procurements Procurement[] // deliveries under this contract @@index([contractNumber]) @@index([farmerId, buyerId]) @@index([status]) @@index([startDate, endDate]) @@index([productId, variantId]) @@index([signedDate]) @@map("contracts") } model ProcurementAttachment { id String @id @default(cuid()) procurementId String type ProcurementAttachmentType title String description String? fileUrl String fileName String fileSize Int? // in bytes mimeType String? uploadedBy String? // user ID who uploaded takenDate DateTime? // when photo was taken gpsLocation Json? // GeoJSON point where photo was taken isVerified Boolean @default(false) verifiedBy String? // admin ID who verified verifiedAt DateTime? createdAt DateTime @default(now()) updatedAt DateTime @updatedAt // Relations procurement Procurement @relation(fields: [procurementId], references: [id], onDelete: Cascade) @@index([procurementId]) @@index([type]) @@index([isVerified]) @@index([createdAt]) @@map("procurement_attachments") }