---
# System prepended metadata

title: 2022 03 Wash Store
tags: [tutorials]

---

---
title: 2022 03 Wash Store
tags: tutorials
disqus: hackmd
---

# Wash Storeeeee

### Update ActivityView (0323-218511筆)
```
  await ActivityView.find({
    _viewed: { $exists: true },
    progress: { $exists: false },
    createdAt: { $lte: new Date("22 March 2022 UTC") },
  })
    .populate({
      path: "activityId",
      populate: { path: "_styles", model: "Style" },
    })
    .then(async (activityViews) => {
      let index = 1;
      for (let activityView of activityViews) {
        const updates = { _viewed: [], progress: 0, isChecked: false };
        const { _id, activityId, userId, isChecked } = activityView;

        const styles = activityId._styles.filter(
          ({ isHidden, isDeleted, isTrash }) =>
            !isHidden && !isDeleted && !isTrash
        );
        const styleViews = await StyleView.find({
          styleId: { $in: styles.map(({ _id }) => _id) },
          userId,
        });
        console.log("activityViewId:", _id);
        console.log(
          `progress: ${styleViews.length} / ${styles.length} / ${isChecked}`
        );

        if (styles.length && styleViews.length) {
          const activityViewProgress = Math.round(
            (styleViews.length / styles.length) * 100
          );

          // isChecked
          if (activityViewProgress === 100) {
            updates.isChecked = true;
          }

          // progress
          updates.progress = Number.isInteger(activityViewProgress)
            ? activityViewProgress
            : 0;

          // _viewed
          updates._viewed = updates._viewed.concat(
            styleViews.map(({ styleId }) => styleId)
          );

          const newView = await ActivityView.findOneAndUpdate(
            { _id, userId },
            updates,
            { new: true }
          );
          console.log(`【${index}】`, newView.progress, newView.isChecked);
        } else {
          await ActivityView.deleteOne({ _id });
          console.log(`【${index}】`, "deleteeeeeeeee");
        }
        index++;
      }
    });
```

### Delete ActivityView by _styles
```
  const activities = await Activity.find({
    _styles: { $eq: [] },
  })
    .skip(12000)
    .limit(4000); 
  const activityIds = activities.map(({ _id }) => _id);
  const aaa = await ActivityView.deleteMany({
    activityId: { $in: activityIds },
  });
  console.log("deletedCount:", aaa.deletedCount);
```

### Update SectionView - field of type (0321-118946筆)
```
  await SectionView.find({
    type: { $exists: false },
  })
    .populate({
      path: "sectionId",
      model: "Section",
      match: {
        $or: [{ type: { $eq: "check" } }, { type: { $eq: "learn" } }],
        isHidden: false,
        isDeleted: false,
      },
    })
    .then(async (sectionViews) => {
      let index = 1;

      for (let sectionView of sectionViews) {
        const { _id, sectionId } = sectionView;
        const type = sectionId?.type;
        const updates = { type: 0 };
        if (type) {
          if (type === "check") {
            updates.type = 1;
          }
          await SectionView.findOneAndUpdate({ _id }, updates);
          console.log(`done【${index}】`, _id, type);
        } else {
          await SectionView.deleteOne({ _id });
          console.log(`not done【${index}】`, _id);
        }

        index++;
      }
    });
```

### Update SectionView - learn
*progress / isChecked
```
await SectionView.find({
    type: 0,
  })
    .populate({
      path: "sectionId",
      model: "Section",
      match: {
        isHidden: false,
        isDeleted: false,
      },
      populate: {
        path: "_activities",
        model: "Activity",
        match: {
          isHidden: false,
          _styles: { $ne: [] },
        },
        populate: {
          path: "_styles",
          select: "_id",
          model: "Style",
          match: {
            isHidden: false,
          },
        },
      },
    })
    .then(async (sectionViews) => {
      let index = 1;
      for (let sectionView of sectionViews) {
        const { _id, userId, sectionId } = sectionView;
        console.log(`sectionViewId:${_id}`);

        if (sectionId) {
          const { id: _section, _activities } = sectionId;
          const updates = { isChecked: false };

          // styles
          const totalStyles = _activities.reduce((acc, _activity) => {
            acc = acc.concat(_activity?._styles);
            return acc;
          }, []);
          const allStylesLength = totalStyles.length;
          const styleViews = await StyleView.countDocuments({
            userId,
            styleId: { $in: totalStyles },
            sectionId: _section,
          });

          if (allStylesLength && styleViews) {
            const sectionViewProgress = allStylesLength
              ? Math.round((styleViews / allStylesLength) * 100)
              : 0;

            updates.progress = sectionViewProgress;
            if (sectionViewProgress === 100) {
              updates.isChecked = true;
            }

            console.log(`progress:${styleViews} / ${allStylesLength}`);

            if (sectionViewProgress > 100) {
              console.log(
                `sectionViewProgress > 100: ${_section}【${sectionViewProgress}】`
              );
            }

            const newSectionView = await SectionView.findByIdAndUpdate(
              _id,
              { ...updates },
              { new: true }
            );
            console.log(
              `【${index}】: ${newSectionView._id} / ${newSectionView.progress} / ${newSectionView.isChecked}`
            );
          } else {
            await SectionView.deleteOne({ _id });
            console.log(`【${index}】: 'deleteeeeeee empty styles}`);
          }
        } else {
          await SectionView.deleteOne({ _id });
          console.log(`【${index}】: 'deleteeeeeee hidden section}`);
        }
        index++;
      }
    });
