177 lines
5.5 KiB
JavaScript
177 lines
5.5 KiB
JavaScript
/// <reference path="../pb_data/types.d.ts" />
|
|
/**
|
|
* Module Recherche & Analyse marché + champ prix revente au m² sur l'analyse financière.
|
|
*
|
|
* Les règles API doivent être assignées APRÈS fields.add(...): sinon le validateur ne voit
|
|
* pas les champs (erreurs "unknown field user" / "failed to resolve field owner").
|
|
*/
|
|
migrate(
|
|
(app) => {
|
|
const usersCol = app.findCollectionByNameOrId("users");
|
|
let usersId = "";
|
|
if (usersCol) {
|
|
const a = usersCol.id != null && String(usersCol.id) !== "" ? usersCol.id : null;
|
|
const b = usersCol.Id != null && String(usersCol.Id) !== "" ? usersCol.Id : null;
|
|
usersId = String(a != null ? a : b != null ? b : "").trim();
|
|
}
|
|
if (!usersId) {
|
|
throw new Error("migration 1746100000: collection users introuvable ou id vide");
|
|
}
|
|
|
|
function findExistingCollection(name) {
|
|
try {
|
|
return app.findCollectionByNameOrId(name);
|
|
} catch (_) {}
|
|
try {
|
|
const all = app.findAllCollections();
|
|
const want = String(name).toLowerCase();
|
|
for (let i = 0; i < all.length; i++) {
|
|
const c = all[i];
|
|
if (c && c.name && String(c.name).toLowerCase() === want) {
|
|
return c;
|
|
}
|
|
}
|
|
} catch (_) {}
|
|
return null;
|
|
}
|
|
|
|
function loadOrCreate(name, factory) {
|
|
const existing = findExistingCollection(name);
|
|
if (existing != null) {
|
|
return existing;
|
|
}
|
|
try {
|
|
const col = factory();
|
|
app.save(col);
|
|
return col;
|
|
} catch (err) {
|
|
const msg = String(err && err.value ? err.value : err && err.message ? err.message : err);
|
|
if (msg.includes("unique") || msg.includes("Unique")) {
|
|
const again = findExistingCollection(name);
|
|
if (again != null) {
|
|
return again;
|
|
}
|
|
}
|
|
throw err;
|
|
}
|
|
}
|
|
|
|
const ownRecords = '@request.auth.id != "" && user.id = @request.auth.id';
|
|
const authOnly = '@request.auth.id != ""';
|
|
|
|
function makeAnalysesSecteur() {
|
|
const col = new Collection({ name: "analyses_secteur", type: "base" });
|
|
col.fields.add(
|
|
new RelationField({
|
|
name: "user",
|
|
required: true,
|
|
collectionId: usersId,
|
|
maxSelect: 1,
|
|
cascadeDelete: true,
|
|
}),
|
|
);
|
|
col.fields.add(new TextField({ name: "ville", required: true }));
|
|
col.fields.add(new TextField({ name: "notes", required: false }));
|
|
col.listRule = ownRecords;
|
|
col.viewRule = ownRecords;
|
|
col.createRule = authOnly;
|
|
col.updateRule = ownRecords;
|
|
col.deleteRule = ownRecords;
|
|
return col;
|
|
}
|
|
|
|
function makeNotesProspection() {
|
|
const col = new Collection({ name: "notes_prospection", type: "base" });
|
|
col.fields.add(
|
|
new RelationField({
|
|
name: "user",
|
|
required: true,
|
|
collectionId: usersId,
|
|
maxSelect: 1,
|
|
cascadeDelete: true,
|
|
}),
|
|
);
|
|
col.fields.add(new TextField({ name: "question", required: true }));
|
|
col.fields.add(new TextField({ name: "reponse", required: false }));
|
|
col.fields.add(new TextField({ name: "categorie", required: false }));
|
|
col.listRule = ownRecords;
|
|
col.viewRule = ownRecords;
|
|
col.createRule = authOnly;
|
|
col.updateRule = ownRecords;
|
|
col.deleteRule = ownRecords;
|
|
return col;
|
|
}
|
|
|
|
function makeGrillePrix() {
|
|
const col = new Collection({ name: "grille_prix", type: "base" });
|
|
col.fields.add(
|
|
new RelationField({
|
|
name: "user",
|
|
required: true,
|
|
collectionId: usersId,
|
|
maxSelect: 1,
|
|
cascadeDelete: true,
|
|
}),
|
|
);
|
|
col.fields.add(
|
|
new SelectField({
|
|
name: "type_bien",
|
|
required: true,
|
|
maxSelect: 1,
|
|
values: ["appartement", "maison", "immeuble"],
|
|
}),
|
|
);
|
|
col.fields.add(
|
|
new SelectField({
|
|
name: "etat",
|
|
required: true,
|
|
maxSelect: 1,
|
|
values: ["bon_etat", "a_renover", "travaux_lourds"],
|
|
}),
|
|
);
|
|
col.fields.add(new NumberField({ name: "prix_achat_m2", required: true }));
|
|
col.fields.add(new NumberField({ name: "prix_revente_m2", required: true }));
|
|
col.fields.add(new NumberField({ name: "marge_estimee_pct", required: false }));
|
|
col.fields.add(new TextField({ name: "ville", required: false }));
|
|
col.listRule = ownRecords;
|
|
col.viewRule = ownRecords;
|
|
col.createRule = authOnly;
|
|
col.updateRule = ownRecords;
|
|
col.deleteRule = ownRecords;
|
|
return col;
|
|
}
|
|
|
|
loadOrCreate("analyses_secteur", makeAnalysesSecteur);
|
|
loadOrCreate("notes_prospection", makeNotesProspection);
|
|
loadOrCreate("grille_prix", makeGrillePrix);
|
|
|
|
try {
|
|
const af = findExistingCollection("analyses_financieres");
|
|
if (af == null) {
|
|
/* rien à faire */
|
|
} else {
|
|
let has = false;
|
|
for (let i = 0; i < af.fields.length; i++) {
|
|
if (af.fields.get(i).name === "prix_revente_m2") {
|
|
has = true;
|
|
break;
|
|
}
|
|
}
|
|
if (!has && typeof NumberField !== "undefined") {
|
|
af.fields.add(new NumberField({ name: "prix_revente_m2", min: 0 }));
|
|
app.save(af);
|
|
}
|
|
}
|
|
} catch (_) {
|
|
/* schéma déjà à jour ou API différente */
|
|
}
|
|
},
|
|
(app) => {
|
|
for (const name of ["grille_prix", "notes_prospection", "analyses_secteur"]) {
|
|
try {
|
|
app.delete(app.findCollectionByNameOrId(name));
|
|
} catch (_) {}
|
|
}
|
|
},
|
|
);
|