From 8f67cf686f428278470e131fcd05df1257c4cbfd Mon Sep 17 00:00:00 2001 From: Angel Fernando Quiroz Campos Date: Thu, 24 Sep 2015 14:42:40 -0500 Subject: [PATCH] Allow register beneficiaries with the sales of items - refs #7768 --- plugin/buycourses/database.php | 24 ++ .../src/buy_course_plugin.class.php | 299 +++++++++++++----- plugin/buycourses/src/configuration.php | 2 + plugin/buycourses/src/configure_course.php | 198 ++++++++++++ plugin/buycourses/src/function.php | 47 +-- plugin/buycourses/view/configuration.tpl | 8 +- 6 files changed, 470 insertions(+), 108 deletions(-) create mode 100644 plugin/buycourses/src/configure_course.php diff --git a/plugin/buycourses/database.php b/plugin/buycourses/database.php index 5b4ffb9aba..e3dddb98c9 100644 --- a/plugin/buycourses/database.php +++ b/plugin/buycourses/database.php @@ -97,6 +97,30 @@ $itemTable->addForeignKeyConstraint( ['onDelete' => 'CASCADE'] ); +$itemBeneficiary = $pluginSchema->createTable(BuyCoursesPlugin::TABLE_ITEM_BENEFICIARY); +$itemBeneficiary->addColumn( + 'id', + \Doctrine\DBAL\Types\Type::INTEGER, + ['autoincrement' => true, 'unsigned' => true] +); +$itemBeneficiary->addColumn( + 'item_id', + \Doctrine\DBAL\Types\Type::INTEGER, + ['unsigned' => true] +); +$itemBeneficiary->addColumn( + 'user_id', + \Doctrine\DBAL\Types\Type::INTEGER, + ['unsigned' => true] +); +$itemBeneficiary->setPrimaryKey(['id']); +$itemBeneficiary->addForeignKeyConstraint( + $itemTable, + ['item_id'], + ['id'], + ['onDelete' => 'CASCADE'] +); + $saleTable = $pluginSchema->createTable(BuyCoursesPlugin::TABLE_SALE); $saleTable->addColumn( 'id', diff --git a/plugin/buycourses/src/buy_course_plugin.class.php b/plugin/buycourses/src/buy_course_plugin.class.php index ed55c6afa8..954ae85b0e 100644 --- a/plugin/buycourses/src/buy_course_plugin.class.php +++ b/plugin/buycourses/src/buy_course_plugin.class.php @@ -16,6 +16,7 @@ class BuyCoursesPlugin extends Plugin const TABLE_PAYPAL = 'plugin_buycourses_paypal_account'; const TABLE_CURRENCY = 'plugin_buycourses_currency'; const TABLE_ITEM = 'plugin_buycourses_item'; + const TABLE_ITEM_BENEFICIARY = 'plugin_buycourses_item_rel_beneficiary'; const TABLE_SALE = 'plugin_buycourses_sale'; const TABLE_TRANSFER = 'plugin_buycourses_transfer'; const PRODUCT_TYPE_COURSE = 1; @@ -75,7 +76,8 @@ class BuyCoursesPlugin extends Plugin self::TABLE_TRANSFER, self::TABLE_ITEM, self::TABLE_SALE, - self::TABLE_CURRENCY + self::TABLE_CURRENCY, + self::TABLE_ITEM_BENEFICIARY ); foreach ($tablesToBeDeleted as $tableToBeDeleted) { @@ -285,26 +287,7 @@ class BuyCoursesPlugin extends Plugin $currency = $this->getSelectedCurrency(); foreach ($courses as $course) { - $courseItem = [ - 'course_id' => $course->getId(), - 'course_visual_code' => $course->getVisualCode(), - 'course_code' => $course->getCode(), - 'course_title' => $course->getTitle(), - 'course_visibility' => $course->getVisibility(), - 'visible' => false, - 'currency' => empty($currency) ? null : $currency['iso_code'], - 'price' => 0.00 - ]; - - $item = $this->getItemByProduct($course->getId(), self::PRODUCT_TYPE_COURSE); - - if ($item !== false) { - $courseItem['visible'] = true; - $courseItem['currency'] = $item['iso_code']; - $courseItem['price'] = $item['price']; - } - - $configurationCourses[] = $courseItem; + $configurationCourses[] = $this->getCourseForConfiguration($course, $currency); } return $configurationCourses; @@ -316,9 +299,6 @@ class BuyCoursesPlugin extends Plugin */ public function getSessionsForConfiguration() { - $buyItemTable = Database::get_main_table(BuyCoursesPlugin::TABLE_ITEM); - $buyCurrencyTable = Database::get_main_table(BuyCoursesPlugin::TABLE_CURRENCY); - $auth = new Auth(); $sessions = $auth->browseSessions(); @@ -326,55 +306,8 @@ class BuyCoursesPlugin extends Plugin $items = []; - $fakeItemFrom = " - $buyItemTable i - INNER JOIN $buyCurrencyTable c - ON i.currency_id = c.id - "; - foreach ($sessions as $session) { - $sessionItem = [ - 'session_id' => $session->getId(), - 'session_name' => $session->getName(), - 'session_visibility' => $session->getVisibility(), - 'session_display_start_date' => null, - 'session_display_end_date' => null, - 'visible' => false, - 'currency' => empty($currency) ? null : $currency['iso_code'], - 'price' => 0.00 - ]; - - if (!empty($session->getDisplayStartDate())) { - $sessionItem['session_display_start_date'] = api_format_date( - $session->getDisplayStartDate()->format('Y-m-d h:i:s') - ); - } - - if (!empty($session->getDisplayEndDate())) { - $sessionItem['session_display_end_date'] = api_format_date( - $session->getDisplayEndDate()->format('Y-m-d h:i:s') - ); - } - - $item = Database::select( - ['i.*', 'c.iso_code'], - $fakeItemFrom, - [ - 'where' => [ - 'i.product_id = ? AND ' => $session->getId(), - 'i.product_type = ?' => self::PRODUCT_TYPE_SESSION - ] - ], - 'first' - ); - - if ($item !== false) { - $sessionItem['visible'] = true; - $sessionItem['currency'] = $item['iso_code']; - $sessionItem['price'] = $item['price']; - } - - $items[] = $sessionItem; + $items[] = $this->getSessionForConfiguration($session, $currency); } return $items; @@ -1157,4 +1090,226 @@ class BuyCoursesPlugin extends Plugin ); } + /** + * Convert the course info to array with necessary course data for save item + * @param \Chamilo\CoreBundle\Entity\Course $course + * @param array $defaultCurrency Optional. Currency data + * @return array + */ + public function getCourseForConfiguration(\Chamilo\CoreBundle\Entity\Course $course, $defaultCurrency = null) + { + $courseItem = [ + 'item_id' => null, + 'course_id' => $course->getId(), + 'course_visual_code' => $course->getVisualCode(), + 'course_code' => $course->getCode(), + 'course_title' => $course->getTitle(), + 'course_visibility' => $course->getVisibility(), + 'visible' => false, + 'currency' => empty($defaultCurrency) ? null : $defaultCurrency['iso_code'], + 'price' => 0.00 + ]; + + $item = $this->getItemByProduct($course->getId(), self::PRODUCT_TYPE_COURSE); + + if ($item !== false) { + $courseItem['item_id'] = $item['id']; + $courseItem['visible'] = true; + $courseItem['currency'] = $item['iso_code']; + $courseItem['price'] = $item['price']; + } + + return $courseItem; + } + + /** + * Convert the session info to array with necessary session data for save item + * @param Chamilo\CoreBundle\Entity\Session $session The session data + * @param array $defaultCurrency Optional. Currency data + * @return array + */ + public function getSessionForConfiguration(Chamilo\CoreBundle\Entity\Session $session, $defaultCurrency = null) + { + $buyItemTable = Database::get_main_table(BuyCoursesPlugin::TABLE_ITEM); + $buyCurrencyTable = Database::get_main_table(BuyCoursesPlugin::TABLE_CURRENCY); + + $fakeItemFrom = " + $buyItemTable i + INNER JOIN $buyCurrencyTable c ON i.currency_id = c.id + "; + + $sessionItem = [ + 'item_id' => null, + 'session_id' => $session->getId(), + 'session_name' => $session->getName(), + 'session_visibility' => $session->getVisibility(), + 'session_display_start_date' => null, + 'session_display_end_date' => null, + 'visible' => false, + 'currency' => empty($defaultCurrency) ? null : $defaultCurrency['iso_code'], + 'price' => 0.00 + ]; + + if (!empty($session->getDisplayStartDate())) { + $sessionItem['session_display_start_date'] = api_format_date( + $session->getDisplayStartDate()->format('Y-m-d h:i:s') + ); + } + + if (!empty($session->getDisplayEndDate())) { + $sessionItem['session_display_end_date'] = api_format_date( + $session->getDisplayEndDate()->format('Y-m-d h:i:s'), + DATE_TIME_FORMAT_LONG_24H + ); + } + + $item = Database::select( + ['i.*', 'c.iso_code'], + $fakeItemFrom, + [ + 'where' => [ + 'i.product_id = ? AND ' => $session->getId(), + 'i.product_type = ?' => self::PRODUCT_TYPE_SESSION + ] + ], + 'first' + ); + + if ($item !== false) { + $sessionItem['item_id'] = $item['id']; + $sessionItem['visible'] = true; + $sessionItem['currency'] = $item['iso_code']; + $sessionItem['price'] = $item['price']; + } + + return $sessionItem; + } + + /** + * Get all beneficiaries for a item + * @param int $itemId The item ID + * @return array The beneficiries. Otherwise return false + */ + public function getItemBeneficiaries($itemId) + { + $beneficiaryTable = Database::get_main_table(self::TABLE_ITEM_BENEFICIARY); + + return Database::select( + '*', + $beneficiaryTable, + ['where' => [ + 'item_id = ?' => intval($itemId) + ]] + ); + } + + /** + * Delete a item with its beneficiaries + * @param int $itemId The item ID + * @return int The number of affected rows. Otherwise return false + */ + public function deleteItem($itemId) + { + $itemTable = Database::get_main_table(BuyCoursesPlugin::TABLE_ITEM); + + $affectedRows = Database::delete( + $itemTable, + ['id = ?' => intval($itemId)] + ); + + if (!$affectedRows) { + return false; + } + + return $this->deleteItemBeneficiaries($itemId); + } + + /** + * Register a item + * @param array $itemData The item data + * @return int The item ID. Otherwise return false + */ + public function registerItem(array $itemData) + { + $itemTable = Database::get_main_table(BuyCoursesPlugin::TABLE_ITEM); + + return Database::insert($itemTable, $itemData); + } + + /** + * Update the item data by product + * @param array $itemData The item data to be updated + * @param int $productId The product ID + * @param int $productType The type of product + * @return int The number of affected rows. Otherwise return false + */ + public function updateItem(array $itemData, $productId, $productType) + { + $itemTable = Database::get_main_table(BuyCoursesPlugin::TABLE_ITEM); + + return Database::update( + $itemTable, + $itemData, + [ + 'product_id = ? AND ' => intval($productId), + 'product_type' => $productType + ] + ); + } + + /** + * Remove all beneficiaries for a item + * @param int $itemId The user ID + * @return int The number of affected rows. Otherwise return false + */ + public function deleteItemBeneficiaries($itemId) + { + $beneficiaryTable = Database::get_main_table(BuyCoursesPlugin::TABLE_ITEM_BENEFICIARY); + + return Database::delete( + $beneficiaryTable, + ['item_id = ?' => intval($itemId)] + ); + } + + /** + * Register the beneficiaries users with the sale of item + * @param int $itemId The item ID + * @param array $userIds The beneficiary user ID + */ + public function registerItemBeneficiaries($itemId, array $userIds) + { + $beneficiaryTable = Database::get_main_table(BuyCoursesPlugin::TABLE_ITEM_BENEFICIARY); + + $this->deleteItemBeneficiaries($itemId); + + foreach ($userIds as $userId) { + Database::insert( + $beneficiaryTable, + [ + 'item_id' => intval($itemId), + 'user_id' => intval($userId) + ] + ); + } + } + + /** + * Check if a course is valid for sale + * @param Chamilo\CoreBundle\Entity\Course $course The course + * @return boolean + */ + public function isValidCourse(Chamilo\CoreBundle\Entity\Course $course) + { + $courses = $this->getCourses(); + + foreach ($courses as $_c) { + if ($_c->getCode() === $course->getCode()) { + return true; + } + } + + return false; + } + } diff --git a/plugin/buycourses/src/configuration.php b/plugin/buycourses/src/configuration.php index ceb4106250..7a49bee247 100644 --- a/plugin/buycourses/src/configuration.php +++ b/plugin/buycourses/src/configuration.php @@ -30,6 +30,8 @@ $interbreadcrumb[] = [ $templateName = $plugin->get_lang('AvailableCourses'); $tpl = new Template($templateName); +$tpl->assign('product_type_course', BuyCoursesPlugin::PRODUCT_TYPE_COURSE); +$tpl->assign('product_type_session', BuyCoursesPlugin::PRODUCT_TYPE_SESSION); $tpl->assign('courses', $courses); $tpl->assign('sessions_are_included', $includeSession); diff --git a/plugin/buycourses/src/configure_course.php b/plugin/buycourses/src/configure_course.php new file mode 100644 index 0000000000..73c7ef5ee0 --- /dev/null +++ b/plugin/buycourses/src/configure_course.php @@ -0,0 +1,198 @@ +get('include_sessions') === 'true'; + +$editingCourse = intval($_REQUEST['t']) === BuyCoursesPlugin::PRODUCT_TYPE_COURSE; +$editingSession = intval($_REQUEST['t']) === BuyCoursesPlugin::PRODUCT_TYPE_SESSION; + +$entityManager = Database::getManager(); +$userRepo = $entityManager->getRepository('ChamiloUserBundle:User'); + +$currency = $plugin->getSelectedCurrency(); +$currencyIso = null; + +if ($editingCourse) { + $course = $entityManager->find('ChamiloCoreBundle:Course', $_REQUEST['i']); + + if (!$course) { + api_not_allowed(true); + } + + if (!$plugin->isValidCourse($course)) { + api_not_allowed(true); + } + + $courseItem = $plugin->getCourseForConfiguration($course, $currency); + + $teachers = $course->getTeachers(); + $teachersOptions = []; + + foreach ($teachers as $courseTeacher) { + $teacher = $courseTeacher->getUser(); + + $teachersOptions[] = [ + 'text' => $teacher->getCompleteName(), + 'value' => $teacher->getId() + ]; + } + + $beneficiaries = $plugin->getItemBeneficiaries($courseItem['item_id']); + $currencyIso = $courseItem['currency']; + $formDefaults = [ + 'i' => $courseItem['course_id'], + 't' => BuyCoursesPlugin::PRODUCT_TYPE_COURSE, + 'name' => $courseItem['course_title'], + 'visible' => $courseItem['visible'], + 'price' => $courseItem['price'], + 'beneficiaries' => array_column($beneficiaries, 'user_id') + ]; +} elseif ($editingSession) { + if (!$includeSession) { + api_not_allowed(true); + } + + $session = $entityManager->find('ChamiloCoreBundle:Session', $_REQUEST['i']); + + if (!$session) { + api_not_allowed(true); + } + + $sessionItem = $plugin->getSessionForConfiguration($session, $currency); + $generalCoach = $session->getGeneralCoach(); + $generalCoachOption = [ + 'text' => $generalCoach->getCompleteName(), + 'value' => $generalCoach->getId() + ]; + $courseCoachesOptions = []; + $sessionCourses = $session->getCourses(); + + foreach ($sessionCourses as $sessionCourse) { + $courseCoaches = $userRepo->getCoachesForSessionCourse($session, $sessionCourse->getCourse()); + + foreach ($courseCoaches as $courseCoach) { + if ($generalCoach->getId() === $courseCoach->getId()) { + continue; + } + + $courseCoachesOptions[] = [ + 'text' => $courseCoach->getCompleteName(), + 'value' => $courseCoach->getId() + ]; + } + } + + $beneficiaries = $plugin->getItemBeneficiaries($sessionItem['item_id']); + + $currencyIso = $sessionItem['currency']; + $formDefaults = [ + 'i' => $session->getId(), + 't' => BuyCoursesPlugin::PRODUCT_TYPE_SESSION, + 'name' => $sessionItem['session_name'], + 'visible' => $sessionItem['visible'], + 'price' => $sessionItem['price'], + 'beneficiaries' => array_column($beneficiaries, 'user_id') + ]; +} else { + api_not_allowed(true); +} + +$form = new FormValidator('beneficiaries'); +$form->addText('name', get_lang('Name'), false); +$visibleCheckbox = $form->addCheckBox('visible', get_lang('Visible'), 'Mostrar en el catálogo de cursos'); +$form->addElement( + 'number', + 'price', + [$plugin->get_lang('Price'), null, $currencyIso], + ['step' => 0.01] +); +$beneficiariesSelect = $form->addSelect( + 'beneficiaries', + get_lang('Beneficiaries'), + null, + ['multiple' => 'multiple'] +); + +if ($editingCourse) { + $beneficiariesSelect->addOptGroup($teachersOptions, get_lang('Teachers')); +} elseif ($editingSession) { + $beneficiariesSelect->addOptGroup([$generalCoachOption], get_lang('SessionGeneralCoach')); + $beneficiariesSelect->addOptGroup($courseCoachesOptions, get_lang('SessionCourseCoach')); +} + +$form->addHidden('t', null); +$form->addHidden('i', null); +$form->addButtonSave(get_lang('Save')); +$form->freeze(['name']); + +if ($form->validate()) { + $formValues = $form->exportValues(); + $productItem = $plugin->getItemByProduct($formValues['i'], $formValues['t']); + + if (isset($formValues['visible'])) { + if (!empty($productItem)) { + $plugin->updateItem( + ['price' => floatval($formValues['price'])], + $formValues['i'], + $formValues['t'] + ); + } else { + $itemId = $plugin->registerItem([ + 'currency_id' => $currency['id'], + 'product_type' => $formValues['t'], + 'product_id' => intval($formValues['i']), + 'price' => floatval($_POST['price']) + ]); + $productItem['id'] = $itemId; + } + + $plugin->deleteItemBeneficiaries($productItem['id']); + + if (isset($formValues['beneficiaries'])) { + $plugin->registerItemBeneficiaries($productItem['id'], $formValues['beneficiaries']); + } + } else { + $plugin->deleteItem($productItem['id']); + } + + header('Location: ' . api_get_path(WEB_PLUGIN_PATH) . 'buycourses/src/configuration.php'); + exit; +} + +$form->setDefaults($formDefaults); + +//View +$templateName = $plugin->get_lang('AvailableCourse'); + +$interbreadcrumb[] = [ + 'url' => 'paymentsetup.php', + 'name' => get_lang('Configuration') +]; +$interbreadcrumb[] = [ + 'url' => 'configuration.php', + 'name' => $plugin->get_lang('AvailableCourses') +]; + +$template = new Template($templateName); +$template->assign('header', $templateName); +$template->assign('content', $form->returnForm()); +$template->display_one_col_template(); diff --git a/plugin/buycourses/src/function.php b/plugin/buycourses/src/function.php index 5dca375fef..79a4a5b336 100644 --- a/plugin/buycourses/src/function.php +++ b/plugin/buycourses/src/function.php @@ -24,48 +24,25 @@ if ($_REQUEST['tab'] == 'save_mod') { } $affectedRows = false; + $item = $plugin->getItemByProduct($productId, $productType); if ($_POST['visible'] == 1) { - $item = Database::select( - 'COUNT(1) AS qty', - $itemTable, - [ - 'where' => [ - 'product_id = ? AND ' => intval($productId), - 'product_type = ?' => $productType - ] - ], - 'first' - ); - - if ($item['qty'] > 0) { - $affectedRows = Database::update( - $itemTable, + if (!empty($item)) { + $affectedRows = $plugin->updateItem( ['price' => floatval($_POST['price'])], - [ - 'product_id = ? AND ' => intval($productId), - 'product_type' => $productType - ] + $productId, + $productType ); } else { - $affectedRows = Database::insert( - $itemTable, - [ - 'currency_id' => $currency['id'], - 'product_type' => $productType, - 'product_id' => intval($productId), - 'price' => floatval($_POST['price']) - ] - ); + $affectedRows = $plugin->registerItem([ + 'currency_id' => $currency['id'], + 'product_type' => $productType, + 'product_id' => intval($productId), + 'price' => floatval($_POST['price']) + ]); } } else { - $affectedRows = Database::delete( - $itemTable, - [ - 'product_id = ? AND ' => intval($productId), - 'product_type = ?' => $productType - ] - ); + $affectedRows = $plugin->deleteItem($item['id']); } if ($affectedRows > 0) { diff --git a/plugin/buycourses/view/configuration.tpl b/plugin/buycourses/view/configuration.tpl index 9609b62b1c..24bbb84302 100644 --- a/plugin/buycourses/view/configuration.tpl +++ b/plugin/buycourses/view/configuration.tpl @@ -67,6 +67,9 @@ {% endif %} + + {{ 'Configure'|get_lang }} + @@ -133,7 +136,10 @@ {% endif %} - + + + {{ 'Configure'|get_lang }} +