Spaces:
Paused
Paused
Deploy Bot commited on
Commit Β·
befdc5c
1
Parent(s): e81c9a5
Implement_Advanced_Stock_Referral_Logic
Browse files- src/controllers/userController.js +55 -5
- src/main.js +3 -0
- src/models/User.js +1 -0
src/controllers/userController.js
CHANGED
|
@@ -71,9 +71,13 @@ exports.handleReferral = async (ctx, referrerId) => {
|
|
| 71 |
// We can fetch referrer user.
|
| 72 |
const referrerUser = await User.findOne({ id: referrerId });
|
| 73 |
if (referrerUser) {
|
|
|
|
|
|
|
|
|
|
|
|
|
| 74 |
const locales = require('../locales');
|
| 75 |
const rLang = locales[referrerUser.language] || locales.uz;
|
| 76 |
-
await ctx.telegram.sendMessage(referrerId, `${rLang.invite_referral} ${ctx.from.first_name}!`);
|
| 77 |
}
|
| 78 |
} catch (e) {
|
| 79 |
// Referrer might have blocked bot
|
|
@@ -86,7 +90,11 @@ exports.inviteFriends = async (ctx) => {
|
|
| 86 |
const botUsername = ctx.botInfo.username;
|
| 87 |
const inviteLink = `https://t.me/${botUsername}?start=${ctx.from.id}`;
|
| 88 |
|
| 89 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
| 90 |
|
| 91 |
const forwardText = `${ctx.i18n.invite_forward}${inviteLink}`;
|
| 92 |
|
|
@@ -593,11 +601,53 @@ exports.showOrderDetails = async (ctx, orderId) => {
|
|
| 593 |
|
| 594 |
text += `\nπ° **Jami: ${order.total} so'm**`;
|
| 595 |
|
| 596 |
-
const
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 597 |
|
| 598 |
-
|
| 599 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 600 |
} catch (err) {
|
| 601 |
console.error(err);
|
|
|
|
|
|
|
|
|
|
|
|
|
| 602 |
}
|
| 603 |
};
|
|
|
|
| 71 |
// We can fetch referrer user.
|
| 72 |
const referrerUser = await User.findOne({ id: referrerId });
|
| 73 |
if (referrerUser) {
|
| 74 |
+
// Increment Count
|
| 75 |
+
referrerUser.referralCount = (referrerUser.referralCount || 0) + 1;
|
| 76 |
+
await referrerUser.save();
|
| 77 |
+
|
| 78 |
const locales = require('../locales');
|
| 79 |
const rLang = locales[referrerUser.language] || locales.uz;
|
| 80 |
+
await ctx.telegram.sendMessage(referrerId, `${rLang.invite_referral} ${ctx.from.first_name}!\nπ Jami takliflar: ${referrerUser.referralCount}`);
|
| 81 |
}
|
| 82 |
} catch (e) {
|
| 83 |
// Referrer might have blocked bot
|
|
|
|
| 90 |
const botUsername = ctx.botInfo.username;
|
| 91 |
const inviteLink = `https://t.me/${botUsername}?start=${ctx.from.id}`;
|
| 92 |
|
| 93 |
+
// Get Stats
|
| 94 |
+
const user = await User.findOne({ id: ctx.from.id });
|
| 95 |
+
const count = user ? (user.referralCount || 0) : 0;
|
| 96 |
+
|
| 97 |
+
const text = `${ctx.i18n.invite_text}\n\nπ **Sizning natijangiz:** ${count} ta do'st taklif qilingan.\n\nπ ${inviteLink}\n\nπ`;
|
| 98 |
|
| 99 |
const forwardText = `${ctx.i18n.invite_forward}${inviteLink}`;
|
| 100 |
|
|
|
|
| 601 |
|
| 602 |
text += `\nπ° **Jami: ${order.total} so'm**`;
|
| 603 |
|
| 604 |
+
const buttons = [];
|
| 605 |
+
// Allow cancellation only if status is 'new'
|
| 606 |
+
if (order.status === 'new') {
|
| 607 |
+
buttons.push([Markup.button.callback("β Bekor qilish", `user_cancel_order_${order.id}`)]);
|
| 608 |
+
}
|
| 609 |
+
buttons.push([Markup.button.callback("π Orqaga", "my_orders_list")]);
|
| 610 |
+
|
| 611 |
+
ctx.editMessageText(text, { parse_mode: 'HTML', ...Markup.inlineKeyboard(buttons) })
|
| 612 |
+
.catch(() => ctx.replyWithHTML(text, Markup.inlineKeyboard(buttons)));
|
| 613 |
+
} catch (err) {
|
| 614 |
+
console.error(err);
|
| 615 |
+
ctx.reply("Xatolik");
|
| 616 |
+
}
|
| 617 |
+
};
|
| 618 |
+
|
| 619 |
+
// User Cancel Order (Restock)
|
| 620 |
+
exports.cancelUserOrder = async (ctx, orderId) => {
|
| 621 |
+
try {
|
| 622 |
+
const id = parseInt(orderId);
|
| 623 |
+
const order = await Order.findOne({ id: id, userId: ctx.from.id });
|
| 624 |
+
|
| 625 |
+
if (!order) return ctx.answerCbQuery("Buyurtma topilmadi");
|
| 626 |
+
if (order.status !== 'new') return ctx.answerCbQuery("Ushbu buyurtmani bekor qilib bo'lmaydi");
|
| 627 |
+
|
| 628 |
+
// Restock Logic
|
| 629 |
+
const Product = require('../models/Product');
|
| 630 |
+
for (const item of order.items) {
|
| 631 |
+
await Product.updateOne({ id: item.id }, { $inc: { quantity: item.count } });
|
| 632 |
+
}
|
| 633 |
+
|
| 634 |
+
await Order.updateOne({ id: id }, { status: 'canceled' });
|
| 635 |
+
|
| 636 |
+
ctx.answerCbQuery("Buyurtma bekor qilindi β");
|
| 637 |
|
| 638 |
+
// Notify Admin about cancellation (Optional but good logic)
|
| 639 |
+
const config = require('../config');
|
| 640 |
+
for (const adminId of config.ADMIN_IDS) {
|
| 641 |
+
ctx.telegram.sendMessage(adminId, `β οΈ <b>Buyurtma bekor qilindi!</b>\n#${id} bekor qilindi (Foydalanuvchi tomonidan).`, { parse_mode: 'HTML' }).catch(e => { });
|
| 642 |
+
}
|
| 643 |
+
|
| 644 |
+
// Refresh View
|
| 645 |
+
exports.showOrderDetails(ctx, id);
|
| 646 |
} catch (err) {
|
| 647 |
console.error(err);
|
| 648 |
+
ctx.reply("Xatolik");
|
| 649 |
+
}
|
| 650 |
+
};
|
| 651 |
+
console.error(err);
|
| 652 |
}
|
| 653 |
};
|
src/main.js
CHANGED
|
@@ -152,6 +152,9 @@ bot.action(/order_deliver_(.+)/, (ctx) => adminController.deliverOrder(ctx, ctx.
|
|
| 152 |
bot.action(/gen_invoice_(.+)/, (ctx) => adminController.showInvoice(ctx, ctx.match[1]));
|
| 153 |
bot.action(/delete_prod_(.+)/, (ctx) => adminController.deleteProduct(ctx, ctx.match[1]));
|
| 154 |
|
|
|
|
|
|
|
|
|
|
| 155 |
// User Commands
|
| 156 |
bot.start(async (ctx) => {
|
| 157 |
try {
|
|
|
|
| 152 |
bot.action(/gen_invoice_(.+)/, (ctx) => adminController.showInvoice(ctx, ctx.match[1]));
|
| 153 |
bot.action(/delete_prod_(.+)/, (ctx) => adminController.deleteProduct(ctx, ctx.match[1]));
|
| 154 |
|
| 155 |
+
// User Actions
|
| 156 |
+
bot.action(/user_cancel_order_(.+)/, (ctx) => userController.cancelUserOrder(ctx, ctx.match[1]));
|
| 157 |
+
|
| 158 |
// User Commands
|
| 159 |
bot.start(async (ctx) => {
|
| 160 |
try {
|
src/models/User.js
CHANGED
|
@@ -12,6 +12,7 @@ const userSchema = new mongoose.Schema({
|
|
| 12 |
longitude: Number
|
| 13 |
}],
|
| 14 |
referredBy: { type: String, default: null },
|
|
|
|
| 15 |
isBlocked: { type: Boolean, default: false },
|
| 16 |
createdAt: { type: Date, default: Date.now }
|
| 17 |
});
|
|
|
|
| 12 |
longitude: Number
|
| 13 |
}],
|
| 14 |
referredBy: { type: String, default: null },
|
| 15 |
+
referralCount: { type: Number, default: 0 },
|
| 16 |
isBlocked: { type: Boolean, default: false },
|
| 17 |
createdAt: { type: Date, default: Date.now }
|
| 18 |
});
|