From be9076d70cf4ed8fff62b43583399cb1a34016e0 Mon Sep 17 00:00:00 2001
From: Ramiro <rbentancor@globaluy.com>
Date: Wed, 27 Oct 2021 21:16:19 -0300
Subject: [PATCH] FAQs service, model

---
 src/Models/FAQ.ts          |  1 -
 src/Services/FAQService.ts | 73 ++++++++++++++++++++++++++++++++------
 2 files changed, 62 insertions(+), 12 deletions(-)

diff --git a/src/Models/FAQ.ts b/src/Models/FAQ.ts
index 4dc96b7..9ad092c 100644
--- a/src/Models/FAQ.ts
+++ b/src/Models/FAQ.ts
@@ -18,7 +18,6 @@ FAQ.init({
   },
   position: {
     type: DataTypes.INTEGER,
-    unique: true,
   },
   createdBy: {
     type: DataTypes.INTEGER,
diff --git a/src/Services/FAQService.ts b/src/Services/FAQService.ts
index 8734d1c..6b56f39 100644
--- a/src/Services/FAQService.ts
+++ b/src/Services/FAQService.ts
@@ -10,34 +10,76 @@ const list = (): Promise<FAQ[]> => FAQ.findAll({
   order: ['position'],
 });
 
-const create = (createDto: FAQDTO): Promise<FAQ> => FAQ.create(createDto);
+const correctFAQs = async (faqs: FAQ[]): Promise<void> => new Promise((resolve, reject) => {
+  const { length } = faqs;
+  const sorted: FAQ[] = faqs.sort((faqA: FAQ, faqB: FAQ) => Number(faqA.get('position')) - Number(faqB.get('position')));
+  const promises: Promise<FAQ>[] = [];
+  for (let index = 0; index < length; index += 1) {
+    const faq: FAQ = sorted[index];
+    promises.push(faq.update({
+      position: index + 1,
+    }));
+  }
+  return Promise.all(promises)
+    .then(() => resolve())
+    .catch(() => reject());
+});
+
+const create = async (createDto: FAQDTO): Promise<FAQ> => {
+  const faqs: FAQ[] = await FAQ.findAll({
+    where: {
+      deletedAt: null,
+    },
+    order: ['position'],
+  });
+  const newFaq: FAQ = await FAQ.create(createDto);
+  if (faqs.length + 1 === Number(newFaq.get('position'))) {
+    newFaq.set('position', Number(newFaq.get('position')) + 0.5);
+  } else {
+    newFaq.set('position', Number(newFaq.get('position')) - 0.5);
+  }
+
+  faqs.push(newFaq);
+  await correctFAQs(faqs);
+
+  return newFaq;
+};
 
 const update = async (id: number, createDto: FAQDTO): Promise<FAQ | null> => {
-  const faq: FAQ | null = await FAQ.findOne({
+  const toUpdate: FAQ | null = await FAQ.findOne({
     where: {
       id,
       deletedAt: null,
     },
   });
-  if (!faq) {
+  if (!toUpdate) {
     return null;
   }
   const { question, answer, position } = createDto;
-  const positionFaq: FAQ | null = await FAQ.findOne({
+  await toUpdate.update({
+    question, answer, position,
+  });
+
+  const faqs: FAQ[] = await FAQ.findAll({
     where: {
       id: {
-        [Op.ne]: id,
+        [Op.not]: Number(toUpdate.get('id')),
       },
-      position,
       deletedAt: null,
     },
+    order: ['position'],
   });
-  if (positionFaq) {
-    return null;
+
+  if (faqs.length + 1 === Number(toUpdate.get('position'))) {
+    toUpdate.set('position', Number(toUpdate.get('position')) + 0.5);
+  } else {
+    toUpdate.set('position', Number(toUpdate.get('position')) - 0.5);
   }
-  return faq.update({
-    question, answer, position,
-  });
+
+  faqs.push(toUpdate);
+  await correctFAQs(faqs);
+
+  return toUpdate;
 };
 
 const deleteFAQ = async (id: number): Promise<boolean> => {
@@ -53,6 +95,15 @@ const deleteFAQ = async (id: number): Promise<boolean> => {
   await faq.update({
     deletedAt: new Date(),
   });
+
+  const faqs: FAQ[] = await FAQ.findAll({
+    where: {
+      deletedAt: null,
+    },
+    order: ['position'],
+  });
+  await correctFAQs(faqs);
+
   return true;
 };
 
-- 
GitLab