create-crm-tmp 1.1.2 → 2.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +1 -1
- package/template/.prettierignore +2 -0
- package/template/README.md +53 -67
- package/template/components.json +22 -0
- package/template/exemple-contacts.csv +54 -0
- package/template/next.config.ts +27 -1
- package/template/package.json +64 -27
- package/template/prisma/schema.prisma +821 -72
- package/template/skills-lock.json +25 -0
- package/template/src/app/(auth)/invite/[token]/page.tsx +21 -24
- package/template/src/app/(auth)/reset-password/complete/page.tsx +12 -21
- package/template/src/app/(auth)/reset-password/page.tsx +12 -8
- package/template/src/app/(auth)/reset-password/verify/page.tsx +12 -8
- package/template/src/app/(auth)/signin/page.tsx +20 -17
- package/template/src/app/(dashboard)/agenda/page.tsx +2231 -2188
- package/template/src/app/(dashboard)/automatisation/[id]/page.tsx +10 -7
- package/template/src/app/(dashboard)/automatisation/_components/workflow-editor.tsx +680 -323
- package/template/src/app/(dashboard)/automatisation/new/page.tsx +11 -8
- package/template/src/app/(dashboard)/automatisation/page.tsx +473 -180
- package/template/src/app/(dashboard)/closing/page.tsx +500 -468
- package/template/src/app/(dashboard)/contacts/[id]/page.tsx +5035 -4126
- package/template/src/app/(dashboard)/contacts/companies/[id]/page.tsx +1703 -0
- package/template/src/app/(dashboard)/contacts/loading.tsx +13 -0
- package/template/src/app/(dashboard)/contacts/page.tsx +3776 -2064
- package/template/src/app/(dashboard)/dashboard/page.tsx +37 -519
- package/template/src/app/(dashboard)/error.tsx +37 -0
- package/template/src/app/(dashboard)/layout.tsx +1 -1
- package/template/src/app/(dashboard)/loading.tsx +5 -0
- package/template/src/app/(dashboard)/settings/loading.tsx +19 -0
- package/template/src/app/(dashboard)/settings/page.tsx +2685 -2489
- package/template/src/app/(dashboard)/templates/page.tsx +500 -300
- package/template/src/app/(dashboard)/users/list/page.tsx +356 -350
- package/template/src/app/(dashboard)/users/page.tsx +279 -310
- package/template/src/app/(dashboard)/users/permissions/page.tsx +104 -99
- package/template/src/app/(dashboard)/users/roles/page.tsx +164 -137
- package/template/src/app/api/audit-logs/route.ts +1 -1
- package/template/src/app/api/auth/google/callback/route.ts +8 -5
- package/template/src/app/api/auth/google/disconnect/route.ts +2 -2
- package/template/src/app/api/companies/[id]/activities/route.ts +131 -0
- package/template/src/app/api/companies/[id]/route.ts +195 -0
- package/template/src/app/api/companies/export/route.ts +206 -0
- package/template/src/app/api/companies/route.ts +166 -0
- package/template/src/app/api/contact-views/[id]/pin/route.ts +69 -0
- package/template/src/app/api/contact-views/[id]/route.ts +197 -0
- package/template/src/app/api/contact-views/route.ts +146 -0
- package/template/src/app/api/contacts/[id]/files/[fileId]/preview/route.ts +77 -0
- package/template/src/app/api/contacts/[id]/files/[fileId]/route.ts +7 -17
- package/template/src/app/api/contacts/[id]/files/route.ts +83 -44
- package/template/src/app/api/contacts/[id]/interactions/route.ts +37 -0
- package/template/src/app/api/contacts/[id]/kyc/route.ts +71 -0
- package/template/src/app/api/contacts/[id]/meet/route.ts +38 -29
- package/template/src/app/api/contacts/[id]/route.ts +111 -20
- package/template/src/app/api/contacts/[id]/send-email/route.ts +6 -0
- package/template/src/app/api/contacts/[id]/workflows/run/route.ts +61 -0
- package/template/src/app/api/contacts/export/route.ts +12 -17
- package/template/src/app/api/contacts/import/route.ts +22 -19
- package/template/src/app/api/contacts/import-preview/route.ts +139 -0
- package/template/src/app/api/contacts/route.ts +202 -49
- package/template/src/app/api/dashboard/stats/route.ts +9 -292
- package/template/src/app/api/integrations/google-sheet/sync/route.ts +203 -185
- package/template/src/app/api/invite/complete/route.ts +20 -23
- package/template/src/app/api/reminders/route.ts +1 -0
- package/template/src/app/api/reset-password/complete/route.ts +11 -13
- package/template/src/app/api/send/route.ts +9 -85
- package/template/src/app/api/settings/closing-reasons/[id]/route.ts +10 -21
- package/template/src/app/api/settings/closing-reasons/route.ts +10 -21
- package/template/src/app/api/settings/company/route.ts +19 -26
- package/template/src/app/api/settings/google-ads/[id]/route.ts +20 -23
- package/template/src/app/api/settings/google-ads/route.ts +20 -23
- package/template/src/app/api/settings/google-sheet/[id]/route.ts +20 -23
- package/template/src/app/api/settings/google-sheet/auto-map/route.ts +23 -32
- package/template/src/app/api/settings/google-sheet/preview/route.ts +104 -0
- package/template/src/app/api/settings/google-sheet/route.ts +20 -23
- package/template/src/app/api/settings/meta-leads/[id]/route.ts +20 -23
- package/template/src/app/api/settings/meta-leads/route.ts +20 -23
- package/template/src/app/api/settings/statuses/[id]/route.ts +33 -23
- package/template/src/app/api/settings/statuses/route.ts +24 -22
- package/template/src/app/api/statuses/route.ts +2 -5
- package/template/src/app/api/tasks/[id]/attendees/route.ts +14 -7
- package/template/src/app/api/tasks/[id]/route.ts +161 -137
- package/template/src/app/api/tasks/meet/route.ts +11 -8
- package/template/src/app/api/tasks/route.ts +155 -95
- package/template/src/app/api/templates/[id]/route.ts +22 -13
- package/template/src/app/api/templates/route.ts +22 -5
- package/template/src/app/api/users/[id]/resend-invite/route.ts +95 -0
- package/template/src/app/api/users/[id]/route.ts +16 -1
- package/template/src/app/api/users/commercials/route.ts +38 -0
- package/template/src/app/api/users/for-agenda/route.ts +1 -2
- package/template/src/app/api/users/route.ts +94 -55
- package/template/src/app/api/webhooks/google-ads/route.ts +20 -1
- package/template/src/app/api/webhooks/meta-leads/route.ts +18 -1
- package/template/src/app/api/workflows/[id]/route.ts +33 -6
- package/template/src/app/api/workflows/process/route.ts +509 -146
- package/template/src/app/api/workflows/route.ts +46 -4
- package/template/src/app/globals.css +210 -101
- package/template/src/app/layout.tsx +19 -8
- package/template/src/app/page.tsx +37 -7
- package/template/src/components/address-autocomplete.tsx +232 -0
- package/template/src/components/contacts/filter-bar.tsx +181 -0
- package/template/src/components/contacts/filter-builder.tsx +589 -0
- package/template/src/components/contacts/save-view-dialog.tsx +160 -0
- package/template/src/components/contacts/views-tab-bar.tsx +440 -0
- package/template/src/components/dashboard/activity-chart.tsx +31 -39
- package/template/src/components/dashboard/dashboard-content.tsx +79 -0
- package/template/src/components/dashboard/stat-card.tsx +40 -42
- package/template/src/components/dashboard/tasks-pie-chart.tsx +34 -37
- package/template/src/components/dashboard/upcoming-tasks-list.tsx +78 -72
- package/template/src/components/date-picker.tsx +396 -0
- package/template/src/components/editor.tsx +27 -13
- package/template/src/components/email-template.tsx +4 -2
- package/template/src/components/global-search.tsx +358 -0
- package/template/src/components/header.tsx +57 -62
- package/template/src/components/invitation-email-template.tsx +4 -2
- package/template/src/components/lazy-editor.tsx +11 -0
- package/template/src/components/meet-cancellation-email-template.tsx +11 -3
- package/template/src/components/meet-confirmation-email-template.tsx +10 -3
- package/template/src/components/meet-update-email-template.tsx +10 -3
- package/template/src/components/page-header.tsx +19 -15
- package/template/src/components/protected-page.tsx +94 -0
- package/template/src/components/reset-password-email-template.tsx +4 -2
- package/template/src/components/sidebar.tsx +92 -94
- package/template/src/components/skeleton.tsx +128 -42
- package/template/src/components/ui/accordion.tsx +64 -0
- package/template/src/components/ui/alert-dialog.tsx +139 -0
- package/template/src/components/ui/button.tsx +60 -0
- package/template/src/components/view-as-banner.tsx +1 -1
- package/template/src/components/view-as-modal.tsx +21 -16
- package/template/src/config/nav-pages.ts +108 -0
- package/template/src/contexts/app-toast-context.tsx +174 -0
- package/template/src/contexts/sidebar-context.tsx +16 -47
- package/template/src/contexts/task-reminder-context.tsx +6 -6
- package/template/src/contexts/view-as-context.tsx +11 -16
- package/template/src/hooks/use-alert.tsx +65 -0
- package/template/src/hooks/use-confirm.tsx +87 -0
- package/template/src/hooks/use-contact-views.ts +140 -0
- package/template/src/hooks/use-contacts.ts +69 -0
- package/template/src/hooks/use-fetch.ts +17 -0
- package/template/src/hooks/use-focus-trap.ts +73 -0
- package/template/src/hooks/use-statuses.ts +22 -0
- package/template/src/lib/address-api.ts +155 -0
- package/template/src/lib/cache.ts +73 -0
- package/template/src/lib/check-permission.ts +12 -177
- package/template/src/lib/contact-interactions.ts +3 -1
- package/template/src/lib/contact-view-filters.ts +341 -0
- package/template/src/lib/dashboard-stats.ts +224 -0
- package/template/src/lib/date-utils.ts +49 -0
- package/template/src/lib/get-auth-user.ts +25 -0
- package/template/src/lib/google-calendar.ts +54 -12
- package/template/src/lib/google-drive.ts +796 -75
- package/template/src/lib/google-fetch.ts +63 -0
- package/template/src/lib/local-storage.ts +34 -0
- package/template/src/lib/permissions.ts +245 -47
- package/template/src/lib/prisma.ts +11 -11
- package/template/src/lib/roles.ts +14 -39
- package/template/src/lib/template-variables.ts +67 -33
- package/template/src/lib/utils.ts +26 -2
- package/template/src/lib/workflow-executor.ts +445 -229
- package/template/src/proxy.ts +34 -73
- package/template/src/types/contact-views.ts +351 -0
- package/template/src/types/yousign.ts +52 -0
- package/template/vercel.json +12 -0
- package/template/WORKFLOWS_CRON.md +0 -185
- package/template/prisma/migrations/20251126144728_init/migration.sql +0 -78
- package/template/prisma/migrations/20251126155204_add_user_roles/migration.sql +0 -5
- package/template/prisma/migrations/20251128095126_add_company_info/migration.sql +0 -19
- package/template/prisma/migrations/20251128123321_add_smtp_config/migration.sql +0 -22
- package/template/prisma/migrations/20251128132303_add_status/migration.sql +0 -23
- package/template/prisma/migrations/20251201102207_add_user_active/migration.sql +0 -75
- package/template/prisma/migrations/20251201105507_add_email_signature/migration.sql +0 -2
- package/template/prisma/migrations/20251201151122_add_tasks/migration.sql +0 -45
- package/template/prisma/migrations/20251202111854_add_task_reminder/migration.sql +0 -2
- package/template/prisma/migrations/20251202135859_add_google_meet_integration/migration.sql +0 -27
- package/template/prisma/migrations/20251203103317_add_meta_lead_integration/migration.sql +0 -20
- package/template/prisma/migrations/20251203104002_add_google_ads_integration/migration.sql +0 -18
- package/template/prisma/migrations/20251203112122_add_google_sheet_integration/migration.sql +0 -32
- package/template/prisma/migrations/20251203153853_allow_multiple_integration_configs/migration.sql +0 -20
- package/template/prisma/migrations/20251205141705_update_user_roles/migration.sql +0 -12
- package/template/prisma/migrations/20251205150000_add_commercial_and_telepro_assignment/migration.sql +0 -21
- package/template/prisma/migrations/20251205160000_add_interaction_logging/migration.sql +0 -11
- package/template/prisma/migrations/20251208090314_add_automatic_interaction_types/migration.sql +0 -12
- package/template/prisma/migrations/20251208094843_mg/migration.sql +0 -14
- package/template/prisma/migrations/20251208100000_add_company_support/migration.sql +0 -14
- package/template/prisma/migrations/20251208110000_add_templates/migration.sql +0 -26
- package/template/prisma/migrations/20251208141304_add_video_conference_task_type/migration.sql +0 -2
- package/template/prisma/migrations/20251209104759_add_internal_note_to_task/migration.sql +0 -2
- package/template/prisma/migrations/20251209134803_add_company_field/migration.sql +0 -2
- package/template/prisma/migrations/20251209150000_rename_company_to_company_name/migration.sql +0 -3
- package/template/prisma/migrations/20251209150016_add_email_tracking/migration.sql +0 -21
- package/template/prisma/migrations/20251209155908_add_notify_contact_to_task/migration.sql +0 -2
- package/template/prisma/migrations/20251210110019_add_appointment_types/migration.sql +0 -10
- package/template/prisma/migrations/20251210113928_add_contact_files/migration.sql +0 -26
- package/template/prisma/migrations/20251212132339_add_custom_roles/migration.sql +0 -24
- package/template/prisma/migrations/20251215104448_add_file_interaction_types/migration.sql +0 -11
- package/template/prisma/migrations/20251215145616_add_closing_reasons/migration.sql +0 -12
- package/template/prisma/migrations/20251216140850_add_log_users/migration.sql +0 -25
- package/template/prisma/migrations/20251216151000_rename_perdu_to_ferme/migration.sql +0 -8
- package/template/prisma/migrations/20251216162318_add_column_mappings_to_google_sheet/migration.sql +0 -2
- package/template/prisma/migrations/20251216185127_add_workflows/migration.sql +0 -80
- package/template/prisma/migrations/20251216192237_add_scheduled_workflow_actions/migration.sql +0 -32
- package/template/prisma/migrations/20251220000000_add_task_interaction_type/migration.sql +0 -4
- package/template/prisma/migrations/20251221000000_add_task_type/migration.sql +0 -3
- package/template/prisma/migrations/20251221000001_add_event_color/migration.sql +0 -23
- package/template/prisma/migrations/20260210114913_add_dashboard_widget/migration.sql +0 -20
- package/template/prisma/migrations/migration_lock.toml +0 -3
- package/template/src/app/(dashboard)/users/layout.tsx +0 -30
- package/template/src/app/api/dashboard/widgets/[id]/route.ts +0 -47
- package/template/src/app/api/dashboard/widgets/route.ts +0 -181
- package/template/src/components/dashboard/add-widget-dialog.tsx +0 -161
- package/template/src/components/dashboard/color-picker.tsx +0 -65
- package/template/src/components/dashboard/contacts-chart.tsx +0 -69
- package/template/src/components/dashboard/interactions-by-type-chart.tsx +0 -121
- package/template/src/components/dashboard/recent-activity.tsx +0 -157
- package/template/src/components/dashboard/sales-analytics-chart.tsx +0 -77
- package/template/src/components/dashboard/status-distribution-chart.tsx +0 -82
- package/template/src/components/dashboard/top-contacts-list.tsx +0 -119
- package/template/src/components/dashboard/widget-wrapper.tsx +0 -39
- package/template/src/contexts/dashboard-theme-context.tsx +0 -58
- package/template/src/lib/dashboard-themes.ts +0 -140
- package/template/src/lib/default-widgets.ts +0 -14
- package/template/src/lib/widget-registry.ts +0 -177
|
@@ -45,7 +45,6 @@ model User {
|
|
|
45
45
|
role Role @default(USER)
|
|
46
46
|
customRoleId String? // Profil personnalisé optionnel
|
|
47
47
|
customRole CustomRole? @relation(fields: [customRoleId], references: [id], onDelete: SetNull)
|
|
48
|
-
eventColor String? // Couleur pour les événements de l'utilisateur
|
|
49
48
|
createdAt DateTime @default(now())
|
|
50
49
|
updatedAt DateTime @updatedAt
|
|
51
50
|
sessions Session[]
|
|
@@ -67,7 +66,24 @@ model User {
|
|
|
67
66
|
auditLogsAsActor AuditLog[] @relation("AuditActor")
|
|
68
67
|
auditLogsAsTargetUser AuditLog[] @relation("AuditTargetUser")
|
|
69
68
|
workflows Workflow[] @relation("WorkflowOwner")
|
|
70
|
-
|
|
69
|
+
toursManaged Tour[] @relation("TourCommercial")
|
|
70
|
+
transactionsCreated Transaction[] @relation("TransactionCreatedBy")
|
|
71
|
+
transactionsAssigned Transaction[] @relation("TransactionAssignedTo")
|
|
72
|
+
transactionAuditLogs TransactionAuditLog[]
|
|
73
|
+
unavailableDatesCreated UnavailableDate[]
|
|
74
|
+
distributionCampaignPayments DistributionCampaignPayment[]
|
|
75
|
+
metaAdsPayments MetaAdsPayment[]
|
|
76
|
+
contactViews ContactView[]
|
|
77
|
+
contactViewPins ContactViewPin[]
|
|
78
|
+
companiesAssignedCommercial Company[] @relation("CompanyAssignedCommercial")
|
|
79
|
+
companiesAssignedTelepro Company[] @relation("CompanyAssignedTelepro")
|
|
80
|
+
companiesCreatedBy Company[] @relation("CompanyCreatedBy")
|
|
81
|
+
companyActivities CompanyActivity[]
|
|
82
|
+
workflowActionsTaskAssigned WorkflowAction[] @relation("WorkflowActionTaskAssignedUser")
|
|
83
|
+
workflowActionsAssignCommercial WorkflowAction[] @relation("WorkflowActionAssignCommercial")
|
|
84
|
+
workflowActionsAssignTelepro WorkflowAction[] @relation("WorkflowActionAssignTelepro")
|
|
85
|
+
workflowActionsNotifyUser WorkflowAction[] @relation("WorkflowActionNotifyUser")
|
|
86
|
+
refinerSubmissions RefinerSubmission[] @relation("RefinerSubmissionCreatedBy")
|
|
71
87
|
|
|
72
88
|
@@unique([email])
|
|
73
89
|
@@index([customRoleId])
|
|
@@ -136,26 +152,80 @@ model Verification {
|
|
|
136
152
|
updatedAt DateTime @updatedAt
|
|
137
153
|
|
|
138
154
|
@@index([identifier])
|
|
155
|
+
@@index([value])
|
|
139
156
|
@@map("verification")
|
|
140
157
|
}
|
|
141
158
|
|
|
159
|
+
model Organization {
|
|
160
|
+
id String @id @default("company")
|
|
161
|
+
name String?
|
|
162
|
+
legalRepresentative String? // Nom du représentant légal ou statutaire
|
|
163
|
+
address String?
|
|
164
|
+
city String?
|
|
165
|
+
postalCode String?
|
|
166
|
+
country String?
|
|
167
|
+
phone String?
|
|
168
|
+
email String?
|
|
169
|
+
website String?
|
|
170
|
+
siret String?
|
|
171
|
+
vatNumber String?
|
|
172
|
+
logo String?
|
|
173
|
+
cerfaTemplateFileId String? // Google Drive File ID du template PDF Cerfa
|
|
174
|
+
contractTemplateFileId String? // Google Drive File ID du template PDF de contrat de rachat
|
|
175
|
+
yousignSignaturePosition Json? // Position de la signature Yousign {page, x, y, width, height}
|
|
176
|
+
yousignRetractionPosition Json? // Position de la signature Yousign pour le formulaire de rétractation (page 4)
|
|
177
|
+
createdAt DateTime @default(now())
|
|
178
|
+
updatedAt DateTime @updatedAt
|
|
179
|
+
|
|
180
|
+
@@map("company")
|
|
181
|
+
}
|
|
182
|
+
|
|
142
183
|
model Company {
|
|
143
|
-
id
|
|
144
|
-
name
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
184
|
+
id String @id @default(cuid())
|
|
185
|
+
name String
|
|
186
|
+
phone String?
|
|
187
|
+
email String?
|
|
188
|
+
address String?
|
|
189
|
+
city String?
|
|
190
|
+
postalCode String?
|
|
191
|
+
website String?
|
|
192
|
+
siret String?
|
|
193
|
+
industry String?
|
|
194
|
+
notes String? @db.Text
|
|
195
|
+
assignedCommercialId String?
|
|
196
|
+
assignedCommercial User? @relation("CompanyAssignedCommercial", fields: [assignedCommercialId], references: [id], onDelete: SetNull)
|
|
197
|
+
assignedTeleproId String?
|
|
198
|
+
assignedTelepro User? @relation("CompanyAssignedTelepro", fields: [assignedTeleproId], references: [id], onDelete: SetNull)
|
|
199
|
+
createdById String?
|
|
200
|
+
createdBy User? @relation("CompanyCreatedBy", fields: [createdById], references: [id], onDelete: SetNull)
|
|
201
|
+
createdAt DateTime @default(now())
|
|
202
|
+
updatedAt DateTime @updatedAt
|
|
203
|
+
contacts Contact[]
|
|
204
|
+
activities CompanyActivity[]
|
|
205
|
+
|
|
206
|
+
@@index([assignedCommercialId])
|
|
207
|
+
@@index([assignedTeleproId])
|
|
208
|
+
@@index([createdById])
|
|
209
|
+
@@index([name])
|
|
210
|
+
@@map("companies")
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
model CompanyActivity {
|
|
214
|
+
id String @id @default(cuid())
|
|
215
|
+
companyId String
|
|
216
|
+
company Company @relation(fields: [companyId], references: [id], onDelete: Cascade)
|
|
217
|
+
type String // COMPANY_UPDATE, CONTACT_ADDED, NOTE
|
|
218
|
+
title String?
|
|
219
|
+
content String @db.Text
|
|
220
|
+
metadata Json? // Détails des changements (champs modifiés, etc.)
|
|
221
|
+
userId String?
|
|
222
|
+
user User? @relation(fields: [userId], references: [id], onDelete: SetNull)
|
|
155
223
|
createdAt DateTime @default(now())
|
|
156
|
-
updatedAt DateTime @updatedAt
|
|
157
224
|
|
|
158
|
-
@@
|
|
225
|
+
@@index([companyId])
|
|
226
|
+
@@index([companyId, createdAt])
|
|
227
|
+
@@index([userId])
|
|
228
|
+
@@map("company_activity")
|
|
159
229
|
}
|
|
160
230
|
|
|
161
231
|
model SmtpConfig {
|
|
@@ -181,6 +251,8 @@ model Status {
|
|
|
181
251
|
name String
|
|
182
252
|
color String // Couleur au format hexadécimal (ex: #3B82F6)
|
|
183
253
|
order Int @default(0) // Ordre d'affichage
|
|
254
|
+
isSystem Boolean @default(false)
|
|
255
|
+
requiresClosingReason Boolean @default(false)
|
|
184
256
|
createdAt DateTime @default(now())
|
|
185
257
|
updatedAt DateTime @updatedAt
|
|
186
258
|
contacts Contact[]
|
|
@@ -222,11 +294,12 @@ enum InteractionType {
|
|
|
222
294
|
|
|
223
295
|
enum TaskType {
|
|
224
296
|
CALL
|
|
225
|
-
MEETING
|
|
297
|
+
MEETING // Rendez-vous physique
|
|
226
298
|
EMAIL
|
|
227
299
|
VIDEO_CONFERENCE
|
|
228
300
|
OTHER
|
|
229
301
|
TASK
|
|
302
|
+
PHYSICAL_APPOINTMENT // Rendez-vous physique avec localisation
|
|
230
303
|
}
|
|
231
304
|
|
|
232
305
|
enum TaskPriority {
|
|
@@ -236,6 +309,133 @@ enum TaskPriority {
|
|
|
236
309
|
URGENT
|
|
237
310
|
}
|
|
238
311
|
|
|
312
|
+
enum PlaceType {
|
|
313
|
+
HOTEL
|
|
314
|
+
RESTAURANT
|
|
315
|
+
AUTRE
|
|
316
|
+
}
|
|
317
|
+
|
|
318
|
+
enum PaymentStatus {
|
|
319
|
+
PAYE
|
|
320
|
+
EN_ATTENTE
|
|
321
|
+
ACOMPTE_VERSE
|
|
322
|
+
}
|
|
323
|
+
|
|
324
|
+
enum CampaignPaymentStatus {
|
|
325
|
+
A_PAYER
|
|
326
|
+
PARTIEL
|
|
327
|
+
PAYE
|
|
328
|
+
}
|
|
329
|
+
|
|
330
|
+
enum CityHallStatus {
|
|
331
|
+
OUI
|
|
332
|
+
NON
|
|
333
|
+
EN_COURS
|
|
334
|
+
EN_ATTENTE
|
|
335
|
+
}
|
|
336
|
+
|
|
337
|
+
enum DistributionType {
|
|
338
|
+
FLYERS
|
|
339
|
+
COURRIERS
|
|
340
|
+
MIX
|
|
341
|
+
}
|
|
342
|
+
|
|
343
|
+
enum IdType {
|
|
344
|
+
CNI
|
|
345
|
+
PASSPORT
|
|
346
|
+
LICENSE
|
|
347
|
+
RESIDENCE_PERMIT
|
|
348
|
+
OTHER
|
|
349
|
+
}
|
|
350
|
+
|
|
351
|
+
enum TransactionStatus {
|
|
352
|
+
DRAFT
|
|
353
|
+
PENDING_ID_VERIFICATION
|
|
354
|
+
ID_VERIFIED
|
|
355
|
+
ITEMS_ENTERED
|
|
356
|
+
PENDING_SIGNATURE // En attente de signature électronique Yousign
|
|
357
|
+
SIGNED
|
|
358
|
+
LOCKED
|
|
359
|
+
PAYMENT_PENDING
|
|
360
|
+
COMPLETED
|
|
361
|
+
PENDING_RETRACTION // En attente de signature du formulaire de rétractation
|
|
362
|
+
CANCELLED_RETRACTION
|
|
363
|
+
CANCELLED
|
|
364
|
+
}
|
|
365
|
+
|
|
366
|
+
enum SignatureType {
|
|
367
|
+
TABLET
|
|
368
|
+
ELECTRONIC
|
|
369
|
+
PAPER
|
|
370
|
+
}
|
|
371
|
+
|
|
372
|
+
enum PaymentMethod {
|
|
373
|
+
CHECK
|
|
374
|
+
BANK_TRANSFER
|
|
375
|
+
}
|
|
376
|
+
|
|
377
|
+
enum TransactionItemCategory {
|
|
378
|
+
GOLD
|
|
379
|
+
PLATINUM
|
|
380
|
+
SILVER
|
|
381
|
+
WATCHES
|
|
382
|
+
COLLECTIBLES
|
|
383
|
+
DIAMONDS
|
|
384
|
+
SILVERED_METAL
|
|
385
|
+
GOLD_PLATED
|
|
386
|
+
TIN
|
|
387
|
+
}
|
|
388
|
+
|
|
389
|
+
enum TransactionItemProcessingStatus {
|
|
390
|
+
A_VERIFIER
|
|
391
|
+
TRAITE
|
|
392
|
+
}
|
|
393
|
+
|
|
394
|
+
enum StockDisposition {
|
|
395
|
+
IN_STOCK
|
|
396
|
+
EXCLUDED
|
|
397
|
+
SENT_TO_REFINER
|
|
398
|
+
SOLD
|
|
399
|
+
}
|
|
400
|
+
|
|
401
|
+
enum RefinerSubmissionStatus {
|
|
402
|
+
PENDING
|
|
403
|
+
PROVISIONAL_PAID
|
|
404
|
+
COMPLETED
|
|
405
|
+
}
|
|
406
|
+
|
|
407
|
+
enum GoldPurity {
|
|
408
|
+
P375
|
|
409
|
+
P585
|
|
410
|
+
P750
|
|
411
|
+
P900
|
|
412
|
+
P916
|
|
413
|
+
P999
|
|
414
|
+
}
|
|
415
|
+
|
|
416
|
+
enum PlatinumPurity {
|
|
417
|
+
P900
|
|
418
|
+
P950
|
|
419
|
+
}
|
|
420
|
+
|
|
421
|
+
enum SilverPurity {
|
|
422
|
+
P680
|
|
423
|
+
P800
|
|
424
|
+
P835
|
|
425
|
+
P900
|
|
426
|
+
P925
|
|
427
|
+
P999
|
|
428
|
+
}
|
|
429
|
+
|
|
430
|
+
enum GoldType {
|
|
431
|
+
JEWELRY
|
|
432
|
+
DEBRIS
|
|
433
|
+
COINS
|
|
434
|
+
INGOTS
|
|
435
|
+
TEETH
|
|
436
|
+
GOLD_WATCHES
|
|
437
|
+
}
|
|
438
|
+
|
|
239
439
|
model Contact {
|
|
240
440
|
id String @id @default(cuid())
|
|
241
441
|
civility Civility?
|
|
@@ -248,11 +448,9 @@ model Contact {
|
|
|
248
448
|
city String?
|
|
249
449
|
postalCode String?
|
|
250
450
|
origin String? // Origine du contact
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
companyRelation Contact? @relation("ContactCompany", fields: [companyId], references: [id], onDelete: SetNull)
|
|
255
|
-
contacts Contact[] @relation("ContactCompany") // Contacts liés à cette entreprise (via companyId)
|
|
451
|
+
companyId String?
|
|
452
|
+
company Company? @relation(fields: [companyId], references: [id], onDelete: SetNull)
|
|
453
|
+
jobTitle String? // Intitulé du poste (pour hiérarchie dans l'entreprise)
|
|
256
454
|
statusId String?
|
|
257
455
|
status Status? @relation(fields: [statusId], references: [id], onDelete: SetNull)
|
|
258
456
|
closingReason String? // Motif de fermeture (si statut Fermé)
|
|
@@ -260,21 +458,34 @@ model Contact {
|
|
|
260
458
|
assignedCommercial User? @relation("ContactAssignedCommercial", fields: [assignedCommercialId], references: [id], onDelete: SetNull)
|
|
261
459
|
assignedTeleproId String? // Télépro assigné
|
|
262
460
|
assignedTelepro User? @relation("ContactAssignedTelepro", fields: [assignedTeleproId], references: [id], onDelete: SetNull)
|
|
263
|
-
createdById String // Utilisateur qui a créé le contact
|
|
264
|
-
createdBy User
|
|
461
|
+
createdById String? // Utilisateur qui a créé le contact
|
|
462
|
+
createdBy User? @relation("ContactCreatedBy", fields: [createdById], references: [id], onDelete: SetNull)
|
|
265
463
|
createdAt DateTime @default(now())
|
|
266
464
|
updatedAt DateTime @updatedAt
|
|
267
465
|
interactions Interaction[]
|
|
268
466
|
tasks Task[]
|
|
269
467
|
files ContactFile[]
|
|
270
468
|
scheduledWorkflowActions ScheduledWorkflowAction[]
|
|
469
|
+
tourLinks TourContact[]
|
|
470
|
+
// KYC fields
|
|
471
|
+
placeOfBirth String? // Lieu de naissance
|
|
472
|
+
dateOfBirth DateTime? // Date de naissance
|
|
473
|
+
idType IdType? // Type de pièce d'identité
|
|
474
|
+
idNumber String? // Numéro de pièce d'identité
|
|
475
|
+
idExpiryDate DateTime? // Date d'expiration de la pièce d'identité
|
|
476
|
+
idDocumentUrl String? // URL/lien vers le document d'identité dans Google Drive
|
|
477
|
+
idVerifiedByAdmin Boolean @default(false) // Vérifié par un admin
|
|
478
|
+
transactions Transaction[]
|
|
271
479
|
|
|
272
480
|
@@index([statusId])
|
|
273
481
|
@@index([assignedCommercialId])
|
|
274
482
|
@@index([assignedTeleproId])
|
|
275
483
|
@@index([createdById])
|
|
276
484
|
@@index([companyId])
|
|
277
|
-
@@index([
|
|
485
|
+
@@index([phone])
|
|
486
|
+
@@index([createdAt])
|
|
487
|
+
@@index([updatedAt])
|
|
488
|
+
@@index([statusId, updatedAt])
|
|
278
489
|
@@map("contact")
|
|
279
490
|
}
|
|
280
491
|
|
|
@@ -286,8 +497,8 @@ model Interaction {
|
|
|
286
497
|
title String?
|
|
287
498
|
content String // Contenu de l'interaction
|
|
288
499
|
metadata Json? // Métadonnées pour stocker les détails des changements (ancienne valeur, nouvelle valeur, etc.)
|
|
289
|
-
userId String // Utilisateur qui a créé l'interaction
|
|
290
|
-
user User
|
|
500
|
+
userId String? // Utilisateur qui a créé l'interaction
|
|
501
|
+
user User? @relation(fields: [userId], references: [id], onDelete: SetNull)
|
|
291
502
|
date DateTime? // Date de l'interaction (pour RDV, appels, etc.)
|
|
292
503
|
createdAt DateTime @default(now())
|
|
293
504
|
updatedAt DateTime @updatedAt
|
|
@@ -295,6 +506,7 @@ model Interaction {
|
|
|
295
506
|
|
|
296
507
|
@@index([contactId])
|
|
297
508
|
@@index([userId])
|
|
509
|
+
@@index([contactId, createdAt])
|
|
298
510
|
@@map("interaction")
|
|
299
511
|
}
|
|
300
512
|
|
|
@@ -316,16 +528,18 @@ model Task {
|
|
|
316
528
|
id String @id @default(cuid())
|
|
317
529
|
contactId String? // Optionnel : peut être créée depuis un contact
|
|
318
530
|
contact Contact? @relation(fields: [contactId], references: [id], onDelete: SetNull)
|
|
531
|
+
tourId String? // Optionnel : lien avec une tournée
|
|
532
|
+
tour Tour? @relation(fields: [tourId], references: [id], onDelete: SetNull)
|
|
319
533
|
type TaskType
|
|
320
534
|
title String?
|
|
321
535
|
description String // Description HTML (avec Editor)
|
|
322
536
|
priority TaskPriority @default(MEDIUM)
|
|
323
537
|
scheduledAt DateTime // Date et heure de la tâche
|
|
324
538
|
reminderMinutesBefore Int? // Rappel en minutes avant l'heure prévue (ex: 15, 30, 60)
|
|
325
|
-
assignedUserId String // Utilisateur assigné
|
|
326
|
-
assignedUser User
|
|
327
|
-
createdById String // Utilisateur qui a créé la tâche
|
|
328
|
-
createdBy User
|
|
539
|
+
assignedUserId String? // Utilisateur assigné
|
|
540
|
+
assignedUser User? @relation("TaskAssignedTo", fields: [assignedUserId], references: [id], onDelete: SetNull)
|
|
541
|
+
createdById String? // Utilisateur qui a créé la tâche
|
|
542
|
+
createdBy User? @relation("TaskCreatedBy", fields: [createdById], references: [id], onDelete: SetNull)
|
|
329
543
|
completed Boolean @default(false) // Tâche terminée ou non
|
|
330
544
|
completedAt DateTime? // Date de complétion
|
|
331
545
|
googleEventId String? // ID de l'évènement Google Calendar
|
|
@@ -333,14 +547,23 @@ model Task {
|
|
|
333
547
|
durationMinutes Int? // Durée de la réunion en minutes (pour Google Meet)
|
|
334
548
|
internalNote String? // Note personnelle (non partagée dans les emails)
|
|
335
549
|
notifyContact Boolean? // Si le contact a été prévenu lors de la création
|
|
550
|
+
// Champs pour les rendez-vous physiques
|
|
551
|
+
location String? // Adresse complète du lieu
|
|
552
|
+
locationAddress String? // Rue
|
|
553
|
+
locationCity String? // Ville
|
|
554
|
+
locationPostalCode String? // Code postal
|
|
555
|
+
isAtHome Boolean @default(false) // Rendez-vous au domicile du contact
|
|
336
556
|
createdAt DateTime @default(now())
|
|
337
557
|
updatedAt DateTime @updatedAt
|
|
338
558
|
|
|
339
559
|
@@index([contactId])
|
|
560
|
+
@@index([tourId])
|
|
340
561
|
@@index([assignedUserId])
|
|
341
562
|
@@index([createdById])
|
|
342
563
|
@@index([scheduledAt])
|
|
343
564
|
@@index([googleEventId])
|
|
565
|
+
@@index([assignedUserId, completed, scheduledAt])
|
|
566
|
+
@@index([assignedUserId, createdAt])
|
|
344
567
|
@@map("task")
|
|
345
568
|
}
|
|
346
569
|
|
|
@@ -359,20 +582,22 @@ model UserGoogleAccount {
|
|
|
359
582
|
}
|
|
360
583
|
|
|
361
584
|
model ContactFile {
|
|
362
|
-
id
|
|
363
|
-
contactId
|
|
364
|
-
contact
|
|
365
|
-
fileName
|
|
366
|
-
fileSize
|
|
367
|
-
mimeType
|
|
368
|
-
googleDriveFileId
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
585
|
+
id String @id @default(cuid())
|
|
586
|
+
contactId String
|
|
587
|
+
contact Contact @relation(fields: [contactId], references: [id], onDelete: Cascade)
|
|
588
|
+
fileName String // Nom original du fichier
|
|
589
|
+
fileSize Int // Taille en octets
|
|
590
|
+
mimeType String // Type MIME du fichier
|
|
591
|
+
googleDriveFileId String // ID du fichier dans Google Drive
|
|
592
|
+
isIdentityDocument Boolean @default(false) // Indique si c'est une pièce d'identité
|
|
593
|
+
uploadedById String? // Utilisateur qui a uploadé le fichier
|
|
594
|
+
uploadedBy User? @relation("ContactFileUploadedBy", fields: [uploadedById], references: [id], onDelete: SetNull)
|
|
595
|
+
createdAt DateTime @default(now())
|
|
596
|
+
updatedAt DateTime @updatedAt
|
|
373
597
|
|
|
374
598
|
@@index([contactId])
|
|
375
599
|
@@index([uploadedById])
|
|
600
|
+
@@index([contactId, isIdentityDocument])
|
|
376
601
|
@@map("contact_file")
|
|
377
602
|
}
|
|
378
603
|
|
|
@@ -411,8 +636,8 @@ model GoogleAdsLeadConfig {
|
|
|
411
636
|
model GoogleSheetSyncConfig {
|
|
412
637
|
id String @id @default(cuid())
|
|
413
638
|
name String // Nom de la configuration (ex: "Contacts Ventes")
|
|
414
|
-
ownerUserId String
|
|
415
|
-
ownerUser User
|
|
639
|
+
ownerUserId String?
|
|
640
|
+
ownerUser User? @relation("GoogleSheetOwner", fields: [ownerUserId], references: [id], onDelete: SetNull)
|
|
416
641
|
spreadsheetId String
|
|
417
642
|
sheetName String
|
|
418
643
|
headerRow Int
|
|
@@ -457,9 +682,10 @@ model Template {
|
|
|
457
682
|
type TemplateType // Type de template (EMAIL, SMS, NOTE)
|
|
458
683
|
subject String? // Sujet (pour EMAIL uniquement)
|
|
459
684
|
content String // Contenu du template (HTML pour EMAIL, texte pour SMS et NOTE)
|
|
460
|
-
userId String // Utilisateur qui a créé le template
|
|
461
|
-
user User
|
|
685
|
+
userId String? // Utilisateur qui a créé le template
|
|
686
|
+
user User? @relation("TemplateCreatedBy", fields: [userId], references: [id], onDelete: SetNull)
|
|
462
687
|
workflowActions WorkflowAction[] @relation("WorkflowActionEmailTemplate")
|
|
688
|
+
placeReminderConfigs PlaceReminderConfig[]
|
|
463
689
|
createdAt DateTime @default(now())
|
|
464
690
|
updatedAt DateTime @updatedAt
|
|
465
691
|
|
|
@@ -468,19 +694,43 @@ model Template {
|
|
|
468
694
|
@@map("template")
|
|
469
695
|
}
|
|
470
696
|
|
|
697
|
+
model PlaceReminderConfig {
|
|
698
|
+
id String @id @default("place-reminder-config")
|
|
699
|
+
enabled Boolean @default(true)
|
|
700
|
+
delayDays Int @default(7)
|
|
701
|
+
templateId String?
|
|
702
|
+
template Template? @relation(fields: [templateId], references: [id], onDelete: SetNull)
|
|
703
|
+
updatedAt DateTime @updatedAt
|
|
704
|
+
|
|
705
|
+
@@map("place_reminder_config")
|
|
706
|
+
}
|
|
707
|
+
|
|
471
708
|
enum WorkflowTriggerType {
|
|
472
|
-
CONTACT_CREATED
|
|
473
|
-
STATUS_CHANGED
|
|
474
|
-
TIME_BASED
|
|
475
|
-
MANUAL
|
|
709
|
+
CONTACT_CREATED // Nouveau contact créé
|
|
710
|
+
STATUS_CHANGED // Changement de statut
|
|
711
|
+
TIME_BASED // Basé sur le temps
|
|
712
|
+
MANUAL // Déclencheur manuel
|
|
713
|
+
TASK_COMPLETED // Tâche complétée
|
|
714
|
+
TRANSACTION_CREATED // Transaction créée
|
|
715
|
+
TRANSACTION_STATUS_CHANGED // Changement de statut de transaction
|
|
716
|
+
CONTACT_ASSIGNMENT_CHANGED // Changement d'assignation du contact
|
|
717
|
+
}
|
|
718
|
+
|
|
719
|
+
enum WorkflowTimeReference {
|
|
720
|
+
CONTACT_CREATED_DATE // Date de création du contact
|
|
721
|
+
LAST_STATUS_CHANGE // Dernier changement de statut
|
|
722
|
+
LAST_INTERACTION // Dernière interaction
|
|
476
723
|
}
|
|
477
724
|
|
|
478
725
|
enum WorkflowActionType {
|
|
479
726
|
SEND_EMAIL // Envoyer un email
|
|
480
727
|
SEND_SMS // Envoyer un SMS
|
|
481
|
-
CHANGE_STATUS
|
|
482
|
-
CREATE_TASK
|
|
483
|
-
WAIT
|
|
728
|
+
CHANGE_STATUS // Changer le statut
|
|
729
|
+
CREATE_TASK // Créer une tâche
|
|
730
|
+
WAIT // Attendre
|
|
731
|
+
ASSIGN_CONTACT // Assigner le contact à un commercial/télépro
|
|
732
|
+
ADD_NOTE // Ajouter une note au contact
|
|
733
|
+
NOTIFY_USER // Notifier un utilisateur (créer une tâche pour lui)
|
|
484
734
|
}
|
|
485
735
|
|
|
486
736
|
enum WorkflowConditionOperator {
|
|
@@ -493,8 +743,8 @@ model Workflow {
|
|
|
493
743
|
name String
|
|
494
744
|
description String?
|
|
495
745
|
active Boolean @default(true)
|
|
496
|
-
userId String
|
|
497
|
-
user User
|
|
746
|
+
userId String? // Utilisateur propriétaire du workflow
|
|
747
|
+
user User? @relation("WorkflowOwner", fields: [userId], references: [id], onDelete: SetNull)
|
|
498
748
|
|
|
499
749
|
// Configuration du déclencheur
|
|
500
750
|
triggerType WorkflowTriggerType
|
|
@@ -506,8 +756,16 @@ model Workflow {
|
|
|
506
756
|
triggerToStatus Status? @relation("WorkflowTriggerToStatus", fields: [triggerToStatusId], references: [id], onDelete: SetNull)
|
|
507
757
|
|
|
508
758
|
// Pour TIME_BASED
|
|
509
|
-
triggerTimeDays
|
|
510
|
-
triggerTimeHours
|
|
759
|
+
triggerTimeDays Int? // Nombre de jours après un événement
|
|
760
|
+
triggerTimeHours Int? // Nombre d'heures après un événement
|
|
761
|
+
triggerTimeReference WorkflowTimeReference? // Événement de référence pour TIME_BASED
|
|
762
|
+
|
|
763
|
+
// Pour TASK_COMPLETED
|
|
764
|
+
triggerTaskType TaskType? // Type de tâche (optionnel, null = toutes)
|
|
765
|
+
|
|
766
|
+
// Pour TRANSACTION_STATUS_CHANGED
|
|
767
|
+
triggerTransactionFromStatus String? // Statut source de la transaction (ex: DRAFT, SIGNED)
|
|
768
|
+
triggerTransactionToStatus String? // Statut cible de la transaction
|
|
511
769
|
|
|
512
770
|
actions WorkflowAction[]
|
|
513
771
|
scheduledActions ScheduledWorkflowAction[]
|
|
@@ -515,7 +773,7 @@ model Workflow {
|
|
|
515
773
|
updatedAt DateTime @updatedAt
|
|
516
774
|
|
|
517
775
|
@@index([userId])
|
|
518
|
-
@@index([active])
|
|
776
|
+
@@index([active, triggerType])
|
|
519
777
|
@@map("workflow")
|
|
520
778
|
}
|
|
521
779
|
|
|
@@ -547,13 +805,32 @@ model WorkflowAction {
|
|
|
547
805
|
newStatus Status? @relation("WorkflowActionNewStatus", fields: [newStatusId], references: [id], onDelete: SetNull)
|
|
548
806
|
|
|
549
807
|
// Pour CREATE_TASK
|
|
550
|
-
taskTitle
|
|
551
|
-
taskDescription
|
|
808
|
+
taskTitle String? // Titre de la tâche
|
|
809
|
+
taskDescription String? // Description de la tâche
|
|
810
|
+
taskType TaskType? // Type de tâche (CALL, MEETING, etc.) — défaut OTHER
|
|
811
|
+
taskPriority TaskPriority? // Priorité (LOW, MEDIUM, HIGH, URGENT) — défaut MEDIUM
|
|
812
|
+
taskAssignedUserId String? // Utilisateur assigné à la tâche
|
|
813
|
+
taskAssignedUser User? @relation("WorkflowActionTaskAssignedUser", fields: [taskAssignedUserId], references: [id], onDelete: SetNull)
|
|
814
|
+
|
|
815
|
+
// Pour ASSIGN_CONTACT
|
|
816
|
+
assignCommercialId String? // Commercial à assigner
|
|
817
|
+
assignCommercial User? @relation("WorkflowActionAssignCommercial", fields: [assignCommercialId], references: [id], onDelete: SetNull)
|
|
818
|
+
assignTeleproId String? // Télépro à assigner
|
|
819
|
+
assignTelepro User? @relation("WorkflowActionAssignTelepro", fields: [assignTeleproId], references: [id], onDelete: SetNull)
|
|
820
|
+
|
|
821
|
+
// Pour ADD_NOTE
|
|
822
|
+
noteContent String? @db.Text // Contenu de la note (supporte les variables de template)
|
|
823
|
+
|
|
824
|
+
// Pour NOTIFY_USER
|
|
825
|
+
notifyUserId String? // Utilisateur à notifier
|
|
826
|
+
notifyUser User? @relation("WorkflowActionNotifyUser", fields: [notifyUserId], references: [id], onDelete: SetNull)
|
|
552
827
|
|
|
553
828
|
// Condition (optionnelle)
|
|
554
|
-
conditionOperator
|
|
555
|
-
conditionStatusId
|
|
556
|
-
conditionStatus
|
|
829
|
+
conditionOperator WorkflowConditionOperator? // Opérateur de condition
|
|
830
|
+
conditionStatusId String? // Statut pour la condition
|
|
831
|
+
conditionStatus Status? @relation("WorkflowActionConditionStatus", fields: [conditionStatusId], references: [id], onDelete: SetNull)
|
|
832
|
+
conditionOrigin String? // Origine du contact pour la condition
|
|
833
|
+
conditionHasCompany Boolean? // true = contact doit avoir une société, false = ne doit pas
|
|
557
834
|
|
|
558
835
|
createdAt DateTime @default(now())
|
|
559
836
|
updatedAt DateTime @updatedAt
|
|
@@ -585,18 +862,490 @@ model ScheduledWorkflowAction {
|
|
|
585
862
|
@@map("scheduled_workflow_action")
|
|
586
863
|
}
|
|
587
864
|
|
|
588
|
-
|
|
865
|
+
/// Tournée commerciale (inclut infos tournée, lieu, mairie, campagnes de distribution)
|
|
866
|
+
model Tour {
|
|
867
|
+
id String @id @default(cuid())
|
|
868
|
+
number String // Numéro de tournée (#T_${année}${mois}${cp})
|
|
869
|
+
region String?
|
|
870
|
+
department String?
|
|
871
|
+
city String?
|
|
872
|
+
postalCode String?
|
|
873
|
+
isoWeek Int? // Semaine ISO
|
|
874
|
+
|
|
875
|
+
presenceStart DateTime? // Début de présence (créneau)
|
|
876
|
+
presenceEnd DateTime? // Fin de présence (créneau)
|
|
877
|
+
|
|
878
|
+
// Lieu
|
|
879
|
+
placeType PlaceType? // Hôtel / Restaurant / Autre
|
|
880
|
+
placeName String?
|
|
881
|
+
placeAddress String?
|
|
882
|
+
placePhone String?
|
|
883
|
+
placeEmail String?
|
|
884
|
+
placeContactName String?
|
|
885
|
+
placeContactRole String?
|
|
886
|
+
placeContacts Json? // Contacts sur place multiples [{name, role, email, phone}]
|
|
887
|
+
placeRentalPriceCents Int? // Prix location en centimes (TTC)
|
|
888
|
+
placePaymentDepositCents Int? // Acompte versé en centimes
|
|
889
|
+
placePaymentDate DateTime?
|
|
890
|
+
placePaymentStatus PaymentStatus? // Payé / En attente / Acompte versé
|
|
891
|
+
placeInvoiceRef String?
|
|
892
|
+
placeInvoiceFileId String? // ID fichier (PDF) éventuel
|
|
893
|
+
|
|
894
|
+
// Lieu – emails
|
|
895
|
+
placeEmailSentDate DateTime?
|
|
896
|
+
placeReminderSentDate DateTime?
|
|
897
|
+
placeEmailSentById String?
|
|
898
|
+
|
|
899
|
+
// Mairie
|
|
900
|
+
cityHallName String?
|
|
901
|
+
cityHallAddress String?
|
|
902
|
+
cityHallCity String?
|
|
903
|
+
cityHallPostalCode String?
|
|
904
|
+
cityHallPhone String?
|
|
905
|
+
cityHallEmail String?
|
|
906
|
+
cityHallContactName String?
|
|
907
|
+
cityHallContacts Json? // Contacts mairie multiples [{name, role, email, phone}]
|
|
908
|
+
cityHallStatus CityHallStatus? // Oui / Non / En cours
|
|
909
|
+
cityHallRequestDate DateTime?
|
|
910
|
+
cityHallReminderDate DateTime?
|
|
911
|
+
cityHallDecisionDate DateTime?
|
|
912
|
+
cityHallDecision String? // Validation / Refus
|
|
913
|
+
cityHallRequestFileId String?
|
|
914
|
+
cityHallResponseFileId String?
|
|
915
|
+
cityHallAuthorizationFileId String?
|
|
916
|
+
|
|
917
|
+
// Campagnes de distribution
|
|
918
|
+
distributionType DistributionType? // Flyers / Courriers / Mix
|
|
919
|
+
distributionFlyersQty Int? // nombre de flyers
|
|
920
|
+
distributionLettersQty Int? // nombre de courriers
|
|
921
|
+
distributionProvider String? // Prestataire (ex: Mediapost)
|
|
922
|
+
distributionCampaignRef String?
|
|
923
|
+
distributionWeek String? // Semaine de distribution (texte)
|
|
924
|
+
distributionEndDate DateTime?
|
|
925
|
+
distributionZones String? // Zones couvertes (CP, quartiers...)
|
|
926
|
+
distributionDailyCostCents Int?
|
|
927
|
+
distributionFlyersHTCents Int? // Prix HT flyers en centimes
|
|
928
|
+
distributionLettersHTCents Int? // Prix HT courriers en centimes
|
|
929
|
+
distributionTotalCostCents Int? // Prix total TTC calculé automatiquement
|
|
930
|
+
distributionInvoiceFileId String?
|
|
931
|
+
|
|
932
|
+
// Relations
|
|
933
|
+
commercialId String?
|
|
934
|
+
commercial User? @relation("TourCommercial", fields: [commercialId], references: [id], onDelete: SetNull)
|
|
935
|
+
contacts TourContact[]
|
|
936
|
+
tasks Task[] // Tâches liées à cette tournée
|
|
937
|
+
transactions Transaction[] @relation("TransactionTour") // Transactions liées à cette tournée
|
|
938
|
+
|
|
939
|
+
// Note / Instructions
|
|
940
|
+
note String?
|
|
941
|
+
|
|
942
|
+
// Compteur interactions manuelles
|
|
943
|
+
interactionCount Int @default(0)
|
|
944
|
+
|
|
945
|
+
createdAt DateTime @default(now())
|
|
946
|
+
updatedAt DateTime @updatedAt
|
|
947
|
+
|
|
948
|
+
@@index([number])
|
|
949
|
+
@@index([commercialId])
|
|
950
|
+
@@index([distributionWeek])
|
|
951
|
+
@@map("tour")
|
|
952
|
+
}
|
|
953
|
+
|
|
954
|
+
/// Liaison plusieurs contacts <-> tournée
|
|
955
|
+
model TourContact {
|
|
589
956
|
id String @id @default(cuid())
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
957
|
+
tourId String
|
|
958
|
+
contactId String
|
|
959
|
+
|
|
960
|
+
tour Tour @relation(fields: [tourId], references: [id], onDelete: Cascade)
|
|
961
|
+
contact Contact @relation(fields: [contactId], references: [id], onDelete: Cascade)
|
|
962
|
+
|
|
963
|
+
createdAt DateTime @default(now())
|
|
964
|
+
|
|
965
|
+
@@unique([tourId, contactId])
|
|
966
|
+
@@index([tourId])
|
|
967
|
+
@@index([contactId])
|
|
968
|
+
@@map("tour_contact")
|
|
969
|
+
}
|
|
970
|
+
|
|
971
|
+
/// Prestataires de distribution (configurés par l'admin)
|
|
972
|
+
model DistributionProvider {
|
|
973
|
+
id String @id @default(cuid())
|
|
974
|
+
name String
|
|
975
|
+
isDefault Boolean @default(false)
|
|
597
976
|
createdAt DateTime @default(now())
|
|
598
977
|
updatedAt DateTime @updatedAt
|
|
599
978
|
|
|
979
|
+
@@map("distribution_provider")
|
|
980
|
+
}
|
|
981
|
+
|
|
982
|
+
/// Documents requis pour la demande d'autorisation en mairie (configurés par l'admin)
|
|
983
|
+
model CityHallRequiredDocument {
|
|
984
|
+
id String @id @default(cuid())
|
|
985
|
+
name String // Nom du document (ex: "Plan d'implantation", "Demande d'autorisation", etc.)
|
|
986
|
+
fileId String // ID du fichier Google Drive
|
|
987
|
+
fileName String // Nom du fichier original
|
|
988
|
+
order Int @default(0) // Ordre d'affichage
|
|
989
|
+
createdAt DateTime @default(now())
|
|
990
|
+
updatedAt DateTime @updatedAt
|
|
991
|
+
|
|
992
|
+
@@index([order])
|
|
993
|
+
@@map("city_hall_required_document")
|
|
994
|
+
}
|
|
995
|
+
|
|
996
|
+
/// Transaction d'achat d'or/métaux précieux
|
|
997
|
+
model Transaction {
|
|
998
|
+
id String @id @default(cuid())
|
|
999
|
+
contactId String
|
|
1000
|
+
contact Contact @relation(fields: [contactId], references: [id], onDelete: Restrict)
|
|
1001
|
+
tourId String? // Optionnel : lié à une tournée
|
|
1002
|
+
tour Tour? @relation("TransactionTour", fields: [tourId], references: [id], onDelete: SetNull)
|
|
1003
|
+
salesRepId String? // Commercial assigné
|
|
1004
|
+
salesRep User? @relation("TransactionAssignedTo", fields: [salesRepId], references: [id], onDelete: SetNull)
|
|
1005
|
+
createdById String?
|
|
1006
|
+
createdBy User? @relation("TransactionCreatedBy", fields: [createdById], references: [id], onDelete: SetNull)
|
|
1007
|
+
status TransactionStatus @default(DRAFT)
|
|
1008
|
+
paymentMethod PaymentMethod?
|
|
1009
|
+
paymentReference String? // Numéro de chèque ou nom de la banque
|
|
1010
|
+
signedAt DateTime? // Date de signature
|
|
1011
|
+
retractionDeadline DateTime? // Date limite de rétractation (48 heures après signature)
|
|
1012
|
+
contractPdfFileId String? // ID du fichier PDF du contrat dans Google Drive
|
|
1013
|
+
signatureType SignatureType? // Type de signature : ELECTRONIC, TABLET, PAPER
|
|
1014
|
+
signatureData String? // Données de signature (pour tablet) ou URL du scan (pour papier)
|
|
1015
|
+
yousignSignatureRequestId String? @unique // ID de la demande de signature Yousign
|
|
1016
|
+
yousignSignatureUrl String? // URL de signature Yousign
|
|
1017
|
+
yousignRetractionRequestId String? @unique // ID de la demande de signature de rétractation Yousign
|
|
1018
|
+
retractionPdfFileId String? // ID du fichier PDF de rétractation signé dans Google Drive
|
|
1019
|
+
transactionAddress String? // Adresse du lieu de la transaction (si pas de tournée)
|
|
1020
|
+
totalAmountCents Int? // Montant total en centimes
|
|
1021
|
+
lockedAt DateTime? // Date de verrouillage
|
|
1022
|
+
lockedBy String? // ID de l'utilisateur qui a verrouillé
|
|
1023
|
+
completedAt DateTime? // Date de complétion
|
|
1024
|
+
cancelledAt DateTime? // Date d'annulation
|
|
1025
|
+
items TransactionItem[]
|
|
1026
|
+
auditLogs TransactionAuditLog[]
|
|
1027
|
+
createdAt DateTime @default(now())
|
|
1028
|
+
updatedAt DateTime @updatedAt
|
|
1029
|
+
|
|
1030
|
+
@@index([contactId])
|
|
1031
|
+
@@index([salesRepId])
|
|
1032
|
+
@@index([createdById])
|
|
1033
|
+
@@index([status])
|
|
1034
|
+
@@index([tourId])
|
|
1035
|
+
@@index([status, contactId])
|
|
1036
|
+
@@index([status, salesRepId])
|
|
1037
|
+
@@index([status, createdAt])
|
|
1038
|
+
@@index([signedAt])
|
|
1039
|
+
@@index([salesRepId, signedAt])
|
|
1040
|
+
@@map("transaction")
|
|
1041
|
+
}
|
|
1042
|
+
|
|
1043
|
+
/// Articles d'une transaction (polymorphique)
|
|
1044
|
+
model TransactionItem {
|
|
1045
|
+
id String @id @default(cuid())
|
|
1046
|
+
transactionId String
|
|
1047
|
+
transaction Transaction @relation(fields: [transactionId], references: [id], onDelete: Cascade)
|
|
1048
|
+
category TransactionItemCategory
|
|
1049
|
+
order Int @default(0)
|
|
1050
|
+
processingStatus TransactionItemProcessingStatus @default(A_VERIFIER)
|
|
1051
|
+
|
|
1052
|
+
// Disposition dans le stock (après traitement)
|
|
1053
|
+
stockDisposition StockDisposition @default(IN_STOCK)
|
|
1054
|
+
exclusionReason String? // "Pas en étain", "Contrefaçon", "Irréparable", "Sans intérêt"
|
|
1055
|
+
|
|
1056
|
+
// Vente manuelle (pour articles d'occasion)
|
|
1057
|
+
saleAmountCents Int?
|
|
1058
|
+
saleDate DateTime?
|
|
1059
|
+
saleNotes String?
|
|
1060
|
+
|
|
1061
|
+
// Pour les métaux (OR, PLATINE, ARGENT)
|
|
1062
|
+
purity Int?
|
|
1063
|
+
weightGross Float?
|
|
1064
|
+
weightNet Float?
|
|
1065
|
+
type String?
|
|
1066
|
+
tmpValueCents Int?
|
|
1067
|
+
|
|
1068
|
+
// Pour les unités (montres, collectibles, diamants)
|
|
1069
|
+
brand String?
|
|
1070
|
+
model String?
|
|
1071
|
+
state String?
|
|
1072
|
+
certificate Boolean?
|
|
1073
|
+
pricePerUnitCents Int?
|
|
1074
|
+
quantity Int?
|
|
1075
|
+
|
|
1076
|
+
// Pour les diamants (4C)
|
|
1077
|
+
carat Float?
|
|
1078
|
+
color String?
|
|
1079
|
+
clarity String?
|
|
1080
|
+
cut String?
|
|
1081
|
+
|
|
1082
|
+
// Pour métal argenté, plaqué or, étains
|
|
1083
|
+
weightKg Float?
|
|
1084
|
+
|
|
1085
|
+
// Fichiers/photos
|
|
1086
|
+
photoFileId String?
|
|
1087
|
+
|
|
1088
|
+
// Métadonnées JSON pour flexibilité
|
|
1089
|
+
metadata Json?
|
|
1090
|
+
|
|
1091
|
+
refinerSubmissionItems RefinerSubmissionItem[]
|
|
1092
|
+
|
|
1093
|
+
createdAt DateTime @default(now())
|
|
1094
|
+
updatedAt DateTime @updatedAt
|
|
1095
|
+
|
|
1096
|
+
@@index([transactionId])
|
|
1097
|
+
@@index([category])
|
|
1098
|
+
@@index([stockDisposition])
|
|
1099
|
+
@@map("transaction_item")
|
|
1100
|
+
}
|
|
1101
|
+
|
|
1102
|
+
/// Journal d'audit pour les transactions verrouillées
|
|
1103
|
+
model TransactionAuditLog {
|
|
1104
|
+
id String @id @default(cuid())
|
|
1105
|
+
transactionId String
|
|
1106
|
+
transaction Transaction @relation(fields: [transactionId], references: [id], onDelete: Cascade)
|
|
1107
|
+
userId String?
|
|
1108
|
+
user User? @relation(fields: [userId], references: [id], onDelete: SetNull)
|
|
1109
|
+
fieldChanged String // Nom du champ modifié
|
|
1110
|
+
oldValue String? // Ancienne valeur (JSON stringifié si nécessaire)
|
|
1111
|
+
newValue String? // Nouvelle valeur (JSON stringifié si nécessaire)
|
|
1112
|
+
createdAt DateTime @default(now())
|
|
1113
|
+
|
|
1114
|
+
@@index([transactionId])
|
|
600
1115
|
@@index([userId])
|
|
601
|
-
@@
|
|
1116
|
+
@@index([createdAt])
|
|
1117
|
+
@@map("transaction_audit_log")
|
|
1118
|
+
}
|
|
1119
|
+
|
|
1120
|
+
/// Types de récurrence pour les jours d'indisponibilité
|
|
1121
|
+
enum RecurrenceType {
|
|
1122
|
+
NONE // Pas de récurrence (date unique)
|
|
1123
|
+
PERIOD // Période (du... au...)
|
|
1124
|
+
WEEKLY // Récurrence hebdomadaire (tous les lundis, mardis, etc.)
|
|
1125
|
+
MONTHLY_DAY // Récurrence mensuelle par jour (tous les 5 du mois)
|
|
1126
|
+
YEARLY // Récurrence annuelle (tous les 25 décembre)
|
|
1127
|
+
}
|
|
1128
|
+
|
|
1129
|
+
/// Types de jour d'indisponibilité
|
|
1130
|
+
enum UnavailableDateType {
|
|
1131
|
+
PUBLIC_HOLIDAY // Jour férié national
|
|
1132
|
+
CUSTOM // Jour personnalisé par l'admin
|
|
1133
|
+
}
|
|
1134
|
+
|
|
1135
|
+
/// Jours d'indisponibilité pour les tournées
|
|
1136
|
+
model UnavailableDate {
|
|
1137
|
+
id String @id @default(cuid())
|
|
1138
|
+
name String // Nom/Description (ex: "Noël", "Fermeture estivale")
|
|
1139
|
+
type UnavailableDateType @default(CUSTOM)
|
|
1140
|
+
date DateTime? // Date spécifique (si pas de récurrence ou date de début de période)
|
|
1141
|
+
endDate DateTime? // Date de fin (pour les périodes, ex: du 7 au 22 janvier)
|
|
1142
|
+
recurrenceType RecurrenceType @default(NONE)
|
|
1143
|
+
// Pour WEEKLY : 0=Dimanche, 1=Lundi, 2=Mardi, etc.
|
|
1144
|
+
// Pour MONTHLY_DAY : jour du mois (1-31)
|
|
1145
|
+
// Pour YEARLY : null (utilise la date)
|
|
1146
|
+
recurrenceValue Int? // Valeur de la récurrence
|
|
1147
|
+
isActive Boolean @default(true) // Permet de désactiver temporairement
|
|
1148
|
+
createdById String?
|
|
1149
|
+
createdBy User? @relation(fields: [createdById], references: [id], onDelete: SetNull)
|
|
1150
|
+
createdAt DateTime @default(now())
|
|
1151
|
+
updatedAt DateTime @updatedAt
|
|
1152
|
+
|
|
1153
|
+
@@index([type])
|
|
1154
|
+
@@index([isActive])
|
|
1155
|
+
@@index([createdById])
|
|
1156
|
+
@@map("unavailable_date")
|
|
1157
|
+
}
|
|
1158
|
+
|
|
1159
|
+
/// Mode de paiement
|
|
1160
|
+
enum PaymentMode {
|
|
1161
|
+
VIREMENT
|
|
1162
|
+
CHEQUE
|
|
1163
|
+
ESPECES
|
|
1164
|
+
CB
|
|
1165
|
+
}
|
|
1166
|
+
|
|
1167
|
+
/// Paiement de campagne de distribution
|
|
1168
|
+
model DistributionCampaignPayment {
|
|
1169
|
+
id String @id @default(cuid())
|
|
1170
|
+
paymentKey String @unique // Clé de paiement (ex: PV-2026-S02)
|
|
1171
|
+
year Int // Année
|
|
1172
|
+
isoWeek Int // Semaine ISO
|
|
1173
|
+
tourDate DateTime // Date tournée
|
|
1174
|
+
amountHT Float // Montant HT
|
|
1175
|
+
tva Float // TVA 20%
|
|
1176
|
+
amountTTC Float // Montant TTC
|
|
1177
|
+
|
|
1178
|
+
// Acompte 1
|
|
1179
|
+
deposit1Date DateTime? // Date acompte 1
|
|
1180
|
+
deposit1Amount Float? @default(0) // Acompte 1
|
|
1181
|
+
|
|
1182
|
+
// Acompte 2
|
|
1183
|
+
deposit2Date DateTime? // Date acompte 2
|
|
1184
|
+
deposit2Amount Float? @default(0) // Acompte 2
|
|
1185
|
+
|
|
1186
|
+
// Acompte 3
|
|
1187
|
+
deposit3Date DateTime? // Date acompte 3
|
|
1188
|
+
deposit3Amount Float? @default(0) // Acompte 3
|
|
1189
|
+
|
|
1190
|
+
// Solde 1
|
|
1191
|
+
balance1Date DateTime? // Date solde 1
|
|
1192
|
+
balance1Amount Float? @default(0) // Solde 1
|
|
1193
|
+
|
|
1194
|
+
// Solde 2
|
|
1195
|
+
balance2Date DateTime? // Date solde 2
|
|
1196
|
+
balance2Amount Float? @default(0) // Solde 2
|
|
1197
|
+
|
|
1198
|
+
// Solde 3
|
|
1199
|
+
balance3Date DateTime? // Date solde 3
|
|
1200
|
+
balance3Amount Float? @default(0) // Solde 3
|
|
1201
|
+
|
|
1202
|
+
totalPaid Float @default(0) // Montant total payé (calculé)
|
|
1203
|
+
remainingBalance Float // Solde restant (calculé)
|
|
1204
|
+
status CampaignPaymentStatus @default(A_PAYER) // Statut
|
|
1205
|
+
|
|
1206
|
+
createdById String?
|
|
1207
|
+
createdBy User? @relation(fields: [createdById], references: [id], onDelete: SetNull)
|
|
1208
|
+
createdAt DateTime @default(now())
|
|
1209
|
+
updatedAt DateTime @updatedAt
|
|
1210
|
+
|
|
1211
|
+
@@index([year])
|
|
1212
|
+
@@index([isoWeek])
|
|
1213
|
+
@@index([status])
|
|
1214
|
+
@@index([createdById])
|
|
1215
|
+
@@map("distribution_campaign_payment")
|
|
1216
|
+
}
|
|
1217
|
+
|
|
1218
|
+
/// Paiement publicité Meta
|
|
1219
|
+
model MetaAdsPayment {
|
|
1220
|
+
id String @id @default(cuid())
|
|
1221
|
+
paymentKey String @unique // Clé paiement Meta (ex: META-2025-12-1)
|
|
1222
|
+
year Int // Année
|
|
1223
|
+
month String // Mois (ex: "décembre")
|
|
1224
|
+
periodCovered String? // Période couverte (ex: "S50 à S52")
|
|
1225
|
+
invoiceNumber String? // N° Facture Meta
|
|
1226
|
+
invoiceDate DateTime? // Date de Facture
|
|
1227
|
+
invoiceDueDate DateTime? // Date d'échéance Facture
|
|
1228
|
+
paymentDate DateTime? // Date de Paiement
|
|
1229
|
+
invoiceAmount Float // Montant facture META
|
|
1230
|
+
paymentMode PaymentMode @default(VIREMENT) // Mode de paiement
|
|
1231
|
+
paymentStatus CampaignPaymentStatus @default(A_PAYER) // Statut paiement
|
|
1232
|
+
|
|
1233
|
+
createdById String?
|
|
1234
|
+
createdBy User? @relation(fields: [createdById], references: [id], onDelete: SetNull)
|
|
1235
|
+
createdAt DateTime @default(now())
|
|
1236
|
+
updatedAt DateTime @updatedAt
|
|
1237
|
+
|
|
1238
|
+
@@index([year])
|
|
1239
|
+
@@index([month])
|
|
1240
|
+
@@index([paymentStatus])
|
|
1241
|
+
@@index([createdById])
|
|
1242
|
+
@@map("meta_ads_payment")
|
|
1243
|
+
}
|
|
1244
|
+
|
|
1245
|
+
model ContactView {
|
|
1246
|
+
id String @id @default(cuid())
|
|
1247
|
+
name String
|
|
1248
|
+
userId String
|
|
1249
|
+
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
|
|
1250
|
+
isPublic Boolean @default(false)
|
|
1251
|
+
isDefault Boolean @default(false)
|
|
1252
|
+
entityType String @default("contacts") // "contacts" | "companies"
|
|
1253
|
+
filters Json @default("[]")
|
|
1254
|
+
columns Json?
|
|
1255
|
+
sortConfig Json?
|
|
1256
|
+
createdAt DateTime @default(now())
|
|
1257
|
+
updatedAt DateTime @updatedAt
|
|
1258
|
+
pins ContactViewPin[]
|
|
1259
|
+
|
|
1260
|
+
@@index([userId])
|
|
1261
|
+
@@index([isPublic])
|
|
1262
|
+
@@index([entityType, isPublic])
|
|
1263
|
+
@@map("contact_view")
|
|
1264
|
+
}
|
|
1265
|
+
|
|
1266
|
+
model ContactViewPin {
|
|
1267
|
+
id String @id @default(cuid())
|
|
1268
|
+
userId String
|
|
1269
|
+
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
|
|
1270
|
+
viewId String
|
|
1271
|
+
view ContactView @relation(fields: [viewId], references: [id], onDelete: Cascade)
|
|
1272
|
+
pinOrder Int @default(0)
|
|
1273
|
+
|
|
1274
|
+
@@unique([userId, viewId])
|
|
1275
|
+
@@index([userId])
|
|
1276
|
+
@@map("contact_view_pin")
|
|
1277
|
+
}
|
|
1278
|
+
|
|
1279
|
+
/// Remise affineur (lot envoyé à l'affineur pour rachat)
|
|
1280
|
+
model RefinerSubmission {
|
|
1281
|
+
id String @id @default(cuid())
|
|
1282
|
+
submissionDate DateTime
|
|
1283
|
+
category TransactionItemCategory
|
|
1284
|
+
purity Int?
|
|
1285
|
+
metalPricePerKgCents Int
|
|
1286
|
+
brokeragePercent Float
|
|
1287
|
+
refinerPricePerGramCents Int
|
|
1288
|
+
totalWeightGrams Float
|
|
1289
|
+
totalFineWeightGrams Float
|
|
1290
|
+
provisionalAmountCents Int?
|
|
1291
|
+
actualAmountCents Int?
|
|
1292
|
+
status RefinerSubmissionStatus @default(PENDING)
|
|
1293
|
+
notes String?
|
|
1294
|
+
createdById String?
|
|
1295
|
+
createdBy User? @relation("RefinerSubmissionCreatedBy", fields: [createdById], references: [id], onDelete: SetNull)
|
|
1296
|
+
items RefinerSubmissionItem[]
|
|
1297
|
+
documents RefinerDocument[]
|
|
1298
|
+
createdAt DateTime @default(now())
|
|
1299
|
+
updatedAt DateTime @updatedAt
|
|
1300
|
+
|
|
1301
|
+
@@index([category])
|
|
1302
|
+
@@index([status])
|
|
1303
|
+
@@index([submissionDate])
|
|
1304
|
+
@@index([createdById])
|
|
1305
|
+
@@map("refiner_submission")
|
|
1306
|
+
}
|
|
1307
|
+
|
|
1308
|
+
/// Article lié à une remise affineur (snapshot des valeurs au moment de la remise)
|
|
1309
|
+
model RefinerSubmissionItem {
|
|
1310
|
+
id String @id @default(cuid())
|
|
1311
|
+
submissionId String
|
|
1312
|
+
submission RefinerSubmission @relation(fields: [submissionId], references: [id], onDelete: Cascade)
|
|
1313
|
+
transactionItemId String
|
|
1314
|
+
transactionItem TransactionItem @relation(fields: [transactionItemId], references: [id], onDelete: Restrict)
|
|
1315
|
+
weightGrams Float
|
|
1316
|
+
purity Int?
|
|
1317
|
+
fineWeightGrams Float
|
|
1318
|
+
provisionalPaymentPercent Float?
|
|
1319
|
+
restitutionPercent Float?
|
|
1320
|
+
calculatedAmountCents Int
|
|
1321
|
+
createdAt DateTime @default(now())
|
|
1322
|
+
|
|
1323
|
+
@@index([submissionId])
|
|
1324
|
+
@@index([transactionItemId])
|
|
1325
|
+
@@map("refiner_submission_item")
|
|
1326
|
+
}
|
|
1327
|
+
|
|
1328
|
+
/// Document attaché à une remise affineur (facture, bordereau)
|
|
1329
|
+
model RefinerDocument {
|
|
1330
|
+
id String @id @default(cuid())
|
|
1331
|
+
submissionId String
|
|
1332
|
+
submission RefinerSubmission @relation(fields: [submissionId], references: [id], onDelete: Cascade)
|
|
1333
|
+
fileName String
|
|
1334
|
+
fileUrl String
|
|
1335
|
+
fileType String?
|
|
1336
|
+
uploadedAt DateTime @default(now())
|
|
1337
|
+
|
|
1338
|
+
@@index([submissionId])
|
|
1339
|
+
@@map("refiner_document")
|
|
1340
|
+
}
|
|
1341
|
+
|
|
1342
|
+
/// Configuration de la valorisation du stock (clé/valeur)
|
|
1343
|
+
model StockConfig {
|
|
1344
|
+
id String @id @default(cuid())
|
|
1345
|
+
key String @unique
|
|
1346
|
+
value String
|
|
1347
|
+
label String
|
|
1348
|
+
updatedAt DateTime @updatedAt
|
|
1349
|
+
|
|
1350
|
+
@@map("stock_config")
|
|
602
1351
|
}
|