Preuve · code, extrait

functions/flexylead-sync-local-google.mjs

Dépôt jeremy-flexylead/flexylead-crm · commit ccbbaa07870e0f786729003dd6f8862e4bcc8256 · dossier de production synchronisé le 14 septembre 2026 à 08 h 46

Extrait tel qu'à ce commit : lignes 2891–2970, sur 5 733 (numérotation d'origine, 30 lignes de contexte autour de chaque citation) · fichier intégral sur GitHub (dépôt privé, accès requis)

Lignes citées par l'audit : 2921–2940

80 lignes reproduites · ← retour à l'audit · catalogue des preuves

2891      listAllAirtableRecords(AIRTABLE_CONSO.suppliers_table_id),
2892      listAllAirtableRecords(AIRTABLE_CONSO.sales_table_id),
2893      loadAllRows(context, 'offer_remuneration_rules', [
2894        'id', 'local_id', 'offre_id', 'vente_type', 'prime_montant',
2895        'prime_devise', 'active', 'starts_at', 'ends_at', 'scope_type', 'scope_id', 'payout_mode',
2896      ]),
2897      loadAllRows(context, 'commerciaux', [
2898        'id', 'email', 'centre_appel_id', 'provider_user_id', 'provider_email', 'active',
2899      ]),
2900    ]);
2901    return applyAirtableRemunerationRules(
2902      mapAirtableConsoPiloteVentes(context, supplierRecords, salesRecords, commercialRows),
2903      remunerationRules
2904    );
2905  } catch (e) {
2906    context.log(`[airtable conso] skipped: ${String(e?.message || e).slice(0, 300)}`);
2907    return [];
2908  }
2909}
2910
2911function identityPart(value) {
2912  const s = String(value ?? '').trim();
2913  if (!s) return '';
2914  return s
2915    .normalize('NFD').replace(/[\u0300-\u036f]/g, '')
2916    .toLowerCase()
2917    .replace(/[^a-z0-9]+/g, '_')
2918    .replace(/^_+|_+$/g, '')
2919    .slice(0, 80);
2920}
2921
2922function preciseTelecomOfferId(defaultOfferId, typeValue) {
2923  const parent = String(defaultOfferId || '').trim();
2924  const type = identityPart(typeValue);
2925  if (!type) return parent;
2926  if (parent === 'free_box') {
2927    if (type.includes('revolution_light')) return 'free_box_revolution_light';
2928    if (type.includes('pop_s')) return 'free_box_pop_s';
2929    if (type.includes('ultra_essentiel')) return 'free_box_ultra_essentiel';
2930    if (type.includes('ultra')) return 'free_box_ultra';
2931    if (type.includes('5g')) return 'free_box_5g';
2932    if (type.includes('pop')) return 'free_box_pop';
2933  }
2934  if (parent === 'free_mobile') {
2935    if (type.includes('free_max') || type.includes('forfait_max')) return 'free_mobile_forfait_free_max';
2936    if (type.includes('serie_free') || type.includes('serie')) return 'free_mobile_serie_free';
2937    if (type.includes('forfait_free') || type === 'free') return 'free_mobile_forfait_free';
2938  }
2939  return parent;
2940}
2941function contractIdentityPart(value) {
2942  const parts = Array.isArray(value) ? value : String(value ?? '').split('+');
2943  return parts
2944    .map(part => {
2945      const raw = String(part ?? '').trim();
2946      if (!raw) return '';
2947      const digits = raw.replace(/\D+/g, '');
2948      return digits.length >= 5 ? digits : identityPart(raw);
2949    })
2950    .filter(Boolean)
2951    .join('_')
2952    .slice(0, 80);
2953}
2954function canonicalVenteLocalId({ centreId, sheetId, tab, tabCfg, rowNumber, mapped, seg, numeros, offre_id, dateVente }) {
2955  const sheetKey = identityPart(sheetId);
2956  const tabKey = identityPart(tab);
2957  const roleKey = identityPart(tabCfg.role || 'sheet') || 'sheet';
2958  const segmentKey = identityPart(seg?.contrat_field || seg?.offre_id_default || offre_id || 'single') || 'single';
2959  const contractKey = contractIdentityPart(numeros || []);
2960  const offreKey = identityPart(offre_id || 'offre') || 'offre';
2961  if (roleKey === 'form') {
2962    const timestampKey = identityPart(mapped.horodateur || mapped.timestamp || mapped.date_vente || dateVente);
2963    if (timestampKey && contractKey) {
2964      return centreId + '::' + sheetKey + '::' + tabKey + '::form::' + timestampKey + '::' + segmentKey + '::' + contractKey;
2965    }
2966  }
2967  if (dateVente && contractKey) {
2968    return centreId + '::' + sheetKey + '::' + tabKey + '::' + roleKey + '::' + dateVente + '::' + offreKey + '::' + contractKey;
2969  }
2970  const rowKey = rowNumber ? ('r' + rowNumber) : 'row_unknown';