PlaceholderAction
Request
GET Parameters
No GET parameters
POST Parameters
No POST parameters
Uploaded Files
No files were uploaded
Request Attributes
| Key | Value |
|---|---|
| _api_item_operation_name | "put" |
| _api_normalization_context | [ "groups" => [ "template:read" ] "operation_type" => "item" "item_operation_name" => "put" "resource_class" => "App\Model\Template\Template" "input" => null "output" => null "request_uri" => "/api/templates/f47ef469dac34bc29180feb40a25724c" "uri" => "https://dev.app.pol-crm.com/api/templates/f47ef469dac34bc29180feb40a25724c" "resources" => ApiPlatform\Core\Serializer\ResourceList {#3321 : [] : false : false : "ArrayIterator" } "exclude_from_cache_key" => [ "resources" "resources_to_push" ] "resources_to_push" => ApiPlatform\Core\Serializer\ResourceList {#5921 : [] : false : false : "ArrayIterator" } ] |
| _api_resource_class | "App\Model\Template\Template" |
| _api_write_item_iri | "/api/templates/f47ef469dac34bc29180feb40a25724c" |
| _controller | "api_platform.action.put_item" |
| _firewall_context | "security.firewall.map.context.api" |
| _format | null |
| _links | Fig\Link\GenericLinkProvider {#5905 -links: [ "000000001c197faf000000003adbb848" => Fig\Link\Link {#5873 -href: "https://dev.app.pol-crm.com/api/docs.jsonld" -rel: [ "http://www.w3.org/ns/hydra/core#apiDocumentation" => true ] -attributes: [] } ] } |
| _resources | [] |
| _route | "api_templates_put_item" |
| _route_params | [ "_format" => null "_api_resource_class" => "App\Model\Template\Template" "_api_item_operation_name" => "put" "id" => "f47ef469dac34bc29180feb40a25724c" ] |
| _stopwatch_token | "e83ddf" |
| data | App\Model\Template\Template {#173 -id: "f47ef469dac34bc29180feb40a25724c" -customerId: "customer_121" -name: "Test" -content: """ <!doctype html>\n <html lang="fr">\n <meta charset="utf-8">\n <meta name="viewport" content="width=device-width, initial-scale=1">\n <title>Devis – YANIGAV – {{ quote.name|default('Enfonce-pieux HYDROCHOC HPG 790') }}</title>\n <style>\n :root { --primary:#0f172a; --muted:#475569; --border:#e2e8f0; --bg:#f8fafc; }\n html, body { margin:0; padding:0; background:var(--bg); color:#0b1220; font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Helvetica,Arial,"Apple Color Emoji","Segoe UI Emoji"; }\n .page { max-width:900px; margin:2rem auto; background:#fff; border:1px solid var(--border); border-radius:12px; overflow:hidden; box-shadow:0 10px 30px rgba(0,0,0,.04); }\n header { padding:1.25rem 1.5rem; background:#fff; border-bottom:1px solid var(--border); display:flex; gap:1rem; align-items:center; }\n .brand { font-weight:700; letter-spacing:.2px; font-size:1rem; color:var(--primary); }\n .sub { color:var(--muted); font-size:.9rem; }\n .grid-2 { display:grid; grid-template-columns:1fr 1fr; gap:1rem; }\n .section { padding:1.25rem 1.5rem; }\n h1 { font-size:1.4rem; margin:.25rem 0 .5rem; letter-spacing:.2px; }\n h2 { font-size:1.1rem; margin:0 0 .75rem; color:var(--primary); }\n p { margin:.25rem 0; line-height:1.55; }\n .card { background:#fff; border:1px solid var(--border); border-radius:10px; padding:1rem; }\n .muted { color:var(--muted); }\n .kvs { display:grid; grid-template-columns:1fr 1fr; gap:.5rem 1rem; font-size:.95rem; }\n .kvs div { display:flex; align-items:center; gap:.5rem; }\n .pill { font-size:.8rem; padding:.15rem .5rem; border:1px solid var(--border); border-radius:999px; background:#f1f5f9; }\n table { width:100%; border-collapse:collapse; }\n th, td { border:1px solid var(--border); padding:.6rem .5rem; text-align:left; vertical-align:top; }\n thead th { background:#f1f5f9; }\n tfoot td { font-weight:600; }\n .note { font-size:.92rem; background:#f8fafc; border:1px dashed var(--border); padding:.75rem; border-radius:8px; }\n .cols-3 { columns:2; column-gap:1rem; }\n .signature { height:80px; border:1px dashed var(--border); border-radius:10px; display:flex; align-items:center; justify-content:center; color:var(--muted); }\n footer { padding:1rem 1.5rem; border-top:1px solid var(--border); color:var(--muted); font-size:.9rem; background:#fff; }\n </style>\n \n <body>\n <div class="page">\n \n {# ==== Raccourcis / sécurisation des accès ==== #}\n {% set c = (quote.prospect is defined and quote.prospect.contact is defined) ? quote.prospect.contact : null %}\n {% set a = (c and c.mainAddress is defined) ? c.mainAddress : null %}\n {% set comp = (quote.prospect is defined and quote.prospect.company is defined) ? quote.prospect.company : null %}\n {% set lines = quote.quoteLines|default([]) %}\n \n {# Portable du commercial : on cherche dans un ordre sûr #}\n {% set tel_portable = '' %}\n {% if managedBy is defined %}\n {% if managedBy.phoneNumber is defined and managedBy.phoneNumber %}{% set tel_portable = managedBy.phoneNumber %}\n {% elseif managedBy.mobilePhone is defined and managedBy.mobilePhone %}{% set tel_portable = managedBy.mobilePhone %}\n {% elseif managedBy.phone is defined and managedBy.phone %}{% set tel_portable = managedBy.phone %}\n {% endif %}\n {% endif %}\n \n {# ==== Totaux/remise/TVA - robustes ==== #}\n {% set total_ht_before_discount = 0 %}\n {% for l in lines %}\n {% set q = l.quantity|default(1) %}\n {% set pu = l.unitPriceExclVat|default(0) %}\n {% set total_ht_before_discount = total_ht_before_discount + (q * pu) %}\n {% endfor %}\n {% if total_ht_before_discount == 0 %}\n {% set total_ht_before_discount = quote.totalExcludingVat|default(0) %}\n {% endif %}\n {% set total_ht = quote.totalExcludingVat|default(total_ht_before_discount) %}\n {% set discount_value = total_ht_before_discount - total_ht %}\n {% set discount_percent = total_ht_before_discount > 0 ? (discount_value / total_ht_before_discount * 100) : 0 %}\n {% set vat_total = 0 %}\n {% for l in lines %}\n {% set vat_total = vat_total + (l.vatAmount|default(0)) %}\n {% endfor %}\n \n {# ==== Sélection ligne principale / formation / options (sans filtres avancés) ==== #}\n {% set first = (lines[0] is defined) ? lines[0] : null %}\n {% set mainLine = null %}\n {% set formationLine = null %}\n {% set options = [] %}\n {% for l in lines %}\n {% set ref = l.reference|default('')|lower %}\n {% set isOpt = l.isOptional is defined and l.isOptional %}\n {% if mainLine is null and not isOpt and ('formation' not in ref) %}\n {% set mainLine = l %}\n {% endif %}\n {% if formationLine is null and ('formation' in ref) %}\n {% set formationLine = l %}\n {% endif %}\n {% if isOpt %}\n {% set options = options|merge([l]) %}\n {% endif %}\n {% endfor %}\n {% if mainLine is null %}{% set mainLine = first %}{% endif %}\n \n <!-- HEADER -->\n <header>\n <div style="flex:1">\n <div class="brand">YANIGAV – Enfonce-pieux • Affûte-piquet • Fendeuse de bûche</div>\n <div class="sub">RCS ROANNE B 403 872 724 • SIRET 403 872 724 00014 • APE 4661Z • TVA FR114038727224</div>\n </div>\n <div class="pill">{{ (quote.createdAt|default('now'))|date('d F Y') }}</div>\n </header>\n \n <!-- COORDONNÉES -->\n <div class="section grid-2">\n <div class="card">\n <h2>Expéditeur</h2>\n <p><strong>YANIGAV</strong></p>\n <p>De la part de <strong>{{ managedBy is defined and managedBy.fullname is defined ? managedBy.fullname : (quote.managedByRealName|default('')) }}</strong> ({{ managedBy is defined and managedBy.role is defined and managedBy.role ? managedBy.role : 'Resp. Commercial' }})</p>\n <div class="kvs">\n <div><span class="pill">Tél</span> {{ managedBy is defined and managedBy.phone is defined and managedBy.phone ? managedBy.phone : '—' }}</div>\n {% if tel_portable %}\n <div><span class="pill">Port</span> {{ tel_portable }}</div>\n {% endif %}\n <div><span class="pill">Email</span>\n {% if managedBy is defined and managedBy.email is defined and managedBy.email %}\n <a href="mailto:{{ managedBy.email }}">{{ managedBy.email }}</a>\n {% else %}—{% endif %}\n </div>\n </div>\n </div>\n <div class="card">\n <h2>Destinataire</h2>\n <p><strong>{{ quote.contactIdRealName|default(c and (c.fullname is defined and c.fullname ? c.fullname : (c.name|default('')))) }}</strong></p>\n {% if comp and comp.name is defined and comp.name %}<p><strong>{{ comp.name }}</strong></p>{% endif %}\n {% if a and (a.postalCode is defined or a.city is defined) %}<p class="muted">{{ a.postalCode|default('') }} {{ a.city|default('') }}</p>{% endif %}\n </div>\n </div>\n \n <!-- INTRO -->\n <div class="section">\n <div class="card">\n <h1>Proposition commerciale</h1>\n <p>{% if c and c.civility is defined and c.civility %}{{ c.civility }},{% else %}Madame, Monsieur,{% endif %}</p>\n <p>Nous vous remercions de l’intérêt que vous portez à la marque YANIGAV et à ses produits. Suite à votre récent appel téléphonique, voici notre proposition pour un <strong>{{ quote.name|default('Enfonce-pieux HYDROCHOC HPG 790') }}</strong> correspondant à votre demande.</p>\n {% if quote.priceListRef is defined and quote.priceListRef %}\n <p class="muted">{{ quote.priceListRef }}</p>\n {% else %}\n <p class="muted">Tarif — {{ (quote.createdAt|default('now'))|date('Y') }}</p>\n {% endif %}\n </div>\n </div>\n \n <!-- OFFRE PRINCIPALE -->\n <div class="section">\n <div class="card">\n <h2>Offre principale</h2>\n <table>\n <thead>\n <tr>\n <th>Désignation</th>\n <th>Référence</th>\n <th>Prix unitaire HT</th>\n </tr>\n </thead>\n <tbody>\n {% set pu = (mainLine and mainLine.unitPriceExclVat is defined) ? mainLine.unitPriceExclVat : (total_ht_before_discount > 0 ? total_ht_before_discount : 0) %}\n <tr>\n <td>{{ (mainLine and mainLine.name is defined and mainLine.name) ? mainLine.name : quote.name }}</td>\n <td>{{ (mainLine and mainLine.reference is defined and mainLine.reference) ? mainLine.reference : '—' }}</td>\n <td>{{ pu|number_format(0, ',', ' ') }} €</td>\n </tr>\n </tbody>\n </table>\n {% set note = 'Cinématique unique sur le marché — un véritable atout dans les terrains compliqués.' %}\n <p class="note" style="margin-top:.75rem">{{ note }}</p>\n </div>\n </div>\n \n {# ==== DESCRIPTION / ÉQUIPEMENT / FORMATION / OPTIONS ==== #}\n {% set description = (mainLine and mainLine.description is defined and mainLine.description) ? mainLine.description : '' %}\n {% set description = description|replace({'•':'\n',';':'\n'}) %}\n {% set descList = description|split('\n') %}\n \n <div class="section grid-2">\n <div class="card">\n <h2>Points forts</h2>\n {% set hasPoint = false %}\n <ul class="cols-3">\n {% for item in descList %}\n {% set t = item|trim %}\n {% if t != '' %}\n {% set hasPoint = true %}\n <li>{{ t }}</li>\n {% endif %}\n {% endfor %}\n </ul>\n {% if not hasPoint %}\n <p class="muted">Aucun détail technique renseigné pour cet article.</p>\n {% endif %}\n </div>\n \n <div class="card">\n <h2>Équipement de série</h2>\n {% set printedEquip = false %}\n {# 1) Liste explicite mainLine.features si fournie #}\n {% if mainLine and mainLine.features is defined and mainLine.features %}\n <ul>\n {% for f in mainLine.features %}\n <li>{{ f }}</li>\n {% set printedEquip = true %}\n {% endfor %}\n </ul>\n {% endif %}\n \n {# 2) Sinon, tentative d’extraction depuis descList avec mots-clés #}\n {% if not printedEquip %}\n {% set equipList = [] %}\n {% for item in descList %}\n {% set t = item|trim %}\n {% if t matches '/(équipement|equipement|de série|serie)/i' %}\n {% set equipList = equipList|merge([t]) %}\n {% endif %}\n {% endfor %}\n {% if equipList %}\n <ul>\n {% for f in equipList %}<li>{{ f }}</li>{% endfor %}\n </ul>\n {% set printedEquip = true %}\n {% endif %}\n {% endif %}\n \n {% if not printedEquip %}\n <p class="muted">Aucun équipement de série spécifié.</p>\n {% endif %}\n \n {% if formationLine %}\n <h2 style="margin-top:1rem">Formation / Mise en route</h2>\n <p><strong>{{ formationLine.name|default('Formation / Mise en route') }}</strong> – Prix net :\n {{ (formationLine.totalExclVat|default(formationLine.unitPriceExclVat|default(0)))|number_format(0, ',', ' ') }} € HT</p>\n {% if formationLine.description is defined and formationLine.description %}<p class="muted">{{ formationLine.description }}</p>{% endif %}\n {% endif %}\n \n {% if options %}\n <h2 style="margin-top:1rem">Équipements recommandés</h2>\n <ul>\n {% for opt in options %}\n {% set q = opt.quantity|default(1) %}\n {% set puo = opt.unitPriceExclVat|default(0) %}\n {% set rem = opt.discountPercent|default(0) %}\n {% set opt_total = opt.totalExclVat|default(q * puo * (1 - (rem / 100))) %}\n <li>{{ opt.name }} — {{ opt_total|number_format(0, ',', ' ') }} € HT</li>\n {% endfor %}\n </ul>\n {% endif %}\n </div>\n </div>\n \n <!-- CONDITIONS COMMERCIALES -->\n <div class="section">\n <div class="card">\n <h2>Conditions commerciales</h2>\n <ul>\n {% if quote.expiredAt is defined and quote.expiredAt %}<li>Validité de l’offre : 1 mois (jusqu’au {{ quote.expiredAt|date('d/m/Y') }})</li>{% else %}<li>Validité de l’offre : 1 mois</li>{% endif %}\n {% if discount_value > 0 %}<li>Remise de service : {{ discount_percent|round(0, 'floor') }} %</li>{% endif %}\n {% if quote.orderContext is defined and quote.orderContext %}<li>{{ quote.orderContext }}</li>{% endif %}\n <li>Règlement {{ quote.paymentMode|default('30 jours nets par LCR') }}</li>\n <li>Délai : {{ quote.leadTime|default('2 à 3 mois après commande') }}</li>\n {% if quote.shippingFeesHt is defined %}\n {% if quote.shippingFeesHt == 0 %}<li>Port franco</li>\n {% elseif quote.shippingFeesHt > 0 %}<li>Frais de port : {{ quote.shippingFeesHt|number_format(2, ',', ' ') }} € HT</li>\n {% else %}<li>Port : {{ quote.shippingMode|default('selon conditions') }}</li>\n {% endif %}\n {% else %}\n <li>Port : {{ quote.shippingMode|default('selon conditions') }}</li>\n {% endif %}\n {% if quote.customerRef is defined and quote.customerRef %}<li>Réf. client : {{ quote.customerRef }}</li>{% endif %}\n </ul>\n </div>\n </div>\n \n <!-- SIGNATURES -->\n <div class="section grid-2">\n <div class="card">\n <h2>Signataires</h2>\n <p>\n <strong>{{ managedBy is defined and managedBy.fullname is defined ? managedBy.fullname : (quote.managedByRealName|default('')) }}</strong>\n – {{ managedBy is defined and managedBy.role is defined and managedBy.role ? managedBy.role : 'Resp. Commercial' }}\n {% if tel_portable %} – {{ tel_portable }}{% endif %}\n </p>\n <div class="signature">Signature expéditeur</div>\n </div>\n <div class="card">\n <h2>Bon pour accord</h2>\n <p><strong>{{ quote.contactIdRealName|default(c and (c.fullname is defined and c.fullname ? c.fullname : (c.name|default('')))) }}</strong>{% if comp and comp.name is defined and comp.name %} – {{ comp.name }}{% endif %}</p>\n <div class="signature">Cachet et signature</div>\n </div>\n </div>\n \n <!-- PIED -->\n <footer>\n YANIGAV – Enfonce-pieux • Affûte-piquet • Fendeuse de bûche — RCS ROANNE B 403 872 724 — SIRET 403 872 724 00014 — APE 4661Z — TVA FR114038727224\n </footer>\n </div>\n \n {# PAGE 2 : CGV (optionnelle) #}\n {% if cgv is defined or quote.cgvText is defined %}\n <div style="page-break-before:always;"></div>\n <div class="page">\n <div class="section">\n <div class="card">\n <h2>Conditions Générales de Vente</h2>\n <div class="note" style="white-space:pre-wrap">\n {{ cgv|default(quote.cgvText)|raw }}\n </div>\n </div>\n </div>\n <footer>\n Document généré automatiquement — valable sous réserve des conditions précisées ci-dessus.\n </footer>\n </div>\n {% endif %}\n </body>\n </html> """ -createdBy: null -updatedBy: null -createdAt: null -updatedAt: null #shouldNormalizeAsIRI: false } |
| id | "f47ef469dac34bc29180feb40a25724c" |
| previous_data | App\Model\Template\Template {#438 -id: "f47ef469dac34bc29180feb40a25724c" -customerId: "customer_121" -name: "Test" -content: """ <!doctype html>\n <html lang="fr">\n <meta charset="utf-8">\n <meta name="viewport" content="width=device-width, initial-scale=1">\n <title>Devis – YANIGAV – {{ quote.name|default('Enfonce-pieux HYDROCHOC HPG 790') }}</title>\n <style>\n :root { --primary:#0f172a; --muted:#475569; --border:#e2e8f0; --bg:#f8fafc; }\n html, body { margin:0; padding:0; background:var(--bg); color:#0b1220; font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Helvetica,Arial,"Apple Color Emoji","Segoe UI Emoji"; }\n .page { max-width:900px; margin:2rem auto; background:#fff; border:1px solid var(--border); border-radius:12px; overflow:hidden; box-shadow:0 10px 30px rgba(0,0,0,.04); }\n header { padding:1.25rem 1.5rem; background:#fff; border-bottom:1px solid var(--border); display:flex; gap:1rem; align-items:center; }\n .brand { font-weight:700; letter-spacing:.2px; font-size:1rem; color:var(--primary); }\n .sub { color:var(--muted); font-size:.9rem; }\n .grid-2 { display:grid; grid-template-columns:1fr 1fr; gap:1rem; }\n .section { padding:1.25rem 1.5rem; }\n h1 { font-size:1.4rem; margin:.25rem 0 .5rem; letter-spacing:.2px; }\n h2 { font-size:1.1rem; margin:0 0 .75rem; color:var(--primary); }\n p { margin:.25rem 0; line-height:1.55; }\n .card { background:#fff; border:1px solid var(--border); border-radius:10px; padding:1rem; }\n .muted { color:var(--muted); }\n .kvs { display:grid; grid-template-columns:1fr 1fr; gap:.5rem 1rem; font-size:.95rem; }\n .kvs div { display:flex; align-items:center; gap:.5rem; }\n .pill { font-size:.8rem; padding:.15rem .5rem; border:1px solid var(--border); border-radius:999px; background:#f1f5f9; }\n table { width:100%; border-collapse:collapse; }\n th, td { border:1px solid var(--border); padding:.6rem .5rem; text-align:left; vertical-align:top; }\n thead th { background:#f1f5f9; }\n tfoot td { font-weight:600; }\n .note { font-size:.92rem; background:#f8fafc; border:1px dashed var(--border); padding:.75rem; border-radius:8px; }\n .cols-3 { columns:2; column-gap:1rem; }\n .signature { height:80px; border:1px dashed var(--border); border-radius:10px; display:flex; align-items:center; justify-content:center; color:var(--muted); }\n footer { padding:1rem 1.5rem; border-top:1px solid var(--border); color:var(--muted); font-size:.9rem; background:#fff; }\n </style>\n \n <body>\n <div class="page">\n \n {# ==== Raccourcis / sécurisation des accès ==== #}\n {% set c = (quote.prospect is defined and quote.prospect.contact is defined) ? quote.prospect.contact : null %}\n {% set a = (c and c.mainAddress is defined) ? c.mainAddress : null %}\n {% set comp = (quote.prospect is defined and quote.prospect.company is defined) ? quote.prospect.company : null %}\n {% set lines = quote.quoteLines|default([]) %}\n \n {# Portable du commercial : on cherche dans un ordre sûr #}\n {% set tel_portable = '' %}\n {% if managedBy is defined %}\n {% if managedBy.phoneNumber is defined and managedBy.phoneNumber %}{% set tel_portable = managedBy.phoneNumber %}\n {% elseif managedBy.mobilePhone is defined and managedBy.mobilePhone %}{% set tel_portable = managedBy.mobilePhone %}\n {% elseif managedBy.phone is defined and managedBy.phone %}{% set tel_portable = managedBy.phone %}\n {% endif %}\n {% endif %}\n \n {# ==== Totaux/remise/TVA - robustes ==== #}\n {% set total_ht_before_discount = 0 %}\n {% for l in lines %}\n {% set q = l.quantity|default(1) %}\n {% set pu = l.unitPriceExclVat|default(0) %}\n {% set total_ht_before_discount = total_ht_before_discount + (q * pu) %}\n {% endfor %}\n {% if total_ht_before_discount == 0 %}\n {% set total_ht_before_discount = quote.totalExcludingVat|default(0) %}\n {% endif %}\n {% set total_ht = quote.totalExcludingVat|default(total_ht_before_discount) %}\n {% set discount_value = total_ht_before_discount - total_ht %}\n {% set discount_percent = total_ht_before_discount > 0 ? (discount_value / total_ht_before_discount * 100) : 0 %}\n {% set vat_total = 0 %}\n {% for l in lines %}\n {% set vat_total = vat_total + (l.vatAmount|default(0)) %}\n {% endfor %}\n \n {# ==== Sélection ligne principale / formation / options (sans filtres avancés) ==== #}\n {% set first = (lines[0] is defined) ? lines[0] : null %}\n {% set mainLine = null %}\n {% set formationLine = null %}\n {% set options = [] %}\n {% for l in lines %}\n {% set ref = l.reference|default('')|lower %}\n {% set isOpt = l.isOptional is defined and l.isOptional %}\n {% if mainLine is null and not isOpt and ('formation' not in ref) %}\n {% set mainLine = l %}\n {% endif %}\n {% if formationLine is null and ('formation' in ref) %}\n {% set formationLine = l %}\n {% endif %}\n {% if isOpt %}\n {% set options = options|merge([l]) %}\n {% endif %}\n {% endfor %}\n {% if mainLine is null %}{% set mainLine = first %}{% endif %}\n \n <!-- HEADER -->\n <header>\n <div style="flex:1">\n <div class="brand">YANIGAV – Enfonce-pieux • Affûte-piquet • Fendeuse de bûche</div>\n <div class="sub">RCS ROANNE B 403 872 724 • SIRET 403 872 724 00014 • APE 4661Z • TVA FR114038727224</div>\n </div>\n <div class="pill">{{ (quote.createdAt|default('now'))|date('d F Y') }}</div>\n </header>\n \n <!-- COORDONNÉES -->\n <div class="section grid-2">\n <div class="card">\n <h2>Expéditeur</h2>\n <p><strong>YANIGAV</strong></p>\n <p>De la part de <strong>{{ managedBy is defined and managedBy.fullname is defined ? managedBy.fullname : (quote.managedByRealName|default('')) }}</strong> ({{ managedBy is defined and managedBy.role is defined and managedBy.role ? managedBy.role : 'Resp. Commercial' }})</p>\n <div class="kvs">\n <div><span class="pill">Tél</span> {{ managedBy is defined and managedBy.phone is defined and managedBy.phone ? managedBy.phone : '—' }}</div>\n {% if tel_portable %}\n <div><span class="pill">Port</span> {{ tel_portable }}</div>\n {% endif %}\n <div><span class="pill">Email</span>\n {% if managedBy is defined and managedBy.email is defined and managedBy.email %}\n <a href="mailto:{{ managedBy.email }}">{{ managedBy.email }}</a>\n {% else %}—{% endif %}\n </div>\n </div>\n </div>\n <div class="card">\n <h2>Destinataire</h2>\n <p><strong>{{ quote.contactIdRealName|default(c and (c.fullname is defined and c.fullname ? c.fullname : (c.name|default('')))) }}</strong></p>\n {% if comp and comp.name is defined and comp.name %}<p><strong>{{ comp.name }}</strong></p>{% endif %}\n {% if a and (a.postalCode is defined or a.city is defined) %}<p class="muted">{{ a.postalCode|default('') }} {{ a.city|default('') }}</p>{% endif %}\n </div>\n </div>\n \n <!-- INTRO -->\n <div class="section">\n <div class="card">\n <h1>Proposition commerciale</h1>\n <p>{% if c and c.civility is defined and c.civility %}{{ c.civility }},{% else %}Madame, Monsieur,{% endif %}</p>\n <p>Nous vous remercions de l’intérêt que vous portez à la marque YANIGAV et à ses produits. Suite à votre récent appel téléphonique, voici notre proposition pour un <strong>{{ quote.name|default('Enfonce-pieux HYDROCHOC HPG 790') }}</strong> correspondant à votre demande.</p>\n {% if quote.priceListRef is defined and quote.priceListRef %}\n <p class="muted">{{ quote.priceListRef }}</p>\n {% else %}\n <p class="muted">Tarif — {{ (quote.createdAt|default('now'))|date('Y') }}</p>\n {% endif %}\n </div>\n </div>\n \n <!-- OFFRE PRINCIPALE -->\n <div class="section">\n <div class="card">\n <h2>Offre principale</h2>\n <table>\n <thead>\n <tr>\n <th>Désignation</th>\n <th>Référence</th>\n <th>Prix unitaire HT</th>\n </tr>\n </thead>\n <tbody>\n {% set pu = (mainLine and mainLine.unitPriceExclVat is defined) ? mainLine.unitPriceExclVat : (total_ht_before_discount > 0 ? total_ht_before_discount : 0) %}\n <tr>\n <td>{{ (mainLine and mainLine.name is defined and mainLine.name) ? mainLine.name : quote.name }}</td>\n <td>{{ (mainLine and mainLine.reference is defined and mainLine.reference) ? mainLine.reference : '—' }}</td>\n <td>{{ pu|number_format(0, ',', ' ') }} €</td>\n </tr>\n </tbody>\n </table>\n {% set note = (mainLine and mainLine.description is defined and mainLine.description) ? mainLine.description : 'Cinématique unique sur le marché — un véritable atout dans les terrains compliqués.' %}\n <p class="note" style="margin-top:.75rem">{{ note }}</p>\n </div>\n </div>\n \n {# ==== DESCRIPTION / ÉQUIPEMENT / FORMATION / OPTIONS ==== #}\n {% set description = (mainLine and mainLine.description is defined and mainLine.description) ? mainLine.description : '' %}\n {% set description = description|replace({'•':'\n',';':'\n'}) %}\n {% set descList = description|split('\n') %}\n \n <div class="section grid-2">\n <div class="card">\n <h2>Points forts</h2>\n {% set hasPoint = false %}\n <ul class="cols-3">\n {% for item in descList %}\n {% set t = item|trim %}\n {% if t != '' %}\n {% set hasPoint = true %}\n <li>{{ t }}</li>\n {% endif %}\n {% endfor %}\n </ul>\n {% if not hasPoint %}\n <p class="muted">Aucun détail technique renseigné pour cet article.</p>\n {% endif %}\n </div>\n \n <div class="card">\n <h2>Équipement de série</h2>\n {% set printedEquip = false %}\n {# 1) Liste explicite mainLine.features si fournie #}\n {% if mainLine and mainLine.features is defined and mainLine.features %}\n <ul>\n {% for f in mainLine.features %}\n <li>{{ f }}</li>\n {% set printedEquip = true %}\n {% endfor %}\n </ul>\n {% endif %}\n \n {# 2) Sinon, tentative d’extraction depuis descList avec mots-clés #}\n {% if not printedEquip %}\n {% set equipList = [] %}\n {% for item in descList %}\n {% set t = item|trim %}\n {% if t matches '/(équipement|equipement|de série|serie)/i' %}\n {% set equipList = equipList|merge([t]) %}\n {% endif %}\n {% endfor %}\n {% if equipList %}\n <ul>\n {% for f in equipList %}<li>{{ f }}</li>{% endfor %}\n </ul>\n {% set printedEquip = true %}\n {% endif %}\n {% endif %}\n \n {% if not printedEquip %}\n <p class="muted">Aucun équipement de série spécifié.</p>\n {% endif %}\n \n {% if formationLine %}\n <h2 style="margin-top:1rem">Formation / Mise en route</h2>\n <p><strong>{{ formationLine.name|default('Formation / Mise en route') }}</strong> – Prix net :\n {{ (formationLine.totalExclVat|default(formationLine.unitPriceExclVat|default(0)))|number_format(0, ',', ' ') }} € HT</p>\n {% if formationLine.description is defined and formationLine.description %}<p class="muted">{{ formationLine.description }}</p>{% endif %}\n {% endif %}\n \n {% if options %}\n <h2 style="margin-top:1rem">Équipements recommandés</h2>\n <ul>\n {% for opt in options %}\n {% set q = opt.quantity|default(1) %}\n {% set puo = opt.unitPriceExclVat|default(0) %}\n {% set rem = opt.discountPercent|default(0) %}\n {% set opt_total = opt.totalExclVat|default(q * puo * (1 - (rem / 100))) %}\n <li>{{ opt.name }} — {{ opt_total|number_format(0, ',', ' ') }} € HT</li>\n {% endfor %}\n </ul>\n {% endif %}\n </div>\n </div>\n \n <!-- CONDITIONS COMMERCIALES -->\n <div class="section">\n <div class="card">\n <h2>Conditions commerciales</h2>\n <ul>\n {% if quote.expiredAt is defined and quote.expiredAt %}<li>Validité de l’offre : 1 mois (jusqu’au {{ quote.expiredAt|date('d/m/Y') }})</li>{% else %}<li>Validité de l’offre : 1 mois</li>{% endif %}\n {% if discount_value > 0 %}<li>Remise de service : {{ discount_percent|round(0, 'floor') }} %</li>{% endif %}\n {% if quote.orderContext is defined and quote.orderContext %}<li>{{ quote.orderContext }}</li>{% endif %}\n <li>Règlement {{ quote.paymentMode|default('30 jours nets par LCR') }}</li>\n <li>Délai : {{ quote.leadTime|default('2 à 3 mois après commande') }}</li>\n {% if quote.shippingFeesHt is defined %}\n {% if quote.shippingFeesHt == 0 %}<li>Port franco</li>\n {% elseif quote.shippingFeesHt > 0 %}<li>Frais de port : {{ quote.shippingFeesHt|number_format(2, ',', ' ') }} € HT</li>\n {% else %}<li>Port : {{ quote.shippingMode|default('selon conditions') }}</li>\n {% endif %}\n {% else %}\n <li>Port : {{ quote.shippingMode|default('selon conditions') }}</li>\n {% endif %}\n {% if quote.customerRef is defined and quote.customerRef %}<li>Réf. client : {{ quote.customerRef }}</li>{% endif %}\n </ul>\n </div>\n </div>\n \n <!-- SIGNATURES -->\n <div class="section grid-2">\n <div class="card">\n <h2>Signataires</h2>\n <p>\n <strong>{{ managedBy is defined and managedBy.fullname is defined ? managedBy.fullname : (quote.managedByRealName|default('')) }}</strong>\n – {{ managedBy is defined and managedBy.role is defined and managedBy.role ? managedBy.role : 'Resp. Commercial' }}\n {% if tel_portable %} – {{ tel_portable }}{% endif %}\n </p>\n <div class="signature">Signature expéditeur</div>\n </div>\n <div class="card">\n <h2>Bon pour accord</h2>\n <p><strong>{{ quote.contactIdRealName|default(c and (c.fullname is defined and c.fullname ? c.fullname : (c.name|default('')))) }}</strong>{% if comp and comp.name is defined and comp.name %} – {{ comp.name }}{% endif %}</p>\n <div class="signature">Cachet et signature</div>\n </div>\n </div>\n \n <!-- PIED -->\n <footer>\n YANIGAV – Enfonce-pieux • Affûte-piquet • Fendeuse de bûche — RCS ROANNE B 403 872 724 — SIRET 403 872 724 00014 — APE 4661Z — TVA FR114038727224\n </footer>\n </div>\n \n {# PAGE 2 : CGV (optionnelle) #}\n {% if cgv is defined or quote.cgvText is defined %}\n <div style="page-break-before:always;"></div>\n <div class="page">\n <div class="section">\n <div class="card">\n <h2>Conditions Générales de Vente</h2>\n <div class="note" style="white-space:pre-wrap">\n {{ cgv|default(quote.cgvText)|raw }}\n </div>\n </div>\n </div>\n <footer>\n Document généré automatiquement — valable sous réserve des conditions précisées ci-dessus.\n </footer>\n </div>\n {% endif %}\n </body>\n </html> """ -createdBy: null -updatedBy: null -createdAt: null -updatedAt: null #shouldNormalizeAsIRI: false } |
Request Headers
| Header | Value |
|---|---|
| accept | "application/ld+json" |
| accept-encoding | "gzip, deflate, br, zstd" |
| accept-language | "fr-FR,fr;q=0.9,en-US;q=0.8,en;q=0.7" |
| connection | "close" |
| content-length | "15077" |
| content-type | "application/json" |
| host | "dev.app.pol-crm.com" |
| origin | "https://dev.pol-crm.com" |
| priority | "u=1, i" |
| referer | "https://dev.pol-crm.com/" |
| sec-ch-ua | ""Chromium";v="140", "Not=A?Brand";v="24", "Google Chrome";v="140"" |
| sec-ch-ua-mobile | "?0" |
| sec-ch-ua-platform | ""Windows"" |
| sec-fetch-dest | "empty" |
| sec-fetch-mode | "cors" |
| sec-fetch-site | "same-site" |
| user-agent | "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/140.0.0.0 Safari/537.36" |
| x-accel-internal | "/internal-nginx-static-location" |
| x-php-ob-level | "1" |
| x-pol-auth | "Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiJ9.eyJpYXQiOjE3NjA5MTI0NDEsImV4cCI6MTc2MDkxNjA0MSwicm9sZXMiOlsiUk9MRV9VU0VSIiwiUk9MRV9TVVBFUkFETUlOIiwiUk9MRV9BRE1JTiIsIlJPTEVfTU9EVUxFX1BST0RVQ1QiLCJST0xFX01PRFVMRV9QUk9EVUNUX0NVU1RPTUlaRSIsIlJPTEVfTU9EVUxFX1FVT1RFX0xJTkUiLCJQUk9TUEVDVF9TSE9XIiwiUFJPU1BFQ1RfQ1VEIiwiQ09OVEFDVF9DVUQiLCJDT05UQUNUX1NIT1ciLCJUQVNLX1NIT1ciLCJUQVNLX0NVRCIsIlFVT1RFX1NIT1ciLCJRVU9URV9DVUQiLCJRVU9URV9SRUdFTkVSQVRFX1BSSUNFUyJdLCJsb2dpbiI6ImRlbW95YW5pZ2F2IiwidXNlcl9pZCI6InVzZXJfMTAxMSIsInVzZXJfZXh0ZXJuYWxfaWQiOiIxMDExIiwiZW1haWwiOiJnLXNhdXRyb25Ac2ZpLmZyIiwiY3VzdG9tZXJfaWQiOiJjdXN0b21lcl8xMjEiLCJjdXN0b21lcl9uYW1lIjoiWUFOSUdBViIsImN1c3RvbWVyX2V4dGVybmFsX2lkIjoiMTIxIiwiY3VzdG9tZXJfbWFpbGluZ19pZCI6IjE0NyIsImZpcnN0bmFtZSI6Ikd1aWxsYXVtZSIsImxhc3RuYW1lIjoiU0FVVFJPTiIsImxpdmVvTG9naW4iOm51bGwsImxpdmVvUGFzc3dvcmQiOm51bGwsImhhc0ludHJhbmV0IjpmYWxzZSwibGFuZ3VhZ2UiOiJGUiIsInNlY3Rpb25zX2xlYWRlZCI6W10sInNlY3Rpb25zX21lbWJlcnMiOlsidXNlcl8xMDExIl0sImlzX3NlY3Rpb25zX2FjdGl2YXRlZCI6ZmFsc2UsInJlZnJlc2hfdG9rZW4iOiIifQ.smruhTDO6MF4efpXGiPp4DyZoLSpsUh3ykwBDmscLGtkvlySQlnSFvS1bxozG8T5Y0oGdkijvDiliogWK_zhqLF6FXho-oEscgCbKhvTjdosGLc4QHX0QAtM1LeVpT3BGVz9isHY1J7X0RDnoWA2GdCwCZ-ELXlS7fP08w_Mc5j8GqGhN5XwD70MLfR5ltD75o5BEhCWKMsWsatkGs3bbd7AfjhqoSz7qexpiHj1BRszq-H5QekWiJWgwOLDUJc85rZYaNVbYu75qseEbKfW-kWAxOZhAZCmVfFDQ-qBxSJ1i7KwVasIGTJDTnJn7l8fDqFWF0jGtC4LJzQEOZDjoOrQVaP2szLusNdOeKICnE3GOpY7E2sHIJpbTf8KlRUSm0uKc4t4hgoSRxnCdQGLx4hcTGSGHyITgso7tVs6068piCfp8JttEo5SoXERPiVNl2oeKa7VQAgtUWMzPI-SYX6QfGCjnrYE3JcTufx8xFtvlS4pmeIaLNJs7Y8l21f-A8MB7y-3zOAzriYExuKUOtT9oZ0GRtCWG5oTUyQ2LI4IjzaqBW_ikRfcccdSOZqZxV_FVw1fO9vPg9Lgi9XKAfKtjCLtI9nMboiZsSk9mx5_CAREqtb476hnnUVOfvHCBazVRQo-FWsSSWNLCIe8MtR9pUny0D8hn5qCQ712Axk" |
| x-real-ip | "176.174.157.21" |
| x-transaction-id | "front:zv9jvbn66i" |
Request Content
Pretty
{
"id": "f47ef469dac34bc29180feb40a25724c",
"customerId": "customer_121",
"name": "Test",
"content": "<!doctype html>\n<html lang=\"fr\">\n<meta charset=\"utf-8\">\n<meta name=\"viewport\" content=\"width=device-width, initial-scale=1\">\n<title>Devis \u2013 YANIGAV \u2013 {{ quote.name|default('Enfonce-pieux HYDROCHOC HPG 790') }}<\/title>\n<style>\n :root { --primary:#0f172a; --muted:#475569; --border:#e2e8f0; --bg:#f8fafc; }\n html, body { margin:0; padding:0; background:var(--bg); color:#0b1220; font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Helvetica,Arial,\"Apple Color Emoji\",\"Segoe UI Emoji\"; }\n .page { max-width:900px; margin:2rem auto; background:#fff; border:1px solid var(--border); border-radius:12px; overflow:hidden; box-shadow:0 10px 30px rgba(0,0,0,.04); }\n header { padding:1.25rem 1.5rem; background:#fff; border-bottom:1px solid var(--border); display:flex; gap:1rem; align-items:center; }\n .brand { font-weight:700; letter-spacing:.2px; font-size:1rem; color:var(--primary); }\n .sub { color:var(--muted); font-size:.9rem; }\n .grid-2 { display:grid; grid-template-columns:1fr 1fr; gap:1rem; }\n .section { padding:1.25rem 1.5rem; }\n h1 { font-size:1.4rem; margin:.25rem 0 .5rem; letter-spacing:.2px; }\n h2 { font-size:1.1rem; margin:0 0 .75rem; color:var(--primary); }\n p { margin:.25rem 0; line-height:1.55; }\n .card { background:#fff; border:1px solid var(--border); border-radius:10px; padding:1rem; }\n .muted { color:var(--muted); }\n .kvs { display:grid; grid-template-columns:1fr 1fr; gap:.5rem 1rem; font-size:.95rem; }\n .kvs div { display:flex; align-items:center; gap:.5rem; }\n .pill { font-size:.8rem; padding:.15rem .5rem; border:1px solid var(--border); border-radius:999px; background:#f1f5f9; }\n table { width:100%; border-collapse:collapse; }\n th, td { border:1px solid var(--border); padding:.6rem .5rem; text-align:left; vertical-align:top; }\n thead th { background:#f1f5f9; }\n tfoot td { font-weight:600; }\n .note { font-size:.92rem; background:#f8fafc; border:1px dashed var(--border); padding:.75rem; border-radius:8px; }\n .cols-3 { columns:2; column-gap:1rem; }\n .signature { height:80px; border:1px dashed var(--border); border-radius:10px; display:flex; align-items:center; justify-content:center; color:var(--muted); }\n footer { padding:1rem 1.5rem; border-top:1px solid var(--border); color:var(--muted); font-size:.9rem; background:#fff; }\n<\/style>\n\n<body>\n<div class=\"page\">\n\n {# ==== Raccourcis \/ s\u00e9curisation des acc\u00e8s ==== #}\n {% set c = (quote.prospect is defined and quote.prospect.contact is defined) ? quote.prospect.contact : null %}\n {% set a = (c and c.mainAddress is defined) ? c.mainAddress : null %}\n {% set comp = (quote.prospect is defined and quote.prospect.company is defined) ? quote.prospect.company : null %}\n {% set lines = quote.quoteLines|default([]) %}\n\n {# Portable du commercial : on cherche dans un ordre s\u00fbr #}\n {% set tel_portable = '' %}\n {% if managedBy is defined %}\n {% if managedBy.phoneNumber is defined and managedBy.phoneNumber %}{% set tel_portable = managedBy.phoneNumber %}\n {% elseif managedBy.mobilePhone is defined and managedBy.mobilePhone %}{% set tel_portable = managedBy.mobilePhone %}\n {% elseif managedBy.phone is defined and managedBy.phone %}{% set tel_portable = managedBy.phone %}\n {% endif %}\n {% endif %}\n\n {# ==== Totaux\/remise\/TVA - robustes ==== #}\n {% set total_ht_before_discount = 0 %}\n {% for l in lines %}\n {% set q = l.quantity|default(1) %}\n {% set pu = l.unitPriceExclVat|default(0) %}\n {% set total_ht_before_discount = total_ht_before_discount + (q * pu) %}\n {% endfor %}\n {% if total_ht_before_discount == 0 %}\n {% set total_ht_before_discount = quote.totalExcludingVat|default(0) %}\n {% endif %}\n {% set total_ht = quote.totalExcludingVat|default(total_ht_before_discount) %}\n {% set discount_value = total_ht_before_discount - total_ht %}\n {% set discount_percent = total_ht_before_discount > 0 ? (discount_value \/ total_ht_before_discount * 100) : 0 %}\n {% set vat_total = 0 %}\n {% for l in lines %}\n {% set vat_total = vat_total + (l.vatAmount|default(0)) %}\n {% endfor %}\n\n {# ==== S\u00e9lection ligne principale \/ formation \/ options (sans filtres avanc\u00e9s) ==== #}\n {% set first = (lines[0] is defined) ? lines[0] : null %}\n {% set mainLine = null %}\n {% set formationLine = null %}\n {% set options = [] %}\n {% for l in lines %}\n {% set ref = l.reference|default('')|lower %}\n {% set isOpt = l.isOptional is defined and l.isOptional %}\n {% if mainLine is null and not isOpt and ('formation' not in ref) %}\n {% set mainLine = l %}\n {% endif %}\n {% if formationLine is null and ('formation' in ref) %}\n {% set formationLine = l %}\n {% endif %}\n {% if isOpt %}\n {% set options = options|merge([l]) %}\n {% endif %}\n {% endfor %}\n {% if mainLine is null %}{% set mainLine = first %}{% endif %}\n\n <!-- HEADER -->\n <header>\n <div style=\"flex:1\">\n <div class=\"brand\">YANIGAV \u2013 Enfonce-pieux \u2022 Aff\u00fbte-piquet \u2022 Fendeuse de b\u00fbche<\/div>\n <div class=\"sub\">RCS ROANNE B 403 872 724 \u2022 SIRET 403 872 724 00014 \u2022 APE 4661Z \u2022 TVA FR114038727224<\/div>\n <\/div>\n <div class=\"pill\">{{ (quote.createdAt|default('now'))|date('d F Y') }}<\/div>\n <\/header>\n\n <!-- COORDONN\u00c9ES -->\n <div class=\"section grid-2\">\n <div class=\"card\">\n <h2>Exp\u00e9diteur<\/h2>\n <p><strong>YANIGAV<\/strong><\/p>\n <p>De la part de <strong>{{ managedBy is defined and managedBy.fullname is defined ? managedBy.fullname : (quote.managedByRealName|default('')) }}<\/strong> ({{ managedBy is defined and managedBy.role is defined and managedBy.role ? managedBy.role : 'Resp. Commercial' }})<\/p>\n <div class=\"kvs\">\n <div><span class=\"pill\">T\u00e9l<\/span> {{ managedBy is defined and managedBy.phone is defined and managedBy.phone ? managedBy.phone : '\u2014' }}<\/div>\n {% if tel_portable %}\n <div><span class=\"pill\">Port<\/span> {{ tel_portable }}<\/div>\n {% endif %}\n <div><span class=\"pill\">Email<\/span>\n {% if managedBy is defined and managedBy.email is defined and managedBy.email %}\n <a href=\"mailto:{{ managedBy.email }}\">{{ managedBy.email }}<\/a>\n {% else %}\u2014{% endif %}\n <\/div>\n <\/div>\n <\/div>\n <div class=\"card\">\n <h2>Destinataire<\/h2>\n <p><strong>{{ quote.contactIdRealName|default(c and (c.fullname is defined and c.fullname ? c.fullname : (c.name|default('')))) }}<\/strong><\/p>\n {% if comp and comp.name is defined and comp.name %}<p><strong>{{ comp.name }}<\/strong><\/p>{% endif %}\n {% if a and (a.postalCode is defined or a.city is defined) %}<p class=\"muted\">{{ a.postalCode|default('') }} {{ a.city|default('') }}<\/p>{% endif %}\n <\/div>\n <\/div>\n\n <!-- INTRO -->\n <div class=\"section\">\n <div class=\"card\">\n <h1>Proposition commerciale<\/h1>\n <p>{% if c and c.civility is defined and c.civility %}{{ c.civility }},{% else %}Madame, Monsieur,{% endif %}<\/p>\n <p>Nous vous remercions de l\u2019int\u00e9r\u00eat que vous portez \u00e0 la marque YANIGAV et \u00e0 ses produits. Suite \u00e0 votre r\u00e9cent appel t\u00e9l\u00e9phonique, voici notre proposition pour un <strong>{{ quote.name|default('Enfonce-pieux HYDROCHOC HPG 790') }}<\/strong> correspondant \u00e0 votre demande.<\/p>\n {% if quote.priceListRef is defined and quote.priceListRef %}\n <p class=\"muted\">{{ quote.priceListRef }}<\/p>\n {% else %}\n <p class=\"muted\">Tarif \u2014 {{ (quote.createdAt|default('now'))|date('Y') }}<\/p>\n {% endif %}\n <\/div>\n <\/div>\n\n <!-- OFFRE PRINCIPALE -->\n <div class=\"section\">\n <div class=\"card\">\n <h2>Offre principale<\/h2>\n <table>\n <thead>\n <tr>\n <th>D\u00e9signation<\/th>\n <th>R\u00e9f\u00e9rence<\/th>\n <th>Prix unitaire HT<\/th>\n <\/tr>\n <\/thead>\n <tbody>\n {% set pu = (mainLine and mainLine.unitPriceExclVat is defined) ? mainLine.unitPriceExclVat : (total_ht_before_discount > 0 ? total_ht_before_discount : 0) %}\n <tr>\n <td>{{ (mainLine and mainLine.name is defined and mainLine.name) ? mainLine.name : quote.name }}<\/td>\n <td>{{ (mainLine and mainLine.reference is defined and mainLine.reference) ? mainLine.reference : '\u2014' }}<\/td>\n <td>{{ pu|number_format(0, ',', ' ') }} \u20ac<\/td>\n <\/tr>\n <\/tbody>\n <\/table>\n {% set note = 'Cin\u00e9matique unique sur le march\u00e9 \u2014 un v\u00e9ritable atout dans les terrains compliqu\u00e9s.' %}\n <p class=\"note\" style=\"margin-top:.75rem\">{{ note }}<\/p>\n <\/div>\n <\/div>\n\n {# ==== DESCRIPTION \/ \u00c9QUIPEMENT \/ FORMATION \/ OPTIONS ==== #}\n {% set description = (mainLine and mainLine.description is defined and mainLine.description) ? mainLine.description : '' %}\n {% set description = description|replace({'\u2022':'\\n',';':'\\n'}) %}\n {% set descList = description|split('\\n') %}\n\n <div class=\"section grid-2\">\n <div class=\"card\">\n <h2>Points forts<\/h2>\n {% set hasPoint = false %}\n <ul class=\"cols-3\">\n {% for item in descList %}\n {% set t = item|trim %}\n {% if t != '' %}\n {% set hasPoint = true %}\n <li>{{ t }}<\/li>\n {% endif %}\n {% endfor %}\n <\/ul>\n {% if not hasPoint %}\n <p class=\"muted\">Aucun d\u00e9tail technique renseign\u00e9 pour cet article.<\/p>\n {% endif %}\n <\/div>\n\n <div class=\"card\">\n <h2>\u00c9quipement de s\u00e9rie<\/h2>\n {% set printedEquip = false %}\n {# 1) Liste explicite mainLine.features si fournie #}\n {% if mainLine and mainLine.features is defined and mainLine.features %}\n <ul>\n {% for f in mainLine.features %}\n <li>{{ f }}<\/li>\n {% set printedEquip = true %}\n {% endfor %}\n <\/ul>\n {% endif %}\n\n {# 2) Sinon, tentative d\u2019extraction depuis descList avec mots-cl\u00e9s #}\n {% if not printedEquip %}\n {% set equipList = [] %}\n {% for item in descList %}\n {% set t = item|trim %}\n {% if t matches '\/(\u00e9quipement|equipement|de s\u00e9rie|serie)\/i' %}\n {% set equipList = equipList|merge([t]) %}\n {% endif %}\n {% endfor %}\n {% if equipList %}\n <ul>\n {% for f in equipList %}<li>{{ f }}<\/li>{% endfor %}\n <\/ul>\n {% set printedEquip = true %}\n {% endif %}\n {% endif %}\n\n {% if not printedEquip %}\n <p class=\"muted\">Aucun \u00e9quipement de s\u00e9rie sp\u00e9cifi\u00e9.<\/p>\n {% endif %}\n\n {% if formationLine %}\n <h2 style=\"margin-top:1rem\">Formation \/ Mise en route<\/h2>\n <p><strong>{{ formationLine.name|default('Formation \/ Mise en route') }}<\/strong> \u2013 Prix net :\n {{ (formationLine.totalExclVat|default(formationLine.unitPriceExclVat|default(0)))|number_format(0, ',', ' ') }} \u20ac HT<\/p>\n {% if formationLine.description is defined and formationLine.description %}<p class=\"muted\">{{ formationLine.description }}<\/p>{% endif %}\n {% endif %}\n\n {% if options %}\n <h2 style=\"margin-top:1rem\">\u00c9quipements recommand\u00e9s<\/h2>\n <ul>\n {% for opt in options %}\n {% set q = opt.quantity|default(1) %}\n {% set puo = opt.unitPriceExclVat|default(0) %}\n {% set rem = opt.discountPercent|default(0) %}\n {% set opt_total = opt.totalExclVat|default(q * puo * (1 - (rem \/ 100))) %}\n <li>{{ opt.name }} \u2014 {{ opt_total|number_format(0, ',', ' ') }} \u20ac HT<\/li>\n {% endfor %}\n <\/ul>\n {% endif %}\n <\/div>\n <\/div>\n\n <!-- CONDITIONS COMMERCIALES -->\n <div class=\"section\">\n <div class=\"card\">\n <h2>Conditions commerciales<\/h2>\n <ul>\n {% if quote.expiredAt is defined and quote.expiredAt %}<li>Validit\u00e9 de l\u2019offre : 1 mois (jusqu\u2019au {{ quote.expiredAt|date('d\/m\/Y') }})<\/li>{% else %}<li>Validit\u00e9 de l\u2019offre : 1 mois<\/li>{% endif %}\n {% if discount_value > 0 %}<li>Remise de service : {{ discount_percent|round(0, 'floor') }} %<\/li>{% endif %}\n {% if quote.orderContext is defined and quote.orderContext %}<li>{{ quote.orderContext }}<\/li>{% endif %}\n <li>R\u00e8glement {{ quote.paymentMode|default('30 jours nets par LCR') }}<\/li>\n <li>D\u00e9lai : {{ quote.leadTime|default('2 \u00e0 3 mois apr\u00e8s commande') }}<\/li>\n {% if quote.shippingFeesHt is defined %}\n {% if quote.shippingFeesHt == 0 %}<li>Port franco<\/li>\n {% elseif quote.shippingFeesHt > 0 %}<li>Frais de port : {{ quote.shippingFeesHt|number_format(2, ',', ' ') }} \u20ac HT<\/li>\n {% else %}<li>Port : {{ quote.shippingMode|default('selon conditions') }}<\/li>\n {% endif %}\n {% else %}\n <li>Port : {{ quote.shippingMode|default('selon conditions') }}<\/li>\n {% endif %}\n {% if quote.customerRef is defined and quote.customerRef %}<li>R\u00e9f. client : {{ quote.customerRef }}<\/li>{% endif %}\n <\/ul>\n <\/div>\n <\/div>\n\n <!-- SIGNATURES -->\n <div class=\"section grid-2\">\n <div class=\"card\">\n <h2>Signataires<\/h2>\n <p>\n <strong>{{ managedBy is defined and managedBy.fullname is defined ? managedBy.fullname : (quote.managedByRealName|default('')) }}<\/strong>\n \u2013 {{ managedBy is defined and managedBy.role is defined and managedBy.role ? managedBy.role : 'Resp. Commercial' }}\n {% if tel_portable %} \u2013 {{ tel_portable }}{% endif %}\n <\/p>\n <div class=\"signature\">Signature exp\u00e9diteur<\/div>\n <\/div>\n <div class=\"card\">\n <h2>Bon pour accord<\/h2>\n <p><strong>{{ quote.contactIdRealName|default(c and (c.fullname is defined and c.fullname ? c.fullname : (c.name|default('')))) }}<\/strong>{% if comp and comp.name is defined and comp.name %} \u2013 {{ comp.name }}{% endif %}<\/p>\n <div class=\"signature\">Cachet et signature<\/div>\n <\/div>\n <\/div>\n\n <!-- PIED -->\n <footer>\n YANIGAV \u2013 Enfonce-pieux \u2022 Aff\u00fbte-piquet \u2022 Fendeuse de b\u00fbche \u2014 RCS ROANNE B 403 872 724 \u2014 SIRET 403 872 724 00014 \u2014 APE 4661Z \u2014 TVA FR114038727224\n <\/footer>\n<\/div>\n\n{# PAGE 2 : CGV (optionnelle) #}\n{% if cgv is defined or quote.cgvText is defined %}\n <div style=\"page-break-before:always;\"><\/div>\n <div class=\"page\">\n <div class=\"section\">\n <div class=\"card\">\n <h2>Conditions G\u00e9n\u00e9rales de Vente<\/h2>\n <div class=\"note\" style=\"white-space:pre-wrap\">\n {{ cgv|default(quote.cgvText)|raw }}\n <\/div>\n <\/div>\n <\/div>\n <footer>\n Document g\u00e9n\u00e9r\u00e9 automatiquement \u2014 valable sous r\u00e9serve des conditions pr\u00e9cis\u00e9es ci-dessus.\n <\/footer>\n <\/div>\n{% endif %}\n<\/body>\n<\/html>\n"
}
Raw
{"id":"f47ef469dac34bc29180feb40a25724c","customerId":"customer_121","name":"Test","content":"<!doctype html>\n<html lang=\"fr\">\n<meta charset=\"utf-8\">\n<meta name=\"viewport\" content=\"width=device-width, initial-scale=1\">\n<title>Devis – YANIGAV – {{ quote.name|default('Enfonce-pieux HYDROCHOC HPG 790') }}</title>\n<style>\n :root { --primary:#0f172a; --muted:#475569; --border:#e2e8f0; --bg:#f8fafc; }\n html, body { margin:0; padding:0; background:var(--bg); color:#0b1220; font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Helvetica,Arial,\"Apple Color Emoji\",\"Segoe UI Emoji\"; }\n .page { max-width:900px; margin:2rem auto; background:#fff; border:1px solid var(--border); border-radius:12px; overflow:hidden; box-shadow:0 10px 30px rgba(0,0,0,.04); }\n header { padding:1.25rem 1.5rem; background:#fff; border-bottom:1px solid var(--border); display:flex; gap:1rem; align-items:center; }\n .brand { font-weight:700; letter-spacing:.2px; font-size:1rem; color:var(--primary); }\n .sub { color:var(--muted); font-size:.9rem; }\n .grid-2 { display:grid; grid-template-columns:1fr 1fr; gap:1rem; }\n .section { padding:1.25rem 1.5rem; }\n h1 { font-size:1.4rem; margin:.25rem 0 .5rem; letter-spacing:.2px; }\n h2 { font-size:1.1rem; margin:0 0 .75rem; color:var(--primary); }\n p { margin:.25rem 0; line-height:1.55; }\n .card { background:#fff; border:1px solid var(--border); border-radius:10px; padding:1rem; }\n .muted { color:var(--muted); }\n .kvs { display:grid; grid-template-columns:1fr 1fr; gap:.5rem 1rem; font-size:.95rem; }\n .kvs div { display:flex; align-items:center; gap:.5rem; }\n .pill { font-size:.8rem; padding:.15rem .5rem; border:1px solid var(--border); border-radius:999px; background:#f1f5f9; }\n table { width:100%; border-collapse:collapse; }\n th, td { border:1px solid var(--border); padding:.6rem .5rem; text-align:left; vertical-align:top; }\n thead th { background:#f1f5f9; }\n tfoot td { font-weight:600; }\n .note { font-size:.92rem; background:#f8fafc; border:1px dashed var(--border); padding:.75rem; border-radius:8px; }\n .cols-3 { columns:2; column-gap:1rem; }\n .signature { height:80px; border:1px dashed var(--border); border-radius:10px; display:flex; align-items:center; justify-content:center; color:var(--muted); }\n footer { padding:1rem 1.5rem; border-top:1px solid var(--border); color:var(--muted); font-size:.9rem; background:#fff; }\n</style>\n\n<body>\n<div class=\"page\">\n\n {# ==== Raccourcis / sécurisation des accès ==== #}\n {% set c = (quote.prospect is defined and quote.prospect.contact is defined) ? quote.prospect.contact : null %}\n {% set a = (c and c.mainAddress is defined) ? c.mainAddress : null %}\n {% set comp = (quote.prospect is defined and quote.prospect.company is defined) ? quote.prospect.company : null %}\n {% set lines = quote.quoteLines|default([]) %}\n\n {# Portable du commercial : on cherche dans un ordre sûr #}\n {% set tel_portable = '' %}\n {% if managedBy is defined %}\n {% if managedBy.phoneNumber is defined and managedBy.phoneNumber %}{% set tel_portable = managedBy.phoneNumber %}\n {% elseif managedBy.mobilePhone is defined and managedBy.mobilePhone %}{% set tel_portable = managedBy.mobilePhone %}\n {% elseif managedBy.phone is defined and managedBy.phone %}{% set tel_portable = managedBy.phone %}\n {% endif %}\n {% endif %}\n\n {# ==== Totaux/remise/TVA - robustes ==== #}\n {% set total_ht_before_discount = 0 %}\n {% for l in lines %}\n {% set q = l.quantity|default(1) %}\n {% set pu = l.unitPriceExclVat|default(0) %}\n {% set total_ht_before_discount = total_ht_before_discount + (q * pu) %}\n {% endfor %}\n {% if total_ht_before_discount == 0 %}\n {% set total_ht_before_discount = quote.totalExcludingVat|default(0) %}\n {% endif %}\n {% set total_ht = quote.totalExcludingVat|default(total_ht_before_discount) %}\n {% set discount_value = total_ht_before_discount - total_ht %}\n {% set discount_percent = total_ht_before_discount > 0 ? (discount_value / total_ht_before_discount * 100) : 0 %}\n {% set vat_total = 0 %}\n {% for l in lines %}\n {% set vat_total = vat_total + (l.vatAmount|default(0)) %}\n {% endfor %}\n\n {# ==== Sélection ligne principale / formation / options (sans filtres avancés) ==== #}\n {% set first = (lines[0] is defined) ? lines[0] : null %}\n {% set mainLine = null %}\n {% set formationLine = null %}\n {% set options = [] %}\n {% for l in lines %}\n {% set ref = l.reference|default('')|lower %}\n {% set isOpt = l.isOptional is defined and l.isOptional %}\n {% if mainLine is null and not isOpt and ('formation' not in ref) %}\n {% set mainLine = l %}\n {% endif %}\n {% if formationLine is null and ('formation' in ref) %}\n {% set formationLine = l %}\n {% endif %}\n {% if isOpt %}\n {% set options = options|merge([l]) %}\n {% endif %}\n {% endfor %}\n {% if mainLine is null %}{% set mainLine = first %}{% endif %}\n\n <!-- HEADER -->\n <header>\n <div style=\"flex:1\">\n <div class=\"brand\">YANIGAV – Enfonce-pieux • Affûte-piquet • Fendeuse de bûche</div>\n <div class=\"sub\">RCS ROANNE B 403 872 724 • SIRET 403 872 724 00014 • APE 4661Z • TVA FR114038727224</div>\n </div>\n <div class=\"pill\">{{ (quote.createdAt|default('now'))|date('d F Y') }}</div>\n </header>\n\n <!-- COORDONNÉES -->\n <div class=\"section grid-2\">\n <div class=\"card\">\n <h2>Expéditeur</h2>\n <p><strong>YANIGAV</strong></p>\n <p>De la part de <strong>{{ managedBy is defined and managedBy.fullname is defined ? managedBy.fullname : (quote.managedByRealName|default('')) }}</strong> ({{ managedBy is defined and managedBy.role is defined and managedBy.role ? managedBy.role : 'Resp. Commercial' }})</p>\n <div class=\"kvs\">\n <div><span class=\"pill\">Tél</span> {{ managedBy is defined and managedBy.phone is defined and managedBy.phone ? managedBy.phone : '—' }}</div>\n {% if tel_portable %}\n <div><span class=\"pill\">Port</span> {{ tel_portable }}</div>\n {% endif %}\n <div><span class=\"pill\">Email</span>\n {% if managedBy is defined and managedBy.email is defined and managedBy.email %}\n <a href=\"mailto:{{ managedBy.email }}\">{{ managedBy.email }}</a>\n {% else %}—{% endif %}\n </div>\n </div>\n </div>\n <div class=\"card\">\n <h2>Destinataire</h2>\n <p><strong>{{ quote.contactIdRealName|default(c and (c.fullname is defined and c.fullname ? c.fullname : (c.name|default('')))) }}</strong></p>\n {% if comp and comp.name is defined and comp.name %}<p><strong>{{ comp.name }}</strong></p>{% endif %}\n {% if a and (a.postalCode is defined or a.city is defined) %}<p class=\"muted\">{{ a.postalCode|default('') }} {{ a.city|default('') }}</p>{% endif %}\n </div>\n </div>\n\n <!-- INTRO -->\n <div class=\"section\">\n <div class=\"card\">\n <h1>Proposition commerciale</h1>\n <p>{% if c and c.civility is defined and c.civility %}{{ c.civility }},{% else %}Madame, Monsieur,{% endif %}</p>\n <p>Nous vous remercions de l’intérêt que vous portez à la marque YANIGAV et à ses produits. Suite à votre récent appel téléphonique, voici notre proposition pour un <strong>{{ quote.name|default('Enfonce-pieux HYDROCHOC HPG 790') }}</strong> correspondant à votre demande.</p>\n {% if quote.priceListRef is defined and quote.priceListRef %}\n <p class=\"muted\">{{ quote.priceListRef }}</p>\n {% else %}\n <p class=\"muted\">Tarif — {{ (quote.createdAt|default('now'))|date('Y') }}</p>\n {% endif %}\n </div>\n </div>\n\n <!-- OFFRE PRINCIPALE -->\n <div class=\"section\">\n <div class=\"card\">\n <h2>Offre principale</h2>\n <table>\n <thead>\n <tr>\n <th>Désignation</th>\n <th>Référence</th>\n <th>Prix unitaire HT</th>\n </tr>\n </thead>\n <tbody>\n {% set pu = (mainLine and mainLine.unitPriceExclVat is defined) ? mainLine.unitPriceExclVat : (total_ht_before_discount > 0 ? total_ht_before_discount : 0) %}\n <tr>\n <td>{{ (mainLine and mainLine.name is defined and mainLine.name) ? mainLine.name : quote.name }}</td>\n <td>{{ (mainLine and mainLine.reference is defined and mainLine.reference) ? mainLine.reference : '—' }}</td>\n <td>{{ pu|number_format(0, ',', ' ') }} €</td>\n </tr>\n </tbody>\n </table>\n {% set note = 'Cinématique unique sur le marché — un véritable atout dans les terrains compliqués.' %}\n <p class=\"note\" style=\"margin-top:.75rem\">{{ note }}</p>\n </div>\n </div>\n\n {# ==== DESCRIPTION / ÉQUIPEMENT / FORMATION / OPTIONS ==== #}\n {% set description = (mainLine and mainLine.description is defined and mainLine.description) ? mainLine.description : '' %}\n {% set description = description|replace({'•':'\\n',';':'\\n'}) %}\n {% set descList = description|split('\\n') %}\n\n <div class=\"section grid-2\">\n <div class=\"card\">\n <h2>Points forts</h2>\n {% set hasPoint = false %}\n <ul class=\"cols-3\">\n {% for item in descList %}\n {% set t = item|trim %}\n {% if t != '' %}\n {% set hasPoint = true %}\n <li>{{ t }}</li>\n {% endif %}\n {% endfor %}\n </ul>\n {% if not hasPoint %}\n <p class=\"muted\">Aucun détail technique renseigné pour cet article.</p>\n {% endif %}\n </div>\n\n <div class=\"card\">\n <h2>Équipement de série</h2>\n {% set printedEquip = false %}\n {# 1) Liste explicite mainLine.features si fournie #}\n {% if mainLine and mainLine.features is defined and mainLine.features %}\n <ul>\n {% for f in mainLine.features %}\n <li>{{ f }}</li>\n {% set printedEquip = true %}\n {% endfor %}\n </ul>\n {% endif %}\n\n {# 2) Sinon, tentative d’extraction depuis descList avec mots-clés #}\n {% if not printedEquip %}\n {% set equipList = [] %}\n {% for item in descList %}\n {% set t = item|trim %}\n {% if t matches '/(équipement|equipement|de série|serie)/i' %}\n {% set equipList = equipList|merge([t]) %}\n {% endif %}\n {% endfor %}\n {% if equipList %}\n <ul>\n {% for f in equipList %}<li>{{ f }}</li>{% endfor %}\n </ul>\n {% set printedEquip = true %}\n {% endif %}\n {% endif %}\n\n {% if not printedEquip %}\n <p class=\"muted\">Aucun équipement de série spécifié.</p>\n {% endif %}\n\n {% if formationLine %}\n <h2 style=\"margin-top:1rem\">Formation / Mise en route</h2>\n <p><strong>{{ formationLine.name|default('Formation / Mise en route') }}</strong> – Prix net :\n {{ (formationLine.totalExclVat|default(formationLine.unitPriceExclVat|default(0)))|number_format(0, ',', ' ') }} € HT</p>\n {% if formationLine.description is defined and formationLine.description %}<p class=\"muted\">{{ formationLine.description }}</p>{% endif %}\n {% endif %}\n\n {% if options %}\n <h2 style=\"margin-top:1rem\">Équipements recommandés</h2>\n <ul>\n {% for opt in options %}\n {% set q = opt.quantity|default(1) %}\n {% set puo = opt.unitPriceExclVat|default(0) %}\n {% set rem = opt.discountPercent|default(0) %}\n {% set opt_total = opt.totalExclVat|default(q * puo * (1 - (rem / 100))) %}\n <li>{{ opt.name }} — {{ opt_total|number_format(0, ',', ' ') }} € HT</li>\n {% endfor %}\n </ul>\n {% endif %}\n </div>\n </div>\n\n <!-- CONDITIONS COMMERCIALES -->\n <div class=\"section\">\n <div class=\"card\">\n <h2>Conditions commerciales</h2>\n <ul>\n {% if quote.expiredAt is defined and quote.expiredAt %}<li>Validité de l’offre : 1 mois (jusqu’au {{ quote.expiredAt|date('d/m/Y') }})</li>{% else %}<li>Validité de l’offre : 1 mois</li>{% endif %}\n {% if discount_value > 0 %}<li>Remise de service : {{ discount_percent|round(0, 'floor') }} %</li>{% endif %}\n {% if quote.orderContext is defined and quote.orderContext %}<li>{{ quote.orderContext }}</li>{% endif %}\n <li>Règlement {{ quote.paymentMode|default('30 jours nets par LCR') }}</li>\n <li>Délai : {{ quote.leadTime|default('2 à 3 mois après commande') }}</li>\n {% if quote.shippingFeesHt is defined %}\n {% if quote.shippingFeesHt == 0 %}<li>Port franco</li>\n {% elseif quote.shippingFeesHt > 0 %}<li>Frais de port : {{ quote.shippingFeesHt|number_format(2, ',', ' ') }} € HT</li>\n {% else %}<li>Port : {{ quote.shippingMode|default('selon conditions') }}</li>\n {% endif %}\n {% else %}\n <li>Port : {{ quote.shippingMode|default('selon conditions') }}</li>\n {% endif %}\n {% if quote.customerRef is defined and quote.customerRef %}<li>Réf. client : {{ quote.customerRef }}</li>{% endif %}\n </ul>\n </div>\n </div>\n\n <!-- SIGNATURES -->\n <div class=\"section grid-2\">\n <div class=\"card\">\n <h2>Signataires</h2>\n <p>\n <strong>{{ managedBy is defined and managedBy.fullname is defined ? managedBy.fullname : (quote.managedByRealName|default('')) }}</strong>\n – {{ managedBy is defined and managedBy.role is defined and managedBy.role ? managedBy.role : 'Resp. Commercial' }}\n {% if tel_portable %} – {{ tel_portable }}{% endif %}\n </p>\n <div class=\"signature\">Signature expéditeur</div>\n </div>\n <div class=\"card\">\n <h2>Bon pour accord</h2>\n <p><strong>{{ quote.contactIdRealName|default(c and (c.fullname is defined and c.fullname ? c.fullname : (c.name|default('')))) }}</strong>{% if comp and comp.name is defined and comp.name %} – {{ comp.name }}{% endif %}</p>\n <div class=\"signature\">Cachet et signature</div>\n </div>\n </div>\n\n <!-- PIED -->\n <footer>\n YANIGAV – Enfonce-pieux • Affûte-piquet • Fendeuse de bûche — RCS ROANNE B 403 872 724 — SIRET 403 872 724 00014 — APE 4661Z — TVA FR114038727224\n </footer>\n</div>\n\n{# PAGE 2 : CGV (optionnelle) #}\n{% if cgv is defined or quote.cgvText is defined %}\n <div style=\"page-break-before:always;\"></div>\n <div class=\"page\">\n <div class=\"section\">\n <div class=\"card\">\n <h2>Conditions Générales de Vente</h2>\n <div class=\"note\" style=\"white-space:pre-wrap\">\n {{ cgv|default(quote.cgvText)|raw }}\n </div>\n </div>\n </div>\n <footer>\n Document généré automatiquement — valable sous réserve des conditions précisées ci-dessus.\n </footer>\n </div>\n{% endif %}\n</body>\n</html>\n"}
Response
Response Headers
| Header | Value |
|---|---|
| access-control-allow-origin | "https://dev.pol-crm.com" |
| access-control-expose-headers | "x-debug-token, sentry-trace, baggage, retry-after" |
| cache-control | "private, must-revalidate" |
| content-location | "/api/templates/f47ef469dac34bc29180feb40a25724c" |
| content-type | "application/ld+json; charset=utf-8" |
| date | "Sun, 19 Oct 2025 22:39:10 GMT" |
| expires | -1 |
| link | "<https://dev.app.pol-crm.com/api/docs.jsonld>; rel="http://www.w3.org/ns/hydra/core#apiDocumentation"" |
| pragma | "no-cache" |
| vary | "Accept" |
| x-content-type-options | "nosniff" |
| x-debug-token | "a91501" |
| x-frame-options | "deny" |
Cookies
Request Cookies
No request cookies
Response Cookies
No response cookies
Session
Session Metadata
No session metadata
Session Attributes
No session attributes
Flashes
Flashes
No flash messages were created.
Server Parameters
Server Parameters
Defined in .env
| Key | Value |
|---|---|
| API_BUSINESS_HOST | "http://dev.pol-api-business.pol-crm.com" |
| API_CRM_HOST | "http://dev.pol-api-crm.pol-crm.com" |
| API_GED_HOST | "http://dev.pol-api-ged.pol-crm.com" |
| API_LIVEO | "https://webservice.centrex.liveo.fr/ws/" |
| API_MIDDLEWARE_HOST | "https://pol-middleware" |
| API_NOTIFY_HOST | "http://dev.pol-api-notify.pol-crm.com" |
| API_PARAM_HOST | "http://dev.pol-api-param.pol-crm.com" |
| API_POL_MAILING | "http://mailing.sfi.fr/webservices" |
| API_POL_MAILING_V2 | "https://dev.mailing.pol-crm.com/webservices" |
| API_SEARCH_HOST | "http://dev.pol-api-search.pol-crm.com" |
| API_SERVICE_PLENETUDE_HOST | "http://dev.plenetude.pol-crm.com" |
| API_USER_HOST | "http://dev.pol-api-user.pol-crm.com" |
| APP_ENV | "dev" |
| APP_SECRET | "61ff627c8e96e9ac55fc1926e4878f2e" |
| BDD_API_BUSINESS | "dev_pol_core" |
| BDD_API_CRM | "dev_pol_core" |
| BDD_API_GED | "dev_pol_core" |
| BDD_API_NOTIFY | "dev_pol_core" |
| BDD_API_PARAM | "dev_pol_core" |
| BDD_API_SEARCH | "dev_pol_core" |
| BDD_API_USER | "dev_pol_core" |
| BDD_MIDDLEWARE | "dev_pol_core" |
| BDD_SERVICE_PLENETUDE | "dev_pol_core" |
| BEGIN_DATE | "2024-01-01" |
| CORS_ALLOW_ORIGIN | "^https?://pol-(crm|prospect).localhost(:[0-9]+)?$" |
| DATABASE_URL | "mysql://dev_pol_core:VTgooWkhcjebxLPy8E2ycoTjytrULgNQ@127.0.0.1:3306/dev_pol_core" |
| END_DATE | "2025-01-31" |
| FRONT_URL | "https://pol-crm.localhost" |
| FTP_INTRANET_SFI_HOST | "preprod.intranet.sfimultimedia.com" |
| FTP_INTRANET_SFI_PASSWORD | "iAw453e?iAw453e?" |
| FTP_INTRANET_SFI_USER | "intranetpreprod" |
| GED_ABSOLUTE_DIRECTORY_PATH | "/var/www/pol-api-ged/application/data/ged" |
| GEONAME_API_TOKEN | "ceciestuntestpourSfi/0000" |
| IMPORT_ONDUPACK_PATH_FILE | "/httpdocs/app-pol-crm/dev/current/application/data/import_ondupack" |
| INSEE_API_SIRENE_KEY | "09afd2bf-050b-465e-afd2-bf050b865e20" |
| IS_MAINTENANCE | "false" |
| JWT_PASSPHRASE | "7de1072d7a8fcab69679c1892deb39a7" |
| JWT_PUBLIC_KEY | "%kernel.project_dir%/config/jwt/public.pem" |
| JWT_SECRET_KEY | "%kernel.project_dir%/config/jwt/private.pem" |
| JWT_WHITELIST_PATH | "%kernel.project_dir%/var/tokens" |
| MAILER_URL | "smtp://127.0.0.1:1025" |
| MAILING_ENV_USER | "depot_mailing_dev-xv42" |
| MESSENGER_TRANSPORT_DSN_MIDDLEWARE | "amqp://sfiweb:sfiwweb0000@127.0.0.1:5672/%2f/dev_middleware_messages" |
| MESSENGER_TRANSPORT_DSN_NOTIFY | "amqp://sfiweb:sfiwweb0000@127.0.0.1:5672/%2f/dev_notify_messages" |
| MESSENGER_TRANSPORT_DSN_SEARCH | "amqp://sfiweb:sfiwweb0000@127.0.0.1:5672/%2f/dev_messages" |
| MICROSOFT_GRAPH_API_CLIENT_ID | "3b7f02c4-aa14-4e54-a2b9-2ee1d5d17f8a" |
| MICROSOFT_GRAPH_API_CLIENT_SECRET | "FID8Q~zfFRP~Gw-85LpaCj0VqrrRr__HMGpI-drP" |
| MICROSOFT_GRAPH_API_NOTIFICATION_URL | "https://dev.app.pol-crm.com/api/microsoft-graph/outlook-subscription-configuration" |
| MICROSOFT_GRAPH_API_REDIRECT_URI | "https://dev.pol-crm.com/microsoft-graph" |
| MICROSOFT_GRAPH_API_SUBSCRIPTION_EXPIRED_AT | "+2 days" |
| MICROSOFT_GRAPH_API_TOKEN_LIFETIME | "+2 days" |
| MODULE_MICROSOFT_GRAPH_SECRET | "jqsFP7MjEx1FBe1138D3" |
| MONOLOG_APPLICATION_ENVIRONMENT | "dev" |
| MONOLOG_APPLICATION_NAME | "pol-middleware" |
| MONOLOG_SUBJECT | "[DEV][%level_name%] POL-MIDDLEWARE - %message%" |
| MONOLOG_TO_EMAIL | "polv3.log@sfi.fr" |
| MYSQL_DATABASE | "dev_pol_core" |
| MYSQL_HOST | "127.0.0.1" |
| MYSQL_PASSWORD | "VTgooWkhcjebxLPy8E2ycoTjytrULgNQ" |
| MYSQL_PORT | "3306" |
| MYSQL_USER | "dev_pol_core" |
| PREFIX_CUSTOMER_NAME_MAILING | "[DEV]" |
| REDIS_ENABLE_V4 | "true" |
| REDIS_PREFIX | "dev" |
| REDIS_URL | "redis://127.0.0.1:6379" |
| SECURITY_ENABLE_TOKEN_WHITELIST | "0" |
| SENTRY_DSN | "https://99729cc06c8241e3b07e3f6ae9b6feec@sentry.sfimultimedia.com/9" |
| SENTRY_ENVIRONMENT | "dev" |
| SENTRY_PERFORMANCE_SAMPLE_RATE | "1.0" |
| SFI_MAILING_URL | "https://mailing.sfi.fr/webservices/recupererContactPol.php" |
| SFI_SSO_FORCE_CREDENTIALS | "87;707" |
| SFI_SSO_MAILING_HOST | "https://mailing.sfi.fr/webservices/sso.php" |
| SYSTEMUSER_0662705af65c48908b017d8fb0724bac_PASSWORD | "7G4k4WhQZDkkB5IGLRPcdfik5s58gf58f2g5s6W6T6BXfbYj2H_customer_newco" |
| SYSTEMUSER_0662705af65c48908b017d8fb0724bac_USERNAME | "system_0662705af65c48908b017d8fb0724bac" |
| SYSTEMUSER_customer_124_PASSWORD | "A6uraa5HQ87hY*unfx3$mr158!d7i*TX_customer_124" |
| SYSTEMUSER_customer_124_USERNAME | "system_customer_124" |
| SYSTEMUSER_customer_65_PASSWORD | "uBRJV4pUKP1wRk4iULwMnty93MPr4qr3Sod8jFlfJwZdURZB_customer_65" |
| SYSTEMUSER_customer_65_USERNAME | "system_customer_65" |
| SYSTEMUSER_customer_66_PASSWORD | "7G4k4WhQZDkkB5IGLRPcdfik3tOZfL4PVfs6W6T6BXfbYj2H_customer_66" |
| SYSTEMUSER_customer_66_USERNAME | "system_customer_66" |
| SYSTEMUSER_customer_98_PASSWORD | "wWZJwEgYjqLdPx77B1o9GR7r6r4Fvug82fmALJLvQCBjWD4G_customer_98" |
| SYSTEMUSER_customer_98_USERNAME | "system_customer_98" |
| SYSTEMUSER_e8919dbc01f34f79ab22b9c434f114eb_PASSWORD | "TPB5ccJCl4ZL5jurkpedelfwdEiYRt4g30xYM82" |
| SYSTEMUSER_e8919dbc01f34f79ab22b9c434f114eb_USERNAME | "system_e8919dbc01f34f79ab22b9c434f114eb" |
Defined as regular env variables
| Key | Value |
|---|---|
| APP_DEBUG | "1" |
| CONTENT_LENGTH | "15077" |
| CONTENT_TYPE | "application/json" |
| CONTEXT_DOCUMENT_ROOT | "/var/www/vhosts/app.pol-crm.com/httpdocs/app-pol-crm/dev/current/application/public" |
| CONTEXT_PREFIX | "" |
| DOCUMENT_ROOT | "/var/www/vhosts/app.pol-crm.com/httpdocs/app-pol-crm/dev/current/application/public" |
| FCGI_ROLE | "RESPONDER" |
| GATEWAY_INTERFACE | "CGI/1.1" |
| HOME | "/var/www/vhosts/app.pol-crm.com" |
| HTTPS | "on" |
| HTTP_ACCEPT | "application/ld+json" |
| HTTP_ACCEPT_ENCODING | "gzip, deflate, br, zstd" |
| HTTP_ACCEPT_LANGUAGE | "fr-FR,fr;q=0.9,en-US;q=0.8,en;q=0.7" |
| HTTP_CONNECTION | "close" |
| HTTP_HOST | "dev.app.pol-crm.com" |
| HTTP_ORIGIN | "https://dev.pol-crm.com" |
| HTTP_PRIORITY | "u=1, i" |
| HTTP_REFERER | "https://dev.pol-crm.com/" |
| HTTP_SEC_CH_UA | ""Chromium";v="140", "Not=A?Brand";v="24", "Google Chrome";v="140"" |
| HTTP_SEC_CH_UA_MOBILE | "?0" |
| HTTP_SEC_CH_UA_PLATFORM | ""Windows"" |
| HTTP_SEC_FETCH_DEST | "empty" |
| HTTP_SEC_FETCH_MODE | "cors" |
| HTTP_SEC_FETCH_SITE | "same-site" |
| HTTP_USER_AGENT | "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/140.0.0.0 Safari/537.36" |
| HTTP_X_ACCEL_INTERNAL | "/internal-nginx-static-location" |
| HTTP_X_POL_AUTH | "Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiJ9.eyJpYXQiOjE3NjA5MTI0NDEsImV4cCI6MTc2MDkxNjA0MSwicm9sZXMiOlsiUk9MRV9VU0VSIiwiUk9MRV9TVVBFUkFETUlOIiwiUk9MRV9BRE1JTiIsIlJPTEVfTU9EVUxFX1BST0RVQ1QiLCJST0xFX01PRFVMRV9QUk9EVUNUX0NVU1RPTUlaRSIsIlJPTEVfTU9EVUxFX1FVT1RFX0xJTkUiLCJQUk9TUEVDVF9TSE9XIiwiUFJPU1BFQ1RfQ1VEIiwiQ09OVEFDVF9DVUQiLCJDT05UQUNUX1NIT1ciLCJUQVNLX1NIT1ciLCJUQVNLX0NVRCIsIlFVT1RFX1NIT1ciLCJRVU9URV9DVUQiLCJRVU9URV9SRUdFTkVSQVRFX1BSSUNFUyJdLCJsb2dpbiI6ImRlbW95YW5pZ2F2IiwidXNlcl9pZCI6InVzZXJfMTAxMSIsInVzZXJfZXh0ZXJuYWxfaWQiOiIxMDExIiwiZW1haWwiOiJnLXNhdXRyb25Ac2ZpLmZyIiwiY3VzdG9tZXJfaWQiOiJjdXN0b21lcl8xMjEiLCJjdXN0b21lcl9uYW1lIjoiWUFOSUdBViIsImN1c3RvbWVyX2V4dGVybmFsX2lkIjoiMTIxIiwiY3VzdG9tZXJfbWFpbGluZ19pZCI6IjE0NyIsImZpcnN0bmFtZSI6Ikd1aWxsYXVtZSIsImxhc3RuYW1lIjoiU0FVVFJPTiIsImxpdmVvTG9naW4iOm51bGwsImxpdmVvUGFzc3dvcmQiOm51bGwsImhhc0ludHJhbmV0IjpmYWxzZSwibGFuZ3VhZ2UiOiJGUiIsInNlY3Rpb25zX2xlYWRlZCI6W10sInNlY3Rpb25zX21lbWJlcnMiOlsidXNlcl8xMDExIl0sImlzX3NlY3Rpb25zX2FjdGl2YXRlZCI6ZmFsc2UsInJlZnJlc2hfdG9rZW4iOiIifQ.smruhTDO6MF4efpXGiPp4DyZoLSpsUh3ykwBDmscLGtkvlySQlnSFvS1bxozG8T5Y0oGdkijvDiliogWK_zhqLF6FXho-oEscgCbKhvTjdosGLc4QHX0QAtM1LeVpT3BGVz9isHY1J7X0RDnoWA2GdCwCZ-ELXlS7fP08w_Mc5j8GqGhN5XwD70MLfR5ltD75o5BEhCWKMsWsatkGs3bbd7AfjhqoSz7qexpiHj1BRszq-H5QekWiJWgwOLDUJc85rZYaNVbYu75qseEbKfW-kWAxOZhAZCmVfFDQ-qBxSJ1i7KwVasIGTJDTnJn7l8fDqFWF0jGtC4LJzQEOZDjoOrQVaP2szLusNdOeKICnE3GOpY7E2sHIJpbTf8KlRUSm0uKc4t4hgoSRxnCdQGLx4hcTGSGHyITgso7tVs6068piCfp8JttEo5SoXERPiVNl2oeKa7VQAgtUWMzPI-SYX6QfGCjnrYE3JcTufx8xFtvlS4pmeIaLNJs7Y8l21f-A8MB7y-3zOAzriYExuKUOtT9oZ0GRtCWG5oTUyQ2LI4IjzaqBW_ikRfcccdSOZqZxV_FVw1fO9vPg9Lgi9XKAfKtjCLtI9nMboiZsSk9mx5_CAREqtb476hnnUVOfvHCBazVRQo-FWsSSWNLCIe8MtR9pUny0D8hn5qCQ712Axk" |
| HTTP_X_REAL_IP | "176.174.157.21" |
| HTTP_X_TRANSACTION_ID | "front:zv9jvbn66i" |
| PASSENGER_COMPILE_NATIVE_SUPPORT_BINARY | "0" |
| PASSENGER_DOWNLOAD_NATIVE_SUPPORT_BINARY | "0" |
| PATH | "/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/snap/bin" |
| PHP_SELF | "/index.php" |
| QUERY_STRING | "" |
| REDIRECT_HTTPS | "on" |
| REDIRECT_PASSENGER_COMPILE_NATIVE_SUPPORT_BINARY | "0" |
| REDIRECT_PASSENGER_DOWNLOAD_NATIVE_SUPPORT_BINARY | "0" |
| REDIRECT_SSL_TLS_SNI | "dev.app.pol-crm.com" |
| REDIRECT_STATUS | "200" |
| REDIRECT_URL | "/api/templates/f47ef469dac34bc29180feb40a25724c" |
| REMOTE_ADDR | "176.174.157.21" |
| REMOTE_PORT | "51304" |
| REQUEST_METHOD | "PUT" |
| REQUEST_SCHEME | "https" |
| REQUEST_TIME | 1760913548 |
| REQUEST_TIME_FLOAT | 1760913548.9908 |
| REQUEST_URI | "/api/templates/f47ef469dac34bc29180feb40a25724c" |
| SCRIPT_FILENAME | "/var/www/vhosts/app.pol-crm.com/httpdocs/app-pol-crm/dev/current/application/public/index.php" |
| SCRIPT_NAME | "/index.php" |
| SERVER_ADDR | "185.18.171.8" |
| SERVER_ADMIN | "[no address given]" |
| SERVER_NAME | "dev.app.pol-crm.com" |
| SERVER_PORT | "443" |
| SERVER_PROTOCOL | "HTTP/1.0" |
| SERVER_SIGNATURE | "<address>Apache Server at dev.app.pol-crm.com Port 443</address>\n" |
| SERVER_SOFTWARE | "Apache" |
| SSL_TLS_SNI | "dev.app.pol-crm.com" |
| SYMFONY_DOTENV_VARS | "APP_ENV,APP_SECRET,BDD_API_BUSINESS,BDD_API_CRM,BDD_API_GED,BDD_API_NOTIFY,BDD_API_PARAM,BDD_API_SEARCH,BDD_API_USER,BDD_MIDDLEWARE,BDD_SERVICE_PLENETUDE,MYSQL_HOST,MYSQL_PORT,MYSQL_USER,MYSQL_PASSWORD,MYSQL_DATABASE,DATABASE_URL,MAILER_URL,CORS_ALLOW_ORIGIN,JWT_SECRET_KEY,JWT_PUBLIC_KEY,JWT_PASSPHRASE,JWT_WHITELIST_PATH,MONOLOG_SUBJECT,MONOLOG_TO_EMAIL,MONOLOG_APPLICATION_NAME,MONOLOG_APPLICATION_ENVIRONMENT,MESSENGER_TRANSPORT_DSN_SEARCH,MESSENGER_TRANSPORT_DSN_NOTIFY,MESSENGER_TRANSPORT_DSN_MIDDLEWARE,SENTRY_DSN,SENTRY_ENVIRONMENT,SENTRY_PERFORMANCE_SAMPLE_RATE,IS_MAINTENANCE,SECURITY_ENABLE_TOKEN_WHITELIST,REDIS_ENABLE_V4,REDIS_URL,API_BUSINESS_HOST,API_CRM_HOST,API_GED_HOST,API_NOTIFY_HOST,API_PARAM_HOST,API_SEARCH_HOST,API_USER_HOST,API_MIDDLEWARE_HOST,API_SERVICE_PLENETUDE_HOST,API_POL_MAILING,API_POL_MAILING_V2,API_LIVEO,MAILING_ENV_USER,FTP_INTRANET_SFI_HOST,FTP_INTRANET_SFI_USER,FTP_INTRANET_SFI_PASSWORD,SFI_SSO_FORCE_CREDENTIALS,MICROSOFT_GRAPH_API_REDIRECT_URI,MICROSOFT_GRAPH_API_CLIENT_ID,MICROSOFT_GRAPH_API_NOTIFICATION_URL,MICROSOFT_GRAPH_API_CLIENT_SECRET,MICROSOFT_GRAPH_API_SUBSCRIPTION_EXPIRED_AT,MODULE_MICROSOFT_GRAPH_SECRET,INSEE_API_SIRENE_KEY,GEONAME_API_TOKEN,GED_ABSOLUTE_DIRECTORY_PATH,IMPORT_ONDUPACK_PATH_FILE,FRONT_URL,REDIS_PREFIX,SFI_SSO_MAILING_HOST,SFI_MAILING_URL,PREFIX_CUSTOMER_NAME_MAILING,MICROSOFT_GRAPH_API_TOKEN_LIFETIME,SYSTEMUSER_e8919dbc01f34f79ab22b9c434f114eb_USERNAME,SYSTEMUSER_e8919dbc01f34f79ab22b9c434f114eb_PASSWORD,SYSTEMUSER_customer_65_USERNAME,SYSTEMUSER_customer_65_PASSWORD,SYSTEMUSER_customer_66_USERNAME,SYSTEMUSER_customer_66_PASSWORD,SYSTEMUSER_customer_124_USERNAME,SYSTEMUSER_customer_124_PASSWORD,SYSTEMUSER_0662705af65c48908b017d8fb0724bac_USERNAME,SYSTEMUSER_0662705af65c48908b017d8fb0724bac_PASSWORD,SYSTEMUSER_customer_98_USERNAME,SYSTEMUSER_customer_98_PASSWORD,BEGIN_DATE,END_DATE" |
| USER | "app-pol-crm" |
| proxy-nokeepalive | "1" |