Manu 1 2 4 5 7 ok
This commit is contained in:
@@ -0,0 +1,709 @@
|
||||
{% extends "base.html" %} {% block title %}Gestion des Ordres - Bolsa{% endblock
|
||||
%} {% block header_title %}Gestion des ordres{% endblock %} {% block content %}
|
||||
<div
|
||||
class="flex flex-col items-center justify-center py-2 px-2 relative w-full"
|
||||
>
|
||||
<!-- Système de Toasts -->
|
||||
<div
|
||||
id="toast-container"
|
||||
class="fixed top-6 left-1/2 transform -translate-x-1/2 z-50 space-y-3 w-full max-w-md px-4 pointer-events-none"
|
||||
>
|
||||
{% set messages = get_flashed_messages(with_categories=true) %} {% if
|
||||
messages %} {% for category, message in messages %}
|
||||
<div
|
||||
class="toast-message pointer-events-auto flex items-center justify-center px-4 py-3 rounded-xl shadow-2xl text-white text-sm font-medium transition-all duration-300 transform translate-y-0 opacity-100 text-center {% if category == 'success' %} bg-emerald-600 border border-emerald-500 {% elif category == 'warning' %} bg-amber-600 border border-amber-500 {% else %} bg-rose-600 border border-rose-500 {% endif %}"
|
||||
>
|
||||
<span>{{ message }}</span>
|
||||
</div>
|
||||
{% endfor %} {% endif %}
|
||||
</div>
|
||||
|
||||
<!-- Box principale -->
|
||||
<div
|
||||
class="bg-gray-900 border border-gray-800 p-4 sm:p-6 rounded-2xl shadow-2xl w-full max-w-[98%]"
|
||||
>
|
||||
<div
|
||||
class="flex justify-between items-center mb-4 border-b border-gray-800 pb-3"
|
||||
>
|
||||
<div>
|
||||
<h2 class="text-2xl font-extrabold text-white flex items-center gap-2">
|
||||
<i class="fa-solid fa-list-check text-blue-500"></i> Ordres -
|
||||
<span class="text-amber-400">{{ selected_societe }}</span>
|
||||
</h2>
|
||||
<p class="text-gray-400 text-sm">
|
||||
Suivi et historique des ordres de bourse par société.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div class="flex items-center gap-3">
|
||||
<form
|
||||
method="POST"
|
||||
action="{{ url_for('main.gestion_ordres') }}"
|
||||
class="m-0"
|
||||
>
|
||||
<select
|
||||
name="societe_id"
|
||||
class="bg-gray-800 border border-gray-700 text-white text-sm rounded-lg px-3 py-2 focus:outline-none focus:border-blue-500"
|
||||
onchange="this.form.submit()"
|
||||
>
|
||||
{% for soc in societes %} {% if soc.id == selected_societe_id %}
|
||||
<option value="{{ soc.id }}" selected>{{ soc.Nom }}</option>
|
||||
{% else %}
|
||||
<option value="{{ soc.id }}">{{ soc.Nom }}</option>
|
||||
{% endif %} {% endfor %}
|
||||
</select>
|
||||
</form>
|
||||
|
||||
<button
|
||||
type="button"
|
||||
onclick="ouvrirModalOrdre()"
|
||||
class="px-4 py-2 bg-emerald-600 hover:bg-emerald-500 text-white text-sm font-medium rounded-lg transition duration-200 flex items-center gap-2 cursor-pointer"
|
||||
>
|
||||
<i class="fa-solid fa-plus"></i> Créer ordre
|
||||
</button>
|
||||
|
||||
<a
|
||||
href="{{ url_for('main.menu') }}"
|
||||
class="px-4 py-2 bg-gray-800 hover:bg-gray-700 text-gray-200 text-sm font-medium rounded-lg transition duration-200"
|
||||
>
|
||||
Retour au menu
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Tableau -->
|
||||
<div
|
||||
class="bg-gray-950 border border-gray-800 rounded-xl p-2 overflow-x-auto"
|
||||
>
|
||||
<table class="w-full text-left border-collapse text-sm">
|
||||
<tbody class="divide-y divide-gray-800 text-gray-300">
|
||||
{% if groupes_ordres %} {% for groupe in groupes_ordres %}
|
||||
<tr class="bg-blue-950 text-white font-semibold">
|
||||
<td colspan="12" class="py-2.5 px-3 text-base">
|
||||
{{ groupe.isin }} --- {{ groupe.company_name }} ( {{ groupe.ticker
|
||||
}} )
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<tr
|
||||
class="bg-blue-950/60 text-gray-400 uppercase tracking-wider text-xs border-t border-b border-gray-800"
|
||||
>
|
||||
<th class="py-2 px-3">Date</th>
|
||||
<th class="py-2 px-3">Qté</th>
|
||||
<th class="py-2 px-3">Prix Brut</th>
|
||||
<th class="py-2 px-3">Frais</th>
|
||||
<th class="py-2 px-3">Prix Net</th>
|
||||
<th class="py-2 px-3">Eng. Brut</th>
|
||||
<th class="py-2 px-3">Eng. Net</th>
|
||||
<th class="py-2 px-3">Ordre</th>
|
||||
<th class="py-2 px-3">Type</th>
|
||||
<th class="py-2 px-3">État</th>
|
||||
<th class="py-2 px-3 text-end">
|
||||
<button
|
||||
type="button"
|
||||
onclick="ouvrirModalLigneOrdre('{{ groupe.id }}', '{{ groupe.isin }}', '{{ groupe.company_name }}', '{{ groupe.ticker }}')"
|
||||
class="px-3.5 py-1.5 bg-emerald-600 hover:bg-emerald-500 text-white text-xs font-semibold rounded shadow transition cursor-pointer"
|
||||
>
|
||||
Créer
|
||||
</button>
|
||||
</th>
|
||||
</tr>
|
||||
|
||||
{% for p in groupe.pieds %}
|
||||
<tr class="hover:bg-gray-900/50 transition">
|
||||
<td class="py-2 px-3 whitespace-nowrap">{{ p.date_op }}</td>
|
||||
<td class="py-2 px-3">
|
||||
{{ "{:,.0f}".format(p.quantite).replace(",", " ") }}
|
||||
</td>
|
||||
<td class="py-2 px-3">{{ "{:,.3f}".format(p.prix_brut) }}</td>
|
||||
<td class="py-2 px-3">{{ "{:,.3f}".format(p.frais) }}</td>
|
||||
<td class="py-2 px-3">{{ "{:,.3f}".format(p.prix_net) }}</td>
|
||||
<td class="py-2 px-3">{{ "{:,.3f}".format(p.eng_brut) }}</td>
|
||||
<td class="py-2 px-3">{{ "{:,.3f}".format(p.eng_net) }}</td>
|
||||
<td class="py-2 px-3">
|
||||
<span
|
||||
class="px-2 py-0.5 rounded text-xs font-semibold {% if p.ordre == 'achat' %}bg-blue-900 text-blue-200{% else %}bg-rose-900 text-rose-200{% endif %}"
|
||||
>
|
||||
{{ p.ordre | upper }}
|
||||
</span>
|
||||
</td>
|
||||
<td class="py-2 px-3">{{ p.type_ordre }}</td>
|
||||
<td class="py-2 px-3">
|
||||
<span
|
||||
class="px-2 py-0.5 rounded text-xs font-medium {% if p.etat == 'actif' %}bg-emerald-900 text-emerald-200 {% elif p.etat == 'soldé' %}bg-gray-800 text-gray-300 {% else %}bg-amber-900 text-amber-200{% endif %}"
|
||||
>
|
||||
{{ p.etat }}
|
||||
</span>
|
||||
</td>
|
||||
<td class="py-2 px-3 text-end">
|
||||
<button
|
||||
type="button"
|
||||
onclick="ouvrirModalModifierLigne('{{ p.id }}', '{{ groupe.isin }}', '{{ groupe.company_name }}', '{{ groupe.ticker }}', '{{ p.date_op }}', '{{ p.quantite }}', '{{ p.prix_brut }}', '{{ p.frais_brocker }}', '{{ p.frais_etat }}', '{{ p.frais_autre }}', '{{ p.ordre }}', '{{ p.type_ordre }}', '{{ p.etat }}')"
|
||||
class="px-3.5 py-1.5 bg-blue-600 hover:bg-blue-500 text-white text-xs font-semibold rounded shadow transition inline-flex items-center justify-center cursor-pointer"
|
||||
title="Modifier"
|
||||
>
|
||||
Modifier
|
||||
</button>
|
||||
</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
|
||||
<!-- LIGNE TOTAL -->
|
||||
<tr
|
||||
class="bg-blue-950/60 text-white uppercase tracking-wider text-xs border-t border-b border-gray-800 font-bold"
|
||||
>
|
||||
<td class="py-2.5 px-3">TOTAL :</td>
|
||||
<td class="py-2.5 px-3">
|
||||
{{ "{:,.0f}".format(groupe.total_quantite).replace(",", " ") }}
|
||||
</td>
|
||||
|
||||
{% if groupe.total_quantite != 0 %} {% set total_prix_net_moyen =
|
||||
groupe.total_eng_net / groupe.total_quantite %} {% set
|
||||
total_prix_brut_moyen = groupe.total_eng_brut /
|
||||
groupe.total_quantite %} {% set total_frais_moyen =
|
||||
total_prix_net_moyen - total_prix_brut_moyen %}
|
||||
|
||||
<td class="py-2.5 px-3">
|
||||
{{ "{:,.3f}".format(total_prix_brut_moyen) }}
|
||||
</td>
|
||||
<td class="py-2.5 px-3">
|
||||
{{ "{:,.3f}".format(total_frais_moyen) }}
|
||||
</td>
|
||||
<td class="py-2.5 px-3">
|
||||
{{ "{:,.3f}".format(total_prix_net_moyen) }}
|
||||
</td>
|
||||
<td class="py-2.5 px-3">
|
||||
{{ "{:,.3f}".format(groupe.total_eng_brut) }}
|
||||
</td>
|
||||
<td class="py-2.5 px-3">
|
||||
{{ "{:,.3f}".format(groupe.total_eng_net) }}
|
||||
</td>
|
||||
{% else %}
|
||||
<td class="py-2.5 px-3">-</td>
|
||||
<td class="py-2.5 px-3">-</td>
|
||||
<td class="py-2.5 px-3">-</td>
|
||||
<td class="py-2.5 px-3">
|
||||
{{ "{:,.3f}".format(groupe.total_eng_brut) }}
|
||||
</td>
|
||||
<td class="py-2.5 px-3">
|
||||
<span
|
||||
class="{% if groupe.total_eng_net >= 0 %}text-emerald-400{% else %}text-rose-400{% endif %}"
|
||||
>
|
||||
{{ "{:,.3f}".format(groupe.total_eng_net) }}
|
||||
</span>
|
||||
</td>
|
||||
{% endif %}
|
||||
|
||||
<td class="py-2.5 px-3" colspan="4"></td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td colspan="11" class="h-3 bg-transparent border-0"></td>
|
||||
</tr>
|
||||
{% endfor %} {% else %}
|
||||
<tr>
|
||||
<td colspan="11" class="text-center text-gray-500 py-8">
|
||||
Aucun ordre trouvé pour cette société.
|
||||
</td>
|
||||
</tr>
|
||||
{% endif %}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Popup Unique (Création d'ordre, Ajout de ligne, et Modification de ligne) -->
|
||||
<div
|
||||
id="modal-creer-ordre"
|
||||
class="fixed inset-0 bg-black/70 backdrop-blur-sm z-50 flex items-center justify-center hidden"
|
||||
>
|
||||
<div
|
||||
class="bg-gray-900 border border-gray-800 rounded-2xl p-6 w-full max-w-xl shadow-2xl text-white relative max-h-[90vh] overflow-y-auto"
|
||||
>
|
||||
<button
|
||||
onclick="fermerModalOrdre()"
|
||||
class="absolute top-4 right-4 text-gray-400 hover:text-white cursor-pointer"
|
||||
>
|
||||
<i class="fa-solid fa-xmark text-xl"></i>
|
||||
</button>
|
||||
|
||||
<h3 id="modal-title" class="text-xl font-bold mb-4 flex items-center gap-2">
|
||||
<i class="fa-solid fa-plus-circle text-emerald-500"></i> Créer un Nouvel
|
||||
Ordre
|
||||
</h3>
|
||||
|
||||
<form
|
||||
id="form-modal-ordre"
|
||||
method="POST"
|
||||
action="{{ url_for('main.creer_ordre_traitement') }}"
|
||||
class="space-y-4"
|
||||
>
|
||||
<!-- Bloc ISIN -->
|
||||
<div>
|
||||
<label class="text-xs text-gray-400">Code ISIN</label>
|
||||
<div class="flex gap-2 mt-1">
|
||||
<input
|
||||
type="text"
|
||||
id="input-isin"
|
||||
name="isin"
|
||||
required
|
||||
placeholder="Ex: NL00150001Q9"
|
||||
class="w-full bg-gray-800 border border-gray-700 rounded-lg px-3 py-2 text-sm text-white focus:outline-none focus:border-blue-500 uppercase"
|
||||
/>
|
||||
<button
|
||||
type="button"
|
||||
id="btn-verifier-isin"
|
||||
onclick="verifierIsin()"
|
||||
class="px-4 py-2 bg-blue-600 hover:bg-blue-500 text-white text-sm font-medium rounded-lg transition cursor-pointer"
|
||||
>
|
||||
Vérifier
|
||||
</button>
|
||||
</div>
|
||||
<p id="isin-status" class="text-xs mt-1"></p>
|
||||
</div>
|
||||
|
||||
<!-- Nom de l'action en lecture seule -->
|
||||
<div>
|
||||
<label class="text-xs text-gray-400">Nom de l'action</label>
|
||||
<input
|
||||
type="text"
|
||||
id="input-company-name"
|
||||
readonly
|
||||
placeholder="Sera affiché après vérification..."
|
||||
class="w-full bg-gray-950 border border-gray-800 rounded-lg px-3 py-2 text-sm text-amber-400 font-semibold focus:outline-none cursor-default mt-1"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<!-- Informations complémentaires -->
|
||||
<div
|
||||
id="action-info"
|
||||
class="hidden bg-gray-950 p-3 rounded-xl border border-gray-800 text-xs space-y-1 text-gray-300"
|
||||
>
|
||||
<p>
|
||||
<strong>Ticker :</strong> <span id="lbl-ticker"></span> |
|
||||
<strong>Devise :</strong> <span id="lbl-currency"></span>
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<!-- Ligne 1 : Date, Quantité, Prix Brut -->
|
||||
<div class="grid grid-cols-3 gap-3">
|
||||
<div>
|
||||
<label class="text-xs text-gray-400">Date Opération</label>
|
||||
<input
|
||||
type="date"
|
||||
id="input-date-op"
|
||||
name="date_op"
|
||||
required
|
||||
class="w-full bg-gray-800 border border-gray-700 rounded-lg px-3 py-2 text-sm text-white focus:outline-none focus:border-blue-500"
|
||||
/>
|
||||
</div>
|
||||
<div>
|
||||
<label class="text-xs text-gray-400">Quantité</label>
|
||||
<input
|
||||
type="number"
|
||||
step="any"
|
||||
id="input-quantite"
|
||||
name="quantite"
|
||||
required
|
||||
oninput="calculerTotauxModal()"
|
||||
class="w-full bg-gray-800 border border-gray-700 rounded-lg px-3 py-2 text-sm text-white focus:outline-none focus:border-blue-500"
|
||||
/>
|
||||
</div>
|
||||
<div>
|
||||
<label class="text-xs text-gray-400">Prix Brut</label>
|
||||
<input
|
||||
type="number"
|
||||
step="0.0001"
|
||||
id="input-prix-brut"
|
||||
name="prix_brut"
|
||||
required
|
||||
oninput="calculerTotauxModal()"
|
||||
class="w-full bg-gray-800 border border-gray-700 rounded-lg px-3 py-2 text-sm text-white focus:outline-none focus:border-blue-500"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Ligne 2 : Les 3 champs de frais -->
|
||||
<div class="grid grid-cols-3 gap-3">
|
||||
<div>
|
||||
<label class="text-xs text-gray-400">Frais Broker</label>
|
||||
<input
|
||||
type="number"
|
||||
step="0.0001"
|
||||
id="input-frais-brocker"
|
||||
name="frais_brocker"
|
||||
value="0.0000"
|
||||
oninput="calculerTotauxModal()"
|
||||
class="w-full bg-gray-800 border border-gray-700 rounded-lg px-3 py-2 text-sm text-white focus:outline-none focus:border-blue-500"
|
||||
/>
|
||||
</div>
|
||||
<div>
|
||||
<label class="text-xs text-gray-400">Frais État</label>
|
||||
<input
|
||||
type="number"
|
||||
step="0.0001"
|
||||
id="input-frais-etat"
|
||||
name="frais_etat"
|
||||
value="0.0000"
|
||||
oninput="calculerTotauxModal()"
|
||||
class="w-full bg-gray-800 border border-gray-700 rounded-lg px-3 py-2 text-sm text-white focus:outline-none focus:border-blue-500"
|
||||
/>
|
||||
</div>
|
||||
<div>
|
||||
<label class="text-xs text-gray-400">Autres Frais</label>
|
||||
<input
|
||||
type="number"
|
||||
step="0.0001"
|
||||
id="input-frais-autre"
|
||||
name="frais_autre"
|
||||
value="0.0000"
|
||||
oninput="calculerTotauxModal()"
|
||||
class="w-full bg-gray-800 border border-gray-700 rounded-lg px-3 py-2 text-sm text-white focus:outline-none focus:border-blue-500"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Aperçu dynamique des calculs en temps réel -->
|
||||
<div
|
||||
class="bg-gray-950 p-3 rounded-xl border border-gray-800 text-xs grid grid-cols-2 gap-2 text-gray-300"
|
||||
>
|
||||
<div>
|
||||
Total Frais :
|
||||
<span id="apercu-frais" class="text-amber-400 font-semibold"
|
||||
>0.000</span
|
||||
>
|
||||
</div>
|
||||
<div>
|
||||
Prix Net :
|
||||
<span id="apercu-prix-net" class="text-emerald-400 font-semibold"
|
||||
>0.000</span
|
||||
>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="grid grid-cols-3 gap-3">
|
||||
<div>
|
||||
<label class="text-xs text-gray-400">Sens (Ordre)</label>
|
||||
<select
|
||||
id="input-ordre"
|
||||
name="ordre"
|
||||
class="w-full bg-gray-800 border border-gray-700 rounded-lg px-3 py-2 text-sm text-white focus:outline-none focus:border-blue-500"
|
||||
>
|
||||
<option value="achat">Achat</option>
|
||||
<option value="vente">Vente</option>
|
||||
</select>
|
||||
</div>
|
||||
<div>
|
||||
<label class="text-xs text-gray-400">Type</label>
|
||||
<select
|
||||
id="input-type-ordre"
|
||||
name="type_ordre"
|
||||
class="w-full bg-gray-800 border border-gray-700 rounded-lg px-3 py-2 text-sm text-white focus:outline-none focus:border-blue-500"
|
||||
>
|
||||
<option value="long">Long</option>
|
||||
<option value="short">Short</option>
|
||||
</select>
|
||||
</div>
|
||||
<div>
|
||||
<label class="text-xs text-gray-400">État</label>
|
||||
<select
|
||||
id="input-etat"
|
||||
name="etat"
|
||||
class="w-full bg-gray-800 border border-gray-700 rounded-lg px-3 py-2 text-sm text-white focus:outline-none focus:border-blue-500"
|
||||
>
|
||||
<option value="actif">Actif</option>
|
||||
<option value="soldé">Soldé</option>
|
||||
<option value="annulé">Annulé</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="flex justify-end gap-2 pt-2">
|
||||
<button
|
||||
type="button"
|
||||
onclick="fermerModalOrdre()"
|
||||
class="px-4 py-2 bg-gray-800 hover:bg-gray-700 text-gray-300 rounded-lg text-sm transition cursor-pointer"
|
||||
>
|
||||
Annuler
|
||||
</button>
|
||||
<button
|
||||
type="submit"
|
||||
id="btn-valider"
|
||||
disabled
|
||||
class="px-4 py-2 bg-emerald-600/50 cursor-not-allowed text-white rounded-lg text-sm transition"
|
||||
>
|
||||
Enregistrer
|
||||
</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
document.addEventListener("DOMContentLoaded", () => {
|
||||
const toasts = document.querySelectorAll(".toast-message");
|
||||
toasts.forEach((toast) => {
|
||||
setTimeout(() => {
|
||||
toast.style.opacity = "0";
|
||||
toast.style.transform = "translateY(-10px)";
|
||||
setTimeout(() => toast.remove(), 300);
|
||||
}, 4000);
|
||||
});
|
||||
calculerTotauxModal();
|
||||
});
|
||||
|
||||
// Calcul dynamique : Prix Net unitaire = Prix Brut + Frais Totaux
|
||||
function calculerTotauxModal() {
|
||||
const quantite =
|
||||
parseFloat(document.getElementById("input-quantite").value) || 0;
|
||||
const prixBrut =
|
||||
parseFloat(document.getElementById("input-prix-brut").value) || 0;
|
||||
const fraisBrocker =
|
||||
parseFloat(document.getElementById("input-frais-brocker").value) || 0;
|
||||
const fraisEtat =
|
||||
parseFloat(document.getElementById("input-frais-etat").value) || 0;
|
||||
const fraisAutre =
|
||||
parseFloat(document.getElementById("input-frais-autre").value) || 0;
|
||||
|
||||
const selectOrdre = document.getElementById("input-ordre");
|
||||
const sensOrdre = selectOrdre
|
||||
? selectOrdre.value.trim().toLowerCase()
|
||||
: "achat";
|
||||
|
||||
const totalFrais = fraisBrocker + fraisEtat + fraisAutre;
|
||||
|
||||
let prixNet = 0;
|
||||
if (sensOrdre === "vente") {
|
||||
prixNet = prixBrut - totalFrais;
|
||||
} else {
|
||||
prixNet = prixBrut + totalFrais;
|
||||
}
|
||||
|
||||
// Engagement Net = Prix Net * Quantité
|
||||
const engNet = quantite * prixNet;
|
||||
|
||||
// Mise à jour des éléments dans le DOM (adaptez les IDs selon vos balises HTML)
|
||||
document.getElementById("apercu-frais").textContent = totalFrais.toFixed(4);
|
||||
document.getElementById("apercu-prix-net").textContent = prixNet.toFixed(4);
|
||||
const apercuEngNet = document.getElementById("apercu-eng-net");
|
||||
if (apercuEngNet) {
|
||||
apercuEngNet.textContent = engNet.toFixed(2);
|
||||
}
|
||||
}
|
||||
|
||||
// Écouteurs pour déclencher le calcul lors des saisies
|
||||
[
|
||||
"input-quantite",
|
||||
"input-prix-brut",
|
||||
"input-frais-brocker",
|
||||
"input-frais-etat",
|
||||
"input-frais-autre",
|
||||
"input-ordre",
|
||||
].forEach((id) => {
|
||||
document.getElementById(id)?.addEventListener("input", calculerTotauxModal);
|
||||
document
|
||||
.getElementById(id)
|
||||
?.addEventListener("change", calculerTotauxModal);
|
||||
});
|
||||
|
||||
function ouvrirModalOrdre() {
|
||||
const modal = document.getElementById("modal-creer-ordre");
|
||||
const form = document.getElementById("form-modal-ordre");
|
||||
const title = document.getElementById("modal-title");
|
||||
const isinInput = document.getElementById("input-isin");
|
||||
const btnVerif = document.getElementById("btn-verifier-isin");
|
||||
const companyInput = document.getElementById("input-company-name");
|
||||
const btnValider = document.getElementById("btn-valider");
|
||||
|
||||
modal.classList.remove("hidden");
|
||||
form.action = "{{ url_for('main.creer_ordre_traitement') }}";
|
||||
title.innerHTML =
|
||||
'<i class="fa-solid fa-plus-circle text-emerald-500"></i> Créer un Nouvel Ordre';
|
||||
|
||||
isinInput.value = "";
|
||||
isinInput.readOnly = false;
|
||||
isinInput.classList.remove("bg-gray-950", "cursor-default");
|
||||
isinInput.classList.add("bg-gray-800");
|
||||
|
||||
btnVerif.style.display = "inline-block";
|
||||
companyInput.value = "";
|
||||
|
||||
form.reset();
|
||||
document.getElementById("action-info").classList.add("hidden");
|
||||
calculerTotauxModal();
|
||||
|
||||
btnValider.disabled = true;
|
||||
btnValider.classList.add("bg-emerald-600/50", "cursor-not-allowed");
|
||||
btnValider.classList.remove(
|
||||
"bg-emerald-600",
|
||||
"hover:bg-emerald-500",
|
||||
"cursor-pointer",
|
||||
);
|
||||
}
|
||||
|
||||
function ouvrirModalLigneOrdre(ordreId, isin, companyName, ticker) {
|
||||
const modal = document.getElementById("modal-creer-ordre");
|
||||
const form = document.getElementById("form-modal-ordre");
|
||||
const title = document.getElementById("modal-title");
|
||||
const isinInput = document.getElementById("input-isin");
|
||||
const btnVerif = document.getElementById("btn-verifier-isin");
|
||||
const companyInput = document.getElementById("input-company-name");
|
||||
const btnValider = document.getElementById("btn-valider");
|
||||
|
||||
modal.classList.remove("hidden");
|
||||
form.action = `/ordre/${ordreId}/ajouter-ligne`;
|
||||
title.innerHTML =
|
||||
'<i class="fa-solid fa-plus text-emerald-500"></i> Ajouter une ligne à l\'ordre';
|
||||
|
||||
isinInput.value = isin;
|
||||
isinInput.readOnly = true;
|
||||
isinInput.classList.add("bg-gray-950", "cursor-default");
|
||||
isinInput.classList.remove("bg-gray-800");
|
||||
|
||||
btnVerif.style.display = "none";
|
||||
companyInput.value = companyName + (ticker ? ` (${ticker})` : "");
|
||||
|
||||
form.reset();
|
||||
isinInput.value = isin;
|
||||
companyInput.value = companyName + (ticker ? ` (${ticker})` : "");
|
||||
document.getElementById("action-info").classList.add("hidden");
|
||||
calculerTotauxModal();
|
||||
|
||||
btnValider.disabled = false;
|
||||
btnValider.classList.remove("bg-emerald-600/50", "cursor-not-allowed");
|
||||
btnValider.classList.add(
|
||||
"bg-emerald-600",
|
||||
"hover:bg-emerald-500",
|
||||
"cursor-pointer",
|
||||
);
|
||||
}
|
||||
|
||||
function ouvrirModalModifierLigne(
|
||||
piedId,
|
||||
isin,
|
||||
companyName,
|
||||
ticker,
|
||||
dateOp,
|
||||
quantite,
|
||||
prixBrut,
|
||||
fraisBrocker,
|
||||
fraisEtat,
|
||||
fraisAutre,
|
||||
ordre,
|
||||
typeOrdre,
|
||||
etat,
|
||||
) {
|
||||
const modal = document.getElementById("modal-creer-ordre");
|
||||
const form = document.getElementById("form-modal-ordre");
|
||||
const title = document.getElementById("modal-title");
|
||||
const isinInput = document.getElementById("input-isin");
|
||||
const btnVerif = document.getElementById("btn-verifier-isin");
|
||||
const companyInput = document.getElementById("input-company-name");
|
||||
const btnValider = document.getElementById("btn-valider");
|
||||
|
||||
modal.classList.remove("hidden");
|
||||
form.action = `/modifier-ligne-ordre/${piedId}`;
|
||||
title.innerHTML =
|
||||
'<i class="fa-solid fa-pen text-blue-500"></i> Modifier la ligne d\'ordre';
|
||||
|
||||
isinInput.value = isin;
|
||||
isinInput.readOnly = true;
|
||||
isinInput.classList.add("bg-gray-950", "cursor-default");
|
||||
isinInput.classList.remove("bg-gray-800");
|
||||
|
||||
btnVerif.style.display = "none";
|
||||
companyInput.value = companyName + (ticker ? ` (${ticker})` : "");
|
||||
|
||||
document.getElementById("input-date-op").value = dateOp;
|
||||
document.getElementById("input-quantite").value = quantite;
|
||||
document.getElementById("input-prix-brut").value = prixBrut;
|
||||
document.getElementById("input-frais-brocker").value = fraisBrocker;
|
||||
document.getElementById("input-frais-etat").value = fraisEtat;
|
||||
document.getElementById("input-frais-autre").value = fraisAutre;
|
||||
document.getElementById("input-ordre").value = ordre.toLowerCase();
|
||||
document.getElementById("input-type-ordre").value = typeOrdre.toLowerCase();
|
||||
document.getElementById("input-etat").value = etat.toLowerCase();
|
||||
document.getElementById("action-info").classList.add("hidden");
|
||||
|
||||
calculerTotauxModal();
|
||||
|
||||
btnValider.disabled = false;
|
||||
btnValider.classList.remove("bg-emerald-600/50", "cursor-not-allowed");
|
||||
btnValider.classList.add(
|
||||
"bg-emerald-600",
|
||||
"hover:bg-emerald-500",
|
||||
"cursor-pointer",
|
||||
);
|
||||
}
|
||||
|
||||
function fermerModalOrdre() {
|
||||
document.getElementById("modal-creer-ordre").classList.add("hidden");
|
||||
}
|
||||
|
||||
function verifierIsin() {
|
||||
const isin = document.getElementById("input-isin").value.trim();
|
||||
const statusEl = document.getElementById("isin-status");
|
||||
const infoBox = document.getElementById("action-info");
|
||||
const companyInput = document.getElementById("input-company-name");
|
||||
const btnValider = document.getElementById("btn-valider");
|
||||
|
||||
if (!isin) {
|
||||
statusEl.textContent = "Veuillez saisir un code ISIN.";
|
||||
statusEl.className = "text-xs mt-1 text-rose-400";
|
||||
return;
|
||||
}
|
||||
|
||||
fetch("/api/verifier_isin", {
|
||||
method: "POST",
|
||||
headers: { "Content-Type": "application/json" },
|
||||
body: JSON.stringify({ isin: isin }),
|
||||
})
|
||||
.then((response) => response.json())
|
||||
.then((data) => {
|
||||
if (data.exists) {
|
||||
statusEl.textContent = "✔ Action reconnue dans la base.";
|
||||
statusEl.className = "text-xs mt-1 text-emerald-400";
|
||||
|
||||
companyInput.value = data.company_name || data.nom || "";
|
||||
|
||||
document.getElementById("lbl-ticker").textContent =
|
||||
data.ticker || "N/A";
|
||||
document.getElementById("lbl-currency").textContent = data.currency;
|
||||
infoBox.classList.remove("hidden");
|
||||
|
||||
btnValider.disabled = false;
|
||||
btnValider.classList.remove(
|
||||
"bg-emerald-600/50",
|
||||
"cursor-not-allowed",
|
||||
);
|
||||
btnValider.classList.add(
|
||||
"bg-emerald-600",
|
||||
"hover:bg-emerald-500",
|
||||
"cursor-pointer",
|
||||
);
|
||||
} else {
|
||||
statusEl.textContent =
|
||||
"✖ Cet ISIN n'existe pas dans la table actions.";
|
||||
statusEl.className = "text-xs mt-1 text-rose-400";
|
||||
|
||||
companyInput.value = "";
|
||||
infoBox.classList.add("hidden");
|
||||
|
||||
btnValider.disabled = true;
|
||||
btnValider.classList.add("bg-emerald-600/50", "cursor-not-allowed");
|
||||
btnValider.classList.remove(
|
||||
"bg-emerald-600",
|
||||
"hover:bg-emerald-500",
|
||||
"cursor-pointer",
|
||||
);
|
||||
}
|
||||
})
|
||||
.catch((error) => {
|
||||
console.error("Erreur lors de la vérification de l'ISIN:", error);
|
||||
statusEl.textContent = "Erreur de communication avec le serveur.";
|
||||
statusEl.className = "text-xs mt-1 text-rose-400";
|
||||
});
|
||||
}
|
||||
</script>
|
||||
{% endblock %}
|
||||
Reference in New Issue
Block a user