---
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: [] }
);
```