Alex van Niekerk
    • Create new note
    • Create a note from template
      • Sharing URL Link copied
      • /edit
      • View mode
        • Edit mode
        • View mode
        • Book mode
        • Slide mode
        Edit mode View mode Book mode Slide mode
      • Customize slides
      • Note Permission
      • Read
        • Only me
        • Signed-in users
        • Everyone
        Only me Signed-in users Everyone
      • Write
        • Only me
        • Signed-in users
        • Everyone
        Only me Signed-in users Everyone
      • Engagement control Commenting, Suggest edit, Emoji Reply
    • Invite by email
      Invitee

      This note has no invitees

    • Publish Note

      Share your work with the world Congratulations! 🎉 Your note is out in the world Publish Note

      Your note will be visible on your profile and discoverable by anyone.
      Your note is now live.
      This note is visible on your profile and discoverable online.
      Everyone on the web can find and read all notes of this public team.
      See published notes
      Unpublish note
      Please check the box to agree to the Community Guidelines.
      View profile
    • Commenting
      Permission
      Disabled Forbidden Owners Signed-in users Everyone
    • Enable
    • Permission
      • Forbidden
      • Owners
      • Signed-in users
      • Everyone
    • Suggest edit
      Permission
      Disabled Forbidden Owners Signed-in users Everyone
    • Enable
    • Permission
      • Forbidden
      • Owners
      • Signed-in users
    • Emoji Reply
    • Enable
    • Versions and GitHub Sync
    • Note settings
    • Note Insights New
    • Engagement control
    • Make a copy
    • Transfer ownership
    • Delete this note
    • Save as template
    • Insert from template
    • Import from
      • Dropbox
      • Google Drive
      • Gist
      • Clipboard
    • Export to
      • Dropbox
      • Google Drive
      • Gist
    • Download
      • Markdown
      • HTML
      • Raw HTML
Menu Note settings Note Insights Versions and GitHub Sync Sharing URL Create Help
Create Create new note Create a note from template
Menu
Options
Engagement control Make a copy Transfer ownership Delete this note
Import from
Dropbox Google Drive Gist Clipboard
Export to
Dropbox Google Drive Gist
Download
Markdown HTML Raw HTML
Back
Sharing URL Link copied
/edit
View mode
  • Edit mode
  • View mode
  • Book mode
  • Slide mode
Edit mode View mode Book mode Slide mode
Customize slides
Note Permission
Read
Only me
  • Only me
  • Signed-in users
  • Everyone
Only me Signed-in users Everyone
Write
Only me
  • Only me
  • Signed-in users
  • Everyone
