diff --git a/public/plugin/BuyCourses/CHANGELOG.md b/public/plugin/BuyCourses/CHANGELOG.md
index ed1ef9f9f75..1938e12eace 100644
--- a/public/plugin/BuyCourses/CHANGELOG.md
+++ b/public/plugin/BuyCourses/CHANGELOG.md
@@ -1,3 +1,45 @@
+v7.4 - 2022-04-28
+====
+Add subscriptions support.
+
+If the plugin has already been installed, the update.php script must be executed (load plugin/BuyCourses/update.php in your browser) to update the database structure by adding the plugin_buycourses_subscription, plugin_buycourses_subscription_rel_sale, plugin_buycourses_subscription_period and plugin_buycourses_coupon_rel_subscription_sale.
+
+v7.3 - 2022-04-28
+====
+Add Cecabank payments support.
+
+If the plugin has already been installed, the update.php script must be executed (load plugin/BuyCourses/update.php in your browser) to update the structure of the tables in the database.
+
+v7.2 - 2021-11-22
+====
+Add Stripe payments support.
+
+If the plugin has already been installed, the update.php script must be executed (load plugin/BuyCourses/update.php in your browser) to update the structure of the tables in the database.
+
+v7.1 - 2021-10-26
+====
+Fix install issue with DB field type.
+
+v7.0 - 2021-08-12
+====
+Added support for discount coupons.
+Added a better table view for the sales report.
+Multiple fixes to navigation-related issues.
+
+WARNING: Updating this plugin (or Chamilo) without going through the specific update procedure for this plugin will break your sales pages.
+
+The file [your-host]/plugin/BuyCourses/update.php *MUST* be executed to update the structure of the tables
+in the database.
+
+v6.0 - 2020-11-29
+====
+Added support for purchase instructions e-mail customization (although this
+does not support multiple languages at the moment).
+This requires changes to the DB tables:
+```sql
+ALTER TABLE plugin_buycourses_global_config ADD COLUMN info_email_extra TEXT;
+```
+
v5.0 - 2019-02-06
====
@@ -11,12 +53,12 @@ The file update.php must be executed to update the structure of the tables
v4.0 - 2017-04-25
====
-This version includes the Culqi payment gateway and introduces an additional
-option to show the Buy Courses tab to anonymous users.
+This version includes the Culqi payment gateway v1.0 (now expired) and introduces
+an additional option to show the Buy Courses tab to anonymous users.
To enable these features, if you have already installed this plugin on your
-portal prior to this version, you will need to add the corresponding configuration
-to your access_url_rel_plugin table. No documentation is available at this time on
+portal prior to this version, you will need to add the corresponding settings
+to your settings_current table. No documentation is available at this time on
how to do that, so please check up the code. Sorry about that.
diff --git a/public/plugin/BuyCourses/README.md b/public/plugin/BuyCourses/README.md
index 1f3157daa4e..6e927e3cc6e 100644
--- a/public/plugin/BuyCourses/README.md
+++ b/public/plugin/BuyCourses/README.md
@@ -1,13 +1,37 @@
-Buy Courses plugin for Chamilo LMS
-=======================================
-Users can access the purchases catalog to buy courses or sessions (since v2 of this plugin)
-enabled for sale.
+Buy Courses (course sales) plugin
+=================================
+This plugin transforms your Chamilo installation in an online shop by adding a catalogue
+ of courses and sessions that you have previously configured for sales.
If the user is not registered or logged in, he/she will be requested to register/login
before he/she can resume buying items.
-Once the course or session is chosen, shows available payment types (currently only PayPal works)
+Do not enable this plugin in any "Region". This is a known issue, but it works without
+region assignation.
+
+Once the course or session is chosen, the plugin displays the available payment methods
and lets the user proceed with the purchase.
+Currently, the plugin allows users to pay through:
+ - PayPal (requires a merchant account on PayPal at configuration time)
+ - Bank payments (requires manual confirmation of payments' reception)
+ - RedSys payments (Spanish payment gateway) (requires the download of an external file)
+ - Stripe payments (requieres a merchant account oin Stripe at configuration time)
+ - Cecabank payments (Spanish payment gateway)
+
+The user receives an e-mail confirming the purchase and she/he can immediately
+access to the course or session.
+
+We recommend using sessions as this gives you more time-related availability options
+(in the session configuration).
+
+Updates
+=========
+
+You must load the update.php script for installations that were in
+production before updating the code, as it will update the database structure to
+enable new features.
+
+Please note that updating Chamilo does *NOT* automatically update the plugins
+structure.
-Finally, the user receives an e-mail confirming the purchase and him/her is can access to the
-course/session.
+You can find a history of changes in the [CHANGELOG.md file](../../plugin/BuyCourses/CHANGELOG.md)
diff --git a/public/plugin/BuyCourses/admin.php b/public/plugin/BuyCourses/admin.php
index 13d165b2b84..a148dda8ac6 100644
--- a/public/plugin/BuyCourses/admin.php
+++ b/public/plugin/BuyCourses/admin.php
@@ -1,3 +1,5 @@
createTable(BuyCoursesPlugin::TABLE_PAYPAL);
$paypalTable->addColumn(
'id',
- 'integer',
+ Types::INTEGER,
['autoincrement' => true, 'unsigned' => true]
);
- $paypalTable->addColumn('username', 'string');
- $paypalTable->addColumn('password', 'string');
- $paypalTable->addColumn('signature', 'string');
- $paypalTable->addColumn('sandbox', 'boolean');
+ $paypalTable->addColumn('username', Types::STRING);
+ $paypalTable->addColumn('password', Types::STRING);
+ $paypalTable->addColumn('signature', Types::STRING);
+ $paypalTable->addColumn('sandbox', Types::BOOLEAN);
$paypalTable->setPrimaryKey(['id']);
}
@@ -39,38 +42,55 @@
$transferTable = $pluginSchema->createTable(BuyCoursesPlugin::TABLE_TRANSFER);
$transferTable->addColumn(
'id',
- 'integer',
+ Types::INTEGER,
['autoincrement' => true, 'unsigned' => true]
);
- $transferTable->addColumn('title', 'string');
- $transferTable->addColumn('account', 'string');
- $transferTable->addColumn('swift', 'string');
+ $transferTable->addColumn('name', Types::STRING);
+ $transferTable->addColumn('account', Types::STRING);
+ $transferTable->addColumn('swift', Types::STRING);
$transferTable->setPrimaryKey(['id']);
}
+if (false === $sm->tablesExist(BuyCoursesPlugin::TABLE_TPV_REDSYS)) {
+ $tpvRedsysTable = $pluginSchema->createTable(BuyCoursesPlugin::TABLE_TPV_REDSYS);
+ $tpvRedsysTable->addColumn(
+ 'id',
+ Types::INTEGER,
+ ['autoincrement' => true, 'unsigned' => true]
+ );
+ $tpvRedsysTable->addColumn('merchantcode', Types::STRING);
+ $tpvRedsysTable->addColumn('terminal', Types::STRING);
+ $tpvRedsysTable->addColumn('currency', Types::STRING);
+ $tpvRedsysTable->addColumn('kc', Types::STRING);
+ $tpvRedsysTable->addColumn('url_redsys', Types::STRING);
+ $tpvRedsysTable->addColumn('url_redsys_sandbox', Types::STRING);
+ $tpvRedsysTable->addColumn('sandbox', Types::BOOLEAN);
+ $tpvRedsysTable->setPrimaryKey(['id']);
+}
+
if (false === $sm->tablesExist(BuyCoursesPlugin::TABLE_CURRENCY)) {
$currencyTable = $pluginSchema->createTable(BuyCoursesPlugin::TABLE_CURRENCY);
$currencyTable->addColumn(
'id',
- 'integer',
+ Types::INTEGER,
['autoincrement' => true, 'unsigned' => true]
);
$currencyTable->addColumn(
'country_code',
- 'string',
+ Types::STRING,
['length' => 2]
);
$currencyTable->addColumn(
'country_name',
- 'string',
+ Types::STRING,
['length' => 255]
);
$currencyTable->addColumn(
'iso_code',
- 'string',
- ['length' => 4]
+ Types::STRING,
+ ['length' => 3]
);
- $currencyTable->addColumn('status', 'boolean');
+ $currencyTable->addColumn('status', Types::BOOLEAN);
$currencyTable->addUniqueIndex(['country_code']);
$currencyTable->addIndex(['iso_code']);
$currencyTable->setPrimaryKey(['id']);
@@ -80,28 +100,28 @@
$itemTable = $pluginSchema->createTable(BuyCoursesPlugin::TABLE_ITEM);
$itemTable->addColumn(
'id',
- 'integer',
+ Types::INTEGER,
['autoincrement' => true, 'unsigned' => true]
);
- $itemTable->addColumn('product_type', 'integer');
+ $itemTable->addColumn('product_type', Types::INTEGER);
$itemTable->addColumn(
'product_id',
- 'integer',
+ Types::INTEGER,
['unsigned' => true]
);
$itemTable->addColumn(
'price',
- 'decimal',
+ Types::DECIMAL,
['scale' => 2]
);
$itemTable->addColumn(
'currency_id',
- 'integer',
+ Types::INTEGER,
['unsigned' => true]
);
$itemTable->addColumn(
'tax_perc',
- 'integer',
+ Types::INTEGER,
['unsigned' => true, 'notnull' => false]
);
$itemTable->setPrimaryKey(['id']);
@@ -117,22 +137,22 @@
$itemBeneficiary = $pluginSchema->createTable(BuyCoursesPlugin::TABLE_ITEM_BENEFICIARY);
$itemBeneficiary->addColumn(
'id',
- 'integer',
+ Types::INTEGER,
['autoincrement' => true, 'unsigned' => true]
);
$itemBeneficiary->addColumn(
'item_id',
- 'integer',
+ Types::INTEGER,
['unsigned' => true]
);
$itemBeneficiary->addColumn(
'user_id',
- 'integer',
+ Types::INTEGER,
['unsigned' => true]
);
$itemBeneficiary->addColumn(
'commissions',
- 'integer',
+ Types::INTEGER,
['unsigned' => true]
);
$itemBeneficiary->setPrimaryKey(['id']);
@@ -147,12 +167,12 @@
$commissions = $pluginSchema->createTable(BuyCoursesPlugin::TABLE_COMMISSION);
$commissions->addColumn(
'id',
- 'integer',
+ Types::INTEGER,
['autoincrement' => true, 'unsigned' => true]
);
$commissions->addColumn(
'commission',
- 'integer',
+ Types::INTEGER,
['unsigned' => true]
);
$commissions->setPrimaryKey(['id']);
@@ -162,29 +182,29 @@
$saleCommissions = $pluginSchema->createTable(BuyCoursesPlugin::TABLE_PAYPAL_PAYOUTS);
$saleCommissions->addColumn(
'id',
- 'integer',
+ Types::INTEGER,
['autoincrement' => true, 'unsigned' => true]
);
- $saleCommissions->addColumn('date', 'datetime');
- $saleCommissions->addColumn('payout_date', 'datetime');
+ $saleCommissions->addColumn('date', Types::DATETIME_MUTABLE);
+ $saleCommissions->addColumn('payout_date', Types::DATETIME_MUTABLE);
$saleCommissions->addColumn(
'sale_id',
- 'integer',
+ Types::INTEGER,
['unsigned' => true]
);
$saleCommissions->addColumn(
'user_id',
- 'integer',
+ Types::INTEGER,
['unsigned' => true]
);
$saleCommissions->addColumn(
'commission',
- 'decimal',
+ Types::DECIMAL,
['scale' => 2]
);
$saleCommissions->addColumn(
'status',
- 'integer',
+ Types::INTEGER,
['unsigned' => true]
);
$saleCommissions->setPrimaryKey(['id']);
@@ -194,51 +214,61 @@
$saleTable = $pluginSchema->createTable(BuyCoursesPlugin::TABLE_SALE);
$saleTable->addColumn(
'id',
- 'integer',
+ Types::INTEGER,
['autoincrement' => true, 'unsigned' => true]
);
- $saleTable->addColumn('reference', 'string');
- $saleTable->addColumn('date', 'datetime');
+ $saleTable->addColumn('reference', Types::STRING);
+ $saleTable->addColumn('date', Types::DATETIME_MUTABLE);
$saleTable->addColumn(
'user_id',
- 'integer',
+ Types::INTEGER,
['unsigned' => true]
);
- $saleTable->addColumn('product_type', 'integer');
- $saleTable->addColumn('product_name', 'string');
+ $saleTable->addColumn('product_type', Types::INTEGER);
+ $saleTable->addColumn('product_name', Types::STRING);
$saleTable->addColumn(
'product_id',
- 'integer',
+ Types::INTEGER,
['unsigned' => true]
);
$saleTable->addColumn(
'price',
- 'decimal',
+ Types::DECIMAL,
['scale' => 2]
);
$saleTable->addColumn(
'price_without_tax',
- 'decimal',
+ Types::DECIMAL,
['scale' => 2, 'notnull' => false]
);
$saleTable->addColumn(
'tax_perc',
- 'integer',
+ Types::INTEGER,
['unsigned' => true, 'notnull' => false]
);
$saleTable->addColumn(
'tax_amount',
- 'decimal',
+ Types::DECIMAL,
['scale' => 2, 'notnull' => false]
);
$saleTable->addColumn(
'currency_id',
- 'integer',
+ Types::INTEGER,
['unsigned' => true]
);
- $saleTable->addColumn('status', 'integer');
- $saleTable->addColumn('payment_type', 'integer');
- $saleTable->addColumn('invoice', 'integer');
+ $saleTable->addColumn('status', Types::INTEGER);
+ $saleTable->addColumn('payment_type', Types::INTEGER);
+ $saleTable->addColumn('invoice', Types::INTEGER);
+ $saleTable->addColumn(
+ 'price_without_discount',
+ Types::DECIMAL,
+ ['scale' => 2, 'notnull' => false]
+ );
+ $saleTable->addColumn(
+ 'discount_amount',
+ Types::DECIMAL,
+ ['scale' => 2, 'notnull' => false]
+ );
$saleTable->setPrimaryKey(['id']);
$saleTable->addForeignKeyConstraint(
$currencyTable,
@@ -252,23 +282,24 @@
$servicesTable = $pluginSchema->createTable(BuyCoursesPlugin::TABLE_SERVICES);
$servicesTable->addColumn(
'id',
- 'integer',
+ Types::INTEGER,
['autoincrement' => true, 'unsigned' => true]
);
- $servicesTable->addColumn('title', 'string');
- $servicesTable->addColumn('description', 'text');
+ $servicesTable->addColumn('name', Types::STRING);
+ $servicesTable->addColumn('description', Types::TEXT);
$servicesTable->addColumn(
'price',
- 'decimal',
+ Types::DECIMAL,
['scale' => 2]
);
- $servicesTable->addColumn('duration_days', 'integer');
- $servicesTable->addColumn('applies_to', 'integer');
- $servicesTable->addColumn('owner_id', 'integer');
- $servicesTable->addColumn('visibility', 'integer');
- $servicesTable->addColumn('video_url', 'string');
- $servicesTable->addColumn('image', 'string');
- $servicesTable->addColumn('service_information', 'text');
+ $servicesTable->addColumn('duration_days', Types::INTEGER);
+ $servicesTable->addColumn('applies_to', Types::INTEGER);
+ $servicesTable->addColumn('owner_id', Types::INTEGER);
+ $servicesTable->addColumn('visibility', Types::INTEGER);
+ $servicesTable->addColumn('video_url', Types::STRING);
+ $servicesTable->addColumn('image', Types::STRING);
+ $servicesTable->addColumn('service_information', Types::TEXT);
+ $servicesTable->addColumn('tax_perc', Types::INTEGER);
$servicesTable->setPrimaryKey(['id']);
}
@@ -276,52 +307,62 @@
$servicesNodeTable = $pluginSchema->createTable(BuyCoursesPlugin::TABLE_SERVICES_SALE);
$servicesNodeTable->addColumn(
'id',
- 'integer',
+ Types::INTEGER,
['autoincrement' => true, 'unsigned' => true]
);
$servicesNodeTable->addColumn(
'service_id',
- 'integer',
+ Types::INTEGER,
['unsigned' => true]
);
- $servicesNodeTable->addColumn('reference', 'string');
- $servicesNodeTable->addColumn('currency_id', 'integer');
+ $servicesNodeTable->addColumn('reference', Types::STRING);
+ $servicesNodeTable->addColumn('currency_id', Types::INTEGER);
$servicesNodeTable->addColumn(
'price',
- 'decimal',
+ Types::DECIMAL,
['scale' => 2]
);
$servicesNodeTable->addColumn(
'price_without_tax',
- 'decimal',
+ Types::DECIMAL,
['scale' => 2, 'notnull' => false]
);
$servicesNodeTable->addColumn(
'tax_perc',
- 'integer',
+ Types::INTEGER,
['unsigned' => true, 'notnull' => false]
);
$servicesNodeTable->addColumn(
'tax_amount',
- 'decimal',
+ Types::DECIMAL,
['scale' => 2, 'notnull' => false]
);
- $servicesNodeTable->addColumn('node_type', 'integer');
- $servicesNodeTable->addColumn('node_id', 'integer');
- $servicesNodeTable->addColumn('buyer_id', 'integer');
- $servicesNodeTable->addColumn('buy_date', 'datetime');
+ $servicesNodeTable->addColumn('node_type', Types::INTEGER);
+ $servicesNodeTable->addColumn('node_id', Types::INTEGER);
+ $servicesNodeTable->addColumn('buyer_id', Types::INTEGER);
+ $servicesNodeTable->addColumn('buy_date', Types::DATETIME_MUTABLE);
$servicesNodeTable->addColumn(
'date_start',
- 'datetime',
+ Types::DATETIME_MUTABLE,
['notnull' => false]
);
$servicesNodeTable->addColumn(
'date_end',
- 'datetime'
+ Types::DATETIME_MUTABLE
+ );
+ $servicesNodeTable->addColumn('status', Types::INTEGER);
+ $servicesNodeTable->addColumn('payment_type', Types::INTEGER);
+ $servicesNodeTable->addColumn('invoice', Types::INTEGER);
+ $servicesNodeTable->addColumn(
+ 'price_without_discount',
+ Types::DECIMAL,
+ ['scale' => 2, 'notnull' => false]
+ );
+ $servicesNodeTable->addColumn(
+ 'discount_amount',
+ Types::DECIMAL,
+ ['scale' => 2, 'notnull' => false]
);
- $servicesNodeTable->addColumn('status', 'integer');
- $servicesNodeTable->addColumn('payment_type', 'integer');
- $servicesNodeTable->addColumn('invoice', 'integer');
$servicesNodeTable->setPrimaryKey(['id']);
$servicesNodeTable->addForeignKeyConstraint(
$servicesTable,
@@ -335,12 +376,12 @@
$culqiTable = $pluginSchema->createTable(BuyCoursesPlugin::TABLE_CULQI);
$culqiTable->addColumn(
'id',
- 'integer',
+ Types::INTEGER,
['autoincrement' => true, 'unsigned' => true]
);
- $culqiTable->addColumn('commerce_code', 'string');
- $culqiTable->addColumn('api_key', 'string');
- $culqiTable->addColumn('integration', 'integer');
+ $culqiTable->addColumn('commerce_code', Types::STRING);
+ $culqiTable->addColumn('api_key', Types::STRING);
+ $culqiTable->addColumn('integration', Types::INTEGER);
$culqiTable->setPrimaryKey(['id']);
}
@@ -348,47 +389,225 @@
$globalTable = $pluginSchema->createTable(BuyCoursesPlugin::TABLE_GLOBAL_CONFIG);
$globalTable->addColumn(
'id',
- 'integer',
+ Types::INTEGER,
['autoincrement' => true, 'unsigned' => true]
);
- $globalTable->addColumn('terms_and_conditions', 'text');
- $globalTable->addColumn('global_tax_perc', 'integer');
- $globalTable->addColumn('tax_applies_to', 'integer');
- $globalTable->addColumn('tax_name', 'string');
- $globalTable->addColumn('seller_name', 'string');
- $globalTable->addColumn('seller_id', 'string');
- $globalTable->addColumn('seller_address', 'string');
- $globalTable->addColumn('seller_email', 'string');
- $globalTable->addColumn('next_number_invoice', 'integer');
- $globalTable->addColumn('invoice_series', 'string');
- $globalTable->addColumn('sale_email', 'string');
+ $globalTable->addColumn('terms_and_conditions', Types::TEXT);
+ $globalTable->addColumn('global_tax_perc', Types::INTEGER);
+ $globalTable->addColumn('tax_applies_to', Types::INTEGER);
+ $globalTable->addColumn('tax_name', Types::STRING);
+ $globalTable->addColumn('seller_name', Types::STRING);
+ $globalTable->addColumn('seller_id', Types::STRING);
+ $globalTable->addColumn('seller_address', Types::STRING);
+ $globalTable->addColumn('seller_email', Types::STRING);
+ $globalTable->addColumn('next_number_invoice', Types::INTEGER);
+ $globalTable->addColumn('invoice_series', Types::STRING);
+ $globalTable->addColumn('sale_email', Types::STRING);
+ $globalTable->addColumn('info_email_extra', Types::TEXT);
$globalTable->setPrimaryKey(['id']);
+} else {
+ $globalTable = $pluginSchema->getTable(BuyCoursesPlugin::TABLE_GLOBAL_CONFIG);
+
+ if (!$globalTable->hasColumn('info_email_extra')) {
+ $globalTable->addColumn('info_email_extra', Types::TEXT);
+ }
}
if (false === $sm->tablesExist(BuyCoursesPlugin::TABLE_INVOICE)) {
$invoiceTable = $pluginSchema->createTable(BuyCoursesPlugin::TABLE_INVOICE);
$invoiceTable->addColumn(
'id',
- 'integer',
+ Types::INTEGER,
['autoincrement' => true, 'unsigned' => true]
);
- $invoiceTable->addColumn('sale_id', 'integer');
- $invoiceTable->addColumn('is_service', 'integer');
+ $invoiceTable->addColumn('sale_id', Types::INTEGER);
+ $invoiceTable->addColumn('is_service', Types::INTEGER);
$invoiceTable->addColumn(
'num_invoice',
- 'integer',
+ Types::INTEGER,
['unsigned' => true, 'notnull' => false]
);
$invoiceTable->addColumn(
'year',
- 'integer',
+ Types::INTEGER,
['unsigned' => true, 'notnull' => false]
);
- $invoiceTable->addColumn('serie', 'string');
- $invoiceTable->addColumn('date_invoice', 'datetime');
+ $invoiceTable->addColumn('serie', Types::STRING);
+ $invoiceTable->addColumn('date_invoice', Types::DATETIME_MUTABLE);
$invoiceTable->setPrimaryKey(['id']);
}
+if (false === $sm->tablesExist(BuyCoursesPlugin::TABLE_COUPON)) {
+ $couponTable = $pluginSchema->createTable(BuyCoursesPlugin::TABLE_COUPON);
+ $couponTable->addColumn(
+ 'id',
+ Types::INTEGER,
+ ['autoincrement' => true, 'unsigned' => true]
+ );
+ $couponTable->addColumn('code', Types::STRING);
+ $couponTable->addColumn('discount_type', Types::INTEGER);
+ $couponTable->addColumn('discount_amount', Types::INTEGER);
+ $couponTable->addColumn('valid_start', Types::DATETIME_MUTABLE);
+ $couponTable->addColumn('valid_end', Types::DATETIME_MUTABLE);
+ $couponTable->addColumn('delivered', Types::INTEGER);
+ $couponTable->addColumn('active', Types::BOOLEAN);
+ $couponTable->setPrimaryKey(['id']);
+}
+
+if (false === $sm->tablesExist(BuyCoursesPlugin::TABLE_COUPON_ITEM)) {
+ $couponItemTable = $pluginSchema->createTable(BuyCoursesPlugin::TABLE_COUPON_ITEM);
+ $couponItemTable->addColumn(
+ 'id',
+ Types::INTEGER,
+ ['autoincrement' => true, 'unsigned' => true]
+ );
+ $couponItemTable->addColumn('coupon_id', Types::INTEGER);
+ $couponItemTable->addColumn('product_type', Types::INTEGER);
+ $couponItemTable->addColumn('product_id', Types::INTEGER);
+ $couponItemTable->setPrimaryKey(['id']);
+}
+
+if (false === $sm->tablesExist(BuyCoursesPlugin::TABLE_COUPON_SERVICE)) {
+ $couponService = $pluginSchema->createTable(BuyCoursesPlugin::TABLE_COUPON_SERVICE);
+ $couponService->addColumn(
+ 'id',
+ Types::INTEGER,
+ ['autoincrement' => true, 'unsigned' => true]
+ );
+ $couponService->addColumn('coupon_id', Types::INTEGER);
+ $couponService->addColumn('service_id', Types::INTEGER);
+ $couponService->setPrimaryKey(['id']);
+}
+
+if (false === $sm->tablesExist(BuyCoursesPlugin::TABLE_SUBSCRIPTION)) {
+ $subscriptionTable = $pluginSchema->createTable(BuyCoursesPlugin::TABLE_SUBSCRIPTION);
+ $subscriptionTable->addColumn(
+ 'product_type',
+ Types::INTEGER,
+ ['unsigned' => true]
+ );
+ $subscriptionTable->addColumn(
+ 'product_id',
+ Types::INTEGER,
+ ['unsigned' => true]
+ );
+ $subscriptionTable->addColumn(
+ 'duration',
+ Types::INTEGER,
+ ['unsigned' => true]
+ );
+ $subscriptionTable->addColumn('currency_id', Types::INTEGER);
+ $subscriptionTable->addColumn('price', Types::DECIMAL);
+ $subscriptionTable->addColumn('tax_perc', Types::INTEGER);
+ $subscriptionTable->setPrimaryKey(['product_type', 'product_id', 'duration']);
+}
+
+if (false === $sm->tablesExist(BuyCoursesPlugin::TABLE_SUBSCRIPTION_SALE)) {
+ $subscriptionSaleTable = $pluginSchema->createTable(BuyCoursesPlugin::TABLE_SUBSCRIPTION_SALE);
+ $subscriptionSaleTable->addColumn(
+ 'id',
+ Types::INTEGER,
+ ['autoincrement' => true, 'unsigned' => true]
+ );
+ $subscriptionSaleTable->addColumn('currency_id', Types::INTEGER);
+ $subscriptionSaleTable->addColumn('reference', Types::STRING);
+ $subscriptionSaleTable->addColumn('date', Types::DATETIME_MUTABLE);
+ $subscriptionSaleTable->addColumn('user_id', Types::INTEGER);
+ $subscriptionSaleTable->addColumn('product_type', Types::INTEGER);
+ $subscriptionSaleTable->addColumn('product_name', Types::STRING);
+ $subscriptionSaleTable->addColumn('product_id', Types::INTEGER);
+ $subscriptionSaleTable->addColumn('price', Types::DECIMAL);
+ $subscriptionSaleTable->addColumn('price_without_tax', Types::DECIMAL, ['notnull' => false]);
+ $subscriptionSaleTable->addColumn('tax_perc', Types::INTEGER, ['notnull' => false]);
+ $subscriptionSaleTable->addColumn('tax_amount', Types::DECIMAL, ['notnull' => false]);
+ $subscriptionSaleTable->addColumn('status', Types::INTEGER);
+ $subscriptionSaleTable->addColumn('payment_type', Types::INTEGER);
+ $subscriptionSaleTable->addColumn('invoice', Types::INTEGER);
+ $subscriptionSaleTable->addColumn('price_without_discount', Types::DECIMAL);
+ $subscriptionSaleTable->addColumn('discount_amount', Types::DECIMAL);
+ $subscriptionSaleTable->addColumn('subscription_end', Types::DATETIME_MUTABLE);
+ $subscriptionSaleTable->addColumn('expired', Types::BOOLEAN);
+ $subscriptionSaleTable->setPrimaryKey(['id']);
+}
+
+if (false === $sm->tablesExist(BuyCoursesPlugin::TABLE_SUBSCRIPTION_PERIOD)) {
+ $subscriptionPeriodTable = $pluginSchema->createTable(BuyCoursesPlugin::TABLE_SUBSCRIPTION_PERIOD);
+ $subscriptionPeriodTable->addColumn(
+ 'duration',
+ Types::INTEGER,
+ ['unsigned' => true]
+ );
+ $subscriptionPeriodTable->addColumn('name', Types::STRING);
+ $subscriptionPeriodTable->setPrimaryKey(['duration']);
+}
+
+if (false === $sm->tablesExist(BuyCoursesPlugin::TABLE_COUPON_SALE)) {
+ $couponSaleTable = $pluginSchema->createTable(BuyCoursesPlugin::TABLE_COUPON_SALE);
+ $couponSaleTable->addColumn(
+ 'id',
+ Types::INTEGER,
+ ['autoincrement' => true, 'unsigned' => true]
+ );
+ $couponSaleTable->addColumn('coupon_id', Types::INTEGER);
+ $couponSaleTable->addColumn('sale_id', Types::INTEGER);
+ $couponSaleTable->setPrimaryKey(['id']);
+}
+
+if (false === $sm->tablesExist(BuyCoursesPlugin::TABLE_COUPON_SERVICE_SALE)) {
+ $couponSaleTable = $pluginSchema->createTable(BuyCoursesPlugin::TABLE_COUPON_SERVICE_SALE);
+ $couponSaleTable->addColumn(
+ 'id',
+ Types::INTEGER,
+ ['autoincrement' => true, 'unsigned' => true]
+ );
+ $couponSaleTable->addColumn('coupon_id', Types::INTEGER);
+ $couponSaleTable->addColumn('service_sale_id', Types::INTEGER);
+ $couponSaleTable->setPrimaryKey(['id']);
+}
+
+if (false === $sm->tablesExist(BuyCoursesPlugin::TABLE_STRIPE)) {
+ $stripeTable = $pluginSchema->createTable(BuyCoursesPlugin::TABLE_STRIPE);
+ $stripeTable->addColumn(
+ 'id',
+ Types::INTEGER,
+ ['autoincrement' => true, 'unsigned' => true]
+ );
+ $stripeTable->addColumn('account_id', Types::STRING);
+ $stripeTable->addColumn('secret_key', Types::STRING);
+ $stripeTable->addColumn('endpoint_secret', Types::STRING);
+ $stripeTable->setPrimaryKey(['id']);
+}
+
+if (false === $sm->tablesExist(BuyCoursesPlugin::TABLE_TPV_CECABANK)) {
+ $tpvCecabankTable = $pluginSchema->createTable(BuyCoursesPlugin::TABLE_TPV_CECABANK);
+ $tpvCecabankTable->addColumn(
+ 'id',
+ Types::INTEGER,
+ ['autoincrement' => true, 'unsigned' => true]
+ );
+ $tpvCecabankTable->addColumn('crypto_key', Types::STRING);
+ $tpvCecabankTable->addColumn('merchant_id', Types::STRING);
+ $tpvCecabankTable->addColumn('acquirer_bin', Types::STRING);
+ $tpvCecabankTable->addColumn('terminal_id', Types::STRING);
+ $tpvCecabankTable->addColumn('cypher', Types::STRING);
+ $tpvCecabankTable->addColumn('exponent', Types::STRING);
+ $tpvCecabankTable->addColumn('supported_payment', Types::STRING);
+ $tpvCecabankTable->addColumn('url', Types::STRING);
+ $tpvCecabankTable->setPrimaryKey(['id']);
+}
+
+if (false === $sm->tablesExist(BuyCoursesPlugin::TABLE_COUPON_SUBSCRIPTION_SALE)) {
+ $couponSubscriptionSaleTable = $pluginSchema->createTable(BuyCoursesPlugin::TABLE_COUPON_SUBSCRIPTION_SALE);
+ $couponSubscriptionSaleTable->addColumn(
+ 'id',
+ Types::INTEGER,
+ ['autoincrement' => true, 'unsigned' => true]
+ );
+ $couponSubscriptionSaleTable->addColumn('coupon_id', Types::INTEGER);
+ $couponSubscriptionSaleTable->addColumn('sale_id', Types::INTEGER);
+ $couponSubscriptionSaleTable->setPrimaryKey(['id']);
+}
+
$queries = $pluginSchema->toSql($platform);
foreach ($queries as $query) {
@@ -404,9 +623,11 @@
$extraFieldTable = Database::get_main_table(TABLE_EXTRA_FIELD);
$culqiTable = Database::get_main_table(BuyCoursesPlugin::TABLE_CULQI);
$globalTable = Database::get_main_table(BuyCoursesPlugin::TABLE_GLOBAL_CONFIG);
+$tpvRedsysTable = Database::get_main_table(BuyCoursesPlugin::TABLE_TPV_REDSYS);
+$stripeTable = Database::get_main_table(BuyCoursesPlugin::TABLE_STRIPE);
$paypalExtraField = Database::select(
- "*",
+ '*',
$extraFieldTable,
[
'where' => ['variable = ?' => 'paypal'],
@@ -442,6 +663,14 @@
]
);
+Database::insert(
+ $tpvRedsysTable,
+ [
+ 'url_redsys' => 'https://sis.redsys.es/sis/realizarPago',
+ 'url_redsys_sandbox' => 'https://sis-t.redsys.es:25443/sis/realizarPago',
+ ]
+);
+
Database::insert(
$culqiTable,
[
@@ -455,16 +684,6 @@
$globalTable,
[
'terms_and_conditions' => '',
- 'global_tax_perc' => 0,
- 'tax_applies_to' => 0,
- 'tax_name' => '',
- 'seller_name' => '',
- 'seller_id' => '',
- 'seller_address' => '',
- 'seller_email' => '',
- 'next_number_invoice' => 1,
- 'invoice_series' => '',
- 'sale_email' => '',
]
);
@@ -475,6 +694,15 @@
]
);
+Database::insert(
+ $stripeTable,
+ [
+ 'account_id' => '',
+ 'secret_key' => '',
+ 'endpoint_secret' => '',
+ ]
+);
+
$currencies = [
['AD', 'Andorra', 'EUR', 'AND', 0],
['AE', 'United Arab Emirates', 'AED', 'ARE', 0],
@@ -731,7 +959,7 @@
foreach ($currencies as $currency) {
$value = Database::select(
- "*",
+ '*',
$currencyTable,
[
'where' => ['country_code = ?' => $currency[0]],
diff --git a/public/plugin/BuyCourses/index.php b/public/plugin/BuyCourses/index.php
index fefacd452bd..45974575ad6 100644
--- a/public/plugin/BuyCourses/index.php
+++ b/public/plugin/BuyCourses/index.php
@@ -1,7 +1,11 @@
configurar pagamento - Defina a moeda com a qual você gostaria de vender seus cursos ou sessões";
-$strings['InstructionsStepThree'] = "Para configurar cursos para vender. Vá em: configurar cursos e preços.";
-$strings['BuyCourses'] = "Comprar cursos";
-$strings['ConfigurationOfCoursesAndPrices'] = "Configurar cursos e preços ";
-$strings['SalesReport'] = "Relatório de vendas";
-$strings['UserInformation'] = "Detalhes do comprador";
-$strings['PaymentMethods'] = "Métodos de pagamento";
-$strings['ConfirmOrder'] = "Confirmar pedido";
-$strings['PurchaseData'] = "Dados de Compra";
-$strings['bc_subject'] = "Confirmação de ordem do curso";
-$strings['PurchaseStatusX'] = "Estado de compra: %s";
-$strings['PendingReasonByTransfer'] = " Pendente Aguardando confirmação da transferência.";
-$strings['CancelOrder'] = "Anular ordem";
-$strings['BankAccountInformation'] = "Detalhes da conta bancária";
-$strings['BankAccount'] = "Contas bancárias";
-$strings['OnceItIsConfirmedYouWillReceiveAnEmailWithTheBankInformationAndAnOrderReference'] = "Uma vez confirmada, você receberá um e-mail com os dados bancários e uma referência de ordem.";
-$strings['SubscriptionToCourseXSuccessful'] = "Sua inscrição para \"%s\" foi concluída com sucesso.";
-$strings['OrderCanceled'] = "Ordem cancelada";
-$strings['OrderStatus'] = "Status do pedido";
-$strings['SearchByStatus'] = "Pesquisar por estado";
-$strings['OrderReference'] = "Código de encomenda";
-$strings['OrderDate'] = "Data do pedido";
-$strings['ProductType'] = "Tipo de produto";
-$strings['SubscribeUser'] = "Inscrever utilizador";
-$strings['DeleteOrder'] = "Excluir a ordem";
-$strings['ErrorContactPlatformAdmin'] = "Por favor entre em contato com o administrador da plataforma de erro desconhecido..";
-$strings['PendingReasonByAddress'] = ". Pendente Você não digitou um endereço de entrega confirmado.";
-$strings['PendingReasonByAuthorization'] = " Pendentes fundos Nós ainda não capturados..";
-$strings['PendingReasonByEcheck'] = " Pendente O pagamento foi feito por um eCheck que ainda não foi eliminada.";
-$strings['PendingReasonByIntl'] = " Pendente Nós não temos um mecanismo de retirada de fundos..";
-$strings['PendingReasonByMulticurrency'] = " Pendente Nós não equilibrar na moeda enviado.";
-$strings['PendingReasonByOrder'] = " Pendente Ordem feita Nós ainda não capturado fundos...";
-$strings['PendingReasonByPaymentReview'] = " Pendente O pagamento está sendo revisto pelo PayPal para o risco.";
-$strings['PendingReasonByRegulatoryReview'] = " Pendente O pagamento está sendo revisado para conformidade com regulamentações governamentais..";
-$strings['PendingReasonByUnilateral'] = " Pendente O e-mail ainda não está registrado o confirmou..";
-$strings['PendingReasonByUpgrade'] = " Pendente O pagamento foi feito por cartão de crédito..";
-$strings['PendingReasonByVerify'] = " Pendente Desculpe Nós ainda não são verificados no PayPal...";
-$strings['PendingReasonByOther'] = " Pendente Por favor, entre em contato com o administrador da plataforma..";
+
+declare(strict_types=1);
+$strings['plugin_title'] = 'Vender cursos';
+$strings['plugin_comment'] = 'Venda cursos diretamente através de seu portal Chamilo, usando uma conta do PayPal para receber fundos Nem a associação Chamilo nem os desenvolvedores envolvidos poderia ser considerado responsável de qualquer problema que você pode sofrer de usar este plugin..';
+$strings['show_main_menu_tab'] = 'Mostrar guia no menu principal';
+$strings['show_main_menu_tab_help'] = 'No caso de não querer mostrar a guia, você pode criar esse link em sua página Chamilo: %s';
+$strings['include_sessions'] = 'Incluir sessões';
+$strings['paypal_enable'] = 'Ativar PayPal';
+$strings['transfer_enable'] = 'Permitir transferência bancária';
+$strings['unregistered_users_enable'] = 'Permitir que usuários anônimos';
+$strings['Free'] = 'GRÁTIS';
+$strings['banktransfer'] = 'Transferência Bancária';
+$strings['SaleStatusPending'] = 'Venda pendente';
+$strings['SaleStatusCanceled'] = 'Venda cancelada';
+$strings['SaleStatusCompleted'] = 'Venda concluída';
+$strings['CourseListOnSale'] = 'Lista de cursos à venda';
+$strings['AvailableCourses'] = 'Campos disponíveis';
+$strings['Price'] = 'Preço';
+$strings['SearchFilter'] = 'Filtrar Pesquisa';
+$strings['MinimumPrice'] = 'Preço mínimo';
+$strings['MaximumPrice'] = 'Preço máximo';
+$strings['AvailableCoursesConfiguration'] = 'Configuração cursos disponíveis';
+$strings['PaymentsConfiguration'] = 'Configurar pagamentos';
+$strings['TheUserIsAlreadyRegisteredInTheCourse'] = 'Você está registrado no curso.';
+$strings['SeeDescription'] = 'Descriçao';
+$strings['Buy'] = 'Comprar';
+$strings['WaitingToReceiveThePayment'] = 'Atualmente pendente de pagamento';
+$strings['TheUserIsAlreadyRegisteredInTheSession'] = 'Você já está registrado na sessão';
+$strings['ItemNotSaved'] = 'Item não salvo';
+$strings['TitlePlugin'] = 'Tudo o que você precisa para ensinar e vender cursos on-line';
+$strings['PluginPresentation'] = 'O BuyCourses Plugin dá-lhe os meios para vender seus cursos ou sessões e ensinar on-line, através de apenas alguns passos e configurações simples. O que você está esperando para começar a vender cursos através Chamilo LMS?';
+$strings['Instructions'] = 'Instruções';
+$strings['InstructionsStepOne'] = 'Criar um curso ou sessão na plataforma.';
+$strings['InstructionsStepTwo'] = 'Em - configurar pagamento - Defina a moeda com a qual você gostaria de vender seus cursos ou sessões';
+$strings['InstructionsStepThree'] = 'Para configurar cursos para vender. Vá em: configurar cursos e preços.';
+$strings['BuyCourses'] = 'Comprar cursos';
+$strings['ConfigurationOfCoursesAndPrices'] = 'Configurar cursos e preços ';
+$strings['SalesReport'] = 'Relatório de vendas';
+$strings['UserInformation'] = 'Detalhes do comprador';
+$strings['PaymentMethods'] = 'Métodos de pagamento';
+$strings['ConfirmOrder'] = 'Confirmar pedido';
+$strings['PurchaseData'] = 'Dados de Compra';
+$strings['bc_subject'] = 'Confirmação de ordem do curso';
+$strings['PurchaseStatusX'] = 'Estado de compra: %s';
+$strings['PendingReasonByTransfer'] = ' Pendente Aguardando confirmação da transferência.';
+$strings['CancelOrder'] = 'Anular ordem';
+$strings['BankAccountInformation'] = 'Detalhes da conta bancária';
+$strings['BankAccount'] = 'Contas bancárias';
+$strings['OnceItIsConfirmedYouWillReceiveAnEmailWithTheBankInformationAndAnOrderReference'] = 'Uma vez confirmada, você receberá um e-mail com os dados bancários e uma referência de ordem.';
+$strings['SubscriptionToCourseXSuccessful'] = 'Sua inscrição para "%s" foi concluída com sucesso.';
+$strings['OrderCanceled'] = 'Ordem cancelada';
+$strings['OrderStatus'] = 'Status do pedido';
+$strings['SearchByStatus'] = 'Pesquisar por estado';
+$strings['OrderReference'] = 'Código de encomenda';
+$strings['OrderDate'] = 'Data do pedido';
+$strings['ProductType'] = 'Tipo de produto';
+$strings['SubscribeUser'] = 'Inscrever utilizador';
+$strings['DeleteOrder'] = 'Excluir a ordem';
+$strings['ErrorContactPlatformAdmin'] = 'Por favor entre em contato com o administrador da plataforma de erro desconhecido..';
+$strings['PendingReasonByAddress'] = '. Pendente Você não digitou um endereço de entrega confirmado.';
+$strings['PendingReasonByAuthorization'] = ' Pendentes fundos Nós ainda não capturados..';
+$strings['PendingReasonByEcheck'] = ' Pendente O pagamento foi feito por um eCheck que ainda não foi eliminada.';
+$strings['PendingReasonByIntl'] = ' Pendente Nós não temos um mecanismo de retirada de fundos..';
+$strings['PendingReasonByMulticurrency'] = ' Pendente Nós não equilibrar na moeda enviado.';
+$strings['PendingReasonByOrder'] = ' Pendente Ordem feita Nós ainda não capturado fundos...';
+$strings['PendingReasonByPaymentReview'] = ' Pendente O pagamento está sendo revisto pelo PayPal para o risco.';
+$strings['PendingReasonByRegulatoryReview'] = ' Pendente O pagamento está sendo revisado para conformidade com regulamentações governamentais..';
+$strings['PendingReasonByUnilateral'] = ' Pendente O e-mail ainda não está registrado o confirmou..';
+$strings['PendingReasonByUpgrade'] = ' Pendente O pagamento foi feito por cartão de crédito..';
+$strings['PendingReasonByVerify'] = ' Pendente Desculpe Nós ainda não são verificados no PayPal...';
+$strings['PendingReasonByOther'] = ' Pendente Por favor, entre em contato com o administrador da plataforma..';
$strings['PayPalPaymentOKPleaseConfirm'] = "PayPal relata a transação está pronto para ser executado. Para confirmar que você está OK para prosseguir, clique no botão de confirmação abaixo. Uma vez clicado, você será registrado para o curso e os fundos serão transferido da sua conta PayPal para a nossa loja. Você sempre pode acessar seus cursos através da aba 'Meus cursos' Obrigado por seu costume.!";
-$strings['Sandbox'] = "Ambiente de teste";
-$strings['PayPalConfig'] = "Configuração PayPal:";
-$strings['TransfersConfig'] = "Configurar transferências bancárias:";
-$strings['PluginInstruction'] = "Você pode ativar ou desativar a opção de pagar via PayPal ou transferência bancária na seção de configuração do plugin.";
-$strings['ClickHere'] = " Clique aqui para obter mais detalhes";
-$strings['CurrencyType'] = "Tipo de moeda";
-$strings['InfoCurrency'] = "Define a moeda para o pagamento de seus cursos.";
-$strings['ApiUsername'] = "Nome de usuário API";
-$strings['ApiPassword'] = "Senha API";
-$strings['ApiSignature'] = "Assinatura API";
-$strings['InfoApiCredentials'] = "Para gerar as suas credenciais de API para integrar Chamilo com a sua conta PayPal, você deve seguir os seguintes passos";
-$strings['InfoApiStepOne'] = "Vá para a sua conta do PayPal, Resumo , então preferências do vendedor na Ferramentas de Vendas menu (se o fizer não ter este item de menu, você pode precisar de obter a autorização para vender o material através do PayPal em primeiro lugar).";
-$strings['InfoApiStepTwo'] = "No parágrafo Acesso API , clique em Atualizar ";
-$strings['InfoApiStepThree'] = "Na opção 2 (credenciais de solicitação de API para criar o seu próprio nome de usuário e senha API), clique no botão Exibir API Assinatura link , e copiar as credenciais apresentadas à direita no formulário do plugin BuyCourses.";
-$strings['ErrorOccurred'] = " Ocorreu um erro Código: %s. Mensagem: %s. Por favor, entre em contato com o Admin da plataforma.";
-$strings['VisibleInCatalog'] = "Visível no catálogo";
-$strings['Beneficiaries'] = "Beneficiários";
-$strings['AvailableCourse'] = "Campo disponível";
-$strings['ShowOnCourseCatalog'] = "Mostrar no catálogo de cursos";
-$strings['ByStatus'] = "Por estado";
-$strings['ByUser'] = "Por usuário";
-$strings['ByEmail'] = "Por email";
-$strings['PaymentMethod'] = "Método de pagamento";
-$strings['SWIFT'] = "Código SWIFT";
-$strings['SWIFT_help'] = "Formato padrão de Códigos de Identificação Bancária (BIC) e serve como um identificador exclusivo de um banco ou instituição financeira";
-$strings['ExportReport'] = "Exportar Relatório de Vendas";
-$strings['OrderTime'] = "Hora do pedido";
-$strings['SelectDateRange'] = "Selecione uma data de início e uma data de término para o relatório";
+$strings['Sandbox'] = 'Ambiente de teste';
+$strings['PayPalConfig'] = 'Configuração PayPal:';
+$strings['TransfersConfig'] = 'Configurar transferências bancárias:';
+$strings['PluginInstruction'] = 'Você pode ativar ou desativar a opção de pagar via PayPal ou transferência bancária na seção de configuração do plugin.';
+$strings['ClickHere'] = ' Clique aqui para obter mais detalhes';
+$strings['CurrencyType'] = 'Tipo de moeda';
+$strings['InfoCurrency'] = 'Define a moeda para o pagamento de seus cursos.';
+$strings['ApiUsername'] = 'Nome de usuário API';
+$strings['ApiPassword'] = 'Senha API';
+$strings['ApiSignature'] = 'Assinatura API';
+$strings['InfoApiCredentials'] = 'Para gerar as suas credenciais de API para integrar Chamilo com a sua conta PayPal, você deve seguir os seguintes passos';
+$strings['InfoApiStepOne'] = 'Vá para a sua conta do PayPal, Resumo , então preferências do vendedor na Ferramentas de Vendas menu (se o fizer não ter este item de menu, você pode precisar de obter a autorização para vender o material através do PayPal em primeiro lugar).';
+$strings['InfoApiStepTwo'] = 'No parágrafo Acesso API , clique em Atualizar ';
+$strings['InfoApiStepThree'] = 'Na opção 2 (credenciais de solicitação de API para criar o seu próprio nome de usuário e senha API), clique no botão Exibir API Assinatura link , e copiar as credenciais apresentadas à direita no formulário do plugin BuyCourses.';
+$strings['ErrorOccurred'] = ' Ocorreu um erro Código: %s. Mensagem: %s. Por favor, entre em contato com o Admin da plataforma.';
+$strings['VisibleInCatalog'] = 'Visível no catálogo';
+$strings['Beneficiaries'] = 'Beneficiários';
+$strings['AvailableCourse'] = 'Campo disponível';
+$strings['ShowOnCourseCatalog'] = 'Mostrar no catálogo de cursos';
+$strings['ByStatus'] = 'Por estado';
+$strings['ByUser'] = 'Por usuário';
+$strings['ByEmail'] = 'Por email';
+$strings['PaymentMethod'] = 'Método de pagamento';
+$strings['SWIFT'] = 'Código SWIFT';
+$strings['SWIFT_help'] = 'Formato padrão de Códigos de Identificação Bancária (BIC) e serve como um identificador exclusivo de um banco ou instituição financeira';
+$strings['ExportReport'] = 'Exportar Relatório de Vendas';
+$strings['OrderTime'] = 'Hora do pedido';
+$strings['SelectDateRange'] = 'Selecione uma data de início e uma data de término para o relatório';
diff --git a/public/plugin/BuyCourses/lang/dutch.php b/public/plugin/BuyCourses/lang/dutch.php
index d265f6c109e..5379ebe6f23 100644
--- a/public/plugin/BuyCourses/lang/dutch.php
+++ b/public/plugin/BuyCourses/lang/dutch.php
@@ -1,135 +1,137 @@
%s . Deze percentage zal invermindering gebracht worden van de totale prijs van het product. Het verschil in het bedrag zal aan de volgende commissies toegepast worden.";
-$strings['CoursesInSessionsDoesntDisplayHere'] = "De cursussen die binnen een training zitten worden niet weergegeven in de lijst van de cursussen als afzonderlijke producten.";
-$strings['WantToSellCourses'] = "Wilt u leren en wat geld verdienen met uw eigen cursussen? Deze lijst kan worden gevuld met de verkoop van uw cursussen via dit platform. Neem contact op met ons.";
-$strings['SelectOptionToProceed'] = "Selecteer de optie om verder te gaan";
-$strings['VerifyTotalAmountToProceedPayout'] = "Controleer het totale bedrag voor over te gaan tot de betaling van commissies. Dit bedrag heeft geen extra kosten voor PayPal rekening houder. De cursussen verkopen die niet meetellen met een Paypal-account voor de begunstigden niet in aanmerking genomen.";
-$strings['TotalAcounts'] = "Totaal van de rekeningen:";
-$strings['TotalPayout'] = "Totaal te betalen:";
-$strings['PayoutDate'] = "Betaaldatum:";
-$strings['CautionThisProcessCantBeCanceled'] = "Let op:Dit proces kan een paar minuten duren en kan niet worden geannuleerd.";
-$strings['ProcessingPayoutsDontCloseThisWindow'] = "Verder gaan met betalingen. Dit venster niet sluiten totdat dit proces is afgerond.";
-$strings['PayoutSuccess'] = "Betalingen met succes verwerkt";
-$strings['Buyer'] = "Koper";
-$strings['BankTransfer'] = "Bankoverschrijving";
-$strings['SaleInfo'] = "Verkoop Informatie";
-$strings['SaleStatusPending'] = "Verkoop in behandeling";
-$strings['SaleStatusCanceled'] = "Verkoop geannuleerd";
-$strings['SaleStatusCompleted'] = "verkoop afgerond";
-$strings['PayoutStatusPending'] = "Betaling in behandeling";
-$strings['PayoutStatusCanceled'] = "Betaling geannuleerd";
-$strings['PayoutStatusCompleted'] = "Betaling afgerond";
-$strings['PayoutsTotalPending'] = "Onafgehandelde betalingen:";
-$strings['PayoutsTotalCanceled'] = "Geannuleerde betalingen:";
-$strings['PayoutsTotalCompleted'] = "Afgeronde betalingen:";
-$strings['TotalAmount'] = "Totaalbedrag:";
-$strings['CourseListOnSale'] = "Lijst van cursussen in verkoop";
-$strings['AvailableCourses'] = "Beschikbare Cursussen";
-$strings['Price'] = "Prijs";
-$strings['SearchFilter'] = "Zoekmachine";
-$strings['MinimumPrice'] = "Minimuum prijs";
-$strings['MaximumPrice'] = "Maximuumm prijs";
-$strings['AvailableCoursesConfiguration'] = "Beschikbare cursussen overzicht";
-$strings['PaymentsConfiguration'] = "Betalingsoverzicht";
-$strings['TheUserIsAlreadyRegisteredInTheCourse'] = "Je bent geregistreerd voor de cursus.";
-$strings['SeeDescription'] = "Omschrijving";
-$strings['Buy'] = "Koop / inschrijven";
-$strings['WaitingToReceiveThePayment'] = "In afwachting van uw betaling";
-$strings['TheUserIsAlreadyRegisteredInTheSession'] = "Je bent geregistreerd voor de sessie";
-$strings['ItemNotSaved'] = "Item niet opgeslagen";
-$strings['TitlePlugin'] = "Alles wat je nodig hebt om online cursussen te onderwijzen en te verkopen";
-$strings['PluginPresentation'] = "The BuyCourses Plugin gives you the means to sell your courses or sessions and teach online, through only a few simple steps and settings. What are you waiting for? Start selling courses through Chamilo LMS!";
-$strings['Instructions'] = "Instructies";
-$strings['InstructionsStepOne'] = "Maak een cursus of een sessie op het platform.";
-$strings['InstructionsStepTwo'] = "In de betaling , stelt de valuta waarmee u wilt uw cursussen of sessies te verkopen.";
-$strings['InstructionsStepThree'] = "Overzicht van cursussen om te verkopen in de Cursussen en prijzen Instellingen.";
-$strings['BuyCourses'] = "Cursussen Kopen";
-$strings['ConfigurationOfCoursesAndPrices'] = "Cursussen en Prijzen overzicht";
-$strings['SalesReport'] = "Verkoopcijfers";
-$strings['UserInformation'] = "Gegevens van de koper";
-$strings['PaymentMethods'] = "Betaal methodes";
-$strings['ConfirmOrder'] = "Bevestig bestelling";
-$strings['PurchaseData'] = "Aankoopgegevens";
-$strings['bc_subject'] = "Bevestiging cursus order";
-$strings['PurchaseStatusX'] = "Aankoop status: %s";
-$strings['PendingReasonByTransfer'] = " In afwachting . In afwachting van de overdracht bevestiging";
-$strings['CancelOrder'] = "Annuleer order";
-$strings['BankAccountInformation'] = "Bankgegevens";
-$strings['BankAccount'] = "Bankrekening";
-$strings['OnceItIsConfirmedYouWillReceiveAnEmailWithTheBankInformationAndAnOrderReference'] = "Eenmaal bevestigd, ontvangt u een e-mail met de bankgegevens en een orderreferentie.";
-$strings['SubscriptionToCourseXSuccessful'] = "Uw aankoop op \"%s\" werd met succes afgerond.";
-$strings['OrderCanceled'] = "Order geannuleerd";
-$strings['OrderStatus'] = "Bestelstatus";
-$strings['PayoutStatus'] = "Betalingsstatus";
-$strings['SearchByStatus'] = "Zoeken op status";
-$strings['OrderReference'] = "Bestelreferentie";
-$strings['OrderDate'] = "Besteldatum";
-$strings['OrderPrice'] = "Bestel prijs";
-$strings['ProductType'] = "Artikel type";
-$strings['SubscribeUser'] = "Onderteken gebruiker";
-$strings['DeleteOrder'] = "Verwijder bestelling";
-$strings['ErrorContactPlatformAdmin'] = "Onbekende fout. Neem contact op met het platform administrator.";
-$strings['PendingReasonByAddress'] = "in afwachting. Je hebt een bevestigde verzendadres niet in te voeren.";
-$strings['PendingReasonByAuthorization'] = "in afwachting. We hebben nog geen betalingen.";
-$strings['PendingReasonByEcheck'] = "in afwachting. De betaling is verricht door een eCheck die nog niet is vrijgemaakt";
-$strings['PendingReasonByIntl'] = "in afwachting.We hebben geen terugtrekking mechanisme voor betalingen.";
-$strings['PendingReasonByMulticurrency'] = "in afwachting. We hebben niet in evenwicht te brengen in de valuta verzonden.";
-$strings['PendingReasonByOrder'] = "in afwachting. Bestelling. We hebben nog geen betalingen.";
-$strings['PendingReasonByPaymentReview'] = "in afwachting. De betaling wordt beoordeeld door PayPal voor risico.";
-$strings['PendingReasonByRegulatoryReview'] = "in afwachting. De betaling wordt beoordeeld voor de naleving van regelgeving van de overheid.";
-$strings['PendingReasonByUnilateral'] = "in afwachting. Het e-mailadres is nog niet geregistreerd of bevestigd.";
-$strings['PendingReasonByUpgrade'] = "in afwachting. De betaling werd gedaan via credit card.";
-$strings['PendingReasonByVerify'] = "in afwachting. Sorry. We zijn nog niet in Paypal geverifieerd.";
-$strings['PendingReasonByOther'] = "in afwachting. Neem contact op met het platform admin.";
+
+declare(strict_types=1);
+$strings['plugin_title'] = 'Sell courses';
+$strings['plugin_comment'] = 'Sell courses directly through your Chamilo portal, using a PayPal account to receive funds. Neither the Chamilo association nor the developers involved could be considered responsible of any issue you might suffer using this plugin.';
+$strings['show_main_menu_tab'] = 'Show tab in hoofdmenu';
+$strings['show_main_menu_tab_help'] = 'In case of not wanting to show the tab, you can create this link in your Chamilo homepage : %s';
+$strings['public_main_menu_tab'] = 'Show tab in main menu aan anonyme gebruikers';
+$strings['include_sessions'] = 'Inclusief sessies';
+$strings['paypal_enable'] = 'Instellen van PayPal';
+$strings['commissions_enable'] = 'Instellen van Opdrachten';
+$strings['transfer_enable'] = 'Instellen van bankoverschrijving';
+$strings['unregistered_users_enable'] = 'Sta anonieme gebruikers toe';
+$strings['Free'] = 'FREE';
+$strings['PaypalPayoutCommissions'] = 'Paypal Uitbetaal Opdrachten';
+$strings['MyPayouts'] = 'Mijn Betalingsoverzicht';
+$strings['Commission'] = 'Commissie';
+$strings['Commissions'] = 'Commissies';
+$strings['SetCommissions'] = 'Set commissies';
+$strings['CommissionsConfig'] = 'Configureren Commissies';
+$strings['PayoutReport'] = 'Uitbetalingen rapport';
+$strings['Stats'] = 'Statistieken';
+$strings['InfoCommissions'] = 'Vul hier de omzet commissie als een percentage(% ) , de organisatie die het platform controleert. Deze percentage wordt in mindering gebracht op de door docenten ontvangen bedrag voor elke cursus of sessie dat verkocht is.';
+$strings['NeedToSelectPaymentType'] = 'Hier u betalings type selecteren';
+$strings['IndividualPayout'] = 'Individuele uitbetalingen';
+$strings['CancelPayout'] = 'Annuleer Uitbetalingen';
+$strings['ContinuePayout'] = 'Continue Uitbetalingen';
+$strings['ProceedPayout'] = 'Ga verder met de betaling';
+$strings['TheActualPlatformCommissionIsX'] = 'De huidige platform commissie %s . Deze percentage zal invermindering gebracht worden van de totale prijs van het product. Het verschil in het bedrag zal aan de volgende commissies toegepast worden.';
+$strings['CoursesInSessionsDoesntDisplayHere'] = 'De cursussen die binnen een training zitten worden niet weergegeven in de lijst van de cursussen als afzonderlijke producten.';
+$strings['WantToSellCourses'] = 'Wilt u leren en wat geld verdienen met uw eigen cursussen? Deze lijst kan worden gevuld met de verkoop van uw cursussen via dit platform. Neem contact op met ons.';
+$strings['SelectOptionToProceed'] = 'Selecteer de optie om verder te gaan';
+$strings['VerifyTotalAmountToProceedPayout'] = 'Controleer het totale bedrag voor over te gaan tot de betaling van commissies. Dit bedrag heeft geen extra kosten voor PayPal rekening houder. De cursussen verkopen die niet meetellen met een Paypal-account voor de begunstigden niet in aanmerking genomen.';
+$strings['TotalAcounts'] = 'Totaal van de rekeningen:';
+$strings['TotalPayout'] = 'Totaal te betalen:';
+$strings['PayoutDate'] = 'Betaaldatum:';
+$strings['CautionThisProcessCantBeCanceled'] = 'Let op:Dit proces kan een paar minuten duren en kan niet worden geannuleerd.';
+$strings['ProcessingPayoutsDontCloseThisWindow'] = 'Verder gaan met betalingen. Dit venster niet sluiten totdat dit proces is afgerond.';
+$strings['PayoutSuccess'] = 'Betalingen met succes verwerkt';
+$strings['Buyer'] = 'Koper';
+$strings['BankTransfer'] = 'Bankoverschrijving';
+$strings['SaleInfo'] = 'Verkoop Informatie';
+$strings['SaleStatusPending'] = 'Verkoop in behandeling';
+$strings['SaleStatusCanceled'] = 'Verkoop geannuleerd';
+$strings['SaleStatusCompleted'] = 'verkoop afgerond';
+$strings['PayoutStatusPending'] = 'Betaling in behandeling';
+$strings['PayoutStatusCanceled'] = 'Betaling geannuleerd';
+$strings['PayoutStatusCompleted'] = 'Betaling afgerond';
+$strings['PayoutsTotalPending'] = 'Onafgehandelde betalingen:';
+$strings['PayoutsTotalCanceled'] = 'Geannuleerde betalingen:';
+$strings['PayoutsTotalCompleted'] = 'Afgeronde betalingen:';
+$strings['TotalAmount'] = 'Totaalbedrag:';
+$strings['CourseListOnSale'] = 'Lijst van cursussen in verkoop';
+$strings['AvailableCourses'] = 'Beschikbare Cursussen';
+$strings['Price'] = 'Prijs';
+$strings['SearchFilter'] = 'Zoekmachine';
+$strings['MinimumPrice'] = 'Minimuum prijs';
+$strings['MaximumPrice'] = 'Maximuumm prijs';
+$strings['AvailableCoursesConfiguration'] = 'Beschikbare cursussen overzicht';
+$strings['PaymentsConfiguration'] = 'Betalingsoverzicht';
+$strings['TheUserIsAlreadyRegisteredInTheCourse'] = 'Je bent geregistreerd voor de cursus.';
+$strings['SeeDescription'] = 'Omschrijving';
+$strings['Buy'] = 'Koop / inschrijven';
+$strings['WaitingToReceiveThePayment'] = 'In afwachting van uw betaling';
+$strings['TheUserIsAlreadyRegisteredInTheSession'] = 'Je bent geregistreerd voor de sessie';
+$strings['ItemNotSaved'] = 'Item niet opgeslagen';
+$strings['TitlePlugin'] = 'Alles wat je nodig hebt om online cursussen te onderwijzen en te verkopen';
+$strings['PluginPresentation'] = 'The BuyCourses Plugin gives you the means to sell your courses or sessions and teach online, through only a few simple steps and settings. What are you waiting for? Start selling courses through Chamilo LMS!';
+$strings['Instructions'] = 'Instructies';
+$strings['InstructionsStepOne'] = 'Maak een cursus of een sessie op het platform.';
+$strings['InstructionsStepTwo'] = 'In de betaling , stelt de valuta waarmee u wilt uw cursussen of sessies te verkopen.';
+$strings['InstructionsStepThree'] = 'Overzicht van cursussen om te verkopen in de Cursussen en prijzen Instellingen.';
+$strings['BuyCourses'] = 'Cursussen Kopen';
+$strings['ConfigurationOfCoursesAndPrices'] = 'Cursussen en Prijzen overzicht';
+$strings['SalesReport'] = 'Verkoopcijfers';
+$strings['UserInformation'] = 'Gegevens van de koper';
+$strings['PaymentMethods'] = 'Betaal methodes';
+$strings['ConfirmOrder'] = 'Bevestig bestelling';
+$strings['PurchaseData'] = 'Aankoopgegevens';
+$strings['bc_subject'] = 'Bevestiging cursus order';
+$strings['PurchaseStatusX'] = 'Aankoop status: %s';
+$strings['PendingReasonByTransfer'] = ' In afwachting . In afwachting van de overdracht bevestiging';
+$strings['CancelOrder'] = 'Annuleer order';
+$strings['BankAccountInformation'] = 'Bankgegevens';
+$strings['BankAccount'] = 'Bankrekening';
+$strings['OnceItIsConfirmedYouWillReceiveAnEmailWithTheBankInformationAndAnOrderReference'] = 'Eenmaal bevestigd, ontvangt u een e-mail met de bankgegevens en een orderreferentie.';
+$strings['SubscriptionToCourseXSuccessful'] = 'Uw aankoop op "%s" werd met succes afgerond.';
+$strings['OrderCanceled'] = 'Order geannuleerd';
+$strings['OrderStatus'] = 'Bestelstatus';
+$strings['PayoutStatus'] = 'Betalingsstatus';
+$strings['SearchByStatus'] = 'Zoeken op status';
+$strings['OrderReference'] = 'Bestelreferentie';
+$strings['OrderDate'] = 'Besteldatum';
+$strings['OrderPrice'] = 'Bestel prijs';
+$strings['ProductType'] = 'Artikel type';
+$strings['SubscribeUser'] = 'Onderteken gebruiker';
+$strings['DeleteOrder'] = 'Verwijder bestelling';
+$strings['ErrorContactPlatformAdmin'] = 'Onbekende fout. Neem contact op met het platform administrator.';
+$strings['PendingReasonByAddress'] = 'in afwachting. Je hebt een bevestigde verzendadres niet in te voeren.';
+$strings['PendingReasonByAuthorization'] = 'in afwachting. We hebben nog geen betalingen.';
+$strings['PendingReasonByEcheck'] = 'in afwachting. De betaling is verricht door een eCheck die nog niet is vrijgemaakt';
+$strings['PendingReasonByIntl'] = 'in afwachting.We hebben geen terugtrekking mechanisme voor betalingen.';
+$strings['PendingReasonByMulticurrency'] = 'in afwachting. We hebben niet in evenwicht te brengen in de valuta verzonden.';
+$strings['PendingReasonByOrder'] = 'in afwachting. Bestelling. We hebben nog geen betalingen.';
+$strings['PendingReasonByPaymentReview'] = 'in afwachting. De betaling wordt beoordeeld door PayPal voor risico.';
+$strings['PendingReasonByRegulatoryReview'] = 'in afwachting. De betaling wordt beoordeeld voor de naleving van regelgeving van de overheid.';
+$strings['PendingReasonByUnilateral'] = 'in afwachting. Het e-mailadres is nog niet geregistreerd of bevestigd.';
+$strings['PendingReasonByUpgrade'] = 'in afwachting. De betaling werd gedaan via credit card.';
+$strings['PendingReasonByVerify'] = 'in afwachting. Sorry. We zijn nog niet in Paypal geverifieerd.';
+$strings['PendingReasonByOther'] = 'in afwachting. Neem contact op met het platform admin.';
$strings['PayPalPaymentOKPleaseConfirm'] = "PayPal rapporteert de transactie nu worden gestart. Om te erkennen dat u op OK om verder te gaan, klikt u op de knop bevestiging hieronder. Eenmaal geklikt, wordt u ingeschreven voor de cursus en het geld zal naar onze winkel worden overgedragen van uw PayPal-rekening. U kunt altijd toegang tot uw cursussen via het tabblad 'Mijn cursussen'. Dank u voor uw aankoop";
-$strings['Sandbox'] = "Test omgeving";
-$strings['PayPalAccount'] = "Paypal rekening";
-$strings['NoPayPalAccountDetected'] = "Geen Paypal account gedetecteerd";
-$strings['PayPalConfig'] = "PayPal bevestiging:";
-$strings['TransfersConfig'] = "Bank overschrijving bevestiging:";
-$strings['PluginInstruction'] = "U kunt de optie in- of uitschakelen om te betalen via PayPal of overschrijving instellen in de configuratie sectie van de plugin.";
-$strings['ClickHere'] = "Click here voor meer details";
-$strings['CurrencyType'] = "Valuta type";
-$strings['InfoCurrency'] = "Stel in de valuta voor de betaling van uw cursussen.";
-$strings['ApiUsername'] = "API Gebruikersnaam";
-$strings['ApiPassword'] = "API Paswoord";
-$strings['ApiSignature'] = "API Handtekening";
-$strings['InfoApiCredentials'] = "To generate your API credentials to integrate Chamilo with your PayPal account, you must follow the following steps";
-$strings['InfoApiStepOne'] = "Ga naar je PayPal-account, Overzicht en verkoper voorkeuren in het Verkoop Tools menu (als je niet dit menu-item hebt, om spullen te verkopen moet u eerst via PayPal om de toestemming te krijgen ).";
-$strings['InfoApiStepTwo'] = "In paragraaf API-toegang , klikt u op Bijwerken ";
-$strings['InfoApiStepThree'] = "In optie 2 (API Request referenties aan uw eigen API gebruikersnaam en wachtwoord), klikt u op de Bekijk API Handtekening , en kopieer de getoonde rechtsaf de Cursusshop plugin vorm referenties";
-$strings['ErrorOccurred'] = " Er is een fout opgetreden . Code:% s. Bericht:% s. Neem contact op met naar platform admin";
-$strings['VisibleInCatalog'] = "Zichtbaar in catalogus";
-$strings['Beneficiaries'] = "begunstigden";
-$strings['AvailableCourse'] = "beschikbare cursus";
-$strings['ShowOnCourseCatalog'] = "Toon op de cursusoverzicht";
-$strings['ByStatus'] = "Door de status";
-$strings['ByUser'] = "Door de gebruiker";
-$strings['PaymentMethod'] = "Betaal methodes";
-$strings['SWIFT'] = "SWIFT code";
-$strings['SWIFT_help'] = "Standaardformaat van Bank Identifier Codes (BIC) en dient als een unieke identificatiecode voor een bank of financiële instelling";
+$strings['Sandbox'] = 'Test omgeving';
+$strings['PayPalAccount'] = 'Paypal rekening';
+$strings['NoPayPalAccountDetected'] = 'Geen Paypal account gedetecteerd';
+$strings['PayPalConfig'] = 'PayPal bevestiging:';
+$strings['TransfersConfig'] = 'Bank overschrijving bevestiging:';
+$strings['PluginInstruction'] = 'U kunt de optie in- of uitschakelen om te betalen via PayPal of overschrijving instellen in de configuratie sectie van de plugin.';
+$strings['ClickHere'] = 'Click here voor meer details';
+$strings['CurrencyType'] = 'Valuta type';
+$strings['InfoCurrency'] = 'Stel in de valuta voor de betaling van uw cursussen.';
+$strings['ApiUsername'] = 'API Gebruikersnaam';
+$strings['ApiPassword'] = 'API Paswoord';
+$strings['ApiSignature'] = 'API Handtekening';
+$strings['InfoApiCredentials'] = 'To generate your API credentials to integrate Chamilo with your PayPal account, you must follow the following steps';
+$strings['InfoApiStepOne'] = 'Ga naar je PayPal-account, Overzicht en verkoper voorkeuren in het Verkoop Tools menu (als je niet dit menu-item hebt, om spullen te verkopen moet u eerst via PayPal om de toestemming te krijgen ).';
+$strings['InfoApiStepTwo'] = 'In paragraaf API-toegang , klikt u op Bijwerken ';
+$strings['InfoApiStepThree'] = 'In optie 2 (API Request referenties aan uw eigen API gebruikersnaam en wachtwoord), klikt u op de Bekijk API Handtekening , en kopieer de getoonde rechtsaf de Cursusshop plugin vorm referenties';
+$strings['ErrorOccurred'] = ' Er is een fout opgetreden . Code:% s. Bericht:% s. Neem contact op met naar platform admin';
+$strings['VisibleInCatalog'] = 'Zichtbaar in catalogus';
+$strings['Beneficiaries'] = 'begunstigden';
+$strings['AvailableCourse'] = 'beschikbare cursus';
+$strings['ShowOnCourseCatalog'] = 'Toon op de cursusoverzicht';
+$strings['ByStatus'] = 'Door de status';
+$strings['ByUser'] = 'Door de gebruiker';
+$strings['PaymentMethod'] = 'Betaal methodes';
+$strings['SWIFT'] = 'SWIFT code';
+$strings['SWIFT_help'] = 'Standaardformaat van Bank Identifier Codes (BIC) en dient als een unieke identificatiecode voor een bank of financiële instelling';
diff --git a/public/plugin/BuyCourses/lang/english.php b/public/plugin/BuyCourses/lang/english.php
index cf04d491b3a..cdbd3edc452 100644
--- a/public/plugin/BuyCourses/lang/english.php
+++ b/public/plugin/BuyCourses/lang/english.php
@@ -1,195 +1,323 @@
%s . This percentage will be discounted from the total product price. The difference will be the amount to apply the following commissions.";
+
+declare(strict_types=1);
+$strings['plugin_title'] = 'Sell courses';
+$strings['plugin_comment'] = 'Sell courses directly through your Chamilo portal, using a PayPal account to receive funds. Neither the Chamilo association nor the developers involved could be considered responsible of any issue you might suffer using this plugin.';
+$strings['show_main_menu_tab'] = 'Show tab in main menu';
+$strings['show_main_menu_tab_help'] = 'In case of not wanting to show the tab, you can create this link in your Chamilo homepage : %s';
+$strings['public_main_menu_tab'] = 'Show tab in main menu to anonymous users too';
+$strings['include_sessions'] = 'Include sessions';
+$strings['paypal_enable'] = 'Enable PayPal';
+$strings['commissions_enable'] = 'Enable Commissions';
+$strings['transfer_enable'] = 'Enable bank transfer';
+$strings['unregistered_users_enable'] = 'Allow anonymous users';
+$strings['invoicing_enable'] = 'Enable Invoicing';
+$strings['tax_enable'] = 'Enable Taxation';
+$strings['Free'] = 'FREE';
+$strings['PaypalPayoutCommissions'] = 'Paypal Payout Commissions';
+$strings['MyPayouts'] = 'My payments';
+$strings['Commission'] = 'Commission';
+$strings['Commissions'] = 'Commissions';
+$strings['SetCommissions'] = 'Set commissions';
+$strings['CommissionsConfig'] = 'Configure Commissions';
+$strings['PayoutReport'] = 'Payouts report';
+$strings['Stats'] = 'Statistics';
+$strings['InfoCommissions'] = 'Enter here the sales commission as a percentage (% ) , the organization that controls the platform. This percentage is deducted from the amount received by teachers for each course or Session sold on the platform.';
+$strings['NeedToSelectPaymentType'] = 'Need to select payment type';
+$strings['IndividualPayout'] = 'Individual payout';
+$strings['CancelPayout'] = 'Cancel payout';
+$strings['ContinuePayout'] = 'Continue Payout';
+$strings['ProceedPayout'] = 'Proceed with payment';
+$strings['TheActualPlatformCommissionIsX'] = 'The current platform commission is %s . This percentage will be discounted from the total product price. The difference will be the amount to apply the following commissions.';
$strings['CoursesInSessionsDoesntDisplayHere'] = "The courses which are inside a training session don't appear in the list of courses to configure as individual products.";
-$strings['WantToSellCourses'] = "Do you want to teach and earn some money with your own courses? This list could be filled with your earnings selling courses through this platform. Get in touch with us.";
-$strings['SelectOptionToProceed'] = "Select option to proceed";
+$strings['WantToSellCourses'] = 'Do you want to teach and earn some money with your own courses? This list could be filled with your earnings selling courses through this platform. Get in touch with us.';
+$strings['SelectOptionToProceed'] = 'Select option to proceed';
$strings['VerifyTotalAmountToProceedPayout'] = "Please check the total amount to proceed with the payment of commissions. This amount doesn't take extra costs for PayPal into account. The courses sales that do not count with a Paypal account for the beneficiaries will not be considered.";
-$strings['TotalAcounts'] = "Total of accounts:";
-$strings['TotalPayout'] = "Total to be paid:";
-$strings['PayoutDate'] = "Payment date:";
-$strings['CautionThisProcessCantBeCanceled'] = "Caution: this process can take a few minutes and cannot be cancelled.";
+$strings['TotalAcounts'] = 'Total of accounts:';
+$strings['TotalPayout'] = 'Total to be paid:';
+$strings['PayoutDate'] = 'Payment date:';
+$strings['CautionThisProcessCantBeCanceled'] = 'Caution: this process can take a few minutes and cannot be cancelled.';
$strings['ProcessingPayoutsDontCloseThisWindow'] = "Proceeding with payments. Don't close this window until this process is finalized.";
-$strings['PayoutSuccess'] = "Payments processed successfully";
-$strings['Buyer'] = "Buyer";
-$strings['BankTransfer'] = "Bank transfer";
-$strings['SaleInfo'] = "Sale information";
-$strings['SaleStatusPending'] = "Sale pending";
-$strings['SaleStatusCanceled'] = "Sale canceled";
-$strings['SaleStatusCompleted'] = "Sale completed";
-$strings['PayoutStatusPending'] = "Payment pending";
-$strings['PayoutStatusCanceled'] = "Payment cancelled";
-$strings['PayoutStatusCompleted'] = "Payment completed";
-$strings['PayoutsTotalPending'] = "Pending payments:";
-$strings['PayoutsTotalCanceled'] = "Cancelled payments:";
-$strings['PayoutsTotalCompleted'] = "Completed payments:";
-$strings['Total'] = "Total";
-$strings['TotalAmount'] = "Total amount:";
-$strings['CourseListOnSale'] = "List of courses on sale";
-$strings['AvailableCourses'] = "Available Courses";
-$strings['Price'] = "Price";
-$strings['SearchFilter'] = "Search filter";
-$strings['MinimumPrice'] = "Minimum price";
-$strings['MaximumPrice'] = "Maximum price";
-$strings['AvailableCoursesConfiguration'] = "Available courses configuration";
-$strings['PaymentsConfiguration'] = "Payments configuration";
-$strings['TheUserIsAlreadyRegisteredInTheCourse'] = "You are already registered in the course.";
-$strings['SeeDescription'] = "Description";
-$strings['Buy'] = "Buy";
-$strings['WaitingToReceiveThePayment'] = "Currently pending payment";
-$strings['TheUserIsAlreadyRegisteredInTheSession'] = "You are already registered in the session";
-$strings['ItemNotSaved'] = "Item not saved";
-$strings['TitlePlugin'] = "Everything you need to teach and sell courses online";
-$strings['PluginPresentation'] = "The BuyCourses Plugin gives you the means to sell your courses or sessions and teach online, through only a few simple steps and settings. What are you waiting for? Start selling courses through Chamilo LMS!";
-$strings['Instructions'] = "Instructions";
-$strings['InstructionsStepOne'] = "Create a course or session on the platform.";
-$strings['InstructionsStepTwo'] = "In the payment settings, set the currency with which you would like to sell your courses or sessions.";
-$strings['InstructionsStepThree'] = "Configure courses to sell in the Courses and prices settings.";
-$strings['BuyCourses'] = "Buy courses";
-$strings['ConfigurationOfCoursesAndPrices'] = "Courses and prices configuration";
-$strings['SalesReport'] = "Sales report";
+$strings['PayoutSuccess'] = 'Payments processed successfully';
+$strings['Buyer'] = 'Buyer';
+$strings['BankTransfer'] = 'Bank transfer';
+$strings['SaleInfo'] = 'Sale information';
+$strings['SaleStatusPending'] = 'Sale pending';
+$strings['SaleStatusCanceled'] = 'Sale canceled';
+$strings['SaleStatusCompleted'] = 'Sale completed';
+$strings['PayoutStatusPending'] = 'Payment pending';
+$strings['PayoutStatusCanceled'] = 'Payment cancelled';
+$strings['PayoutStatusCompleted'] = 'Payment completed';
+$strings['PayoutsTotalPending'] = 'Pending payments:';
+$strings['PayoutsTotalCanceled'] = 'Cancelled payments:';
+$strings['PayoutsTotalCompleted'] = 'Completed payments:';
+$strings['Total'] = 'Total';
+$strings['TotalAmount'] = 'Total amount:';
+$strings['CourseListOnSale'] = 'List of courses on sale';
+$strings['AvailableCourses'] = 'Available Courses';
+$strings['Price'] = 'Price';
+$strings['SearchFilter'] = 'Search filter';
+$strings['MinimumPrice'] = 'Minimum price';
+$strings['MaximumPrice'] = 'Maximum price';
+$strings['AvailableCoursesConfiguration'] = 'Available courses configuration';
+$strings['PaymentsConfiguration'] = 'Payments configuration';
+$strings['TheUserIsAlreadyRegisteredInTheCourse'] = 'You are already registered in the course.';
+$strings['SeeDescription'] = 'Description';
+$strings['Buy'] = 'Buy';
+$strings['WaitingToReceiveThePayment'] = 'Currently pending payment';
+$strings['TheUserIsAlreadyRegisteredInTheSession'] = 'You are already registered in the session';
+$strings['ItemNotSaved'] = 'Item not saved';
+$strings['TitlePlugin'] = 'Everything you need to teach and sell courses online';
+$strings['PluginPresentation'] = 'The BuyCourses Plugin gives you the means to sell your courses or sessions and teach online, through only a few simple steps and settings. What are you waiting for? Start selling courses through Chamilo LMS!';
+$strings['Instructions'] = 'Instructions';
+$strings['InstructionsStepOne'] = 'Create a course or session on the platform.';
+$strings['InstructionsStepTwo'] = 'In the payment settings, set the currency with which you would like to sell your courses or sessions.';
+$strings['InstructionsStepThree'] = 'Configure courses to sell in the Courses and prices settings.';
+$strings['BuyCourses'] = 'Buy courses';
+$strings['ConfigurationOfCoursesAndPrices'] = 'Courses and prices configuration';
+$strings['SalesReport'] = 'Sales report';
$strings['UserInformation'] = "Buyer's details";
-$strings['PaymentMethods'] = "Payment methods";
-$strings['ConfirmOrder'] = "Confirm order";
-$strings['PurchaseData'] = "Purchase data";
-$strings['bc_subject'] = "Confirmation of course order";
-$strings['PurchaseStatusX'] = "Purchase status: %s";
-$strings['PendingReasonByTransfer'] = "Pending. Awaiting for transfer confirmation";
-$strings['CancelOrder'] = "Cancel order";
-$strings['BankAccountInformation'] = "Bank account details";
-$strings['BankAccount'] = "Bank account";
-$strings['OnceItIsConfirmedYouWillReceiveAnEmailWithTheBankInformationAndAnOrderReference'] = "Once confirmed, you will receive an e-mail with the bank details and an order reference.";
-$strings['SubscriptionToCourseXSuccessful'] = "Your subscription to \"%s\" was completed successfully.";
-$strings['OrderCanceled'] = "Order canceled";
-$strings['OrderStatus'] = "Order status";
-$strings['PayoutStatus'] = "Payment status";
-$strings['SearchByStatus'] = "Search by status";
-$strings['OrderReference'] = "Order reference";
-$strings['OrderDate'] = "Order date";
-$strings['OrderPrice'] = "Order price";
-$strings['ProductType'] = "Product type";
-$strings['SubscribeUser'] = "Subscribe user";
-$strings['DeleteOrder'] = "Delete order";
-$strings['ErrorContactPlatformAdmin'] = "Unknown error. Please contact the platform administrator.";
-$strings['PendingReasonByAddress'] = "Pending. You did not enter a confirmed shipping address.";
-$strings['PendingReasonByAuthorization'] = "Pending. We have not yet captured funds.";
-$strings['PendingReasonByEcheck'] = "Pending. The payment was made by an eCheck that has not yet cleared";
-$strings['PendingReasonByIntl'] = "Pending. We have no a withdrawal mechanism for funds.";
-$strings['PendingReasonByMulticurrency'] = "Pending. We have not balance in the currency sent.";
-$strings['PendingReasonByOrder'] = "Pending. Order made. We have not yet captured funds.";
-$strings['PendingReasonByPaymentReview'] = "Pending. The payment is being reviewed by PayPal for risk.";
-$strings['PendingReasonByRegulatoryReview'] = "Pending. The payment is being reviewed for compliance with government regulations.";
-$strings['PendingReasonByUnilateral'] = "Pending. The email address is not yet registered o confirmed.";
-$strings['PendingReasonByUpgrade'] = "Pending. The payment was made via credit card.";
-$strings['PendingReasonByVerify'] = "Pending. Sorry. We are not yet verified in PayPal.";
-$strings['PendingReasonByOther'] = "Pending. Please contact with the platform admin.";
+$strings['PaymentMethods'] = 'Payment methods';
+$strings['ConfirmOrder'] = 'Confirm order';
+$strings['PurchaseData'] = 'Purchase data';
+$strings['bc_subject'] = 'Confirmation of course order';
+$strings['PurchaseStatusX'] = 'Purchase status: %s';
+$strings['PendingReasonByTransfer'] = 'Pending. Awaiting for transfer confirmation';
+$strings['CancelOrder'] = 'Cancel order';
+$strings['BankAccountInformation'] = 'Bank account details';
+$strings['BankAccount'] = 'Bank account';
+$strings['OnceItIsConfirmedYouWillReceiveAnEmailWithTheBankInformationAndAnOrderReference'] = 'Once confirmed, you will receive an e-mail with the bank details and an order reference.';
+$strings['SubscriptionToCourseXSuccessful'] = 'Completed process. Your subscription to "%s" was completed successfully.';
+$strings['OrderCanceled'] = 'Order canceled';
+$strings['OrderStatus'] = 'Order status';
+$strings['PayoutStatus'] = 'Payment status';
+$strings['SearchByStatus'] = 'Search by status';
+$strings['OrderReference'] = 'Order reference';
+$strings['OrderDate'] = 'Order date';
+$strings['OrderPrice'] = 'Order price';
+$strings['ProductType'] = 'Product type';
+$strings['SubscribeUser'] = 'Subscribe user';
+$strings['DeleteOrder'] = 'Delete order';
+$strings['ErrorContactPlatformAdmin'] = 'Unknown error. Please contact the platform administrator.';
+$strings['PendingReasonByAddress'] = 'Pending. You did not enter a confirmed shipping address.';
+$strings['PendingReasonByAuthorization'] = 'Pending. We have not yet captured funds.';
+$strings['PendingReasonByEcheck'] = 'Pending. The payment was made by an eCheck that has not yet cleared';
+$strings['PendingReasonByIntl'] = 'Pending. We have no a withdrawal mechanism for funds.';
+$strings['PendingReasonByMulticurrency'] = 'Pending. We have not balance in the currency sent.';
+$strings['PendingReasonByOrder'] = 'Pending. Order made. We have not yet captured funds.';
+$strings['PendingReasonByPaymentReview'] = 'Pending. The payment is being reviewed by PayPal for risk.';
+$strings['PendingReasonByRegulatoryReview'] = 'Pending. The payment is being reviewed for compliance with government regulations.';
+$strings['PendingReasonByUnilateral'] = 'Pending. The email address is not yet registered o confirmed.';
+$strings['PendingReasonByUpgrade'] = 'Pending. The payment was made via credit card.';
+$strings['PendingReasonByVerify'] = 'Pending. Sorry. We are not yet verified in PayPal.';
+$strings['PendingReasonByOther'] = 'Pending. Please contact with the platform admin.';
$strings['PayPalPaymentOKPleaseConfirm'] = "PayPal reports the transaction is ready to be executed. To acknowledge that you are OK to proceed, please click the confirmation button below. Once clicked, you will be registered to the course and the funds will be transferred from your PayPal account to our shop. You can always access your courses through the 'My courses' tab. Thank you for your custom!";
-$strings['Sandbox'] = "Test environment";
-$strings['PayPalAccount'] = "Paypal account";
-$strings['NoPayPalAccountDetected'] = "No Paypal account detected";
-$strings['PayPalConfig'] = "PayPal configuration:";
-$strings['TransfersConfig'] = "Bank transfers configuration:";
-$strings['PluginInstruction'] = "You can enable or disable the option to pay via PayPal, Culqi or bank transfer settings in the configuration section of the plugin.";
-$strings['ClickHere'] = "Click here for more details";
-$strings['CurrencyType'] = "Currency type";
-$strings['InfoCurrency'] = "Sets the currency for the payment of your courses.";
-$strings['ApiUsername'] = "API Username";
-$strings['ApiPassword'] = "API Password";
-$strings['ApiSignature'] = "API Signature";
-$strings['InfoApiCredentials'] = "To generate your API credentials to integrate Chamilo with your PayPal account, you must follow the following steps";
-$strings['InfoApiStepOne'] = "Go to your PayPal account, Summary, then Seller preferences in the Selling Tools menu (if you do not have this menu entry, you might need to get the authorization to sell stuff through PayPal first).";
-$strings['InfoApiStepTwo'] = "In paragraph API access, click Update";
-$strings['InfoApiStepThree'] = "In Option 2 (Request API credentials to create your own API username and password), click the View API Signature link, and copy the credentials shown right into the BuyCourses plugin form";
-$strings['ErrorOccurred'] = "An error ocurred. Code: %s. Message: %s. Please contact to platform admin";
-$strings['VisibleInCatalog'] = "Visible in catalog";
-$strings['Beneficiaries'] = "Beneficiaries";
-$strings['AvailableCourse'] = "Available course";
-$strings['ShowOnCourseCatalog'] = "Show on course catalog";
-$strings['ByStatus'] = "By status";
-$strings['ByUser'] = "By user";
-$strings['ByEmail'] = "By email";
-$strings['PaymentMethod'] = "Payment method";
-$strings['SWIFT'] = "SWIFT code";
-$strings['SWIFT_help'] = "Standard format of Bank Identifier Codes (BIC) and serves as a unique identifier for a bank or financial institution";
-$strings['PleaseSelectThePaymentMethodBeforeConfirmYourOrder'] = "Please select your favorite payment method before confirming your order";
+$strings['Sandbox'] = 'Test environment';
+$strings['PayPalAccount'] = 'Paypal account';
+$strings['NoPayPalAccountDetected'] = 'No Paypal account detected';
+$strings['PayPalConfig'] = 'PayPal configuration:';
+$strings['TransfersConfig'] = 'Bank transfers configuration:';
+$strings['PluginInstruction'] = 'You can enable or disable the option to pay via PayPal, Culqi or bank transfer settings in the configuration section of the plugin.';
+$strings['ClickHere'] = 'Click here for more details';
+$strings['CurrencyType'] = 'Currency type';
+$strings['InfoCurrency'] = 'Sets the currency for the payment of your courses.';
+$strings['ApiUsername'] = 'API Username';
+$strings['ApiPassword'] = 'API Password';
+$strings['ApiSignature'] = 'API Signature';
+$strings['InfoApiCredentials'] = 'To generate your API credentials to integrate Chamilo with your PayPal account, you must follow the following steps';
+$strings['InfoApiStepOne'] = 'Go to your PayPal account, Summary, then Seller preferences in the Selling Tools menu (if you do not have this menu entry, you might need to get the authorization to sell stuff through PayPal first).';
+$strings['InfoApiStepTwo'] = 'In paragraph API access, click Update';
+$strings['InfoApiStepThree'] = 'In Option 2 (Request API credentials to create your own API username and password), click the View API Signature link, and copy the credentials shown right into the BuyCourses plugin form';
+$strings['ErrorOccurred'] = 'An error ocurred. Code: %s. Message: %s. Please contact to platform admin';
+$strings['VisibleInCatalog'] = 'Visible in catalog';
+$strings['Beneficiaries'] = 'Beneficiaries';
+$strings['AvailableCourse'] = 'Available course';
+$strings['ShowOnCourseCatalog'] = 'Show on course catalog';
+$strings['ByStatus'] = 'By status';
+$strings['ByUser'] = 'By user';
+$strings['ByEmail'] = 'By email';
+$strings['PaymentMethod'] = 'Payment method';
+$strings['SWIFT'] = 'SWIFT code';
+$strings['SWIFT_help'] = 'Standard format of Bank Identifier Codes (BIC) and serves as a unique identifier for a bank or financial institution';
+$strings['PleaseSelectThePaymentMethodBeforeConfirmYourOrder'] = 'Please select your favorite payment method before confirming your order';
$strings['NoPaymentOptionAvailable'] = 'No payment option available. Please report to the administrator.';
$strings['XIsOnlyPaymentMethodAvailable'] = '%s is the only payment method available for this purchase.';
$strings['hide_free_text'] = "Hide 'Free' text";
-$strings['culqi_enable'] = "Enable culqi";
-$strings['include_services'] = "Include services";
-$strings['CurrencyIsNotConfigured'] = "Please, configure a currency before continuing.";
-$strings['Services'] = "Services";
-$strings['ServiceName'] = "Service name";
-$strings['AppliesTo'] = "Applies to";
-$strings['ListOfServicesOnSale'] = "List of services on sale";
-$strings['GlobalConfig'] = "Global configuration";
-$strings['WriteHereTheTermsAndConditionsOfYourECommerce'] = "Write here the terms and conditions of your e-commerce";
-$strings['NewService'] = "New service";
-$strings['Service'] = "Service";
-$strings['ServiceInformation'] = "Service information";
-$strings['EditService'] = "Edit service";
-$strings['DeleteThisService'] = "Delete this service";
-$strings['IConfirmIReadAndAcceptTermsAndCondition'] = "I confirm I read and accept the terms and conditions";
-$strings['PleaseSelectTheCorrectInfoToApplyTheService'] = "Please select the correct info to apply the service";
-$strings['SaleStatusCancelled'] = "Sale cancelled";
-$strings['ServiceSaleInfo'] = "Service sale info";
-$strings['ServiceId'] = "Service Id";
-$strings['BoughtBy'] = "Bought by";
-$strings['PurchaserUser'] = "Purchaser user";
-$strings['Pending'] = "Pending";
-$strings['Names'] = "Names";
-$strings['SellerName'] = "Seller name";
-$strings['SellerId'] = "Seller id";
-$strings['SellerAddress'] = "Seller address";
-$strings['SellerEmail'] = "Seller e-mail";
-$strings['NextNumberInvoice'] = "Next invoice number";
-$strings['NextNumberInvoiceDescription'] = "Number of the following invoice";
-$strings['InvoiceSeries'] = "Invoice series";
-$strings['InvoiceSeriesDescription'] = "Optional parameter: Example invoice Id <series><year>/<number>";
-$strings['InvoiceView'] = "View invoice";
-$strings['NoInvoiceEnable'] = "No invoicing block enable";
-$strings['Company'] = "Company";
-$strings['VAT'] = "VAT";
-$strings['Address'] = "Address";
-$strings['InvoiceNumber'] = "Invoice number";
-$strings['InvoiceDate'] = "Invoice date";
-$strings['Invoice'] = "Invoice";
-$strings['SaleEmail'] = "Sales e-mail";
-$strings['PurchaseDetailsIntro'] = "Purchase details";
-$strings['PurchaseDetailsEnd'] = "Regards";
-$strings['ProductName'] = "Product name";
-$strings['BankAccountIntro'] = "Bank Account Info";
+$strings['culqi_enable'] = 'Enable culqi';
+$strings['include_services'] = 'Include services';
+$strings['CurrencyIsNotConfigured'] = 'Please, configure a currency before continuing.';
+$strings['Services'] = 'Services';
+$strings['Service'] = 'Service';
+$strings['NewService'] = 'New service';
+$strings['ServiceName'] = 'Service name';
+$strings['AppliesTo'] = 'Applies to';
+$strings['ServiceInformation'] = 'Service information';
+$strings['ListOfServicesOnSale'] = 'List of services on sale';
+$strings['GlobalConfig'] = 'Global configuration';
+$strings['WriteHereTheTermsAndConditionsOfYourECommerce'] = 'Write here the terms and conditions of your e-commerce';
+$strings['EditService'] = 'Edit service';
+$strings['DeleteThisService'] = 'Delete this service';
+$strings['IConfirmIReadAndAcceptTermsAndCondition'] = 'I confirm I read and accept the terms and conditions';
+$strings['PleaseSelectTheCorrectInfoToApplyTheService'] = 'Please select the correct info to apply the service';
+$strings['SaleStatusCancelled'] = 'Sale cancelled';
+$strings['ServiceSaleInfo'] = 'Service sale info';
+$strings['ServiceId'] = 'Service Id';
+$strings['BoughtBy'] = 'Bought by';
+$strings['PurchaserUser'] = 'Purchaser user';
+$strings['Pending'] = 'Pending';
+$strings['Names'] = 'Names';
+$strings['SellerName'] = 'Seller name';
+$strings['SellerId'] = 'Seller id';
+$strings['SellerAddress'] = 'Seller address';
+$strings['SellerEmail'] = 'Seller e-mail';
+$strings['NextNumberInvoice'] = 'Next invoice number';
+$strings['NextNumberInvoiceDescription'] = 'Number of the following invoice';
+$strings['InvoiceSeries'] = 'Invoice series';
+$strings['InvoiceSeriesDescription'] = 'Optional parameter: Example invoice Id <series><year>/<number>';
+$strings['InvoiceView'] = 'View invoice';
+$strings['NoInvoiceEnable'] = 'No invoicing block enable';
+$strings['Company'] = 'Company';
+$strings['VAT'] = 'VAT';
+$strings['Address'] = 'Address';
+$strings['InvoiceNumber'] = 'Invoice number';
+$strings['InvoiceDate'] = 'Invoice date';
+$strings['Invoice'] = 'Invoice';
+$strings['SaleEmail'] = 'Sales e-mail';
+$strings['PurchaseDetailsIntro'] = 'Purchase details';
+$strings['PurchaseDetailsEnd'] = 'Regards';
+$strings['ProductName'] = 'Product name';
+$strings['BankAccountIntro'] = 'Bank Account Info';
$strings['AdditionalInfoRequired'] = 'More information needed';
-$strings['SubscriptionToServiceXSuccessful'] = "Subscription to service %s completed.";
-$strings['ClickHereToFinish'] = "Click here to finish";
-$strings['OrderCancelled'] = "Order cancelled";
-$strings['use_currency_symbol'] = "Use currency symbol";
-$strings['ExportReport'] = "Export Sales Report";
-$strings['OrderTime'] = "Order time";
-$strings['SelectDateRange'] = "Select a start date and end date for the report";
+$strings['SubscriptionToServiceXSuccessful'] = 'Subscription to service %s completed.';
+$strings['ClickHereToFinish'] = 'Click here to finish';
+$strings['OrderCancelled'] = 'Order cancelled';
+$strings['use_currency_symbol'] = 'Use currency symbol';
+$strings['ExportReport'] = 'Export Sales Report';
+$strings['OrderTime'] = 'Order time';
+$strings['SelectDateRange'] = 'Select a start date and end date for the report';
+$strings['ServiceAdded'] = 'Service added';
+$strings['ServiceEdited'] = 'Service updated';
+$strings['ListOfServicesOnSale'] = 'List of services for sale';
+$strings['AdditionalInfo'] = 'Additional information';
+$strings['culqi_enable'] = 'Enable Culqi';
+$strings['CulqiConfig'] = 'Culqi configuration:';
+$strings['InfoCulqiCredentials'] = 'To obtain your credentials, you will need to create an account on Culqi and enter the development mode, copy the merchant code in your dashboard, then enter the API Keys section and copy the corresponding key to paste it here.';
+$strings['CommerceCode'] = 'Merchant code';
+$strings['NoTermsAndConditionsProvided'] = 'No defined terms and conditions';
+$strings['GlobalConfig'] = 'Global configuration:';
+$strings['MyServices'] = 'My services';
+$strings['SalePrice'] = 'Sale price';
+$strings['YouNeedToBeRegisteredInAtLeastOneCourse'] = 'You need to be registered in at least one course';
+$strings['YouNeedToBeRegisteredInAtLeastOneSession'] = 'You need to be registered in at least one session';
+$strings['IfYouWantToGetTheCertificateAndOrSkillsAsociatedToThisCourseYouNeedToBuyTheCertificateServiceYouCanGoToServiceCatalogClickingHere'] = "To obtain the certificate and/or the skills associated to this course, you need to buy the Certificate service. Go to the services catalogue to buy it by clicking here";
+$strings['ServiceDeleted'] = 'Service deleted';
+$strings['YourCoursesNeedAtLeastOneLearningPath'] = 'The courses to which you are subscribed need at least one learning path that contains a final certificate item';
+$strings['GlobalTaxPerc'] = 'Global tax rate';
+$strings['GlobalTaxPercDescription'] = 'Default tax rate that will be used unless there is a specific tax rate for the course, session or service.';
+$strings['TaxPerc'] = 'Tax rate';
+$strings['TaxPercDescription'] = 'If left blank, the global tax rate will be used.';
+$strings['ByDefault'] = 'by default (global value)';
+$strings['OnlyCourses'] = 'Only courses';
+$strings['OnlySessions'] = 'Only sessions';
+$strings['OnlyServices'] = 'Only services';
+$strings['TaxAppliesTo'] = 'Tax applied to';
+$strings['AllCoursesSessionsAndServices'] = 'All (courses, sessions and services)';
+$strings['TaxNameCustom'] = 'Tax name';
+$strings['TaxNameExamples'] = 'VAT, IVA, IGV, TVA, IV ...';
+$strings['ErrorUpdateFieldDB'] = 'Error updating the database fields';
+$strings['tpv_redsys_enable'] = 'Enable RedSys POS';
+$strings['tpv_redsys_enable_help'] = "In order to use the RedSys POS payment method, it is necessary to download the \"REST INTEGRATION - PHP API \" files at the following link web de RedSys and locate the file apiRedSys.php in the plugin/BuyCourses/resources directory.";
+$strings['NotFindRedsysFile'] = 'The apiRedsys.php file cannot be found in plugin/BuyCourses/resources directory';
+$strings['TpvPayment'] = 'POS payment';
+$strings['TpvRedsysConfig'] = 'Redsys POS configuration';
+$strings['DS_MERCHANT_MERCHANTCODE'] = 'Trade number (FUC)';
+$strings['DS_MERCHANT_TERMINAL'] = 'Terminal number';
+$strings['DS_MERCHANT_CURRENCY'] = 'Terminal currency';
+$strings['kc'] = 'Secret encryption key';
+$strings['url_redsys'] = 'Redsys connection URL';
+$strings['url_redsys_sandbox'] = 'Redsys connection URL (Sandbox)';
+$strings['InfoTpvRedsysApiCredentials'] = 'You must complete the following form fields with the information provided by the Redsys POS Technical Support:';
+$strings['InfoEmailExtra'] = 'Extra info in payment e-mail';
+$strings['Coupon'] = 'Coupon';
+$strings['DiscountAmount'] = 'Discount amount';
+$strings['RedeemCoupon'] = 'Redeem';
+$strings['NeedToAddCouponCode'] = 'A coupon code has not been entered';
+$strings['CouponNotValid'] = 'This coupon is not valid';
+$strings['CouponRedeemed'] = 'Coupon redeemed';
+$strings['CouponDiscount'] = 'Discount';
+$strings['CouponStatus'] = 'Coupon status';
+$strings['CouponPercentage'] = 'Percentage';
+$strings['CouponAmount'] = 'Amount';
+$strings['CouponList'] = 'Coupon list';
+$strings['CouponCode'] = 'Coupon code';
+$strings['CouponDiscountType'] = 'Discount type';
+$strings['CouponDateStart'] = 'Valid from';
+$strings['CouponDateEnd'] = 'Expires on';
+$strings['CouponDelivered'] = 'Delivered';
+$strings['CouponDisable'] = 'Disable';
+$strings['CouponEnable'] = 'Enable';
+$strings['CouponCodeUsed'] = 'Coupon code already used';
+$strings['CouponNoExists'] = 'Coupon no exists';
+$strings['CouponErrorInsert'] = 'Error inserting new coupon';
+$strings['CouponActive'] = 'Active';
+$strings['CouponDisabled'] = 'Disabled';
+$strings['CouponUpdate'] = 'Coupon updated';
+$strings['CouponsConfiguration'] = 'Coupons configuration';
+$strings['CouponAdd'] = 'New coupon';
+$strings['ConfigureCoupon'] = 'Configure coupon';
+$strings['DiscountCoupon'] = 'Discount coupons';
+$strings['CouponsCode'] = 'Code';
+$strings['DoYouHaveACoupon'] = 'Do you have a coupon?';
+$strings['stripe_enable'] = 'Enable Stripe';
+$strings['StripeConfig'] = 'Stripe configuration:';
+$strings['InfoStripeCredentials'] = 'To obtain the credentials you must first create an account in Stripe, copy the account id from your profile, go to the API Keys configuration section and copy the secret key, finally you must go to the Developers button (top right), register a new Endpoint in the Webhooks section, pointing to https://{site}/plugin/BuyCourses/src/stripe_response.php for the checkout.session.completed event type and copy the secret of the Endpoint.';
+$strings['StripeAccountId'] = 'Account id:';
+$strings['StripeSecret'] = 'Secret key:';
+$strings['StripeEndpointSecret'] = 'Endpoint secret:';
+$strings['PendingReasonByStripe'] = 'Pending. Awaiting for payment confirmation ...';
+$strings['cecabank_enable'] = 'Enable Cecabank POS';
+$strings['TpvCecabank'] = 'POS payment (Cecabank)';
+$strings['CecaSecret'] = 'Secret';
+$strings['CecaUrl'] = 'Url';
+$strings['CecaMerchanId'] = 'Merchant';
+$strings['CecaAcquirerId'] = 'Adquirer';
+$strings['CecaTerminalId'] = 'Terminal';
+$strings['CecaCypher'] = 'Cypher';
+$strings['CecaCurrency'] = 'Currency';
+$strings['CecaExponent'] = 'Exponent';
+$strings['CecaSupportedPayment'] = 'Payment supported';
+$strings['CecabankConfig'] = 'Cecabank configuration';
+$strings['Country'] = 'Country';
+$strings['PaymentType'] = 'Payment type';
+$strings['CountryRelPaymentConfig'] = 'Payment type configuration for the country';
+$strings['CountryRelPaymentMessage'] = 'To process an order, the type of payment per country must be defined, otherwise the order will not be allowed to go through.';
+$strings['CountryEmpty'] = 'To process an order, you need to define the Country field in the user profile.';
+$strings['Duration'] = 'Duration';
+$strings['SubscriptionAdd'] = 'Add subscription';
+$strings['SubscriptionList'] = 'Subscription list';
+$strings['SubscriptionListOnSale'] = 'Subscriptions on sale';
+$strings['SelectSubscription'] = 'Select duration';
+$strings['SubscriptionNotValid'] = 'Subscription not valid';
+$strings['SubscriptionSalesReport'] = 'Sales report';
+$strings['BuySubscriptions'] = 'Buy subscriptions';
+$strings['ConfigurationOfSubscriptionsAndPrices'] = 'Subscriptions and prices configuration';
+$strings['FrequencyConfig'] = 'Duration config';
+$strings['Subscriptions'] = 'Subscriptions';
+$strings['HasSubscriptions'] = 'Has subscriptions';
+$strings['FrequencyRemoved'] = 'Period removed';
+$strings['SubscriptionPeriodOnUse'] = 'Subscription period in use';
+$strings['FrequencyNotExits'] = 'Period does not exist';
+$strings['FrequencyIncorrect'] = 'Period incorrect';
+$strings['SubscriptionFrequencyValueDays'] = 'Value on days';
+$strings['FrequencyNotUpdated'] = 'Period not updated';
+$strings['FrequencyNotSaved'] = 'Period not saved';
+$strings['NeedToAddDuration'] = 'Need to add duration';
+$strings['SubscriptionNotValid'] = 'Subscription not valid';
+$strings['SelecSubscription'] = 'Select a subscription';
+$strings['ConfigureSubscriptionsFrequencies'] = 'Configure subscriptions periods';
+$strings['FrequencyAdd'] = 'Add periods';
+$strings['SubscriptionAlreadyExists'] = 'Subscription already exists';
+$strings['SubscriptionPeriodDuration'] = 'Subscription duration (in days)';
+$strings['Product'] = 'Product name';
+$strings['YouProductIsActivatedYouCanNowAccessIt'] = 'Your product is now activated and you can now have access to it.';
+$strings['hide_shopping_cart_from_course_catalogue'] = 'Hide shopping cart from the course catalogue and leave the subscribe button';
diff --git a/public/plugin/BuyCourses/lang/french.php b/public/plugin/BuyCourses/lang/french.php
index c2e8bee86ca..ca7ff4675d3 100644
--- a/public/plugin/BuyCourses/lang/french.php
+++ b/public/plugin/BuyCourses/lang/french.php
@@ -1,165 +1,252 @@
%s . Ce pourcentage sera soustrait du prix total du produit. La différence sera répartie selon les commissions définies ci-dessous.";
+$strings['NeedToSelectPaymentType'] = 'Besoin pour sélectionner le type de paiement';
+$strings['IndividualPayout'] = 'Paiement individuel';
+$strings['CancelPayout'] = 'Annuler paiement';
+$strings['ContinuePayout'] = 'Continuer paiement';
+$strings['ProceedPayout'] = 'Confirmer le paiement';
+$strings['TheActualPlatformCommissionIsX'] = 'La commission de la plateforme est actuellement établie à %s . Ce pourcentage sera soustrait du prix total du produit. La différence sera répartie selon les commissions définies ci-dessous.';
$strings['CoursesInSessionsDoesntDisplayHere'] = "Les cours qui se trouvent dans une session n'apparaissent pas dans la liste de cours individuels.";
$strings['WantToSellCourses'] = "Envie d'enseigner et de gagner un peu d'argent avec vos propres cours? Cette liste pourraît être pleine de ventes de vos cours. Contactez-nous.";
-$strings['SelectOptionToProceed'] = "Sélectionnez une option pour continuer";
+$strings['SelectOptionToProceed'] = 'Sélectionnez une option pour continuer';
$strings['VerifyTotalAmountToProceedPayout'] = "Veuillez vérifier le montant total avant de continuer le paiement des commissions. Ce montant ne prend pas en compte le coût additionnel éventuellement perçu par PayPal. Les ventes de cours pour lesquelles les bénéficiaires n'ont pas de compte PayPal configuré ne seront pas prises en compte.";
-$strings['TotalAcounts'] = "Total des comptes:";
-$strings['TotalPayout'] = "Total à payer:";
-$strings['PayoutDate'] = "Date de paiement:";
-$strings['CautionThisProcessCantBeCanceled'] = "Attention: ce processus peut prendre quelques minutes et ne peut pas être interrompu.";
-$strings['ProcessingPayoutsDontCloseThisWindow'] = "Exécution des paiements. Ne fermez pas cette fenêtre avant que le processus ne soit finalisé.";
-$strings['PayoutSuccess'] = "Paiements effectués avec succès";
-$strings['Buyer'] = "Acheteur";
-$strings['BankTransfer'] = "Transfert bancaire";
-$strings['SaleInfo'] = "Information vente";
-$strings['SaleStatusPending'] = "Vente non confirmée";
-$strings['SaleStatusCanceled'] = "Vente annulée";
-$strings['SaleStatusCompleted'] = "Vente finalisée";
-$strings['PayoutStatusPending'] = "Paiement en attente";
-$strings['PayoutStatusCanceled'] = "Paiement annulé";
-$strings['PayoutStatusCompleted'] = "Paiement complété";
-$strings['PayoutsTotalPending'] = "Paiements en attente:";
-$strings['PayoutsTotalCanceled'] = "Paiements annulés:";
-$strings['PayoutsTotalCompleted'] = "Paiements complétés:";
-$strings['TotalAmount'] = "Montant total:";
-$strings['CourseListOnSale'] = "Liste de cours en vente";
-$strings['AvailableCourses'] = "Cours disponibles";
-$strings['Price'] = "Prix";
-$strings['SearchFilter'] = "Filtre de recherche";
-$strings['MinimumPrice'] = "Prix minimum";
-$strings['MaximumPrice'] = "Prix maximum";
-$strings['AvailableCoursesConfiguration'] = "Configuration des cours disponibles";
-$strings['PaymentsConfiguration'] = "Configuration des paiements";
+$strings['TotalAcounts'] = 'Total des comptes:';
+$strings['TotalPayout'] = 'Total à payer:';
+$strings['PayoutDate'] = 'Date de paiement:';
+$strings['CautionThisProcessCantBeCanceled'] = 'Attention: ce processus peut prendre quelques minutes et ne peut pas être interrompu.';
+$strings['ProcessingPayoutsDontCloseThisWindow'] = 'Exécution des paiements. Ne fermez pas cette fenêtre avant que le processus ne soit finalisé.';
+$strings['PayoutSuccess'] = 'Paiements effectués avec succès';
+$strings['Buyer'] = 'Acheteur';
+$strings['BankTransfer'] = 'Transfert bancaire';
+$strings['SaleInfo'] = 'Information vente';
+$strings['SaleStatusPending'] = 'Vente non confirmée';
+$strings['SaleStatusCanceled'] = 'Vente annulée';
+$strings['SaleStatusCompleted'] = 'Vente finalisée';
+$strings['PayoutStatusPending'] = 'Paiement en attente';
+$strings['PayoutStatusCanceled'] = 'Paiement annulé';
+$strings['PayoutStatusCompleted'] = 'Paiement complété';
+$strings['PayoutsTotalPending'] = 'Paiements en attente:';
+$strings['PayoutsTotalCanceled'] = 'Paiements annulés:';
+$strings['PayoutsTotalCompleted'] = 'Paiements complétés:';
+$strings['TotalAmount'] = 'Montant total:';
+$strings['CourseListOnSale'] = 'Liste de cours en vente';
+$strings['AvailableCourses'] = 'Cours disponibles';
+$strings['Price'] = 'Prix';
+$strings['SearchFilter'] = 'Filtre de recherche';
+$strings['MinimumPrice'] = 'Prix minimum';
+$strings['MaximumPrice'] = 'Prix maximum';
+$strings['AvailableCoursesConfiguration'] = 'Configuration des cours disponibles';
+$strings['PaymentsConfiguration'] = 'Configuration des paiements';
$strings['TheUserIsAlreadyRegisteredInTheCourse'] = "L'utilisateur est déjà inscrit au cours";
-$strings['SeeDescription'] = "Voir description";
-$strings['Buy'] = "Acheter";
-$strings['WaitingToReceiveThePayment'] = "En attente de réception du paiement";
-$strings['TheUserIsAlreadyRegisteredInTheSession'] = "Vous êtes déjà inscrit à cette session";
-$strings['ItemNotSaved'] = "Article non sauvé";
-$strings['TitlePlugin'] = "Tout le nécessaire pour enseigner et vendre des cours en ligne";
+$strings['SeeDescription'] = 'Voir description';
+$strings['Buy'] = 'Acheter';
+$strings['WaitingToReceiveThePayment'] = 'En attente de réception du paiement';
+$strings['TheUserIsAlreadyRegisteredInTheSession'] = 'Vous êtes déjà inscrit à cette session';
+$strings['ItemNotSaved'] = 'Article non sauvé';
+$strings['TitlePlugin'] = 'Tout le nécessaire pour enseigner et vendre des cours en ligne';
$strings['PluginPresentation'] = "Le plugin BuyCourses vous donne les moyens nécessaires pour vendre vos cours ou vos sessions existants et d'enseigner en ligne, en quelques étapes très simples. Qu'attendez-vous? Commencez à vendre des cours grâce à Chamilo dès maintenant!";
$strings['Instructions'] = "Instructions d'utilisation";
-$strings['InstructionsStepOne'] = "Créer un cours ou une session de formation sur la plateforme.";
-$strings['InstructionsStepTwo'] = "Dans la section configuration de paiements, configurer le type de devise dans lequel vous souhaitez vendre vos cours et sessions";
-$strings['InstructionsStepThree'] = "Configurer les cours à vendre dans la section Configuration de cours et prix";
-$strings['BuyCourses'] = "Acheter des cours";
-$strings['ConfigurationOfCoursesAndPrices'] = "Configuration des cours et prix";
-$strings['SalesReport'] = "Rapport des ventes";
-$strings['UserInformation'] = "Fiche acheteur";
-$strings['PaymentMethods'] = "Méthodes de paiement";
-$strings['ConfirmOrder'] = "Confirmer commande";
+$strings['InstructionsStepOne'] = 'Créer un cours ou une session de formation sur la plateforme.';
+$strings['InstructionsStepTwo'] = 'Dans la section configuration de paiements, configurer le type de devise dans lequel vous souhaitez vendre vos cours et sessions';
+$strings['InstructionsStepThree'] = 'Configurer les cours à vendre dans la section Configuration de cours et prix';
+$strings['BuyCourses'] = 'Acheter des cours';
+$strings['ConfigurationOfCoursesAndPrices'] = 'Configuration des cours et prix';
+$strings['SalesReport'] = 'Rapport des ventes';
+$strings['UserInformation'] = 'Fiche acheteur';
+$strings['PaymentMethods'] = 'Méthodes de paiement';
+$strings['ConfirmOrder'] = 'Confirmer commande';
$strings['PurchaseData'] = "Détails d'achat";
-$strings['bc_subject'] = "Confirmation de commande de cours";
-$strings['PurchaseStatusX'] = "État de la vente: %s";
-$strings['PendingReasonByTransfer'] = "En attente. Transfert pas encore confirmé";
-$strings['CancelOrder'] = "Annuler la commande";
-$strings['BankAccountInformation'] = "Détails du compte bancaire";
-$strings['BankAccount'] = "Compte bancaire";
-$strings['OnceItIsConfirmedYouWillReceiveAnEmailWithTheBankInformationAndAnOrderReference'] = "Une fois confirmée, vous recevrez un e-mail avec les données bancaires et la référence de la commande";
-$strings['SubscriptionToCourseXSuccessful'] = "Votre inscription au \"%s\" est terminée.";
-$strings['OrderCanceled'] = "Commande annulée";
-$strings['OrderStatus'] = "Statut de commande";
-$strings['PayoutStatus'] = "État du paiement";
-$strings['SearchByStatus'] = "Recherche par statut";
-$strings['OrderReference'] = "Référence de la commande";
-$strings['OrderDate'] = "Date de commande";
-$strings['OrderPrice'] = "Commande Prix";
-$strings['ProductType'] = "Type de produit";
-$strings['SubscribeUser'] = "Inscrire utilisateur";
-$strings['DeleteOrder'] = "Éliminer la commande";
+$strings['bc_subject'] = 'Confirmation de commande de cours';
+$strings['PurchaseStatusX'] = 'État de la vente: %s';
+$strings['PendingReasonByTransfer'] = 'En attente. Transfert pas encore confirmé';
+$strings['CancelOrder'] = 'Annuler la commande';
+$strings['BankAccountInformation'] = 'Détails du compte bancaire';
+$strings['BankAccount'] = 'Compte bancaire';
+$strings['OnceItIsConfirmedYouWillReceiveAnEmailWithTheBankInformationAndAnOrderReference'] = 'Une fois confirmée, vous recevrez un e-mail avec les données bancaires et la référence de la commande';
+$strings['SubscriptionToCourseXSuccessful'] = 'Votre inscription au "%s" est terminée.';
+$strings['OrderCanceled'] = 'Commande annulée';
+$strings['OrderStatus'] = 'Statut de commande';
+$strings['PayoutStatus'] = 'État du paiement';
+$strings['SearchByStatus'] = 'Recherche par statut';
+$strings['OrderReference'] = 'Référence de la commande';
+$strings['OrderDate'] = 'Date de commande';
+$strings['OrderPrice'] = 'Commande Prix';
+$strings['ProductType'] = 'Type de produit';
+$strings['SubscribeUser'] = 'Inscrire utilisateur';
+$strings['DeleteOrder'] = 'Éliminer la commande';
$strings['ErrorContactPlatformAdmin'] = "Une erreur inconnue s'est produite. Veuillez contacter l'administrateur de la plateforme.";
-$strings['PendingReasonByAddress'] = "En attente. Il manque une adresse de livraison.";
+$strings['PendingReasonByAddress'] = 'En attente. Il manque une adresse de livraison.';
$strings['PendingReasonByAuthorization'] = "En attente. Nous n'avons pas confirmé la réception des fonds.";
$strings['PendingReasonByEcheck'] = "En attente. Le paiement a été fait via un chèque qui n'a pas encore été libéré";
-$strings['PendingReasonByIntl'] = "En attente. Aucun moyen de toucher les fonds.";
+$strings['PendingReasonByIntl'] = 'En attente. Aucun moyen de toucher les fonds.';
$strings['PendingReasonByMulticurrency'] = "En attente. Nous n'avons pas de compte dans la devise indiquée.";
$strings['PendingReasonByOrder'] = "En attente. Commande enregistrée. Les fonds n'ont pas encore été libérés.";
-$strings['PendingReasonByPaymentReview'] = "En attente. Le paiement est en révision anti-fraude chez PayPal.";
-$strings['PendingReasonByRegulatoryReview'] = "En attente. Le paiement est actuellement revu pour correspondre aux règles mises en vigueur par le gouvernement.";
+$strings['PendingReasonByPaymentReview'] = 'En attente. Le paiement est en révision anti-fraude chez PayPal.';
+$strings['PendingReasonByRegulatoryReview'] = 'En attente. Le paiement est actuellement revu pour correspondre aux règles mises en vigueur par le gouvernement.';
$strings['PendingReasonByUnilateral'] = "En attente. L'adresse e-mail n'est pas encore confirmée ou enregistrée.";
-$strings['PendingReasonByUpgrade'] = "En attente. Le paiement a été fait par carte de crédit.";
+$strings['PendingReasonByUpgrade'] = 'En attente. Le paiement a été fait par carte de crédit.';
$strings['PendingReasonByVerify'] = "En attente. Désolé, nous n'avons pas encore vérifié sur PayPal.";
$strings['PendingReasonByOther'] = "En attente. Veuillez contacter l'administrateur.";
$strings['PayPalPaymentOKPleaseConfirm'] = "PayPal nous indique que la transaction est prête à être exécutée. Par mesure de sécurité, nous vous demandons de bien vouloir confirmer une dernière fois la transaction en cliquant sur le bouton de confirmation ci-dessous. Une fois cliqué, vous serez immédiatement enregistré au cours, et les fonds correspondants seront soustraits de votre compte PayPal. Vous pouvez accéder à vos cours à tout moment à partir de l'onglet 'Mes cours'. Merci de votre fidélité!";
-$strings['Sandbox'] = "Environnement de test";
-$strings['PayPalAccount'] = "Compte Paypal";
-$strings['NoPayPalAccountDetected'] = "Pas de compte paypal détecté";
-$strings['PayPalConfig'] = "Configuration PayPal:";
-$strings['TransfersConfig'] = "Configuration des transfers bancaires:";
+$strings['Sandbox'] = 'Environnement de test';
+$strings['PayPalAccount'] = 'Compte Paypal';
+$strings['NoPayPalAccountDetected'] = 'Pas de compte paypal détecté';
+$strings['PayPalConfig'] = 'Configuration PayPal:';
+$strings['TransfersConfig'] = 'Configuration des transfers bancaires:';
$strings['PluginInstruction'] = "Vous pouvez activer ou désactiver l'option de paiements via PayPal, Culqi ou de transferts bancaires dans la section de configuration des plugins.";
$strings['ClickHere'] = "Cliquez ici pour plus d'infos";
-$strings['CurrencyType'] = "Type de devise";
+$strings['CurrencyType'] = 'Type de devise';
$strings['InfoCurrency'] = "Permet de configurer la devise pour l'achat des cours.";
$strings['ApiUsername'] = "Nom d'utilisateur de l'API";
$strings['ApiPassword'] = "Mot de passe de l'API";
$strings['ApiSignature'] = "Signature de l'API";
-$strings['InfoApiCredentials'] = "Pour générer vos données API pour intégrer votre compte PayPal à Chamilo, il vous faudra suivre les étapes suivantes";
+$strings['InfoApiCredentials'] = 'Pour générer vos données API pour intégrer votre compte PayPal à Chamilo, il vous faudra suivre les étapes suivantes';
$strings['InfoApiStepOne'] = "Aller dans l'option profil de PayPal, et ensuite dans Outils de vente";
$strings['InfoApiStepTwo'] = "Dans la section API d'accès, cliquer sur l'option Mettre à jour";
$strings['InfoApiStepThree'] = "Dans l'option 2 de Configuration des données et permissions API, cliquer sur Voir signature API. Copier ces donées dans le formulaire de configuration de ce plugin";
$strings['ErrorOccurred'] = "Une erreur est survenue. Code: %s. Message: %s. Veuillez contacter l'administrateur de la plateforme";
-$strings['VisibleInCatalog'] = "Visible dans le catalogue";
-$strings['Beneficiaries'] = "Bénéficiaires";
-$strings['AvailableCourse'] = "Cours disponibles";
-$strings['ShowOnCourseCatalog'] = "Afficher dans le catalogue de cours";
-$strings['ByStatus'] = "Par statut";
-$strings['ByUser'] = "Par utilisateur";
-$strings['ByEmail'] = "Par email";
-$strings['PaymentMethod'] = "Méthodes de paiement";
-$strings['SWIFT'] = "Code SWIFT";
+$strings['VisibleInCatalog'] = 'Visible dans le catalogue';
+$strings['Beneficiaries'] = 'Bénéficiaires';
+$strings['AvailableCourse'] = 'Cours disponibles';
+$strings['ShowOnCourseCatalog'] = 'Afficher dans le catalogue de cours';
+$strings['ByStatus'] = 'Par statut';
+$strings['ByUser'] = 'Par utilisateur';
+$strings['ByEmail'] = 'Par email';
+$strings['PaymentMethod'] = 'Méthodes de paiement';
+$strings['SWIFT'] = 'Code SWIFT';
$strings['SWIFT_help'] = "Format standard des codes d'identification de banque (BIC) et sert un identifiant unique pour une banque ou une institution financière.";
$strings['PleaseSelectThePaymentMethodBeforeConfirmYourOrder'] = 'Veuillez sélectionner votre méthode de paiement préférée avant de confirmer';
$strings['NoPaymentOptionAvailable'] = 'Aucune méthode de paiement disponible. Merci de bien vouloir rapporter ce problème à l\'administrateur.';
$strings['XIsOnlyPaymentMethodAvailable'] = '%s est la seule méthode de paiement disponible pour cet achat.';
$strings['public_main_menu_tab'] = "Montrer l'onglet dans le menu principal aux utilisateurs anonyme également";
-$strings['culqi_enable'] = "Activé culqi";
-$strings['include_services'] = "Inclure les services";
+$strings['culqi_enable'] = 'Activé culqi';
+$strings['include_services'] = 'Inclure les services';
$strings['hide_free_text'] = "Cacher le texte 'Free' ou 'Gratuit'";
-$strings['Services'] = "Services";
-$strings['ServiceName'] = "Nom du service";
+$strings['Services'] = 'Services';
+$strings['ServiceName'] = 'Nom du service';
$strings['AppliesTo'] = "S'applique à";
-$strings['ListOfServicesOnSale'] = "Liste de services en vente";
-$strings['GlobalConfig'] = "Configuration globale";
-$strings['WriteHereTheTermsAndConditionsOfYourECommerce'] = "Écrire les conditions de ventes de votre e-commerce";
-$strings['NewService'] = "Nouveau service";
-$strings['Service'] = "Service";
-$strings['ServiceInformation'] = "Information sur le service";
-$strings['EditService'] = "Edition du service";
-$strings['DeleteThisService'] = "Supprimer ce service";
+$strings['ListOfServicesOnSale'] = 'Liste de services en vente';
+$strings['GlobalConfig'] = 'Configuration globale';
+$strings['WriteHereTheTermsAndConditionsOfYourECommerce'] = 'Écrire les conditions de ventes de votre e-commerce';
+$strings['NewService'] = 'Nouveau service';
+$strings['Service'] = 'Service';
+$strings['ServiceInformation'] = 'Information sur le service';
+$strings['EditService'] = 'Edition du service';
+$strings['DeleteThisService'] = 'Supprimer ce service';
$strings['IConfirmIReadAndAcceptTermsAndCondition'] = "Je confirme que j'ai lu et que j'accepte les termes et conditions";
$strings['PleaseSelectTheCorrectInfoToApplyTheService'] = "Veuillez choisir l'information à appliquer au service";
-$strings['SaleStatusCancelled'] = "Vente annulée";
-$strings['ServiceSaleInfo'] = "Information de vente";
-$strings['ServiceId'] = "Id du service";
-$strings['BoughtBy'] = "Acheté par";
-$strings['PurchaserUser'] = "Utilisateur acheteur";
-$strings['Pending'] = "En attente";
-$strings['Names'] = "Nom";
-$strings['ExportReport'] = "Export du rapport des ventes";
-$strings['OrderTime'] = "Heure de commande";
-$strings['SelectDateRange'] = "Sélectionnez une date de début et une date de fin pour le rapport";
+$strings['SaleStatusCancelled'] = 'Vente annulée';
+$strings['ServiceSaleInfo'] = 'Information de vente';
+$strings['ServiceId'] = 'Id du service';
+$strings['BoughtBy'] = 'Acheté par';
+$strings['PurchaserUser'] = 'Utilisateur acheteur';
+$strings['Pending'] = 'En attente';
+$strings['Names'] = 'Nom';
+$strings['ExportReport'] = 'Export du rapport des ventes';
+$strings['OrderTime'] = 'Heure de commande';
+$strings['SelectDateRange'] = 'Sélectionnez une date de début et une date de fin pour le rapport';
+$strings['InfoEmailExtra'] = "Informations additionnelles dans l'e-mail de paiement";
+$strings['Coupon'] = 'Coupon';
+$strings['DiscountAmount'] = 'Ristourne totale';
+$strings['RedeemCoupon'] = 'Échanger';
+$strings['NeedToAddCouponCode'] = "Aucun code de coupon n'a été introduit";
+$strings['CouponNotValid'] = "Ce coupon n'est pas valable";
+$strings['CouponRedeemed'] = 'Coupon échangé';
+$strings['CouponDiscount'] = 'Ristourne';
+$strings['CouponStatus'] = 'Statut du coupon';
+$strings['CouponPercentage'] = 'Pourcentage';
+$strings['CouponAmount'] = 'Montant';
+$strings['CouponList'] = 'Liste des coupons';
+$strings['CouponCode'] = 'Code du coupon';
+$strings['CouponDiscountType'] = 'Type de ristourne';
+$strings['CouponDateStart'] = 'Valable apd';
+$strings['CouponDateEnd'] = 'Expire le';
+$strings['CouponDelivered'] = 'Livré';
+$strings['CouponDisable'] = 'Désactivé';
+$strings['CouponEnable'] = 'Activé';
+$strings['CouponCodeUsed'] = 'Code de coupon déjà utilisé';
+$strings['CouponNoExists'] = "Ce coupon n'existe pas";
+$strings['CouponErrorInsert'] = "Erreur lors de l'insertion du coupon";
+$strings['CouponActive'] = 'Actif';
+$strings['CouponDisabled'] = 'Désactivé';
+$strings['CouponUpdate'] = 'Coupon mis à jour';
+$strings['CouponsConfiguration'] = 'Configuration coupons';
+$strings['CouponAdd'] = 'Nouveau coupon';
+$strings['ConfigureCoupon'] = 'Configurer le coupon';
+$strings['DiscountCoupon'] = 'Coupons de ristourne';
+$strings['CouponsCode'] = 'Code';
+$strings['DoYouHaveACoupon'] = 'Vous avez un coupon?';
+$strings['stripe_enable'] = 'Activer Stripe';
+$strings['StripeConfig'] = 'Configuration de Stripe:';
+$strings['InfoStripeCredentials'] = "Pour obtenir les données de connexion, vous devez d'abord réer un compte Stripe (ce qui prend un certain temps), puis copier l'ID du compte depuis votre profil et le renseigner ici. Puis aller dans la configuration des clefs API et copier la clef secrète. Enfin, suivre le bouton 'Développeurs' (haut droite), enregistrer un nouveau Endpoint dans la section Webhooks, le pointer vers l'URL https://{site}/plugin/BuyCourses/src/stripe_response.php et l'associer à l'événement checkout.session.completed et copier le secret du Endpoint ici.";
+$strings['StripeAccountId'] = 'ID du compte:';
+$strings['StripeSecret'] = 'Clef secrète:';
+$strings['StripeEndpointSecret'] = 'Clef secrète du Endpoint:';
+$strings['PendingReasonByStripe'] = 'Un instant.... En attente de confirmation du paiement...';
+$strings['cecabank_enable'] = 'Activer Cecabank POS';
+$strings['TpvCecabank'] = 'Paiement POS (Cecabank)';
+$strings['CecaSecret'] = 'Clef secrète';
+$strings['CecaUrl'] = 'URL';
+$strings['CecaMerchanId'] = 'Marchand';
+$strings['CecaAcquirerId'] = 'Acquéreur';
+$strings['CecaTerminalId'] = 'Terminal';
+$strings['CecaCypher'] = 'Chiffrage';
+$strings['CecaCurrency'] = 'Devise';
+$strings['CecaExponent'] = 'Exposant';
+$strings['CecaSupportedPayment'] = 'Paiement supporté';
+$strings['CecabankConfig'] = 'Configuration de Cecabank';
+$strings['Country'] = 'Pays';
+$strings['PaymentType'] = 'Type de paiement';
+$strings['CountryRelPaymentConfig'] = 'Configuration du type de paiement par pays';
+$strings['CountryRelPaymentMessage'] = 'Pour faire une commande, il est nécessaire de définir le type de paiement par pays. Sinon, il est impossible de clôturer la commande';
+$strings['CountryEmpty'] = 'Pour passer commande, il est nécessaire de définir le champ Pays dans le profil utilisateur.';
+$strings['Duration'] = 'Durée';
+$strings['SubscriptionAdd'] = 'Ajouter souscription';
+$strings['SubscriptionList'] = 'Liste des souscriptions';
+$strings['SubscriptionListOnSale'] = 'Souscriptions en promo';
+$strings['SelectSubscription'] = 'Sélectionner la durée';
+$strings['SubscriptionNotValid'] = 'Souscription non valable';
+$strings['SubscriptionSalesReport'] = 'Rapport de ventes';
+$strings['BuySubscriptions'] = 'Souscrire';
+$strings['ConfigurationOfSubscriptionsAndPrices'] = 'Configuration des souscriptions et prix';
+$strings['FrequencyConfig'] = 'Configuration périodes';
+$strings['Subscriptions'] = 'Souscriptions';
+$strings['HasSubscriptions'] = 'A des souscriptions';
+$strings['FrequencyRemoved'] = 'Période supprimée';
+$strings['SubscriptionPeriodOnUse'] = 'Période de souscription utilisée';
+$strings['FrequencyNotExits'] = "Cette période n'existe pas";
+$strings['FrequencyIncorrect'] = 'Période incorrecte';
+$strings['SubscriptionFrequencyValueDays'] = 'Valeur en jours';
+$strings['FrequencyNotUpdated'] = 'Période non mise à jour';
+$strings['FrequencyNotSaved'] = 'Période non sauvegardée';
+$strings['NeedToAddDuration'] = 'Une durée est nécessaire';
+$strings['SubscriptionNotValid'] = 'Souscription non valable';
+$strings['SelecSubscription'] = 'Sélectionnez une souscription';
+$strings['ConfigureSubscriptionsFrequencies'] = 'Configurez des périodes de souscription';
+$strings['FrequencyAdd'] = 'Ajouter période';
+$strings['SubscriptionAlreadyExists'] = 'La souscription existe déjà';
+$strings['SubscriptionPeriodDuration'] = 'Durée de souscription (en jours)';
+$strings['Product'] = 'Produit';
+$strings['SalePrice'] = 'Prix';
+$strings['YouProductIsActivatedYouCanNowAccessIt'] = 'Votre abonnement a été activé, vous avez maintenant accès au module choisi.';
+$strings['hide_shopping_cart_from_course_catalogue'] = "Cacher le chariot de vente dans le catalogue de cours et laisse le bouton s'inscrire";
diff --git a/public/plugin/BuyCourses/lang/spanish.php b/public/plugin/BuyCourses/lang/spanish.php
index af4e0368c20..d50a949ee07 100644
--- a/public/plugin/BuyCourses/lang/spanish.php
+++ b/public/plugin/BuyCourses/lang/spanish.php
@@ -1,216 +1,323 @@
%s , este porcentaje será descontado del total del precio del producto cuya diferencia será el monto base para aplicar estas comisiones.";
-$strings['CoursesInSessionsDoesntDisplayHere'] = "Los cursos que se encuentren dentro de una sesión de formación no aparecerán en la lista de cursos a configurar como productos individuales.";
-$strings['WantToSellCourses'] = "¿Quieres enseñar y ganar dinero con tus propios cursos?, Esta lista puede estar llena de tus ganancias vendiendo cursos a través de esta plataforma!. Informate con nosotros! ";
-$strings['SelectOptionToProceed'] = "Selecciona una opción para proceder";
-$strings['VerifyTotalAmountToProceedPayout'] = "Por favor verificar el monto total para proceder con el pago de comisiones, este monto no considera cargos extras por paypal, las ventas de cursos que no cuenten con una cuenta de Paypal para el o los beneficiarios no serán consideradas.";
-$strings['TotalAcounts'] = "Total de cuentas:";
-$strings['TotalPayout'] = "Total a pagar:";
-$strings['PayoutDate'] = "Fecha del Pago:";
-$strings['CautionThisProcessCantBeCanceled'] = "Precaución: este proceso puede tomar unos minutos y no puede ser cancelado.";
-$strings['ProcessingPayoutsDontCloseThisWindow'] = "Procesando los pagos, no cierre esta ventana hasta que haya finalizado";
-$strings['PayoutSuccess'] = "Los pagos se han realizado con éxito";
-$strings['Buyer'] = "Comprador";
-$strings['BankTransfer'] = "Transferencia Bancaria";
-$strings['SaleInfo'] = "Información de la venta";
-$strings['SaleStatusPending'] = "Venta pendiente";
-$strings['SaleStatusCanceled'] = "Venta cancelada";
-$strings['SaleStatusCompleted'] = "Venta completada";
-$strings['PayoutStatusPending'] = "Pago pendiente";
-$strings['PayoutStatusCanceled'] = "Pago cancelado";
-$strings['PayoutStatusCompleted'] = "Pago completado";
-$strings['PayoutsTotalPending'] = "Pagos pendientes:";
-$strings['PayoutsTotalCanceled'] = "Pagos cancelados:";
-$strings['PayoutsTotalCompleted'] = "Pagos completados:";
-$strings['Total'] = "Total";
-$strings['TotalAmount'] = "Monto total:";
-$strings['CourseListOnSale'] = "Lista de cursos a la venta";
-$strings['AvailableCourses'] = "Cursos disponibles";
-$strings['Price'] = "Precio";
-$strings['SearchFilter'] = "Filtro de búsqueda";
-$strings['MinimumPrice'] = "Precio mínimo";
-$strings['MaximumPrice'] = "Precio máximo";
-$strings['AvailableCoursesConfiguration'] = "Configuración de cursos disponibles";
-$strings['PaymentsConfiguration'] = "Configuración de Pagos";
-$strings['TheUserIsAlreadyRegisteredInTheCourse'] = "Usted ya está registrado en el curso.";
-$strings['SeeDescription'] = "Ver descripción";
-$strings['Buy'] = "Comprar";
-$strings['WaitingToReceiveThePayment'] = "Se encuentra a la espera de recibir el pago";
-$strings['TheUserIsAlreadyRegisteredInTheSession'] = "Usted ya está registrado en la sesión";
-$strings['ItemNotSaved'] = "Elemento no guardado";
-$strings['TitlePlugin'] = "Todo lo que necesita para enseñar y vender cursos en línea";
-$strings['PluginPresentation'] = "El Plugin BuyCourses le da los recursos para vender sus cursos o sus sesiones ya creados y enseñar en línea, todo en unos simples pasos y configuraciones. ¿Qué espera? Empiece a vender cursos a través de Chamilo ahora!";
-$strings['Instructions'] = "Instrucciones de uso";
-$strings['InstructionsStepOne'] = "Crea un curso o una sesión de formación en la plataforma.";
-$strings['InstructionsStepTwo'] = "En la sección configuración de pagos, configure el tipo de moneda con el que venderá sus cursos o sesiones.";
-$strings['InstructionsStepThree'] = "Configure los cursos a vender en la sección Configuración de cursos y precios";
-$strings['BuyCourses'] = "Comprar cursos";
-$strings['ConfigurationOfCoursesAndPrices'] = "Configuración de cursos y precios";
-$strings['SalesReport'] = "Reporte de ventas";
-$strings['UserInformation'] = "Ficha del comprador";
-$strings['PaymentMethods'] = "Métodos de pago";
-$strings['ConfirmOrder'] = "Confirmar Orden";
-$strings['PurchaseData'] = "Datos de la compra";
-$strings['bc_subject'] = "Confirmación pedido de cursos";
-$strings['PurchaseStatusX'] = "Estado de la compra: %s";
-$strings['PendingReasonByTransfer'] = "Pendiente. Esperando la confirmación de la transferencia";
-$strings['CancelOrder'] = "Cancelar Orden";
-$strings['BankAccountInformation'] = "Información de la Cuenta Bancaria";
-$strings['BankAccount'] = "Cuenta Bancaria";
-$strings['OnceItIsConfirmedYouWillReceiveAnEmailWithTheBankInformationAndAnOrderReference'] = "Una vez confirmado, recibira un e-mail con los datos bancarios y una referencia del pedido.";
-$strings['SubscriptionToCourseXSuccessful'] = "
';
- if (!empty($item)) {
+ if ($item) {
$html .= '
'.$item['total_price_formatted'].'
';
$return['verificator'] = true;
} else {
- if (false == $hideFree) {
+ if (!$hideFree) {
$html .= '
'.$this->get_lang('Free').'
';
@@ -363,34 +593,30 @@ public function buyCoursesForGridCatalogValidator($productId, $productType)
return $return;
}
- return false;
+ return null;
}
/**
* Return the buyCourses plugin button to buy the course.
- *
- * @param int $productId
- * @param int $productType
- *
- * @return string $html
*/
- public function returnBuyCourseButton($productId, $productType)
+ public function returnBuyCourseButton(int $productId, int $productType): string
{
- $productId = (int) $productId;
- $productType = (int) $productType;
- $url = api_get_path(WEB_PLUGIN_PATH).'BuyCourses/src/process.php?i='.$productId.'&t='.$productType;
- $html = '
'.
- Display::getMdiIcon('cart').'';
+ $url = api_get_path(WEB_PLUGIN_PATH).'buycourses/src/process.php?i='.$productId.'&t='.$productType;
+ $buyButton = Display::returnFontAwesomeIcon('shopping-cart');
+ if ('true' === $this->get('hide_shopping_cart_from_course_catalogue')) {
+ $buyButton = Display::returnFontAwesomeIcon('check').\PHP_EOL.get_lang('Subscribe');
+ }
- return $html;
+ return '
'.
+ $buyButton.'';
}
/**
* Get the currency for sales.
*
- * @return array The selected currency. Otherwise return false
+ * @return array The selected currency. Otherwise, return false
*/
- public function getSelectedCurrency()
+ public function getSelectedCurrency(): array
{
return Database::select(
'*',
@@ -404,10 +630,8 @@ public function getSelectedCurrency()
/**
* Get a list of currencies.
- *
- * @return array The currencies. Otherwise return false
*/
- public function getCurrencies()
+ public function getCurrencies(): array
{
return Database::select(
'*',
@@ -418,9 +642,9 @@ public function getCurrencies()
/**
* Save the selected currency.
*
- * @param int $selectedId The currency Id
+ * @param int $selectedId The currency ID
*/
- public function saveCurrency($selectedId)
+ public function saveCurrency(int $selectedId): void
{
$currencyTable = Database::get_main_table(
self::TABLE_CURRENCY
@@ -433,18 +657,16 @@ public function saveCurrency($selectedId)
Database::update(
$currencyTable,
['status' => 1],
- ['id = ?' => (int) $selectedId]
+ ['id = ?' => $selectedId]
);
}
/**
* Save the PayPal configuration params.
*
- * @param array $params
- *
- * @return int Rows affected. Otherwise return false
+ * @return int Rows affected. Otherwise, return false
*/
- public function savePaypalParams($params)
+ public function savePaypalParams(array $params): int
{
return Database::update(
Database::get_main_table(self::TABLE_PAYPAL),
@@ -474,24 +696,119 @@ public function getPaypalParams()
}
/**
- * Save a transfer account information.
+ * Gets the stored TPV Redsys params.
+ */
+ public function getTpvRedsysParams(): array
+ {
+ return Database::select(
+ '*',
+ Database::get_main_table(self::TABLE_TPV_REDSYS),
+ ['id = ?' => 1],
+ 'first'
+ );
+ }
+
+ /**
+ * Save the tpv Redsys configuration params.
+ *
+ * @return int Rows affected. Otherwise, return false
+ */
+ public function saveTpvRedsysParams(array $params): int
+ {
+ return Database::update(
+ Database::get_main_table(self::TABLE_TPV_REDSYS),
+ [
+ 'merchantcode' => $params['merchantcode'],
+ 'terminal' => $params['terminal'],
+ 'currency' => $params['currency'],
+ 'kc' => $params['kc'],
+ 'url_redsys' => $params['url_redsys'],
+ 'url_redsys_sandbox' => $params['url_redsys_sandbox'],
+ 'sandbox' => isset($params['sandbox']),
+ ],
+ ['id = ?' => 1]
+ );
+ }
+
+ /**
+ * Save Stripe configuration params.
+ *
+ * @return int Rows affected. Otherwise, return false
+ */
+ public function saveStripeParameters(array $params): int
+ {
+ return Database::update(
+ Database::get_main_table(self::TABLE_STRIPE),
+ [
+ 'account_id' => $params['account_id'],
+ 'secret_key' => $params['secret_key'],
+ 'endpoint_secret' => $params['endpoint_secret'],
+ ],
+ ['id = ?' => 1]
+ );
+ }
+
+ /**
+ * Gets the stored Stripe params.
+ */
+ public function getStripeParams(): array
+ {
+ return Database::select(
+ '*',
+ Database::get_main_table(self::TABLE_STRIPE),
+ ['id = ?' => 1],
+ 'first'
+ );
+ }
+
+ /**
+ * Save transfer account information.
*
* @param array $params The transfer account
*
- * @return int Rows affected. Otherwise return false
+ * @return int Rows affected. Otherwise, return false
*/
- public function saveTransferAccount($params)
+ public function saveTransferAccount(array $params): int
{
return Database::insert(
Database::get_main_table(self::TABLE_TRANSFER),
[
- 'title' => $params['tname'],
+ 'name' => $params['tname'],
'account' => $params['taccount'],
'swift' => $params['tswift'],
]
);
}
+ /**
+ * Save email message information in transfer.
+ *
+ * @param array $params The transfer message
+ *
+ * @return int Rows affected. Otherwise, return false
+ */
+ public function saveTransferInfoEmail(array $params): int
+ {
+ return Database::update(
+ Database::get_main_table(self::TABLE_GLOBAL_CONFIG),
+ ['info_email_extra' => $params['tinfo_email_extra']],
+ ['id = ?' => 1]
+ );
+ }
+
+ /**
+ * Gets message information for transfer email.
+ */
+ public function getTransferInfoExtra(): array
+ {
+ return Database::select(
+ 'info_email_extra AS tinfo_email_extra',
+ Database::get_main_table(self::TABLE_GLOBAL_CONFIG),
+ ['id = ?' => 1],
+ 'first'
+ );
+ }
+
/**
* Get a list of transfer accounts.
*
@@ -510,13 +827,13 @@ public function getTransferAccounts()
*
* @param int $id The transfer account ID
*
- * @return int Rows affected. Otherwise return false
+ * @return int Rows affected. Otherwise, return false
*/
- public function deleteTransferAccount($id)
+ public function deleteTransferAccount(int $id): int
{
return Database::delete(
Database::get_main_table(self::TABLE_TRANSFER),
- ['id = ?' => (int) $id]
+ ['id = ?' => $id]
);
}
@@ -524,16 +841,14 @@ public function deleteTransferAccount($id)
* Get registered item data.
*
* @param int $itemId The item ID
- *
- * @return array
*/
- public function getItem($itemId)
+ public function getItem(int $itemId): array
{
return Database::select(
'*',
Database::get_main_table(self::TABLE_ITEM),
[
- 'where' => ['id = ?' => (int) $itemId],
+ 'where' => ['id = ?' => $itemId],
],
'first'
);
@@ -544,11 +859,8 @@ public function getItem($itemId)
*
* @param int $productId The item ID
* @param int $itemType The item type
- *
- * @return array
- * @throws Exception
*/
- public function getItemByProduct(int $productId, int $itemType): array
+ public function getItemByProduct(int $productId, int $itemType, ?array $coupon = null): ?array
{
$buyItemTable = Database::get_main_table(self::TABLE_ITEM);
$buyCurrencyTable = Database::get_main_table(self::TABLE_CURRENCY);
@@ -574,75 +886,183 @@ public function getItemByProduct(int $productId, int $itemType): array
);
if (empty($product)) {
- return [];
+ return null;
}
- $this->setPriceSettings($product, self::TAX_APPLIES_TO_ONLY_COURSE);
+ $this->setPriceSettings($product, self::TAX_APPLIES_TO_ONLY_COURSE, $coupon);
return $product;
}
/**
- * List courses details from the configuration page.
+ * Get registered item data.
*
- * @return array
+ * @param int $itemId The product ID
+ * @param int $productType The product type
*/
- public function getCourseList($first, $maxResults)
+ public function getSubscriptionItem(int $itemId, int $productType): array
{
- return $this->getCourses($first, $maxResults);
+ return Database::select(
+ '*',
+ Database::get_main_table(self::TABLE_SUBSCRIPTION),
+ [
+ 'where' => ['product_id = ? AND product_type = ?' => [
+ $itemId,
+ $productType,
+ ],
+ ],
+ ],
+ 'first'
+ );
}
/**
- * Lists current user session details, including each session course details.
- *
- * It can return the number of rows when $typeResult is 'count'.
- *
- * @param int $start
- * @param int $end
- * @param string $name Optional. The name filter.
- * @param int $min Optional. The minimum price filter.
- * @param int $max Optional. The maximum price filter.
- * @param string $typeResult Optional. 'all', 'first' or 'count'.
+ * Get the item data.
*
- * @return array|int
- * @throws Exception
+ * @param int $productId The item ID
+ * @param int $itemType The item type
+ * @param array $coupon Array with at least 'discount_type' and 'discount_amount' elements
*/
- public function getCatalogSessionList($start, $end, $name = null, $min = 0, $max = 0, $typeResult = 'all')
+ public function getSubscriptionItemByProduct(int $productId, int $itemType, ?array $coupon = null): ?array
{
- $sessions = $this->filterSessionList($start, $end, $name, $min, $max, $typeResult);
-
- if ('count' === $typeResult) {
- return $sessions;
- }
+ $buySubscriptionItemTable = Database::get_main_table(self::TABLE_SUBSCRIPTION);
+ $buyCurrencyTable = Database::get_main_table(self::TABLE_CURRENCY);
- $sessionCatalog = [];
- /** @var Session $session */
- foreach ($sessions as $session) {
- $sessionCourses = $session->getCourses();
+ $fakeItemFrom = "
+ $buySubscriptionItemTable s
+ INNER JOIN $buyCurrencyTable c
+ ON s.currency_id = c.id
+ ";
- if (empty($sessionCourses)) {
- continue;
- }
+ $item = Database::select(
+ ['s.*', 'c.iso_code'],
+ $fakeItemFrom,
+ [
+ 'where' => [
+ 's.product_id = ? AND s.product_type = ?' => [
+ $productId,
+ $itemType,
+ ],
+ ],
+ ],
+ 'first'
+ );
- $item = $this->getItemByProduct(
- $session->getId(),
- self::PRODUCT_TYPE_SESSION
- );
+ if (empty($item)) {
+ return null;
+ }
- if (empty($item)) {
- continue;
- }
+ $this->setPriceSettings($item, self::TAX_APPLIES_TO_ONLY_COURSE, $coupon);
- $sessionData = $this->getSessionInfo($session->getId());
- $sessionData['coaches'] = $session->getGeneralCoaches()->map(fn(User $coach) => $coach->getFullName());
- $sessionData['enrolled'] = $this->getUserStatusForSession(
- api_get_user_id(),
- $session
- );
- $sessionData['courses'] = [];
+ return $item;
+ }
- foreach ($sessionCourses as $sessionCourse) {
- $course = $sessionCourse->getCourse();
+ /**
+ * Get the item data.
+ *
+ * @param int $productId The item ID
+ * @param int $itemType The item type
+ */
+ public function getSubscriptionsItemsByProduct(int $productId, int $itemType): ?array
+ {
+ $buySubscriptionItemTable = Database::get_main_table(self::TABLE_SUBSCRIPTION);
+ $buyCurrencyTable = Database::get_main_table(self::TABLE_CURRENCY);
+
+ $fakeItemFrom = "
+ $buySubscriptionItemTable s
+ INNER JOIN $buyCurrencyTable c
+ ON s.currency_id = c.id
+ ";
+
+ $items = Database::select(
+ ['s.*', 'c.iso_code'],
+ $fakeItemFrom,
+ [
+ 'where' => [
+ 's.product_id = ? AND s.product_type = ?' => [
+ $productId,
+ $itemType,
+ ],
+ ],
+ ]
+ );
+
+ for ($i = 0; $i < count($items); $i++) {
+ $this->setPriceSettings($items[$i], self::TAX_APPLIES_TO_ONLY_COURSE);
+ }
+
+ if (empty($items)) {
+ return null;
+ }
+
+ return $items;
+ }
+
+ /**
+ * Get registered item data by duration.
+ *
+ * @param int $duration The subscription duration
+ */
+ public function getSubscriptionsItemsByDuration(int $duration): array
+ {
+ return Database::select(
+ '*',
+ Database::get_main_table(self::TABLE_SUBSCRIPTION),
+ [
+ 'where' => [
+ 'duration = ?' => [$duration],
+ ],
+ ]
+ );
+ }
+
+ /**
+ * Lists current user session details, including each session course detail.
+ *
+ * It can return the number of rows when $typeResult is 'count'.
+ *
+ * @param string|null $name Optional. The name filter.
+ * @param int $min Optional. The minimum price filter.
+ * @param int $max Optional. The maximum price filter.
+ * @param string $typeResult Optional. 'all', 'first' or 'count'.
+ * @param int $sessionCategory
+ */
+ public function getCatalogSessionList(int $start, int $end, ?string $name = null, int $min = 0, int $max = 0, string $typeResult = 'all', $sessionCategory = 0): array|int
+ {
+ $sessions = $this->filterSessionList($start, $end, $name, $min, $max, $typeResult, $sessionCategory);
+
+ if ('count' === $typeResult) {
+ return $sessions;
+ }
+
+ $sessionCatalog = [];
+ // loop through all sessions
+ foreach ($sessions as $session) {
+ $sessionCourses = $session->getCourses();
+
+ if (empty($sessionCourses)) {
+ continue;
+ }
+
+ $item = $this->getItemByProduct(
+ $session->getId(),
+ self::PRODUCT_TYPE_SESSION
+ );
+
+ if (empty($item)) {
+ continue;
+ }
+
+ $sessionData = $this->getSessionInfo($session->getId());
+ $sessionData['coaches'] = $session->getGeneralCoaches()->map(fn (User $coach) => $coach->getFullName());
+ $sessionData['enrolled'] = $this->getUserStatusForSession(
+ api_get_user_id(),
+ $session
+ );
+ $sessionData['courses'] = [];
+
+ foreach ($sessionCourses as $sessionCourse) {
+ $course = $sessionCourse->getCourse();
$sessionCourseData = [
'title' => $course->getTitle(),
@@ -651,7 +1071,7 @@ public function getCatalogSessionList($start, $end, $name = null, $min = 0, $max
$userCourseSubscriptions = $session->getSessionRelCourseRelUsersByStatus(
$course,
- Chamilo\CoreBundle\Entity\Session::COURSE_COACH
+ Session::COURSE_COACH
);
foreach ($userCourseSubscriptions as $userCourseSubscription) {
@@ -671,11 +1091,10 @@ public function getCatalogSessionList($start, $end, $name = null, $min = 0, $max
* Lists current user course details.
*
* @param string $name Optional. The name filter
- * @param int $min Optional. The minimum price filter
- * @param int $max Optional. The maximum price filter
- * @throws Exception
+ * @param int $min Optional. The minimum price filter
+ * @param int $max Optional. The maximum price filter
*/
- public function getCatalogCourseList($first, $pageSize, $name = null, $min = 0, $max = 0, $typeResult = 'all'): array|int
+ public function getCatalogCourseList(int $first, int $pageSize, ?string $name = null, int $min = 0, int $max = 0, string $typeResult = 'all'): array|int
{
$courses = $this->filterCourseList($first, $pageSize, $name, $min, $max, $typeResult);
@@ -688,7 +1107,6 @@ public function getCatalogCourseList($first, $pageSize, $name = null, $min = 0,
}
$courseCatalog = [];
- /* @var Course $course */
foreach ($courses as $course) {
$item = $this->getItemByProduct(
$course->getId(),
@@ -710,7 +1128,7 @@ public function getCatalogCourseList($first, $pageSize, $name = null, $min = 0,
];
foreach ($course->getTeachersSubscriptions() as $courseUser) {
- /* @var CourseRelUser $courseUser */
+ /** @var CourseRelUser $courseUser */
$teacher = $courseUser->getUser();
$courseItem['teachers'][] = $teacher->getFullName();
}
@@ -743,22 +1161,141 @@ private function getCourseIllustrationUrl(Course $course): ?string
}
/**
- * @param $price
- * @param $isoCode
+ * Lists current user subscription session details, including each session course details.
*
- * @return string
+ * It can return the number of rows when $typeResult is 'count'.
+ *
+ * @param int $start pagination start
+ * @param int $end pagination end
+ * @param string $name Optional. The name filter.
+ * @param string $typeResult Optional. 'all', 'first' or 'count'.
+ * @param int $sessionCategory Optional. Session category id
+ *
+ * @return array|int
+ */
+ public function getCatalogSubscriptionSessionList(int $start, int $end, ?string $name = null, string $typeResult = 'all', int $sessionCategory = 0)
+ {
+ $sessions = $this->filterSubscriptionSessionList($start, $end, $name, $typeResult, $sessionCategory);
+
+ if ('count' === $typeResult) {
+ return $sessions;
+ }
+
+ $sessionCatalog = [];
+ // loop through all sessions
+ foreach ($sessions as $session) {
+ $sessionCourses = $session->getCourses();
+
+ if (empty($sessionCourses)) {
+ continue;
+ }
+
+ $item = $this->getSubscriptionItemByProduct(
+ $session->getId(),
+ self::PRODUCT_TYPE_SESSION
+ );
+
+ if (empty($item)) {
+ continue;
+ }
+
+ $sessionData = $this->getSubscriptionSessionInfo($session->getId());
+ $sessionData['coaches'] = $session->getGeneralCoaches()->map(fn (User $coach) => $coach->getFullName());
+ $sessionData['enrolled'] = $this->getUserStatusForSubscriptionSession(
+ api_get_user_id(),
+ $session
+ );
+ $sessionData['courses'] = [];
+
+ foreach ($sessionCourses as $sessionCourse) {
+ $course = $sessionCourse->getCourse();
+
+ $sessionCourseData = [
+ 'title' => $course->getTitle(),
+ 'coaches' => [],
+ ];
+
+ $userCourseSubscriptions = $session->getSessionRelCourseRelUsersByStatus(
+ $course,
+ Session::COURSE_COACH
+ );
+
+ foreach ($userCourseSubscriptions as $userCourseSubscription) {
+ $user = $userCourseSubscription->getUser();
+ $sessionCourseData['coaches'][] = $user->getFullName();
+ }
+ $sessionData['courses'][] = $sessionCourseData;
+ }
+
+ $sessionCatalog[] = $sessionData;
+ }
+
+ return $sessionCatalog;
+ }
+
+ /**
+ * Lists current user subscription course details.
+ *
+ * @param string $typeResult Optional. 'all', 'first' or 'count'.
+ *
+ * @return array|int
*/
- public function getPriceWithCurrencyFromIsoCode($price, $isoCode)
+ public function getCatalogSubscriptionCourseList(int $first, int $pageSize, ?string $name = null, string $typeResult = 'all')
+ {
+ $courses = $this->filterSubscriptionCourseList($first, $pageSize, $name, $typeResult);
+
+ if ('count' === $typeResult) {
+ return $courses;
+ }
+
+ if (empty($courses)) {
+ return [];
+ }
+
+ $courseCatalog = [];
+ foreach ($courses as $course) {
+ $item = $this->getSubscriptionItemByProduct(
+ $course->getId(),
+ self::PRODUCT_TYPE_COURSE
+ );
+
+ if (empty($item)) {
+ continue;
+ }
+
+ $courseItem = [
+ 'id' => $course->getId(),
+ 'title' => $course->getTitle(),
+ 'code' => $course->getCode(),
+ 'course_img' => null,
+ 'item' => $item,
+ 'teachers' => [],
+ 'enrolled' => $this->getUserStatusForSubscriptionCourse(api_get_user_id(), $course),
+ ];
+
+ foreach ($course->getTeachersSubscriptions() as $courseUser) {
+ $teacher = $courseUser->getUser();
+ $courseItem['teachers'][] = $teacher->getFullName();
+ }
+
+ // Check images
+ $imgUrl = $this->getCourseIllustrationUrl($course);
+ if (!empty($imgUrl)) {
+ $courseItem['course_img'] = $imgUrl;
+ }
+ $courseCatalog[] = $courseItem;
+ }
+
+ return $courseCatalog;
+ }
+
+ public function getPriceWithCurrencyFromIsoCode(float $price, string $isoCode): string
{
$useSymbol = 'true' === $this->get('use_currency_symbol');
$result = $isoCode.' '.$price;
if ($useSymbol) {
- if ('BRL' === $isoCode) {
- $symbol = 'R$';
- } else {
- $symbol = Currencies::getSymbol($isoCode);
- }
+ $symbol = 'BRL' === $isoCode ? 'R$' : Currencies::getSymbol($isoCode);
$result = $symbol.' '.$price;
}
@@ -768,12 +1305,10 @@ public function getPriceWithCurrencyFromIsoCode($price, $isoCode)
/**
* Get course info.
*
- * @param int $courseId The course ID
- *
* @return array
- * @throws Exception
+ * @throws \Doctrine\ORM\NonUniqueResultException
*/
- public function getCourseInfo($courseId)
+ public function getCourseInfo(int $courseId, ?array $coupon = null)
{
$entityManager = Database::getManager();
$course = $entityManager->find(Course::class, $courseId);
@@ -784,18 +1319,28 @@ public function getCourseInfo($courseId)
$item = $this->getItemByProduct(
$course->getId(),
- self::PRODUCT_TYPE_COURSE
+ self::PRODUCT_TYPE_COURSE,
+ $coupon
);
if (empty($item)) {
return [];
}
+ /** @var CCourseDescription $courseDescription */
+ $courseDescription = Container::getCourseDescriptionRepository()
+ ->getResourcesByCourse($course)
+ ->addOrderBy('descriptionType', 'ASC')
+ ->setMaxResults(1)
+ ->getQuery()
+ ->getOneOrNullResult()
+ ;
+
$globalParameters = $this->getGlobalParameters();
$courseInfo = [
'id' => $course->getId(),
'title' => $course->getTitle(),
- 'description' => $course->getDescription(),
+ 'description' => $courseDescription?->getContent(),
'code' => $course->getCode(),
'visual_code' => $course->getVisualCode(),
'teachers' => [],
@@ -824,12 +1369,9 @@ public function getCourseInfo($courseId)
/**
* Get session info.
*
- * @param int $sessionId The session ID
- *
* @return array
- * @throws Exception
*/
- public function getSessionInfo(int $sessionId): array
+ public function getSessionInfo(int $sessionId, ?array $coupon = null)
{
$entityManager = Database::getManager();
$session = $entityManager->find(Session::class, $sessionId);
@@ -838,7 +1380,11 @@ public function getSessionInfo(int $sessionId): array
return [];
}
- $item = $this->getItemByProduct($session->getId(), self::PRODUCT_TYPE_SESSION);
+ $item = $this->getItemByProduct(
+ $session->getId(),
+ self::PRODUCT_TYPE_SESSION,
+ $coupon
+ );
if (empty($item)) {
return [];
@@ -849,7 +1395,7 @@ public function getSessionInfo(int $sessionId): array
$globalParameters = $this->getGlobalParameters();
$sessionInfo = [
'id' => $session->getId(),
- 'name' => $session->getTitle(),
+ 'name' => $session->getName(),
'description' => $session->getDescription(),
'dates' => $sessionDates,
'courses' => [],
@@ -859,6 +1405,7 @@ public function getSessionInfo(int $sessionId): array
'nbrCourses' => $session->getNbrCourses(),
'nbrUsers' => $session->getNbrUsers(),
'item' => $item,
+ 'duration' => $session->getDuration(),
];
$imgUrl = $this->getSessionIllustrationUrl($session);
@@ -876,12 +1423,12 @@ public function getSessionInfo(int $sessionId): array
$userCourseSubscriptions = $session->getSessionRelCourseRelUsersByStatus(
$course,
- Chamilo\CoreBundle\Entity\Session::COURSE_COACH
+ Session::COURSE_COACH
);
foreach ($userCourseSubscriptions as $userCourseSubscription) {
$user = $userCourseSubscription->getUser();
- $coaches['id'] = $user->getUserId();
+ $coaches['id'] = $user->getId();
$coaches['name'] = $user->getFullName();
$sessionCourseData['coaches'][] = $coaches;
}
@@ -910,69 +1457,232 @@ private function getSessionIllustrationUrl(Session $session): ?string
}
/**
- * Register a sale.
- *
- * @param int $itemId The product ID
- * @param int $paymentType The payment type
+ * Get course info.
*
- * @return bool
+ * @throws \Doctrine\ORM\NonUniqueResultException
*/
- public function registerSale($itemId, $paymentType)
+ public function getSubscriptionCourseInfo(int $courseId, ?array $coupon = null): array
{
- if (!in_array(
- $paymentType,
- [self::PAYMENT_TYPE_PAYPAL, self::PAYMENT_TYPE_TRANSFER, self::PAYMENT_TYPE_CULQI]
- )
- ) {
- return false;
+ $entityManager = Database::getManager();
+ $course = $entityManager->find(Course::class, $courseId);
+
+ if (empty($course)) {
+ return [];
}
- $entityManager = Database::getManager();
- $item = $this->getItem($itemId);
+ $item = $this->getSubscriptionItemByProduct(
+ $course->getId(),
+ self::PRODUCT_TYPE_COURSE,
+ $coupon
+ );
if (empty($item)) {
- return false;
+ return [];
}
- $productName = '';
- if (self::PRODUCT_TYPE_COURSE == $item['product_type']) {
- $course = $entityManager->find(Course::class, $item['product_id']);
-
- if (empty($course)) {
- return false;
- }
+ /** @var CCourseDescription $courseDescription */
+ $courseDescription = Container::getCourseDescriptionRepository()
+ ->getResourcesByCourse($course)
+ ->addOrderBy('descriptionType', 'ASC')
+ ->setMaxResults(1)
+ ->getQuery()
+ ->getOneOrNullResult()
+ ;
- $productName = $course->getTitle();
- } elseif (self::PRODUCT_TYPE_SESSION == $item['product_type']) {
- $session = $entityManager->find(Session::class, $item['product_id']);
+ $globalParameters = $this->getGlobalParameters();
+ $courseInfo = [
+ 'id' => $course->getId(),
+ 'title' => $course->getTitle(),
+ 'description' => $courseDescription?->getContent(),
+ 'code' => $course->getCode(),
+ 'visual_code' => $course->getVisualCode(),
+ 'teachers' => [],
+ 'item' => $item,
+ 'tax_name' => $globalParameters['tax_name'],
+ 'tax_enable' => $this->checkTaxEnabledInProduct(self::TAX_APPLIES_TO_ONLY_COURSE),
+ 'course_img' => null,
+ ];
- if (empty($session)) {
- return false;
- }
+ $courseTeachers = $course->getTeachersSubscriptions();
- $productName = $session->getTitle();
+ foreach ($courseTeachers as $teachers) {
+ $user = $teachers->getUser();
+ $teacher['id'] = $user->getId();
+ $teacher['name'] = $user->getFullName();
+ $courseInfo['teachers'][] = $teacher;
}
- $price = $item['price'];
- $priceWithoutTax = null;
- $taxPerc = null;
- $taxAmount = 0;
- $taxEnable = 'true' === $this->get('tax_enable');
- $globalParameters = $this->getGlobalParameters();
- $taxAppliesTo = $globalParameters['tax_applies_to'];
+ $imgUrl = $this->getCourseIllustrationUrl($course);
- if ($taxEnable &&
- (
- self::TAX_APPLIES_TO_ALL == $taxAppliesTo ||
- (self::TAX_APPLIES_TO_ONLY_COURSE == $taxAppliesTo && self::PRODUCT_TYPE_COURSE == $item['product_type']) ||
- (self::TAX_APPLIES_TO_ONLY_SESSION == $taxAppliesTo && self::PRODUCT_TYPE_SESSION == $item['product_type'])
+ if (!empty($imgUrl)) {
+ $courseInfo['course_img'] = $imgUrl;
+ }
+
+ return $courseInfo;
+ }
+
+ /**
+ * Get session info.
+ *
+ * @param array $sessionId The session ID
+ *
+ * @return array
+ */
+ public function getSubscriptionSessionInfo(int $sessionId, ?array $coupon = null)
+ {
+ $entityManager = Database::getManager();
+ $session = $entityManager->find(Session::class, $sessionId);
+
+ if (empty($session)) {
+ return [];
+ }
+
+ $item = $this->getSubscriptionItemByProduct(
+ $session->getId(),
+ self::PRODUCT_TYPE_SESSION,
+ $coupon
+ );
+
+ if (empty($item)) {
+ return [];
+ }
+
+ $sessionDates = SessionManager::parseSessionDates($session);
+
+ $globalParameters = $this->getGlobalParameters();
+ $sessionInfo = [
+ 'id' => $session->getId(),
+ 'name' => $session->getName(),
+ 'description' => $session->getDescription(),
+ 'dates' => $sessionDates,
+ 'courses' => [],
+ 'tax_name' => $globalParameters['tax_name'],
+ 'tax_enable' => $this->checkTaxEnabledInProduct(self::TAX_APPLIES_TO_ONLY_SESSION),
+ 'image' => null,
+ 'nbrCourses' => $session->getNbrCourses(),
+ 'nbrUsers' => $session->getNbrUsers(),
+ 'item' => $item,
+ 'duration' => $session->getDuration(),
+ ];
+
+ $imgUrl = $this->getSessionIllustrationUrl($session);
+ if (!empty($imgUrl)) {
+ $sessionInfo['image'] = $imgUrl;
+ }
+
+ $sessionCourses = $session->getCourses();
+ foreach ($sessionCourses as $sessionCourse) {
+ $course = $sessionCourse->getCourse();
+ $sessionCourseData = [
+ 'title' => $course->getTitle(),
+ 'coaches' => [],
+ ];
+
+ $userCourseSubscriptions = $session->getSessionRelCourseRelUsersByStatus(
+ $course,
+ Session::COURSE_COACH
+ );
+
+ foreach ($userCourseSubscriptions as $userCourseSubscription) {
+ $user = $userCourseSubscription->getUser();
+ $coaches['id'] = $user->getId();
+ $coaches['name'] = $user->getFullName();
+ $sessionCourseData['coaches'][] = $coaches;
+ }
+
+ $sessionInfo['courses'][] = $sessionCourseData;
+ }
+
+ return $sessionInfo;
+ }
+
+ /**
+ * Register a sale.
+ *
+ * @param int $itemId The product ID
+ * @param int $paymentType The payment type
+ * @param int $couponId The coupon ID
+ */
+ public function registerSale(int $itemId, int $paymentType, ?int $couponId = null): ?int
+ {
+ if (!in_array(
+ $paymentType,
+ [
+ self::PAYMENT_TYPE_PAYPAL,
+ self::PAYMENT_TYPE_TRANSFER,
+ self::PAYMENT_TYPE_CULQI,
+ self::PAYMENT_TYPE_TPV_REDSYS,
+ self::PAYMENT_TYPE_STRIPE,
+ self::PAYMENT_TYPE_TPV_CECABANK,
+ ]
+ )
+ ) {
+ return null;
+ }
+
+ $entityManager = Database::getManager();
+ $item = $this->getItem($itemId);
+
+ if (empty($item)) {
+ return null;
+ }
+
+ $productName = '';
+ if (self::PRODUCT_TYPE_COURSE == $item['product_type']) {
+ $course = $entityManager->find(Course::class, $item['product_id']);
+
+ if (empty($course)) {
+ return null;
+ }
+
+ $productName = $course->getTitle();
+ } elseif (self::PRODUCT_TYPE_SESSION == $item['product_type']) {
+ $session = $entityManager->find(Session::class, $item['product_id']);
+
+ if (empty($session)) {
+ return null;
+ }
+
+ $productName = $session->getName();
+ }
+
+ $coupon = null;
+
+ if (null != $couponId) {
+ $coupon = $this->getCoupon($couponId, $item['product_type'], $item['product_id']);
+ }
+
+ $couponDiscount = 0;
+ $priceWithoutDiscount = 0;
+ if (null != $coupon) {
+ if (self::COUPON_DISCOUNT_TYPE_AMOUNT == $coupon['discount_type']) {
+ $couponDiscount = $coupon['discount_amount'];
+ } elseif (self::COUPON_DISCOUNT_TYPE_PERCENTAGE == $coupon['discount_type']) {
+ $couponDiscount = ($item['price'] * $coupon['discount_amount']) / 100;
+ }
+ $priceWithoutDiscount = $item['price'];
+ }
+ $item['price'] -= $couponDiscount;
+ $price = $item['price'];
+ $priceWithoutTax = null;
+ $taxPerc = null;
+ $taxAmount = 0;
+ $taxEnable = 'true' === $this->get('tax_enable');
+ $globalParameters = $this->getGlobalParameters();
+ $taxAppliesTo = $globalParameters['tax_applies_to'];
+
+ if ($taxEnable
+ && (
+ self::TAX_APPLIES_TO_ALL == $taxAppliesTo
+ || (self::TAX_APPLIES_TO_ONLY_COURSE == $taxAppliesTo && self::PRODUCT_TYPE_COURSE == $item['product_type'])
+ || (self::TAX_APPLIES_TO_ONLY_SESSION == $taxAppliesTo && self::PRODUCT_TYPE_SESSION == $item['product_type'])
)
) {
$priceWithoutTax = $item['price'];
$globalTaxPerc = $globalParameters['global_tax_perc'];
$precision = 2;
- $taxPerc = is_null($item['tax_perc']) ? $globalTaxPerc : $item['tax_perc'];
- $taxAmount = round($priceWithoutTax * $taxPerc / 100, $precision, PHP_ROUND_HALF_UP);
+ $taxPerc = null === $item['tax_perc'] ? $globalTaxPerc : $item['tax_perc'];
+ $taxAmount = round($priceWithoutTax * $taxPerc / 100, $precision);
$price = $priceWithoutTax + $taxAmount;
}
@@ -993,21 +1703,36 @@ public function registerSale($itemId, $paymentType)
'tax_perc' => $taxPerc,
'tax_amount' => $taxAmount,
'status' => self::SALE_STATUS_PENDING,
- 'payment_type' => (int) $paymentType,
- 'invoice' => 0, //default value if no invoice
+ 'payment_type' => $paymentType,
+ 'price_without_discount' => $priceWithoutDiscount,
+ 'discount_amount' => $couponDiscount,
];
return Database::insert(self::TABLE_SALE, $values);
}
/**
- * Get sale data by ID.
+ * Update the sale reference.
*
- * @param int $saleId The sale ID
+ * @return bool
+ */
+ public function updateSaleReference(int $saleId, string $saleReference)
+ {
+ $saleTable = Database::get_main_table(self::TABLE_SALE);
+
+ return Database::update(
+ $saleTable,
+ ['reference' => $saleReference],
+ ['id = ?' => $saleId]
+ );
+ }
+
+ /**
+ * Get sale data by ID.
*
* @return array
*/
- public function getSale($saleId)
+ public function getSale(int $saleId)
{
return Database::select(
'*',
@@ -1019,14 +1744,31 @@ public function getSale($saleId)
);
}
+ /**
+ * Get sale data by reference.
+ *
+ * @return array
+ */
+ public function getSaleFromReference(string $reference)
+ {
+ return Database::select(
+ '*',
+ Database::get_main_table(self::TABLE_SALE),
+ [
+ 'where' => ['reference = ?' => $reference],
+ ],
+ 'first'
+ );
+ }
+
/**
* Get a list of sales by the payment type.
*
* @param int $paymentType The payment type to filter (default : Paypal)
*
- * @return array The sale list. Otherwise return false
+ * @return array The sale list. Otherwise, return false
*/
- public function getSaleListByPaymentType($paymentType = self::PAYMENT_TYPE_PAYPAL)
+ public function getSaleListByPaymentType(int $paymentType = self::PAYMENT_TYPE_PAYPAL)
{
$saleTable = Database::get_main_table(self::TABLE_SALE);
$currencyTable = Database::get_main_table(self::TABLE_CURRENCY);
@@ -1043,7 +1785,7 @@ public function getSaleListByPaymentType($paymentType = self::PAYMENT_TYPE_PAYPA
[
'where' => [
's.payment_type = ? AND s.status = ?' => [
- (int) $paymentType,
+ $paymentType,
self::SALE_STATUS_COMPLETED,
],
],
@@ -1060,7 +1802,7 @@ public function getSaleListByPaymentType($paymentType = self::PAYMENT_TYPE_PAYPA
*
* @return array The sale data
*/
- public function getDataSaleInvoice($saleId, $isService)
+ public function getDataSaleInvoice(int $saleId, int $isService)
{
if ($isService) {
$sale = $this->getServiceSale($saleId);
@@ -1084,7 +1826,7 @@ public function getDataSaleInvoice($saleId, $isService)
*
* @return array The invoice data
*/
- public function getDataInvoice($saleId, $isService)
+ public function getDataInvoice(int $saleId, int $isService)
{
return Database::select(
'*',
@@ -1107,7 +1849,7 @@ public function getDataInvoice($saleId, $isService)
*
* @return string
*/
- public function getNumInvoice($saleId, $isService)
+ public function getNumInvoice(int $saleId, int $isService)
{
$dataInvoice = $this->getDataInvoice($saleId, $isService);
if (empty($dataInvoice)) {
@@ -1124,13 +1866,13 @@ public function getNumInvoice($saleId, $isService)
*
* @return array
*/
- public function getCurrency($currencyId)
+ public function getCurrency(int $currencyId)
{
return Database::select(
'*',
Database::get_main_table(self::TABLE_CURRENCY),
[
- 'where' => ['id = ?' => (int) $currencyId],
+ 'where' => ['id = ?' => $currencyId],
],
'first'
);
@@ -1139,11 +1881,9 @@ public function getCurrency($currencyId)
/**
* Complete sale process. Update sale status to completed.
*
- * @param int $saleId The sale ID
- *
* @return bool
*/
- public function completeSale($saleId)
+ public function completeSale(int $saleId)
{
$sale = $this->getSale($saleId);
@@ -1152,10 +1892,14 @@ public function completeSale($saleId)
}
$saleIsCompleted = false;
+
switch ($sale['product_type']) {
case self::PRODUCT_TYPE_COURSE:
- $saleIsCompleted = CourseManager::subscribeUser($sale['user_id'], $sale['product_id']);
+ $course = api_get_course_info_by_id($sale['product_id']);
+ $saleIsCompleted = CourseManager::subscribeUser($sale['user_id'], $course['code']);
+
break;
+
case self::PRODUCT_TYPE_SESSION:
SessionManager::subscribeUsersToSession(
$sale['product_id'],
@@ -1165,6 +1909,7 @@ public function completeSale($saleId)
);
$saleIsCompleted = true;
+
break;
}
@@ -1183,23 +1928,56 @@ public function completeSale($saleId)
*
* @param int $saleId The sale ID
*/
- public function cancelSale($saleId)
+ public function cancelSale(int $saleId): void
{
$this->updateSaleStatus($saleId, self::SALE_STATUS_CANCELED);
}
/**
* Get payment types.
- *
- * @return array
*/
- public function getPaymentTypes()
+ public function getPaymentTypes(bool $onlyActive = false): array
{
- return [
+ $types = [
self::PAYMENT_TYPE_PAYPAL => 'PayPal',
self::PAYMENT_TYPE_TRANSFER => $this->get_lang('BankTransfer'),
self::PAYMENT_TYPE_CULQI => 'Culqi',
+ self::PAYMENT_TYPE_TPV_REDSYS => $this->get_lang('TpvPayment'),
+ self::PAYMENT_TYPE_STRIPE => 'Stripe',
+ self::PAYMENT_TYPE_TPV_CECABANK => $this->get_lang('TpvCecabank'),
];
+
+ if (!$onlyActive) {
+ return $types;
+ }
+
+ if ('true' !== $this->get('paypal_enable')) {
+ unset($types[self::PAYMENT_TYPE_PAYPAL]);
+ }
+
+ if ('true' !== $this->get('transfer_enable')) {
+ unset($types[self::PAYMENT_TYPE_TRANSFER]);
+ }
+
+ if ('true' !== $this->get('culqi_enable')) {
+ unset($types[self::PAYMENT_TYPE_CULQI]);
+ }
+
+ if ('true' !== $this->get('tpv_redsys_enable')
+ || !file_exists(api_get_path(SYS_PLUGIN_PATH).'buycourses/resources/apiRedsys.php')
+ ) {
+ unset($types[self::PAYMENT_TYPE_TPV_REDSYS]);
+ }
+
+ if ('true' !== $this->get('stripe_enable')) {
+ unset($types[self::PAYMENT_TYPE_STRIPE]);
+ }
+
+ if ('true' !== $this->get('cecabank_enable')) {
+ unset($types[self::PAYMENT_TYPE_TPV_CECABANK]);
+ }
+
+ return $types;
}
/**
@@ -1208,7 +1986,7 @@ public function getPaymentTypes()
* @param int $saleId The sale ID
* @param int $isService The service type to filter (default : 0)
*/
- public function setInvoice($saleId, $isService = 0)
+ public function setInvoice(int $saleId, int $isService = 0): void
{
$invoiceTable = Database::get_main_table(self::TABLE_INVOICE);
$year = date('Y');
@@ -1284,9 +2062,9 @@ public function getTaxAppliesTo()
*
* @param int $status The status to filter
*
- * @return array The sale list. Otherwise return false
+ * @return array The sale list. Otherwise, return false
*/
- public function getSaleListByStatus($status = self::SALE_STATUS_PENDING)
+ public function getSaleListByStatus(int $status = self::SALE_STATUS_PENDING)
{
$saleTable = Database::get_main_table(self::TABLE_SALE);
$currencyTable = Database::get_main_table(self::TABLE_CURRENCY);
@@ -1301,7 +2079,7 @@ public function getSaleListByStatus($status = self::SALE_STATUS_PENDING)
['c.iso_code', 'u.firstname', 'u.lastname', 'u.email', 's.*'],
"$saleTable s $innerJoins",
[
- 'where' => ['s.status = ?' => (int) $status],
+ 'where' => ['s.status = ?' => $status],
'order' => 'id DESC',
]
);
@@ -1310,14 +2088,11 @@ public function getSaleListByStatus($status = self::SALE_STATUS_PENDING)
/**
* Get the list statuses for sales.
*
- * @param string $dateStart
- * @param string $dateEnd
+ * @return array
*
* @throws Exception
- *
- * @return array
*/
- public function getSaleListReport($dateStart = null, $dateEnd = null)
+ public function getSaleListReport(?string $dateStart = null, ?string $dateEnd = null)
{
$saleTable = Database::get_main_table(self::TABLE_SALE);
$currencyTable = Database::get_main_table(self::TABLE_CURRENCY);
@@ -1340,15 +2115,21 @@ public function getSaleListReport($dateStart = null, $dateEnd = null)
$productTypes = $this->getProductTypes();
foreach ($list as $item) {
$statusSaleOrder = $item['status'];
+
switch ($statusSaleOrder) {
case 0:
$textStatus = $this->get_lang('SaleStatusPending');
+
break;
+
case 1:
$textStatus = $this->get_lang('SaleStatusCompleted');
+
break;
+
case -1:
$textStatus = $this->get_lang('SaleStatusCanceled');
+
break;
}
$dateFilter = new DateTime($item['date']);
@@ -1376,10 +2157,10 @@ public function getSaleListReport($dateStart = null, $dateEnd = null)
$this->get_lang('SalePrice'),
$this->get_lang('ProductType'),
$this->get_lang('ProductName'),
- get_lang('Username'),
- get_lang('E-mail'),
+ $this->get_lang('UserName'),
+ get_lang('Email'),
];
- //Validation Export
+ // Validation Export
$dateStart = strtotime($dateStart);
$dateEnd = strtotime($dateEnd);
foreach ($listExportTemp as $item) {
@@ -1459,22 +2240,46 @@ public function getServiceTypes()
];
}
+ /**
+ * Get the list of coupon status.
+ *
+ * @return array
+ */
+ public function getCouponStatuses()
+ {
+ return [
+ self::COUPON_STATUS_ACTIVE => $this->get_lang('CouponActive'),
+ self::COUPON_STATUS_DISABLE => $this->get_lang('CouponDisabled'),
+ ];
+ }
+
+ /**
+ * Get the list of coupon discount types.
+ *
+ * @return array
+ */
+ public function getCouponDiscountTypes()
+ {
+ return [
+ self::COUPON_DISCOUNT_TYPE_PERCENTAGE => $this->get_lang('CouponPercentage'),
+ self::COUPON_DISCOUNT_TYPE_AMOUNT => $this->get_lang('CouponAmount'),
+ ];
+ }
+
/**
* Generates a random text (used for order references).
*
- * @param int $length Optional. Length of characters
+ * @param int $length Optional. Length of characters (defaults to 6)
* @param bool $lowercase Optional. Include lowercase characters
* @param bool $uppercase Optional. Include uppercase characters
* @param bool $numbers Optional. Include numbers
- *
- * @return string
*/
public static function randomText(
- $length = 6,
- $lowercase = true,
- $uppercase = true,
- $numbers = true
- ) {
+ int $length = 6,
+ bool $lowercase = true,
+ bool $uppercase = true,
+ bool $numbers = true
+ ): string {
$salt = $lowercase ? 'abchefghknpqrstuvwxyz' : '';
$salt .= $uppercase ? 'ACDEFHKNPRSTUVWXYZ' : '';
$salt .= $numbers ? (strlen($salt) ? '2345679' : '0123456789') : '';
@@ -1485,7 +2290,7 @@ public static function randomText(
$str = '';
- srand((float) microtime() * 1000000);
+ srand(microtime() * 1000000);
for ($i = 0; $i < $length; $i++) {
$numbers = rand(0, strlen($salt) - 1);
@@ -1501,10 +2306,8 @@ public static function randomText(
* @param int $userId The user ID
* @param int $productType The course/session type
* @param int $productId The course/session ID
- *
- * @return string
*/
- public function generateReference($userId, $productType, $productId)
+ public function generateReference(int $userId, int $productType, int $productId): string
{
return vsprintf(
'%d-%d-%d-%s',
@@ -1517,9 +2320,9 @@ public function generateReference($userId, $productType, $productId)
*
* @param string $term The search term
*
- * @return array The sale list. Otherwise return false
+ * @return array The sale list. Otherwise, return false
*/
- public function getSaleListByUser($term)
+ public function getSaleListByUser(string $term)
{
$term = trim($term);
@@ -1554,9 +2357,9 @@ public function getSaleListByUser($term)
*
* @param int $id The user id
*
- * @return array The sale list. Otherwise return false
+ * @return array The sale list. Otherwise, return false
*/
- public function getSaleListByUserId($id)
+ public function getSaleListByUserId(int $id)
{
if (empty($id)) {
return [];
@@ -1586,12 +2389,9 @@ public function getSaleListByUserId($id)
/**
* Get a list of sales by date range.
*
- * @param string $dateStart
- * @param string $dateEnd
- *
- * @return array The sale list. Otherwise return false
+ * @return array The sale list. Otherwise, return false
*/
- public function getSaleListByDate($dateStart, $dateEnd)
+ public function getSaleListByDate(string $dateStart, string $dateEnd)
{
$dateStart = trim($dateStart);
$dateEnd = trim($dateEnd);
@@ -1627,9 +2427,9 @@ public function getSaleListByDate($dateStart, $dateEnd)
*
* @param string $term The search term
*
- * @return array The sale list. Otherwise return false
+ * @return array The sale list. Otherwise, return false
*/
- public function getSaleListByEmail($term)
+ public function getSaleListByEmail(string $term)
{
$term = trim($term);
if (empty($term)) {
@@ -1661,9 +2461,8 @@ public function getSaleListByEmail($term)
* @param array $defaultCurrency Optional. Currency data
*
* @return array
- * @throws Exception
*/
- public function getCourseForConfiguration(Course $course, $defaultCurrency = null)
+ public function getCourseForConfiguration(Course $course, ?array $defaultCurrency = null)
{
$courseItem = [
'item_id' => null,
@@ -1681,7 +2480,7 @@ public function getCourseForConfiguration(Course $course, $defaultCurrency = nul
$item = $this->getItemByProduct($course->getId(), self::PRODUCT_TYPE_COURSE);
- if (!empty($item)) {
+ if (false !== $item) {
$courseItem['item_id'] = $item['id'];
$courseItem['visible'] = true;
$courseItem['currency'] = $item['iso_code'];
@@ -1700,7 +2499,7 @@ public function getCourseForConfiguration(Course $course, $defaultCurrency = nul
*
* @return array
*/
- public function getSessionForConfiguration(Session $session, $defaultCurrency = null)
+ public function getSessionForConfiguration(Session $session, ?array $defaultCurrency = null)
{
$buyItemTable = Database::get_main_table(self::TABLE_ITEM);
$buyCurrencyTable = Database::get_main_table(self::TABLE_CURRENCY);
@@ -1713,7 +2512,7 @@ public function getSessionForConfiguration(Session $session, $defaultCurrency =
$sessionItem = [
'item_id' => null,
'session_id' => $session->getId(),
- 'session_name' => $session->getTitle(),
+ 'session_name' => $session->getName(),
'session_visibility' => $session->getVisibility(),
'session_display_start_date' => null,
'session_display_end_date' => null,
@@ -1768,9 +2567,9 @@ public function getSessionForConfiguration(Session $session, $defaultCurrency =
*
* @param int $itemId The item ID
*
- * @return array The beneficiaries. Otherwise return false
+ * @return array The beneficiaries. Otherwise, return false
*/
- public function getItemBeneficiaries($itemId)
+ public function getItemBeneficiaries(int $itemId)
{
$beneficiaryTable = Database::get_main_table(self::TABLE_ITEM_BENEFICIARY);
@@ -1779,7 +2578,7 @@ public function getItemBeneficiaries($itemId)
$beneficiaryTable,
[
'where' => [
- 'item_id = ?' => (int) $itemId,
+ 'item_id = ?' => $itemId,
],
]
);
@@ -1790,14 +2589,14 @@ public function getItemBeneficiaries($itemId)
*
* @param int $itemId The item ID
*
- * @return int The number of affected rows. Otherwise return false
+ * @return int The number of affected rows. Otherwise, return false
*/
- public function deleteItem($itemId)
+ public function deleteItem(int $itemId)
{
$itemTable = Database::get_main_table(self::TABLE_ITEM);
$affectedRows = Database::delete(
$itemTable,
- ['id = ?' => (int) $itemId]
+ ['id = ?' => $itemId]
);
if (!$affectedRows) {
@@ -1812,7 +2611,7 @@ public function deleteItem($itemId)
*
* @param array $itemData The item data
*
- * @return int The item ID. Otherwise return false
+ * @return int The item ID. Otherwise, return false
*/
public function registerItem(array $itemData)
{
@@ -1828,9 +2627,9 @@ public function registerItem(array $itemData)
* @param int $productId The product ID
* @param int $productType The type of product
*
- * @return int The number of affected rows. Otherwise return false
+ * @return int The number of affected rows. Otherwise, return false
*/
- public function updateItem(array $itemData, $productId, $productType)
+ public function updateItem(array $itemData, int $productId, int $productType)
{
$itemTable = Database::get_main_table(self::TABLE_ITEM);
@@ -1838,7 +2637,7 @@ public function updateItem(array $itemData, $productId, $productType)
$itemTable,
$itemData,
[
- 'product_id = ? AND ' => (int) $productId,
+ 'product_id = ? AND ' => $productId,
'product_type' => $productType,
]
);
@@ -1849,15 +2648,15 @@ public function updateItem(array $itemData, $productId, $productType)
*
* @param int $itemId The user ID
*
- * @return int The number of affected rows. Otherwise return false
+ * @return int The number of affected rows. Otherwise, return false
*/
- public function deleteItemBeneficiaries($itemId)
+ public function deleteItemBeneficiaries(int $itemId)
{
$beneficiaryTable = Database::get_main_table(self::TABLE_ITEM_BENEFICIARY);
return Database::delete(
$beneficiaryTable,
- ['item_id = ?' => (int) $itemId]
+ ['item_id = ?' => $itemId]
);
}
@@ -1867,7 +2666,7 @@ public function deleteItemBeneficiaries($itemId)
* @param int $itemId The item ID
* @param array $userIds The beneficiary user ID and Teachers commissions if enabled
*/
- public function registerItemBeneficiaries($itemId, array $userIds)
+ public function registerItemBeneficiaries(int $itemId, array $userIds): void
{
$beneficiaryTable = Database::get_main_table(self::TABLE_ITEM_BENEFICIARY);
@@ -1877,7 +2676,7 @@ public function registerItemBeneficiaries($itemId, array $userIds)
Database::insert(
$beneficiaryTable,
[
- 'item_id' => (int) $itemId,
+ 'item_id' => $itemId,
'user_id' => (int) $userId,
'commissions' => (int) $commissions,
]
@@ -1911,17 +2710,13 @@ public function isValidCourse(Course $course)
* @param int $saleId The sale ID
*
* @return array
- * @throws Exception
*/
- public function getBeneficiariesBySale(int $saleId): array
+ public function getBeneficiariesBySale(int $saleId)
{
$sale = $this->getSale($saleId);
$item = $this->getItemByProduct($sale['product_id'], $sale['product_type']);
- if (!empty($item)) {
- return $this->getItemBeneficiaries($item['id']);
- }
- return [];
+ return $this->getItemBeneficiaries($item['id']);
}
/**
@@ -1929,7 +2724,6 @@ public function getBeneficiariesBySale(int $saleId): array
*
* @param int $status - default 0 - pending
* @param int $payoutId - for get an individual payout if want all then false
- * @param int $userId
*
* @return array
*/
@@ -1937,10 +2731,9 @@ public function getPayouts(
int $status = self::PAYOUT_STATUS_PENDING,
int $payoutId = 0,
int $userId = 0
- ): array
- {
- $condition = ($payoutId > 0) ? 'AND p.id = '.$payoutId : '';
- $condition2 = ($userId > 0) ? ' AND p.user_id = '.$userId : '';
+ ) {
+ $condition = ($payoutId) ? 'AND p.id = '.($payoutId) : '';
+ $condition2 = ($userId) ? ' AND p.user_id = '.($userId) : '';
$typeResult = ($condition) ? 'first' : 'all';
$payoutsTable = Database::get_main_table(self::TABLE_PAYPAL_PAYOUTS);
$saleTable = Database::get_main_table(self::TABLE_SALE);
@@ -1950,7 +2743,7 @@ public function getPayouts(
$extraFieldValues = Database::get_main_table(TABLE_EXTRA_FIELD_VALUES);
$paypalExtraField = Database::select(
- "*",
+ '*',
$extraFieldTable,
[
'where' => ['variable = ?' => 'paypal'],
@@ -1967,29 +2760,25 @@ public function getPayouts(
INNER JOIN $saleTable s ON s.id = p.sale_id
INNER JOIN $currencyTable c ON s.currency_id = c.id
LEFT JOIN $extraFieldValues efv ON p.user_id = efv.item_id
- AND field_id = ".((int) $paypalExtraField['id'])."
- ";
+ AND field_id = ".((int) $paypalExtraField['id']).'
+ ';
- $payouts = Database::select(
- "p.* , u.firstname, u.lastname, efv.field_value as paypal_account, s.reference as sale_reference, s.price as item_price, c.iso_code",
+ return Database::select(
+ 'p.* , u.firstname, u.lastname, efv.value as paypal_account, s.reference as sale_reference, s.price as item_price, c.iso_code',
"$payoutsTable p $innerJoins",
[
'where' => ['p.status = ? '.$condition.' '.$condition2 => $status],
],
$typeResult
);
-
- return $payouts;
}
/**
* Verify if the beneficiary have a paypal account.
*
- * @param int $userId
- *
* @return true if the user have a paypal account, false if not
*/
- public function verifyPaypalAccountByBeneficiary($userId)
+ public function verifyPaypalAccountByBeneficiary(int $userId)
{
$extraFieldTable = Database::get_main_table(TABLE_EXTRA_FIELD);
$extraFieldValues = Database::get_main_table(TABLE_EXTRA_FIELD_VALUES);
@@ -2009,10 +2798,10 @@ public function verifyPaypalAccountByBeneficiary($userId)
$paypalFieldId = $paypalExtraField['id'];
$paypalAccount = Database::select(
- 'field_value',
+ 'value',
$extraFieldValues,
[
- 'where' => ['field_id = ? AND item_id = ?' => [(int) $paypalFieldId, (int) $userId]],
+ 'where' => ['field_id = ? AND item_id = ?' => [(int) $paypalFieldId, $userId]],
],
'first'
);
@@ -2021,7 +2810,7 @@ public function verifyPaypalAccountByBeneficiary($userId)
return false;
}
- if ('' === $paypalAccount['field_value']) {
+ if ('' === $paypalAccount['value']) {
return false;
}
@@ -2031,11 +2820,9 @@ public function verifyPaypalAccountByBeneficiary($userId)
/**
* Register the users payouts.
*
- * @param int $saleId The sale ID
- *
* @return array
*/
- public function storePayouts($saleId)
+ public function storePayouts(int $saleId)
{
$payoutsTable = Database::get_main_table(self::TABLE_PAYPAL_PAYOUTS);
$platformCommission = $this->getPlatformCommission();
@@ -2043,7 +2830,7 @@ public function storePayouts($saleId)
$sale = $this->getSale($saleId);
$commission = (int) $platformCommission['commission'];
$teachersCommission = number_format(
- (floatval($sale['price']) * $commission) / 100,
+ ((float) $sale['price'] * $commission) / 100,
2
);
@@ -2054,11 +2841,11 @@ public function storePayouts($saleId)
$payoutsTable,
[
'date' => $sale['date'],
- 'payout_date' => getdate(),
- 'sale_id' => (int) $saleId,
+ 'payout_date' => api_get_utc_datetime(),
+ 'sale_id' => $saleId,
'user_id' => $beneficiary['user_id'],
'commission' => number_format(
- (floatval($teachersCommission) * $beneficiaryCommission) / 100,
+ ((float) $teachersCommission * $beneficiaryCommission) / 100,
2
),
'status' => self::PAYOUT_STATUS_PENDING,
@@ -2070,27 +2857,66 @@ public function storePayouts($saleId)
/**
* Register the users payouts.
*
- * @param int $payoutId The payout ID
- * @param int $status The status to set (-1 to cancel, 0 to pending, 1 to completed)
+ * @param int $saleId The subscription sale ID
*
* @return array
*/
- public function setStatusPayouts($payoutId, $status)
+ public function storeSubscriptionPayouts(int $saleId)
{
$payoutsTable = Database::get_main_table(self::TABLE_PAYPAL_PAYOUTS);
+ $platformCommission = $this->getPlatformCommission();
- Database::update(
- $payoutsTable,
- ['status' => (int) $status],
- ['id = ?' => (int) $payoutId]
+ $sale = $this->getSubscriptionSale($saleId);
+ $commission = (int) $platformCommission['commission'];
+ $teachersCommission = number_format(
+ ((float) $sale['price'] * $commission) / 100,
+ 2
);
+
+ $beneficiaries = $this->getBeneficiariesBySale($saleId);
+ foreach ($beneficiaries as $beneficiary) {
+ $beneficiaryCommission = (int) $beneficiary['commissions'];
+ Database::insert(
+ $payoutsTable,
+ [
+ 'date' => $sale['date'],
+ 'payout_date' => api_get_utc_datetime(),
+ 'sale_id' => $saleId,
+ 'user_id' => $beneficiary['user_id'],
+ 'commission' => number_format(
+ ((float) $teachersCommission * $beneficiaryCommission) / 100,
+ 2
+ ),
+ 'status' => self::PAYOUT_STATUS_PENDING,
+ ]
+ );
+ }
}
/**
- * Gets the stored platform commission params.
+ * Register the users payouts.
*
- * @return array
- */
+ * @param int $payoutId The payout ID
+ * @param int $status The status to set (-1 to cancel, 0 to pending, 1 to completed)
+ *
+ * @return array
+ */
+ public function setStatusPayouts(int $payoutId, int $status)
+ {
+ $payoutsTable = Database::get_main_table(self::TABLE_PAYPAL_PAYOUTS);
+
+ Database::update(
+ $payoutsTable,
+ ['status' => (int) $status],
+ ['id = ?' => (int) $payoutId]
+ );
+ }
+
+ /**
+ * Gets the stored platform commission params.
+ *
+ * @return array
+ */
public function getPlatformCommission()
{
return Database::select(
@@ -2104,11 +2930,11 @@ public function getPlatformCommission()
/**
* Update the platform commission.
*
- * @param int $params platform commission
+ * @param array $params platform commission
*
- * @return int The number of affected rows. Otherwise return false
+ * @return int The number of affected rows. Otherwise, return false
*/
- public function updateCommission($params)
+ public function updateCommission(array $params)
{
$commissionTable = Database::get_main_table(self::TABLE_COMMISSION);
@@ -2125,14 +2951,14 @@ public function updateCommission($params)
*
* @return mixed response
*/
- public function storeService($service)
+ public function storeService(array $service)
{
$servicesTable = Database::get_main_table(self::TABLE_SERVICES);
$return = Database::insert(
$servicesTable,
[
- 'title' => Security::remove_XSS($service['name']),
+ 'name' => Security::remove_XSS($service['name']),
'description' => Security::remove_XSS($service['description']),
'price' => $service['price'],
'tax_perc' => '' != $service['tax_perc'] ? (int) $service['tax_perc'] : null,
@@ -2146,19 +2972,19 @@ public function storeService($service)
]
);
- if ($return && !empty($service['picture_crop_image_base_64']) &&
- !empty($service['picture_crop_result'])
+ if ($return && !empty($service['picture_crop_image_base_64'])
+ && !empty($service['picture_crop_result'])
) {
$img = str_replace('data:image/png;base64,', '', $service['picture_crop_image_base_64']);
$img = str_replace(' ', '+', $img);
$data = base64_decode($img);
- $file = api_get_path(SYS_PLUGIN_PATH).'BuyCourses/uploads/services/images/simg-'.$return.'.png';
+ $file = api_get_path(SYS_PLUGIN_PATH).'buycourses/uploads/services/images/simg-'.$return.'.png';
file_put_contents($file, $data);
Database::update(
$servicesTable,
['image' => 'simg-'.$return.'.png'],
- ['id = ?' => (int) $return]
+ ['id = ?' => $return]
);
}
@@ -2168,26 +2994,23 @@ public function storeService($service)
/**
* update a service.
*
- * @param array $service
- * @param int $id
- *
* @return mixed response
*/
- public function updateService($service, $id)
+ public function updateService(array $service, int $id)
{
$servicesTable = Database::get_main_table(self::TABLE_SERVICES);
if (!empty($service['picture_crop_image_base_64'])) {
$img = str_replace('data:image/png;base64,', '', $service['picture_crop_image_base_64']);
$img = str_replace(' ', '+', $img);
$data = base64_decode($img);
- $file = api_get_path(SYS_PLUGIN_PATH).'BuyCourses/uploads/services/images/simg-'.$id.'.png';
+ $file = api_get_path(SYS_PLUGIN_PATH).'buycourses/uploads/services/images/simg-'.$id.'.png';
file_put_contents($file, $data);
}
return Database::update(
$servicesTable,
[
- 'title' => Security::remove_XSS($service['name']),
+ 'name' => Security::remove_XSS($service['name']),
'description' => Security::remove_XSS($service['description']),
'price' => $service['price'],
'tax_perc' => '' != $service['tax_perc'] ? (int) $service['tax_perc'] : null,
@@ -2199,7 +3022,7 @@ public function updateService($service, $id)
'video_url' => $service['video_url'],
'service_information' => $service['service_information'],
],
- ['id = ?' => (int) $id]
+ ['id = ?' => $id]
);
}
@@ -2208,49 +3031,58 @@ public function updateService($service, $id)
*
* @param int $id The transfer account ID
*
- * @return int Rows affected. Otherwise return false
+ * @return int Rows affected. Otherwise, return false
*/
- public function deleteService($id)
+ public function deleteService(int $id)
{
Database::delete(
Database::get_main_table(self::TABLE_SERVICES_SALE),
- ['service_id = ?' => (int) $id]
+ ['service_id = ?' => $id]
);
return Database::delete(
Database::get_main_table(self::TABLE_SERVICES),
- ['id = ?' => (int) $id]
+ ['id = ?' => $id]
);
}
/**
- * @param array $product
- * @param int $productType
- *
- * @return bool
+ * @param array|null $coupon Array with at least 'discount_type' and 'discount_amount' elements
*/
- public function setPriceSettings(&$product, $productType)
+ public function setPriceSettings(array &$product, int $productType, ?array $coupon = null): bool
{
if (empty($product)) {
return false;
}
$taxPerc = null;
+ $product['has_coupon'] = null != $coupon ? true : false;
+ $couponDiscount = 0;
+ if (null != $coupon) {
+ if (self::COUPON_DISCOUNT_TYPE_AMOUNT == $coupon['discount_type']) {
+ $couponDiscount = $coupon['discount_amount'];
+ } elseif (self::COUPON_DISCOUNT_TYPE_PERCENTAGE == $coupon['discount_type']) {
+ $couponDiscount = ($product['price'] * $coupon['discount_amount']) / 100;
+ }
+ $product['price_without_discount'] = $product['price'];
+ }
+ $product['discount_amount'] = $couponDiscount;
+ $product['price'] -= $couponDiscount;
$priceWithoutTax = $product['price'];
$product['total_price'] = $product['price'];
$product['tax_amount'] = 0;
- $precision = 2;
+
if ($this->checkTaxEnabledInProduct($productType)) {
- if (is_null($product['tax_perc'])) {
+ if (null === $product['tax_perc']) {
$globalParameters = $this->getGlobalParameters();
$globalTaxPerc = $globalParameters['global_tax_perc'];
$taxPerc = $globalTaxPerc;
} else {
$taxPerc = $product['tax_perc'];
}
- //$taxPerc = is_null($product['tax_perc']) ? $globalTaxPerc : $product['tax_perc'];
+ // $taxPerc = is_null($product['tax_perc']) ? $globalTaxPerc : $product['tax_perc'];
- $taxAmount = round($priceWithoutTax * $taxPerc / 100, $precision, PHP_ROUND_HALF_UP);
+ $taxAmount = round($priceWithoutTax * $taxPerc / 100, 2);
$product['tax_amount'] = $taxAmount;
$priceWithTax = $priceWithoutTax + $taxAmount;
$product['total_price'] = $priceWithTax;
@@ -2258,27 +3090,37 @@ public function setPriceSettings(&$product, $productType)
$product['tax_perc_show'] = $taxPerc;
$product['price_formatted'] = $this->getPriceWithCurrencyFromIsoCode(
- number_format($product['price'], $precision),
+ $product['price'],
$product['iso_code']
);
- $product['tax_amount_formatted'] = number_format($product['tax_amount'], $precision);
+ $product['tax_amount_formatted'] = number_format($product['tax_amount'], 2);
$product['total_price_formatted'] = $this->getPriceWithCurrencyFromIsoCode(
- number_format($product['total_price'], $precision),
+ $product['total_price'],
$product['iso_code']
);
+
+ if (null != $coupon) {
+ $product['discount_amount_formatted'] = $this->getPriceWithCurrencyFromIsoCode(
+ $product['discount_amount'],
+ $product['iso_code']
+ );
+
+ $product['price_without_discount_formatted'] = $this->getPriceWithCurrencyFromIsoCode(
+ $product['price_without_discount'],
+ $product['iso_code']
+ );
+ }
+
+ return true;
}
/**
- * @param int $id
- *
* @return array
*/
- public function getService($id)
+ public function getService(int $id, ?array $coupon = null)
{
- $id = (int) $id;
-
if (empty($id)) {
return [];
}
@@ -2300,12 +3142,12 @@ public function getService($id)
$service['iso_code'] = $isoCode;
$globalParameters = $this->getGlobalParameters();
- $this->setPriceSettings($service, self::TAX_APPLIES_TO_ONLY_SERVICES);
+ $this->setPriceSettings($service, self::TAX_APPLIES_TO_ONLY_SERVICES, $coupon);
$service['tax_name'] = $globalParameters['tax_name'];
$service['tax_enable'] = $this->checkTaxEnabledInProduct(self::TAX_APPLIES_TO_ONLY_SERVICES);
$service['owner_name'] = api_get_person_name($service['firstname'], $service['lastname']);
- $service['image'] = !empty($service['image']) ? api_get_path(WEB_PLUGIN_PATH).'BuyCourses/uploads/services/images/'.$service['image'] : null;
+ $service['image'] = !empty($service['image']) ? api_get_path(WEB_PLUGIN_PATH).'buycourses/uploads/services/images/'.$service['image'] : null;
return $service;
}
@@ -2315,13 +3157,36 @@ public function getService($id)
*
* @return array
*/
- public function getServices($start, $end, $typeResult = 'all')
+ public function getAllServices()
{
$servicesTable = Database::get_main_table(self::TABLE_SERVICES);
$userTable = Database::get_main_table(TABLE_MAIN_USER);
- $start = (int) $start;
- $end = (int) $end;
+ $innerJoins = "INNER JOIN $userTable u ON s.owner_id = u.id";
+ $return = Database::select(
+ 's.id',
+ "$servicesTable s $innerJoins",
+ [],
+ 'all'
+ );
+
+ $services = [];
+ foreach ($return as $index => $service) {
+ $services[$index] = $this->getService($service['id']);
+ }
+
+ return $services;
+ }
+
+ /**
+ * List additional services.
+ *
+ * @return array|int
+ */
+ public function getServices(int $start, int $end, string $typeResult = 'all')
+ {
+ $servicesTable = Database::get_main_table(self::TABLE_SERVICES);
+ $userTable = Database::get_main_table(TABLE_MAIN_USER);
$conditions = ['limit' => "$start, $end"];
$innerJoins = "INNER JOIN $userTable u ON s.owner_id = u.id";
@@ -2369,19 +3234,18 @@ public function getServiceSaleStatuses()
* @return array
*/
public function getServiceSales(
- $buyerId = 0,
- $status = 0,
- $nodeType = 0,
- $nodeId = 0
+ int $buyerId = 0,
+ int $status = 0,
+ int $nodeType = 0,
+ int $nodeId = 0
) {
$conditions = null;
$groupBy = '';
- $buyerId = (int) $buyerId;
- $status = (int) $status;
- $nodeType = (int) $nodeType;
- $nodeId = (int) $nodeId;
- $defaultOrder = 'ss.id ASC';
+ $servicesTable = Database::get_main_table(self::TABLE_SERVICES);
+ $servicesSaleTable = Database::get_main_table(self::TABLE_SERVICES_SALE);
+
+ $defaultOrder = 'id ASC';
if (!empty($buyerId)) {
$conditions = ['WHERE' => ['ss.buyer_id = ?' => $buyerId], 'ORDER' => $defaultOrder];
@@ -2412,19 +3276,16 @@ public function getServiceSales(
$status,
],
],
- 'ORDER' => 'ss.service_id ASC',
+ 'ORDER' => $defaultOrder,
];
}
- $servicesTable = Database::get_main_table(self::TABLE_SERVICES);
- $servicesSaleTable = Database::get_main_table(self::TABLE_SERVICES_SALE);
-
$innerJoins = "INNER JOIN $servicesTable s ON ss.service_id = s.id $groupBy";
$return = Database::select(
'DISTINCT ss.id ',
"$servicesSaleTable ss $innerJoins",
$conditions
- //, "all", null, true
+ // , "all", null, true
);
$list = [];
@@ -2440,7 +3301,7 @@ public function getServiceSales(
*
* @return array
*/
- public function getServiceSale($id)
+ public function getServiceSale(int $id)
{
$servicesTable = Database::get_main_table(self::TABLE_SERVICES);
$servicesSaleTable = Database::get_main_table(self::TABLE_SERVICES_SALE);
@@ -2455,7 +3316,7 @@ public function getServiceSale($id)
$isoCode = $currency['iso_code'];
$servicesSale = Database::select(
- 'ss.*, s.title, s.description, s.price as service_price, s.duration_days, s.applies_to, s.owner_id, s.visibility, s.image',
+ 'ss.*, s.name, s.description, s.price as service_price, s.duration_days, s.applies_to, s.owner_id, s.visibility, s.image',
"$servicesSaleTable ss $innerJoins",
$conditions,
'first'
@@ -2464,7 +3325,7 @@ public function getServiceSale($id)
$buyer = api_get_user_info($servicesSale['buyer_id']);
$servicesSale['service']['id'] = $servicesSale['service_id'];
- $servicesSale['service']['title'] = $servicesSale['title'];
+ $servicesSale['service']['name'] = $servicesSale['name'];
$servicesSale['service']['description'] = $servicesSale['description'];
$servicesSale['service']['price'] = $servicesSale['service_price'];
$servicesSale['service']['currency'] = $isoCode;
@@ -2495,7 +3356,7 @@ public function getServiceSale($id)
*
* @return bool
*/
- public function cancelServiceSale($serviceSaleId)
+ public function cancelServiceSale(int $serviceSaleId)
{
$this->updateServiceSaleStatus(
$serviceSaleId,
@@ -2512,7 +3373,7 @@ public function cancelServiceSale($serviceSaleId)
*
* @return bool
*/
- public function completeServiceSale($serviceSaleId)
+ public function completeServiceSale(int $serviceSaleId)
{
$serviceSale = $this->getServiceSale($serviceSaleId);
if (self::SERVICE_STATUS_COMPLETED == $serviceSale['status']) {
@@ -2534,13 +3395,19 @@ public function completeServiceSale($serviceSaleId)
/**
* Lists current service details.
*
- * @param string $name Optional. The name filter
- * @param int $min Optional. The minimum price filter
- * @param int $max Optional. The maximum price filter
- * @param mixed $appliesTo optional
+ * @param mixed $appliesTo
+ *
+ * @return array|int
*/
- public function getCatalogServiceList($start, $end, $name = null, $min = 0, $max = 0, $appliesTo = '', $typeResult = 'all'): array|int
- {
+ public function getCatalogServiceList(
+ int $start,
+ int $end,
+ ?string $name = null,
+ int $min = 0,
+ int $max = 0,
+ $appliesTo = '',
+ string $typeResult = 'all'
+ ) {
$servicesTable = Database::get_main_table(self::TABLE_SERVICES);
$userTable = Database::get_main_table(TABLE_MAIN_USER);
@@ -2549,7 +3416,7 @@ public function getCatalogServiceList($start, $end, $name = null, $min = 0, $max
];
if (!empty($name)) {
- $whereConditions['AND s.title LIKE %?%'] = $name;
+ $whereConditions['AND s.name LIKE %?%'] = $name;
}
if (!empty($min)) {
@@ -2564,9 +3431,6 @@ public function getCatalogServiceList($start, $end, $name = null, $min = 0, $max
$whereConditions['AND s.applies_to = ?'] = $appliesTo;
}
- $start = (int) $start;
- $end = (int) $end;
-
$innerJoins = "INNER JOIN $userTable u ON s.owner_id = u.id";
$return = Database::select(
's.*',
@@ -2596,7 +3460,7 @@ public function getCatalogServiceList($start, $end, $name = null, $min = 0, $max
*
* @return bool
*/
- public function registerServiceSale($serviceId, $paymentType, $infoSelect)
+ public function registerServiceSale(int $serviceId, int $paymentType, int $infoSelect, ?int $couponId = null)
{
if (!in_array(
$paymentType,
@@ -2613,6 +3477,21 @@ public function registerServiceSale($serviceId, $paymentType, $infoSelect)
return false;
}
+ if (null != $couponId) {
+ $coupon = $this->getCouponService($couponId, $serviceId);
+ }
+
+ $couponDiscount = 0;
+ $priceWithoutDiscount = 0;
+ if (null != $coupon) {
+ if (self::COUPON_DISCOUNT_TYPE_AMOUNT == $coupon['discount_type']) {
+ $couponDiscount = $coupon['discount_amount'];
+ } elseif (self::COUPON_DISCOUNT_TYPE_PERCENTAGE == $coupon['discount_type']) {
+ $couponDiscount = ($service['price'] * $coupon['discount_amount']) / 100;
+ }
+ $priceWithoutDiscount = $service['price'];
+ }
+ $service['price'] -= $couponDiscount;
$currency = $this->getSelectedCurrency();
$price = $service['price'];
$priceWithoutTax = null;
@@ -2622,14 +3501,14 @@ public function registerServiceSale($serviceId, $paymentType, $infoSelect)
$taxAppliesTo = $globalParameters['tax_applies_to'];
$taxAmount = 0;
- if ($taxEnable &&
- (self::TAX_APPLIES_TO_ALL == $taxAppliesTo || self::TAX_APPLIES_TO_ONLY_SERVICES == $taxAppliesTo)
+ if ($taxEnable
+ && (self::TAX_APPLIES_TO_ALL == $taxAppliesTo || self::TAX_APPLIES_TO_ONLY_SERVICES == $taxAppliesTo)
) {
$priceWithoutTax = $service['price'];
$globalTaxPerc = $globalParameters['global_tax_perc'];
$precision = 2;
- $taxPerc = is_null($service['tax_perc']) ? $globalTaxPerc : $service['tax_perc'];
- $taxAmount = round($priceWithoutTax * $taxPerc / 100, $precision, PHP_ROUND_HALF_UP);
+ $taxPerc = null === $service['tax_perc'] ? $globalTaxPerc : $service['tax_perc'];
+ $taxAmount = round($priceWithoutTax * $taxPerc / 100, $precision);
$price = $priceWithoutTax + $taxAmount;
}
@@ -2646,7 +3525,7 @@ public function registerServiceSale($serviceId, $paymentType, $infoSelect)
'tax_perc' => $taxPerc,
'tax_amount' => $taxAmount,
'node_type' => $service['applies_to'],
- 'node_id' => (int) $infoSelect,
+ 'node_id' => $infoSelect,
'buyer_id' => $userId,
'buy_date' => api_get_utc_datetime(),
'date_start' => api_get_utc_datetime(),
@@ -2658,22 +3537,20 @@ public function registerServiceSale($serviceId, $paymentType, $infoSelect)
'Y-m-d H:i:s'
),
'status' => self::SERVICE_STATUS_PENDING,
- 'payment_type' => (int) $paymentType,
+ 'payment_type' => $paymentType,
+ 'price_without_discount' => $priceWithoutDiscount,
+ 'discount_amount' => $couponDiscount,
];
- $returnedServiceSaleId = Database::insert(self::TABLE_SERVICES_SALE, $values);
-
- return $returnedServiceSaleId;
+ return Database::insert(self::TABLE_SERVICES_SALE, $values);
}
/**
* Save Culqi configuration params.
*
- * @param array $params
- *
- * @return int Rows affected. Otherwise return false
+ * @return int Rows affected. Otherwise, return false
*/
- public function saveCulqiParameters($params)
+ public function saveCulqiParameters(array $params)
{
return Database::update(
Database::get_main_table(self::TABLE_CULQI),
@@ -2702,13 +3579,49 @@ public function getCulqiParams()
}
/**
- * Save Global Parameters.
+ * Save Cecabank configuration params.
+ *
+ * @return array
+ */
+ public function saveCecabankParameters(array $params)
+ {
+ return Database::update(
+ Database::get_main_table(self::TABLE_TPV_CECABANK),
+ [
+ 'crypto_key' => $params['crypto_key'],
+ 'merchant_id' => $params['merchart_id'],
+ 'acquirer_bin' => $params['acquirer_bin'],
+ 'terminal_id' => $params['terminal_id'],
+ 'cypher' => $params['cypher'],
+ 'exponent' => $params['exponent'],
+ 'supported_payment' => $params['supported_payment'],
+ 'url' => $params['url'],
+ ],
+ ['id = ?' => 1]
+ );
+ }
+
+ /**
+ * Gets the stored Cecabank params.
*
- * @param array $params
+ * @return array
+ */
+ public function getCecabankParams()
+ {
+ return Database::select(
+ '*',
+ Database::get_main_table(self::TABLE_TPV_CECABANK),
+ ['id = ?' => 1],
+ 'first'
+ );
+ }
+
+ /**
+ * Save Global Parameters.
*
- * @return int Rows affected. Otherwise return false
+ * @return int Rows affected. Otherwise, return false
*/
- public function saveGlobalParameters($params)
+ public function saveGlobalParameters(array $params)
{
$sqlParams = [
'terms_and_conditions' => $params['terms_and_conditions'],
@@ -2753,11 +3666,9 @@ public function getGlobalParameters()
}
/**
- * @param int $productType
- *
* @return bool
*/
- public function checkTaxEnabledInProduct($productType)
+ public function checkTaxEnabledInProduct(int $productType)
{
if (empty('true' === $this->get('tax_enable'))) {
return false;
@@ -2778,14 +3689,10 @@ public function checkTaxEnabledInProduct($productType)
/**
* Get the path.
- *
- * @param string $var path variable
- *
- * @return string path
*/
- public function getPath($var)
+ public function getPath(string $var): string
{
- $pluginPath = api_get_path(WEB_PLUGIN_PATH).'BuyCourses/';
+ $pluginPath = api_get_path(WEB_PLUGIN_PATH).'buycourses/';
$paths = [
'SERVICE_IMAGES' => $pluginPath.'uploads/services/images/',
'SRC' => $pluginPath.'src/',
@@ -2801,410 +3708,2337 @@ public function getPath($var)
return $paths[$var];
}
- /**
- * @return array
- */
- public function getBuyCoursePluginPrice(Session $session)
+ public function getBuyCoursePluginPrice(Session $session): array
{
// start buycourse validation
- // display the course price and buy button if the BuyCourses plugin is enabled and this course is configured
+ // display the course price and buy button if the buycourses plugin is enabled and this course is configured
$isThisCourseInSale = $this->buyCoursesForGridCatalogValidator($session->getId(), self::PRODUCT_TYPE_SESSION);
$return = [];
if ($isThisCourseInSale) {
// set the Price label
$return['html'] = $isThisCourseInSale['html'];
- // set the Buy button instead register.
+ // set the Buy button instead of register.
if ($isThisCourseInSale['verificator']) {
$return['buy_button'] = $this->returnBuyCourseButton($session->getId(), self::PRODUCT_TYPE_SESSION);
}
}
+
// end buycourse validation
return $return;
}
/**
- * @return string
+ * Register a coupon sale.
+ *
+ * @param int $saleId The sale ID
+ * @param int $couponId The coupon ID
*/
- public function getSubscriptionSuccessMessage(array $saleInfo)
+ public function registerCouponSale(int $saleId, int $couponId): bool
{
- switch ($saleInfo['product_type']) {
- case self::PRODUCT_TYPE_COURSE:
- $courseInfo = api_get_course_info_by_id($saleInfo['product_id']);
- $url = api_get_course_url($courseInfo['real_id']);
- break;
- case self::PRODUCT_TYPE_SESSION:
- $sessionId = (int) $saleInfo['product_id'];
- $url = api_get_path(WEB_CODE_PATH).'session/index.php?session_id='.$sessionId;
- break;
- default:
- $url = '#';
+ $sale = $this->getSale($saleId);
+
+ if (empty($sale)) {
+ return false;
}
- return Display::return_message(
- sprintf(
- $this->get_lang('SubscriptionToCourseXSuccessful'),
- $url,
- $saleInfo['product_name']
- ),
- 'success',
- false
- );
+ $values = [
+ 'coupon_id' => $couponId,
+ 'sale_id' => $saleId,
+ ];
+
+ return Database::insert(self::TABLE_COUPON_SALE, $values) > 0;
}
- public static function returnPagination(
- string $baseUrl,
- string $currentPage,
- string $pagesCount,
- string $totalItems,
- array $extraQueryParams = []
- ): string {
- $queryParams = HttpRequest::createFromGlobals()->query->all();
+ /**
+ * Register a coupon service sale.
+ *
+ * @param int $saleId The sale ID
+ * @param int $couponId The coupon ID
+ */
+ public function registerCouponServiceSale(int $saleId, int $couponId): bool
+ {
+ $sale = $this->getSale($saleId);
- unset($queryParams['page']);
+ if (empty($sale)) {
+ return false;
+ }
- $url = $baseUrl.'?'.http_build_query(
- array_merge($queryParams, $extraQueryParams)
- );
+ $values = [
+ 'coupon_id' => $couponId,
+ 'service_sale_id' => $saleId,
+ ];
- return Display::getPagination($url, $currentPage, $pagesCount, $totalItems);
+ return Database::insert(self::TABLE_COUPON_SERVICE_SALE, $values) > 0;
}
/**
- * Filter the registered courses for show in plugin catalog.
+ * Register a coupon sale.
+ *
+ * @param int $saleId The sale ID
+ * @param int $couponId The coupon ID
*/
- private function getCourses($first, $maxResults): QueryBuilder
+ public function registerCouponSubscriptionSale(int $saleId, int $couponId): bool
{
- $em = Database::getManager();
- $urlId = api_get_current_access_url_id();
+ $sale = $this->getSubscriptionSale($saleId);
- $qb = $em->createQueryBuilder();
- $qb2 = $em->createQueryBuilder();
- $qb3 = $em->createQueryBuilder();
+ if (empty($sale)) {
+ return false;
+ }
- $qb = $qb
- ->select('c')
- ->from(Course::class, 'c')
- ->where(
- $qb->expr()->notIn(
- 'c',
- $qb2
- ->select('course2')
- ->from(SessionRelCourse::class, 'sc')
- ->join('sc.course', 'course2')
- ->innerJoin(
- AccessUrlRelSession::class,
- 'us',
- Join::WITH,
- 'us.session = sc.session'
- )->where(
- $qb->expr()->eq('us.url ', $urlId)
- )
- ->getDQL()
- )
- )->andWhere(
- $qb->expr()->in(
- 'c',
- $qb3
- ->select('course3')
- ->from(AccessUrlRelCourse::class, 'uc')
- ->join('uc.course', 'course3')
- ->where(
- $qb3->expr()->eq('uc.url ', $urlId)
- )
- ->getDQL()
- )
- )
- ->setFirstResult($first)
- ->setMaxResults($maxResults);
+ $values = [
+ 'coupon_id' => (int) $couponId,
+ 'sale_id' => (int) $saleId,
+ ];
- return $qb;
+ return Database::insert(self::TABLE_COUPON_SUBSCRIPTION_SALE, $values) > 0;
}
/**
- * Get the user status for the session.
- *
- * @param int $userId The user ID
- * @param Session $session The session
- *
- * @return string
+ * Add a new coupon.
*/
- private function getUserStatusForSession($userId, Session $session)
+ public function addNewCoupon(array $coupon): bool
{
- if (empty($userId)) {
- return 'NO';
- }
+ $couponId = $this->registerCoupon($coupon);
- $entityManager = Database::getManager();
- $scuRepo = $entityManager->getRepository(SessionRelCourseRelUser::class);
+ if ($couponId) {
+ if (isset($coupon['courses'])) {
+ foreach ($coupon['courses'] as $course) {
+ $this->registerCouponItem($couponId, self::PRODUCT_TYPE_COURSE, $course);
+ }
+ }
- $buySaleTable = Database::get_main_table(self::TABLE_SALE);
+ if (isset($coupon['sessions'])) {
+ foreach ($coupon['sessions'] as $session) {
+ $this->registerCouponItem($couponId, self::PRODUCT_TYPE_SESSION, $session);
+ }
+ }
- // Check if user bought the course
- $sale = Database::select(
- 'COUNT(1) as qty',
- $buySaleTable,
- [
- 'where' => [
- 'user_id = ? AND product_type = ? AND product_id = ? AND status = ?' => [
- $userId,
- self::PRODUCT_TYPE_SESSION,
- $session->getId(),
- self::SALE_STATUS_PENDING,
- ],
- ],
- ],
- 'first'
- );
+ if (isset($coupon['services'])) {
+ foreach ($coupon['services'] as $service) {
+ $this->registerCouponService($couponId, $service);
+ }
+ }
- if ($sale['qty'] > 0) {
- return 'TMP';
+ return true;
}
- // Check if user is already subscribe to session
- $userSubscription = $scuRepo->findBy([
- 'session' => $session,
- 'user' => $userId,
- ]);
-
- if (!empty($userSubscription)) {
- return 'YES';
- }
+ Display::addFlash(
+ Display::return_message(
+ $this->get_lang('CouponErrorInsert'),
+ 'error',
+ false
+ )
+ );
- return 'NO';
+ return false;
}
/**
- * Get the user status for the course.
- *
- * @param int $userId The user Id
- * @param Course $course The course
+ * Add a new coupon.
*
- * @return string
+ * @return bool
*/
- private function getUserStatusForCourse($userId, Course $course)
+ public function updateCouponData(array $coupon)
{
- if (empty($userId)) {
- return 'NO';
+ $this->updateCoupon($coupon);
+ $this->deleteCouponItemsByCoupon(self::PRODUCT_TYPE_COURSE, $coupon['id']);
+ $this->deleteCouponItemsByCoupon(self::PRODUCT_TYPE_SESSION, $coupon['id']);
+ $this->deleteCouponServicesByCoupon($coupon['id']);
+
+ if (isset($coupon['courses'])) {
+ foreach ($coupon['courses'] as $course) {
+ $this->registerCouponItem($coupon['id'], self::PRODUCT_TYPE_COURSE, $course);
+ }
}
- $entityManager = Database::getManager();
- $cuRepo = $entityManager->getRepository(CourseRelUser::class);
- $buySaleTable = Database::get_main_table(self::TABLE_SALE);
-
- // Check if user bought the course
- $sale = Database::select(
- 'COUNT(1) as qty',
- $buySaleTable,
- [
- 'where' => [
- 'user_id = ? AND product_type = ? AND product_id = ? AND status = ?' => [
- $userId,
- self::PRODUCT_TYPE_COURSE,
- $course->getId(),
- self::SALE_STATUS_PENDING,
- ],
- ],
- ],
- 'first'
- );
-
- if ($sale['qty'] > 0) {
- return 'TMP';
+ if (isset($coupon['sessions'])) {
+ foreach ($coupon['sessions'] as $session) {
+ $this->registerCouponItem($coupon['id'], self::PRODUCT_TYPE_SESSION, $session);
+ }
}
- // Check if user is already subscribe to course
- $userSubscription = $cuRepo->findBy([
- 'course' => $course,
- 'user' => $userId,
- ]);
-
- if (!empty($userSubscription)) {
- return 'YES';
+ if (isset($coupon['services'])) {
+ foreach ($coupon['services'] as $service) {
+ $this->registerCouponService($coupon['id'], $service);
+ }
}
- return 'NO';
+ return true;
}
/**
- * Update the sale status.
+ * Update coupons delivered.
*
- * @param int $saleId The sale ID
- * @param int $newStatus The new status
+ * @param int $couponId The coupon ID
*
* @return bool
*/
- private function updateSaleStatus($saleId, $newStatus = self::SALE_STATUS_PENDING)
+ public function updateCouponDelivered(int $couponId)
{
- $saleTable = Database::get_main_table(self::TABLE_SALE);
+ $couponTable = Database::get_main_table(self::TABLE_COUPON);
- return Database::update(
- $saleTable,
- ['status' => (int) $newStatus],
- ['id = ?' => (int) $saleId]
- );
+ $sql = "UPDATE $couponTable
+ SET delivered = delivered+1
+ WHERE id = $couponId";
+
+ Database::query($sql);
}
/**
- * Search filtered sessions by name, and range of price.
+ * Get coupon info.
*
- * @param int $start
- * @param int $end
- * @param string $name Optional. The name filter
- * @param int $min Optional. The minimun price filter
- * @param int $max Optional. The maximum price filter
+ * @param int $couponId The coupon ID
*
- * @return array
+ * @return array The coupon data
*/
- private function filterSessionList($start, $end, $name = null, $min = 0, $max = 0, $typeResult = 'all')
+ public function getCouponInfo(int $couponId)
{
- $itemTable = Database::get_main_table(self::TABLE_ITEM);
- $sessionTable = Database::get_main_table(TABLE_MAIN_SESSION);
+ $coupon = $this->getDataCoupon($couponId);
- $min = floatval($min);
- $max = floatval($max);
+ $couponRelCourses = $this->getItemsCoupons($couponId, self::PRODUCT_TYPE_COURSE);
+ $couponRelSessions = $this->getItemsCoupons($couponId, self::PRODUCT_TYPE_SESSION);
+ $couponRelServices = $this->getServicesCoupons($couponId);
- $innerJoin = "$itemTable i ON s.id = i.product_id";
- $whereConditions = [
- 'i.product_type = ? ' => self::PRODUCT_TYPE_SESSION,
- ];
+ $coupon['courses'] = $couponRelCourses;
+ $coupon['sessions'] = $couponRelSessions;
+ $coupon['services'] = $couponRelServices;
- if (!empty($name)) {
- $whereConditions['AND s.title LIKE %?%'] = $name;
- }
+ return $coupon;
+ }
- if (!empty($min)) {
- $whereConditions['AND i.price >= ?'] = $min;
- }
+ /**
+ * Get a list of coupons.
+ *
+ * @param int $status The coupons activation status
+ *
+ * @return array Coupons data
+ */
+ public function getCouponsListByStatus(int $status)
+ {
+ return $this->getDataCoupons($status);
+ }
- if (!empty($max)) {
- $whereConditions['AND i.price <= ?'] = $max;
- }
+ /**
+ * Get the coupon data.
+ *
+ * @return array The coupon data
+ */
+ public function getCoupon(int $couponId, int $productType, int $productId)
+ {
+ return $this->getDataCoupon($couponId, $productType, $productId);
+ }
- $start = (int) $start;
- $end = (int) $end;
+ /**
+ * Get data of the coupon code.
+ *
+ * @param string $couponCode The coupon code
+ * @param int $productId The product ID
+ * @param int $productType The product type
+ *
+ * @return array The coupon data
+ */
+ public function getCouponByCode(string $couponCode, ?int $productType = null, ?int $productId = null)
+ {
+ return $this->getDataCouponByCode($couponCode, $productType, $productId);
+ }
- $sessionIds = Database::select(
- 's.id',
- "$sessionTable s INNER JOIN $innerJoin",
- ['where' => $whereConditions, 'limit' => "$start, $end"],
- $typeResult
- );
+ /**
+ * Get data of the coupon code for a service.
+ *
+ * @param int $couponId The coupon ID
+ * @param int $serviceId The product ID
+ *
+ * @return array The coupon data
+ */
+ public function getCouponService(int $couponId, int $serviceId)
+ {
+ return $this->getDataCouponService($couponId, $serviceId);
+ }
- if ('count' === $typeResult) {
- return $sessionIds;
- }
+ /**
+ * Get data of the coupon code for a service.
+ *
+ * @param string $couponCode The coupon code code
+ * @param int $serviceId The product id
+ *
+ * @return array The coupon data
+ */
+ public function getCouponServiceByCode(string $couponCode, int $serviceId)
+ {
+ return $this->getDataCouponServiceByCode($couponCode, $serviceId);
+ }
- if (!$sessionIds) {
- return [];
- }
+ /**
+ * Get the coupon code of a item sale.
+ *
+ * @param int $saleId The sale ID
+ *
+ * @return string The coupon code
+ */
+ public function getSaleCouponCode(int $saleId)
+ {
+ $couponTable = Database::get_main_table(self::TABLE_COUPON);
+ $couponSaleTable = Database::get_main_table(self::TABLE_COUPON_SALE);
- $sessions = [];
+ $couponFrom = "
+ $couponTable c
+ INNER JOIN $couponSaleTable s
+ on c.id = s.coupon_id
+ ";
- foreach ($sessionIds as $sessionId) {
- $sessions[] = Database::getManager()->find(
- Session::class,
- $sessionId
- );
- }
+ $couponCode = Database::select(
+ ['c.code'],
+ $couponFrom,
+ [
+ 'where' => [
+ 's.sale_id = ? ' => $saleId,
+ ],
+ ],
+ 'first'
+ );
- return $sessions;
+ return $couponCode['code'];
}
/**
- * Search filtered courses by name, and range of price.
+ * Get the coupon code of a service sale.
*
- * @param string $name Optional. The name filter
- * @param int $min Optional. The minimun price filter
- * @param int $max Optional. The maximum price filter
+ * @param int $serviceSaleId The service sale ID
*
- * @return array
+ * @return string The coupon code
*/
- private function filterCourseList($start, $end, $name = '', $min = 0, $max = 0, $typeResult = 'all')
+ public function getServiceSaleCouponCode(int $serviceSaleId)
{
- $itemTable = Database::get_main_table(self::TABLE_ITEM);
- $courseTable = Database::get_main_table(TABLE_MAIN_COURSE);
- $urlTable = Database::get_main_table(TABLE_MAIN_ACCESS_URL_REL_COURSE);
+ $couponTable = Database::get_main_table(self::TABLE_COUPON);
+ $couponServiceSaleTable = Database::get_main_table(self::TABLE_COUPON_SERVICE_SALE);
- $urlId = api_get_current_access_url_id();
+ $couponFrom = "
+ $couponTable c
+ INNER JOIN $couponServiceSaleTable s
+ on c.id = s.coupon_id
+ ";
- $min = floatval($min);
- $max = floatval($max);
+ $couponCode = Database::select(
+ ['c.code'],
+ $couponFrom,
+ [
+ 'where' => [
+ 's.service_sale_id = ? ' => $serviceSaleId,
+ ],
+ ],
+ 'first'
+ );
- $whereConditions = [
- 'i.product_type = ? ' => self::PRODUCT_TYPE_COURSE,
- ];
+ return $couponCode['code'];
+ }
- if (!empty($name)) {
- $whereConditions['AND c.title LIKE %?%'] = $name;
- }
+ /**
+ * @return array
+ */
+ public function getCecabankSignature(string $saleReference, float $price)
+ {
+ $urlOk = api_get_path(WEB_PLUGIN_PATH).'buycourses/src/cecabank_success.php';
+ $urlKo = api_get_path(WEB_PLUGIN_PATH).'buycourses/src/cecabank_cancel.php';
+
+ $cecabankParams = $this->getCecabankParams();
+ $signature = $cecabankParams['crypto_key']
+ .$cecabankParams['merchant_id']
+ .$cecabankParams['acquirer_bin']
+ .$cecabankParams['terminal_id']
+ .$saleReference
+ .$price * 100
+ .'978'
+ .$cecabankParams['exponent']
+ .$cecabankParams['cypher']
+ .$urlOk
+ .$urlKo;
+
+ $sha256 = hash('sha256', $signature);
+
+ return strtolower($sha256);
+ }
- if (!empty($min)) {
- $whereConditions['AND i.price >= ?'] = $min;
+ /**
+ * Register a subscription sale.
+ *
+ * @param int $productId The product ID
+ * @param int $productType The product type
+ * @param int $paymentType The payment type
+ * @param int $duration The subscription duration
+ * @param int $couponId The coupon ID
+ *
+ * @return int
+ */
+ public function registerSubscriptionSale(
+ int $productId,
+ int $productType,
+ int $paymentType,
+ int $duration,
+ ?int $couponId = null
+ ) {
+ if (!in_array(
+ $paymentType,
+ [
+ self::PAYMENT_TYPE_PAYPAL,
+ self::PAYMENT_TYPE_TRANSFER,
+ self::PAYMENT_TYPE_CULQI,
+ self::PAYMENT_TYPE_TPV_REDSYS,
+ self::PAYMENT_TYPE_STRIPE,
+ self::PAYMENT_TYPE_TPV_CECABANK,
+ ]
+ )
+ ) {
+ return false;
}
- if (!empty($max)) {
- $whereConditions['AND i.price <= ?'] = $max;
+ $entityManager = Database::getManager();
+ $item = $this->getSubscriptionItem($productId, $productType);
+
+ if (empty($item)) {
+ return false;
}
- $whereConditions['AND url.access_url_id = ?'] = $urlId;
- $start = (int) $start;
- $end = (int) $end;
+ $productName = '';
+ if (self::PRODUCT_TYPE_COURSE == $item['product_type']) {
+ $course = $entityManager->find(Course::class, $item['product_id']);
- $courseIds = Database::select(
- 'c.id',
- "$courseTable c
- INNER JOIN $itemTable i
- ON c.id = i.product_id
- INNER JOIN $urlTable url
- ON c.id = url.c_id
- ",
- ['where' => $whereConditions, 'limit' => "$start, $end"],
- $typeResult
- );
+ if (empty($course)) {
+ return false;
+ }
- if ('count' === $typeResult) {
- return $courseIds;
+ $productName = $course->getTitle();
+ } elseif (self::PRODUCT_TYPE_SESSION == $item['product_type']) {
+ $session = $entityManager->find(Session::class, $item['product_id']);
+
+ if (empty($session)) {
+ return false;
+ }
+
+ $productName = $session->getName();
}
- if (!$courseIds) {
- return [];
+ if (null != $couponId) {
+ $coupon = $this->getCoupon($couponId, $item['product_type'], $item['product_id']);
}
- $courses = [];
- foreach ($courseIds as $courseId) {
- $courses[] = Database::getManager()->find(
- Course::class,
- $courseId['id']
- );
+ $couponDiscount = 0;
+ $priceWithoutDiscount = 0;
+ if (null != $coupon) {
+ if (self::COUPON_DISCOUNT_TYPE_AMOUNT == $coupon['discount_type']) {
+ $couponDiscount = $coupon['discount_amount'];
+ } elseif (self::COUPON_DISCOUNT_TYPE_PERCENTAGE == $coupon['discount_type']) {
+ $couponDiscount = ($item['price'] * $coupon['discount_amount']) / 100;
+ }
+ $priceWithoutDiscount = $item['price'];
}
+ $item['price'] -= $couponDiscount;
+ $price = $item['price'];
+ $priceWithoutTax = null;
+ $taxPerc = null;
+ $taxAmount = 0;
+ $taxEnable = 'true' === $this->get('tax_enable');
+ $globalParameters = $this->getGlobalParameters();
+ $taxAppliesTo = $globalParameters['tax_applies_to'];
- return $courses;
+ if ($taxEnable
+ && (
+ self::TAX_APPLIES_TO_ALL == $taxAppliesTo
+ || (self::TAX_APPLIES_TO_ONLY_COURSE == $taxAppliesTo && self::PRODUCT_TYPE_COURSE == $item['product_type'])
+ || (self::TAX_APPLIES_TO_ONLY_SESSION == $taxAppliesTo && self::PRODUCT_TYPE_SESSION == $item['product_type'])
+ )
+ ) {
+ $priceWithoutTax = $item['price'];
+ $globalTaxPerc = $globalParameters['global_tax_perc'];
+ $precision = 2;
+ $taxPerc = null === $item['tax_perc'] ? $globalTaxPerc : $item['tax_perc'];
+ $taxAmount = round($priceWithoutTax * $taxPerc / 100, $precision);
+ $price = $priceWithoutTax + $taxAmount;
+ }
+
+ $subscriptionEnd = date('y:m:d', strtotime('+'.$duration.' days'));
+
+ $values = [
+ 'reference' => $this->generateReference(
+ api_get_user_id(),
+ $item['product_type'],
+ $item['product_id']
+ ),
+ 'currency_id' => $item['currency_id'],
+ 'date' => api_get_utc_datetime(),
+ 'user_id' => api_get_user_id(),
+ 'product_type' => $item['product_type'],
+ 'product_name' => $productName,
+ 'product_id' => $item['product_id'],
+ 'price' => $price,
+ 'price_without_tax' => $priceWithoutTax,
+ 'tax_perc' => $taxPerc,
+ 'tax_amount' => $taxAmount,
+ 'status' => self::SALE_STATUS_PENDING,
+ 'payment_type' => $paymentType,
+ 'price_without_discount' => $priceWithoutDiscount,
+ 'discount_amount' => $couponDiscount,
+ 'subscription_end' => $subscriptionEnd,
+ ];
+
+ return Database::insert(self::TABLE_SUBSCRIPTION_SALE, $values);
}
/**
- * Update the service sale status.
- *
- * @param int $serviceSaleId The service sale ID
- * @param int $newStatus The new status
+ * Add a new subscription.
*
* @return bool
*/
- private function updateServiceSaleStatus(
- $serviceSaleId,
- $newStatus = self::SERVICE_STATUS_PENDING
- ) {
+ public function addNewSubscription(array $subscription)
+ {
+ $result = false;
+
+ if (isset($subscription['frequencies'])) {
+ foreach ($subscription['frequencies'] as $frequency) {
+ $subscriptionDb = $this->getSubscription($subscription['product_type'], $subscription['product_id'], $frequency['duration']);
+
+ if (!isset($subscriptionDb) || empty($subscription)) {
+ Display::addFlash(
+ Display::return_message(
+ $this->get_lang('SubscriptionAlreadyExists').' ('.$frequency['duration'].')',
+ 'error',
+ false
+ )
+ );
+
+ return false;
+ }
+ $subscriptionId = $this->registerSubscription($subscription, $frequency);
+ if ($subscriptionId) {
+ $result = true;
+ } else {
+ Display::addFlash(
+ Display::return_message(
+ $this->get_lang('SubscriptionErrorInsert'),
+ 'error',
+ false
+ )
+ );
+
+ return false;
+ }
+ }
+ } else {
+ Display::addFlash(
+ Display::return_message(
+ $this->get_lang('FrequenciesNotSetError'),
+ 'error',
+ false
+ )
+ );
+
+ return false;
+ }
+
+ return $result;
+ }
+
+ /**
+ * Delete a subscription.
+ *
+ * @return int
+ */
+ public function deleteSubscription(int $productType, int $productId, int $duration)
+ {
+ return Database::delete(
+ Database::get_main_table(self::TABLE_SUBSCRIPTION),
+ [
+ 'product_type = ? AND ' => (int) $productType,
+ 'product_id = ? AND ' => (int) $productId,
+ 'duration = ? ' => (int) $duration,
+ ]
+ );
+ }
+
+ /**
+ * Get a list of subscriptions by product ID and type.
+ *
+ * @param string $productId The product ID
+ * @param int $productType The product type
+ *
+ * @return array Subscriptions data
+ */
+ public function getSubscriptions($productType, $productId)
+ {
+ return $this->getDataSubscriptions($productType, $productId);
+ }
+
+ /**
+ * Get data of the subscription.
+ *
+ * @return array The subscription data
+ */
+ public function getSubscription(int $productType, int $productId, int $duration, ?array $coupon = null)
+ {
+ $subscription = $this->getDataSubscription($productType, $productId, $duration);
+
+ $currency = $this->getSelectedCurrency();
+ $isoCode = $currency['iso_code'];
+
+ $subscription['iso_code'] = $isoCode;
+
+ $this->setPriceSettings($subscription, self::TAX_APPLIES_TO_ONLY_COURSE, $coupon);
+
+ return $subscription;
+ }
+
+ /**
+ * Get subscription sale data by ID.
+ *
+ * @param int $saleId The sale ID
+ *
+ * @return array
+ */
+ public function getSubscriptionSale(int $saleId)
+ {
+ return Database::select(
+ '*',
+ Database::get_main_table(self::TABLE_SUBSCRIPTION_SALE),
+ [
+ 'where' => ['id = ?' => $saleId],
+ ],
+ 'first'
+ );
+ }
+
+ /**
+ * Complete subscription sale process. Update sale status to completed.
+ *
+ * @param int $saleId The subscription sale ID
+ *
+ * @return bool
+ */
+ public function completeSubscriptionSale(int $saleId)
+ {
+ $sale = $this->getSubscriptionSale($saleId);
+
+ if (self::SALE_STATUS_COMPLETED == $sale['status']) {
+ return true;
+ }
+
+ $saleIsCompleted = false;
+
+ switch ($sale['product_type']) {
+ case self::PRODUCT_TYPE_COURSE:
+ $course = api_get_course_info_by_id($sale['product_id']);
+ $saleIsCompleted = CourseManager::subscribeUser($sale['user_id'], $course['code']);
+
+ break;
+
+ case self::PRODUCT_TYPE_SESSION:
+ SessionManager::subscribeUsersToSession(
+ $sale['product_id'],
+ [$sale['user_id']],
+ api_get_session_visibility($sale['product_id']),
+ false
+ );
+
+ $saleIsCompleted = true;
+
+ break;
+ }
+
+ if ($saleIsCompleted) {
+ $this->updateSubscriptionSaleStatus($sale['id'], self::SALE_STATUS_COMPLETED);
+ if ('true' === $this->get('invoicing_enable')) {
+ $this->setInvoice($sale['id']);
+ }
+ }
+
+ return $saleIsCompleted;
+ }
+
+ /**
+ * Update subscription sale status to canceled.
+ *
+ * @param int $saleId The subscription sale ID
+ */
+ public function cancelSubscriptionSale(int $saleId): void
+ {
+ $this->updateSubscriptionSaleStatus($saleId, self::SALE_STATUS_CANCELED);
+ }
+
+ /**
+ * Get a list of subscription sales by the status.
+ *
+ * @param int $status The status to filter
+ *
+ * @return array The sale list. Otherwise, return false
+ */
+ public function getSubscriptionSaleListByStatus(int $status = self::SALE_STATUS_PENDING)
+ {
+ $saleTable = Database::get_main_table(self::TABLE_SUBSCRIPTION_SALE);
+ $currencyTable = Database::get_main_table(self::TABLE_CURRENCY);
+ $userTable = Database::get_main_table(TABLE_MAIN_USER);
+
+ $innerJoins = "
+ INNER JOIN $currencyTable c ON s.currency_id = c.id
+ INNER JOIN $userTable u ON s.user_id = u.id
+ ";
+
+ return Database::select(
+ ['c.iso_code', 'u.firstname', 'u.lastname', 'u.email', 's.*'],
+ "$saleTable s $innerJoins",
+ [
+ 'where' => ['s.status = ?' => $status],
+ 'order' => 'id DESC',
+ ]
+ );
+ }
+
+ /**
+ * Get the list statuses for subscriptions sales.
+ *
+ * @return array
+ *
+ * @throws Exception
+ */
+ public function getSubscriptionSaleListReport(?string $dateStart = null, ?string $dateEnd = null)
+ {
+ $saleTable = Database::get_main_table(self::TABLE_SUBSCRIPTION_SALE);
+ $currencyTable = Database::get_main_table(self::TABLE_CURRENCY);
+ $userTable = Database::get_main_table(TABLE_MAIN_USER);
+ $innerJoins = "
+ INNER JOIN $currencyTable c ON s.currency_id = c.id
+ INNER JOIN $userTable u ON s.user_id = u.id
+ ";
+ $list = Database::select(
+ ['c.iso_code', 'u.firstname', 'u.lastname', 'u.email', 's.*'],
+ "$saleTable s $innerJoins",
+ [
+ 'order' => 'id DESC',
+ ]
+ );
+ $listExportTemp = [];
+ $listExport = [];
+ $textStatus = null;
+ $paymentTypes = $this->getPaymentTypes();
+ $productTypes = $this->getProductTypes();
+ foreach ($list as $item) {
+ $statusSaleOrder = $item['status'];
+
+ switch ($statusSaleOrder) {
+ case 0:
+ $textStatus = $this->get_lang('SaleStatusPending');
+
+ break;
+
+ case 1:
+ $textStatus = $this->get_lang('SaleStatusCompleted');
+
+ break;
+
+ case -1:
+ $textStatus = $this->get_lang('SaleStatusCanceled');
+
+ break;
+ }
+ $dateFilter = new DateTime($item['date']);
+ $listExportTemp[] = [
+ 'id' => $item['id'],
+ 'reference' => $item['reference'],
+ 'status' => $textStatus,
+ 'status_filter' => $item['status'],
+ 'date' => $dateFilter->format('Y-m-d'),
+ 'order_time' => $dateFilter->format('H:i:s'),
+ 'price' => $item['iso_code'].' '.$item['price'],
+ 'product_type' => $productTypes[$item['product_type']],
+ 'product_name' => $item['product_name'],
+ 'payment_type' => $paymentTypes[$item['payment_type']],
+ 'complete_user_name' => api_get_person_name($item['firstname'], $item['lastname']),
+ 'email' => $item['email'],
+ ];
+ }
+ $listExport[] = [
+ get_lang('Number'),
+ $this->get_lang('OrderStatus'),
+ $this->get_lang('OrderDate'),
+ $this->get_lang('OrderTime'),
+ $this->get_lang('PaymentMethod'),
+ $this->get_lang('SalePrice'),
+ $this->get_lang('ProductType'),
+ $this->get_lang('ProductName'),
+ $this->get_lang('UserName'),
+ get_lang('Email'),
+ ];
+ // Validation Export
+ $dateStart = strtotime($dateStart);
+ $dateEnd = strtotime($dateEnd);
+ foreach ($listExportTemp as $item) {
+ $dateFilter = strtotime($item['date']);
+ if (($dateFilter >= $dateStart) && ($dateFilter <= $dateEnd)) {
+ $listExport[] = [
+ 'id' => $item['id'],
+ 'status' => $item['status'],
+ 'date' => $item['date'],
+ 'order_time' => $item['order_time'],
+ 'payment_type' => $item['payment_type'],
+ 'price' => $item['price'],
+ 'product_type' => $item['product_type'],
+ 'product_name' => $item['product_name'],
+ 'complete_user_name' => $item['complete_user_name'],
+ 'email' => $item['email'],
+ ];
+ }
+ }
+
+ return $listExport;
+ }
+
+ /**
+ * Get a list of subscription sales by the user.
+ *
+ * @param string $term The search term
+ *
+ * @return array The sale list. Otherwise, return false
+ */
+ public function getSubscriptionSaleListByUser(string $term)
+ {
+ $term = trim($term);
+
+ if (empty($term)) {
+ return [];
+ }
+
+ $saleTable = Database::get_main_table(self::TABLE_SUBSCRIPTION_SALE);
+ $currencyTable = Database::get_main_table(self::TABLE_CURRENCY);
+ $userTable = Database::get_main_table(TABLE_MAIN_USER);
+ $innerJoins = "
+ INNER JOIN $currencyTable c ON s.currency_id = c.id
+ INNER JOIN $userTable u ON s.user_id = u.id
+ ";
+
+ return Database::select(
+ ['c.iso_code', 'u.firstname', 'u.lastname', 'u.email', 's.*'],
+ "$saleTable s $innerJoins",
+ [
+ 'where' => [
+ 'u.username LIKE %?% OR ' => $term,
+ 'u.lastname LIKE %?% OR ' => $term,
+ 'u.firstname LIKE %?%' => $term,
+ ],
+ 'order' => 'id DESC',
+ ]
+ );
+ }
+
+ /**
+ * Get a list of subscription sales by the user id.
+ *
+ * @param int $id The user id
+ *
+ * @return array The sale list. Otherwise, return false
+ */
+ public function getSubscriptionSaleListByUserId(int $id)
+ {
+ if (empty($id)) {
+ return [];
+ }
+
+ $saleTable = Database::get_main_table(self::TABLE_SUBSCRIPTION_SALE);
+ $currencyTable = Database::get_main_table(self::TABLE_CURRENCY);
+ $userTable = Database::get_main_table(TABLE_MAIN_USER);
+
+ $innerJoins = "
+ INNER JOIN $currencyTable c ON s.currency_id = c.id
+ INNER JOIN $userTable u ON s.user_id = u.id
+ ";
+
+ return Database::select(
+ ['c.iso_code', 'u.firstname', 'u.lastname', 's.*'],
+ "$saleTable s $innerJoins",
+ [
+ 'where' => [
+ 'u.id = ? AND s.status = ?' => [$id, self::SALE_STATUS_COMPLETED],
+ ],
+ 'order' => 'id DESC',
+ ]
+ );
+ }
+
+ /**
+ * Get a list of subscription sales by date range.
+ *
+ * @return array The sale list. Otherwise, return false
+ */
+ public function getSubscriptionSaleListByDate(string $dateStart, string $dateEnd)
+ {
+ $dateStart = trim($dateStart);
+ $dateEnd = trim($dateEnd);
+ if (empty($dateStart)) {
+ return [];
+ }
+ if (empty($dateEnd)) {
+ return [];
+ }
+ $saleTable = Database::get_main_table(self::TABLE_SUBSCRIPTION_SALE);
+ $currencyTable = Database::get_main_table(self::TABLE_CURRENCY);
+ $userTable = Database::get_main_table(TABLE_MAIN_USER);
+ $innerJoins = "
+ INNER JOIN $currencyTable c ON s.currency_id = c.id
+ INNER JOIN $userTable u ON s.user_id = u.id
+ ";
+
+ return Database::select(
+ ['c.iso_code', 'u.firstname', 'u.lastname', 'u.email', 's.*'],
+ "$saleTable s $innerJoins",
+ [
+ 'where' => [
+ 's.date BETWEEN ? AND ' => $dateStart,
+ ' ? ' => $dateEnd,
+ ],
+ 'order' => 'id DESC',
+ ]
+ );
+ }
+
+ /**
+ * Get a list of subscription sales by the user Email.
+ *
+ * @param string $term The search term
+ *
+ * @return array The sale list. Otherwise, return false
+ */
+ public function getSubscriptionSaleListByEmail(string $term)
+ {
+ $term = trim($term);
+ if (empty($term)) {
+ return [];
+ }
+ $saleTable = Database::get_main_table(self::TABLE_SUBSCRIPTION_SALE);
+ $currencyTable = Database::get_main_table(self::TABLE_CURRENCY);
+ $userTable = Database::get_main_table(TABLE_MAIN_USER);
+ $innerJoins = "
+ INNER JOIN $currencyTable c ON s.currency_id = c.id
+ INNER JOIN $userTable u ON s.user_id = u.id
+ ";
+
+ return Database::select(
+ ['c.iso_code', 'u.firstname', 'u.lastname', 'u.email', 's.*'],
+ "$saleTable s $innerJoins",
+ [
+ 'where' => [
+ 'u.email LIKE %?% ' => $term,
+ ],
+ 'order' => 'id DESC',
+ ]
+ );
+ }
+
+ /**
+ * Get subscription sale data by ID.
+ *
+ * @param string $date The date
+ *
+ * @return array
+ */
+ public function getSubscriptionsDue(string $date)
+ {
+ return Database::select(
+ 'id, user_id, product_id, product_type',
+ Database::get_main_table(self::TABLE_SUBSCRIPTION_SALE),
+ [
+ 'where' => ['subscription_end < ? AND status <> ? AND (expired is NULL OR expired <> ?)' => [
+ $date,
+ self::SALE_STATUS_COMPLETED,
+ 1,
+ ],
+ ],
+ ],
+ 'first'
+ );
+ }
+
+ /**
+ * Get subscription sale data by ID.
+ *
+ * @param int $userId The user ID
+ * @param int $productId The product ID
+ * @param int $productType The product type
+ *
+ * @return array
+ */
+ public function checkItemSubscriptionActive(int $userId, int $productId, int $productType)
+ {
+ return Database::select(
+ '*',
+ Database::get_main_table(self::TABLE_SUBSCRIPTION_SALE),
+ [
+ 'where' => ['subscription_end >= ? AND userId = ? AND productId = ? AND productType = ? AND status <> ?' => [
+ api_get_utc_datetime(),
+ $userId,
+ $productId,
+ $productType,
+ self::SALE_STATUS_COMPLETED,
+ ],
+ ],
+ ],
+ 'first'
+ );
+ }
+
+ /**
+ * Get subscription sale data by ID.
+ *
+ * @return array
+ */
+ public function updateSubscriptionSaleExpirationStatus(int $id)
+ {
+ $saleTable = Database::get_main_table(self::TABLE_SUBSCRIPTION_SALE);
+
+ return Database::update(
+ $saleTable,
+ ['expired' => 1],
+ ['id = ?' => $id]
+ );
+ }
+
+ /**
+ * Get the list of frequencies discount types.
+ *
+ * @return array
+ */
+ public function getFrequencies()
+ {
+ $data = Database::select(
+ '*',
+ Database::get_main_table(self::TABLE_SUBSCRIPTION_PERIOD),
+ []
+ );
+
+ $frequenciesList = $this->getFrequenciesList();
+ $frequencies = [];
+
+ foreach ($data as $key => $items) {
+ $frequencies[$items['duration']] = $items['name'];
+ }
+
+ return $frequencies;
+ }
+
+ /**
+ * Get the list of frequencies discount types.
+ *
+ * @return array
+ */
+ public function getFrequenciesList()
+ {
+ return Database::select(
+ '*',
+ Database::get_main_table(self::TABLE_SUBSCRIPTION_PERIOD),
+ []
+ );
+ }
+
+ /**
+ * Get the a frequency.
+ *
+ * @param int $duration The duration of the frequency value
+ *
+ * @return array
+ */
+ public function selectFrequency(int $duration)
+ {
+ return Database::select(
+ '*',
+ Database::get_main_table(self::TABLE_SUBSCRIPTION_PERIOD),
+ [
+ 'where' => [
+ 'duration = ?' => [
+ (int) $duration,
+ ],
+ ],
+ ],
+ 'first'
+ );
+ }
+
+ /**
+ * Add a new subscription frequency.
+ *
+ * @return array
+ */
+ public function addFrequency(int $duration, string $name)
+ {
+ $values = [
+ 'duration' => $duration,
+ 'name' => $name,
+ ];
+
+ return Database::insert(self::TABLE_SUBSCRIPTION_PERIOD, $values);
+ }
+
+ /**
+ * Update a subscription frequency.
+ *
+ * @return array
+ */
+ public function updateFrequency(int $duration, string $name)
+ {
+ $periodTable = Database::get_main_table(self::TABLE_SUBSCRIPTION_PERIOD);
+
+ return Database::update(
+ $periodTable,
+ ['name' => $name],
+ ['duration = ?' => $duration]
+ );
+ }
+
+ /**
+ * Delete a subscription frequency.
+ *
+ * @return array
+ */
+ public function deleteFrequency(int $duration)
+ {
+ return Database::delete(
+ Database::get_main_table(self::TABLE_SUBSCRIPTION_PERIOD),
+ [
+ 'duration = ?' => $duration,
+ ]
+ );
+ }
+
+ /**
+ * @return string
+ */
+ public function getSubscriptionSuccessMessage(array $saleInfo)
+ {
+ switch ($saleInfo['product_type']) {
+ case self::PRODUCT_TYPE_COURSE:
+ $courseInfo = api_get_course_info_by_id($saleInfo['product_id']);
+ $url = api_get_course_url($courseInfo['code']);
+
+ break;
+
+ case self::PRODUCT_TYPE_SESSION:
+ $sessionId = (int) $saleInfo['product_id'];
+ $url = api_get_path(WEB_CODE_PATH).'session/index.php?session_id='.$sessionId;
+
+ break;
+
+ default:
+ $url = '#';
+ }
+
+ return Display::return_message(
+ sprintf(
+ $this->get_lang('SubscriptionToCourseXSuccessful'),
+ $url,
+ $saleInfo['product_name']
+ ),
+ 'success',
+ false
+ );
+ }
+
+ /**
+ * @return string
+ */
+ public static function returnPagination(
+ string $baseUrl,
+ int $currentPage,
+ int $pagesCount,
+ int $totalItems,
+ array $extraQueryParams = []
+ ) {
+ $queryParams = HttpRequest::createFromGlobals()->query->all();
+
+ unset($queryParams['page']);
+
+ $url = $baseUrl.'?'.http_build_query(
+ array_merge($queryParams, $extraQueryParams)
+ );
+
+ return Display::getPagination($url, $currentPage, $pagesCount, $totalItems);
+ }
+
+ /**
+ * Returns the javascript to set the sales report table for courses.
+ */
+ public static function getSalesReportScript(array $sales = [], bool $invoicingEnable = false)
+ {
+ $cols = "
+ '".preg_replace("/'/", "\\'", get_plugin_lang('OrderReference', 'BuyCoursesPlugin'))."',
+ '".preg_replace("/'/", "\\'", get_plugin_lang('OrderStatus', 'BuyCoursesPlugin'))."',
+ '".preg_replace("/'/", "\\'", get_plugin_lang('OrderDate', 'BuyCoursesPlugin'))."',
+ '".preg_replace("/'/", "\\'", get_plugin_lang('PaymentMethod', 'BuyCoursesPlugin'))."',
+ '".preg_replace("/'/", "\\'", get_plugin_lang('Price', 'BuyCoursesPlugin'))."',
+ '".preg_replace("/'/", "\\'", get_plugin_lang('CouponDiscount', 'BuyCoursesPlugin'))."',
+ '".preg_replace("/'/", "\\'", get_plugin_lang('Coupon', 'BuyCoursesPlugin'))."',
+ '".preg_replace("/'/", "\\'", get_plugin_lang('ProductType', 'BuyCoursesPlugin'))."',
+ '".preg_replace("/'/", "\\'", get_plugin_lang('Name', 'BuyCoursesPlugin'))."',
+ '".preg_replace("/'/", "\\'", get_lang('UserName'))."',
+ '".preg_replace("/'/", "\\'", get_lang('Email'))."',";
+ $model = "
+ {name:'reference', index:'reference', height:'auto', width:70, sorttype:'string', align:'center'},
+ {name:'status', index:'status', height:'auto', width:70, sorttype:'string', align:'center'},
+ {name:'date', index:'date', height:'auto', width:70, sorttype:'date', align:'center'},
+ {name:'payment_type', index:'payment_type', height:'auto', width:70, sorttype:'string', align:'center'},
+ {name:'total_price', index:'total_price', height:'auto', width:70, sorttype:'string', align:'center'},
+ {name:'coupon_discount', index:'coupon_discount', height:'auto', width:40, sorttype:'string', align: 'center'},
+ {name:'coupon', index:'coupon', height:'auto', width:60, sorttype:'string', align:'center'},
+ {name:'product_type', index:'product_type', height:'auto', width:40, sorttype:'string'},
+ {name:'product_name', index:'product_name', height:'auto', /*width:60,*/ sorttype:'string'},
+ {name:'complete_user_name', index:'complete_user_name', height:'auto', width:70, sorttype:'string'},
+ {name:'email', index:'email', height:'auto', /*width:60,*/ sorttype:'string'}, ";
+ if ($invoicingEnable) {
+ $model .= "{name:'invoice', index:'invoice', height:'auto', width:70, sorttype:'string'},";
+ $cols .= "'".get_plugin_lang('Invoice', 'BuyCoursesPlugin')."',";
+ }
+ $cols .= "'".get_lang('Options')."',";
+ $model .= "
+ {name:'options', index:'options', height:'auto', width:60, sortable:false},";
+ $data = '';
+ foreach ($sales as $item) {
+ $option = '';
+ if (!isset($item['complete_user_name'])) {
+ $item['complete_user_name'] = api_get_person_name($item['firstname'], $item['lastname']);
+ }
+ if (1 == $item['invoice']) {
+ if ($invoicingEnable) {
+ $item['invoice'] = "
".
+ Display::return_icon('default.png', get_plugin_lang('InvoiceView', 'BuyCoursesPlugin'), '', ICON_SIZE_MEDIUM).
+ '
'.$item['num_invoice'].
+ '';
+ }
+ } else {
+ $item['invoice'] = null;
+ }
+ if (self::SALE_STATUS_CANCELED == $item['status']) {
+ $item['status'] = get_plugin_lang('SaleStatusCanceled', 'BuyCoursesPlugin');
+ } elseif (self::SALE_STATUS_PENDING == $item['status']) {
+ $item['status'] = get_plugin_lang('SaleStatusPending', 'BuyCoursesPlugin');
+ $option = "
';
+ } elseif (self::SALE_STATUS_COMPLETED == $item['status']) {
+ $item['status'] = get_plugin_lang('SaleStatusCompleted', 'BuyCoursesPlugin');
+ }
+ $item['options'] = $option;
+ $item['date'] = api_get_local_time($item['date']);
+ $data .= json_encode($item).',';
+ }
+
+ return "
+";
+ }
+
+ /**
+ * Filter the registered courses for show in the plugin catalog.
+ */
+ public function getCourses(int $first, int $maxResults): QueryBuilder
+ {
+ $em = Database::getManager();
+ $urlId = api_get_current_access_url_id();
+
+ $qb = $em->createQueryBuilder();
+ $qb2 = $em->createQueryBuilder();
+ $qb3 = $em->createQueryBuilder();
+
+ return $qb
+ ->select('c')
+ ->from(Course::class, 'c')
+ ->where(
+ $qb->expr()->notIn(
+ 'c',
+ $qb2
+ ->select('course2')
+ ->from(SessionRelCourse::class, 'sc')
+ ->innerJoin('sc.course', 'course2')
+ ->innerJoin(
+ AccessUrlRelSession::class,
+ 'us',
+ Join::WITH,
+ 'us.session = sc.session'
+ )->where(
+ $qb->expr()->eq('us.url ', $urlId)
+ )
+ ->getDQL()
+ )
+ )->andWhere(
+ $qb->expr()->in(
+ 'c',
+ $qb3
+ ->select('course3')
+ ->from(AccessUrlRelCourse::class, 'uc')
+ ->innerJoin('uc.course', 'course3')
+ ->where(
+ $qb3->expr()->eq('uc.url ', $urlId)
+ )
+ ->getDQL()
+ )
+ )
+ ->setFirstResult($first)
+ ->setMaxResults($maxResults)
+ ;
+ }
+
+ /**
+ * Get the user status for the session.
+ *
+ * @param int $userId The user ID
+ * @param Session $session The session
+ *
+ * @return string
+ */
+ private function getUserStatusForSession(int $userId, Session $session)
+ {
+ if (empty($userId)) {
+ return 'NO';
+ }
+
+ $entityManager = Database::getManager();
+ $scuRepo = $entityManager->getRepository(SessionRelCourseRelUser::class);
+
+ $buySaleTable = Database::get_main_table(self::TABLE_SALE);
+
+ // Check if user bought the course
+ $sale = Database::select(
+ 'COUNT(1) as qty',
+ $buySaleTable,
+ [
+ 'where' => [
+ 'user_id = ? AND product_type = ? AND product_id = ? AND status = ?' => [
+ $userId,
+ self::PRODUCT_TYPE_SESSION,
+ $session->getId(),
+ self::SALE_STATUS_PENDING,
+ ],
+ ],
+ ],
+ 'first'
+ );
+
+ if ($sale['qty'] > 0) {
+ return 'TMP';
+ }
+
+ // Check if user is already subscribe to session
+ $userSubscription = $scuRepo->findBy([
+ 'session' => $session,
+ 'user' => $userId,
+ ]);
+
+ if (!empty($userSubscription)) {
+ return 'YES';
+ }
+
+ return 'NO';
+ }
+
+ /**
+ * Get the user status for the course.
+ *
+ * @param int $userId The user Id
+ * @param Course $course The course
+ *
+ * @return string
+ */
+ private function getUserStatusForCourse(int $userId, Course $course)
+ {
+ if (empty($userId)) {
+ return 'NO';
+ }
+
+ $entityManager = Database::getManager();
+ $cuRepo = $entityManager->getRepository(CourseRelUser::class);
+ $buySaleTable = Database::get_main_table(self::TABLE_SALE);
+
+ // Check if user bought the course
+ $sale = Database::select(
+ 'COUNT(1) as qty',
+ $buySaleTable,
+ [
+ 'where' => [
+ 'user_id = ? AND product_type = ? AND product_id = ? AND status = ?' => [
+ $userId,
+ self::PRODUCT_TYPE_COURSE,
+ $course->getId(),
+ self::SALE_STATUS_PENDING,
+ ],
+ ],
+ ],
+ 'first'
+ );
+
+ if ($sale['qty'] > 0) {
+ return 'TMP';
+ }
+
+ // Check if user is already subscribe to course
+ $userSubscription = $cuRepo->findBy([
+ 'course' => $course,
+ 'user' => $userId,
+ ]);
+
+ if (!empty($userSubscription)) {
+ return 'YES';
+ }
+
+ return 'NO';
+ }
+
+ /**
+ * Update the sale status.
+ *
+ * @param int $saleId The sale ID
+ * @param int $newStatus The new status
+ *
+ * @return bool
+ */
+ private function updateSaleStatus(int $saleId, int $newStatus = self::SALE_STATUS_PENDING)
+ {
+ $saleTable = Database::get_main_table(self::TABLE_SALE);
+
+ return Database::update(
+ $saleTable,
+ ['status' => (int) $newStatus],
+ ['id = ?' => (int) $saleId]
+ );
+ }
+
+ /**
+ * Search filtered sessions by name, and range of price.
+ *
+ * @param string $name Optional. The name filter
+ * @param int $min Optional. The minimum price filter
+ * @param int $max Optional. The maximum price filter
+ * @param string $typeResult Optional. 'all' and 'count'
+ * @param int $sessionCategory Optional. Session category id
+ *
+ * @return array
|int
+ */
+ private function filterSessionList(
+ int $start,
+ int $end,
+ ?string $name = null,
+ int $min = 0,
+ int $max = 0,
+ string $typeResult = 'all',
+ int $sessionCategory = 0
+ ): array|int {
+ $itemTable = Database::get_main_table(self::TABLE_ITEM);
+ $sessionTable = Database::get_main_table(TABLE_MAIN_SESSION);
+
+ $innerJoin = "$itemTable i ON s.id = i.product_id";
+ $whereConditions = [
+ 'i.product_type = ? ' => self::PRODUCT_TYPE_SESSION,
+ ];
+
+ if (!empty($name)) {
+ $whereConditions['AND s.title LIKE %?%'] = $name;
+ }
+
+ if (!empty($min)) {
+ $whereConditions['AND i.price >= ?'] = $min;
+ }
+
+ if (!empty($max)) {
+ $whereConditions['AND i.price <= ?'] = $max;
+ }
+
+ if (0 != $sessionCategory) {
+ $whereConditions['AND s.session_category_id = ?'] = $sessionCategory;
+ }
+
+ $sessionIds = Database::select(
+ 's.id',
+ "$sessionTable s INNER JOIN $innerJoin",
+ ['where' => $whereConditions, 'limit' => "$start, $end"],
+ $typeResult
+ );
+
+ if ('count' === $typeResult) {
+ return $sessionIds;
+ }
+
+ if (!$sessionIds) {
+ return [];
+ }
+
+ $sessions = [];
+
+ foreach ($sessionIds as $sessionId) {
+ $sessions[] = Database::getManager()->find(
+ Session::class,
+ $sessionId
+ );
+ }
+
+ return $sessions;
+ }
+
+ /**
+ * Search filtered courses by name, and range of price.
+ *
+ * @param string $name Optional. The name filter
+ * @param int $min Optional. The minimun price filter
+ * @param int $max Optional. The maximum price filter
+ *
+ * @return array|int
+ */
+ private function filterCourseList(
+ int $start,
+ int $end,
+ ?string $name = null,
+ int $min = 0,
+ int $max = 0,
+ string $typeResult = 'all'
+ ): array|int {
+ $itemTable = Database::get_main_table(self::TABLE_ITEM);
+ $courseTable = Database::get_main_table(TABLE_MAIN_COURSE);
+ $urlTable = Database::get_main_table(TABLE_MAIN_ACCESS_URL_REL_COURSE);
+
+ $urlId = api_get_current_access_url_id();
+
+ $min = (float) $min;
+ $max = (float) $max;
+
+ $whereConditions = [
+ 'i.product_type = ? ' => self::PRODUCT_TYPE_COURSE,
+ ];
+
+ if (!empty($name)) {
+ $whereConditions['AND c.title LIKE %?%'] = $name;
+ }
+
+ if (!empty($min)) {
+ $whereConditions['AND i.price >= ?'] = $min;
+ }
+
+ if (!empty($max)) {
+ $whereConditions['AND i.price <= ?'] = $max;
+ }
+
+ $whereConditions['AND url.access_url_id = ?'] = $urlId;
+
+ $courseIds = Database::select(
+ 'c.id',
+ "$courseTable c
+ INNER JOIN $itemTable i
+ ON c.id = i.product_id
+ INNER JOIN $urlTable url
+ ON c.id = url.c_id
+ ",
+ ['where' => $whereConditions, 'limit' => "$start, $end"],
+ $typeResult
+ );
+
+ if ('count' === $typeResult) {
+ return $courseIds;
+ }
+
+ if (!$courseIds) {
+ return [];
+ }
+
+ $courses = [];
+ foreach ($courseIds as $courseId) {
+ $courses[] = Database::getManager()->find(
+ Course::class,
+ $courseId['id']
+ );
+ }
+
+ return $courses;
+ }
+
+ /**
+ * Search filtered sessions by name, and range of price.
+ *
+ * @param string $name Optional. The name filter
+ * @param int $sessionCategory Optional. Session category id
+ *
+ * @return array|int
+ */
+ private function filterSubscriptionSessionList(
+ int $start,
+ int $end,
+ ?string $name = null,
+ string $typeResult = 'all',
+ int $sessionCategory = 0
+ ): array|int {
+ $subscriptionTable = Database::get_main_table(self::TABLE_SUBSCRIPTION);
+ $sessionTable = Database::get_main_table(TABLE_MAIN_SESSION);
+
+ $innerJoin = "$subscriptionTable st ON s.id = st.product_id";
+ $whereConditions = [
+ 'st.product_type = ? ' => self::PRODUCT_TYPE_SESSION,
+ ];
+
+ if (!empty($name)) {
+ $whereConditions['AND s.name LIKE %?%'] = $name;
+ }
+
+ if (0 != $sessionCategory) {
+ $whereConditions['AND s.session_category_id = ?'] = $sessionCategory;
+ }
+
+ $sessionIds = Database::select(
+ 'DISTINCT s.id',
+ "$sessionTable s INNER JOIN $innerJoin",
+ ['where' => $whereConditions, 'limit' => "$start, $end"],
+ $typeResult
+ );
+
+ if ('count' === $typeResult) {
+ return $sessionIds;
+ }
+
+ if (!$sessionIds) {
+ return [];
+ }
+
+ $sessions = [];
+
+ foreach ($sessionIds as $sessionId) {
+ $sessions[] = Database::getManager()->find(
+ Session::class,
+ $sessionId
+ );
+ }
+
+ return $sessions;
+ }
+
+ /**
+ * Search filtered subscription courses by name, and range of price.
+ *
+ * @param string $name Optional. The name filter
+ *
+ * @return array|int
+ */
+ private function filterSubscriptionCourseList(
+ int $start,
+ int $end,
+ string $name = '',
+ string $typeResult = 'all'
+ ): array|int {
+ $subscriptionTable = Database::get_main_table(self::TABLE_SUBSCRIPTION);
+ $courseTable = Database::get_main_table(TABLE_MAIN_COURSE);
+ $urlTable = Database::get_main_table(TABLE_MAIN_ACCESS_URL_REL_COURSE);
+
+ $urlId = api_get_current_access_url_id();
+
+ $whereConditions = [
+ 'st.product_type = ? ' => self::PRODUCT_TYPE_COURSE,
+ ];
+
+ if (!empty($name)) {
+ $whereConditions['AND c.title LIKE %?%'] = $name;
+ }
+
+ $whereConditions['AND url.access_url_id = ?'] = $urlId;
+
+ $courseIds = Database::select(
+ 'DISTINCT c.id',
+ "$courseTable c
+ INNER JOIN $subscriptionTable st
+ ON c.id = st.product_id
+ INNER JOIN $urlTable url
+ ON c.id = url.c_id
+ ",
+ ['where' => $whereConditions, 'limit' => "$start, $end"],
+ $typeResult
+ );
+
+ if ('count' === $typeResult) {
+ return $courseIds;
+ }
+
+ if (!$courseIds) {
+ return [];
+ }
+
+ $courses = [];
+ foreach ($courseIds as $courseId) {
+ $courses[] = Database::getManager()->find(
+ Course::class,
+ $courseId
+ );
+ }
+
+ return $courses;
+ }
+
+ /**
+ * Update the service sale status.
+ *
+ * @param int $serviceSaleId The service sale ID
+ * @param int $newStatus The new status
+ */
+ private function updateServiceSaleStatus(
+ int $serviceSaleId,
+ int $newStatus = self::SERVICE_STATUS_PENDING
+ ): void {
$serviceSaleTable = Database::get_main_table(self::TABLE_SERVICES_SALE);
+ Database::update(
+ $serviceSaleTable,
+ ['status' => $newStatus],
+ ['id = ?' => $serviceSaleId]
+ );
+ }
+
+ /**
+ * Get the items (courses or sessions) of a coupon.
+ *
+ * @return array The item data
+ */
+ private function getItemsCoupons(int $couponId, int $productType): array
+ {
+ $couponItemTable = Database::get_main_table(self::TABLE_COUPON_ITEM);
+
+ if (self::PRODUCT_TYPE_COURSE == $productType) {
+ $itemTable = Database::get_main_table(TABLE_MAIN_COURSE);
+ $select = ['ci.product_id as id', 'it.title'];
+ } elseif (self::PRODUCT_TYPE_SESSION == $productType) {
+ $itemTable = Database::get_main_table(TABLE_MAIN_SESSION);
+ $select = ['ci.product_id as id', 'it.name'];
+ }
+
+ $couponFrom = "
+ $couponItemTable ci
+ INNER JOIN $itemTable it
+ on it.id = ci.product_id and ci.product_type = $productType
+ ";
+
+ return Database::select(
+ $select,
+ $couponFrom,
+ [
+ 'where' => [
+ 'ci.coupon_id = ? ' => $couponId,
+ ],
+ ]
+ );
+ }
+
+ /**
+ * Get the services of a coupon.
+ *
+ * @param int $couponId The coupon ID
+ *
+ * @return array The service data
+ */
+ private function getServicesCoupons(int $couponId): array
+ {
+ $couponServiceTable = Database::get_main_table(self::TABLE_COUPON_SERVICE);
+ $serviceTable = Database::get_main_table(self::TABLE_SERVICES);
+
+ $couponFrom = "
+ $couponServiceTable cs
+ INNER JOIN $serviceTable s
+ on s.id = cs.service_id
+ ";
+
+ return Database::select(
+ ['cs.service_id as id', 's.name'],
+ $couponFrom,
+ [
+ 'where' => [
+ 'cs.coupon_id = ? ' => $couponId,
+ ],
+ ]
+ );
+ }
+
+ /**
+ * Get an array of coupons filtered by their status.
+ *
+ * @param int $status The coupon activation status
+ *
+ * @return array Coupons data
+ */
+ private function getDataCoupons(?int $status = null): array
+ {
+ $couponTable = Database::get_main_table(self::TABLE_COUPON);
+
+ if (null != $status) {
+ return Database::select(
+ ['*'],
+ $couponTable,
+ [
+ 'where' => [
+ ' active = ? ' => (int) $status,
+ ],
+ 'order' => 'id DESC',
+ ]
+ );
+ }
+
+ return Database::select(
+ ['*'],
+ $couponTable,
+ [
+ 'order' => 'id DESC',
+ ]
+ );
+ }
+
+ /**
+ * Get data of a coupon for a product (course or service) by the coupon ID.
+ *
+ * @param int $couponId The coupon code code
+ * @param int $productType The product type
+ * @param int $productId The product ID
+ *
+ * @return array The coupon data
+ */
+ private function getDataCoupon(int $couponId, ?int $productType = null, ?int $productId = null): array
+ {
+ $couponTable = Database::get_main_table(self::TABLE_COUPON);
+
+ if (null == $productType || null == $productId) {
+ return Database::select(
+ ['*'],
+ $couponTable,
+ [
+ 'where' => [
+ 'id = ? ' => $couponId,
+ ],
+ ],
+ 'first'
+ );
+ }
+
+ $couponItemTable = Database::get_main_table(self::TABLE_COUPON_ITEM);
+ $dtmNow = api_get_utc_datetime();
+
+ $couponFrom = "
+ $couponTable c
+ INNER JOIN $couponItemTable ci
+ on ci.coupon_id = c.id
+ ";
+
+ return Database::select(
+ ['c.*'],
+ $couponFrom,
+ [
+ 'where' => [
+ 'c.id = ? AND ' => $couponId,
+ 'c.valid_start <= ? AND ' => $dtmNow,
+ 'c.valid_end >= ? AND ' => $dtmNow,
+ 'ci.product_type = ? AND ' => $productType,
+ 'ci.product_id = ?' => $productId,
+ ],
+ ],
+ 'first'
+ );
+ }
+
+ /**
+ * Get data of a coupon for a product (course or service) by the coupon code.
+ *
+ * @param string $couponCode The coupon code code
+ * @param int $productType The product type
+ * @param int $productId The product ID
+ *
+ * @return array The coupon data
+ */
+ private function getDataCouponByCode(string $couponCode, ?int $productType = null, ?int $productId = null)
+ {
+ $couponTable = Database::get_main_table(self::TABLE_COUPON);
+ $couponItemTable = Database::get_main_table(self::TABLE_COUPON_ITEM);
+ $dtmNow = api_get_utc_datetime();
+
+ if (null == $productType || null == $productId) {
+ return Database::select(
+ ['*'],
+ $couponTable,
+ [
+ 'where' => [
+ 'code = ? ' => $couponCode,
+ ],
+ ],
+ 'first'
+ );
+ }
+
+ $couponFrom = "
+ $couponTable c
+ INNER JOIN $couponItemTable ci
+ on ci.coupon_id = c.id
+ ";
+
+ return Database::select(
+ ['c.*'],
+ $couponFrom,
+ [
+ 'where' => [
+ 'c.code = ? AND ' => $couponCode,
+ 'c.valid_start <= ? AND ' => $dtmNow,
+ 'c.valid_end >= ? AND ' => $dtmNow,
+ 'ci.product_type = ? AND ' => $productType,
+ 'ci.product_id = ?' => $productId,
+ ],
+ ],
+ 'first'
+ );
+ }
+
+ /**
+ * Get data of a coupon for a service by the coupon ID.
+ *
+ * @param int $couponId The coupon ID
+ * @param int $serviceId The service ID
+ *
+ * @return array The coupon data
+ */
+ private function getDataCouponService(int $couponId, int $serviceId): array
+ {
+ $couponTable = Database::get_main_table(self::TABLE_COUPON);
+ $couponServiceTable = Database::get_main_table(self::TABLE_COUPON_SERVICE);
+ $dtmNow = api_get_utc_datetime();
+
+ $couponFrom = "
+ $couponTable c
+ INNER JOIN $couponServiceTable cs
+ on cs.coupon_id = c.id
+ ";
+
+ return Database::select(
+ ['c.*'],
+ $couponFrom,
+ [
+ 'where' => [
+ 'c.id = ? AND ' => $couponId,
+ 'c.valid_start <= ? AND ' => $dtmNow,
+ 'c.valid_end >= ? AND ' => $dtmNow,
+ 'cs.service_id = ?' => $serviceId,
+ ],
+ ],
+ 'first'
+ );
+ }
+
+ /**
+ * Get data of coupon for a service by the coupon code.
+ *
+ * @param string $couponCode The coupon code
+ * @param int $serviceId The service ID
+ *
+ * @return array The coupon data
+ */
+ private function getDataCouponServiceByCode(string $couponCode, int $serviceId): array
+ {
+ $couponTable = Database::get_main_table(self::TABLE_COUPON);
+ $couponServiceTable = Database::get_main_table(self::TABLE_COUPON_SERVICE);
+ $dtmNow = api_get_utc_datetime();
+
+ $couponFrom = "
+ $couponTable c
+ INNER JOIN $couponServiceTable cs
+ on cs.coupon_id = c.id
+ ";
+
+ return Database::select(
+ ['c.*'],
+ $couponFrom,
+ [
+ 'where' => [
+ 'c.code = ? AND ' => $couponCode,
+ 'c.valid_start <= ? AND ' => $dtmNow,
+ 'c.valid_end >= ? AND ' => $dtmNow,
+ 'cs.service_id = ?' => $serviceId,
+ ],
+ ],
+ 'first'
+ );
+ }
+
+ /**
+ * Update a coupon.
+ */
+ private function updateCoupon(array $coupon): void
+ {
+ $couponExist = $this->getCouponByCode($coupon['code']);
+ if (!$couponExist) {
+ Display::addFlash(
+ Display::return_message(
+ $this->get_lang('CouponNoExists'),
+ 'error',
+ false
+ )
+ );
+
+ return;
+ }
+
+ $values = [
+ 'valid_start' => $coupon['valid_start'],
+ 'valid_end' => $coupon['valid_end'],
+ 'active' => $coupon['active'],
+ ];
+
+ Database::update(
+ self::TABLE_COUPON,
+ $values,
+ ['id = ?' => $coupon['id']]
+ );
+ }
+
+ /**
+ * Register a coupon.
+ */
+ private function registerCoupon(array $coupon): int
+ {
+ $couponExist = $this->getCouponByCode($coupon['code']);
+ if ($couponExist) {
+ Display::addFlash(
+ Display::return_message(
+ $this->get_lang('CouponCodeUsed'),
+ 'error',
+ false
+ )
+ );
+
+ return 0;
+ }
+
+ $values = [
+ 'code' => (string) $coupon['code'],
+ 'discount_type' => (int) $coupon['discount_type'],
+ 'discount_amount' => $coupon['discount_amount'],
+ 'valid_start' => $coupon['valid_start'],
+ 'valid_end' => $coupon['valid_end'],
+ 'delivered' => 0,
+ 'active' => $coupon['active'],
+ ];
+
+ return Database::insert(self::TABLE_COUPON, $values);
+ }
+
+ /**
+ * Register a coupon item.
+ *
+ * @param int $couponId The coupon ID
+ * @param int $productType The product type
+ * @param int $productId The product ID
+ */
+ private function registerCouponItem(int $couponId, int $productType, int $productId): void
+ {
+ $coupon = $this->getDataCoupon($couponId);
+ if (empty($coupon)) {
+ Display::addFlash(
+ Display::return_message(
+ $this->get_lang('CouponNoExists'),
+ 'error',
+ false
+ )
+ );
+
+ return;
+ }
+
+ $values = [
+ 'coupon_id' => $couponId,
+ 'product_type' => $productType,
+ 'product_id' => $productId,
+ ];
+
+ Database::insert(self::TABLE_COUPON_ITEM, $values);
+ }
+
+ /**
+ * Remove all coupon items for a product type and coupon ID.
+ *
+ * @param int $productType The product type
+ * @param int $couponId The coupon ID
+ */
+ private function deleteCouponItemsByCoupon(int $productType, int $couponId): void
+ {
+ Database::delete(
+ Database::get_main_table(self::TABLE_COUPON_ITEM),
+ [
+ 'product_type = ? AND ' => $productType,
+ 'coupon_id = ?' => $couponId,
+ ]
+ );
+ }
+
+ /**
+ * Register a coupon service.
+ *
+ * @param int $couponId The coupon ID
+ * @param int $serviceId The service ID
+ */
+ private function registerCouponService(int $couponId, int $serviceId): void
+ {
+ $coupon = $this->getDataCoupon($couponId);
+ if (empty($coupon)) {
+ Display::addFlash(
+ Display::return_message(
+ $this->get_lang('CouponNoExists'),
+ 'error',
+ false
+ )
+ );
+
+ return;
+ }
+
+ $values = [
+ 'coupon_id' => $couponId,
+ 'service_id' => $serviceId,
+ ];
+
+ Database::insert(self::TABLE_COUPON_SERVICE, $values);
+ }
+
+ /**
+ * Remove all coupon services for a product type and coupon ID.
+ */
+ private function deleteCouponServicesByCoupon(int $couponId): void
+ {
+ Database::delete(
+ Database::get_main_table(self::TABLE_COUPON_SERVICE),
+ [
+ 'coupon_id = ?' => (int) $couponId,
+ ]
+ );
+ }
+
+ /**
+ * Get an array of subscriptions.
+ *
+ * @return array Subscriptions data
+ */
+ private function getDataSubscriptions(int $productType, int $productId): array
+ {
+ $subscriptionTable = Database::get_main_table(self::TABLE_SUBSCRIPTION);
+
+ return Database::select(
+ ['*'],
+ $subscriptionTable,
+ [
+ 'where' => [
+ 'product_type = ? AND ' => (int) $productType,
+ 'product_id = ? ' => (int) $productId,
+ ],
+ 'order' => 'duration ASC',
+ ]
+ );
+ }
+
+ /**
+ * Get data of a subscription for a product (course or service) by the subscription ID.
+ *
+ * @param int $productType The product type
+ * @param int $productId The product ID
+ * @param int $duration The duration (in seconds)
+ *
+ * @return array The subscription data
+ */
+ private function getDataSubscription(int $productType, int $productId, int $duration): array
+ {
+ $subscriptionTable = Database::get_main_table(self::TABLE_SUBSCRIPTION);
+
+ return Database::select(
+ ['*'],
+ $subscriptionTable,
+ [
+ 'where' => [
+ 'product_type = ? AND ' => $productType,
+ 'product_id = ? AND ' => $productId,
+ 'duration = ? ' => $duration,
+ ],
+ ],
+ 'first'
+ );
+ }
+
+ /**
+ * Update a subscription.
+ */
+ public function updateSubscription(int $productType, int $productId, int $taxPerc): bool
+ {
+ $values = [
+ 'tax_perc' => $taxPerc,
+ ];
+
return Database::update(
- $serviceSaleTable,
- ['status' => (int) $newStatus],
- ['id = ?' => (int) $serviceSaleId]
+ self::TABLE_SUBSCRIPTION,
+ $values,
+ [
+ 'product_type = ? AND ' => $productType,
+ 'product_id = ?' => $productId,
+ ]
+ ) > 0;
+ }
+
+ /**
+ * Register a subscription.
+ */
+ private function registerSubscription(array $subscription, array $frequency): bool
+ {
+ $values = [
+ 'product_type' => (int) $subscription['product_type'],
+ 'product_id' => (int) $subscription['product_id'],
+ 'duration' => (int) $frequency['duration'],
+ 'currency_id' => (int) $subscription['currency_id'],
+ 'tax_perc' => (int) $subscription['tax_perc'],
+ 'price' => (float) $frequency['price'],
+ ];
+
+ return Database::insert(self::TABLE_SUBSCRIPTION, $values) > 0;
+ }
+
+ /**
+ * Update the subscription sale status.
+ *
+ * @param int $saleId The sale ID
+ * @param int $newStatus The new status
+ */
+ private function updateSubscriptionSaleStatus(int $saleId, int $newStatus = self::SALE_STATUS_PENDING): void
+ {
+ $saleTable = Database::get_main_table(self::TABLE_SUBSCRIPTION_SALE);
+
+ Database::update(
+ $saleTable,
+ ['status' => $newStatus],
+ ['id = ?' => $saleId]
+ );
+ }
+
+ /**
+ * Get the user status for the subscription session.
+ *
+ * @param int $userId The user ID
+ * @param Session $session The session
+ */
+ private function getUserStatusForSubscriptionSession(int $userId, Session $session): string
+ {
+ if (empty($userId)) {
+ return 'NO';
+ }
+
+ $scuRepo = Database::getManager()->getRepository(SessionRelCourseRelUser::class);
+
+ $buySaleTable = Database::get_main_table(self::TABLE_SUBSCRIPTION_SALE);
+
+ // Check if user bought the course
+ $sale = Database::select(
+ 'COUNT(1) as qty',
+ $buySaleTable,
+ [
+ 'where' => [
+ 'user_id = ? AND product_type = ? AND product_id = ? AND status = ? AND (expired is NULL OR expired <> ?)' => [
+ $userId,
+ self::PRODUCT_TYPE_SESSION,
+ $session->getId(),
+ self::SALE_STATUS_PENDING,
+ 1,
+ ],
+ ],
+ ],
+ 'first'
);
+
+ if ($sale['qty'] > 0) {
+ return 'TMP';
+ }
+
+ // Check if user is already subscribed to session
+ $userSubscription = $scuRepo->findBy([
+ 'session' => $session,
+ 'user' => $userId,
+ ]);
+
+ if (!empty($userSubscription)) {
+ return 'YES';
+ }
+
+ return 'NO';
}
- public function get_name()
+ /**
+ * Get the user status for the subscription course.
+ *
+ * @param int $userId The user Id
+ * @param Course $course The course
+ */
+ private function getUserStatusForSubscriptionCourse(int $userId, Course $course): string
{
- return 'BuyCourses'; // TODO: Change the autogenerated stub
+ if (empty($userId)) {
+ return 'NO';
+ }
+
+ $cuRepo = Database::getManager()->getRepository(CourseRelUser::class);
+ $buySaleTable = Database::get_main_table(self::TABLE_SUBSCRIPTION_SALE);
+
+ // Check if user bought the course
+ $sale = Database::select(
+ 'COUNT(1) as qty',
+ $buySaleTable,
+ [
+ 'where' => [
+ 'user_id = ? AND product_type = ? AND product_id = ? AND status = ? AND (expired is NULL OR expired <> ?)' => [
+ $userId,
+ self::PRODUCT_TYPE_COURSE,
+ $course->getId(),
+ self::SALE_STATUS_PENDING,
+ 1,
+ ],
+ ],
+ ],
+ 'first'
+ );
+
+ if ($sale['qty'] > 0) {
+ return 'TMP';
+ }
+
+ // Check if a user is already subscribed to course
+ $userSubscription = $cuRepo->findBy([
+ 'course' => $course,
+ 'user' => $userId,
+ ]);
+
+ if (!empty($userSubscription)) {
+ return 'YES';
+ }
+
+ return 'NO';
}
}
diff --git a/public/plugin/BuyCourses/src/buycourses.ajax.php b/public/plugin/BuyCourses/src/buycourses.ajax.php
index 998b1476d6e..91f3afe3000 100644
--- a/public/plugin/BuyCourses/src/buycourses.ajax.php
+++ b/public/plugin/BuyCourses/src/buycourses.ajax.php
@@ -1,4 +1,6 @@
* '.$plugin->get_lang('NoPayPalAccountDetected').'';
}
+
break;
+
case 'saleInfo':
if (api_is_anonymous()) {
break;
@@ -52,8 +56,7 @@
$productImage = $productInfo['course_image_large'];
} else {
$productImage = ($productInfo['image'])
- ? $productInfo['image']
- : Template::get_icon_path('session_default.png');
+ ?: Template::get_icon_path('session_default.png');
}
$userInfo = api_get_user_info($sale['user_id']);
@@ -80,7 +83,9 @@
$html .= ' ';
echo $html;
+
break;
+
case 'stats':
if (api_is_anonymous()) {
break;
@@ -120,20 +125,22 @@
$html = '');
+$form->addSelect('status', $plugin->get_lang('CouponStatus'), $couponStatuses);
+$form->addHtml('
');
+$form->addButtonFilter(get_lang('Search'));
+$form->setDefaults([
+ 'filter_type' => $selectedFilterType,
+ 'status' => $selectedStatus,
+]);
+
+$coupons = $plugin->getCouponsListByStatus($selectedStatus);
+$currency = $plugin->getSelectedCurrency();
+
+foreach ($coupons as &$coupon) {
+ if (BuyCoursesPlugin::COUPON_DISCOUNT_TYPE_PERCENTAGE == $coupon['discount_type']) {
+ $coupon['discount_value'] = $coupon['discount_amount'].' %';
+ } elseif (BuyCoursesPlugin::COUPON_DISCOUNT_TYPE_AMOUNT == $coupon['discount_type']) {
+ $coupon['discount_value'] = $plugin->getPriceWithCurrencyFromIsoCode($coupon['discount_amount'], $currency['iso_code']);
+ }
+ $coupon['discount_type'] = $discountTypes[$coupon['discount_type']];
+}
+
+$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('CouponList');
+$template = new Template($templateName);
+
+$toolbar = Display::url(
+ Display::returnFontAwesomeIcon('fas fa-plus').
+ $plugin->get_lang('CouponAdd'),
+ api_get_path(WEB_PLUGIN_PATH).'BuyCourses/src/coupon_add.php',
+ ['class' => 'btn btn-primary']
+);
+
+$template->assign(
+ 'actions',
+ Display::toolbarAction('toolbar', [$toolbar])
+);
+
+$template->assign('form', $form->returnForm());
+$template->assign('selected_status', $selectedStatus);
+$template->assign('coupon_list', $coupons);
+$template->assign('coupon_status_active', BuyCoursesPlugin::COUPON_STATUS_ACTIVE);
+$template->assign('coupon_status_disable', BuyCoursesPlugin::COUPON_STATUS_DISABLE);
+
+$content = $template->fetch('BuyCourses/view/coupons.tpl');
+
+$template->assign('header', $templateName);
+$template->assign('content', $content);
+$template->display_one_col_template();
diff --git a/public/plugin/BuyCourses/src/course_catalog.php b/public/plugin/BuyCourses/src/course_catalog.php
index 8d827ccad4f..d26bd859b34 100644
--- a/public/plugin/BuyCourses/src/course_catalog.php
+++ b/public/plugin/BuyCourses/src/course_catalog.php
@@ -1,4 +1,6 @@
getCatalogCourseList($first, $pageSize, $nameFilter, $minFilter, $maxFilter, 'count');
$pagesCount = ceil($totalItems / $pageSize);
-$url = api_get_self().'?';
-$pagination = Display::getPagination($url, $currentPage, $pagesCount, $totalItems);
+$pagination = Display::getPagination(api_get_self().'?', $currentPage, $pagesCount, $totalItems);
// View
if (api_is_platform_admin()) {
@@ -72,7 +73,7 @@
} else {
$interbreadcrumb[] = [
'url' => 'course_panel.php',
- 'name' => get_lang('Dashboard'),
+ 'name' => get_lang('TabsDashboard'),
];
}
diff --git a/public/plugin/BuyCourses/src/course_panel.php b/public/plugin/BuyCourses/src/course_panel.php
index b98085c21df..87209319ed9 100644
--- a/public/plugin/BuyCourses/src/course_panel.php
+++ b/public/plugin/BuyCourses/src/course_panel.php
@@ -1,4 +1,6 @@
$plugin->get_lang('CourseListOnSale')]
);
-$templateName = get_lang('Dashboard');
+$htmlHeadXtra[] = api_get_css(api_get_path(WEB_PLUGIN_PATH).'BuyCourses/resources/css/style.css');
+
+$templateName = get_lang('TabsDashboard');
$tpl = new Template($templateName);
$tpl->assign('showing_courses', true);
$tpl->assign('sessions_are_included', $includeSessions);
diff --git a/public/plugin/BuyCourses/src/error.php b/public/plugin/BuyCourses/src/error.php
index 290274166f5..2cc57a1117e 100644
--- a/public/plugin/BuyCourses/src/error.php
+++ b/public/plugin/BuyCourses/src/error.php
@@ -1,12 +1,15 @@
addDatePicker('date_start', get_lang('Start date'), false);
-$form->addDatePicker('date_end', get_lang('End date'), false);
-$form->addButton('export_sales', get_lang('Excel export'), 'check', 'primary');
+$form->addDatePicker('date_start', get_lang('DateStart'), false);
+$form->addDatePicker('date_end', get_lang('DateEnd'), false);
+$form->addButton('export_sales', get_lang('ExportExcel'), 'check', 'primary');
$salesStatus = [];
if ($form->validate()) {
@@ -51,7 +50,7 @@
$templateName = $plugin->get_lang('ExportReport');
$toolbar = Display::url(
- Display::getMdiIcon(ActionIcon::BACK, 'ch-tool-icon', null, ICON_SIZE_MEDIUM, get_lang('Back')),
+ Display::return_icon('back.png', get_lang('GoBack'), [], ICON_SIZE_MEDIUM),
api_get_path(WEB_PLUGIN_PATH).'BuyCourses/src/sales_report.php'
);
$template = new Template($templateName);
diff --git a/public/plugin/BuyCourses/src/export_subscription_report.php b/public/plugin/BuyCourses/src/export_subscription_report.php
new file mode 100644
index 00000000000..55052efd031
--- /dev/null
+++ b/public/plugin/BuyCourses/src/export_subscription_report.php
@@ -0,0 +1,65 @@
+addDatePicker('date_start', get_lang('DateStart'), false);
+$form->addDatePicker('date_end', get_lang('DateEnd'), false);
+$form->addButton('export_sales', get_lang('ExportExcel'), 'check', 'primary');
+$salesStatus = [];
+
+if ($form->validate()) {
+ $reportValues = $form->getSubmitValues();
+
+ $dateStart = $reportValues['date_start'];
+ $dateEnd = $reportValues['date_end'];
+
+ if (null == $dateStart || null == $dateEnd) {
+ Display::addFlash(
+ Display::return_message($plugin->get_lang('SelectDateRange'), 'error', false)
+ );
+ } elseif ($dateStart > $dateEnd) {
+ Display::addFlash(
+ Display::return_message(get_lang('EndDateCannotBeBeforeTheStartDate'), 'error', false)
+ );
+ } else {
+ $salesStatus = $plugin->getSubscriptionSaleListReport($dateStart, $dateEnd);
+ }
+}
+
+if (!empty($salesStatus)) {
+ $archiveFile = 'export_report_sales_'.api_get_local_time();
+ Export::arrayToXls($salesStatus, $archiveFile);
+}
+$interbreadcrumb[] = [
+ 'url' => '../index.php', 'name' => $plugin->get_lang('plugin_title'),
+];
+$interbreadcrumb[] = [
+ 'url' => api_get_path(WEB_PLUGIN_PATH).'BuyCourses/src/subscription_sales_report.php',
+ 'name' => $plugin->get_lang('SubscriptionSalesReport'),
+];
+
+$templateName = $plugin->get_lang('ExportReport');
+$toolbar = Display::url(
+ Display::return_icon('back.png', get_lang('GoBack'), [], ICON_SIZE_MEDIUM),
+ api_get_path(WEB_PLUGIN_PATH).'BuyCourses/src/subscription_sales_report.php'
+);
+$template = new Template($templateName);
+$template->assign(
+ 'actions',
+ Display::toolbarAction('toolbar', [$toolbar])
+);
+$template->assign('form', $form->returnForm());
+$content = $template->fetch('BuyCourses/view/export_report.tpl');
+$template->assign('header', $templateName);
+$template->assign('content', $content);
+$template->display_one_col_template();
diff --git a/public/plugin/BuyCourses/src/expresscheckout.php b/public/plugin/BuyCourses/src/expresscheckout.php
index e98dff6067e..95d0f12a575 100644
--- a/public/plugin/BuyCourses/src/expresscheckout.php
+++ b/public/plugin/BuyCourses/src/expresscheckout.php
@@ -1,4 +1,7 @@
get('unregistered_users_enable');
+$userIsAdmin = api_is_platform_admin();
+
if (('true' === $allow && api_is_anonymous()) || !api_is_anonymous()) {
+ $webPluginPath = api_get_path(WEB_PLUGIN_PATH).'BuyCourses/';
+
+ $countCourses = $plugin->getCatalogCourseList(
+ 0,
+ BuyCoursesPlugin::PAGINATION_PAGE_SIZE,
+ null,
+ 0,
+ 0,
+ 'count'
+ );
+
+ if ($countCourses > 0 && !$userIsAdmin) {
+ api_location($webPluginPath.'src/course_catalog.php');
+ }
+
+ $countSessions = $plugin->getCatalogSessionList(
+ 0,
+ BuyCoursesPlugin::PAGINATION_PAGE_SIZE,
+ null,
+ 0,
+ 0,
+ 'count'
+ );
+
+ if ($countSessions > 0 && !$userIsAdmin) {
+ api_location($webPluginPath.'src/session_catalog.php');
+ }
+
+ $htmlHeadXtra[] = api_get_css(api_get_path(WEB_PLUGIN_PATH).'BuyCourses/resources/css/style.css');
+
$tpl = new Template();
$content = $tpl->fetch('BuyCourses/view/index.tpl');
$tpl->assign('content', $content);
- $tpl->display_one_col_template();
+ $tpl->display_one_col_template(false);
}
diff --git a/public/plugin/BuyCourses/src/index.php b/public/plugin/BuyCourses/src/index.php
index b3d9bbc7f37..174d7fd709f 100644
--- a/public/plugin/BuyCourses/src/index.php
+++ b/public/plugin/BuyCourses/src/index.php
@@ -1 +1,3 @@
getDataInvoice($saleId, $isService);
$taxAppliesTo = $globalParameters['tax_applies_to'];
-$taxEnable = 'true' === $plugin->get('tax_enable') &&
- (BuyCoursesPlugin::TAX_APPLIES_TO_ALL == $taxAppliesTo ||
- (BuyCoursesPlugin::TAX_APPLIES_TO_ONLY_COURSE == $taxAppliesTo && !$isService) ||
- (BuyCoursesPlugin::TAX_APPLIES_TO_ONLY_SESSION == $taxAppliesTo && $isService));
+$taxEnable = 'true' === $plugin->get('tax_enable')
+ && (BuyCoursesPlugin::TAX_APPLIES_TO_ALL == $taxAppliesTo
+ || (BuyCoursesPlugin::TAX_APPLIES_TO_ONLY_COURSE == $taxAppliesTo && !$isService)
+ || (BuyCoursesPlugin::TAX_APPLIES_TO_ONLY_SESSION == $taxAppliesTo && $isService));
$htmlText = '';
$htmlText .= '