```

### Update SectionView - check
*scores / progress / isChecked / _viewed
```
await SectionView.find({
    type: 1,
  })
    .populate({
      path: "sectionId",
      model: "Section",
      match: {
        isHidden: false,
      },
      populate: {
        path: "_styles",
        model: "Style",
        match: {
          isTrash: false,
          isHidden: false,
        },
      },
    })
    .then(async (sectionViews) => {
      let index = 1;
      for (let sectionView of sectionViews) {
        const { _id, userId, sectionId } = sectionView;
        console.log(`sectionViewId:${_id}`);

        if (sectionId) {
          const { _id: _section, _styles } = sectionId;
          const updates = {
            _viewed: [],
            scores: [],
            progress: 0,
            isChecked: false,
          };

          // styles
          const styleIds = _styles.map(({ _id }) => _id);
          const styleViews = await StyleView.find({
            userId,
            styleId: { $in: styleIds },
            sectionId: _section,
          });
          const correctStyleViews = styleViews.filter(
            ({ scores }) => scores[scores.length - 1] === "1"
          ).length;

          const allStylesLength = styleIds.length >= 30 ? 30 : styleIds.length;
          // progress
          const sectionViewProgress = allStylesLength
            ? Math.round((styleViews.length / allStylesLength) * 100)
            : 0;
          updates.progress =
            sectionViewProgress >= 100 ? 100 : sectionViewProgress;
          // scores
          const sectionViewScore = allStylesLength
            ? Math.round((correctStyleViews / allStylesLength) * 100)
            : 0;
          updates.scores = updates.scores.concat(
            sectionViewScore >= 100 ? 100 : sectionViewScore
          );
          // _viewd
          updates._viewed = updates._viewed.concat(
            styleViews.map(({ styleId }) => styleId)
          );
          if (updates.progress === 100) {
            updates.isChecked = true;
          }

          console.log(`${sectionViewScore} / ${sectionViewProgress}`);

          const newSectionView = await SectionView.findByIdAndUpdate(
            _id,
            { ...updates },
            { new: true }
          );

          console.log(
            `【${index}】: ${newSectionView.scores} / ${newSectionView.progress} / ${newSectionView.isChecked}`
          );
        } else {
          await SectionView.deleteOne({ _id });
          console.log(`【${index}】: 'deleteeeeeee}`);
        }
        index++;
      }
    });
```

### Update UnitView 
*isChecked
```
await UnitView.find({})
    .limit(10)
    .populate({
      path: "unitId",
      model: "Unit",
      match: { isHidden: false },
      select: "_sections",
      populate: {
        path: "_sections",
        model: "Section",
        select: "type _activities _styles isHidden",
        populate: {
          path: "_activities",
          model: "Activity",
        },
      },
    })
    .then(async (unitViews) => {
      let index = 1;
      let hiddenUnits = [];
      for (let unitView of unitViews) {
        console.log(`unitViewId:${unitView?._id}`);
        if (unitView?.unitId?.id) {
          // get none empty styles of learn & check
          const sections = unitView?.unitId._sections
            .filter(({ type, isHidden }) => {
              // console.log(type, isHidden);
              return !isHidden && ["learn", "check"].includes(type); // get section isHidden:false and learn、check
            })
            // .map((section) => console.log(section));
            .filter(
              ({ _styles, _activities }) =>
                !isEmpty(_styles) ||
                !isEmpty(
                  _activities.reduce((acc, activity) => {
                    // console.log("***", activity);
                    acc = acc.concat(
                      (!activity.isHidden && activity._styles) || [] // get activity isHidden fasle
                    );
                    return acc;
                  }, [])
                )
            );

          // console.log(sections.map(({ _id }) => _id));
          const sectionViews = await SectionView.find({
            sectionId: { $in: sections.map(({ _id }) => _id) },
            userId: unitView.userId,
          });

          const isAllChecked = sectionViews
            .map(({ isChecked }) => isChecked)
            .every((item) => item);
          console.log(sectionViews);

          // const unitView = await UnitView.findByIdAndUpdate(
          //   unitView._id,
          //   {
          //     isChecked: isAllChecked,
          //   },
          //   { new: true }
          // );
          // console.log(`【${index}】: ${unitView._id} / ${unitView.isChecked}`);
        } else {
          hiddenUnits.push(unitView?._id);
        }
        index++;
      }
      console.log(`********${hiddenUnits}********`);
    });
```

### Add a field of products in User
const { gql } = require("graphql-request");
const { masterGraphqlHelper } = require("../../../utils/masterGraphqlHelper");
```
    const skowtUserIds = (
      await User.find({
        role: { $in: ["principal", "secretary", "teacher", "student"] },
        products: { $exists: false },
      })
    ).map(({ userId }) => userId);
    const query = gql`
      query getUsers($filter: UserFilterInputs) {
        getUsers(filter: $filter, pagination: { limit: 0, offset: 0 }) {
          id
          name
          username
          products {
            id
            name
          }
        }
      }
    `;
    const { getUsers } = await masterGraphqlHelper(query, {
      filter: { id: { in: skowtUserIds } },
    });

    let [index, noproductusers] = [1, []];
    for (const getUser of getUsers) {
      const { id, products } = getUser;
      if (products) {
        console.log(index, "with products:", id);
        await User.findOneAndUpdate(
          { userId: id },
          {
            products:
              products?.map(({ id, name }) => {
                return { _id: id, name };
              }) || [],
          }
        );
      } else {
        console.log(index, "without products:", id);
        noproductusers = noproductusers.concat([id]);
      }
      index++;
    }

    console.log("noproductusers:", noproductusers);
    await User.updateMany(
      { userId: { $in: noproductusers } },
      { products: [] }
    );
```