Wizard: section Installation (palier financé) à l'étape Items

- Presets Standard 360→240 (10$/mois) / Simple 180→120 (5$/mois) / Aucune
- 2 cases éditables Prix original / Prix financé + aperçu live (barré, $/mois, crédité→0$)
- Alimente install_fee/install_regular du Service Contract → page d'acceptation affiche le détail
- Placé sous Code de référence dans la vue résidentielle

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
louispaulb 2026-06-03 19:20:04 -04:00
parent e2104c93f2
commit 37f4d5a941
2 changed files with 51 additions and 0 deletions

View File

@ -488,6 +488,42 @@
<q-icon name="error" size="13px" /> {{ referralError }}
</div>
<!-- Installation financée créance réelle créditée chaque mois (conforme CRTC, pas de clawback) -->
<div class="referral-row q-mt-md" style="border-color:#bde5cb;background:#f4fff6">
<q-icon name="construction" size="18px" color="green-7" class="q-mr-sm" />
<div class="col" style="min-width:0">
<div class="referral-title" style="color:#00733a">Installation</div>
<div class="referral-desc">Financée sur {{ maxContractMonths }} mois, créditée chaque mois 0&nbsp;$ net pour le client tant qu'abonné</div>
</div>
<div class="row q-gutter-xs items-center no-wrap">
<q-btn v-for="p in INSTALL_PRESETS" :key="p.key" dense no-caps size="sm"
:outline="!isInstallPreset(p)" :unelevated="isInstallPreset(p)"
color="green-7" :text-color="isInstallPreset(p) ? 'white' : 'green-8'"
:label="p.label" @click="setInstallPreset(p)" />
</div>
</div>
<div v-if="installFee > 0 || installRegular > 0" class="row q-col-gutter-sm q-mt-xs items-center">
<div class="col-4">
<q-input v-model.number="installRegular" dense outlined type="number" step="0.01" min="0"
label="Prix original" :input-style="{ fontSize: '0.78rem' }"
title="Prix barré affiché au client (0 = aucun barré)">
<template v-slot:append><q-icon name="local_offer" size="13px" color="orange-7" /></template>
</q-input>
</div>
<div class="col-4">
<q-input v-model.number="installFee" dense outlined type="number" step="0.01" min="0"
label="Prix financé $" :input-style="{ fontSize: '0.78rem' }"
title="Montant réellement financé/dû (créance). 0 = installation gratuite" />
</div>
<div v-if="installFee > 0" class="col-4" style="font-size:0.76rem">
<div v-if="installRegular > installFee">
<s style="color:#9ca3af">{{ Number(installRegular).toFixed(2) }}$</s>
<b class="text-green-8 q-ml-xs">{{ Number(installFee).toFixed(2) }}$</b>
</div>
<div class="text-grey-7">+{{ (Number(installFee) / (maxContractMonths || 24)).toFixed(2) }}$/mois · crédité <b class="text-green-8">0$</b></div>
</div>
</div>
<!-- "Autre item" + "Item manuel" shortcuts live at the bottom
the sticky cart pill at the top handles navigation to Sommaire
which is where cart details and totals are edited/reviewed. -->
@ -1697,6 +1733,7 @@ const { publish } = useWizardPublish({
acceptanceSentVia, publishedJobCount,
sendTo, sendChannel,
publishedContractName,
installFee, installRegular,
cancel () { cancel() },
},
})
@ -1900,6 +1937,17 @@ const referralApplied = ref(false)
const referralChecking = ref(false)
const referralError = ref('')
// Installation financée (CRTC-compliant) alimente install_fee / install_regular du contrat.
const installRegular = ref(0) // prix de référence barré (marketing)
const installFee = ref(0) // montant réellement financé/dû (créance)
const INSTALL_PRESETS = [
{ key: 'standard', label: 'Standard', regular: 360, fee: 240 },
{ key: 'simple', label: 'Simple', regular: 180, fee: 120 },
{ key: 'none', label: 'Aucune', regular: 0, fee: 0 },
]
function setInstallPreset (p) { installRegular.value = p.regular; installFee.value = p.fee }
function isInstallPreset (p) { return Number(installFee.value) === p.fee && Number(installRegular.value) === p.regular }
async function applyReferralCode () {
const code = referralCode.value.trim().toUpperCase()
if (!code) return

View File

@ -13,6 +13,7 @@ export function useWizardPublish ({ props, emit, state }) {
acceptanceSentVia, publishedJobCount,
sendTo, sendChannel,
publishedContractName,
installFee, installRegular,
} = state
async function resolveAddress () {
@ -265,6 +266,8 @@ export function useWizardPublish ({ props, emit, state }) {
duration_months: durationMonths,
monthly_rate: monthlyRate,
monthly_regular: monthlyRegular > monthlyRate ? monthlyRegular : 0,
install_fee: installFee?.value || 0,
install_regular: (installRegular?.value || 0) > (installFee?.value || 0) ? installRegular.value : 0,
service_location: serviceLocation,
quotation: orderDocName,
start_date: today,