Merge branch 'sabrecat/panel-subscription' into release

This commit is contained in:
SabreCat
2022-09-30 14:46:10 -05:00
7 changed files with 229 additions and 7 deletions

View File

@@ -22,11 +22,6 @@
Account created:
<strong>{{ hero.auth.timestamps.created | formatDate }}</strong>
</div>
<div>
Most recent cron:
<strong>{{ hero.auth.timestamps.loggedin | formatDate }}</strong>
("auth.timestamps.loggedin")
</div>
<div v-if="cronError">
"lastCron" value:
<strong>{{ hero.lastCron | formatDate }}</strong>
@@ -36,6 +31,19 @@
("auth.timestamps.loggedin" and "lastCron" dates are different).
</span>
</div>
<div class="form-inline">
<div>
Most recent cron:
<strong>{{ hero.auth.timestamps.loggedin | formatDate }}</strong>
("auth.timestamps.loggedin")
</div>
<button
class="btn btn-primary ml-2"
@click="resetCron()"
>
Reset Cron to Yesterday
</button>
</div>
<div class="subsection-start">
Time zone:
<strong>{{ hero.preferences.timezoneOffset | formatTimeZone }}</strong>
@@ -218,6 +226,10 @@ export default {
await this.saveHero({ hero: this.hero, msg: 'API Token' });
this.tokenModified = true;
},
resetCron () {
this.hero.resetCron = true;
this.saveHero({ hero: this.hero, msg: 'Last Cron', clearData: true });
},
},
};
</script>

View File

@@ -17,6 +17,10 @@
:reset-counter="resetCounter"
/>
<subscription-and-perks
:hero="hero"
/>
<cron-and-auth
:hero="hero"
:reset-counter="resetCounter"
@@ -97,6 +101,7 @@ import AvatarAndDrops from './avatarAndDrops';
import PrivilegesAndGems from './privilegesAndGems';
import ContributorDetails from './contributorDetails';
import Transactions from './transactions';
import SubscriptionAndPerks from './subscriptionAndPerks';
import { userStateMixin } from '../../../mixins/userState';
@@ -110,6 +115,7 @@ export default {
PrivilegesAndGems,
ContributorDetails,
Transactions,
SubscriptionAndPerks,
},
mixins: [userStateMixin],
data () {

View File

@@ -0,0 +1,155 @@
<template>
<div class="accordion-group">
<h3
class="expand-toggle"
:class="{'open': expand}"
@click="expand = !expand"
>
Subscription, Monthly Perks
</h3>
<div v-if="expand">
<form @submit.prevent="saveHero({ hero, msg: 'Subscription Perks' })">
<div v-if="hero.purchased.plan.paymentMethod">
Payment method:
<strong>{{ hero.purchased.plan.paymentMethod }}</strong>
</div>
<div v-if="hero.purchased.plan.planId">
Payment schedule ("basic-earned" is monthly):
<strong>{{ hero.purchased.plan.planId }}</strong>
</div>
<div v-if="hero.purchased.plan.dateCreated">
Creation date:
<strong>{{ dateFormat(hero.purchased.plan.dateCreated) }}</strong>
</div>
<div>
Termination date:
<strong
v-if="hero.purchased.plan.dateTerminated"
>
{{ dateFormat(hero.purchased.plan.dateTerminated) }}
</strong>
<strong v-else> None </strong>
</div>
<div class="form-inline">
<label>
Consecutive months:
<input
v-model="hero.purchased.plan.consecutive.count"
class="form-control"
type="number"
min="0"
step="1"
>
</label>
</div>
<div>
Months until renewal:
<strong>{{ hero.purchased.plan.consecutive.offset }}</strong>
</div>
<div>
Next Mystic Hourglass:
<strong>{{ nextHourglassDate }}</strong>
</div>
<div class="form-inline">
<label>
Mystic Hourglasses:
<input
v-model="hero.purchased.plan.consecutive.trinkets"
class="form-control"
type="number"
min="0"
step="1"
>
</label>
</div>
<div>
Gem cap:
<strong>{{ hero.purchased.plan.consecutive.gemCapExtra + 25 }}</strong>
</div>
<div class="form-inline">
<label>
Gems bought this month:
<input
v-model="hero.purchased.plan.gemsBought"
class="form-control"
type="number"
min="0"
:max="hero.purchased.plan.consecutive.gemCapExtra + 25"
step="1"
>
</label>
</div>
<div
v-if="hero.purchased.plan.extraMonths > 0"
>
Additional credit (applied upon cancellation):
<strong>{{ hero.purchased.plan.extraMonths }}</strong>
</div>
<div>
Mystery Items:
<span
v-if="hero.purchased.plan.mysteryItems.length > 0"
>
<span
v-for="(item, index) in hero.purchased.plan.mysteryItems"
:key="index"
>
<strong v-if="index < hero.purchased.plan.mysteryItems.length - 1">
{{ item }},
</strong>
<strong v-else> {{ item }} </strong>
</span>
</span>
<span v-else>
<strong>None</strong>
</span>
</div>
<input
type="submit"
value="Save"
class="btn btn-primary mt-1"
>
</form>
</div>
</div>
</template>
<script>
import moment from 'moment';
import saveHero from '../mixins/saveHero';
import { getPlanContext } from '@/../../common/script/cron';
export default {
mixins: [saveHero],
props: {
hero: {
type: Object,
required: true,
},
},
data () {
return {
expand: false,
};
},
computed: {
nextHourglassDate () {
const currentPlanContext = getPlanContext(this.hero, new Date());
return currentPlanContext.nextHourglassDate.format('MMMM');
},
},
watch: {
'hero.purchased.plan.consecutive.count' () { // eslint-disable-line object-shorthand
this.hero.purchased.plan.consecutive.gemCapExtra = Math.min(
Math.floor(this.hero.purchased.plan.consecutive.count / 3) * 5, 25,
);
},
},
methods: {
dateFormat (date) {
return moment(date).format('YYYY/MM/DD');
},
},
};
</script>

View File

@@ -213,5 +213,6 @@
"transaction_release_mounts": "Released mounts",
"transaction_reroll": "Used Fortify Potion",
"transaction_subscription_perks": "From subscription perk",
"transaction_admin_update_balance": "Admin given"
"transaction_admin_update_balance": "Admin given",
"transaction_admin_update_hourglasses": "Admin updated"
}

