Skip to content

Commit 00941d2

Browse files
pysnooLabclaude
andcommitted
feat: generate demo machines/contracts, filter machines by company in deal form
- Add generateMachines: 20+ machines spread across first 18 companies - Add generateMachineContracts: 6 contracts expiring within 30 days (RenewalWidget), plus expired and far-future contracts for variety - Fix DealInputs: filter machine ReferenceInput by deal's company_id so only that client's machines appear in the autocomplete Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
1 parent d1cb6c7 commit 00941d2

3 files changed

Lines changed: 113 additions & 4 deletions

File tree

src/components/atomic-crm/deals/DealInputs.tsx

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,7 @@ const DealMiscInputs = () => {
6969
const { dealStages } = useConfigurationContext();
7070
const translate = useTranslate();
7171
const dealType = useWatch({ name: "deal_type", defaultValue: "tondeuse" });
72+
const companyId = useWatch({ name: "company_id" });
7273

7374
return (
7475
<div className="flex flex-col gap-4 flex-1">
@@ -108,10 +109,18 @@ const DealMiscInputs = () => {
108109
)}
109110

110111
{dealType === "entretien" && (
111-
<ReferenceInput source="machine_id" reference="machines">
112+
<ReferenceInput
113+
source="machine_id"
114+
reference="machines"
115+
filter={companyId ? { "company_id@eq": companyId } : {}}
116+
>
112117
<AutocompleteInput
113118
label="Machine concernée (optionnel)"
114-
optionText={(record: any) => record?.numero_serie ?? record?.modele_libre ?? `Machine #${record?.id}`}
119+
optionText={(record: any) =>
120+
record?.modele_libre ??
121+
record?.numero_serie ??
122+
`Machine #${record?.id}`
123+
}
115124
helperText={false}
116125
/>
117126
</ReferenceInput>

src/components/atomic-crm/providers/fakerest/dataGenerator/index.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import { generateDealNotes } from "./dealNotes";
55
import { generateDeals } from "./deals";
66
import { finalize } from "./finalize";
77
import { generateMaintenance } from "./maintenance";
8+
import { generateMachines, generateMachineContracts } from "./machines";
89
import { generateProducts } from "./products";
910
import { generateSales } from "./sales";
1011
import { generateTags } from "./tags";
@@ -29,8 +30,8 @@ export default (): Db => {
2930
];
3031
db.products = generateProducts();
3132
db.services = generateMaintenance();
32-
db.machines = [];
33-
db.machine_contracts = [];
33+
db.machines = generateMachines(db);
34+
db.machine_contracts = generateMachineContracts(db);
3435
finalize(db);
3536

3637
return db;
Lines changed: 99 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,99 @@
1+
import type { Machine, MachineContract } from "../../../types";
2+
import type { Db } from "./types";
3+
4+
const MODELES_LIBRES = [
5+
"Kubota G23",
6+
"John Deere X350",
7+
"Toro TimeCutter 4225",
8+
"Hustler Raptor",
9+
"Ferris IS700",
10+
];
11+
12+
const daysFromNow = (n: number): string => {
13+
const d = new Date();
14+
d.setDate(d.getDate() + n);
15+
return d.toISOString().split("T")[0];
16+
};
17+
18+
const pastDate = (yearsAgo: number, monthOffset: number): string => {
19+
const d = new Date();
20+
d.setFullYear(d.getFullYear() - yearsAgo);
21+
d.setMonth(d.getMonth() - monthOffset);
22+
d.setDate(15);
23+
return d.toISOString().split("T")[0];
24+
};
25+
26+
export const generateMachines = (db: Db): Machine[] => {
27+
const machines: Machine[] = [];
28+
let id = 1;
29+
30+
// Give machines to the first 18 companies (1–2 machines each)
31+
const companies = db.companies.slice(0, 18);
32+
for (let ci = 0; ci < companies.length; ci++) {
33+
const company = companies[ci];
34+
const count = ci % 3 === 0 ? 2 : 1;
35+
for (let i = 0; i < count; i++) {
36+
const useProduct = i === 0 && db.products.length > 0;
37+
machines.push({
38+
id,
39+
company_id: company.id,
40+
product_id: useProduct ? db.products[id % db.products.length].id : undefined,
41+
modele_libre: !useProduct ? MODELES_LIBRES[id % MODELES_LIBRES.length] : undefined,
42+
numero_serie: `SN-${String(id).padStart(5, "0")}`,
43+
date_achat: pastDate(id % 3, id % 6),
44+
});
45+
id++;
46+
}
47+
}
48+
49+
return machines;
50+
};
51+
52+
export const generateMachineContracts = (db: Db): MachineContract[] => {
53+
if (!db.machines.length || !db.services.length) return [];
54+
55+
const contracts: MachineContract[] = [];
56+
// Upcoming renewals spread over next 30 days (feed the dashboard widget)
57+
const upcomingDays = [4, 8, 12, 17, 23, 28];
58+
59+
db.machines.forEach((machine, index) => {
60+
const service = db.services[index % db.services.length];
61+
const isUpcoming = index < upcomingDays.length;
62+
63+
if (isUpcoming) {
64+
// Active contract expiring in next 30 days → visible in RenewalWidget
65+
const startDate = pastDate(1, 0);
66+
const renewDate = daysFromNow(upcomingDays[index]);
67+
contracts.push({
68+
id: contracts.length + 1,
69+
machine_id: machine.id,
70+
service_id: service.id,
71+
date_debut: startDate,
72+
date_renouvellement: renewDate,
73+
statut: "actif",
74+
});
75+
} else if (index % 3 === 0) {
76+
// Expired contract (historical)
77+
contracts.push({
78+
id: contracts.length + 1,
79+
machine_id: machine.id,
80+
service_id: service.id,
81+
date_debut: pastDate(2, 0),
82+
date_renouvellement: pastDate(1, 0),
83+
statut: "expiré",
84+
});
85+
} else {
86+
// Active contract renewing far in the future
87+
contracts.push({
88+
id: contracts.length + 1,
89+
machine_id: machine.id,
90+
service_id: service.id,
91+
date_debut: pastDate(0, 6),
92+
date_renouvellement: daysFromNow(90 + index * 10),
93+
statut: "actif",
94+
});
95+
}
96+
});
97+
98+
return contracts;
99+
};

0 commit comments

Comments
 (0)