mirror of
https://github.com/rgrgogu/new_starr.git
synced 2026-09-27 00:12:54 +08:00
@@ -83,11 +83,18 @@ exports.getPlan = async (req, res) => {
|
||||
}
|
||||
};
|
||||
|
||||
const DURATION_UNIT_TO_DAYS = { minute: 1 / 1440, hour: 1 / 24, day: 1, month: 30, year: 365 };
|
||||
|
||||
function computeDurationDays(value, unit) {
|
||||
const multiplier = DURATION_UNIT_TO_DAYS[unit] ?? 1;
|
||||
return parseFloat(value) * multiplier;
|
||||
}
|
||||
|
||||
exports.createPlan = async (req, res) => {
|
||||
try {
|
||||
const { tier_category_id, label, duration_days, price, currency } = req.body;
|
||||
if (!tier_category_id || !label || !duration_days || !price)
|
||||
return R.error(res, 'tier_category_id, label, duration_days, and price are required.', 400);
|
||||
const { tier_category_id, label, description, duration_value, duration_unit = 'day', price, currency } = req.body;
|
||||
if (!tier_category_id || !label || !duration_value || !price)
|
||||
return R.error(res, 'tier_category_id, label, duration_value, and price are required.', 400);
|
||||
|
||||
const category = await mdl_TierCategories.findByPk(tier_category_id);
|
||||
if (!category || !category.is_active)
|
||||
@@ -96,10 +103,12 @@ exports.createPlan = async (req, res) => {
|
||||
if (category.is_default)
|
||||
return R.error(res, 'Plans cannot be created under the default (Free) tier. Free access is automatic.', 400);
|
||||
|
||||
const duration_days = computeDurationDays(duration_value, duration_unit);
|
||||
|
||||
const plan = await mdl_TierPlans.create({
|
||||
tier_category_id: category.tier_category_id,
|
||||
tier: category.slug,
|
||||
label, duration_days, price, currency,
|
||||
label, description, duration_days, duration_unit, price, currency,
|
||||
});
|
||||
const plain = plan.get({ plain: true });
|
||||
logActivity(req.user?.user_id, 'create_tier_plan', { entityType: 'tier_plan', details: { label: plain.label, tier: plain.tier } });
|
||||
@@ -115,12 +124,22 @@ exports.updatePlan = async (req, res) => {
|
||||
const plan = await mdl_TierPlans.findByPk(req.params.id);
|
||||
if (!plan) return R.error(res, 'Plan not found.', 404);
|
||||
|
||||
const allowed = ['label', 'duration_days', 'price', 'currency', 'is_active', 'tier_category_id'];
|
||||
const allowed = ['label', 'description', 'price', 'currency', 'is_active', 'tier_category_id'];
|
||||
const updates = {};
|
||||
for (const k of allowed) {
|
||||
if (req.body[k] !== undefined) updates[k] = req.body[k];
|
||||
}
|
||||
|
||||
// Recompute duration_days when value or unit changes
|
||||
const { duration_value, duration_unit } = req.body;
|
||||
if (duration_value !== undefined) {
|
||||
const unit = duration_unit ?? plan.duration_unit ?? 'day';
|
||||
updates.duration_days = computeDurationDays(duration_value, unit);
|
||||
updates.duration_unit = unit;
|
||||
} else if (duration_unit !== undefined) {
|
||||
updates.duration_unit = duration_unit;
|
||||
}
|
||||
|
||||
// If tier_category_id is being changed, sync the tier slug
|
||||
if (updates.tier_category_id) {
|
||||
const category = await mdl_TierCategories.findByPk(updates.tier_category_id);
|
||||
@@ -140,6 +159,22 @@ exports.updatePlan = async (req, res) => {
|
||||
}
|
||||
};
|
||||
|
||||
exports.getPlanImpact = async (req, res) => {
|
||||
try {
|
||||
const plan = await mdl_TierPlans.findByPk(req.params.id);
|
||||
if (!plan) return R.error(res, 'Plan not found.', 404);
|
||||
|
||||
const active_subscriber_count = await mdl_UserTiers.count({
|
||||
where: { plan_id: req.params.id, status: 'active' },
|
||||
});
|
||||
|
||||
return R.success(res, 'Plan impact retrieved.', { active_subscriber_count });
|
||||
} catch (err) {
|
||||
console.error('[ADMIN][GET PLAN IMPACT]', err);
|
||||
return R.error(res, 'Could not retrieve plan impact.', 500);
|
||||
}
|
||||
};
|
||||
|
||||
exports.archivePlan = async (req, res) => {
|
||||
try {
|
||||
const plan = await mdl_TierPlans.findByPk(req.params.id);
|
||||
|
||||
Reference in New Issue
Block a user