View File

@@ -273,6 +273,28 @@ api.updateHero = {
hero.balance = updateData.balance;
}
if (updateData.purchased && updateData.purchased.plan) {
if (updateData.purchased.plan.gemsBought) {
hero.purchased.plan.gemsBought = updateData.purchased.plan.gemsBought;
}
if (updateData.purchased.plan.consecutive) {
if (updateData.purchased.plan.consecutive.trinkets) {
await hero.updateHourglasses(
updateData.purchased.plan.consecutive.trinkets
- hero.purchased.plan.consecutive.trinkets,
'admin_update_hourglasses', '', 'Updated by Habitica staff',
);
hero.purchased.plan.consecutive.trinkets = updateData.purchased.plan.consecutive.trinkets;
}
if (updateData.purchased.plan.consecutive.gemCapExtra) {
hero.purchased.plan.consecutive.gemCapExtra = updateData.purchased.plan.consecutive.gemCapExtra; // eslint-disable-line max-len
}
if (updateData.purchased.plan.consecutive.count) {
hero.purchased.plan.consecutive.count = updateData.purchased.plan.consecutive.count; // eslint-disable-line max-len
}
}
}
// give them gems if they got an higher level
// tier = level in this context
let newTier = updateData.contributor && updateData.contributor.level;
@@ -331,6 +353,13 @@ api.updateHero = {
hero.apiToken = common.uuid();
}
if (updateData.resetCron) {
// Set last cron to yesterday. Quick approach so we don't need moment() for one line
const yesterday = new Date(new Date().setDate(new Date().getDate() - 1));
hero.lastCron = yesterday;
hero.auth.timestamps.loggedin = yesterday; // so admin panel doesn't gripe about mismatch
}
const savedHero = await hero.save();
const heroJSON = savedHero.toJSON();
heroJSON.secret = savedHero.getSecretData();

View File

@@ -5,7 +5,7 @@ import baseModel from '../libs/baseModel';
const { Schema } = mongoose;
export const currencies = ['gems', 'hourglasses'];
export const transactionTypes = ['buy_money', 'buy_gold', 'spend', 'gift_send', 'gift_receive', 'debug', 'create_challenge', 'create_bank_challenge', 'create_guild', 'change_class', 'rebirth', 'release_pets', 'release_mounts', 'reroll', 'contribution', 'subscription_perks', 'admin_update_balance'];
export const transactionTypes = ['buy_money', 'buy_gold', 'spend', 'gift_send', 'gift_receive', 'debug', 'create_challenge', 'create_bank_challenge', 'create_guild', 'change_class', 'rebirth', 'release_pets', 'release_mounts', 'reroll', 'contribution', 'subscription_perks', 'admin_update_balance', 'admin_update_hourglasses'];
export const schema = new Schema({
currency: { $type: String, enum: currencies, required: true },

View File

@@ -577,3 +577,22 @@ schema.methods.updateBalance = async function updateBalance (amount,
currentAmount: this.balance,
});
};
schema.methods.updateHourglasses = async function updateHourglasses (
amount,
transactionType,
reference,
referenceText,
) {
this.purchased.plan.consecutive.trinkets += amount;
await Transaction.create({
currency: 'hourglasses',
userId: this._id,
transactionType,
amount,
reference,
referenceText,
currentAmount: this.purchased.plan.consecutive.trinkets,
});
};