Only me Signed-in users Everyone
Engagement control Commenting, Suggest edit, Emoji Reply
  • Invite by email
    Invitee

    This note has no invitees

  • Publish Note

    Share your work with the world Congratulations! 🎉 Your note is out in the world Publish Note

    Your note will be visible on your profile and discoverable by anyone.
    Your note is now live.
    This note is visible on your profile and discoverable online.
    Everyone on the web can find and read all notes of this public team.
    See published notes
    Unpublish note
    Please check the box to agree to the Community Guidelines.
    View profile
    Engagement control
    Commenting
    Permission
    Disabled Forbidden Owners Signed-in users Everyone
    Enable
    Permission
    • Forbidden
    • Owners
    • Signed-in users
    • Everyone
    Suggest edit
    Permission
    Disabled Forbidden Owners Signed-in users Everyone
    Enable
    Permission
    • Forbidden
    • Owners
    • Signed-in users
    Emoji Reply
    Enable
    Import from Dropbox Google Drive Gist Clipboard
       Owned this note    Owned this note      
    Published Linked with GitHub
    • Any changes
      Be notified of any changes
    • Mention me
      Be notified of mention me
    • Unsubscribe
    # Spécifications Technique 2.16.0 Corrigées ### ==TMA-155 Ajout des frais de distribution en fiche produit et actualisation composition pack (si existant).== Travail a faire : - Lors de l'intégration d'un CGN, valoriser et stocker la valeur contenue dans les champs **tauxDistri** et **fraiDistri** associés à un article si une valeur est différente de "vide". Ajouter deux nouveaux champs en fiche article : **Taux frais de distribution** : XX,XX % **Montant frais de distribution** : YY,YY € #### **Scénario 1 : Visualiser la fiche article depuis le catalogue général** Conditions **Taux frais de distribution** : ``` Si tauxDistri > 0 Taux frais de distribution = **tauxDistri** % Sinon si tauxDistri == 0 Taux frais de distribution = 0.00 % Sinon Ne pas afficher la ligne ``` Conditions **Montant frais de distribution** : ``` Si fraisDistri > 0 Montant frais de distribution = **fraisDistri** % Sinon si tauxDistri == 0 Montant frais de distribution = 0.00 € Sinon Ne pas afficher la ligne ``` #### **Scénario 2 : Visualiser la fiche article depuis une commande** La valorisation des deux valeurs se base selon les taux des remises MLO ET ALO. Ce scénario est valable à **n'importe quel statut de la commande**. :::info ### Mise à jour Après analyse plus approfondie, il n'est plus nécessaire de passer par un service dédié. Le bon de commande possède bel et bien le taux associé à une remise MLO ALO. Les deux valeurs peuvent donc être calculées coté front sans passer par un nouveau service. ::: Algorithme a exécuter (uniquement si on vient du bon de commande) : ``` taux = 0; remises = liste des remises du bon de commande : Si remises contient la remise de type MLO ET ALO taux = 0; Sinon Si remises contient la remise de type MLO taux = tauxRemiseMLO Sinon Si remises contient la remise de type ALO taux = tauxRemiseALO Si taux est > 0 frais distrib = prix de l'article * taux / 100; taux distrib = +taux % Renseigner les deux lignes Taux frais de distribution et Montant frais de distribution Sinon Ne pas afficher les lignes ``` Respecter ce fonctionnement avec les boutons précédant suivant. #### **En addition** :::info ### Mise à jour Un nouvel onglet 'Contenu' est ajouté pour y afficher le tableau "Composition du pack". ::: Le tableau "Composition du pack" est à retirer de l'onglet composition et infos techniques. **Condition pour afficher le nouvel onglet 'Contenu'** ``` Si proprietes.attr.type == 'BOX' ET qu'il existe au moins 1 composition d'articles : Afficher un nouvel onglet à droite de Composition et infos techniques Insérer le même tableau "Composition du pack" (toute la largeur de l'écran) qui se base sur les données issues de CGN. Ajouter deux nouvelles colonnes dans le tableau ``` Précision sur les deux nouvelles colonnes : **Nom colonne : Prix hors FD (En €)** ``` Si tauxDistri > 0 PrixHorsFD = puht - fraisDistri Sinon PrixHorsFD = puht ``` **Nom colonne : Frais distrib. (en €)** ``` Si tauxDistri > 0 FraisDistrib = fraisDistri Sinon si tauxDistri == 0 FraisDistrib = 0 Sinon FraisDistrib = vide ``` Renommer la colonne Prix de vente unitaire HT par **Prix Catalogue HT (en €)** ### ==TMA-127 - Persistance des filtres sur onglet Liste Magasin/Recap Commande pour utilisateur SA== La persistance des filtres se fait uniquement coté front. L'objectif est d'ajouter de nouveaux éléments persistants et de garder la même logique de persistance des filtres dans le projet. Les filtres à persister sont : "conseiller ALI/NAL/ULF", "plateforme", "statut" et "BOX/CAM Obligatoire/Vrac" Filtres persistant à ajouter au fichier environnement.ts : ```ts // Filtre BOX CAM VRAC de l'onglet recap commande RECAP_COMMANDE_FILTERS_BOX_CAM_VRAC: 'RecapCommandeFiltersBCC', // Filtre Plateforme de l'onglet recap commande et liste magasin GES_FILTERS_PLATEFORMES: 'GesFiltersPlateformes', // Filtre conseillers de l'onglet recap commande et liste magasin GES_FILTERS_CONSEILLERS: 'GesFiltersConseillers', // Filtre Statut de l'onglet liste magasins LISTE_MAGASIN_FILTERS_STATUT: 'ListeMagFiltersStatut' ``` Ajouter un service 'GestionnaireFiltreService' Implémenter les fonctions suivantes : ```ts // Permet de stocker les valeurs sélectionnées du filtre en question void registerFiltre(valeur, filtre) // Permet de récupérer les valeurs précédemment sélectionnées du filtre en question getValuesFiltre(filtre) // Permet de supprimer les valeurs des filtres RECAP_COMMANDE_FILTERS_BOX_CAM_VRAC, GES_FILTERS_PLATEFORMES, LISTE_MAGASIN_FILTERS_STATUT resetFiltre() ``` **Algorithme à intégrer :** - Le filtre "conseiller ALI/NAL/ULF" est tout le temps persistant. (Il n'y a pas de bouton de réinitialisation). - Ne pas conserver le filtre "Statut", "Plateforme et BOX/CAM Obligatoire/Vrac" lors d'un changement d'offre ni après déconnexion/reconnexion Uniquement filtre conseiller ``` // Initilisation Lors du chargement de l'onglet recap-commande ou liste magasins values = getValuesFiltre(GES_FILTERS_CONSEILLERS); Si values est vide : Charger la page (Existant à ne pas modifier). Sinon Associer les conseillers avec values et filtrer selon les values ``` ``` // Click sur conseiller registerFiltre(listeConseillerSelectionné, GES_FILTERS_CONSEILLERS) ``` Filtre "Statut", "Plateforme et "BOX/CAM Obligatoire/Vrac" ``` // A repeter pour chaque filtre a l'initilsiation values = getValuesFiltre(FILTRE); Si values est vide : Charger la page (Existant à ne pas modifier). Sinon Associer le FILTRE avec values et filtrer selon les valeurs ``` ``` // Click sur le filtre registerFiltre(listeduFiltreSelectionné, FILTRE) ``` ``` // Sortie de l'offre Si l'utilisateur change d'url et que l'url ne contient pas '/references' ou '/magasins' ou '/recap' ou 'performances' resetFiltre() ``` :::info ### Risques de régression Risque que les autres filtres persistants ne fonctionnent plus exactement suite à l'ajout des 4 nouveaux filtres. Du nouveau code vient s'ajouter aux composants B2bioDetailOffreRecapPage et B2bioListeMagasinsComponent qui sont déjà assez complexes. De nouvelles conditions vont donc s'ajouter ce qui pourrait potentiellement changer le comportement existant. Il pourrait y avoir des difficultés à valoriser les filtres plateformes puisqu'ils ne sont pas structurés de la même manière sur les deux onglets. Ces éléments feront l'objet d'une recette fine. ::: ### ==TMA-161 - Affichage du suivi de commande en magasin== Modifier l'affichage des offres sur l'onglet suivi de commande en fonction de leur ancienneté et de leur type. Uniquement coté back-end. **Travail à effectuer :** 1. Ajouter de nouvelles valeurs dans la table ParametreFonctionnel et les indiquer dans le fichier ParametreFonctionnelCode.java Ajouter 5 nouvelles cle/valeurs en BDD (table paramètres fonctionnels, schéma référentiel) correspondant au critère d'affichage (en nb de mois) : - PRECO : 6 - PRECO_EVENEMENTIEL : 14 - PRECO_FEL : 6 - OPE : 2 - OPE_FEL : 2 2. Modifier le endpoint `/search` du micro-service commande et l'adapter en fonction des valeurs indiquées dans la table ParametreFonctionnel. Fonction a créer : ```java public EsPagedResponse<CommandeEsDto> suiviDeCommande(SearchCommandeDto searchDto) ``` Ne pas impacter la requete Elastic search Ajouter du code JAVA qui va venir filtrer les catalogues en fonction des valeurs indiquées dans la table ParametreFonctionnel, puis associer les catalogues filtrés avec les commandes. Modifier le end-point coté front pour appeler le nouveau afin d'afficher les commandes filtrées. **Offre à filter** #### Offre précommande ferme ou avec réassort Afficher les offres de type "offre évenementielle" datant de moins de 14 mois après la date de fin d'opération (commandes préco et réassort) --> Récupérer en base les commandes si finCommande >= dateDuJour - 14 mois puis afficher commande --> Récupérer en base les commandes si dateFinReassort >= dateDuJour - 14 mois puis afficher commande Afficher les offres pour tous les autres types datant de moins de 6 mois après date de fin d'opération (commandes préco et réassort) --> Récupérer en base les commandes si finCommande >= dateDuJour - 6 mois puis afficher commande --> Récupérer en base les commandes si dateFinReassort >= dateDuJour - 6 mois puis afficher commande #### Offre précommande FEL Afficher les offres datant de moins de deux mois après la date de fin de précommande --> Récupérer en base les commandes si dateFinPrecommande >= dateDuJour - 2 mois puis afficher commande #### Offre opération Afficher les offres de type "FEL" datant de moins de 2 mois après la date de création de commande --> Récupérer en base les commandes si dateCreationCommande >= dateDuJour - 2 mois puis afficher commande Afficher les autres offres datant de moins de 2 mois après la date de création de commande réelle --> Récupérer en base les commandes si dateCreationCommande >= dateDuJour - 2 mois puis afficher commande :::info ### Remarque La requete va par conséquent prendre légèrement plus de temps qu'aujourdhui. ::: ### ==TMA-314 - Suppression sur offre en réassort des semaines ou jours affichés en opérations== #### **Travail a faire :** 1. Masquer la colonne 'Sem Jour livraison' 2. Modifier l'intégration des articles à une commande si l'offre est en période de réassort lors d'un retour ERP. 3. Modifier l'affichage du recap commande 4. Ajout d'un nouveau flag pour déterminer que la commande est de type REASSORT #### **Ajout d'article à une commande:** precommande = NULL signifie "Précommande avec réassort" ``` Si precommande == NULL ET que la date du jour est supérieur ou égale à la date de debut réassort FLAG REASSORT = true (commande) article.commandeSemaine = vide; article.typeSemaine = null; article.semaineOriginal = null; article.semaine = null; Sinon FLAG REASSORT = false (commande) ``` #### **Retour ERP** Lors de l'intégration d'une offre sur une commande dont le flag REASSORT = true, l'intégration se fait uniquement sur **codeArt** #### **Page récap coté gestionnaire** Ajout d'une nouvelle colonne "OPE" sur les onglets : 'Contrôle des quantités / engagement / Total'. La colonne est affichée dès lors qu'une des commandes du tableau contient le flag REASSORT. Cette colonne OPE, contiendra le cumul des quantités de l'article correspondant dont le flag REASSORT de la commande est égal à TRUE. #### Export appro et tableau intégration Lors de l'export des deux tableaux, les quantités renvoyées sont uniquement les commandes ou le flag REASSORT est différent de TRUE. **Travail à faire**: Ajuster les requêtes ES de récupération de commande , en ajoutant la condition 'REASSORT !== TRUE' lors des deux exports. ### ==TMA-308 Ordre d'affichage du BDC sur lot2== Ajouter le champ "ordre" sur les articles des catalogues d'offres. Trier les articles en fonction de cette nouvelle valeur dans le BDC, l'export BDC Excel, l'affichage SA et les retours ERP par ordre d'affichage croissant. Règle de regroupement : Si valeur de champ "ordre" consécutive ET si arborescence en commun, alors regrouper l'arborescence (nature/rayon/famille/sous-famille) des articles au maximum, Sinon répéter les niveaux. **Travail à effectuer :** Le tri se fera uniquement coté back-end, au niveau de la fonction sortArticlesCatalogueMarque du fichier CatalogueESHelper.java. Cela veut dire que les niveaux seront triés en amont coté back-end et sauvegardé via ElasticSearch. Le front récupérera donc les articles déjà triés. 1. Adapter la fonction de tri des niveaux lors de l’intégration d’une offre en y ajoutant de nouvelles règles métiers qui respectent les scénarios suivants : #### **Scénario 1 : Champs "ordre" nul** Si le champ "ordre" n'existe pas alors on laisse l'ordre existant (aujourd'hui). #### **Scénario 2 : Tous les articles possèdent un champ "ordre" différent de null** Trier les articles en fonction de leur valeur "ordre" par ordre croissant ET respecter règle de regroupement. Si même valeur de champ "ordre" alors on laisse l'ordre existant (aujourd'hui). #### **Scénario 3 : Seulement une partie des articles possèdent un champ "ordre" non nul** Si champ "ordre" alors afficher en premier ces articles par ordre croissant ET respecter règle de regroupement puis afficher les autres articles d'ordre existant (aujourd'hui). :::info ### Risque de regression Potentiel risque de régression au niveau de l’export du bon de commande. Potentiel risque de régression au niveau de l’impression. ::: ### ==TMA-281 - Ré-import des stocks limités== #### **Travail a faire :** - Ajouter Redis et Redisson (utile pour les verrous) - Ajouter un service dédié à Redis au projet BtoBio-Back - Service de connection à Redis - Implémenter les différentes fonction utiles à la récupération et la modification de données - Prévoir l'architecture permettant l'ajout d'un nouveau service REST dédié à Redis - Intégrer redis au micro-service Catalogue et Commande (injection de dépendance) - Ajouter le champ "stockLimite": (boolean) à un catalogue (true = si au moins un article est à stock limité sinon false) - Ajouter le champ "stockLimite": (boolean) à un article du catalogue (true = un article à stock limité sinon false) - Ajouter le champ "maj" à CatalogueDto (XML OFFRE COM) - Adapter la fonction d'import d'une offre pour permettre la mise à jour du stock sur les articles associés à une offre #### **Architecture Redis** CLE : ``` codeOffre#codeProduit // A verifier codeOffre peut pas '#' et codeProduit ``` VALEUR : ```json { "stockCommandee" : number, // Nombre d'articles commandés "stockActuel" : number // La quantité commandable associée à l'article } ``` :::info ### Attention En clé, il faut ajouter le code de l'offre et le code produit. Nous suggérons d'ajouter le symbole '**#**' comme délimiteur. Cela implique que le code produit ET que le code d'une offre ne pourra jamais contenir le symbole '**#**'. ::: #### **Initialisation de redis** Lors du lancement du micro service commande et catalogue. Le micro service en question fera uniquement en sorte de se connecter à l’instance de redis. Aucun calcul et aucun chargement de données ne sont effectués. #### **Algorithme stock restant Integration d'une offre** Lors de l'intégration d'un Catalogue d'offre ``` Si <maj></maj> est présent ET que maj est égale à "contingentement" Mettre a jour les stocks de tous les articles Pour chaque article du fichier XML: Si l'article est connu du catalogue Si contingentement est vide ou absent stockLimite = false (L'article n'a pas de stock limité) Sinon stockLimite = true (L'article à un stock limité) POSER VERROU(codeOffre#codeArticle) Si aucune valeur existe dans redis stockActuel = contingentement stockCommandee = 0 Sinon Si stockCommandee est vide (exemple : erreur serveur, tout est supprimé pour X raison) stockCommandee = Récupération des quantités déja commandées (sum(qte) articlecommande coté BDD) Si contingentement >= stockCommandee stockActuel = contingentement (mise à jour du stock) Sinon stockActuel = stockCommandee Afficher Warning LIBERER VERROU(codeOffre#codeArticle) Ajout d'un AUDIT 'CONTINGENTEMENT' qui contient le libelle 'Mise à jour du contingentement du codeArticle : XXXXX avec un stock à XX.XX du catalogue XXXXXX' Pour chaque article du catalogue non présent dans le fichier XML : POSER VERROU(codeOffre#codeArticle) stockActuel = stockCommandee LIBERER VERROU(codeOffre#codeArticle) Sinon Laisser traitement actuel ``` ### ==TMA-280 - Gestion des stocks limités== #### **Travail a faire :** - Ajouter un nouveau end point (coté back) permettant de fournir les stocks restant à partir d'une liste de code article. - Ajouter une nouvelle ligne 'Stock restant XXX' (coté front) (5 digits possibles sans retour à la ligne uniquement sur la première ligne) en dessous de la quantité d'un article en bon de commande et en fiche article qui affiche le stock restant associé à l'article. - Modifier la requête PATCH (coté back) permettant l'ajout ou la modification d'une quantité d'un article en vérifiant si la quantité demandée est inférieur ou égale au stock restant ainsi que la gestion d'erreur. - Ajuster le service de gestion d'erreur (coté front) qui vient ajouter des erreurs bloquantes si qteDemandé >= stockRestant #### **Algorithme Lecture** Lors de la lecture d'un article à stock restant, si aucune valeur n'est présente via REDIS (Exemple : erreur serveur, ou l'instance redis est supprimé pour X raison), il est nécessaire de recalculer les quantités commandées. La vérification si le stock est inexistant sera séquentiel. ``` // Fonction de lecture des stocks pour une commande magasin Stocks = Récupération des stock de rédis Si(Stocks inexistant){ // L'ensemble des appelants sera bloqué via l'utilisation du synchronized Lock de la clé Redis(codeOffre#codeProduit) Stocks.stockActuel = Récupération du stock actuel de l'article pour l'offre Stocks.stockCommandee = Récupération des quantités déja commandées (sum(qte) articlecommande) Stocks = Valorisation du stock dans la variable locale Mise à jour dans Redis de la clé Redis(codeOffre#codeProduit) Libération du Lock de la clé Redis(codeOffre#codeProduit) } renvoyer Stocks ``` #### **Accès au bon de commande** Lors de l'accès au bon de commande, si stockLimite du catalogue est égal à true alors appeller le nouveau service REST qui va renvoyer les stocks limités des articles. Et appeler le service de gestion d'erreur qui va automatiquement afficher les erreurs s'il y en a. #### **Scénario 1 : Création d'une commande (bon de commande ou fiche article)** Aucune mise à jour REDIS peut être effectuée. ``` Si la quantité est supérieure au stock restant ALORS - Créer commande ET Afficher message d'erreur ``` #### **Scénario 2 : Modification de commande (Statut Brouillon) (bon de commande ou fiche article)** Aucune mise à jour REDIS peut être effectuée. ``` Si la quantité est supérieure au stock restant ALORS - Modifier la quantité et Afficher message erreur ``` #### **Scénario 3 : Click sur "commander"** Cet algorithme permet une validation ou un refus global de la commande. Une mise à jour REDIS est effectuée. Les quantités ne seront pas sauvegardées avant de faire les contrôles des stocks restants. Un verrou mettra tous les autres clients en attente tant qu'il ne sera pas libéré. Algorithme executé coté back-end. ``` // Fonction existante lors de l'action commander Parcourir chaque article avec stockRestant de la commande List<VERROU>.add(Verou article) // Liste des verrous des articles stocks Si qte <= stock disponible article suivant else Erreur, Envoyer ExceptionCustomStock ( status 409) sortie de boucle et libération de tous les verrous Fin de boucle Parcourir tous les vérrous si pas erreur Mise à jour de Redis et sauvegarde des quantités pour chaque article finsi Libération du verrou Fin de boucle ``` Si une erreur est renvoyée, le front détectera l'exception, appellera le nouveau service REST qui va renvoyer les nouveaux stocks limités des articles et afficher les erreurs bloquante. #### **Scénario 4 : Modification de commande (Statut Commandé) (bon de commande ou fiche article)** Tout ce qui est autorisé par le stock restant est enregistré et sauvegardé en base et REDIS. Tout ce qui excède les quantités restantes est refusé, avec message d'erreur, le stock restant est actualisé au niveau du bon de commande MAIS on conserve dans le champ de saisie, la nouvelle demande, charge à l'utilisateur d'adapter sa quantité au stock Algorithme executé coté back-end. ``` // Fonction existante lors de l'action commander Parcourir chaque article avec stockRestant de la commande Poser verrou Si qte <= stock disponible Mise à jour BDD Mise à jour coté REDIS else erreur = true Libération du verrou Fin de boucle Si erreur = true Envoyer erreur (notifier front) ``` Le même algorithme ci-dessus sera exécuté. La seule différence est que : ``` Lors de la mise à jour de redis : La quantité à metre à jour = QteSaisie - QtePrecedente ``` #### **Scénario 5 : Modification d'une quantité coté GESTIONNAIRE (Controle des quantités)** ``` Pour chaque article du tableau Si l'Article contient un stock restant - Alors griser la colonne (background-color : lightgrey;) + readonly Sinon - Laisser tel quel ``` :::info ### Risque de regression Risque de régression sur l'affichage du bon de commande puisque le bon de commande contient déjà du code assez complexe, il se pourrait que certaines actions ne se comportent pas exactement de la même manière, comme c'est le cas aujourd'hui suite à l'ajout de nouvelles fonctions qui viennent complexifier le model métier. :::

    Import from clipboard

    Paste your markdown or webpage here...

    Advanced permission required

    Your current role can only read. Ask the system administrator to acquire write and comment permission.

    This team is disabled

    Sorry, this team is disabled. You can't edit this note.

    This note is locked

    Sorry, only owner can edit this note.

    Reach the limit

    Sorry, you've reached the max length this note can be.
    Please reduce the content or divide it to more notes, thank you!

    Import from Gist

    Import from Snippet

    or

    Export to Snippet

    Are you sure?

    Do you really want to delete this note?
    All users will lose their connection.

    Create a note from template

    Create a note from template

    Oops...
    This template has been removed or transferred.
    Upgrade
    All
    • All
    • Team
    No template.

    Create a template

    Upgrade

    Delete template

    Do you really want to delete this template?
    Turn this template into a regular note and keep its content, versions, and comments.

    This page need refresh

    You have an incompatible client version.
    Refresh to update.
    New version available!
    See releases notes here
    Refresh to enjoy new features.
    Your user state has changed.
    Refresh to load new user state.

    Sign in

    Forgot password

    or

    By clicking below, you agree to our terms of service.

    Sign in via Facebook Sign in via Twitter Sign in via GitHub Sign in via Dropbox Sign in with Wallet
    Wallet ( )
    Connect another wallet

    New to HackMD? Sign up

    Help

    • English
    • 中文
    • Français
    • Deutsch
    • 日本語
    • Español
    • Català
    • Ελληνικά
    • Português
    • italiano
    • Türkçe
    • Русский
    • Nederlands
    • hrvatski jezik
    • język polski
    • Українська
    • हिन्दी
    • svenska
    • Esperanto
    • dansk

    Documents

    Help & Tutorial

    How to use Book mode

    Slide Example

    API Docs

    Edit in VSCode

    Install browser extension

    Contacts

    Feedback

    Discord

    Send us email

    Resources

    Releases

    Pricing

    Blog

    Policy

    Terms

    Privacy

    Cheatsheet

    Syntax Example Reference
    # Header Header 基本排版
    - Unordered List
    • Unordered List
    1. Ordered List
    1. Ordered List
    - [ ] Todo List
    • Todo List
    > Blockquote
    Blockquote
    **Bold font** Bold font
    *Italics font* Italics font
    ~~Strikethrough~~ Strikethrough
    19^th^ 19th
    H~2~O H2O
    ++Inserted text++ Inserted text
    ==Marked text== Marked text
    [link text](https:// "title") Link
    ![image alt](https:// "title") Image
    `Code` Code 在筆記中貼入程式碼
    ```javascript
    var i = 0;
    ```
    var i = 0;
    :smile: :smile: Emoji list
    {%youtube youtube_id %} Externals
    $L^aT_eX$ LaTeX
    :::info
    This is a alert area.
    :::

    This is a alert area.

    Versions and GitHub Sync
    Get Full History Access

    • Edit version name
    • Delete

    revision author avatar     named on  

    More Less

    Note content is identical to the latest version.
    Compare
      Choose a version
      No search result
      Version not found
    Sign in to link this note to GitHub
    Learn more
    This note is not linked with GitHub
     

    Feedback

    Submission failed, please try again

    Thanks for your support.

    On a scale of 0-10, how likely is it that you would recommend HackMD to your friends, family or business associates?

    Please give us some advice and help us improve HackMD.

     

    Thanks for your feedback

    Remove version name

    Do you want to remove this version name and description?

    Transfer ownership

    Transfer to
      Warning: is a public team. If you transfer note to this team, everyone on the web can find and read this note.

        Link with GitHub

        Please authorize HackMD on GitHub
        • Please sign in to GitHub and install the HackMD app on your GitHub repo.
        • HackMD links with GitHub through a GitHub App. You can choose which repo to install our App.
        Learn more  Sign in to GitHub

        Push the note to GitHub Push to GitHub Pull a file from GitHub

          Authorize again
         

        Choose which file to push to

        Select repo
        Refresh Authorize more repos
        Select branch
        Select file
        Select branch
        Choose version(s) to push
        • Save a new version and push
        • Choose from existing versions
        Include title and tags
        Available push count

        Pull from GitHub

         
        File from GitHub
        File from HackMD

        GitHub Link Settings

        File linked

        Linked by
        File path
        Last synced branch
        Available push count

        Danger Zone

        Unlink
        You will no longer receive notification when GitHub file changes after unlink.

        Syncing

        Push failed

        Push successfully