mirror of
https://github.com/LaCasemate/fab-manager.git
synced 2025-01-29 18:52:22 +01:00
compute payment schedule + basic display
This commit is contained in:
parent
506d9dd5fb
commit
21bd1312bc
@ -5,6 +5,7 @@
|
||||
- Fix a bug: unable to access embedded plan views
|
||||
- Fix a bug: warning message overflow in credit wallet modal
|
||||
- [TODO DEPLOY] `rails fablab:stripe:plans_prices`
|
||||
- [TODO DEPLOY] `rails fablab:maintenance:rebuild_stylesheet`
|
||||
|
||||
## v4.6.3 2020 October 28
|
||||
|
||||
|
2
Procfile
2
Procfile
@ -1,4 +1,4 @@
|
||||
web: bundle exec rails server puma -p $PORT
|
||||
#web: bundle exec rails server puma -p $PORT
|
||||
worker: bundle exec sidekiq -C ./config/sidekiq.yml
|
||||
wp-client: bin/webpack-dev-server
|
||||
wp-server: SERVER_BUNDLE_ONLY=yes bin/webpack --watch
|
||||
|
@ -155,10 +155,10 @@ class API::PaymentsController < API::ApiController
|
||||
current_user,
|
||||
reservable,
|
||||
slots,
|
||||
plan_id,
|
||||
nb_places,
|
||||
tickets,
|
||||
coupon_params[:coupon_code])
|
||||
plan_id: plan_id,
|
||||
nb_places: nb_places,
|
||||
tickets: tickets,
|
||||
coupon_code: coupon_params[:coupon_code])
|
||||
|
||||
# Subtract wallet amount from total
|
||||
total = price_details[:total]
|
||||
|
@ -41,18 +41,23 @@ class API::PricesController < API::ApiController
|
||||
# user
|
||||
user = User.find(price_parameters[:user_id])
|
||||
# reservable
|
||||
if [nil, ''].include? price_parameters[:reservable_id]
|
||||
if [nil, ''].include?(price_parameters[:reservable_id]) && ['', nil].include?(price_parameters[:plan_id])
|
||||
@amount = { elements: nil, total: 0, before_coupon: 0 }
|
||||
else
|
||||
reservable = price_parameters[:reservable_type].constantize.find(price_parameters[:reservable_id])
|
||||
reservable = if [nil, ''].include?(price_parameters[:reservable_id])
|
||||
nil
|
||||
else
|
||||
price_parameters[:reservable_type].constantize.find(price_parameters[:reservable_id])
|
||||
end
|
||||
@amount = Price.compute(current_user.admin? || (current_user.manager? && current_user.id != user.id),
|
||||
user,
|
||||
reservable,
|
||||
price_parameters[:slots_attributes] || [],
|
||||
price_parameters[:plan_id],
|
||||
price_parameters[:nb_reserve_places],
|
||||
price_parameters[:tickets_attributes],
|
||||
coupon_params[:coupon_code])
|
||||
plan_id: price_parameters[:plan_id],
|
||||
nb_places: price_parameters[:nb_reserve_places],
|
||||
tickets: price_parameters[:tickets_attributes],
|
||||
coupon_code: coupon_params[:coupon_code],
|
||||
payment_schedule: price_parameters[:payment_schedule])
|
||||
end
|
||||
|
||||
|
||||
@ -70,7 +75,7 @@ class API::PricesController < API::ApiController
|
||||
end
|
||||
|
||||
def compute_price_params
|
||||
params.require(:reservation).permit(:reservable_id, :reservable_type, :plan_id, :user_id, :nb_reserve_places,
|
||||
params.require(:reservation).permit(:reservable_id, :reservable_type, :plan_id, :user_id, :nb_reserve_places, :payment_schedule,
|
||||
tickets_attributes: %i[event_price_category_id booked],
|
||||
slots_attributes: %i[id start_at end_at availability_id offered])
|
||||
end
|
||||
|
@ -65,10 +65,10 @@ class API::ReservationsController < API::ApiController
|
||||
user,
|
||||
reservation_params[:reservable_type].constantize.find(reservation_params[:reservable_id]),
|
||||
reservation_params[:slots_attributes] || [],
|
||||
reservation_params[:plan_id],
|
||||
reservation_params[:nb_reserve_places],
|
||||
reservation_params[:tickets_attributes],
|
||||
coupon_params[:coupon_code])
|
||||
plan_id: reservation_params[:plan_id],
|
||||
nb_places: reservation_params[:nb_reserve_places],
|
||||
tickets: reservation_params[:tickets_attributes],
|
||||
coupon_code: coupon_params[:coupon_code])
|
||||
|
||||
# Subtract wallet amount from total
|
||||
total = price_details[:total]
|
||||
|
@ -54,10 +54,10 @@ class API::SubscriptionsController < API::ApiController
|
||||
user,
|
||||
nil,
|
||||
[],
|
||||
subscription_params[:plan_id],
|
||||
nil,
|
||||
nil,
|
||||
coupon_params[:coupon_code])
|
||||
plan_id: subscription_params[:plan_id],
|
||||
nb_places: nil,
|
||||
tickets: nil,
|
||||
coupon_code: coupon_params[:coupon_code])
|
||||
|
||||
# Subtract wallet amount from total
|
||||
total = price_details[:total]
|
||||
|
@ -12,8 +12,8 @@
|
||||
*/
|
||||
'use strict';
|
||||
|
||||
Application.Controllers.controller('PlansIndexController', ['$scope', '$rootScope', '$state', '$uibModal', 'Auth', 'AuthService', 'dialogs', 'growl', 'plansPromise', 'groupsPromise', 'Subscription', 'Member', 'subscriptionExplicationsPromise', '_t', 'Wallet', 'helpers', 'settingsPromise',
|
||||
function ($scope, $rootScope, $state, $uibModal, Auth, AuthService, dialogs, growl, plansPromise, groupsPromise, Subscription, Member, subscriptionExplicationsPromise, _t, Wallet, helpers, settingsPromise) {
|
||||
Application.Controllers.controller('PlansIndexController', ['$scope', '$rootScope', '$state', '$uibModal', 'Auth', 'AuthService', 'dialogs', 'growl', 'plansPromise', 'groupsPromise', 'Subscription', 'Member', 'subscriptionExplicationsPromise', '_t', 'Wallet', 'helpers', 'settingsPromise', 'Price',
|
||||
function ($scope, $rootScope, $state, $uibModal, Auth, AuthService, dialogs, growl, plansPromise, groupsPromise, Subscription, Member, subscriptionExplicationsPromise, _t, Wallet, helpers, settingsPromise, Price) {
|
||||
/* PUBLIC SCOPE */
|
||||
|
||||
// list of groups
|
||||
@ -46,9 +46,12 @@ Application.Controllers.controller('PlansIndexController', ['$scope', '$rootScop
|
||||
$scope.coupon =
|
||||
{ applied: null };
|
||||
|
||||
// Storage for the total price (plan price + coupon, if any)
|
||||
$scope.cart =
|
||||
{ total: null };
|
||||
// Storage for the total price (plan price + coupon, if any) and of the payment schedule
|
||||
$scope.cart = {
|
||||
total: null,
|
||||
payment_schedule: false,
|
||||
schedule: null
|
||||
};
|
||||
|
||||
// text that appears in the bottom-right box of the page (subscriptions rules details)
|
||||
$scope.subscriptionExplicationsAlert = subscriptionExplicationsPromise.setting.value;
|
||||
@ -76,6 +79,7 @@ Application.Controllers.controller('PlansIndexController', ['$scope', '$rootScop
|
||||
if ($scope.isAuthenticated()) {
|
||||
if ($scope.selectedPlan !== plan) {
|
||||
$scope.selectedPlan = plan;
|
||||
$scope.cart.payment_schedule = plan.monthly_payment;
|
||||
updateCartPrice();
|
||||
} else {
|
||||
$scope.selectedPlan = null;
|
||||
@ -87,6 +91,18 @@ Application.Controllers.controller('PlansIndexController', ['$scope', '$rootScop
|
||||
}, 50);
|
||||
};
|
||||
|
||||
/**
|
||||
* This will update the payment_schedule setting when the user toggles the switch button
|
||||
* @param checked {Boolean}
|
||||
*/
|
||||
$scope.togglePaymentSchedule = (checked) => {
|
||||
setTimeout(() => {
|
||||
$scope.cart.payment_schedule = checked;
|
||||
updateCartPrice();
|
||||
$scope.$apply();
|
||||
}, 50);
|
||||
};
|
||||
|
||||
/**
|
||||
* Check if the provided plan is currently selected
|
||||
* @param plan {Object} Resource plan
|
||||
@ -101,17 +117,17 @@ Application.Controllers.controller('PlansIndexController', ['$scope', '$rootScop
|
||||
$scope.openSubscribePlanModal = function () {
|
||||
Wallet.getWalletByUser({ user_id: $scope.ctrl.member.id }, function (wallet) {
|
||||
const amountToPay = helpers.getAmountToPay($scope.cart.total, wallet.amount);
|
||||
if ((AuthService.isAuthorized('member') && amountToPay > 0)
|
||||
|| (AuthService.isAuthorized('manager') && $scope.ctrl.member.id === $rootScope.currentUser.id && amountToPay > 0)) {
|
||||
if ((AuthService.isAuthorized('member') && amountToPay > 0) ||
|
||||
(AuthService.isAuthorized('manager') && $scope.ctrl.member.id === $rootScope.currentUser.id && amountToPay > 0)) {
|
||||
if (settingsPromise.online_payment_module !== 'true') {
|
||||
growl.error(_t('app.public.plans.online_payment_disabled'));
|
||||
} else {
|
||||
return payByStripe();
|
||||
}
|
||||
} else {
|
||||
if (AuthService.isAuthorized('admin')
|
||||
|| (AuthService.isAuthorized('manager') && $scope.ctrl.member.id !== $rootScope.currentUser.id)
|
||||
|| amountToPay === 0) {
|
||||
if (AuthService.isAuthorized('admin') ||
|
||||
(AuthService.isAuthorized('manager') && $scope.ctrl.member.id !== $rootScope.currentUser.id) ||
|
||||
amountToPay === 0) {
|
||||
return payOnSite();
|
||||
}
|
||||
}
|
||||
@ -191,7 +207,7 @@ Application.Controllers.controller('PlansIndexController', ['$scope', '$rootScop
|
||||
// group all plans by Group
|
||||
for (const group of $scope.groups) {
|
||||
const groupObj = { id: group.id, name: group.name, plans: [], actives: 0 };
|
||||
for (let plan of plansPromise) {
|
||||
for (const plan of plansPromise) {
|
||||
if (plan.group_id === group.id) {
|
||||
groupObj.plans.push(plan);
|
||||
if (!plan.disabled) { groupObj.actives++; }
|
||||
@ -225,22 +241,44 @@ Application.Controllers.controller('PlansIndexController', ['$scope', '$rootScop
|
||||
const updateCartPrice = function () {
|
||||
// first we check the selection of a user
|
||||
if (Object.keys($scope.ctrl.member).length > 0 && $scope.selectedPlan) {
|
||||
$scope.cart.total = $scope.selectedPlan.amount;
|
||||
// apply the coupon if any
|
||||
if ($scope.coupon.applied) {
|
||||
let discount;
|
||||
if ($scope.coupon.applied.type === 'percent_off') {
|
||||
discount = ($scope.cart.total * $scope.coupon.applied.percent_off) / 100;
|
||||
} else if ($scope.coupon.applied.type === 'amount_off') {
|
||||
discount = $scope.coupon.applied.amount_off;
|
||||
}
|
||||
return $scope.cart.total -= discount;
|
||||
}
|
||||
const r = mkReservation($scope.ctrl.member, $scope.selectedPlan);
|
||||
Price.compute(mkRequestParams(r, $scope.coupon.applied), function (res) {
|
||||
$scope.cart.total = res.price;
|
||||
$scope.cart.schedule = res.schedule;
|
||||
});
|
||||
} else {
|
||||
return $scope.reserve.amountTotal = null;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Format the parameters expected by /api/prices/compute or /api/reservations and return the resulting object
|
||||
* @param reservation {Object} as returned by mkReservation()
|
||||
* @param coupon {Object} Coupon as returned from the API
|
||||
* @return {{reservation:Object, coupon_code:string}}
|
||||
*/
|
||||
const mkRequestParams = function (reservation, coupon) {
|
||||
return {
|
||||
reservation,
|
||||
coupon_code: ((coupon ? coupon.code : undefined))
|
||||
};
|
||||
};
|
||||
|
||||
/**
|
||||
* Create an hash map implementing the Reservation specs
|
||||
* @param member {Object} User as retrieved from the API: current user / selected user if current is admin
|
||||
* @param [plan] {Object} Plan as retrieved from the API: plan to buy with the current reservation
|
||||
* @return {{user_id:Number, slots_attributes:Array<Object>, plan_id:Number|null}}
|
||||
*/
|
||||
const mkReservation = function (member, plan) {
|
||||
return {
|
||||
user_id: member.id,
|
||||
slots_attributes: [],
|
||||
plan_id: ((plan ? plan.id : undefined)),
|
||||
payment_schedule: $scope.cart.payment_schedule
|
||||
};
|
||||
};
|
||||
|
||||
/**
|
||||
* Open a modal window which trigger the stripe payment process
|
||||
*/
|
||||
@ -296,7 +334,7 @@ Application.Controllers.controller('PlansIndexController', ['$scope', '$rootScop
|
||||
};
|
||||
}
|
||||
]
|
||||
}).result['finally'](null).then(function (subscription) {
|
||||
}).result.finally(null).then(function (subscription) {
|
||||
$scope.ctrl.member.subscribed_plan = angular.copy($scope.selectedPlan);
|
||||
Auth._currentUser.subscribed_plan = angular.copy($scope.selectedPlan);
|
||||
$scope.paid.plan = angular.copy($scope.selectedPlan);
|
||||
@ -383,7 +421,7 @@ Application.Controllers.controller('PlansIndexController', ['$scope', '$rootScop
|
||||
$scope.cancel = function () { $uibModalInstance.dismiss('cancel'); };
|
||||
}
|
||||
]
|
||||
}).result['finally'](null).then(function (subscription) {
|
||||
}).result.finally(null).then(function (subscription) {
|
||||
$scope.ctrl.member.subscribed_plan = angular.copy($scope.selectedPlan);
|
||||
Auth._currentUser.subscribed_plan = angular.copy($scope.selectedPlan);
|
||||
$scope.ctrl.member = null;
|
||||
|
@ -118,10 +118,24 @@
|
||||
</div>
|
||||
|
||||
<coupon show="!ctrl.member.subscribed_plan" coupon="coupon.applied" total="selectedPlan.amount" user-id="{{ctrl.member.id}}"></coupon>
|
||||
|
||||
<label for="payment_schedule" translate>{{ 'app.public.plans.monthly_payment' }}</label>
|
||||
<switch checked="cart.payment_schedule" id="payment_schedule" on-change="togglePaymentSchedule" class-name="'v-middle'" ng-if="selectedPlan.monthly_payment"></switch>
|
||||
</div>
|
||||
|
||||
<div class="widget-footer">
|
||||
<button class="btn btn-valid btn-info btn-block p-l text-u-c r-b" ng-click="openSubscribePlanModal()" ng-if="!ctrl.member.subscribed_plan">{{ 'app.public.plans.confirm_and_pay' | translate }} {{cart.total | currency}}</button>
|
||||
<div ng-if="cart.schedule">
|
||||
<h4 translate>{{ 'app.public.plans.your_payment_schedule' }}</h4>
|
||||
<ul>
|
||||
<li ng-repeat="item in cart.schedule.items">
|
||||
<span>{{item.due_date | amDateFormat:'L'}}</span>
|
||||
<span>{{item.price | currency}}</span>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
<button class="btn btn-valid btn-info btn-block p-l text-u-c r-b" ng-click="openSubscribePlanModal()" ng-if="!ctrl.member.subscribed_plan">
|
||||
{{ 'app.public.plans.confirm_and_pay' | translate }} {{cart.total | currency}}
|
||||
</button>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
|
@ -20,13 +20,15 @@ class Price < ApplicationRecord
|
||||
# @param user {User} The user who's reserving (or selected if an admin is reserving)
|
||||
# @param reservable {Machine|Training|Event} what the reservation is targeting
|
||||
# @param slots {Array<Slot>} when did the reservation will occur
|
||||
# @param [plan_id] {Number} if the user is subscribing to a plan at the same time of his reservation, specify the plan's ID here
|
||||
# @param [nb_places] {Number} for _reservable_ of type Event, pass here the number of booked places
|
||||
# @param [tickets] {Array<Ticket>} for _reservable_ of type Event, mapping of the number of seats booked per price's category
|
||||
# @param [coupon_code] {String} Code of the coupon to apply to the total price
|
||||
# @param options {plan_id:Number, nb_places:Number, tickets:Array<Ticket>, coupon_code:String, payment_schedule:Boolean}
|
||||
# - plan_id {Number} if the user is subscribing to a plan at the same time of his reservation, specify the plan's ID here
|
||||
# - nb_places {Number} for _reservable_ of type Event, pass here the number of booked places
|
||||
# - tickets {Array<Ticket>} for _reservable_ of type Event, mapping of the number of seats booked per price's category
|
||||
# - coupon_code {String} Code of the coupon to apply to the total price
|
||||
# - payment_schedule {Boolean} if the user is requesting a payment schedule for his subscription
|
||||
# @return {Hash} total and price detail
|
||||
##
|
||||
def compute(admin, user, reservable, slots, plan_id = nil, nb_places = nil, tickets = nil, coupon_code = nil)
|
||||
def compute(admin, user, reservable, slots, options = {})
|
||||
total_amount = 0
|
||||
all_elements = {}
|
||||
all_elements[:slots] = []
|
||||
@ -35,9 +37,9 @@ class Price < ApplicationRecord
|
||||
plan = if user.subscribed_plan
|
||||
new_plan_being_bought = false
|
||||
user.subscribed_plan
|
||||
elsif plan_id
|
||||
elsif options[:plan_id]
|
||||
new_plan_being_bought = true
|
||||
Plan.find(plan_id)
|
||||
Plan.find(options[:plan_id])
|
||||
else
|
||||
new_plan_being_bought = false
|
||||
nil
|
||||
@ -91,8 +93,8 @@ class Price < ApplicationRecord
|
||||
|
||||
# Event reservation
|
||||
when Event
|
||||
amount = reservable.amount * nb_places
|
||||
tickets&.each do |ticket|
|
||||
amount = reservable.amount * options[:nb_places]
|
||||
options[:tickets]&.each do |ticket|
|
||||
amount += ticket[:booked] * EventPriceCategory.find(ticket[:event_price_category_id]).amount
|
||||
end
|
||||
slots.each do |slot|
|
||||
@ -130,8 +132,8 @@ class Price < ApplicationRecord
|
||||
raise NotImplementedError
|
||||
end
|
||||
|
||||
# === compute Plan price if any ===
|
||||
unless plan_id.nil?
|
||||
# === compute Plan price (if any) ===
|
||||
unless options[:plan_id].nil?
|
||||
all_elements[:plan] = plan.amount
|
||||
total_amount += plan.amount
|
||||
end
|
||||
@ -139,11 +141,29 @@ class Price < ApplicationRecord
|
||||
# === apply Coupon if any ===
|
||||
_amount_no_coupon = total_amount
|
||||
cs = CouponService.new
|
||||
cp = cs.validate(coupon_code, user.id)
|
||||
cp = cs.validate(options[:coupon_code], user.id)
|
||||
total_amount = cs.apply(total_amount, cp)
|
||||
|
||||
# == generate PaymentSchedule ()if applicable) ===
|
||||
schedule = if options[:payment_schedule] && plan.monthly_payment
|
||||
pss = PaymentScheduleService.new
|
||||
pss.compute(plan, _amount_no_coupon, cp)
|
||||
else
|
||||
nil
|
||||
end
|
||||
if schedule
|
||||
total_amount -= schedule[:payment_schedule].total
|
||||
total_amount += schedule[:items][0].amount
|
||||
end
|
||||
|
||||
# return result
|
||||
{ elements: all_elements, total: total_amount.to_i, before_coupon: _amount_no_coupon.to_i, coupon: cp }
|
||||
{
|
||||
elements: all_elements,
|
||||
total: total_amount.to_i,
|
||||
before_coupon: _amount_no_coupon.to_i,
|
||||
coupon: cp,
|
||||
schedule: schedule
|
||||
}
|
||||
end
|
||||
|
||||
|
||||
|
38
app/services/payment_schedule_service.rb
Normal file
38
app/services/payment_schedule_service.rb
Normal file
@ -0,0 +1,38 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
# create PaymentSchedules for various items
|
||||
class PaymentScheduleService
|
||||
##
|
||||
# Compute a payment schedule for a new subscription to the provided plan
|
||||
# @param plan {Plan}
|
||||
# @param total {Number} Total amount of the current shopping cart (which includes this plan)
|
||||
# @param coupon {Coupon} apply this coupon, if any
|
||||
##
|
||||
def compute(plan, total, coupon = nil)
|
||||
price = if coupon
|
||||
cs = CouponService.new
|
||||
cs.ventilate(total, plan.amount, coupon)
|
||||
else
|
||||
plan.amount
|
||||
end
|
||||
ps = PaymentSchedule.new(scheduled: plan, total: price, coupon: coupon)
|
||||
deadlines = plan.duration / 1.month
|
||||
per_month = price / deadlines
|
||||
adjustment = if per_month * deadlines != price
|
||||
price - (per_month * deadlines)
|
||||
else
|
||||
0
|
||||
end
|
||||
items = []
|
||||
(0..deadlines - 1).each do |i|
|
||||
date = DateTime.current + i.months
|
||||
items.push PaymentScheduleItem.new(
|
||||
amount: per_month + adjustment,
|
||||
due_date: date,
|
||||
payment_schedule: ps
|
||||
)
|
||||
adjustment = 0
|
||||
end
|
||||
{ payment_schedule: ps, items: items }
|
||||
end
|
||||
end
|
@ -1,10 +1,20 @@
|
||||
json.price @amount[:total] / 100.00
|
||||
json.price_without_coupon @amount[:before_coupon] / 100.00
|
||||
json.details do
|
||||
json.slots @amount[:elements][:slots] do |slot|
|
||||
json.start_at slot[:start_at]
|
||||
json.price slot[:price] / 100.00
|
||||
json.promo slot[:promo]
|
||||
if @amount[:elements]
|
||||
json.details do
|
||||
json.slots @amount[:elements][:slots] do |slot|
|
||||
json.start_at slot[:start_at]
|
||||
json.price slot[:price] / 100.00
|
||||
json.promo slot[:promo]
|
||||
end
|
||||
json.plan @amount[:elements][:plan] / 100.00 if @amount[:elements][:plan]
|
||||
end
|
||||
json.plan @amount[:elements][:plan] / 100.00 if @amount[:elements][:plan]
|
||||
end if @amount[:elements]
|
||||
end
|
||||
if @amount[:schedule]
|
||||
json.schedule do
|
||||
json.items @amount[:schedule][:items] do |item|
|
||||
json.price item.amount / 100.00
|
||||
json.due_date item.due_date
|
||||
end
|
||||
end
|
||||
end
|
||||
|
@ -250,7 +250,9 @@ en:
|
||||
your_subscription_has_expired_on_the_DATE: "Your subscription has expired on the {DATE}"
|
||||
subscription_price: "Subscription price"
|
||||
you_ve_just_selected_a_subscription_html: "You've just selected a <strong>subscription</strong>:"
|
||||
monthly_payment: "Pay by monthly schedule"
|
||||
confirm_and_pay: "Confirm and pay"
|
||||
your_payment_schedule: "Your payment schedule"
|
||||
you_ve_just_payed_the_subscription_html: "You've just paid the <strong>subscription</strong>:"
|
||||
thank_you_your_subscription_is_successful: "Thank you. Your subscription is successful!"
|
||||
your_invoice_will_be_available_soon_from_your_dashboard: "Your invoice will be available soon from your dashboard"
|
||||
|
@ -250,6 +250,8 @@ fr:
|
||||
your_subscription_has_expired_on_the_DATE: "Votre abonnement a expiré au {DATE}"
|
||||
subscription_price: "Coût de l'abonnement"
|
||||
you_ve_just_selected_a_subscription_html: "Vous venez de sélectionner un <strong>abonnement</strong> :"
|
||||
monthly_payment: "Payer par échéancier mensuel"
|
||||
your_payment_schedule: "Votre échéancier de paiement"
|
||||
confirm_and_pay: "Valider et payer"
|
||||
you_ve_just_payed_the_subscription_html: "Vous venez de régler <strong>l'abonnement</strong> :"
|
||||
thank_you_your_subscription_is_successful: "Merci. Votre abonnement a bien été pris en compte !"
|
||||
|
@ -108,8 +108,8 @@ SET default_tablespace = '';
|
||||
|
||||
CREATE TABLE public.abuses (
|
||||
id integer NOT NULL,
|
||||
signaled_id integer,
|
||||
signaled_type character varying,
|
||||
signaled_id integer,
|
||||
first_name character varying,
|
||||
last_name character varying,
|
||||
email character varying,
|
||||
@ -187,8 +187,8 @@ CREATE TABLE public.addresses (
|
||||
locality character varying,
|
||||
country character varying,
|
||||
postal_code character varying,
|
||||
placeable_id integer,
|
||||
placeable_type character varying,
|
||||
placeable_id integer,
|
||||
created_at timestamp without time zone,
|
||||
updated_at timestamp without time zone
|
||||
);
|
||||
@ -263,8 +263,8 @@ CREATE TABLE public.ar_internal_metadata (
|
||||
|
||||
CREATE TABLE public.assets (
|
||||
id integer NOT NULL,
|
||||
viewable_id integer,
|
||||
viewable_type character varying,
|
||||
viewable_id integer,
|
||||
attachment character varying,
|
||||
type character varying,
|
||||
created_at timestamp without time zone,
|
||||
@ -504,8 +504,8 @@ ALTER SEQUENCE public.coupons_id_seq OWNED BY public.coupons.id;
|
||||
|
||||
CREATE TABLE public.credits (
|
||||
id integer NOT NULL,
|
||||
creditable_id integer,
|
||||
creditable_type character varying,
|
||||
creditable_id integer,
|
||||
plan_id integer,
|
||||
hours integer,
|
||||
created_at timestamp without time zone,
|
||||
@ -1046,8 +1046,8 @@ ALTER SEQUENCE public.invoice_items_id_seq OWNED BY public.invoice_items.id;
|
||||
|
||||
CREATE TABLE public.invoices (
|
||||
id integer NOT NULL,
|
||||
invoiced_id integer,
|
||||
invoiced_type character varying,
|
||||
invoiced_id integer,
|
||||
stp_invoice_id character varying,
|
||||
total integer,
|
||||
created_at timestamp without time zone,
|
||||
@ -1226,15 +1226,15 @@ ALTER SEQUENCE public.machines_id_seq OWNED BY public.machines.id;
|
||||
CREATE TABLE public.notifications (
|
||||
id integer NOT NULL,
|
||||
receiver_id integer,
|
||||
attached_object_id integer,
|
||||
attached_object_type character varying,
|
||||
attached_object_id integer,
|
||||
notification_type_id integer,
|
||||
is_read boolean DEFAULT false,
|
||||
created_at timestamp without time zone,
|
||||
updated_at timestamp without time zone,
|
||||
receiver_type character varying,
|
||||
is_send boolean DEFAULT false,
|
||||
meta_data jsonb DEFAULT '{}'::jsonb
|
||||
meta_data jsonb DEFAULT '"{}"'::jsonb
|
||||
);
|
||||
|
||||
|
||||
@ -1653,8 +1653,8 @@ CREATE TABLE public.prices (
|
||||
id integer NOT NULL,
|
||||
group_id integer,
|
||||
plan_id integer,
|
||||
priceable_id integer,
|
||||
priceable_type character varying,
|
||||
priceable_id integer,
|
||||
amount integer,
|
||||
created_at timestamp without time zone NOT NULL,
|
||||
updated_at timestamp without time zone NOT NULL
|
||||
@ -1969,8 +1969,8 @@ CREATE TABLE public.reservations (
|
||||
message text,
|
||||
created_at timestamp without time zone,
|
||||
updated_at timestamp without time zone,
|
||||
reservable_id integer,
|
||||
reservable_type character varying,
|
||||
reservable_id integer,
|
||||
nb_reserve_places integer,
|
||||
statistic_profile_id integer
|
||||
);
|
||||
@ -2002,8 +2002,8 @@ ALTER SEQUENCE public.reservations_id_seq OWNED BY public.reservations.id;
|
||||
CREATE TABLE public.roles (
|
||||
id integer NOT NULL,
|
||||
name character varying,
|
||||
resource_id integer,
|
||||
resource_type character varying,
|
||||
resource_id integer,
|
||||
created_at timestamp without time zone,
|
||||
updated_at timestamp without time zone
|
||||
);
|
||||
@ -2937,8 +2937,8 @@ CREATE TABLE public.users_roles (
|
||||
CREATE TABLE public.wallet_transactions (
|
||||
id integer NOT NULL,
|
||||
wallet_id integer,
|
||||
transactable_id integer,
|
||||
transactable_type character varying,
|
||||
transactable_id integer,
|
||||
transaction_type character varying,
|
||||
amount integer,
|
||||
created_at timestamp without time zone NOT NULL,
|
||||
@ -4027,6 +4027,14 @@ ALTER TABLE ONLY public.roles
|
||||
ADD CONSTRAINT roles_pkey PRIMARY KEY (id);
|
||||
|
||||
|
||||
--
|
||||
-- Name: schema_migrations schema_migrations_pkey; Type: CONSTRAINT; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
ALTER TABLE ONLY public.schema_migrations
|
||||
ADD CONSTRAINT schema_migrations_pkey PRIMARY KEY (version);
|
||||
|
||||
|
||||
--
|
||||
-- Name: settings settings_pkey; Type: CONSTRAINT; Schema: public; Owner: -
|
||||
--
|
||||
@ -5084,29 +5092,6 @@ CREATE INDEX profiles_lower_unaccent_last_name_trgm_idx ON public.profiles USING
|
||||
CREATE INDEX projects_search_vector_idx ON public.projects USING gin (search_vector);
|
||||
|
||||
|
||||
--
|
||||
-- Name: unique_schema_migrations; Type: INDEX; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
CREATE UNIQUE INDEX unique_schema_migrations ON public.schema_migrations USING btree (version);
|
||||
|
||||
|
||||
--
|
||||
-- Name: accounting_periods accounting_periods_del_protect; Type: RULE; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
CREATE RULE accounting_periods_del_protect AS
|
||||
ON DELETE TO public.accounting_periods DO INSTEAD NOTHING;
|
||||
|
||||
|
||||
--
|
||||
-- Name: accounting_periods accounting_periods_upd_protect; Type: RULE; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
CREATE RULE accounting_periods_upd_protect AS
|
||||
ON UPDATE TO public.accounting_periods DO INSTEAD NOTHING;
|
||||
|
||||
|
||||
--
|
||||
-- Name: projects projects_search_content_trigger; Type: TRIGGER; Schema: public; Owner: -
|
||||
--
|
||||
@ -5633,7 +5618,6 @@ INSERT INTO "schema_migrations" (version) VALUES
|
||||
('20140605125131'),
|
||||
('20140605142133'),
|
||||
('20140605151442'),
|
||||
('20140606133116'),
|
||||
('20140609092700'),
|
||||
('20140609092827'),
|
||||
('20140610153123'),
|
||||
@ -5702,14 +5686,12 @@ INSERT INTO "schema_migrations" (version) VALUES
|
||||
('20150507075620'),
|
||||
('20150512123546'),
|
||||
('20150520132030'),
|
||||
('20150520133409'),
|
||||
('20150526130729'),
|
||||
('20150527153312'),
|
||||
('20150529113555'),
|
||||
('20150601125944'),
|
||||
('20150603104502'),
|
||||
('20150603104658'),
|
||||
('20150603133050'),
|
||||
('20150604081757'),
|
||||
('20150604131525'),
|
||||
('20150608142234'),
|
||||
@ -5791,7 +5773,6 @@ INSERT INTO "schema_migrations" (version) VALUES
|
||||
('20160905142700'),
|
||||
('20160906094739'),
|
||||
('20160906094847'),
|
||||
('20160906145713'),
|
||||
('20160915105234'),
|
||||
('20161123104604'),
|
||||
('20170109085345'),
|
||||
|
Loading…
x
Reference in New Issue
Block a user