diff --git a/plugin/buycourses/src/subscription_add.php b/plugin/buycourses/src/subscription_add.php
new file mode 100644
index 0000000000..4f37dce862
--- /dev/null
+++ b/plugin/buycourses/src/subscription_add.php
@@ -0,0 +1,234 @@
+get('include_sessions') === 'true';
+
+$entityManager = Database::getManager();
+$userRepo = UserManager::getRepository();
+$currency = $plugin->getSelectedCurrency();
+
+if (empty($currency)) {
+ Display::addFlash(
+ Display::return_message($plugin->get_lang('CurrencyIsNotConfigured'), 'error')
+ );
+}
+
+$currencyIso = null;
+
+if ($editingCourse) {
+ $course = $entityManager->find('ChamiloCoreBundle:Course', $id);
+ if (!$course) {
+ api_not_allowed(true);
+ }
+
+ $courseItem = $plugin->getCourseForConfiguration($course, $currency);
+
+ $currencyIso = $courseItem['currency'];
+ $formDefaults = [
+ 'product_type' => get_lang('Course'),
+ 'id' => $courseItem['course_id'],
+ 'type' => BuyCoursesPlugin::PRODUCT_TYPE_COURSE,
+ 'name' => $courseItem['course_title'],
+ 'visible' => $courseItem['visible'],
+ 'price' => $courseItem['price'],
+ 'tax_perc' => $courseItem['tax_perc'],
+ 'currency_id' => $currency['id'],
+ ];
+} else if ($editingSession) {
+ if (!$includeSession) {
+ api_not_allowed(true);
+ }
+
+ $session = $entityManager->find('ChamiloCoreBundle:Session', $id);
+ if (!$session) {
+ api_not_allowed(true);
+ }
+
+ $sessionItem = $plugin->getSessionForConfiguration($session, $currency);
+
+ $currencyIso = $sessionItem['currency'];
+ $formDefaults = [
+ 'product_type' => get_lang('Session'),
+ 'id' => $session->getId(),
+ 'type' => BuyCoursesPlugin::PRODUCT_TYPE_SESSION,
+ 'name' => $sessionItem['session_name'],
+ 'visible' => $sessionItem['visible'],
+ 'price' => $sessionItem['price'],
+ 'tax_perc' => $sessionItem['tax_perc'],
+ 'currency_id' => $currency['id'],
+ ];
+} else {
+ api_not_allowed(true);
+}
+
+$globalSettingsParams = $plugin->getGlobalParameters();
+
+$form = new FormValidator('add_subscription');
+
+$form->addText('product_type', $plugin->get_lang('ProductType'), false);
+$form->addText('name', get_lang('Name'), false);
+
+$form->freeze(['product_type', 'name']);
+
+$form->addElement(
+ 'number',
+ 'tax_perc',
+ [$plugin->get_lang('TaxPerc'), $plugin->get_lang('TaxPercDescription'), '%'],
+ ['step' => 1, 'placeholder' => $globalSettingsParams['global_tax_perc'].'% '.$plugin->get_lang('ByDefault')]
+);
+
+$frequencies = $plugin->getFrequencies();
+
+$selectOptions = '';
+foreach ($frequencies as $key => $frequency) {
+ $selectOptions .= '';
+}
+
+if (empty($frequencies)) {
+ Display::addFlash(
+ Display::return_message($plugin->get_lang('FrequencyIsNotConfigured'), 'error')
+ );
+}
+
+$platformCommission = $plugin->getPlatformCommission();
+$form->addHtml(
+ '
+
+ '
+);
+
+$form->addHidden('type', null);
+$form->addHidden('id', null);
+$button = $form->addButtonSave(get_lang('Save'));
+
+if (empty($currency) || empty($frequencies)) {
+ $button->setAttribute('disabled');
+}
+
+if ($form->validate()) {
+ $formValues = $form->getSubmitValues();
+ $subscription['product_id'] = $formValues['id'];
+ $subscription['product_type'] = $formValues['type'];
+ $subscription['currency_id'] = $currency['id'];
+ $subscription['tax_perc'] = $formValues['tax_perc'] != '' ? (int) $formValues['tax_perc'] : null;
+ $subscription['frequencies'] = isset($formValues['frequencies']) ? $formValues['frequencies'] : [];
+
+ $result = $plugin->addNewSubscription($subscription);
+
+ if ($result) {
+ header('Location: '.api_get_path(WEB_PLUGIN_PATH).'buycourses/src/subscriptions_courses.php');
+ } else {
+ header('Location:'.api_get_self().'?'.$queryString);
+ }
+
+ exit;
+}
+
+$form->setDefaults($formDefaults);
+
+$templateName = $plugin->get_lang('SubscriptionAdd');
+$interbreadcrumb[] = [
+ 'url' => 'subscriptions_courses.php',
+ 'name' => get_lang('Configuration'),
+];
+$interbreadcrumb[] = [
+ 'url' => 'subscriptions_courses.php',
+ 'name' => $plugin->get_lang('SubscriptionList'),
+];
+
+$template = new Template($templateName);
+$template->assign('header', $templateName);
+$template->assign('items_form', $form->returnForm());
+$template->assign('currencyIso', $currencyIso);
+
+$content = $template->fetch('buycourses/view/subscription_add.tpl');
+$template->assign('content', $content);
+
+$template->display_one_col_template();
diff --git a/plugin/buycourses/src/subscription_course_catalog.php b/plugin/buycourses/src/subscription_course_catalog.php
new file mode 100644
index 0000000000..db9e2c7f78
--- /dev/null
+++ b/plugin/buycourses/src/subscription_course_catalog.php
@@ -0,0 +1,88 @@
+get('include_sessions') === 'true';
+$includeServices = $plugin->get('include_services') === 'true';
+
+$nameFilter = '';
+
+$form = new FormValidator(
+ 'search_filter_form',
+ 'get',
+ null,
+ null,
+ [],
+ FormValidator::LAYOUT_INLINE
+);
+
+if ($form->validate()) {
+ $formValues = $form->getSubmitValues();
+ $nameFilter = isset($formValues['name']) ? $formValues['name'] : null;
+}
+
+$form->addHeader($plugin->get_lang('SearchFilter'));
+$form->addText('name', get_lang('CourseName'), false);
+$form->addHtml('
');
+$form->addButtonFilter(get_lang('Search'));
+
+$pageSize = BuyCoursesPlugin::PAGINATION_PAGE_SIZE;
+$currentPage = isset($_GET['page']) ? (int) $_GET['page'] : 1;
+$first = $pageSize * ($currentPage - 1);
+$courseList = $plugin->getCatalogSubscriptionCourseList($first, $pageSize, $nameFilter);
+$totalItems = $plugin->getCatalogSubscriptionCourseList($first, $pageSize, $nameFilter, 'count');
+$pagesCount = ceil($totalItems / $pageSize);
+
+$pagination = BuyCoursesPlugin::returnPagination(api_get_self(), $currentPage, $pagesCount, $totalItems);
+
+// View
+if (api_is_platform_admin()) {
+ $interbreadcrumb[] = [
+ 'url' => 'subscriptions_courses.php',
+ 'name' => $plugin->get_lang('AvailableCoursesConfiguration'),
+ ];
+ $interbreadcrumb[] = [
+ 'url' => 'paymentsetup.php',
+ 'name' => $plugin->get_lang('PaymentsConfiguration'),
+ ];
+} else {
+ $interbreadcrumb[] = [
+ 'url' => 'course_panel.php',
+ 'name' => get_lang('TabsDashboard'),
+ ];
+}
+
+$htmlHeadXtra[] = api_get_css(api_get_path(WEB_PLUGIN_PATH).'buycourses/resources/css/style.css');
+
+$templateName = $plugin->get_lang('SubscriptionListOnSale');
+$tpl = new Template($templateName);
+$tpl->assign('search_filter_form', $form->returnForm());
+$tpl->assign('showing_courses', true);
+$tpl->assign('courses', $courseList);
+$tpl->assign('sessions_are_included', $includeSessions);
+$tpl->assign('pagination', $pagination);
+
+$sessionList = $plugin->getCatalogSubscriptionSessionList($first, $pageSize, $nameFilter, 'first', 0);
+$coursesExist = true;
+$sessionExist = true;
+if (count($sessionList) <= 0) {
+ $sessionExist = false;
+}
+
+$tpl->assign('coursesExist', $coursesExist);
+$tpl->assign('sessionExist', $sessionExist);
+
+$content = $tpl->fetch('buycourses/view/subscription_catalog.tpl');
+
+$tpl->assign('header', $templateName);
+$tpl->assign('content', $content);
+$tpl->display_one_col_template();
diff --git a/plugin/buycourses/src/subscription_process.php b/plugin/buycourses/src/subscription_process.php
new file mode 100644
index 0000000000..4376e57ed0
--- /dev/null
+++ b/plugin/buycourses/src/subscription_process.php
@@ -0,0 +1,305 @@
+';
+$plugin = BuyCoursesPlugin::create();
+$includeSession = $plugin->get('include_sessions') === 'true';
+$paypalEnabled = $plugin->get('paypal_enable') === 'true';
+$transferEnabled = $plugin->get('transfer_enable') === 'true';
+$culqiEnabled = $plugin->get('culqi_enable') === 'true';
+$tpvRedsysEnable = $plugin->get('tpv_redsys_enable') === 'true';
+
+if (!$paypalEnabled && !$transferEnabled && !$culqiEnabled && !$tpvRedsysEnable) {
+ api_not_allowed(true);
+}
+
+if (!isset($_REQUEST['t'], $_REQUEST['i'])) {
+ api_not_allowed(true);
+}
+
+$buyingCourse = intval($_REQUEST['t']) === BuyCoursesPlugin::PRODUCT_TYPE_COURSE;
+$buyingSession = intval($_REQUEST['t']) === BuyCoursesPlugin::PRODUCT_TYPE_SESSION;
+$queryString = 'i='.intval($_REQUEST['i']).'&t='.intval($_REQUEST['t']);
+
+if (isset($_REQUEST['c'])) {
+ $couponCode = $_REQUEST['c'];
+ if ($buyingCourse) {
+ $coupon = $plugin->getCouponByCode($couponCode, BuyCoursesPlugin::PRODUCT_TYPE_COURSE, $_REQUEST['i']);
+ } else {
+ $coupon = $plugin->getCouponByCode($couponCode, BuyCoursesPlugin::PRODUCT_TYPE_SESSION, $_REQUEST['i']);
+ }
+
+ $queryString .= 'c='.$coupon['code'];
+}
+
+if (isset($_REQUEST['d'])) {
+ $duration = $_REQUEST['d'];
+ if ($buyingCourse) {
+ $subscriptionItem = $plugin->getSubscription(BuyCoursesPlugin::PRODUCT_TYPE_COURSE, $_REQUEST['i'], $duration, $coupon);
+ } else {
+ $subscriptionItem = $plugin->getSubscription(BuyCoursesPlugin::PRODUCT_TYPE_SESSION, $_REQUEST['i'], $duration, $coupon);
+ }
+}
+
+if (empty($currentUserId)) {
+ Session::write('buy_course_redirect', api_get_self().'?'.$queryString);
+ header('Location: '.api_get_path(WEB_CODE_PATH).'auth/inscription.php');
+ exit;
+}
+
+$subscriptionItems = $plugin->getSubscriptionsItemsByProduct($_REQUEST['i'], $_REQUEST['t']);
+
+if (!isset($subscriptionItems) || empty($subscriptionItems)) {
+ api_not_allowed(true);
+}
+
+if (!isset($subscriptionItem) || empty($subscriptionItem)) {
+ $subscriptionItem = $plugin->getSubscription($subscriptionItems[0]['product_type'], $subscriptionItems[0]['product_id'], $subscriptionItems[0]['duration'], $coupon);
+}
+
+$queryString .= 'd='.intval($subscriptionItem['duration']);
+
+if ($buyingCourse) {
+ $courseInfo = $plugin->getSubscriptionCourseInfo($_REQUEST['i'], $coupon);
+ $item = $plugin->getSubscriptionItemByProduct($_REQUEST['i'], BuyCoursesPlugin::PRODUCT_TYPE_COURSE);
+} elseif ($buyingSession) {
+ $sessionInfo = $plugin->getSubscriptionSessionInfo($_REQUEST['i'], $coupon);
+ $item = $plugin->getSubscriptionItemByProduct($_REQUEST['i'], BuyCoursesPlugin::PRODUCT_TYPE_SESSION);
+}
+
+$form = new FormValidator('confirm_sale');
+if ($form->validate()) {
+ $formValues = $form->getSubmitValues();
+
+ if (!$formValues['payment_type']) {
+ Display::addFlash(
+ Display::return_message($plugin->get_lang('NeedToSelectPaymentType'), 'error', false)
+ );
+ header('Location:'.api_get_self().'?'.$queryString);
+ exit;
+ }
+
+ $saleId = $plugin->registerSubscriptionSale($item['product_id'], $item['product_type'], $formValues['payment_type'], $formValues['d'], $formValues['c']);
+
+ if ($saleId !== false) {
+ $_SESSION['bc_sale_id'] = $saleId;
+
+ if (isset($formValues['c'])) {
+ $couponSaleId = $plugin->registerCouponSubscriptionSale($saleId, $formValues['c']);
+ if ($couponSaleId !== false) {
+ $plugin->updateCouponDelivered($formValues['c']);
+ $_SESSION['bc_coupon_id'] = $formValues['c'];
+ }
+ }
+
+ header('Location: '.api_get_path(WEB_PLUGIN_PATH).'buycourses/src/process_subscription_confirm.php');
+ }
+
+ exit;
+}
+
+$paymentTypesOptions = $plugin->getPaymentTypes();
+
+if (!$paypalEnabled) {
+ unset($paymentTypesOptions[BuyCoursesPlugin::PAYMENT_TYPE_PAYPAL]);
+}
+
+if (!$transferEnabled) {
+ unset($paymentTypesOptions[BuyCoursesPlugin::PAYMENT_TYPE_TRANSFER]);
+}
+
+if (!$culqiEnabled) {
+ unset($paymentTypesOptions[BuyCoursesPlugin::PAYMENT_TYPE_CULQI]);
+}
+
+if (!$tpvRedsysEnable || !file_exists(api_get_path(SYS_PLUGIN_PATH).'buycourses/resources/apiRedsys.php')) {
+ unset($paymentTypesOptions[BuyCoursesPlugin::PAYMENT_TYPE_TPV_REDSYS]);
+}
+
+$messagePayment = '';
+$extraField = new ExtraField('user');
+$extraData = $extraField->get_handler_extra_data(api_get_user_id());
+if (empty($extraData['extra_country'])) {
+ $messagePayment = Display::return_message(
+ $plugin->get_lang('CountryEmpty'),
+ 'warning'
+ );
+} else {
+ $listCountryPayment = $plugin->getPaymentsByCountry($extraData['extra_country']);
+
+ $paymentTypesRelCountries = [];
+ foreach ($listCountryPayment as $itemCountryPayment) {
+ $paymentTypesRelCountries[] = $itemCountryPayment['payment_type'];
+ }
+
+ foreach ($paymentTypesOptions as $key => $itemPayment) {
+ if (in_array($key, $paymentTypesRelCountries) === false) {
+ unset($paymentTypesOptions[$key]);
+ }
+ }
+}
+
+$count = count($paymentTypesOptions);
+if ($count === 0) {
+ $form->addHtml($plugin->get_lang('NoPaymentOptionAvailable'));
+ $form->addHtml('
');
+ $form->addHtml('
');
+} elseif ($count === 1) {
+ // get the only array item
+ foreach ($paymentTypesOptions as $type => $value) {
+ $form->addHtml(sprintf($plugin->get_lang('XIsOnlyPaymentMethodAvailable'), $value));
+ $form->addHtml('
');
+ $form->addHtml('
');
+ $form->addHidden('payment_type', $type);
+ }
+} else {
+ $form->addHtml(
+ Display::return_message(
+ $plugin->get_lang('PleaseSelectThePaymentMethodBeforeConfirmYourOrder'),
+ 'info'
+ )
+ );
+ $form->addRadio('payment_type', null, $paymentTypesOptions);
+}
+
+$form->addHidden('t', intval($_GET['t']));
+$form->addHidden('i', intval($_GET['i']));
+if ($coupon != null) {
+ $form->addHidden('c', intval($coupon['id']));
+}
+$form->addButton('submit', $plugin->get_lang('ConfirmOrder'), 'check', 'success', 'btn-lg pull-right');
+
+$formSubscription = new FormValidator('confirm_subscription');
+if ($formSubscription->validate()) {
+ $formSubscriptionValues = $formSubscription->getSubmitValues();
+
+ if (!$formSubscriptionValues['duration']) {
+ Display::addFlash(
+ Display::return_message($plugin->get_lang('NeedToAddDuration'), 'error', false)
+ );
+ header('Location:'.api_get_self().'?'.$queryString);
+ exit;
+ }
+
+ if ($buyingCourse) {
+ $subscription = $plugin->getSubscription(BuyCoursesPlugin::PRODUCT_TYPE_COURSE, $_REQUEST['i'], $formSubscriptionValues['duration']);
+ } else {
+ $subscription = $plugin->getSubscription(BuyCoursesPlugin::PRODUCT_TYPE_SESSION, $_REQUEST['i'], $formSubscriptionValues['duration']);
+ }
+
+ if ($subscription == null) {
+ Display::addFlash(
+ Display::return_message($plugin->get_lang('SubscriptionNotValid'), 'error', false)
+ );
+ header('Location:'.api_get_self().'?'.$queryString);
+ exit;
+ }
+
+ header('Location: '.api_get_path(WEB_PLUGIN_PATH).'buycourses/src/subscription_process.php?i='.$_REQUEST['i'].'&t='.$_REQUEST['t'].'&d='.$formSubscriptionValues['duration']);
+
+ exit;
+}
+
+$frequencies = $plugin->getFrequencies();
+$selectedFrequencies = [];
+
+foreach($subscriptionItems as $si) {
+ if (isset($frequencies[$si['duration']])) {
+ $selectedFrequencies[$si['duration']] = $frequencies[$si['duration']].' - '.$si['price_formatted'] . ' ' . $si['iso_code'];
+ }
+}
+
+$formSubscription->addRadio('duration', null, $selectedFrequencies);
+
+if (!empty($selectedFrequencies)) {
+ $formSubscriptionDefaults['duration'] = $subscriptionItem['duration'];
+ $formSubscription->setDefaults($formSubscriptionDefaults);
+}
+
+$selectedDurationName = $frequencies[$subscriptionItem['duration']];
+
+$formSubscription->addHidden('t', intval($_GET['t']));
+$formSubscription->addHidden('i', intval($_GET['i']));
+
+$form->addHidden('d', $subscriptionItem['duration']);
+
+$formCoupon = new FormValidator('confirm_coupon');
+if ($formCoupon->validate()) {
+ $formCouponValues = $formCoupon->getSubmitValues();
+
+ if (!$formCouponValues['coupon_code']) {
+ Display::addFlash(
+ Display::return_message($plugin->get_lang('NeedToAddCouponCode'), 'error', false)
+ );
+ header('Location:'.api_get_self().'?'.$queryString);
+ exit;
+ }
+
+ if ($buyingCourse) {
+ $coupon = $plugin->getCouponByCode($formCouponValues['coupon_code'], BuyCoursesPlugin::PRODUCT_TYPE_COURSE, $_REQUEST['i']);
+ } else {
+ $coupon = $plugin->getCouponByCode($formCouponValues['coupon_code'], BuyCoursesPlugin::PRODUCT_TYPE_SESSION, $_REQUEST['i']);
+ }
+
+ if ($coupon == null) {
+ Display::addFlash(
+ Display::return_message($plugin->get_lang('CouponNotValid'), 'error', false)
+ );
+ header('Location:'.api_get_self().'?'.$queryString);
+ exit;
+ }
+
+ Display::addFlash(
+ Display::return_message($plugin->get_lang('CouponRedeemed'), 'success', false)
+ );
+
+ header('Location: '.api_get_path(WEB_PLUGIN_PATH).'buycourses/src/subscription_process.php?i='.$_REQUEST['i'].'&t='.$_REQUEST['t'].'&d='.$_REQUEST['d'].'&c='.$formCouponValues['coupon_code']);
+
+ exit;
+}
+$formCoupon->addText('coupon_code', $plugin->get_lang('CouponsCode'), true);
+$formCoupon->addHidden('t', intval($_GET['t']));
+$formCoupon->addHidden('i', intval($_GET['i']));
+$formCoupon->addHidden('d', $subscriptionItem['duration']);
+$formCoupon->addButton('submit', $plugin->get_lang('RedeemCoupon'), 'check', 'success', 'btn-lg pull-right');
+
+// View
+$templateName = $plugin->get_lang('PaymentMethods');
+$interbreadcrumb[] = ['url' => 'subscription_course_catalog.php', 'name' => $plugin->get_lang('CourseListOnSale')];
+
+$tpl = new Template($templateName);
+$tpl->assign('item_type', (int) $_GET['t']);
+$tpl->assign('buying_course', $buyingCourse);
+$tpl->assign('buying_session', $buyingSession);
+$tpl->assign('user', api_get_user_info());
+$tpl->assign('form_coupon', $formCoupon->returnForm());
+$tpl->assign('message_payment', $messagePayment);
+$tpl->assign('selected_duration_name', $selectedDurationName);
+$tpl->assign('form', $form->returnForm());
+$tpl->assign('form_subscription', $formSubscription->returnForm());
+
+if ($buyingCourse) {
+ $tpl->assign('course', $courseInfo);
+} elseif ($buyingSession) {
+ $tpl->assign('session', $sessionInfo);
+}
+
+$tpl->assign('subscription', $subscriptionItem);
+
+$content = $tpl->fetch('buycourses/view/subscription_process.tpl');
+
+$tpl->assign('content', $content);
+$tpl->display_one_col_template();
diff --git a/plugin/buycourses/src/subscription_sales_report.php b/plugin/buycourses/src/subscription_sales_report.php
new file mode 100644
index 0000000000..a29c4eded1
--- /dev/null
+++ b/plugin/buycourses/src/subscription_sales_report.php
@@ -0,0 +1,201 @@
+get('paypal_enable');
+$commissionsEnable = $plugin->get('commissions_enable');
+$includeServices = $plugin->get('include_services');
+$invoicingEnable = $plugin->get('invoicing_enable') === 'true';
+
+if (isset($_GET['order'])) {
+ $sale = $plugin->getSubscriptionSale($_GET['order']);
+
+ if (empty($sale)) {
+ api_not_allowed(true);
+ }
+
+ $urlToRedirect = api_get_self().'?';
+
+ switch ($_GET['action']) {
+ case 'confirm':
+ $plugin->completeSubscriptionSale($sale['id']);
+ $plugin->storeSubscriptionPayouts($sale['id']);
+ Display::addFlash(
+ $plugin->getSubscriptionSuccessMessage($sale)
+ );
+
+ $urlToRedirect .= http_build_query([
+ 'status' => BuyCoursesPlugin::SALE_STATUS_COMPLETED,
+ 'sale' => $sale['id'],
+ ]);
+ break;
+ case 'cancel':
+ $plugin->cancelSubscriptionSale($sale['id']);
+
+ Display::addFlash(
+ Display::return_message(
+ $plugin->get_lang('OrderCanceled'),
+ 'warning'
+ )
+ );
+
+ $urlToRedirect .= http_build_query([
+ 'status' => BuyCoursesPlugin::SALE_STATUS_CANCELED,
+ 'sale' => $sale['id'],
+ ]);
+ break;
+ }
+
+ header("Location: $urlToRedirect");
+ exit;
+}
+
+$productTypes = $plugin->getProductTypes();
+$saleStatuses = $plugin->getSaleStatuses();
+$paymentTypes = $plugin->getPaymentTypes();
+
+$selectedFilterType = '0';
+$selectedStatus = isset($_GET['status']) ? $_GET['status'] : BuyCoursesPlugin::SALE_STATUS_PENDING;
+$selectedSale = isset($_GET['sale']) ? intval($_GET['sale']) : 0;
+$dateStart = isset($_GET['date_start']) ? $_GET['date_start'] : date('Y-m-d H:i', mktime(0, 0, 0));
+$dateEnd = isset($_GET['date_end']) ? $_GET['date_end'] : date('Y-m-d H:i', mktime(23, 59, 59));
+$searchTerm = '';
+$email = '';
+
+$form = new FormValidator('search', 'get');
+
+if ($form->validate()) {
+ $selectedFilterType = $form->getSubmitValue('filter_type');
+ $selectedStatus = $form->getSubmitValue('status');
+ $searchTerm = $form->getSubmitValue('user');
+ $dateStart = $form->getSubmitValue('date_start');
+ $dateEnd = $form->getSubmitValue('date_end');
+ $email = $form->getSubmitValue('email');
+
+ if ($selectedStatus === false) {
+ $selectedStatus = BuyCoursesPlugin::SALE_STATUS_PENDING;
+ }
+
+ if ($selectedFilterType === false) {
+ $selectedFilterType = '0';
+ }
+}
+
+$form->addRadio(
+ 'filter_type',
+ get_lang('Filter'),
+ [
+ $plugin->get_lang('ByStatus'),
+ $plugin->get_lang('ByUser'),
+ $plugin->get_lang('ByDate'),
+ $plugin->get_lang('ByEmail'),
+ ]
+);
+$form->addHtml('');
+$form->addSelect('status', $plugin->get_lang('OrderStatus'), $saleStatuses);
+$form->addHtml('
');
+$form->addHtml('');
+$form->addText('user', get_lang('UserName'), false);
+$form->addHtml('
');
+$form->addHtml('');
+$form->addDateRangePicker('date', get_lang('Date'), false);
+$form->addHtml('
');
+$form->addHtml('');
+$form->addText('email', get_lang('Email'), false);
+$form->addHtml('
');
+$form->addButtonFilter(get_lang('Search'));
+$form->setDefaults([
+ 'filter_type' => $selectedFilterType,
+ 'status' => $selectedStatus,
+ 'date_start' => $dateStart,
+ 'date_end' => $dateEnd,
+ 'email' => $email,
+]);
+
+switch ($selectedFilterType) {
+ case '0':
+ $sales = $plugin->getSubscriptionSaleListByStatus($selectedStatus);
+ break;
+ case '1':
+ $sales = $plugin->getSubscriptionSaleListByUser($searchTerm);
+ break;
+ case '2':
+ $sales = $plugin->getSubscriptionSaleListByDate($dateStart, $dateEnd);
+ break;
+ case '3':
+ $sales = $plugin->getSubscriptionSaleListByEmail($email);
+ break;
+}
+
+foreach ($sales as &$sale) {
+ $sale['product_type'] = $productTypes[$sale['product_type']];
+ $sale['payment_type'] = $paymentTypes[$sale['payment_type']];
+ $sale['complete_user_name'] = api_get_person_name($sale['firstname'], $sale['lastname']);
+ $sale['num_invoice'] = $plugin->getNumInvoice($sale['id'], 0);
+ $sale['total_price'] = $plugin->getPriceWithCurrencyFromIsoCode($sale['price'], $sale['iso_code']);
+ if (isset($sale['discount_amount']) && $sale['discount_amount'] != 0) {
+ $sale['total_discount'] = $plugin->getPriceWithCurrencyFromIsoCode($sale['discount_amount'], $sale['iso_code']);
+ $sale['coupon_code'] = $plugin->getSaleCouponCode($sale['id']);
+ }
+}
+
+$interbreadcrumb[] = ['url' => '../index.php', 'name' => $plugin->get_lang('plugin_title')];
+
+$htmlHeadXtra[] = api_get_css(api_get_path(WEB_PLUGIN_PATH).'buycourses/resources/css/style.css');
+
+$templateName = $plugin->get_lang('SalesReport');
+$template = new Template($templateName);
+
+$toolbar = Display::url(
+ Display::returnFontAwesomeIcon('file-excel-o').
+ get_lang('GenerateReport'),
+ api_get_path(WEB_PLUGIN_PATH).'buycourses/src/export_subscription_report.php',
+ ['class' => 'btn btn-primary']
+);
+
+if ($paypalEnable === 'true' && $commissionsEnable === 'true') {
+ $toolbar .= Display::toolbarButton(
+ $plugin->get_lang('PaypalPayoutCommissions'),
+ api_get_path(WEB_PLUGIN_PATH).'buycourses/src/paypal_payout.php',
+ 'paypal',
+ 'primary',
+ ['title' => $plugin->get_lang('PaypalPayoutCommissions')]
+ );
+
+ $template->assign(
+ 'actions',
+ Display::toolbarAction('toolbar', [$toolbar])
+ );
+}
+
+$template->assign(
+ 'actions',
+ Display::toolbarAction('toolbar', [$toolbar])
+);
+$template->assign('form', $form->returnForm());
+$template->assign('selected_sale', $selectedSale);
+$template->assign('selected_status', $selectedStatus);
+$template->assign('services_are_included', $includeServices);
+$template->assign('sale_list', $sales);
+$template->assign('sale_status_canceled', BuyCoursesPlugin::SALE_STATUS_CANCELED);
+$template->assign('sale_status_pending', BuyCoursesPlugin::SALE_STATUS_PENDING);
+$template->assign('sale_status_completed', BuyCoursesPlugin::SALE_STATUS_COMPLETED);
+$template->assign('invoicing_enable', $invoicingEnable);
+
+$content = $template->fetch('buycourses/view/subscription_sales_report.tpl');
+
+$template->assign('header', $templateName);
+$template->assign('content', $content);
+$template->display_one_col_template();
diff --git a/plugin/buycourses/src/subscription_session_catalog.php b/plugin/buycourses/src/subscription_session_catalog.php
new file mode 100644
index 0000000000..a52309899b
--- /dev/null
+++ b/plugin/buycourses/src/subscription_session_catalog.php
@@ -0,0 +1,114 @@
+get('include_sessions') === 'true';
+$includeServices = $plugin->get('include_services') === 'true';
+
+if (!$includeSessions) {
+ api_not_allowed(true);
+}
+
+$nameFilter = null;
+$sessionCategory = isset($_GET['session_category']) ? (int) $_GET['session_category'] : 0;
+$form = new FormValidator(
+ 'search_filter_form',
+ 'get',
+ null,
+ null,
+ [],
+ FormValidator::LAYOUT_INLINE
+);
+
+$form->removeAttribute('class');
+
+if ($form->validate()) {
+ $formValues = $form->getSubmitValues();
+ $nameFilter = isset($formValues['name']) ? $formValues['name'] : null;
+ $sessionCategory = isset($formValues['session_category']) ? $formValues['session_category'] : $sessionCategory;
+}
+
+$form->addHeader($plugin->get_lang('SearchFilter'));
+
+$categoriesOptions = [
+ '0' => get_lang('AllCategories'),
+];
+$categoriesList = SessionManager::get_all_session_category();
+if ($categoriesList != false) {
+ foreach ($categoriesList as $categoryItem) {
+ $categoriesOptions[$categoryItem['id']] = $categoryItem['name'];
+ }
+}
+$form->addSelect(
+ 'session_category',
+ get_lang('SessionCategory'),
+ $categoriesOptions,
+ [
+ 'id' => 'session_category',
+ ]
+);
+
+$form->addText('name', get_lang('SessionName'), false);
+
+$form->addHtml('
');
+$form->addButtonFilter(get_lang('Search'));
+
+$form->setDefaults(
+ [
+ 'session_category' => $sessionCategory,
+ ]
+);
+$pageSize = BuyCoursesPlugin::PAGINATION_PAGE_SIZE;
+$currentPage = isset($_GET['page']) ? (int) $_GET['page'] : 1;
+$first = $pageSize * ($currentPage - 1);
+$sessionList = $plugin->getCatalogSubscriptionSessionList($first, $pageSize, $nameFilter, 'all', $sessionCategory);
+$totalItems = $plugin->getCatalogSubscriptionSessionList($first, $pageSize, $nameFilter, 'count', $sessionCategory);
+$pagesCount = ceil($totalItems / $pageSize);
+$pagination = BuyCoursesPlugin::returnPagination(api_get_self(), $currentPage, $pagesCount, $totalItems);
+
+// View
+if (api_is_platform_admin()) {
+ $interbreadcrumb[] = [
+ 'url' => 'subscriptions_sessions.php',
+ 'name' => $plugin->get_lang('AvailableCoursesConfiguration'),
+ ];
+ $interbreadcrumb[] = [
+ 'url' => 'paymentsetup.php',
+ 'name' => $plugin->get_lang('PaymentsConfiguration'),
+ ];
+}
+
+$templateName = $plugin->get_lang('CourseListOnSale');
+
+$htmlHeadXtra[] = api_get_css(api_get_path(WEB_PLUGIN_PATH).'buycourses/resources/css/style.css');
+
+$template = new Template($templateName);
+$template->assign('search_filter_form', $form->returnForm());
+$template->assign('sessions_are_included', $includeSessions);
+$template->assign('showing_sessions', true);
+$template->assign('sessions', $sessionList);
+$template->assign('pagination', $pagination);
+
+$courseList = $plugin->getCatalogSubscriptionCourseList($first, $pageSize, $nameFilter);
+$coursesExist = true;
+$sessionExist = true;
+if (count($courseList) <= 0) {
+ $coursesExist = false;
+}
+$template->assign('coursesExist', $coursesExist);
+$template->assign('sessionExist', $sessionExist);
+
+$content = $template->fetch('buycourses/view/subscription_catalog.tpl');
+
+$template->assign('header', $templateName);
+$template->assign('content', $content);
+$template->display_one_col_template();
diff --git a/plugin/buycourses/src/subscriptions_courses.php b/plugin/buycourses/src/subscriptions_courses.php
new file mode 100644
index 0000000000..1347e233e3
--- /dev/null
+++ b/plugin/buycourses/src/subscriptions_courses.php
@@ -0,0 +1,97 @@
+get('include_sessions') === 'true';
+$taxEnable = $plugin->get('tax_enable') === 'true';
+
+api_protect_admin_script(true);
+
+Display::addFlash(
+ Display::return_message(
+ get_lang('Info').' - '.$plugin->get_lang('CoursesInSessionsDoesntDisplayHere'),
+ 'info'
+ )
+);
+
+$pageSize = BuyCoursesPlugin::PAGINATION_PAGE_SIZE;
+$type = isset($_GET['type']) ? (int) $_GET['type'] : BuyCoursesPlugin::PRODUCT_TYPE_COURSE;
+$currentPage = isset($_GET['page']) ? (int) $_GET['page'] : 1;
+$first = $pageSize * ($currentPage - 1);
+
+$qb = $plugin->getCourseList($first, $pageSize);
+$query = $qb->getQuery();
+$courses = new Paginator($query, $fetchJoinCollection = true);
+foreach ($courses as $course) {
+ $item = $plugin->getSubscriptionItemByProduct($course->getId(), BuyCoursesPlugin::PRODUCT_TYPE_COURSE);
+ $course->buyCourseData = [];
+ if ($item !== false) {
+ $course->buyCourseData = $item;
+ }
+}
+
+$totalItems = count($courses);
+$pagesCount = ceil($totalItems / $pageSize);
+
+$pagination = BuyCoursesPlugin::returnPagination(
+ api_get_self(),
+ $currentPage,
+ $pagesCount,
+ $totalItems,
+ ['type' => $type]
+);
+
+// breadcrumbs
+$interbreadcrumb[] = [
+ 'url' => api_get_path(WEB_PLUGIN_PATH).'buycourses/index.php',
+ 'name' => $plugin->get_lang('plugin_title'),
+];
+
+$templateName = $plugin->get_lang('AvailableCourses');
+
+$htmlHeadXtra[] = api_get_css(api_get_path(WEB_PLUGIN_PATH).'buycourses/resources/css/style.css');
+
+$tpl = new Template($templateName);
+
+$toolbar = Display::url(
+ Display::returnFontAwesomeIcon('fa-calendar-alt').
+ $plugin->get_lang('ConfigureSubscriptionsFrequencies'),
+ api_get_path(WEB_PLUGIN_PATH).'buycourses/src/configure_frequency.php',
+ ['class' => 'btn btn-primary']
+);
+
+$tpl->assign(
+ 'actions',
+ Display::toolbarAction('toolbar', [$toolbar])
+);
+
+$tpl->assign('product_type_course', BuyCoursesPlugin::PRODUCT_TYPE_COURSE);
+$tpl->assign('product_type_session', BuyCoursesPlugin::PRODUCT_TYPE_SESSION);
+$tpl->assign('courses', $courses);
+$tpl->assign('course_pagination', $pagination);
+$tpl->assign('sessions_are_included', $includeSession);
+$tpl->assign('tax_enable', $taxEnable);
+
+if ($taxEnable) {
+ $globalParameters = $plugin->getGlobalParameters();
+ $tpl->assign('global_tax_perc', $globalParameters['global_tax_perc']);
+ $tpl->assign('tax_applies_to', $globalParameters['tax_applies_to']);
+ $tpl->assign('tax_name', $globalParameters['tax_name']);
+}
+
+$content = $tpl->fetch('buycourses/view/subscriptions.tpl');
+
+$tpl->assign('header', $templateName);
+$tpl->assign('content', $content);
+$tpl->display_one_col_template();
diff --git a/plugin/buycourses/src/subscriptions_sessions.php b/plugin/buycourses/src/subscriptions_sessions.php
new file mode 100644
index 0000000000..a892d79e9f
--- /dev/null
+++ b/plugin/buycourses/src/subscriptions_sessions.php
@@ -0,0 +1,101 @@
+get('include_sessions') === 'true';
+
+if (!$includeSession) {
+ api_not_allowed(true);
+}
+$includeServices = $plugin->get('include_services') === 'true';
+$taxEnable = $plugin->get('tax_enable') === 'true';
+
+api_protect_admin_script(true);
+
+Display::addFlash(
+ Display::return_message(
+ get_lang('Info').' - '.$plugin->get_lang('CoursesInSessionsDoesntDisplayHere'),
+ 'info'
+ )
+);
+
+$pageSize = BuyCoursesPlugin::PAGINATION_PAGE_SIZE;
+$currentPage = isset($_GET['page']) ? (int) $_GET['page'] : 1;
+$first = $pageSize * ($currentPage - 1);
+
+// breadcrumbs
+$interbreadcrumb[] = [
+ 'url' => api_get_path(WEB_PLUGIN_PATH).'buycourses/index.php',
+ 'name' => $plugin->get_lang('plugin_title'),
+];
+
+$htmlHeadXtra[] = api_get_css(api_get_path(WEB_PLUGIN_PATH).'buycourses/resources/css/style.css');
+
+$templateName = $plugin->get_lang('AvailableCourses');
+
+$tpl = new Template($templateName);
+
+$toolbar = Display::url(
+ Display::returnFontAwesomeIcon('fa-calendar-alt').
+ $plugin->get_lang('ConfigureSubscriptionsFrequencies'),
+ api_get_path(WEB_PLUGIN_PATH).'buycourses/src/configure_frequency.php',
+ ['class' => 'btn btn-primary']
+);
+
+$tpl->assign(
+ 'actions',
+ Display::toolbarAction('toolbar', [$toolbar])
+);
+
+$tpl->assign('product_type_course', BuyCoursesPlugin::PRODUCT_TYPE_COURSE);
+$tpl->assign('product_type_session', BuyCoursesPlugin::PRODUCT_TYPE_SESSION);
+$tpl->assign('sessions_are_included', $includeSession);
+$tpl->assign('services_are_included', $includeServices);
+$tpl->assign('tax_enable', $taxEnable);
+
+$query = CoursesAndSessionsCatalog::browseSessions(null, ['start' => $first, 'length' => $pageSize], true);
+$sessions = new Paginator($query, $fetchJoinCollection = true);
+foreach ($sessions as $session) {
+ $item = $plugin->getSubscriptionItemByProduct($session->getId(), BuyCoursesPlugin::PRODUCT_TYPE_SESSION);
+ $session->buyCourseData = [];
+ if ($item !== false) {
+ $session->buyCourseData = $item;
+ }
+}
+
+$totalItems = count($sessions);
+$pagesCount = ceil($totalItems / $pageSize);
+
+$pagination = BuyCoursesPlugin::returnPagination(
+ api_get_self(),
+ $currentPage,
+ $pagesCount,
+ $totalItems,
+ ['type' => BuyCoursesPlugin::PRODUCT_TYPE_SESSION]
+);
+
+$tpl->assign('sessions', $sessions);
+$tpl->assign('session_pagination', $pagination);
+
+if ($taxEnable) {
+ $globalParameters = $plugin->getGlobalParameters();
+ $tpl->assign('global_tax_perc', $globalParameters['global_tax_perc']);
+ $tpl->assign('tax_applies_to', $globalParameters['tax_applies_to']);
+ $tpl->assign('tax_name', $globalParameters['tax_name']);
+}
+
+$content = $tpl->fetch('buycourses/view/subscriptions.tpl');
+
+$tpl->assign('header', $templateName);
+$tpl->assign('content', $content);
+$tpl->display_one_col_template();