diff --git a/main/inc/lib/CoursesAndSessionsCatalog.class.php b/main/inc/lib/CoursesAndSessionsCatalog.class.php
index c548a61757..b9c489b42a 100644
--- a/main/inc/lib/CoursesAndSessionsCatalog.class.php
+++ b/main/inc/lib/CoursesAndSessionsCatalog.class.php
@@ -477,7 +477,7 @@ class CoursesAndSessionsCatalog
{
$em = Database::getManager();
$urlId = api_get_current_access_url_id();
- $date = Database::escape_string($date);
+
$sql = "SELECT s.id FROM session s ";
$sql .= "
INNER JOIN access_url_rel_session ars
@@ -490,6 +490,7 @@ class CoursesAndSessionsCatalog
";
if (!is_null($date)) {
+ $date = Database::escape_string($date);
$sql .= "
AND (
('$date' BETWEEN DATE(s.access_start_date) AND DATE(s.access_end_date))
diff --git a/plugin/buycourses/CHANGELOG.md b/plugin/buycourses/CHANGELOG.md
index 865d81d154..ab30cadbc4 100644
--- a/plugin/buycourses/CHANGELOG.md
+++ b/plugin/buycourses/CHANGELOG.md
@@ -1,3 +1,13 @@
+v5.0 - 2019-02-06
+====
+
+This version includes two additional modules (taxes and invoices),
+which can be enabled from the configuration.
+
+The file update.php must be executed to update the structure of the tables
+ in the database.
+
+
v4.0 - 2017-04-25
====
diff --git a/plugin/buycourses/database.php b/plugin/buycourses/database.php
index fa270bda1b..7e8442101b 100644
--- a/plugin/buycourses/database.php
+++ b/plugin/buycourses/database.php
@@ -90,6 +90,11 @@ $itemTable->addColumn(
\Doctrine\DBAL\Types\Type::INTEGER,
['unsigned' => true]
);
+$itemTable->addColumn(
+ 'tax_perc',
+ \Doctrine\DBAL\Types\Type::INTEGER,
+ ['unsigned' => true, 'notnull' => false]
+);
$itemTable->setPrimaryKey(['id']);
$itemTable->addForeignKeyConstraint(
$currencyTable,
@@ -195,6 +200,21 @@ $saleTable->addColumn(
\Doctrine\DBAL\Types\Type::DECIMAL,
['scale' => 2]
);
+$saleTable->addColumn(
+ 'price_without_tax',
+ \Doctrine\DBAL\Types\Type::DECIMAL,
+ ['scale' => 2, 'notnull' => false]
+);
+$saleTable->addColumn(
+ 'tax_perc',
+ \Doctrine\DBAL\Types\Type::INTEGER,
+ ['unsigned' => true, 'notnull' => false]
+);
+$saleTable->addColumn(
+ 'tax_amount',
+ \Doctrine\DBAL\Types\Type::DECIMAL,
+ ['scale' => 2, 'notnull' => false]
+);
$saleTable->addColumn(
'currency_id',
\Doctrine\DBAL\Types\Type::INTEGER,
@@ -202,6 +222,7 @@ $saleTable->addColumn(
);
$saleTable->addColumn('status', \Doctrine\DBAL\Types\Type::INTEGER);
$saleTable->addColumn('payment_type', \Doctrine\DBAL\Types\Type::INTEGER);
+$saleTable->addColumn('invoice', \Doctrine\DBAL\Types\Type::INTEGER);
$saleTable->setPrimaryKey(['id']);
$saleTable->addForeignKeyConstraint(
$currencyTable,
@@ -250,6 +271,21 @@ $servicesNodeTable->addColumn(
\Doctrine\DBAL\Types\Type::DECIMAL,
['scale' => 2]
);
+$servicesNodeTable->addColumn(
+ 'price_without_tax',
+ \Doctrine\DBAL\Types\Type::DECIMAL,
+ ['scale' => 2, 'notnull' => false]
+);
+$servicesNodeTable->addColumn(
+ 'tax_perc',
+ \Doctrine\DBAL\Types\Type::INTEGER,
+ ['unsigned' => true, 'notnull' => false]
+);
+$servicesNodeTable->addColumn(
+ 'tax_amount',
+ \Doctrine\DBAL\Types\Type::DECIMAL,
+ ['scale' => 2, 'notnull' => false]
+);
$servicesNodeTable->addColumn('node_type', \Doctrine\DBAL\Types\Type::INTEGER);
$servicesNodeTable->addColumn('node_id', \Doctrine\DBAL\Types\Type::INTEGER);
$servicesNodeTable->addColumn('buyer_id', \Doctrine\DBAL\Types\Type::INTEGER);
@@ -265,6 +301,7 @@ $servicesNodeTable->addColumn(
);
$servicesNodeTable->addColumn('status', \Doctrine\DBAL\Types\Type::INTEGER);
$servicesNodeTable->addColumn('payment_type', \Doctrine\DBAL\Types\Type::INTEGER);
+$servicesNodeTable->addColumn('invoice', \Doctrine\DBAL\Types\Type::INTEGER);
$servicesNodeTable->setPrimaryKey(['id']);
$servicesNodeTable->addForeignKeyConstraint(
$servicesTable,
@@ -291,8 +328,39 @@ $globalTable->addColumn(
['autoincrement' => true, 'unsigned' => true]
);
$globalTable->addColumn('terms_and_conditions', \Doctrine\DBAL\Types\Type::TEXT);
+$globalTable->addColumn('global_tax_perc', \Doctrine\DBAL\Types\Type::INTEGER);
+$globalTable->addColumn('tax_applies_to', \Doctrine\DBAL\Types\Type::INTEGER);
+$globalTable->addColumn('tax_name', \Doctrine\DBAL\Types\Type::STRING);
+$globalTable->addColumn('seller_name', \Doctrine\DBAL\Types\Type::STRING);
+$globalTable->addColumn('seller_id', \Doctrine\DBAL\Types\Type::STRING);
+$globalTable->addColumn('seller_address', \Doctrine\DBAL\Types\Type::STRING);
+$globalTable->addColumn('seller_email', \Doctrine\DBAL\Types\Type::STRING);
+$globalTable->addColumn('next_number_invoice', \Doctrine\DBAL\Types\Type::INTEGER);
+$globalTable->addColumn('invoice_series', \Doctrine\DBAL\Types\Type::STRING);
$globalTable->setPrimaryKey(['id']);
+$invoiceTable = $pluginSchema->createTable(BuyCoursesPlugin::TABLE_INVOICE);
+$invoiceTable->addColumn(
+ 'id',
+ \Doctrine\DBAL\Types\Type::INTEGER,
+ ['autoincrement' => true, 'unsigned' => true]
+);
+$invoiceTable->addColumn('sale_id', \Doctrine\DBAL\Types\Type::INTEGER);
+$invoiceTable->addColumn('is_service', \Doctrine\DBAL\Types\Type::INTEGER);
+$invoiceTable->addColumn(
+ 'num_invoice',
+ \Doctrine\DBAL\Types\Type::INTEGER,
+ ['unsigned' => true, 'notnull' => false]
+);
+$invoiceTable->addColumn(
+ 'year',
+ \Doctrine\DBAL\Types\Type::INTEGER,
+ ['unsigned' => true, 'notnull' => false]
+);
+$invoiceTable->addColumn('serie', \Doctrine\DBAL\Types\Type::STRING);
+$invoiceTable->addColumn('date_invoice', \Doctrine\DBAL\Types\Type::DATETIME);
+$invoiceTable->setPrimaryKey(['id']);
+
$queries = $pluginSchema->toSql($platform);
foreach ($queries as $query) {
@@ -631,3 +699,21 @@ foreach ($currencies as $currency) {
]
);
}
+
+$fieldlabel = 'buycourses_company';
+$fieldtype = '1';
+$fieldtitle = BuyCoursesPlugin::get_lang('Company');
+$fielddefault = '';
+$field_id = UserManager::create_extra_field($fieldlabel, $fieldtype, $fieldtitle, $fielddefault);
+
+$fieldlabel = 'buycourses_vat';
+$fieldtype = '1';
+$fieldtitle = BuyCoursesPlugin::get_lang('VAT');
+$fielddefault = '';
+$field_id = UserManager::create_extra_field($fieldlabel, $fieldtype, $fieldtitle, $fielddefault);
+
+$fieldlabel = 'buycourses_address';
+$fieldtype = '1';
+$fieldtitle = BuyCoursesPlugin::get_lang('Address');
+$fielddefault = '';
+$field_id = UserManager::create_extra_field($fieldlabel, $fieldtype, $fieldtitle, $fielddefault);
diff --git a/plugin/buycourses/lang/english.php b/plugin/buycourses/lang/english.php
index 1a5ca76432..eca6ea392c 100644
--- a/plugin/buycourses/lang/english.php
+++ b/plugin/buycourses/lang/english.php
@@ -9,6 +9,8 @@ $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";
@@ -160,3 +162,24 @@ $strings['BoughtBy'] = "BoughtBy";
$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";
diff --git a/plugin/buycourses/lang/spanish.php b/plugin/buycourses/lang/spanish.php
index 35b11882ce..50dcd64890 100644
--- a/plugin/buycourses/lang/spanish.php
+++ b/plugin/buycourses/lang/spanish.php
@@ -9,8 +9,9 @@ $strings['paypal_enable'] = "Habilitar PayPal";
$strings['commissions_enable'] = "Habilitar Comisiones";
$strings['transfer_enable'] = "Habilitar transferencia";
$strings['unregistered_users_enable'] = "Permitir usuarios sin registro en la plataforma";
+$strings['invoicing_enable'] = "Habilitar Facturación";
+$strings['tax_enable'] = "Habilitar Impuestos";
$strings['Free'] = "GRATIS";
-
$strings['PaypalPayoutCommissions'] = "Pagar comisiones por Paypal";
$strings['MyPayouts'] = "Mis Pagos";
$strings['Commission'] = "Comisión";
@@ -40,7 +41,7 @@ $strings['Buyer'] = "Comprador";
$strings['BankTransfer'] = "Transferencia Bancaria";
$strings['SaleInfo'] = "Información de la venta";
$strings['SaleStatusPending'] = "Venta pendiente";
-$strings['SaleStatusCancelled'] = "Venta cancelada";
+$strings['SaleStatusCanceled'] = "Venta cancelada";
$strings['SaleStatusCompleted'] = "Venta completada";
$strings['PayoutStatusPending'] = "Pago pendiente";
$strings['PayoutStatusCanceled'] = "Pago cancelado";
@@ -173,3 +174,37 @@ $strings['DeleteThisService'] = 'Eliminar este servicio';
$strings['YourCoursesNeedAtLeastOneLearningPath'] = 'Los cursos en los que estás registrado necesitan tener al menos una lección que contenga un item de cerficado final';
$strings['NoPaymentOptionAvailable'] = 'No existen opciones de pago. Por favor reporte este problema al administrador.';
$strings['XIsOnlyPaymentMethodAvailable'] = '%s es el único método de pago disponible para esta compra.';
+$strings['GlobalTaxPerc'] = "Porcentaje del impuesto global";
+$strings['GlobalTaxPercDescription'] = "Porcentaje por defecto que se usará, excepto si existe un impuesto específico en el curso, sesión o servicio.";
+$strings['TaxPerc'] = "Porcentaje del impuesto";
+$strings['TaxPercDescription'] = "Si se deja vacío se usará valor global por defecto.";
+$strings['ByDefault'] = "por defecto (valor global)";
+$strings['OnlyCourses'] = "Solo Cursos";
+$strings['OnlySessions'] = "Solo Sesiones";
+$strings['OnlyServices'] = "Solo Servicios";
+$strings['TaxAppliesTo'] = "Impuestos aplicados a";
+$strings['AllCoursesSessionsAndServices'] = "Todos (Cursos, sesiones y servicios)";
+$strings['TaxNameCustom'] = "Nombre del impuesto";
+$strings['TaxNameExamples'] = "VAT, IVA, IGV, TVA, IV ...";
+$strings['ErrorUpdateFieldDB'] = "Error al actualizar los campos de la base de datos";
+$strings['SellerName'] = "Nombre vendedor";
+$strings['SellerId'] = "Identificador vendedor";
+$strings['SellerAddress'] = "Dirección vendedor";
+$strings['SellerEmail'] = "E-mail vendedor";
+$strings['NextNumberInvoice'] = "Número siguiente factura";
+$strings['NextNumberInvoiceDescription'] = "Número de la siguiente factura asignado de forma manual";
+$strings['InvoiceSeries'] = "Serie factura";
+$strings['InvoiceSeriesDescription'] = "Parámetro opcional: Ejemplo de numeración factura <serie><año>/<número>";
+$strings['InvoiceView'] = "Ver factura";
+$strings['NoInvoiceEnable'] = "No está habilitado el bloque de facturación";
+$strings['Company'] = "Empresa";
+$strings['VAT'] = "CIF";
+$strings['Address'] = "Dirección";
+$strings['InvoiceNumber'] = "Num. factura";
+$strings['InvoiceDate'] = "Fecha de emisión";
+$strings['Invoice'] = "Factura";
+$strings['SaleEmail'] = "E-mail de ventas";
+$strings['PurchaseDetailsIntro'] = "Detalles de la comprar";
+$strings['PurchaseDetailsEnd'] = "Atentamente";
+$strings['ProductName'] = "Nombre producto";
+$strings['BankAccountIntro'] = "Información cuentas bancarias";
diff --git a/plugin/buycourses/resources/css/style.css b/plugin/buycourses/resources/css/style.css
index ff9e395394..11317a086c 100644
--- a/plugin/buycourses/resources/css/style.css
+++ b/plugin/buycourses/resources/css/style.css
@@ -41,6 +41,15 @@
letter-spacing: -0.020em;
}
+.buy-info .price-details-tax, .service-buy .price-details-tax {
+ font-size: 18px;
+ line-height: 24px;
+ font-weight: bold;
+ padding-bottom: 0px;
+ padding-top: 10px;
+ letter-spacing: -0.020em;
+}
+
.buy-info .buy-item .title {
margin-top: 5px;
font-weight: bold;
diff --git a/plugin/buycourses/src/buy_course_plugin.class.php b/plugin/buycourses/src/buy_course_plugin.class.php
index 5497ca4d7b..c2197eaf8d 100644
--- a/plugin/buycourses/src/buy_course_plugin.class.php
+++ b/plugin/buycourses/src/buy_course_plugin.class.php
@@ -31,6 +31,7 @@ class BuyCoursesPlugin extends Plugin
const TABLE_SERVICES_SALE = 'plugin_buycourses_service_sale';
const TABLE_CULQI = 'plugin_buycourses_culqi';
const TABLE_GLOBAL_CONFIG = 'plugin_buycourses_global_config';
+ const TABLE_INVOICE = 'plugin_buycourses_invoices';
const PRODUCT_TYPE_COURSE = 1;
const PRODUCT_TYPE_SESSION = 2;
const PAYMENT_TYPE_PAYPAL = 1;
@@ -51,6 +52,10 @@ class BuyCoursesPlugin extends Plugin
const SERVICE_TYPE_LP_FINAL_ITEM = 4;
const CULQI_INTEGRATION_TYPE = 'INTEG';
const CULQI_PRODUCTION_TYPE = 'PRODUC';
+ const TAX_APPLIES_TO_ALL = 1;
+ const TAX_APPLIES_TO_ONLY_COURSE = 2;
+ const TAX_APPLIES_TO_ONLY_SESSION = 3;
+ const TAX_APPLIES_TO_ONLY_SERVICES = 4;
public $isAdminPlugin = true;
@@ -60,7 +65,7 @@ class BuyCoursesPlugin extends Plugin
public function __construct()
{
parent::__construct(
- '1.0',
+ '5.0',
"
Jose Angel Ruiz - NoSoloRed (original author)
Francis Gonzales and Yannick Warnier - BeezNest (integration)
@@ -81,6 +86,8 @@ class BuyCoursesPlugin extends Plugin
'commissions_enable' => 'boolean',
'unregistered_users_enable' => 'boolean',
'hide_free_text' => 'boolean',
+ 'invoicing_enable' => 'boolean',
+ 'tax_enable' => 'boolean',
]
);
}
@@ -164,6 +171,131 @@ class BuyCoursesPlugin extends Plugin
$this->manageTab(false);
}
+ public function update()
+ {
+ $table = self::TABLE_GLOBAL_CONFIG;
+ $sql = "SHOW COLUMNS FROM $table WHERE Field = 'global_tax_perc'";
+ $res = Database::query($sql);
+
+ if (Database::num_rows($res) === 0) {
+ $sql = "ALTER TABLE $table ADD (
+ sale_email varchar(255) NOT NULL,
+ global_tax_perc int unsigned NOT NULL,
+ tax_applies_to int unsigned NOT NULL,
+ tax_name varchar(255) NOT NULL,
+ seller_name varchar(255) NOT NULL,
+ seller_id varchar(255) NOT NULL,
+ seller_address varchar(255) NOT NULL,
+ seller_email varchar(255) NOT NULL,
+ next_number_invoice int unsigned NOT NULL,
+ invoice_series varchar(255) NOT NULL
+ )";
+ $res = Database::query($sql);
+ if (!$res) {
+ echo Display::return_message($this->get_lang('ErrorUpdateFieldDB'), 'warning');
+ }
+ }
+
+ $table = self::TABLE_ITEM;
+ $sql = "SHOW COLUMNS FROM $table WHERE Field = 'tax_perc'";
+ $res = Database::query($sql);
+
+ if (Database::num_rows($res) === 0) {
+ $sql = "ALTER TABLE $table ADD tax_perc int unsigned NULL";
+ $res = Database::query($sql);
+ if (!$res) {
+ echo Display::return_message($this->get_lang('ErrorUpdateFieldDB'), 'warning');
+ }
+ }
+
+ $table = self::TABLE_SERVICES;
+ $sql = "SHOW COLUMNS FROM $table WHERE Field = 'tax_perc'";
+ $res = Database::query($sql);
+
+ if (Database::num_rows($res) === 0) {
+ $sql = "ALTER TABLE $table ADD tax_perc int unsigned NULL";
+ $res = Database::query($sql);
+ if (!$res) {
+ echo Display::return_message($this->get_lang('ErrorUpdateFieldDB'), 'warning');
+ }
+ }
+
+ $table = self::TABLE_SALE;
+ $sql = "SHOW COLUMNS FROM $table WHERE Field = 'tax_perc'";
+ $res = Database::query($sql);
+
+ if (Database::num_rows($res) === 0) {
+ $sql = "ALTER TABLE $table ADD (
+ price_without_tax decimal(10,2) NULL,
+ tax_perc int unsigned NULL,
+ tax_amount decimal(10,2) NULL,
+ invoice int unsigned NULL
+ )";
+ $res = Database::query($sql);
+ if (!$res) {
+ echo Display::return_message($this->get_lang('ErrorUpdateFieldDB'), 'warning');
+ }
+ }
+
+ $table = self::TABLE_SERVICES_SALE;
+ $sql = "SHOW COLUMNS FROM $table WHERE Field = 'tax_perc'";
+ $res = Database::query($sql);
+
+ if (Database::num_rows($res) === 0) {
+ $sql = "ALTER TABLE $table ADD (
+ price_without_tax decimal(10,2) NULL,
+ tax_perc int unsigned NULL,
+ tax_amount decimal(10,2) NULL,
+ invoice int unsigned NULL
+ )";
+ $res = Database::query($sql);
+ if (!$res) {
+ echo Display::return_message($this->get_lang('ErrorUpdateFieldDB'), 'warning');
+ }
+ }
+
+ $table = self::TABLE_INVOICE;
+ $sql = "CREATE TABLE IF NOT EXISTS $table (
+ id int unsigned NOT NULL AUTO_INCREMENT,
+ sale_id int unsigned NOT NULL,
+ is_service int unsigned NOT NULL,
+ num_invoice int unsigned NOT NULL,
+ year int(4) unsigned NOT NULL,
+ serie varchar(255) NOT NULL,
+ date_invoice datetime NOT NULL,
+ PRIMARY KEY (id)
+ )";
+ $res = Database::query($sql);
+
+ Display::addFlash(
+ Display::return_message(
+ $this->get_lang('Updated'),
+ 'info',
+ false
+ )
+ );
+
+ $fieldlabel = 'buycourses_company';
+ $fieldtype = '1';
+ $fieldtitle = $this->get_lang('Company');
+ $fielddefault = '';
+ $field_id = UserManager::create_extra_field($fieldlabel, $fieldtype, $fieldtitle, $fielddefault);
+
+ $fieldlabel = 'buycourses_vat';
+ $fieldtype = '1';
+ $fieldtitle = $this->get_lang('VAT');
+ $fielddefault = '';
+ $field_id = UserManager::create_extra_field($fieldlabel, $fieldtype, $fieldtitle, $fielddefault);
+
+ $fieldlabel = 'buycourses_address';
+ $fieldtype = '1';
+ $fieldtitle = $this->get_lang('Address');
+ $fielddefault = '';
+ $field_id = UserManager::create_extra_field($fieldlabel, $fieldtype, $fieldtitle, $fielddefault);
+
+ header('Location: '.api_get_path(WEB_PLUGIN_PATH).'buycourses');
+ }
+
/**
* This function verify if the plugin is enable and return the price info for a course or session in the new grid
* catalog for 1.11.x , the main purpose is to show if a course or session is in sale it shows in the main platform
@@ -212,7 +344,8 @@ class BuyCoursesPlugin extends Plugin
*/
public function returnBuyCourseButton($productId, $productType)
{
- $url = api_get_path(WEB_PLUGIN_PATH).'buycourses/src/process.php?i='.intval($productId).'&t='.$productType;
+ $productId = (int) $productId;
+ $url = api_get_path(WEB_PLUGIN_PATH).'buycourses/src/process.php?i='.$productId.'&t='.Security::remove_XSS($productType);
$html = ''.
Display::returnFontAwesomeIcon('shopping-cart').'';
@@ -267,7 +400,7 @@ class BuyCoursesPlugin extends Plugin
Database::update(
$currencyTable,
['status' => 1],
- ['id = ?' => intval($selectedId)]
+ ['id = ?' => (int) $selectedId]
);
}
@@ -350,7 +483,7 @@ class BuyCoursesPlugin extends Plugin
{
return Database::delete(
Database::get_main_table(self::TABLE_TRANSFER),
- ['id = ?' => intval($id)]
+ ['id = ?' => (int) $id]
);
}
@@ -379,8 +512,8 @@ class BuyCoursesPlugin extends Plugin
[
'where' => [
'i.product_id = ? AND i.product_type = ?' => [
- intval($productId),
- intval($itemType),
+ (int) $productId,
+ (int) $itemType,
],
],
],
@@ -525,12 +658,29 @@ class BuyCoursesPlugin extends Plugin
continue;
}
+ $price = $item['price'];
+ $taxPerc = null;
+ $priceWithoutTax = $item['price'];
+
+ $taxEnable = $this->get('tax_enable') === 'true';
+ $globalParameters = $this->getGlobalParameters();
+ $taxAppliesTo = $globalParameters['tax_applies_to'];
+ if ($taxEnable &&
+ ($taxAppliesTo == self::TAX_APPLIES_TO_ALL || $taxAppliesTo == self::TAX_APPLIES_TO_ONLY_COURSE)
+ ) {
+ $globalTaxPerc = $globalParameters['global_tax_perc'];
+ $precision = 2;
+ $taxPerc = is_null($item['tax_perc']) ? $globalTaxPerc : $item['tax_perc'];
+ $taxAmount = round($priceWithoutTax * $taxPerc / 100, $precision);
+ $price = $priceWithoutTax + $taxAmount;
+ }
+
$courseItem = [
'id' => $course->getId(),
'title' => $course->getTitle(),
'code' => $course->getCode(),
'course_img' => null,
- 'price' => $item['price'],
+ 'price' => $price,
'currency' => $item['iso_code'],
'teachers' => [],
'enrolled' => $this->getUserStatusForCourse(api_get_user_id(), $course),
@@ -592,6 +742,24 @@ class BuyCoursesPlugin extends Plugin
]
);
+ $price = $item['price'];
+ $taxPerc = null;
+ $priceWithoutTax = $item['price'];
+ $precision = 2;
+
+ $taxEnable = $this->get('tax_enable') === 'true';
+ $globalParameters = $this->getGlobalParameters();
+ $taxAppliesTo = $globalParameters['tax_applies_to'];
+ if ($taxEnable &&
+ ($taxAppliesTo == self::TAX_APPLIES_TO_ALL || $taxAppliesTo == self::TAX_APPLIES_TO_ONLY_COURSE)
+ ) {
+ $globalTaxPerc = $globalParameters['global_tax_perc'];
+ $precision = 2;
+ $taxPerc = is_null($item['tax_perc']) ? $globalTaxPerc : $item['tax_perc'];
+ $taxAmount = round($priceWithoutTax * $taxPerc / 100, $precision);
+ $price = $priceWithoutTax + $taxAmount;
+ }
+
$courseInfo = [
'id' => $course->getId(),
'title' => $course->getTitle(),
@@ -599,7 +767,13 @@ class BuyCoursesPlugin extends Plugin
'code' => $course->getCode(),
'visual_code' => $course->getVisualCode(),
'teachers' => [],
- 'price' => $item['price'],
+ 'price' => number_format($price, $precision),
+ 'price_without_tax' => number_format($priceWithoutTax, $precision),
+ 'tax_amount' => number_format($taxAmount, $precision),
+ 'tax_perc' => $taxPerc,
+ 'tax_name' => $globalParameters['tax_name'],
+ 'tax_enable' => $taxEnable &&
+ ($taxAppliesTo == self::TAX_APPLIES_TO_ALL || $taxAppliesTo == self::TAX_APPLIES_TO_ONLY_COURSE),
'currency' => $item['iso_code'],
'course_img' => null,
];
@@ -658,13 +832,36 @@ class BuyCoursesPlugin extends Plugin
'coach_access_end_date' => $session->getCoachAccessEndDate(),
]);
+ $price = $item['price'];
+ $taxPerc = null;
+ $priceWithoutTax = $item['price'];
+ $precision = 2;
+
+ $taxEnable = $this->get('tax_enable') === 'true';
+ $globalParameters = $this->getGlobalParameters();
+ $taxAppliesTo = $globalParameters['tax_applies_to'];
+ if ($taxEnable &&
+ ($taxAppliesTo == self::TAX_APPLIES_TO_ALL || $taxAppliesTo == self::TAX_APPLIES_TO_ONLY_SESSION)
+ ) {
+ $globalTaxPerc = $globalParameters['global_tax_perc'];
+ $taxPerc = is_null($item['tax_perc']) ? $globalTaxPerc : $item['tax_perc'];
+ $taxAmount = round($priceWithoutTax * $taxPerc / 100, $precision);
+ $price = $priceWithoutTax + $taxAmount;
+ }
+
$sessionInfo = [
'id' => $session->getId(),
'name' => $session->getName(),
'description' => $session->getDescription(),
'dates' => $sessionDates,
'courses' => [],
- 'price' => $item['price'],
+ 'price' => number_format($price, $precision),
+ 'price_without_tax' => number_format($priceWithoutTax, $precision),
+ 'tax_amount' => number_format($taxAmount, $precision),
+ 'tax_perc' => $taxPerc,
+ 'tax_name' => $globalParameters['tax_name'],
+ 'tax_enable' => $taxEnable &&
+ ($taxAppliesTo == self::TAX_APPLIES_TO_ALL || $taxAppliesTo == self::TAX_APPLIES_TO_ONLY_SESSION),
'currency' => $item['iso_code'],
'image' => null,
'nbrCourses' => $session->getNbrCourses(),
@@ -722,7 +919,7 @@ class BuyCoursesPlugin extends Plugin
'*',
Database::get_main_table(self::TABLE_ITEM),
[
- 'where' => ['id = ?' => intval($itemId)],
+ 'where' => ['id = ?' => (int) $itemId],
],
'first'
);
@@ -771,6 +968,26 @@ class BuyCoursesPlugin extends Plugin
$productName = $session->getName();
}
+ $price = $item['price'];
+ $priceWithoutTax = null;
+ $taxPerc = null;
+
+ $taxEnable = $this->get('tax_enable') === 'true';
+ $globalParameters = $this->getGlobalParameters();
+ $taxAppliesTo = $globalParameters['tax_applies_to'];
+ if ($taxEnable &&
+ ($taxAppliesTo == self::TAX_APPLIES_TO_ALL ||
+ ($taxAppliesTo == TAX_APPLIES_TO_ONLY_COURSE && $item['product_type'] == self::PRODUCT_TYPE_COURSE) ||
+ ($taxAppliesTo == TAX_APPLIES_TO_ONLY_SESSION && $item['product_type'] == self::PRODUCT_TYPE_SESSION))
+ ) {
+ $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);
+ $price = $priceWithoutTax + $taxAmount;
+ }
+
$values = [
'reference' => $this->generateReference(
api_get_user_id(),
@@ -783,9 +1000,12 @@ class BuyCoursesPlugin extends Plugin
'product_type' => $item['product_type'],
'product_name' => $productName,
'product_id' => $item['product_id'],
- 'price' => $item['price'],
+ 'price' => $price,
+ 'price_without_tax' => $priceWithoutTax,
+ 'tax_perc' => $taxPerc,
+ 'tax_amount' => $taxAmount,
'status' => self::SALE_STATUS_PENDING,
- 'payment_type' => intval($paymentType),
+ 'payment_type' => (int) $paymentType,
];
return Database::insert(self::TABLE_SALE, $values);
@@ -804,7 +1024,7 @@ class BuyCoursesPlugin extends Plugin
'*',
Database::get_main_table(self::TABLE_SALE),
[
- 'where' => ['id = ?' => intval($saleId)],
+ 'where' => ['id = ?' => (int) $saleId],
],
'first'
);
@@ -834,7 +1054,7 @@ class BuyCoursesPlugin extends Plugin
[
'where' => [
's.payment_type = ? AND s.status = ?' => [
- intval($paymentType),
+ (int) $paymentType,
self::SALE_STATUS_COMPLETED,
],
],
@@ -843,6 +1063,87 @@ class BuyCoursesPlugin extends Plugin
);
}
+ /**
+ * Get data of sales.
+ *
+ * @param int $saleId The sale id
+ * @param int $isService Check if a service
+ *
+ * @return array The sale data
+ */
+ public function getDataSaleInvoice($saleId, $isService)
+ {
+ $data = [];
+ if ($isService) {
+ $sale = $this->getServiceSale($saleId);
+ $data['reference'] = $sale['reference'];
+ $data['product_name'] = $sale['service']['name'];
+ $data['payment_type'] = $sale['payment_type'];
+ $data['user_id'] = $sale['buyer']['id'];
+ $data['price'] = $sale['price'];
+ $data['price_without_tax'] = $sale['price_without_tax'];
+ $data['tax_perc'] = $sale['tax_perc'];
+ $data['tax_amount'] = $sale['tax_amount'];
+ $data['currency_id'] = $sale['currency_id'];
+ $data['date'] = $sale['buy_date'];
+ } else {
+ $sale = $this->getSale($saleId);
+ $data['reference'] = $sale['reference'];
+ $data['product_name'] = $sale['product_name'];
+ $data['payment_type'] = $sale['payment_type'];
+ $data['user_id'] = $sale['user_id'];
+ $data['price'] = $sale['price'];
+ $data['price_without_tax'] = $sale['price_without_tax'];
+ $data['tax_perc'] = $sale['tax_perc'];
+ $data['tax_amount'] = $sale['tax_amount'];
+ $data['currency_id'] = $sale['currency_id'];
+ $data['date'] = $sale['date'];
+ }
+
+ return $data;
+ }
+
+ /**
+ * Get data of invoice.
+ *
+ * @param int $saleId The sale id
+ * @param int $isService Check if a service
+ *
+ * @return array The invoice data
+ */
+ public function getDataInvoice($saleId, $isService)
+ {
+ return Database::select(
+ '*',
+ Database::get_main_table(self::TABLE_INVOICE),
+ [
+ 'where' => [
+ 'sale_id = ? AND ' => (int) $saleId,
+ 'is_service = ?' => (int) $isService,
+ ],
+ ],
+ 'first'
+ );
+ }
+
+ /**
+ * Get invoice numbering
+ *
+ * @param int $saleId The sale id
+ * @param int $isService Check if a service
+ *
+ * @return array The invoice numbers
+ */
+ public function getNumInvoice($saleId, $isService)
+ {
+ $dataInvoice = $this->getDataInvoice($saleId, $isService);
+ if (empty($dataInvoice)) {
+ return '-';
+ }
+
+ return $dataInvoice['serie'].$dataInvoice['year'].'/'.$dataInvoice['num_invoice'];
+ }
+
/**
* Get currency data by ID.
*
@@ -856,7 +1157,7 @@ class BuyCoursesPlugin extends Plugin
'*',
Database::get_main_table(self::TABLE_CURRENCY),
[
- 'where' => ['id = ?' => intval($currencyId)],
+ 'where' => ['id = ?' => (int) $currencyId],
],
'first'
);
@@ -897,6 +1198,9 @@ class BuyCoursesPlugin extends Plugin
if ($saleIsCompleted) {
$this->updateSaleStatus($sale['id'], self::SALE_STATUS_COMPLETED);
+ if ($this->get('invoicing_enable') === 'true') {
+ $this->setInvoice($sale['id']);
+ }
}
return $saleIsCompleted;
@@ -926,6 +1230,82 @@ class BuyCoursesPlugin extends Plugin
];
}
+ /**
+ * Register a invoice.
+ *
+ * @param int $saleId The sale ID
+ * @param int $isService The service type to filter (default : 0)
+ */
+ public function setInvoice($saleId, $isService = 0)
+ {
+ $invoiceTable = Database::get_main_table(self::TABLE_INVOICE);
+ $year = date('Y');
+
+ $globalParameters = $this->getGlobalParameters();
+ $numInvoice = $globalParameters['next_number_invoice'];
+ $serie = $globalParameters['invoice_series'];
+
+ if (empty($numInvoice)) {
+ $item = Database::select(
+ ['MAX(num_invoice) AS num_invoice'],
+ $invoiceTable,
+ [
+ 'where' => ['year = ?' => $year],
+ ],
+ 'first'
+ );
+
+ $numInvoice = 1;
+ if ($item !== false) {
+ $numInvoice = (int) ($item['num_invoice'] + 1);
+ }
+ } else {
+ Database::update(
+ Database::get_main_table(self::TABLE_GLOBAL_CONFIG),
+ ['next_number_invoice' => 0],
+ ['id = ?' => 1]
+ );
+ }
+
+ Database::insert(
+ $invoiceTable,
+ [
+ 'sale_id' => $saleId,
+ 'is_service' => $isService,
+ 'num_invoice' => $numInvoice,
+ 'year' => $year,
+ 'serie' => $serie,
+ 'date_invoice' => api_get_utc_datetime(),
+ ]
+ );
+
+ // Record invoice in the sales table
+ $table = Database::get_main_table(self::TABLE_SALE);
+ if (empty($isService)) {
+ $table = Database::get_main_table(self::TABLE_SERVICES_SALE);
+ }
+ Database::update(
+ $table,
+ ['invoice' => 1],
+ ['id = ?' => $saleId]
+ );
+ }
+
+ /**
+ * Get Tax's types.
+ *
+ * @return array
+ */
+ public function getTaxAppliesTo()
+ {
+ return [
+ self::TAX_APPLIES_TO_ALL => $this->get_lang('AllCoursesSessionsAndServices'),
+ self::TAX_APPLIES_TO_ONLY_COURSE => $this->get_lang('OnlyCourses'),
+ self::TAX_APPLIES_TO_ONLY_SESSION => $this->get_lang('OnlySessions'),
+ self::TAX_APPLIES_TO_ONLY_SERVICES => $this->get_lang('OnlyServices'),
+ ];
+ }
+
/**
* Get a list of sales by the status.
*
@@ -948,7 +1328,7 @@ class BuyCoursesPlugin extends Plugin
['c.iso_code', 'u.firstname', 'u.lastname', 's.*'],
"$saleTable s $innerJoins",
[
- 'where' => ['s.status = ?' => intval($status)],
+ 'where' => ['s.status = ?' => (int) $status],
'order' => 'id DESC',
]
);
@@ -1127,7 +1507,7 @@ class BuyCoursesPlugin extends Plugin
"$saleTable s $innerJoins",
[
'where' => [
- 'u.id = ? AND s.status = ?' => [intval($id), self::SALE_STATUS_COMPLETED],
+ 'u.id = ? AND s.status = ?' => [(int) $id, self::SALE_STATUS_COMPLETED],
],
'order' => 'id DESC',
]
@@ -1155,6 +1535,7 @@ class BuyCoursesPlugin extends Plugin
'visible' => false,
'currency' => empty($defaultCurrency) ? null : $defaultCurrency['iso_code'],
'price' => 0.00,
+ 'tax_perc' => null,
];
$item = $this->getItemByProduct($course->getId(), self::PRODUCT_TYPE_COURSE);
@@ -1164,6 +1545,7 @@ class BuyCoursesPlugin extends Plugin
$courseItem['visible'] = true;
$courseItem['currency'] = $item['iso_code'];
$courseItem['price'] = $item['price'];
+ $courseItem['tax_perc'] = $item['tax_perc'];
}
return $courseItem;
@@ -1197,6 +1579,7 @@ class BuyCoursesPlugin extends Plugin
'visible' => false,
'currency' => empty($defaultCurrency) ? null : $defaultCurrency['iso_code'],
'price' => 0.00,
+ 'tax_perc' => null,
];
$displayStartDate = $session->getDisplayStartDate();
@@ -1233,6 +1616,7 @@ class BuyCoursesPlugin extends Plugin
$sessionItem['visible'] = true;
$sessionItem['currency'] = $item['iso_code'];
$sessionItem['price'] = $item['price'];
+ $sessionItem['tax_perc'] = $item['tax_perc'];
}
return $sessionItem;
@@ -1254,7 +1638,7 @@ class BuyCoursesPlugin extends Plugin
$beneficiaryTable,
[
'where' => [
- 'item_id = ?' => intval($itemId),
+ 'item_id = ?' => (int) $itemId,
],
]
);
@@ -1272,7 +1656,7 @@ class BuyCoursesPlugin extends Plugin
$itemTable = Database::get_main_table(self::TABLE_ITEM);
$affectedRows = Database::delete(
$itemTable,
- ['id = ?' => intval($itemId)]
+ ['id = ?' => (int) $itemId]
);
if (!$affectedRows) {
@@ -1313,7 +1697,7 @@ class BuyCoursesPlugin extends Plugin
$itemTable,
$itemData,
[
- 'product_id = ? AND ' => intval($productId),
+ 'product_id = ? AND ' => (int) $productId,
'product_type' => $productType,
]
);
@@ -1332,7 +1716,7 @@ class BuyCoursesPlugin extends Plugin
return Database::delete(
$beneficiaryTable,
- ['item_id = ?' => intval($itemId)]
+ ['item_id = ?' => (int) $itemId]
);
}
@@ -1352,9 +1736,9 @@ class BuyCoursesPlugin extends Plugin
Database::insert(
$beneficiaryTable,
[
- 'item_id' => intval($itemId),
- 'user_id' => intval($userId),
- 'commissions' => intval($commissions),
+ 'item_id' => (int) $itemId,
+ 'user_id' => (int) $userId,
+ 'commissions' => (int) $commissions,
]
);
}
@@ -1410,8 +1794,8 @@ class BuyCoursesPlugin extends Plugin
$payoutId = false,
$userId = false
) {
- $condition = ($payoutId) ? 'AND p.id = '.intval($payoutId) : '';
- $condition2 = ($userId) ? ' AND p.user_id = '.intval($userId) : '';
+ $condition = ($payoutId) ? 'AND p.id = '.((int) $payoutId) : '';
+ $condition2 = ($userId) ? ' AND p.user_id = '.((int) $userId) : '';
$typeResult = ($condition) ? 'first' : 'all';
$payoutsTable = Database::get_main_table(self::TABLE_PAYPAL_PAYOUTS);
$saleTable = Database::get_main_table(self::TABLE_SALE);
@@ -1438,7 +1822,7 @@ class BuyCoursesPlugin extends Plugin
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 = ".intval($paypalExtraField['id'])."
+ AND field_id = ".((int) $paypalExtraField['id'])."
";
$payouts = Database::select(
@@ -1483,7 +1867,7 @@ class BuyCoursesPlugin extends Plugin
"value",
$extraFieldValues,
[
- 'where' => ['field_id = ? AND item_id = ?' => [intval($paypalFieldId), intval($userId)]],
+ 'where' => ['field_id = ? AND item_id = ?' => [(int) $paypalFieldId, (int) $userId]],
],
'first'
);
@@ -1512,22 +1896,24 @@ class BuyCoursesPlugin extends Plugin
$platformCommission = $this->getPlatformCommission();
$sale = $this->getSale($saleId);
+ $commission = (int) $platformCommission['commission'];
$teachersCommission = number_format(
- (floatval($sale['price']) * intval($platformCommission['commission'])) / 100,
+ (floatval($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' => getdate(),
- 'sale_id' => intval($saleId),
+ 'sale_id' => (int) $saleId,
'user_id' => $beneficiary['user_id'],
'commission' => number_format(
- (floatval($teachersCommission) * intval($beneficiary['commissions'])) / 100,
+ (floatval($teachersCommission) * $beneficiaryCommission) / 100,
2
),
'status' => self::PAYOUT_STATUS_PENDING,
@@ -1550,8 +1936,8 @@ class BuyCoursesPlugin extends Plugin
Database::update(
$payoutsTable,
- ['status' => intval($status)],
- ['id = ?' => intval($payoutId)]
+ ['status' => (int) $status],
+ ['id = ?' => (int) $payoutId]
);
}
@@ -1583,7 +1969,7 @@ class BuyCoursesPlugin extends Plugin
return Database::update(
$commissionTable,
- ['commission' => intval($params['commission'])]
+ ['commission' => (int) $params['commission']]
);
}
@@ -1604,10 +1990,11 @@ class BuyCoursesPlugin extends Plugin
'name' => Security::remove_XSS($service['name']),
'description' => Security::remove_XSS($service['description']),
'price' => $service['price'],
- 'duration_days' => intval($service['duration_days']),
- 'applies_to' => intval($service['applies_to']),
- 'owner_id' => intval($service['owner_id']),
- 'visibility' => intval($service['visibility']),
+ 'tax_perc' => $service['tax_perc'] != '' ? (int) $service['tax_perc'] : null,
+ 'duration_days' => (int) $service['duration_days'],
+ 'applies_to' => (int) $service['applies_to'],
+ 'owner_id' => (int) $service['owner_id'],
+ 'visibility' => (int) $service['visibility'],
'image' => '',
'video_url' => $service['video_url'],
'service_information' => $service['service_information'],
@@ -1626,7 +2013,7 @@ class BuyCoursesPlugin extends Plugin
Database::update(
$servicesTable,
['image' => 'simg-'.$return.'.png'],
- ['id = ?' => intval($return)]
+ ['id = ?' => (int) $return]
);
}
@@ -1658,15 +2045,16 @@ class BuyCoursesPlugin extends Plugin
'name' => Security::remove_XSS($service['name']),
'description' => Security::remove_XSS($service['description']),
'price' => $service['price'],
- 'duration_days' => intval($service['duration_days']),
- 'applies_to' => intval($service['applies_to']),
- 'owner_id' => intval($service['owner_id']),
- 'visibility' => intval($service['visibility']),
+ 'tax_perc' => $service['tax_perc'] != '' ? (int) $service['tax_perc'] : null,
+ 'duration_days' => (int) $service['duration_days'],
+ 'applies_to' => (int) $service['applies_to'],
+ 'owner_id' => (int) $service['owner_id'],
+ 'visibility' => (int) $service['visibility'],
'image' => 'simg-'.$id.'.png',
'video_url' => $service['video_url'],
'service_information' => $service['service_information'],
],
- ['id = ?' => intval($id)]
+ ['id = ?' => (int) $id]
);
}
@@ -1681,12 +2069,12 @@ class BuyCoursesPlugin extends Plugin
{
Database::delete(
Database::get_main_table(self::TABLE_SERVICES_SALE),
- ['service_id = ?' => intval($id)]
+ ['service_id = ?' => (int) $id]
);
return Database::delete(
Database::get_main_table(self::TABLE_SERVICES),
- ['id = ?' => intval($id)]
+ ['id = ?' => (int) $id]
);
}
@@ -1723,10 +2111,36 @@ class BuyCoursesPlugin extends Plugin
$services = [];
if ($id) {
+ $price = $return['price'];
+ $taxPerc = null;
+ $priceWithoutTax = $priceWithTax = $return['price'];
+ $precision = 2;
+
+ $taxEnable = $this->get('tax_enable') === 'true';
+ $globalParameters = $this->getGlobalParameters();
+ $taxAppliesTo = $globalParameters['tax_applies_to'];
+ if ($taxEnable &&
+ ($taxAppliesTo == self::TAX_APPLIES_TO_ALL || $taxAppliesTo == self::TAX_APPLIES_TO_ONLY_SERVICES)
+ ) {
+ $globalTaxPerc = $globalParameters['global_tax_perc'];
+ $precision = 2;
+ $taxPerc = is_null($return['tax_perc']) ? $globalTaxPerc : $return['tax_perc'];
+ $taxAmount = round($priceWithoutTax * $taxPerc / 100, $precision);
+ $priceWithTax = $priceWithoutTax + $taxAmount;
+ }
+
$services['id'] = $return['id'];
$services['name'] = $return['name'];
$services['description'] = $return['description'];
- $services['price'] = $return['price'];
+ $services['price'] = $price;
+ $services['tax_perc'] = $return['tax_perc'];
+ $services['price_with_tax'] = number_format($priceWithTax, $precision);
+ $services['price_without_tax'] = number_format($priceWithoutTax, $precision);
+ $services['tax_amount'] = number_format($taxAmount, $precision);
+ $services['tax_perc_show'] = $taxPerc;
+ $services['tax_name'] = $globalParameters['tax_name'];
+ $services['tax_enable'] = $taxEnable &&
+ ($taxAppliesTo == self::TAX_APPLIES_TO_ALL || $taxAppliesTo == self::TAX_APPLIES_TO_ONLY_SERVICES);
$services['currency'] = $return['currency'];
$services['duration_days'] = $return['duration_days'];
$services['applies_to'] = $return['applies_to'];
@@ -1747,6 +2161,7 @@ class BuyCoursesPlugin extends Plugin
$services[$index]['name'] = $service['name'];
$services[$index]['description'] = $service['description'];
$services[$index]['price'] = $service['price'];
+ $services[$index]['tax_perc'] = $service['tax_perc'];
$services[$index]['currency'] = $service['currency'];
$services[$index]['duration_days'] = $service['duration_days'];
$services[$index]['applies_to'] = $service['applies_to'];
@@ -1818,7 +2233,7 @@ class BuyCoursesPlugin extends Plugin
$conditions = ['WHERE' => ['ss.buyer_id = ?' => $buyerId], 'ORDER' => 'id ASC'];
}
- if (is_numeric($status)) {
+ if (is_numeric($status) && empty($id)) {
$conditions = ['WHERE' => ['ss.status = ?' => $status], 'ORDER' => 'id ASC'];
}
@@ -1862,7 +2277,6 @@ class BuyCoursesPlugin extends Plugin
$conditions,
$showData
);
-
$servicesSale = [];
if ($id) {
@@ -1885,6 +2299,9 @@ class BuyCoursesPlugin extends Plugin
$servicesSale['currency_id'] = $return['currency_id'];
$servicesSale['currency'] = $return['currency'];
$servicesSale['price'] = $return['price'];
+ $servicesSale['price_without_tax'] = $return['price_without_tax'];
+ $servicesSale['tax_perc'] = $return['tax_perc'];
+ $servicesSale['tax_amount'] = $return['tax_amount'];
$servicesSale['node_type'] = $return['node_type'];
$servicesSale['node_id'] = $return['node_id'];
$servicesSale['buyer']['id'] = $buyer['user_id'];
@@ -1895,6 +2312,7 @@ class BuyCoursesPlugin extends Plugin
$servicesSale['date_end'] = $return['date_end'];
$servicesSale['status'] = $return['status'];
$servicesSale['payment_type'] = $return['payment_type'];
+ $servicesSale['invoice'] = $return['invoice'];
return $servicesSale;
}
@@ -1931,6 +2349,7 @@ class BuyCoursesPlugin extends Plugin
$servicesSale[$index]['date_end'] = $service['date_end'];
$servicesSale[$index]['status'] = $service['status'];
$servicesSale[$index]['payment_type'] = $service['payment_type'];
+ $servicesSale[$index]['invoice'] = $service['invoice'];
}
return $servicesSale;
@@ -1972,6 +2391,10 @@ class BuyCoursesPlugin extends Plugin
self::SERVICE_STATUS_COMPLETED
);
+ if ($this->get('invoicing_enable') === 'true') {
+ $this->setInvoice($serviceSaleId, 1);
+ }
+
return true;
}
@@ -2022,10 +2445,27 @@ class BuyCoursesPlugin extends Plugin
$services = [];
foreach ($return as $index => $service) {
+ $price = $service['price'];
+ $taxPerc = null;
+ $priceWithoutTax = $service['price'];
+
+ $taxEnable = $this->get('tax_enable') === 'true';
+ $globalParameters = $this->getGlobalParameters();
+ $taxAppliesTo = $globalParameters['tax_applies_to'];
+ if ($taxEnable &&
+ ($taxAppliesTo == self::TAX_APPLIES_TO_ALL || $taxAppliesTo == self::TAX_APPLIES_TO_ONLY_SERVICES)
+ ) {
+ $globalTaxPerc = $globalParameters['global_tax_perc'];
+ $precision = 2;
+ $taxPerc = is_null($service['tax_perc']) ? $globalTaxPerc : $service['tax_perc'];
+ $taxAmount = round($priceWithoutTax * $taxPerc / 100, $precision);
+ $price = $priceWithoutTax + $taxAmount;
+ }
+
$services[$index]['id'] = $service['id'];
$services[$index]['name'] = $service['name'];
$services[$index]['description'] = $service['description'];
- $services[$index]['price'] = $service['price'];
+ $services[$index]['price'] = number_format($price, $precision);
$services[$index]['currency'] = $service['currency'];
$services[$index]['duration_days'] = $service['duration_days'];
$services[$index]['applies_to'] = $service['applies_to'];
@@ -2070,6 +2510,23 @@ class BuyCoursesPlugin extends Plugin
}
$currency = $this->getSelectedCurrency();
+ $price = $service['price'];
+ $priceWithoutTax = null;
+ $taxPerc = null;
+
+ $taxEnable = $this->get('tax_enable') === 'true';
+ $globalParameters = $this->getGlobalParameters();
+ $taxAppliesTo = $globalParameters['tax_applies_to'];
+ if ($taxEnable &&
+ ($taxAppliesTo == self::TAX_APPLIES_TO_ALL || $taxAppliesTo == TAX_APPLIES_TO_ONLY_SERVICES)
+ ) {
+ $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);
+ $price = $priceWithoutTax + $taxAmount;
+ }
$values = [
'service_id' => $serviceId,
@@ -2079,9 +2536,12 @@ class BuyCoursesPlugin extends Plugin
$infoSelect
),
'currency_id' => $currency['id'],
- 'price' => $service['price'],
+ 'price' => $price,
+ 'price_without_tax' => $priceWithoutTax,
+ 'tax_perc' => $taxPerc,
+ 'tax_amount' => $taxAmount,
'node_type' => $service['applies_to'],
- 'node_id' => intval($infoSelect),
+ 'node_id' => (int) $infoSelect,
'buyer_id' => $userId,
'buy_date' => api_get_utc_datetime(),
'date_start' => api_get_utc_datetime(),
@@ -2093,7 +2553,7 @@ class BuyCoursesPlugin extends Plugin
'Y-m-d H:i:s'
),
'status' => self::SERVICE_STATUS_PENDING,
- 'payment_type' => intval($paymentType),
+ 'payment_type' => (int) $paymentType,
];
$returnedServiceSaleId = Database::insert(self::TABLE_SERVICES_SALE, $values);
@@ -2145,11 +2605,29 @@ class BuyCoursesPlugin extends Plugin
*/
public function saveGlobalParameters($params)
{
+ $sqlParams = [
+ 'terms_and_conditions' => $params['terms_and_conditions'],
+ 'sale_email' => $params['sale_email'],
+ ];
+
+ if ($this->get('tax_enable') === 'true') {
+ $sqlParams['global_tax_perc'] = $params['global_tax_perc'];
+ $sqlParams['tax_applies_to'] = $params['tax_applies_to'];
+ $sqlParams['tax_name'] = $params['tax_name'];
+ }
+
+ if ($this->get('invoicing_enable') === 'true') {
+ $sqlParams['seller_name'] = $params['seller_name'];
+ $sqlParams['seller_id'] = $params['seller_id'];
+ $sqlParams['seller_address'] = $params['seller_address'];
+ $sqlParams['seller_email'] = $params['seller_email'];
+ $sqlParams['next_number_invoice'] = $params['next_number_invoice'];
+ $sqlParams['invoice_series'] = $params['invoice_series'];
+ }
+
return Database::update(
Database::get_main_table(self::TABLE_GLOBAL_CONFIG),
- [
- 'terms_and_conditions' => $params['terms_and_conditions'],
- ],
+ $sqlParams,
['id = ?' => 1]
);
}
@@ -2422,8 +2900,8 @@ class BuyCoursesPlugin extends Plugin
return Database::update(
$saleTable,
- ['status' => intval($newStatus)],
- ['id = ?' => intval($saleId)]
+ ['status' => (int) $newStatus],
+ ['id = ?' => (int) $saleId]
);
}
diff --git a/plugin/buycourses/src/buycourses.ajax.php b/plugin/buycourses/src/buycourses.ajax.php
index 02529ecc97..4efc20bcee 100644
--- a/plugin/buycourses/src/buycourses.ajax.php
+++ b/plugin/buycourses/src/buycourses.ajax.php
@@ -235,6 +235,9 @@ switch ($action) {
$payout['id'],
BuyCoursesPlugin::PAYOUT_STATUS_COMPLETED
);
+ if ($plugin->get('invoicing_enable') === 'true') {
+ $plugin->setInvoice($payout['id']);
+ }
}
echo Display::return_message(
diff --git a/plugin/buycourses/src/configuration.php b/plugin/buycourses/src/configuration.php
index 317b2ed964..65882893eb 100644
--- a/plugin/buycourses/src/configuration.php
+++ b/plugin/buycourses/src/configuration.php
@@ -12,6 +12,7 @@ require_once __DIR__.'/../../../main/inc/global.inc.php';
$plugin = BuyCoursesPlugin::create();
$includeSession = $plugin->get('include_sessions') === 'true';
$includeServices = $plugin->get('include_services') === 'true';
+$taxEnable = $plugin->get('tax_enable') === 'true';
api_protect_admin_script(true);
@@ -39,6 +40,7 @@ $tpl->assign('product_type_session', BuyCoursesPlugin::PRODUCT_TYPE_SESSION);
$tpl->assign('courses', $courses);
$tpl->assign('sessions_are_included', $includeSession);
$tpl->assign('services_are_included', $includeServices);
+$tpl->assign('tax_enable', $taxEnable);
if ($includeSession) {
$sessions = $plugin->getSessionsForConfiguration();
@@ -50,6 +52,13 @@ if ($includeServices) {
$tpl->assign('services', $services);
}
+if ($taxEnable) {
+ $globalParameters = $plugin->getGlobalParameters();
+ $tpl->assign('global_tax_perc', $globalParameters['global_tax_perc']);
+ $tpl->assign('tax_applies_to', $globalParameters['tax_applies_to']);
+ $tpl->assign('tax_name', $globalParameters['tax_name']);
+}
+
$content = $tpl->fetch('buycourses/view/configuration.tpl');
$tpl->assign('header', $templateName);
diff --git a/plugin/buycourses/src/configure_course.php b/plugin/buycourses/src/configure_course.php
index e9157ecfdb..1c5885b5ac 100644
--- a/plugin/buycourses/src/configure_course.php
+++ b/plugin/buycourses/src/configure_course.php
@@ -88,6 +88,7 @@ if ($editingCourse) {
'name' => $courseItem['course_title'],
'visible' => $courseItem['visible'],
'price' => $courseItem['price'],
+ 'tax_perc' => $courseItem['tax_perc'],
'beneficiaries' => $defaultBeneficiaries,
($commissionsEnable == "true") ? 'commissions' : '' => ($commissionsEnable == "true") ? $commissions : '',
];
@@ -154,6 +155,7 @@ if ($editingCourse) {
'name' => $sessionItem['session_name'],
'visible' => $sessionItem['visible'],
'price' => $sessionItem['price'],
+ 'tax_perc' => $sessionItem['tax_perc'],
'beneficiaries' => $defaultBeneficiaries,
($commissionsEnable == "true") ? 'commissions' : '' => ($commissionsEnable == "true") ? $commissions : '',
];
@@ -190,6 +192,8 @@ if ($commissionsEnable === 'true') {
";
}
+$globalSettingsParams = $plugin->getGlobalParameters();
+
$form = new FormValidator('beneficiaries');
$form->addText('product_type', $plugin->get_lang('ProductType'), false);
$form->addText('name', get_lang('Name'), false);
@@ -204,6 +208,12 @@ $form->addElement(
[$plugin->get_lang('Price'), null, $currencyIso],
['step' => 0.01]
);
+$form->addElement(
+ 'number',
+ 'tax_perc',
+ [$plugin->get_lang('TaxPerc'), $plugin->get_lang('TaxPercDescription'), '%'],
+ ['step' => 1, 'placeholder' => $globalSettingsParams['global_tax_perc'].'% '.$plugin->get_lang('ByDefault')]
+);
$beneficiariesSelect = $form->addSelect(
'beneficiaries',
$plugin->get_lang('Beneficiaries'),
@@ -252,9 +262,13 @@ if ($form->validate()) {
$productItem = $plugin->getItemByProduct($formValues['i'], $formValues['t']);
if (isset($formValues['visible'])) {
+ $taxPerc = $formValues['tax_perc'] != '' ? (int) $formValues['tax_perc'] : null;
if (!empty($productItem)) {
$plugin->updateItem(
- ['price' => floatval($formValues['price'])],
+ [
+ 'price' => floatval($formValues['price']),
+ 'tax_perc' => $taxPerc,
+ ],
$formValues['i'],
$formValues['t']
);
@@ -264,6 +278,7 @@ if ($form->validate()) {
'product_type' => $formValues['t'],
'product_id' => intval($formValues['i']),
'price' => floatval($_POST['price']),
+ 'tax_perc' => $taxPerc,
]);
$productItem['id'] = $itemId;
}
diff --git a/plugin/buycourses/src/invoice.php b/plugin/buycourses/src/invoice.php
new file mode 100644
index 0000000000..de004e521a
--- /dev/null
+++ b/plugin/buycourses/src/invoice.php
@@ -0,0 +1,122 @@
+get('invoicing_enable') === 'true';
+if (!$invoicingEnable) {
+ api_not_allowed(true, $plugin->get_lang('NoInvoiceEnable'));
+}
+
+$saleId = isset($_GET['invoice']) ? (int) $_GET['invoice'] : 0;
+$isService = isset($_GET['is_service']) ? (int) $_GET['is_service'] : 0;
+
+$globalParameters = $plugin->getGlobalParameters();
+$infoSale = $plugin->getDataSaleInvoice($saleId, $isService);
+$buyer = api_get_user_info($infoSale['user_id']);
+$extraUserInfoData = UserManager::get_extra_user_data($infoSale['user_id']);
+$infoInvoice = $plugin->getDataInvoice($saleId, $isService);
+
+$htmlText = '';
+$htmlText .= '';
+$htmlText .= '';
+$htmlText .= '
| ';
+$htmlText .= ''.$globalParameters['seller_name'].' '; +$htmlText .= $globalParameters['seller_id'].' '; +$htmlText .= $globalParameters['seller_address'].' '; +$htmlText .= $globalParameters['seller_email'].' '; +$htmlText .= ' | ';
+$htmlText .= '';
+$htmlText .= ''.$buyer['complete_name'].' '; +$htmlText .= ($extraUserInfoData['buycourses_company'] ? $extraUserInfoData['buycourses_company'].' ' : ''); +$htmlText .= ($extraUserInfoData['buycourses_vat'] ? $extraUserInfoData['buycourses_vat'].' ' : ''); +$htmlText .= ($extraUserInfoData['buycourses_address'] ? $extraUserInfoData['buycourses_address'].' ' : ''); +$htmlText .= ($buyer['phone'] ? $buyer['phone'].' ' : ''); +$htmlText .= ($buyer['email'] ? $buyer['email'].' ' : ''); +$htmlText .= ' | ';
+$htmlText .= '
';
+$htmlText .= $plugin->get_lang('InvoiceDate').': '.api_format_date($infoInvoice['date_invoice'], DATE_TIME_FORMAT_LONG_24H).'
';
+$htmlText .= $plugin->get_lang('InvoiceNumber').': '.$infoInvoice['serie'].$infoInvoice['year'].'/'.$infoInvoice['num_invoice'].'
';
+$htmlText .= '