Jdavydz
Jdavydz

Reputation: 21

Cron Job not running function

I have a node js controller

const calculateInitialStartTime = (
  startDate,
  frequency,
  timeOfDay,
  dayOfWeek,
  dayOfMonth
) => {
  let initialStart = new Date(startDate);
  if (timeOfDay) {
    const [hour, minute] = timeOfDay.split(":");
    initialStart.setHours(hour);
    initialStart.setMinutes(minute);
    initialStart.setSeconds(0);
  } else {
    initialStart.setHours(7);
    initialStart.setMinutes(0);
    initialStart.setSeconds(0);
  }

  switch (frequency) {
    case "weekly":
      const day = initialStart.getDay();
      const targetDay = dayOfWeek || 0;
      const diff = (targetDay - day + 7) % 7;
      initialStart.setDate(initialStart.getDate() + diff);
      break;
    case "monthly":
      const monthDay = dayOfMonth || 1;
      if (initialStart.getDate() > monthDay) {
        initialStart.setMonth(initialStart.getMonth() + 1);
      }
      initialStart.setDate(monthDay);
      break;
  }
  return initialStart;
};

const getCronExpression = (frequency, timeOfDay, dayOfWeek, dayOfMonth) => {
  let cronTime = "0 7"; // Default to 7:00 AM

  if (timeOfDay) {
    const [hour, minute] = timeOfDay.split(":");
    cronTime = `${minute} ${hour}`;
  }

  switch (frequency) {
    case "hourly":
      return "0 * * * *"; // Every hour at minute 0
    case "daily":
      return `${cronTime} * * *`; // Daily at specified time
    case "weekly":
      return `${cronTime} * * ${dayOfWeek || 0}`; // Weekly on specified day and time
    case "monthly":
      return `${cronTime} ${dayOfMonth || 1} * *`; // Monthly on specified day and time
    default:
      throw new BadRequestError("Invalid frequency");
  }
};

agenda.define(`thrift job wallet`, async (job, done) => {
  try {
    const { thriftId, userId, email, name } = job.attrs.data;
    const thriftSave = await ThriftSave.findOne({ _id: thriftId });
    const wallet = await Wallet.findOne({ user: userId });

    if (thriftSave.status === "completed") {
      await job.remove();
      logger.info(`Job removed for completed thrift: ${thriftId}`);
      return done();
    }

    if (!wallet) {
      throw new BadRequestError("No Wallet found");
    }

    if (+wallet.amount < +thriftSave.per) {
      await sendFailedWalletDebitEmail({
        email,
        title: `Thrift - ${thriftSave.title}`,
        amount: thriftSave.per,
      });
      await Transactions.create({
        user: userId,
        username: name,
        amount: thriftSave.per,
        title: `Thrift - ${thriftSave.title}`,
        type: "debit",
        status: "success",
      });
      throw new BadRequestError("Insufficient funds");
    }

    await Wallet.updateOne(
      { user: userId },
      { $inc: { amount: -thriftSave.per } }
    );
    await ThriftSave.updateOne(
      { _id: thriftId },
      { $inc: { amount: thriftSave.per } }
    );
    await Transactions.create({
      user: userId,
      username: name,
      amount: thriftSave.per,
      title: `Thrift - ${thriftSave.title}`,
      type: "debit",
      status: "success",
    });
    done();
  } catch (error) {
    logger.error(`Error processing thrift job: ${error.message}`);
    done(error);
  }
});

agenda.define(`recurringThrift job wallet`, async (job, done) => {
  const { thriftId, userId, email, name, cronExpression } = job.attrs.data;

  await agenda.every(cronExpression, `thrift job wallet`, {
    thriftId,
    userId,
    email,
    name,
  });
  job.remove();
});

const createThriftSave = async (req, res) => {
  const { title, frequency, per, startDate, timeOfDay, dayOfWeek, dayOfMonth } =
    req.body;
  const { id, email, name } = req.user;

  const startDateObj = new Date(startDate);

  const initialStartTime = calculateInitialStartTime(
    startDate,
    frequency,
    timeOfDay,
    dayOfWeek,
    dayOfMonth
  );
  const cronExpression = getCronExpression(
    frequency,
    timeOfDay,
    dayOfWeek,
    dayOfMonth
  );

  const interest = 0;

  const thrift = await ThriftSave.create({
    title,
    amount: 0,
    frequency,
    startDate: startDateObj,
    per,
    interest,
    user: id,
  });

  await agenda.schedule(
    initialStartTime,
    `recurringThrift job wallet`,
    {
      thriftId: thrift._id,
      userId: id,
      email,
      name,
      cronExpression,
    }
  );

  await sendThriftEmail({ email, title, per, frequency });
  res.status(StatusCodes.OK).json({ thrift });
};

This is supposed to schedule a job at a future time and then that job triggers a recurring job according to the set interval..

My issue is that when it schedules one job, the next time a job is scheduled, it replaces the previous one and that one is lost, i think because these jobs are of the same name..Is there a way i can make multiple jobs be created with the different job.attrb.data but the same name?

Upvotes: 0

Views: 48

Answers (0)

Related Questions