Skip to content
Snippets Groups Projects
FAQService.ts 2.68 KiB
Newer Older
Ramiro's avatar
Ramiro committed
import { Op } from 'sequelize';
Ramiro's avatar
Ramiro committed
import { FAQDTO } from '../DTOs/FAQDTO';
Ramiro's avatar
Ramiro committed
import FAQ from '../Models/FAQ';
Ramiro's avatar
Ramiro committed

const list = (): Promise<FAQ[]> => FAQ.findAll({
Ramiro's avatar
Ramiro committed
  attributes: ['id', 'question', 'answer', 'position', 'createdAt'],
Ramiro's avatar
Ramiro committed
  where: {
    deletedAt: null,
  },
Ramiro's avatar
Ramiro committed
  order: ['position'],
Ramiro's avatar
Ramiro committed
});

Ramiro's avatar
Ramiro committed
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;
};
Ramiro's avatar
Ramiro committed

const update = async (id: number, createDto: FAQDTO): Promise<FAQ | null> => {
Ramiro's avatar
Ramiro committed
  const toUpdate: FAQ | null = await FAQ.findOne({
Ramiro's avatar
Ramiro committed
    where: {
      id,
      deletedAt: null,
    },
  });
Ramiro's avatar
Ramiro committed
  if (!toUpdate) {
Ramiro's avatar
Ramiro committed
    return null;
  }
Ramiro's avatar
Ramiro committed
  const { question, answer, position } = createDto;
Ramiro's avatar
Ramiro committed
  await toUpdate.update({
    question, answer, position,
  });

  const faqs: FAQ[] = await FAQ.findAll({
Ramiro's avatar
Ramiro committed
    where: {
      id: {
Ramiro's avatar
Ramiro committed
        [Op.not]: Number(toUpdate.get('id')),
Ramiro's avatar
Ramiro committed
      },
      deletedAt: null,
    },
Ramiro's avatar
Ramiro committed
    order: ['position'],
Ramiro's avatar
Ramiro committed
  });
Ramiro's avatar
Ramiro committed

  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);
Ramiro's avatar
Ramiro committed
  }
Ramiro's avatar
Ramiro committed

  faqs.push(toUpdate);
  await correctFAQs(faqs);

  return toUpdate;
Ramiro's avatar
Ramiro committed
};

const deleteFAQ = async (id: number): Promise<boolean> => {
  const faq: FAQ | null = await FAQ.findOne({
    where: {
      id,
      deletedAt: null,
    },
  });
  if (!faq) {
    return false;
  }
  await faq.update({
    deletedAt: new Date(),
  });
Ramiro's avatar
Ramiro committed

  const faqs: FAQ[] = await FAQ.findAll({
    where: {
      deletedAt: null,
    },
    order: ['position'],
  });
  await correctFAQs(faqs);

Ramiro's avatar
Ramiro committed
  return true;
};

export default {
  list,
  create,
  update,
  deleteFAQ,
};