Merge branch 'develop' into patch-8
This commit is contained in:
commit
0d59ac34d2
32
README.md
32
README.md
@ -3,13 +3,13 @@
|
||||

|
||||

|
||||
|
||||
Dolibarr ERP & CRM is a modern software package to manage your organization's activity (contacts, suppliers, invoices, orders, stocks, agenda…).
|
||||
Dolibarr ERP & CRM is a modern software package that helps manage your organization's activity (contacts, suppliers, invoices, orders, stocks, agenda…).
|
||||
|
||||
It's an Open Source Software (written in PHP with optional JavaScript enhancements) designed for small, medium or large companies, foundations and freelancers.
|
||||
It's an Open Source Software suite (written in PHP with optional JavaScript enhancements) designed for small, medium or large companies, foundations and freelancers.
|
||||
|
||||
You can freely use, study, modify or distribute it according to its Free Software licence.
|
||||
You can freely use, study, modify or distribute it according to its licence.
|
||||
|
||||
You can use it as a standalone application or as a web application to be able to access it from the Internet or a LAN.
|
||||
You can use it as a standalone application or as a web application to access it from the Internet or a LAN.
|
||||
|
||||

|
||||
|
||||
@ -35,11 +35,15 @@ Releases can be downloaded from [official website](https://www.dolibarr.org/).
|
||||
|
||||
### Advanced setup
|
||||
|
||||
You can use a Web server and a supported database (MariaDB, MySQL or PostgreSQL) to install the standard version.
|
||||
You can use a web server and a supported database (MariaDB, MySQL or PostgreSQL) to install the standard version.
|
||||
|
||||
On GNU/Linux, first check if your distribution has already packaged Dolibarr.
|
||||
|
||||
#### Generic install steps:
|
||||
|
||||
- Check that your installed PHP version is supported [see PHP support](https://wiki.dolibarr.org/index.php/Versions).
|
||||
|
||||
- Uncompress the downloaded .zip archive to copy the "dolibarr/htdocs" directory and all its files inside your web server root or get the files directly from GitHub (recommanded if you known git):
|
||||
- Uncompress the downloaded .zip archive to copy the "dolibarr/htdocs" directory and all its files inside your web server root or get the files directly from GitHub (recommanded if you know git as it makes it easier if you want to upgrade later):
|
||||
|
||||
`git clone https://github.com/dolibarr/dolibarr -b x.y` (where x.y is main version like 3.6, 9.0, ...)
|
||||
|
||||
@ -70,11 +74,11 @@ If you don't have time to install it yourself, you can try some commercial 'read
|
||||
|
||||
## UPGRADING
|
||||
|
||||
- At first make a backup of your Dolibarr files & than see https://wiki.dolibarr.org/index.php/Installation_-_Upgrade#Upgrade_Dolibarr
|
||||
- At first make a backup of your Dolibarr files & then read https://wiki.dolibarr.org/index.php/Installation_-_Upgrade#Upgrade_Dolibarr
|
||||
- Check that your installed PHP version is supported by the new version [see PHP support](./doc/phpmatrix.md).
|
||||
- Overwrite all old files from 'dolibarr' directory with files provided into the new version's package.
|
||||
- At first next access, Dolibarr will redirect your to the "install/" page to follow the upgrade process.
|
||||
If an `install.lock` file exists to lock any other upgrade process, the application will ask you to remove the file manually (you should find the `install.lock` file into the directory used to store generated and uploaded documents, in most cases, it is the directory called "*documents*").
|
||||
- At first next access, Dolibarr will redirect you to the "install/" page to follow the upgrade process.
|
||||
If an `install.lock` file exists to lock any other upgrade process, the application will ask you to remove the file manually (you should find the `install.lock` file in the directory used to store generated and uploaded documents, in most cases, it is the directory called "*documents*").
|
||||
|
||||
*Note: migration process can be safely done multiple times by calling the `/install/index.php` page*
|
||||
|
||||
@ -139,7 +143,7 @@ See the [ChangeLog](https://github.com/Dolibarr/dolibarr/blob/develop/ChangeLog)
|
||||
- Highly customizable: enable only the modules you need, add user personalized fields, choose your skin, several menu managers (can be used by internal users as a back-office with a particular menu, or by external users as a front-office with another one)
|
||||
|
||||
- APIs
|
||||
- An easy to understand, maintain and develop code (PHP with no heavy framework; trigger and hook architecture)
|
||||
- Code that is easy to understand, maintain and develop (PHP with no heavy framework; trigger and hook architecture)
|
||||
- Support a lot of country specific features:
|
||||
- Spanish Tax RE and ISPF
|
||||
- French NPR VAT rate (VAT called "Non Perçue Récupérable" for DOM-TOM)
|
||||
@ -149,7 +153,7 @@ See the [ChangeLog](https://github.com/Dolibarr/dolibarr/blob/develop/ChangeLog)
|
||||
- Compatible with [European directives](http://europa.eu/legislation_summaries/taxation/l31057_en.htm) (2006/112/CE ... 2010/45/UE)
|
||||
- Compatible with European GDPR rules
|
||||
- ...
|
||||
- PDF or ODT generation for invoice, proposals, orders...
|
||||
- Flexible PDF & ODT generation for invoices, proposals, orders...
|
||||
- …
|
||||
|
||||
### System Environment / Requirements
|
||||
@ -167,12 +171,12 @@ These are features that Dolibarr does **not** yet fully support:
|
||||
|
||||
- Tasks dependencies in projects
|
||||
- Payroll module
|
||||
- No native embedded Webmail
|
||||
- No native embedded Webmail, but you can send email to contacts in Dolibarr with e.g. offers, invoices, etc.
|
||||
- Dolibarr can't do coffee (yet)
|
||||
|
||||
## DOCUMENTATION
|
||||
|
||||
Administrator, user, developer and translator's documentations are available along with other community resources on the [Wiki](https://wiki.dolibarr.org).
|
||||
Administrator, user, developer and translator's documentations are available along with other community resources in the [Wiki](https://wiki.dolibarr.org).
|
||||
|
||||
## CONTRIBUTING
|
||||
|
||||
@ -182,7 +186,7 @@ This project exists thanks to all the people who contribute. [[Contribute](https
|
||||
|
||||
## CREDITS
|
||||
|
||||
Dolibarr is the work of many contributors over the years and uses some fine libraries.
|
||||
Dolibarr is the work of many contributors over the years and uses some fine PHP libraries.
|
||||
|
||||
See [COPYRIGHT](https://github.com/Dolibarr/dolibarr/blob/develop/COPYRIGHT) file.
|
||||
|
||||
|
||||
@ -14,7 +14,7 @@ Architecture: all
|
||||
Depends: libapache2-mod-php5 | libapache2-mod-php5filter | php5-cgi | php5-fpm | php5 | libapache2-mod-php | libapache2-mod-phpfilter | php-cgi | php-fpm | php,
|
||||
php5-cli | php-cli,
|
||||
# Required PHP extensions
|
||||
php5-mysql | php5-mysqli | php-mysql | php-mysqli, php5-curl | php-curl, php5-gd | php-gd, php5-ldap | php-gd,
|
||||
php5-mysql | php5-mysqli | php-mysql | php-mysqli, php5-curl | php-curl, php5-gd | php-gd, php5-ldap | php-gd, php5-zip | php-zip,
|
||||
# Required PHP libraries
|
||||
php-pear, php-mail-mime,
|
||||
# php-tcpdf,
|
||||
|
||||
@ -79,6 +79,7 @@ $object = new Fiscalyear($db);
|
||||
$max = 100;
|
||||
|
||||
$form = new Form($db);
|
||||
$fiscalyearstatic = new Fiscalyear($db);
|
||||
|
||||
$title = $langs->trans('AccountingPeriods');
|
||||
$helpurl = "";
|
||||
@ -132,13 +133,15 @@ if ($result)
|
||||
print '</tr>';
|
||||
|
||||
if ($num) {
|
||||
$fiscalyearstatic = new Fiscalyear($db);
|
||||
|
||||
while ($i < $num && $i < $max) {
|
||||
$obj = $db->fetch_object($result);
|
||||
|
||||
$fiscalyearstatic->id = $obj->rowid;
|
||||
|
||||
print '<tr class="oddeven">';
|
||||
print '<td><a href="fiscalyear_card.php?id='.$obj->rowid.'">'.img_object($langs->trans("ShowFiscalYear"), "technic").' '.$obj->rowid.'</a></td>';
|
||||
print '<td>';
|
||||
print $fiscalyearstatic->getNomUrl(1);
|
||||
print '</td>';
|
||||
print '<td class="left">'.$obj->label.'</td>';
|
||||
print '<td class="left">'.dol_print_date($db->jdate($obj->date_start), 'day').'</td>';
|
||||
print '<td class="left">'.dol_print_date($db->jdate($obj->date_end), 'day').'</td>';
|
||||
|
||||
@ -38,7 +38,7 @@ require_once DOL_DOCUMENT_ROOT.'/admin/dolistore/class/dolistore.class.php';
|
||||
// Load translation files required by the page
|
||||
$langs->loadLangs(array("errors", "admin", "modulebuilder"));
|
||||
|
||||
$mode = GETPOSTISSET('mode') ? GETPOST('mode', 'alpha') : 'commonkanban';
|
||||
$mode = GETPOSTISSET('mode') ? GETPOST('mode', 'alpha') : (empty($conf->global->MAIN_MODULE_SETUP_ON_LIST_BY_DEFAULT) ? 'commonkanban' : 'common');
|
||||
if (empty($mode)) $mode = 'common';
|
||||
$action = GETPOST('action', 'alpha');
|
||||
//var_dump($_POST);exit;
|
||||
|
||||
@ -192,10 +192,10 @@ if (empty($reshook))
|
||||
$error = 0;
|
||||
|
||||
// Set if we used free entry or predefined product
|
||||
$qty = GETPOST('qty', 'int');
|
||||
$qty = price2num(GETPOST('qty', 'int'));
|
||||
$qty_frozen = GETPOST('qty_frozen', 'int');
|
||||
$disable_stock_change = GETPOST('disable_stock_change', 'int');
|
||||
$efficiency = GETPOST('efficiency', 'int');
|
||||
$efficiency = price2num(GETPOST('efficiency', 'int'));
|
||||
|
||||
if ($qty == '') {
|
||||
setEventMessages($langs->trans('ErrorFieldRequired', $langs->transnoentitiesnoconv('Qty')), null, 'errors');
|
||||
@ -219,6 +219,8 @@ if (empty($reshook))
|
||||
unset($_POST['qty']);
|
||||
unset($_POST['qty_frozen']);
|
||||
unset($_POST['disable_stock_change']);
|
||||
|
||||
$object->fetchLines();
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -541,7 +543,7 @@ if ($object->id > 0 && (empty($action) || ($action != 'edit' && $action != 'crea
|
||||
|
||||
if (!empty($object->table_element_line))
|
||||
{
|
||||
print ' <form name="addproduct" id="addproduct" action="'.$_SERVER["PHP_SELF"].'?id='.$object->id.(($action != 'editline') ? '#addline' : '#line_'.GETPOST('lineid', 'int')).'" method="POST">
|
||||
print ' <form name="addproduct" id="addproduct" action="'.$_SERVER["PHP_SELF"].'?id='.$object->id.(($action != 'editline') ? '#addline' : '').'" method="POST">
|
||||
<input type="hidden" name="token" value="' . newToken().'">
|
||||
<input type="hidden" name="action" value="' . (($action != 'editline') ? 'addline' : 'updateline').'">
|
||||
<input type="hidden" name="mode" value="">
|
||||
|
||||
@ -113,7 +113,7 @@ if ($conf->global->PRODUCT_USE_UNITS)
|
||||
{
|
||||
$coldisplay++;
|
||||
print '<td class="nobottom linecoluseunit left">';
|
||||
print $form->selectUnits($line->fk_unit, "units");
|
||||
print $form->selectUnits(empty($line->fk_unit) ? $conf->global->PRODUCT_USE_UNITS : $line->fk_unit, "units");
|
||||
print '</td>';
|
||||
}
|
||||
|
||||
|
||||
@ -5,7 +5,7 @@
|
||||
* Copyright (C) 2005 Marc Barilley / Ocebo <marc@ocebo.com>
|
||||
* Copyright (C) 2005-2015 Regis Houssin <regis.houssin@inodbox.com>
|
||||
* Copyright (C) 2006 Andre Cianfarani <acianfa@free.fr>
|
||||
* Copyright (C) 2010-2012 Juanjo Menent <jmenent@2byte.es>
|
||||
* Copyright (C) 2010-2020 Juanjo Menent <jmenent@2byte.es>
|
||||
* Copyright (C) 2012 Christophe Battarel <christophe.battarel@altairis.fr>
|
||||
* Copyright (C) 2013 Florian Henry <florian.henry@open-concept.pro>
|
||||
* Copyright (C) 2013 Cédric Salvador <csalvador@gpcsolutions.fr>
|
||||
@ -545,6 +545,8 @@ if (!$sall)
|
||||
$sql .= ' f.paye, f.fk_statut, f.close_code,';
|
||||
$sql .= ' f.datec, f.tms, f.date_closing,';
|
||||
$sql .= ' f.retained_warranty, f.retained_warranty_date_limit, f.situation_final, f.situation_cycle_ref, f.situation_counter,';
|
||||
$sql .= ' f.fk_user_author, f.fk_multicurrency, f.multicurrency_code, f.multicurrency_tx, f.multicurrency_total_ht, f.multicurrency_total_tva,';
|
||||
$sql .= ' f.multicurrency_total_tva, f.multicurrency_total_ttc,';
|
||||
$sql .= ' s.rowid, s.nom, s.email, s.town, s.zip, s.fk_pays, s.client, s.fournisseur, s.code_client, s.code_fournisseur, s.code_compta, s.code_compta_fournisseur,';
|
||||
$sql .= ' typent.code,';
|
||||
$sql .= ' state.code_departement, state.nom,';
|
||||
|
||||
@ -38,8 +38,6 @@ require_once DOL_DOCUMENT_ROOT.'/societe/class/companybankaccount.class.php';
|
||||
require_once DOL_DOCUMENT_ROOT.'/fourn/class/fournisseur.class.php';
|
||||
require_once DOL_DOCUMENT_ROOT.'/fourn/class/fournisseur.facture.class.php';
|
||||
|
||||
if (!$user->rights->facture->lire) accessforbidden();
|
||||
|
||||
// Load translation files required by the page
|
||||
$langs->loadLangs(array('bills', 'banks', 'withdrawals', 'companies'));
|
||||
|
||||
@ -51,7 +49,6 @@ $type = GETPOST('type', 'aZ09');
|
||||
|
||||
$fieldid = (!empty($ref) ? 'ref' : 'rowid');
|
||||
if ($user->socid) $socid = $user->socid;
|
||||
$result = restrictedArea($user, 'facture', $id, '', '', 'fk_soc', $fieldid);
|
||||
|
||||
if ($type == 'bank-transfer') {
|
||||
$object = new FactureFournisseur($db);
|
||||
@ -63,6 +60,7 @@ if ($type == 'bank-transfer') {
|
||||
if ($id > 0 || !empty($ref))
|
||||
{
|
||||
$ret = $object->fetch($id, $ref);
|
||||
$isdraft = (($object->statut == FactureFournisseur::STATUS_DRAFT) ? 1 : 0);
|
||||
if ($ret > 0)
|
||||
{
|
||||
$object->fetch_thirdparty();
|
||||
@ -71,6 +69,13 @@ if ($id > 0 || !empty($ref))
|
||||
|
||||
$hookmanager->initHooks(array('directdebitcard', 'globalcard'));
|
||||
|
||||
if ($type == 'bank-transfer') {
|
||||
$result = restrictedArea($user, 'fournisseur', $id, 'facture_fourn', 'facture', 'fk_soc', $fieldid, $isdraft);
|
||||
if (!$user->rights->fournisseur->facture->lire) accessforbidden();
|
||||
} else {
|
||||
$result = restrictedArea($user, 'facture', $id, '', '', 'fk_soc', $fieldid, $isdraft);
|
||||
if (!$user->rights->facture->lire) accessforbidden();
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
|
||||
@ -2,7 +2,7 @@
|
||||
/* Copyright (C) 2001-2005 Rodolphe Quiedeville <rodolphe@quiedeville.org>
|
||||
* Copyright (C) 2004-2013 Laurent Destailleur <eldy@users.sourceforge.net>
|
||||
* Copyright (C) 2005-2015 Regis Houssin <regis.houssin@inodbox.com>
|
||||
* Copyright (C) 2015-2016 Juanjo Menent <jmenent@2byte.es>
|
||||
* Copyright (C) 2015-2020 Juanjo Menent <jmenent@2byte.es>
|
||||
* Copyright (C) 2015 Jean-François Ferry <jfefe@aternatik.fr>
|
||||
* Copyright (C) 2015 Raphaël Doursenaud <rdoursenaud@gpcsolutions.fr>
|
||||
* Copyright (C) 2016 Marcos García <marcosgdf@gmail.com>
|
||||
@ -161,6 +161,14 @@ if (!empty($conf->facture->enabled) && $user->rights->facture->lire)
|
||||
$reshook = $hookmanager->executeHooks('printFieldListWhereCustomerDraft', $parameters);
|
||||
$sql .= $hookmanager->resPrint;
|
||||
|
||||
$sql.= " GROUP BY f.rowid, f.ref, f.datef, f.total, f.tva, f.total_ttc, f.ref_client, f.type, ";
|
||||
$sql.= "s.email, s.nom, s.rowid, s.code_client, s.code_compta, s.code_fournisseur, s.code_compta_fournisseur";
|
||||
|
||||
// Add Group from hooks
|
||||
$parameters = array();
|
||||
$reshook = $hookmanager->executeHooks('printFieldListGroupByCustomerDraft', $parameters);
|
||||
$sql .= $hookmanager->resPrint;
|
||||
|
||||
$resql = $db->query($sql);
|
||||
|
||||
if ($resql)
|
||||
@ -458,7 +466,7 @@ if ((!empty($conf->fournisseur->enabled) && empty($conf->global->MAIN_USE_NEW_SU
|
||||
$sql .= $hookmanager->resPrint;
|
||||
|
||||
$sql .= " GROUP BY ff.rowid, ff.ref, ff.fk_statut, ff.libelle, ff.total_ht, ff.tva, ff.total_tva, ff.total_ttc, ff.tms, ff.paye,";
|
||||
$sql .= " s.nom, s.rowid, s.code_fournisseur, s.code_compta_fournisseur";
|
||||
$sql .= " s.nom, s.rowid, s.code_fournisseur, s.code_compta_fournisseur, s.email";
|
||||
$sql .= " ORDER BY ff.tms DESC ";
|
||||
$sql .= $db->plimit($max, 0);
|
||||
|
||||
|
||||
@ -206,7 +206,13 @@ if (is_array($extrafields->attributes[$object->table_element]['label']) && count
|
||||
foreach ($extrafields->attributes[$object->table_element]['label'] as $key => $val)
|
||||
{
|
||||
if (!empty($extrafields->attributes[$object->table_element]['list'][$key]))
|
||||
$arrayfields["ef.".$key] = array('label'=>$extrafields->attributes[$object->table_element]['label'][$key], 'checked'=>(($extrafields->attributes[$object->table_element]['list'][$key] < 0) ? 0 : 1), 'position'=>$extrafields->attributes[$object->table_element]['pos'][$key], 'enabled'=>(abs($extrafields->attributes[$object->table_element]['list'][$key]) != 3 && $extrafields->attributes[$object->table_element]['perms'][$key]));
|
||||
$arrayfields["ef.".$key] = array(
|
||||
'label'=>$extrafields->attributes[$object->table_element]['label'][$key],
|
||||
'checked'=>(($extrafields->attributes[$object->table_element]['list'][$key] < 0) ? 0 : 1),
|
||||
'position'=>$extrafields->attributes[$object->table_element]['pos'][$key],
|
||||
'enabled'=>(abs($extrafields->attributes[$object->table_element]['list'][$key]) != 3 && $extrafields->attributes[$object->table_element]['perms'][$key]),
|
||||
'langfile'=>$extrafields->attributes[$object->table_element]['langfile'][$key],
|
||||
);
|
||||
}
|
||||
}
|
||||
$object->fields = dol_sort_array($object->fields, 'position');
|
||||
|
||||
@ -355,8 +355,8 @@ class CMailFile
|
||||
}
|
||||
|
||||
$smtps->setSubject($subjecttouse);
|
||||
$smtps->setTO($this->getValidAddress($this->to, 0, 1));
|
||||
$smtps->setFrom($this->getValidAddress($this->from, 0, 1));
|
||||
$smtps->setTO($this->getValidAddress($this->addr_to, 0, 1));
|
||||
$smtps->setFrom($this->getValidAddress($this->addr_from, 0, 1));
|
||||
$smtps->setTrackId($this->trackid);
|
||||
$smtps->setReplyTo($this->getValidAddress($this->replyto, 0, 1));
|
||||
|
||||
@ -402,7 +402,7 @@ class CMailFile
|
||||
$smtps->setDeliveryReceipt($this->deliveryreceipt);
|
||||
|
||||
$host = dol_getprefix('email');
|
||||
$this->msgid = time().'.SMTPs-dolibarr-'.$trackid.'@'.$host;
|
||||
$this->msgid = time().'.SMTPs-dolibarr-'.$this->trackid.'@'.$host;
|
||||
|
||||
$this->smtps = $smtps;
|
||||
} elseif ($this->sendmode == 'swiftmailer') {
|
||||
@ -786,14 +786,14 @@ class CMailFile
|
||||
$from = $this->smtps->getFrom('org');
|
||||
if ($res && !$from)
|
||||
{
|
||||
$this->error = "Failed to send mail with smtps lib to HOST=".$server.", PORT=".$conf->global->$keyforsmtpport."<br>Sender address '$from' invalid";
|
||||
$this->error = "Failed to send mail with smtps lib to HOST=".$server.", PORT=".$conf->global->$keyforsmtpport." - Sender address '$from' invalid";
|
||||
dol_syslog("CMailFile::sendfile: mail end error=".$this->error, LOG_ERR);
|
||||
$res = false;
|
||||
}
|
||||
$dest = $this->smtps->getTo();
|
||||
if ($res && !$dest)
|
||||
{
|
||||
$this->error = "Failed to send mail with smtps lib to HOST=".$server.", PORT=".$conf->global->$keyforsmtpport."<br>Recipient address '$dest' invalid";
|
||||
$this->error = "Failed to send mail with smtps lib to HOST=".$server.", PORT=".$conf->global->$keyforsmtpport." - Recipient address '$dest' invalid";
|
||||
dol_syslog("CMailFile::sendfile: mail end error=".$this->error, LOG_ERR);
|
||||
$res = false;
|
||||
}
|
||||
@ -814,7 +814,7 @@ class CMailFile
|
||||
$res = true;
|
||||
} else {
|
||||
if (empty($this->error)) $this->error = $result;
|
||||
dol_syslog("CMailFile::sendfile: mail end error with smtps lib to HOST=".$server.", PORT=".$conf->global->$keyforsmtpport."<br>".$this->error, LOG_ERR);
|
||||
dol_syslog("CMailFile::sendfile: mail end error with smtps lib to HOST=".$server.", PORT=".$conf->global->$keyforsmtpport." - ".$this->error, LOG_ERR);
|
||||
$res = false;
|
||||
}
|
||||
}
|
||||
|
||||
@ -35,6 +35,8 @@ class Fiscalyear extends CommonObject
|
||||
*/
|
||||
public $element = 'fiscalyear';
|
||||
|
||||
public $picto = 'technic';
|
||||
|
||||
/**
|
||||
* @var string Name of table without prefix where object is stored
|
||||
*/
|
||||
@ -97,6 +99,7 @@ class Fiscalyear extends CommonObject
|
||||
public $statuts = array();
|
||||
public $statuts_short = array();
|
||||
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
@ -267,6 +270,78 @@ class Fiscalyear extends CommonObject
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Return clicable link of object (with eventually picto)
|
||||
*
|
||||
* @param int $withpicto Add picto into link
|
||||
* @param int $notooltip 1=Disable tooltip
|
||||
* @param int $save_lastsearch_value -1=Auto, 0=No save of lastsearch_values when clicking, 1=Save lastsearch_values whenclicking
|
||||
* @return string String with URL
|
||||
*/
|
||||
public function getNomUrl($withpicto = 0, $notooltip = 0, $save_lastsearch_value = -1)
|
||||
{
|
||||
global $conf, $langs, $user;
|
||||
|
||||
if (empty($this->ref)) $this->ref = $this->id;
|
||||
|
||||
if (!empty($conf->dol_no_mouse_hover)) $notooltip = 1; // Force disable tooltips
|
||||
|
||||
$result = '';
|
||||
|
||||
$url = DOL_URL_ROOT.'/accountancy/admin/fiscalyear_card.php?id='.$this->id;
|
||||
|
||||
if (!$user->rights->accounting->fiscalyear->write)
|
||||
$option = 'nolink';
|
||||
|
||||
if ($option !== 'nolink')
|
||||
{
|
||||
// Add param to save lastsearch_values or not
|
||||
$add_save_lastsearch_values = ($save_lastsearch_value == 1 ? 1 : 0);
|
||||
if ($save_lastsearch_value == -1 && preg_match('/list\.php/', $_SERVER["PHP_SELF"])) $add_save_lastsearch_values = 1;
|
||||
if ($add_save_lastsearch_values) $url .= '&save_lastsearch_values=1';
|
||||
}
|
||||
|
||||
if ($short) return $url;
|
||||
|
||||
$label = '';
|
||||
|
||||
if ($user->rights->accounting->fiscalyear->write) {
|
||||
$label = '<u>'.$langs->trans("FiscalPeriod").'</u>';
|
||||
$label .= '<br><b>'.$langs->trans('Ref').':</b> '.$this->id;
|
||||
if (isset($this->statut)) {
|
||||
$label .= '<br><b>'.$langs->trans("Status").":</b> ".$this->getLibStatut(5);
|
||||
}
|
||||
}
|
||||
|
||||
$linkclose = '';
|
||||
if (empty($notooltip) && $user->rights->accounting->fiscalyear->write)
|
||||
{
|
||||
if (!empty($conf->global->MAIN_OPTIMIZEFORTEXTBROWSER))
|
||||
{
|
||||
$label = $langs->trans("FiscalYear");
|
||||
$linkclose .= ' alt="'.dol_escape_htmltag($label, 1).'"';
|
||||
}
|
||||
$linkclose .= ' title="'.dol_escape_htmltag($label, 1).'"';
|
||||
$linkclose .= ' class="classfortooltip"';
|
||||
}
|
||||
|
||||
$linkstart = '<a href="'.$url.'"';
|
||||
$linkstart .= $linkclose.'>';
|
||||
$linkend = '</a>';
|
||||
|
||||
if ($option === 'nolink') {
|
||||
$linkstart = '';
|
||||
$linkend = '';
|
||||
}
|
||||
|
||||
$result .= $linkstart;
|
||||
if ($withpicto) $result .= img_object(($notooltip ? '' : $label), $this->picto, ($notooltip ? (($withpicto != 2) ? 'class="paddingright"' : '') : 'class="'.(($withpicto != 2) ? 'paddingright ' : '').'classfortooltip"'), 0, 0, $notooltip ? 0 : 1);
|
||||
if ($withpicto != 2) $result .= $this->ref;
|
||||
$result .= $linkend;
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Give a label from a status
|
||||
*
|
||||
|
||||
@ -5830,7 +5830,7 @@ class Form
|
||||
$urlforajaxcall = DOL_URL_ROOT.'/core/ajax/selectobject.php';
|
||||
|
||||
// No immediate load of all database
|
||||
$urloption = 'htmlname='.$htmlname.'&outjson=1&objectdesc='.$objectdesc.'&filter='.urlencode($objecttmp->filter).($moreparams ? $moreparams : '');
|
||||
$urloption = 'htmlname='.$htmlname.'&outjson=1&objectdesc='.$objectdesc.'&filter='.urlencode($objecttmp->filter);
|
||||
// Activate the auto complete using ajax call.
|
||||
$out .= ajax_autocompleter($preselectedvalue, $htmlname, $urlforajaxcall, $urloption, $conf->global->$confkeyforautocompletemode, 0, array());
|
||||
$out .= '<style type="text/css">.ui-autocomplete { z-index: 250; }</style>';
|
||||
@ -6496,7 +6496,7 @@ class Form
|
||||
*/
|
||||
public static function multiSelectArrayWithCheckbox($htmlname, &$array, $varpage)
|
||||
{
|
||||
global $conf, $langs, $user;
|
||||
global $conf, $langs, $user, $extrafields;
|
||||
|
||||
if (!empty($conf->global->MAIN_OPTIMIZEFORTEXTBROWSER)) return '';
|
||||
|
||||
@ -6528,6 +6528,10 @@ class Form
|
||||
}
|
||||
if ($val['label'])
|
||||
{
|
||||
if (! empty($val['langfile']) && is_object($langs)) {
|
||||
$langs->load($val['langfile']);
|
||||
}
|
||||
|
||||
$lis .= '<li><input type="checkbox" id="checkbox'.$key.'" value="'.$key.'"'.(empty($val['checked']) ? '' : ' checked="checked"').'/><label for="checkbox'.$key.'">'.dol_escape_htmltag($langs->trans($val['label'])).'</label></li>';
|
||||
$listcheckedstring .= (empty($val['checked']) ? '' : $key.',');
|
||||
}
|
||||
|
||||
@ -25,25 +25,26 @@
|
||||
|
||||
|
||||
/**
|
||||
* Generic function that return javascript to add to a page to transform a common input field into an autocomplete field by calling an Ajax page (ex: /societe/ajaxcompanies.php).
|
||||
* The HTML field must be an input text with id=search_$htmlname.
|
||||
* This use the jQuery "autocomplete" function. If we want to use the select2, we must also convert the input into select on funcntions that call this method.
|
||||
* Generic function that return javascript to add to a page to transform a common input field into an autocomplete field by calling an Ajax page (ex: /societe/ajaxcompanies.php).
|
||||
* The HTML field must be an input text with id=search_$htmlname.
|
||||
* This use the jQuery "autocomplete" function. If we want to use the select2, we must also convert the input into select on funcntions that call this method.
|
||||
*
|
||||
* @param string $selected Preselected value
|
||||
* @param string $htmlname HTML name of input field
|
||||
* @param string $url Ajax Url to call for request: /path/page.php. Must return a json array ('key'=>id, 'value'=>String shown into input field once selected, 'label'=>String shown into combo list)
|
||||
* @param string $urloption More parameters on URL request
|
||||
* @param int $minLength Minimum number of chars to trigger that Ajax search
|
||||
* @param int $autoselect Automatic selection if just one value
|
||||
* @param array $ajaxoptions Multiple options array
|
||||
* @param string $selected Preselected value
|
||||
* @param string $htmlname HTML name of input field
|
||||
* @param string $url Ajax Url to call for request: /path/page.php. Must return a json array ('key'=>id, 'value'=>String shown into input field once selected, 'label'=>String shown into combo list)
|
||||
* @param string $urloption More parameters on URL request
|
||||
* @param int $minLength Minimum number of chars to trigger that Ajax search
|
||||
* @param int $autoselect Automatic selection if just one value
|
||||
* @param array $ajaxoptions Multiple options array
|
||||
* - Ex: array('update'=>array('field1','field2'...)) will reset field1 and field2 once select done
|
||||
* - Ex: array('disabled'=> )
|
||||
* - Ex: array('show'=> )
|
||||
* - Ex: array('update_textarea'=> )
|
||||
* - Ex: array('option_disabled'=> id to disable and warning to show if we select a disabled value (this is possible when using autocomplete ajax)
|
||||
* @return string Script
|
||||
* @param string $moreparams More params provided to ajax call
|
||||
* @return string Script
|
||||
*/
|
||||
function ajax_autocompleter($selected, $htmlname, $url, $urloption = '', $minLength = 2, $autoselect = 0, $ajaxoptions = array())
|
||||
function ajax_autocompleter($selected, $htmlname, $url, $urloption = '', $minLength = 2, $autoselect = 0, $ajaxoptions = array(), $moreparams = '')
|
||||
{
|
||||
if (empty($minLength)) $minLength = 1;
|
||||
|
||||
@ -55,7 +56,7 @@ function ajax_autocompleter($selected, $htmlname, $url, $urloption = '', $minLen
|
||||
|
||||
// Input search_htmlname is original field
|
||||
// Input htmlname is a second input field used when using ajax autocomplete.
|
||||
$script = '<input type="hidden" name="'.$htmlname.'" id="'.$htmlname.'" value="'.$selected.'" />';
|
||||
$script = '<input type="hidden" name="'.$htmlname.'" id="'.$htmlname.'" value="'.$selected.'" '.($moreparams ? $moreparams : '').' />';
|
||||
|
||||
$script .= '<!-- Javascript code for autocomplete of field '.$htmlname.' -->'."\n";
|
||||
$script .= '<script>'."\n";
|
||||
|
||||
@ -3850,7 +3850,7 @@ function dol_print_error($db = '', $error = '', $errors = null)
|
||||
{
|
||||
$out .= "<b>".$langs->trans("OS").":</b> ".php_uname()."<br>\n";
|
||||
}
|
||||
$out .= "<b>".$langs->trans("UserAgent").":</b> ".$_SERVER["HTTP_USER_AGENT"]."<br>\n";
|
||||
$out .= "<b>".$langs->trans("UserAgent").":</b> ".dol_htmlentities($_SERVER["HTTP_USER_AGENT"], ENT_COMPAT, 'UTF-8')."<br>\n";
|
||||
$out .= "<br>\n";
|
||||
$out .= "<b>".$langs->trans("RequestedUrl").":</b> ".dol_htmlentities($_SERVER["REQUEST_URI"], ENT_COMPAT, 'UTF-8')."<br>\n";
|
||||
$out .= "<b>".$langs->trans("Referer").":</b> ".(isset($_SERVER["HTTP_REFERER"]) ?dol_htmlentities($_SERVER["HTTP_REFERER"], ENT_COMPAT, 'UTF-8') : '')."<br>\n";
|
||||
@ -6071,6 +6071,7 @@ function getCommonSubstitutionArray($outputlangs, $onlykey = 0, $exclude = null,
|
||||
$substitutionarray['__MEMBER_PHONE__'] = $object->phone;
|
||||
$substitutionarray['__MEMBER_PHONEPRO__'] = $object->phone_perso;
|
||||
$substitutionarray['__MEMBER_PHONEMOBILE__'] = $object->phone_mobile;
|
||||
$substitutionarray['__MEMBER_TYPE__'] = $object->type;
|
||||
$substitutionarray['__MEMBER_FIRST_SUBSCRIPTION_DATE__'] = dol_print_date($object->first_subscription_date, 'dayrfc');
|
||||
$substitutionarray['__MEMBER_FIRST_SUBSCRIPTION_DATE_START__'] = dol_print_date($object->first_subscription_date_start, 'dayrfc');
|
||||
$substitutionarray['__MEMBER_FIRST_SUBSCRIPTION_DATE_END__'] = dol_print_date($object->first_subscription_date_end, 'dayrfc');
|
||||
|
||||
@ -48,13 +48,10 @@ function takepos_prepare_head()
|
||||
$head[$h][2] = 'receipt';
|
||||
$h++;
|
||||
|
||||
if ($conf->global->TAKEPOS_BAR_RESTAURANT)
|
||||
{
|
||||
$head[$h][0] = DOL_URL_ROOT.'/takepos/admin/bar.php';
|
||||
$head[$h][1] = $langs->trans("BarRestaurant");
|
||||
$head[$h][2] = 'bar';
|
||||
$h++;
|
||||
}
|
||||
$head[$h][0] = DOL_URL_ROOT.'/takepos/admin/bar.php';
|
||||
$head[$h][1] = $langs->trans("BarRestaurant");
|
||||
$head[$h][2] = 'bar';
|
||||
$h++;
|
||||
|
||||
$numterminals = max(1, $conf->global->TAKEPOS_NUM_TERMINALS);
|
||||
for ($i = 1; $i <= $numterminals; $i++)
|
||||
|
||||
@ -1740,7 +1740,7 @@ function print_left_eldy_menu($db, $menu_array_before, $menu_array_after, &$tabM
|
||||
if (empty($conf->global->PROJECT_HIDE_TASKS))
|
||||
{
|
||||
// Project affected to user
|
||||
$newmenu->add("/projet/activity/index.php?leftmenu=tasks".($search_project_user ? '&search_project_user='.$search_project_user : ''), $langs->trans("Activities"), 0, $user->rights->projet->lire);
|
||||
$newmenu->add("/projet/activity/index.php?leftmenu=tasks".($search_project_user ? '&search_project_user='.$search_project_user : ''), $langs->trans("Activities"), 0, $user->rights->projet->lire, '', 'project', 'tasks');
|
||||
$newmenu->add("/projet/tasks.php?leftmenu=tasks&action=create", $langs->trans("NewTask"), 1, $user->rights->projet->creer);
|
||||
$newmenu->add("/projet/tasks/list.php?leftmenu=tasks".($search_project_user ? '&search_project_user='.$search_project_user : ''), $langs->trans("List"), 1, $user->rights->projet->lire);
|
||||
$newmenu->add("/projet/tasks/stats/index.php?leftmenu=projects", $langs->trans("Statistics"), 1, $user->rights->projet->lire);
|
||||
|
||||
@ -40,7 +40,7 @@ $langs->load("modulebuilder");
|
||||
?>
|
||||
|
||||
<!-- BEGIN PHP TEMPLATE admin_extrafields_add.tpl.php -->
|
||||
<script type="text/javascript">
|
||||
<script>
|
||||
jQuery(document).ready(function() {
|
||||
function init_typeoffields(type)
|
||||
{
|
||||
|
||||
@ -39,7 +39,7 @@ $langs->load("modulebuilder");
|
||||
?>
|
||||
|
||||
<!-- BEGIN PHP TEMPLATE admin_extrafields_edit.tpl.php -->
|
||||
<script type="text/javascript">
|
||||
<script>
|
||||
jQuery(document).ready(function() {
|
||||
function init_typeoffields(type)
|
||||
{
|
||||
|
||||
@ -19,7 +19,7 @@ if (!empty($conf->categorie->enabled) && $user->rights->categorie->lire) {
|
||||
require_once DOL_DOCUMENT_ROOT.'/categories/class/categorie.class.php';
|
||||
}
|
||||
|
||||
print '<script type="text/javascript" language="javascript">
|
||||
print '<script>
|
||||
$(document).ready(function() {
|
||||
|
||||
// Click Function
|
||||
|
||||
@ -25,7 +25,7 @@ if (empty($conf) || !is_object($conf))
|
||||
?>
|
||||
|
||||
<!-- START TEMPLATE FILE UPLOAD MAIN -->
|
||||
<script type="text/javascript">
|
||||
<script>
|
||||
window.locale = {
|
||||
"fileupload": {
|
||||
"errors": {
|
||||
|
||||
@ -31,7 +31,7 @@ if ($object->element == 'propal')
|
||||
?>
|
||||
|
||||
<!-- START TEMPLATE IMPORT OBJECT LINKED LINES -->
|
||||
<script type="text/javascript">
|
||||
<script>
|
||||
|
||||
$(document).ready(function(){
|
||||
$('.objectlinked_importbtn').click(function (e) {
|
||||
|
||||
@ -32,7 +32,7 @@ if (isset($object->extraparams[$blocname]['showhide'])) $hide = (empty($object->
|
||||
<!-- BEGIN PHP TEMPLATE bloc_showhide.tpl.php -->
|
||||
|
||||
<?php
|
||||
print '<script type="text/javascript">'."\n";
|
||||
print '<script>'."\n";
|
||||
print '$(document).ready(function() {'."\n";
|
||||
print '$("#hide-'.$blocname.'").click(function(){'."\n";
|
||||
print ' setShowHide(0);'."\n";
|
||||
|
||||
@ -207,7 +207,7 @@ if (empty($reshook) && is_array($extrafields->attributes[$object->table_element]
|
||||
{
|
||||
print "\n";
|
||||
print '
|
||||
<script type="text/javascript">
|
||||
<script>
|
||||
jQuery(document).ready(function() {
|
||||
function showOptions(child_list, parent_list)
|
||||
{
|
||||
|
||||
@ -101,7 +101,7 @@ if ((!empty($conf->use_javascript_ajax) && empty($conf->global->MAIN_ECM_DISABLE
|
||||
if ((empty($section) || $section == -1) && ($module != 'medias'))
|
||||
{
|
||||
?>
|
||||
<script type="text/javascript">
|
||||
<script>
|
||||
jQuery(document).ready(function() {
|
||||
jQuery('#<?php echo $nameforformuserfile ?>').hide();
|
||||
});
|
||||
|
||||
@ -79,7 +79,7 @@ if (!empty($conf->global->ADD_UNSPLASH_LOGIN_BACKGROUND)) {
|
||||
?>
|
||||
|
||||
<?php if (empty($conf->dol_use_jmobile)) { ?>
|
||||
<script type="text/javascript">
|
||||
<script>
|
||||
$(document).ready(function () {
|
||||
/* Set focus on correct field */
|
||||
<?php if ($focus_element) { ?>$('#<?php echo $focus_element; ?>').focus(); <?php } ?> // Warning to use this only on visible element
|
||||
@ -356,23 +356,22 @@ if (!empty($conf->google->enabled) && !empty($conf->global->MAIN_GOOGLE_AN_ID))
|
||||
}
|
||||
}
|
||||
|
||||
// Google Adsense
|
||||
// TODO Replace this with a hook
|
||||
// Google Adsense (need Google module)
|
||||
if (!empty($conf->google->enabled) && !empty($conf->global->MAIN_GOOGLE_AD_CLIENT) && !empty($conf->global->MAIN_GOOGLE_AD_SLOT))
|
||||
{
|
||||
if (empty($conf->dol_use_jmobile))
|
||||
{
|
||||
?>
|
||||
<div class="center"><br>
|
||||
<script type="text/javascript"><!--
|
||||
<script><!--
|
||||
google_ad_client = "<?php echo $conf->global->MAIN_GOOGLE_AD_CLIENT ?>";
|
||||
google_ad_slot = "<?php echo $conf->global->MAIN_GOOGLE_AD_SLOT ?>";
|
||||
google_ad_width = <?php echo $conf->global->MAIN_GOOGLE_AD_WIDTH ?>;
|
||||
google_ad_height = <?php echo $conf->global->MAIN_GOOGLE_AD_HEIGHT ?>;
|
||||
//-->
|
||||
</script>
|
||||
<script type="text/javascript"
|
||||
src="http://pagead2.googlesyndication.com/pagead/show_ads.js">
|
||||
</script>
|
||||
<script src="//pagead2.googlesyndication.com/pagead/show_ads.js"></script>
|
||||
</div>
|
||||
<?php
|
||||
}
|
||||
|
||||
@ -224,7 +224,7 @@ if ($nolinesbefore) {
|
||||
if (!empty($conf->global->MAIN_AUTO_OPEN_SELECT2_ON_FOCUS_FOR_CUSTOMER_PRODUCTS))
|
||||
{
|
||||
?>
|
||||
<script type="text/javascript">
|
||||
<script>
|
||||
$(document).ready(function(){
|
||||
// On first focus on a select2 combo, auto open the menu (this allow to use the keyboard only)
|
||||
$(document).on('focus', '.select2-selection.select2-selection--single', function (e) {
|
||||
@ -259,7 +259,7 @@ if ($nolinesbefore) {
|
||||
if (!empty($conf->global->MAIN_AUTO_OPEN_SELECT2_ON_FOCUS_FOR_SUPPLIER_PRODUCTS))
|
||||
{
|
||||
?>
|
||||
<script type="text/javascript">
|
||||
<script>
|
||||
$(document).ready(function(){
|
||||
// On first focus on a select2 combo, auto open the menu (this allow to use the keyboard only)
|
||||
$(document).on('focus', '.select2-selection.select2-selection--single', function (e) {
|
||||
@ -362,7 +362,7 @@ if ($nolinesbefore) {
|
||||
if (!empty($conf->global->PRODUCT_USE_UNITS)) {
|
||||
$coldisplay++;
|
||||
print '<td class="nobottom linecoluseunit left">';
|
||||
print $form->selectUnits($line->fk_unit, "units");
|
||||
print $form->selectUnits(empty($line->fk_unit) ? $conf->global->PRODUCT_USE_UNITS : $line->fk_unit, "units");
|
||||
print '</td>';
|
||||
}
|
||||
$remise_percent = $buyer->remise_percent;
|
||||
@ -423,6 +423,27 @@ if ((!empty($conf->service->enabled) || ($object->element == 'contrat')) && $dat
|
||||
print '<td colspan="'.($coldisplay - (empty($conf->global->MAIN_VIEW_LINE_NUMBER) ? 0 : 1)).'">';
|
||||
$date_start = dol_mktime(GETPOST('date_starthour'), GETPOST('date_startmin'), 0, GETPOST('date_startmonth'), GETPOST('date_startday'), GETPOST('date_startyear'));
|
||||
$date_end = dol_mktime(GETPOST('date_starthour'), GETPOST('date_startmin'), 0, GETPOST('date_endmonth'), GETPOST('date_endday'), GETPOST('date_endyear'));
|
||||
|
||||
$prefillDates = false;
|
||||
|
||||
if (!empty($conf->global->MAIN_FILL_SERVICE_DATES_FROM_LAST_SERVICE_LINE) && ! empty($object->lines))
|
||||
{
|
||||
for ($i = count($object->lines) - 1; $i >= 0; $i--)
|
||||
{
|
||||
$lastline = $object->lines[$i];
|
||||
|
||||
if ($lastline->product_type == Product::TYPE_SERVICE && (! empty($lastline->date_start) || ! empty($lastline->date_end)))
|
||||
{
|
||||
$date_start_prefill = $lastline->date_start;
|
||||
$date_end_prefill = $lastline->date_end;
|
||||
|
||||
$prefillDates = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (!empty($object->element) && $object->element == 'contrat')
|
||||
{
|
||||
print $langs->trans("DateStartPlanned").' ';
|
||||
@ -435,7 +456,33 @@ if ((!empty($conf->service->enabled) || ($object->element == 'contrat')) && $dat
|
||||
print ' '.$langs->trans('to').' ';
|
||||
print $form->selectDate($date_end, 'date_end', empty($conf->global->MAIN_USE_HOURMIN_IN_DATE_RANGE) ? 0 : 1, empty($conf->global->MAIN_USE_HOURMIN_IN_DATE_RANGE) ? 0 : 1, 1, "addproduct", 1, 0);
|
||||
};
|
||||
|
||||
if ($prefillDates)
|
||||
{
|
||||
echo ' <span class="small"><a href="#" id="prefill_service_dates">' . $langs->trans('FillWithLastServiceDates') . '</a></span>';
|
||||
}
|
||||
|
||||
print '<script>';
|
||||
|
||||
if ($prefillDates)
|
||||
{
|
||||
?>
|
||||
function prefill_service_dates()
|
||||
{
|
||||
$('#date_start').val("<?php echo dol_escape_js(dol_print_date($date_start_prefill, '%d/%m/%Y')); ?>").trigger('change');
|
||||
$('#date_end').val("<?php echo dol_escape_js(dol_print_date($date_end_prefill, '%d/%m/%Y')); ?>").trigger('change');
|
||||
|
||||
return false; // Prevent default link behaviour (which is go to href URL)
|
||||
}
|
||||
|
||||
$(document).ready(function()
|
||||
{
|
||||
$('#prefill_service_dates').click(prefill_service_dates);
|
||||
});
|
||||
|
||||
<?php
|
||||
}
|
||||
|
||||
if (!$date_start) {
|
||||
if (isset($conf->global->MAIN_DEFAULT_DATE_START_HOUR)) {
|
||||
print 'jQuery("#date_starthour").val("'.$conf->global->MAIN_DEFAULT_DATE_START_HOUR.'");';
|
||||
|
||||
@ -272,7 +272,7 @@ if (!empty($extrafields))
|
||||
print $form->selectDate($line->date_start, 'date_start', $hourmin, $hourmin, $line->date_start ? 0 : 1, "updateline", 1, 0);
|
||||
print ' '.$langs->trans('to').' ';
|
||||
print $form->selectDate($line->date_end, 'date_end', $hourmin, $hourmin, $line->date_end ? 0 : 1, "updateline", 1, 0);
|
||||
print '<script type="text/javascript">';
|
||||
print '<script>';
|
||||
if (!$line->date_start) {
|
||||
if (isset($conf->global->MAIN_DEFAULT_DATE_START_HOUR)) {
|
||||
print 'jQuery("#date_starthour").val("'.$conf->global->MAIN_DEFAULT_DATE_START_HOUR.'");';
|
||||
@ -297,7 +297,7 @@ if (!empty($extrafields))
|
||||
?>
|
||||
|
||||
|
||||
<script type="text/javascript">
|
||||
<script>
|
||||
|
||||
jQuery(document).ready(function()
|
||||
{
|
||||
|
||||
@ -148,7 +148,7 @@ if (!empty($conf->don->enabled))
|
||||
|
||||
if (!empty($conf->use_javascript_ajax))
|
||||
{
|
||||
print "\n".'<script type="text/javascript">';
|
||||
print "\n".'<script>';
|
||||
print '$(document).ready(function () {
|
||||
$("#generate_token").click(function() {
|
||||
$.get( "'.DOL_URL_ROOT.'/core/ajax/security.php", {
|
||||
|
||||
@ -58,7 +58,7 @@ $colorbackhmenu1 = join(',', colorStringToArray($colorbackhmenu1)); // Normalize
|
||||
<body class="body bodylogin"<?php print empty($conf->global->MAIN_LOGIN_BACKGROUND) ? '' : ' style="background-size: cover; background-position: center center; background-attachment: fixed; background-repeat: no-repeat; background-image: url(\''.DOL_URL_ROOT.'/viewimage.php?cache=1&noalt=1&modulepart=mycompany&file='.urlencode('logos/'.$conf->global->MAIN_LOGIN_BACKGROUND).'\')"'; ?>>
|
||||
|
||||
<?php if (empty($conf->dol_use_jmobile)) { ?>
|
||||
<script type="text/javascript">
|
||||
<script>
|
||||
$(document).ready(function () {
|
||||
// Set focus on correct field
|
||||
<?php if ($focus_element) { ?>$('#<?php echo $focus_element; ?>').focus(); <?php } ?> // Warning to use this only on visible element
|
||||
@ -246,23 +246,22 @@ if (!empty($conf->google->enabled) && !empty($conf->global->MAIN_GOOGLE_AN_ID))
|
||||
}
|
||||
}
|
||||
|
||||
// Google Adsense
|
||||
// TODO Replace this with a hook
|
||||
// Google Adsense (need Google module)
|
||||
if (!empty($conf->google->enabled) && !empty($conf->global->MAIN_GOOGLE_AD_CLIENT) && !empty($conf->global->MAIN_GOOGLE_AD_SLOT))
|
||||
{
|
||||
if (empty($conf->dol_use_jmobile))
|
||||
{
|
||||
?>
|
||||
<div class="center"><br>
|
||||
<script type="text/javascript"><!--
|
||||
<script><!--
|
||||
google_ad_client = "<?php echo $conf->global->MAIN_GOOGLE_AD_CLIENT ?>";
|
||||
google_ad_slot = "<?php echo $conf->global->MAIN_GOOGLE_AD_SLOT ?>";
|
||||
google_ad_width = <?php echo $conf->global->MAIN_GOOGLE_AD_WIDTH ?>;
|
||||
google_ad_height = <?php echo $conf->global->MAIN_GOOGLE_AD_HEIGHT ?>;
|
||||
//-->
|
||||
</script>
|
||||
<script type="text/javascript"
|
||||
src="http://pagead2.googlesyndication.com/pagead/show_ads.js">
|
||||
</script>
|
||||
<script src="//pagead2.googlesyndication.com/pagead/show_ads.js"></script>
|
||||
</div>
|
||||
<?php
|
||||
}
|
||||
|
||||
@ -1299,7 +1299,7 @@ if ((empty($id) && empty($ref)) || $action == 'add' || $action == 'request' || $
|
||||
print '</tr>';
|
||||
}
|
||||
|
||||
// Validator
|
||||
// Approver
|
||||
if (!$edit && $action != 'editvalidator') {
|
||||
print '<tr>';
|
||||
print '<td class="titlefield">';
|
||||
@ -1310,7 +1310,7 @@ if ((empty($id) && empty($ref)) || $action == 'add' || $action == 'request' || $
|
||||
$include_users = $object->fetch_users_approver_holiday();
|
||||
if (is_array($include_users) && in_array($user->id, $include_users) && $object->statut == Holiday::STATUS_VALIDATED)
|
||||
{
|
||||
print '<a class="editfielda" href="'.$_SERVER["PHP_SELF"].'?id='.$object->id.'&action=editvalidator">'.img_edit($langs->trans("Edit")).'</a>';
|
||||
print '<a class="editfielda paddingleft" href="'.$_SERVER["PHP_SELF"].'?id='.$object->id.'&action=editvalidator">'.img_edit($langs->trans("Edit")).'</a>';
|
||||
}
|
||||
print '</td>';
|
||||
print '</tr>';
|
||||
|
||||
@ -175,6 +175,16 @@ ALTER TABLE llx_recruitment_recruitmentcandidature_extrafields ADD INDEX idx_fk_
|
||||
|
||||
|
||||
|
||||
CREATE TABLE llx_product_attribute_combination_price_level
|
||||
(
|
||||
rowid INTEGER PRIMARY KEY NOT NULL AUTO_INCREMENT,
|
||||
fk_product_attribute_combination INTEGER DEFAULT 1 NOT NULL,
|
||||
fk_price_level INTEGER DEFAULT 1 NOT NULL,
|
||||
variation_price DOUBLE(24,8) NOT NULL,
|
||||
variation_price_percentage INTEGER NULL
|
||||
)ENGINE=innodb;
|
||||
|
||||
ALTER TABLE llx_product_attribute_combination_price_level ADD UNIQUE( fk_product_attribute_combination, fk_price_level);
|
||||
|
||||
|
||||
|
||||
@ -219,3 +229,10 @@ create table llx_c_recruitment_origin
|
||||
label varchar(64) NOT NULL,
|
||||
active tinyint DEFAULT 1 NOT NULL
|
||||
)ENGINE=innodb;
|
||||
|
||||
|
||||
|
||||
ALTER TABLE llx_product MODIFY COLUMN seuil_stock_alerte float;
|
||||
ALTER TABLE llx_product MODIFY COLUMN desiredstock float;
|
||||
ALTER TABLE llx_product_warehouse_properties MODIFY COLUMN seuil_stock_alerte float;
|
||||
ALTER TABLE llx_product_warehouse_properties MODIFY COLUMN desiredstock float;
|
||||
|
||||
@ -60,7 +60,7 @@ create table llx_product
|
||||
tobatch tinyint DEFAULT 0 NOT NULL, -- Is it a product that need a batch management (eat-by or lot management)
|
||||
fk_product_type integer DEFAULT 0, -- Type of product: 0 for regular product, 1 for service, 9 for other (used by external module)
|
||||
duration varchar(6),
|
||||
seuil_stock_alerte integer DEFAULT NULL,
|
||||
seuil_stock_alerte float DEFAULT NULL,
|
||||
url varchar(255),
|
||||
barcode varchar(180) DEFAULT NULL, -- barcode
|
||||
fk_barcode_type integer DEFAULT NULL, -- barcode type
|
||||
@ -96,7 +96,7 @@ create table llx_product
|
||||
import_key varchar(14), -- Import key
|
||||
model_pdf varchar(255), -- model save dodument used
|
||||
fk_price_expression integer, -- Link to the rule for dynamic price calculation
|
||||
desiredstock integer DEFAULT 0,
|
||||
desiredstock float DEFAULT 0,
|
||||
fk_unit integer DEFAULT NULL,
|
||||
price_autogen tinyint DEFAULT 0,
|
||||
fk_project integer DEFAULT NULL -- Used when product was generated by a project or is specifif to a project
|
||||
|
||||
@ -0,0 +1,28 @@
|
||||
-- ============================================================================
|
||||
-- Copyright (C) 2020 John BOTELLA <john.botella@atm-consulting.fr>
|
||||
--
|
||||
-- This program is free software; you can redistribute it and/or modify
|
||||
-- it under the terms of the GNU General Public License as published by
|
||||
-- the Free Software Foundation; either version 3 of the License, or
|
||||
-- (at your option) any later version.
|
||||
--
|
||||
-- This program is distributed in the hope that it will be useful,
|
||||
-- but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
-- GNU General Public License for more details.
|
||||
--
|
||||
-- You should have received a copy of the GNU General Public License
|
||||
-- along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
--
|
||||
-- ============================================================================
|
||||
|
||||
CREATE TABLE llx_product_attribute_combination_price_level
|
||||
(
|
||||
rowid INTEGER PRIMARY KEY NOT NULL AUTO_INCREMENT,
|
||||
fk_product_attribute_combination INTEGER DEFAULT 1 NOT NULL,
|
||||
fk_price_level INTEGER DEFAULT 1 NOT NULL,
|
||||
variation_price DOUBLE(24,8) NOT NULL,
|
||||
variation_price_percentage INTEGER NULL
|
||||
)ENGINE=innodb;
|
||||
|
||||
ALTER TABLE llx_product_attribute_combination_price_level ADD UNIQUE( fk_product_attribute_combination, fk_price_level);
|
||||
@ -24,8 +24,8 @@ create table llx_product_warehouse_properties
|
||||
tms timestamp,
|
||||
fk_product integer NOT NULL,
|
||||
fk_entrepot integer NOT NULL,
|
||||
seuil_stock_alerte integer DEFAULT '0',
|
||||
desiredstock integer DEFAULT '0',
|
||||
seuil_stock_alerte float DEFAULT '0',
|
||||
desiredstock float DEFAULT '0',
|
||||
import_key varchar(14) -- Import key
|
||||
)ENGINE=innodb;
|
||||
|
||||
|
||||
@ -77,7 +77,7 @@ POSModule=POS Module
|
||||
BasicPhoneLayout=Use basic layout for phones
|
||||
SetupOfTerminalNotComplete=Setup of terminal %s is not complete
|
||||
DirectPayment=Direct payment
|
||||
DirectPaymentButton=Direct cash payment button
|
||||
DirectPaymentButton=Add a "Direct cash payment" button
|
||||
InvoiceIsAlreadyValidated=Invoice is already validated
|
||||
NoLinesToBill=No lines to bill
|
||||
CustomReceipt=Custom Receipt
|
||||
@ -94,12 +94,12 @@ TakeposConnectorMethodDescription=External module with extra features. Posibilit
|
||||
PrintMethod=Print method
|
||||
ReceiptPrinterMethodDescription=Powerful method with a lot of parameters. Full customizable with templates. Cannot print from the cloud.
|
||||
ByTerminal=By terminal
|
||||
TakeposNumpadUsePaymentIcon=Use payment icon on numpad
|
||||
TakeposNumpadUsePaymentIcon=Use icon instead of text on payment buttons of numpad
|
||||
CashDeskRefNumberingModules=Numbering module for POS sales
|
||||
CashDeskGenericMaskCodes6 = <br><b>{TN}</b> tag is used to add the terminal number
|
||||
TakeposGroupSameProduct=Group same products lines
|
||||
StartAParallelSale=Start a new parallel sale
|
||||
ControlCashOpening=Control cash box at opening pos
|
||||
ControlCashOpening=Control cash box at opening POS
|
||||
CloseCashFence=Close cash fence
|
||||
CashReport=Cash report
|
||||
MainPrinterToUse=Main printer to use
|
||||
@ -117,6 +117,6 @@ HideCategoryImages=Hide Category Images
|
||||
HideProductImages=Hide Product Images
|
||||
NumberOfLinesToShow=Number of lines of images to show
|
||||
DefineTablePlan=Define tables plan
|
||||
GiftReceiptButton=Gift receipt button
|
||||
GiftReceiptButton=Add a "Gift receipt" button
|
||||
GiftReceipt=Gift receipt
|
||||
ModuleReceiptPrinterMustBeEnabled=Module Receipt printer must have been enabled first
|
||||
|
||||
@ -355,8 +355,8 @@ PriceUTTC=U.P. (inc. tax)
|
||||
Amount=Amount
|
||||
AmountInvoice=Invoice amount
|
||||
AmountInvoiced=Amount invoiced
|
||||
AmountInvoicedHT=Amount invoiced (incl. tax)
|
||||
AmountInvoicedTTC=Amount invoiced (excl. tax)
|
||||
AmountInvoicedHT=Amount invoiced (excl. tax)
|
||||
AmountInvoicedTTC=Amount invoiced (inc. tax)
|
||||
AmountPayment=Payment amount
|
||||
AmountHTShort=Amount (excl.)
|
||||
AmountTTCShort=Amount (inc. tax)
|
||||
|
||||
@ -104,6 +104,7 @@ SetDefaultBarcodeType=Set barcode type
|
||||
BarcodeValue=Barcode value
|
||||
NoteNotVisibleOnBill=Note (not visible on invoices, proposals...)
|
||||
ServiceLimitedDuration=If product is a service with limited duration:
|
||||
FillWithLastServiceDates=Fill with last service line dates
|
||||
MultiPricesAbility=Multiple price segments per product/service (each customer is in one price segment)
|
||||
MultiPricesNumPrices=Number of prices
|
||||
DefaultPriceType=Base of prices per default (with versus without tax) when adding new sale prices
|
||||
@ -361,6 +362,9 @@ SelectCombination=Select combination
|
||||
ProductCombinationGenerator=Variants generator
|
||||
Features=Features
|
||||
PriceImpact=Price impact
|
||||
ImpactOnPriceLevel=Impact on price level %s
|
||||
ApplyToAllPriceImpactLevel= Apply to all levels
|
||||
ApplyToAllPriceImpactLevelHelp=By clicking here you set the same price impact on all levels
|
||||
WeightImpact=Weight impact
|
||||
NewProductAttribute=New attribute
|
||||
NewProductAttributeValue=New attribute value
|
||||
|
||||
@ -211,9 +211,9 @@ ProjectNbProjectByMonth=No. of created projects by month
|
||||
ProjectNbTaskByMonth=No. of created tasks by month
|
||||
ProjectOppAmountOfProjectsByMonth=Amount of leads by month
|
||||
ProjectWeightedOppAmountOfProjectsByMonth=Weighted amount of leads by month
|
||||
ProjectOpenedProjectByOppStatus=Open project/lead by lead status
|
||||
ProjectsStatistics=Statistics on projects/leads
|
||||
TasksStatistics=Statistics on project/lead tasks
|
||||
ProjectOpenedProjectByOppStatus=Open project|lead by lead status
|
||||
ProjectsStatistics=Statistics on projects or leads
|
||||
TasksStatistics=Statistics on tasks of projects or leads
|
||||
TaskAssignedToEnterTime=Task assigned. Entering time on this task should be possible.
|
||||
IdTaskTime=Id task time
|
||||
YouCanCompleteRef=If you want to complete the ref with some suffix, it is recommanded to add a - character to separate it, so the automatic numbering will still work correctly for next projects. For example %s-MYSUFFIX
|
||||
|
||||
@ -355,8 +355,8 @@ PriceUTTC=P.U TTC
|
||||
Amount=Montant
|
||||
AmountInvoice=Montant facture
|
||||
AmountInvoiced=Montant facturé
|
||||
AmountInvoicedHT=Montant facturé (TTC)
|
||||
AmountInvoicedTTC=Montant facturé (HT)
|
||||
AmountInvoicedHT=Montant facturé (HT)
|
||||
AmountInvoicedTTC=Montant facturé (TTC)
|
||||
AmountPayment=Montant paiement
|
||||
AmountHTShort=Montant HT
|
||||
AmountTTCShort=Montant TTC
|
||||
|
||||
@ -147,7 +147,8 @@ if (is_array($extrafields->attributes[$object->table_element]['label']) && count
|
||||
'label'=>$extrafields->attributes[$object->table_element]['label'][$key],
|
||||
'checked'=>(($extrafields->attributes[$object->table_element]['list'][$key] < 0) ? 0 : 1),
|
||||
'position'=>$extrafields->attributes[$object->table_element]['pos'][$key],
|
||||
'enabled'=>(abs($extrafields->attributes[$object->table_element]['list'][$key]) != 3 && $extrafields->attributes[$object->table_element]['perms'][$key])
|
||||
'enabled'=>(abs($extrafields->attributes[$object->table_element]['list'][$key]) != 3 && $extrafields->attributes[$object->table_element]['perms'][$key]),
|
||||
'langfile'=>$extrafields->attributes[$object->table_element]['langfile'][$key]
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1107,7 +1107,7 @@ if (is_object($objcanvas) && $objcanvas->displayCanvasExists($action))
|
||||
{
|
||||
print '<tr><td>'.$langs->trans('DefaultUnitToShow').'</td>';
|
||||
print '<td colspan="3">';
|
||||
print $form->selectUnits('', 'units');
|
||||
print $form->selectUnits(empty($line->fk_unit) ? $conf->global->PRODUCT_USE_UNITS : $line->fk_unit, 'units');
|
||||
print '</td></tr>';
|
||||
}
|
||||
|
||||
|
||||
@ -287,8 +287,8 @@ class Products extends DolibarrApi
|
||||
foreach ($request_data as $field => $value) {
|
||||
if ($field == 'id') { continue;
|
||||
}
|
||||
if ($field == 'stock_reel') {
|
||||
throw new RestException(400, 'Stock reel cannot be updated here. Use the /stockmovements endpoint instead');
|
||||
if ($field == 'stock_reel') {
|
||||
throw new RestException(400, 'Stock reel cannot be updated here. Use the /stockmovements endpoint instead');
|
||||
}
|
||||
$this->product->$field = $value;
|
||||
}
|
||||
@ -578,12 +578,12 @@ class Products extends DolibarrApi
|
||||
}
|
||||
|
||||
if ($result > 0) {
|
||||
require_once DOL_DOCUMENT_ROOT.'/product/class/productcustomerprice.class.php';
|
||||
$prodcustprice = new Productcustomerprice($this->db);
|
||||
$filter = array();
|
||||
$filter['t.fk_product'] .= $id;
|
||||
if ($thirdparty_id) $filter['t.fk_soc'] .= $thirdparty_id;
|
||||
$result = $prodcustprice->fetch_all('', '', 0, 0, $filter);
|
||||
require_once DOL_DOCUMENT_ROOT.'/product/class/productcustomerprice.class.php';
|
||||
$prodcustprice = new Productcustomerprice($this->db);
|
||||
$filter = array();
|
||||
$filter['t.fk_product'] .= $id;
|
||||
if ($thirdparty_id) $filter['t.fk_soc'] .= $thirdparty_id;
|
||||
$result = $prodcustprice->fetch_all('', '', 0, 0, $filter);
|
||||
}
|
||||
|
||||
if (empty($prodcustprice->lines)) {
|
||||
@ -624,8 +624,8 @@ class Products extends DolibarrApi
|
||||
}
|
||||
|
||||
return array(
|
||||
'prices_by_qty'=>$this->product->prices_by_qty[0], // 1 if price by quantity was activated for the product
|
||||
'prices_by_qty_list'=>$this->product->prices_by_qty_list[0]
|
||||
'prices_by_qty'=>$this->product->prices_by_qty[0], // 1 if price by quantity was activated for the product
|
||||
'prices_by_qty_list'=>$this->product->prices_by_qty_list[0]
|
||||
);
|
||||
}
|
||||
|
||||
@ -641,11 +641,11 @@ class Products extends DolibarrApi
|
||||
* @param string $ref_fourn Supplier ref
|
||||
* @param float $tva_tx New VAT Rate (For example 8.5. Should not be a string)
|
||||
* @param string $charges costs affering to product
|
||||
* @param float $remise_percent Discount regarding qty (percent)
|
||||
* @param float $remise Discount regarding qty (amount)
|
||||
* @param int $newnpr Set NPR or not
|
||||
* @param int $delivery_time_days Delay in days for delivery (max). May be '' if not defined.
|
||||
* @param string $supplier_reputation Reputation with this product to the defined supplier (empty, FAVORITE, DONOTORDER)
|
||||
* @param float $remise_percent Discount regarding qty (percent)
|
||||
* @param float $remise Discount regarding qty (amount)
|
||||
* @param int $newnpr Set NPR or not
|
||||
* @param int $delivery_time_days Delay in days for delivery (max). May be '' if not defined.
|
||||
* @param string $supplier_reputation Reputation with this product to the defined supplier (empty, FAVORITE, DONOTORDER)
|
||||
* @param array $localtaxes_array Array with localtaxes info array('0'=>type1,'1'=>rate1,'2'=>type2,'3'=>rate2) (loaded by getLocalTaxesFromRate(vatrate, 0, ...) function).
|
||||
* @param string $newdefaultvatcode Default vat code
|
||||
* @param float $multicurrency_buyprice Purchase price for the quantity min in currency
|
||||
@ -749,77 +749,77 @@ class Products extends DolibarrApi
|
||||
*/
|
||||
public function getSupplierProducts($sortfield = "t.ref", $sortorder = 'ASC', $limit = 100, $page = 0, $mode = 0, $category = 0, $supplier = 0, $sqlfilters = '')
|
||||
{
|
||||
global $db, $conf;
|
||||
$obj_ret = array();
|
||||
$socid = DolibarrApiAccess::$user->socid ? DolibarrApiAccess::$user->socid : '';
|
||||
$sql = "SELECT t.rowid, t.ref, t.ref_ext";
|
||||
$sql .= " FROM ".MAIN_DB_PREFIX."product as t";
|
||||
if ($category > 0) {
|
||||
$sql .= ", ".MAIN_DB_PREFIX."categorie_product as c";
|
||||
}
|
||||
$sql .= ", ".MAIN_DB_PREFIX."product_fournisseur_price as s";
|
||||
global $db, $conf;
|
||||
$obj_ret = array();
|
||||
$socid = DolibarrApiAccess::$user->socid ? DolibarrApiAccess::$user->socid : '';
|
||||
$sql = "SELECT t.rowid, t.ref, t.ref_ext";
|
||||
$sql .= " FROM ".MAIN_DB_PREFIX."product as t";
|
||||
if ($category > 0) {
|
||||
$sql .= ", ".MAIN_DB_PREFIX."categorie_product as c";
|
||||
}
|
||||
$sql .= ", ".MAIN_DB_PREFIX."product_fournisseur_price as s";
|
||||
|
||||
$sql .= ' WHERE t.entity IN ('.getEntity('product').')';
|
||||
$sql .= ' WHERE t.entity IN ('.getEntity('product').')';
|
||||
|
||||
if ($supplier > 0) {
|
||||
$sql .= " AND s.fk_soc = ".$db->escape($supplier);
|
||||
}
|
||||
$sql .= " AND s.fk_product = t.rowid";
|
||||
// Select products of given category
|
||||
if ($category > 0) {
|
||||
$sql .= " AND c.fk_categorie = ".$db->escape($category);
|
||||
$sql .= " AND c.fk_product = t.rowid";
|
||||
}
|
||||
if ($mode == 1) {
|
||||
// Show only products
|
||||
$sql .= " AND t.fk_product_type = 0";
|
||||
} elseif ($mode == 2) {
|
||||
// Show only services
|
||||
$sql .= " AND t.fk_product_type = 1";
|
||||
}
|
||||
// Add sql filters
|
||||
if ($sqlfilters) {
|
||||
if (!DolibarrApi::_checkFilters($sqlfilters)) {
|
||||
throw new RestException(503, 'Error when validating parameter sqlfilters '.$sqlfilters);
|
||||
}
|
||||
$regexstring = '\(([^:\'\(\)]+:[^:\'\(\)]+:[^:\(\)]+)\)';
|
||||
$sql .= " AND (".preg_replace_callback('/'.$regexstring.'/', 'DolibarrApi::_forge_criteria_callback', $sqlfilters).")";
|
||||
}
|
||||
$sql .= $db->order($sortfield, $sortorder);
|
||||
if ($limit) {
|
||||
if ($page < 0) {
|
||||
$page = 0;
|
||||
}
|
||||
$offset = $limit * $page;
|
||||
$sql .= $db->plimit($limit + 1, $offset);
|
||||
}
|
||||
$result = $db->query($sql);
|
||||
if ($result) {
|
||||
$num = $db->num_rows($result);
|
||||
$min = min($num, ($limit <= 0 ? $num : $limit));
|
||||
$i = 0;
|
||||
while ($i < $min)
|
||||
{
|
||||
$obj = $db->fetch_object($result);
|
||||
if ($supplier > 0) {
|
||||
$sql .= " AND s.fk_soc = ".$db->escape($supplier);
|
||||
}
|
||||
$sql .= " AND s.fk_product = t.rowid";
|
||||
// Select products of given category
|
||||
if ($category > 0) {
|
||||
$sql .= " AND c.fk_categorie = ".$db->escape($category);
|
||||
$sql .= " AND c.fk_product = t.rowid";
|
||||
}
|
||||
if ($mode == 1) {
|
||||
// Show only products
|
||||
$sql .= " AND t.fk_product_type = 0";
|
||||
} elseif ($mode == 2) {
|
||||
// Show only services
|
||||
$sql .= " AND t.fk_product_type = 1";
|
||||
}
|
||||
// Add sql filters
|
||||
if ($sqlfilters) {
|
||||
if (!DolibarrApi::_checkFilters($sqlfilters)) {
|
||||
throw new RestException(503, 'Error when validating parameter sqlfilters '.$sqlfilters);
|
||||
}
|
||||
$regexstring = '\(([^:\'\(\)]+:[^:\'\(\)]+:[^:\(\)]+)\)';
|
||||
$sql .= " AND (".preg_replace_callback('/'.$regexstring.'/', 'DolibarrApi::_forge_criteria_callback', $sqlfilters).")";
|
||||
}
|
||||
$sql .= $db->order($sortfield, $sortorder);
|
||||
if ($limit) {
|
||||
if ($page < 0) {
|
||||
$page = 0;
|
||||
}
|
||||
$offset = $limit * $page;
|
||||
$sql .= $db->plimit($limit + 1, $offset);
|
||||
}
|
||||
$result = $db->query($sql);
|
||||
if ($result) {
|
||||
$num = $db->num_rows($result);
|
||||
$min = min($num, ($limit <= 0 ? $num : $limit));
|
||||
$i = 0;
|
||||
while ($i < $min)
|
||||
{
|
||||
$obj = $db->fetch_object($result);
|
||||
|
||||
$product_fourn = new ProductFournisseur($this->db);
|
||||
$product_fourn_list = $product_fourn->list_product_fournisseur_price($obj->rowid, '', '', 0, 0);
|
||||
foreach ($product_fourn_list as $tmpobj) {
|
||||
$this->_cleanObjectDatas($tmpobj);
|
||||
}
|
||||
$product_fourn = new ProductFournisseur($this->db);
|
||||
$product_fourn_list = $product_fourn->list_product_fournisseur_price($obj->rowid, '', '', 0, 0);
|
||||
foreach ($product_fourn_list as $tmpobj) {
|
||||
$this->_cleanObjectDatas($tmpobj);
|
||||
}
|
||||
|
||||
//var_dump($product_fourn_list->db);exit;
|
||||
$obj_ret[$obj->rowid] = $product_fourn_list;
|
||||
//var_dump($product_fourn_list->db);exit;
|
||||
$obj_ret[$obj->rowid] = $product_fourn_list;
|
||||
|
||||
$i++;
|
||||
}
|
||||
} else {
|
||||
throw new RestException(503, 'Error when retrieve product list : '.$db->lasterror());
|
||||
}
|
||||
if (!count($obj_ret)) {
|
||||
throw new RestException(404, 'No product found');
|
||||
}
|
||||
return $obj_ret;
|
||||
$i++;
|
||||
}
|
||||
} else {
|
||||
throw new RestException(503, 'Error when retrieve product list : '.$db->lasterror());
|
||||
}
|
||||
if (!count($obj_ret)) {
|
||||
throw new RestException(404, 'No product found');
|
||||
}
|
||||
return $obj_ret;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -1057,7 +1057,7 @@ class Products extends DolibarrApi
|
||||
$result = $prodattr->delete(DolibarrApiAccess::$user);
|
||||
|
||||
if ($result <= 0) {
|
||||
throw new RestException(500, "Error deleting attribute");
|
||||
throw new RestException(500, "Error deleting attribute");
|
||||
}
|
||||
|
||||
return $result;
|
||||
@ -1161,9 +1161,23 @@ class Products extends DolibarrApi
|
||||
throw new RestException(401);
|
||||
}
|
||||
|
||||
$sql = "DELETE FROM ".MAIN_DB_PREFIX."product_attribute_value WHERE ref LIKE '".trim($ref)."' AND fk_product_attribute = ".(int) $id;
|
||||
$sql = "SELECT rowid FROM ".MAIN_DB_PREFIX."product_attribute_value WHERE ref LIKE '".trim($ref)."' AND fk_product_attribute = ".(int) $id." AND entity IN (".getEntity('product').")";
|
||||
$query = $this->db->query($sql);
|
||||
|
||||
if ($this->db->query($sql)) {
|
||||
if (!$query) {
|
||||
throw new RestException(401);
|
||||
}
|
||||
|
||||
if (!$this->db->num_rows($query)) {
|
||||
throw new RestException(404, 'Attribute value not found');
|
||||
}
|
||||
|
||||
$result = $this->db->fetch_object($query);
|
||||
|
||||
$attrval = new ProductAttributeValue($this->db);
|
||||
$attrval->id = $result->rowid;
|
||||
$result = $attrval->delete(DolibarrApiAccess::$user);
|
||||
if ($result > 0) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
@ -1328,7 +1342,7 @@ class Products extends DolibarrApi
|
||||
$objectval = new ProductAttributeValue($this->db);
|
||||
$objectval->id = (int) $id;
|
||||
|
||||
if ($objectval->delete() > 0) {
|
||||
if ($objectval->delete(DolibarrApiAccess::$user) > 0) {
|
||||
return 1;
|
||||
}
|
||||
throw new RestException(500, "Error deleting attribute value");
|
||||
@ -1448,9 +1462,9 @@ class Products extends DolibarrApi
|
||||
$result = $prodcomb->createProductCombination(DolibarrApiAccess::$user, $this->product, $features, array(), $price_impact_is_percent, $price_impact, $weight_impact, $reference);
|
||||
if ($result > 0)
|
||||
{
|
||||
return $result;
|
||||
return $result;
|
||||
} else {
|
||||
throw new RestException(500, "Error creating new product variant");
|
||||
throw new RestException(500, "Error creating new product variant");
|
||||
}
|
||||
}
|
||||
|
||||
@ -1573,7 +1587,7 @@ class Products extends DolibarrApi
|
||||
$result = $prodcomb->delete(DolibarrApiAccess::$user);
|
||||
if ($result <= 0)
|
||||
{
|
||||
throw new RestException(500, "Error deleting variant");
|
||||
throw new RestException(500, "Error deleting variant");
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
@ -1665,17 +1679,17 @@ class Products extends DolibarrApi
|
||||
}
|
||||
|
||||
if ($includestockdata) {
|
||||
$this->product->load_stock();
|
||||
$this->product->load_stock();
|
||||
|
||||
if (is_array($this->product->stock_warehouse)) {
|
||||
foreach ($this->product->stock_warehouse as $keytmp => $valtmp) {
|
||||
if (is_array($this->product->stock_warehouse[$keytmp]->detail_batch)) {
|
||||
foreach ($this->product->stock_warehouse[$keytmp]->detail_batch as $keytmp2 => $valtmp2) {
|
||||
unset($this->product->stock_warehouse[$keytmp]->detail_batch[$keytmp2]->db);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (is_array($this->product->stock_warehouse)) {
|
||||
foreach ($this->product->stock_warehouse as $keytmp => $valtmp) {
|
||||
if (is_array($this->product->stock_warehouse[$keytmp]->detail_batch)) {
|
||||
foreach ($this->product->stock_warehouse[$keytmp]->detail_batch as $keytmp2 => $valtmp2) {
|
||||
unset($this->product->stock_warehouse[$keytmp]->detail_batch[$keytmp2]->db);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ($includesubproducts) {
|
||||
|
||||
@ -205,7 +205,7 @@ class Product extends CommonObject
|
||||
/**
|
||||
* Stock alert
|
||||
*
|
||||
* @var int
|
||||
* @var float
|
||||
*/
|
||||
public $seuil_stock_alerte = 0;
|
||||
|
||||
@ -995,7 +995,7 @@ class Product extends CommonObject
|
||||
$sql .= ", volume = ".($this->volume != '' ? "'".$this->db->escape($this->volume)."'" : 'null');
|
||||
$sql .= ", volume_units = ".($this->volume_units != '' ? "'".$this->db->escape($this->volume_units)."'" : 'null');
|
||||
$sql .= ", fk_default_warehouse = ".($this->fk_default_warehouse > 0 ? $this->db->escape($this->fk_default_warehouse) : 'null');
|
||||
$sql .= ", seuil_stock_alerte = ".((isset($this->seuil_stock_alerte) && is_numeric($this->seuil_stock_alerte)) ? (int) $this->seuil_stock_alerte : 'null');
|
||||
$sql .= ", seuil_stock_alerte = ".((isset($this->seuil_stock_alerte) && is_numeric($this->seuil_stock_alerte)) ? (float) $this->seuil_stock_alerte : 'null');
|
||||
$sql .= ", description = '".$this->db->escape($this->description)."'";
|
||||
$sql .= ", url = ".($this->url ? "'".$this->db->escape($this->url)."'" : 'null');
|
||||
$sql .= ", customcode = '".$this->db->escape($this->customcode)."'";
|
||||
@ -1008,7 +1008,7 @@ class Product extends CommonObject
|
||||
$sql .= ", accountancy_code_sell= '".$this->db->escape($this->accountancy_code_sell)."'";
|
||||
$sql .= ", accountancy_code_sell_intra= '".$this->db->escape($this->accountancy_code_sell_intra)."'";
|
||||
$sql .= ", accountancy_code_sell_export= '".$this->db->escape($this->accountancy_code_sell_export)."'";
|
||||
$sql .= ", desiredstock = ".((isset($this->desiredstock) && is_numeric($this->desiredstock)) ? (int) $this->desiredstock : "null");
|
||||
$sql .= ", desiredstock = ".((isset($this->desiredstock) && is_numeric($this->desiredstock)) ? (float) $this->desiredstock : "null");
|
||||
$sql .= ", cost_price = ".($this->cost_price != '' ? $this->db->escape($this->cost_price) : 'null');
|
||||
$sql .= ", fk_unit= ".(!$this->fk_unit ? 'NULL' : (int) $this->fk_unit);
|
||||
$sql .= ", price_autogen = ".(!$this->price_autogen ? 0 : 1);
|
||||
@ -1077,7 +1077,7 @@ class Product extends CommonObject
|
||||
$comb = new ProductCombination($this->db);
|
||||
|
||||
foreach ($comb->fetchAllByFkProductParent($this->id) as $currcomb) {
|
||||
$currcomb->updateProperties($this, $user);
|
||||
$currcomb->updateProperties($this, $user);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -66,7 +66,7 @@ if ($id > 0 || !empty($ref))
|
||||
|
||||
if ($cancel) $action = '';
|
||||
|
||||
// Action association d'un sousproduit
|
||||
// Add subproduct to product
|
||||
if ($action == 'add_prod' && ($user->rights->produit->creer || $user->rights->service->creer))
|
||||
{
|
||||
$error = 0;
|
||||
|
||||
@ -101,7 +101,9 @@ $search_all = trim(GETPOST("search_all", 'alpha'));
|
||||
$search = array();
|
||||
foreach ($object->fields as $key => $val)
|
||||
{
|
||||
if (GETPOST('search_'.$key, 'alpha') !== '') $search[$key] = GETPOST('search_'.$key, 'alpha');
|
||||
$search_key = $key;
|
||||
if ($search_key == 'statut') $search_key = 'status'; // remove this after refactor entrepot.class property statut to status
|
||||
if (GETPOST('search_'.$search_key, 'alpha') !== '') $search[$search_key] = GETPOST('search_'.$search_key, 'alpha');
|
||||
}
|
||||
|
||||
// Definition of fields for list
|
||||
@ -225,13 +227,15 @@ if (!empty($conf->categorie->enabled))
|
||||
}
|
||||
foreach ($search as $key => $val)
|
||||
{
|
||||
$class_key = $key;
|
||||
if ($class_key == 'status') $class_key = 'statut'; // remove this after refactor entrepot.class property statut to status
|
||||
if (($key == 'status' && $search[$key] == -1) || $key=='entity') continue;
|
||||
$mode_search = (($object->isInt($object->fields[$key]) || $object->isFloat($object->fields[$key])) ? 1 : 0);
|
||||
if (strpos($object->fields[$key]['type'], 'integer:') === 0) {
|
||||
if ($search[$key] == '-1') $search[$key] = '';
|
||||
$mode_search = 2;
|
||||
}
|
||||
if ($search[$key] != '') $sql .= natural_search((($key == 'ref') ? 't.ref' : 't.' . $key), $search[$key], (($key == 'status') ? 2 : $mode_search));
|
||||
if ($search[$key] != '') $sql .= natural_search((($key == 'ref') ? 't.ref' : 't.' . $class_key), $search[$key], (($key == 'status') ? 2 : $mode_search));
|
||||
}
|
||||
if ($search_all) $sql .= natural_search(array_keys($fieldstosearchall), $search_all);
|
||||
// Add where from extra fields
|
||||
|
||||
@ -61,7 +61,7 @@ $search_agenda_label = GETPOST('search_agenda_label');
|
||||
$id = GETPOST("id", 'int');
|
||||
$socid = 0;
|
||||
//if ($user->socid > 0) $socid = $user->socid; // For external user, no check is done on company because readability is managed by public status of project and assignement.
|
||||
$result = restrictedArea($user, 'projet', $id, '');
|
||||
$result = restrictedArea($user, 'projet', $id, 'projet&project');
|
||||
|
||||
if (!$user->rights->projet->lire) accessforbidden();
|
||||
|
||||
|
||||
@ -417,16 +417,14 @@ if (!empty($conf->google->enabled) && !empty($conf->global->MAIN_GOOGLE_AD_CLIEN
|
||||
if (empty($conf->dol_use_jmobile))
|
||||
{
|
||||
print '<div align="center">'."\n";
|
||||
print '<script type="text/javascript"><!--'."\n";
|
||||
print '<script><!--'."\n";
|
||||
print 'google_ad_client = "'.$conf->global->MAIN_GOOGLE_AD_CLIENT.'";'."\n";
|
||||
print 'google_ad_slot = "'.$conf->global->MAIN_GOOGLE_AD_SLOT.'";'."\n";
|
||||
print 'google_ad_width = '.$conf->global->MAIN_GOOGLE_AD_WIDTH.';'."\n";
|
||||
print 'google_ad_height = '.$conf->global->MAIN_GOOGLE_AD_HEIGHT.';'."\n";
|
||||
print '//-->'."\n";
|
||||
print '</script>'."\n";
|
||||
print '<script type="text/javascript"'."\n";
|
||||
print 'src="http://pagead2.googlesyndication.com/pagead/show_ads.js">'."\n";
|
||||
print '</script>'."\n";
|
||||
print '<script src="//pagead2.googlesyndication.com/pagead/show_ads.js"></script>'."\n";
|
||||
print '</div>'."\n";
|
||||
} else {
|
||||
print '<!-- google js advert tag disabled with jmobile -->'."\n";
|
||||
|
||||
@ -34,7 +34,8 @@ if (!$user->admin) accessforbidden();
|
||||
|
||||
$langs->loadLangs(array("admin", "cashdesk", "printing"));
|
||||
|
||||
global $db;
|
||||
$res = 0;
|
||||
|
||||
|
||||
/*
|
||||
* Actions
|
||||
@ -44,9 +45,15 @@ if (GETPOST('action', 'alpha') == 'set')
|
||||
{
|
||||
$db->begin();
|
||||
|
||||
dol_syslog("admin/cashdesk: level ".GETPOST('level', 'alpha'));
|
||||
dol_syslog("admin/bar");
|
||||
|
||||
if (!$res > 0) $error++;
|
||||
$suplement_category = GETPOST('TAKEPOS_SUPPLEMENTS_CATEGORY', 'alpha');
|
||||
if ($suplement_category < 0) $suplement_category= 0;
|
||||
|
||||
$res = dolibarr_set_const($db, "TAKEPOS_SUPPLEMENTS_CATEGORY", $suplement_category, 'chaine', 0, '', $conf->entity);
|
||||
if ($res <= 0) {
|
||||
$error++;
|
||||
}
|
||||
|
||||
if (!$error)
|
||||
{
|
||||
@ -74,7 +81,6 @@ $linkback = '<a href="'.DOL_URL_ROOT.'/admin/modules.php">'.$langs->trans("BackT
|
||||
print load_fiche_titre($langs->trans("CashDeskSetup").' (TakePOS)', $linkback, 'title_setup');
|
||||
$head = takepos_prepare_head();
|
||||
dol_fiche_head($head, 'bar', 'TakePOS', -1, 'cash-register');
|
||||
print '<br>';
|
||||
|
||||
|
||||
// Mode
|
||||
@ -93,129 +99,138 @@ function Floors() {
|
||||
|
||||
<?php
|
||||
|
||||
print '<a href="" onclick="Floors(); return false;"><span class="fa fa-glass-cheers"></span> '.$langs->trans("DefineTablePlan").'</a><br>';
|
||||
print '<br><br>';
|
||||
|
||||
print '<div class="div-table-responsive">';
|
||||
print '<table class="noborder centpercent">';
|
||||
print '<tr class="liste_titre">';
|
||||
print '<td class="titlefieldcreate">'.$langs->trans("Parameters").'</td><td>'.$langs->trans("Value").'</td>';
|
||||
print "</tr>\n";
|
||||
|
||||
if ($conf->global->TAKEPOS_BAR_RESTAURANT && $conf->global->TAKEPOS_PRINT_METHOD != "browser") {
|
||||
print '<tr class="oddeven value"><td>';
|
||||
print $langs->trans("OrderPrinters").' (<a href="'.DOL_URL_ROOT.'/takepos/admin/orderprinters.php?leftmenu=setup">'.$langs->trans("Setup").'</a>)';
|
||||
print '</td>';
|
||||
print '<td>';
|
||||
print ajax_constantonoff("TAKEPOS_ORDER_PRINTERS", array(), $conf->entity, 0, 0, 1, 0);
|
||||
//print $form->selectyesno("TAKEPOS_ORDER_PRINTERS", $conf->global->TAKEPOS_ORDER_PRINTERS, 1);
|
||||
print '</td></tr>';
|
||||
|
||||
print '<tr class="oddeven value"><td>';
|
||||
print $langs->trans("OrderNotes");
|
||||
print '</td>';
|
||||
print '<td>';
|
||||
print ajax_constantonoff("TAKEPOS_ORDER_NOTES", array(), $conf->entity, 0, 0, 1, 0);
|
||||
//print $form->selectyesno("TAKEPOS_ORDER_NOTES", $conf->global->TAKEPOS_ORDER_NOTES, 1);
|
||||
print '</td></tr>';
|
||||
}
|
||||
|
||||
print '<tr class="oddeven value"><td>';
|
||||
print $langs->trans("BasicPhoneLayout");
|
||||
print '</td>';
|
||||
print '<td>';
|
||||
//print $form->selectyesno("TAKEPOS_PHONE_BASIC_LAYOUT", $conf->global->TAKEPOS_PHONE_BASIC_LAYOUT, 1);
|
||||
print ajax_constantonoff("TAKEPOS_PHONE_BASIC_LAYOUT", array(), $conf->entity, 0, 0, 1, 0);
|
||||
print '</td></tr>';
|
||||
|
||||
print '<tr class="oddeven value"><td>';
|
||||
print $langs->trans("ProductSupplements");
|
||||
print '</td>';
|
||||
print '<td>';
|
||||
//print $form->selectyesno("TAKEPOS_SUPPLEMENTS", $conf->global->TAKEPOS_SUPPLEMENTS, 1);
|
||||
print ajax_constantonoff("TAKEPOS_SUPPLEMENTS", array(), $conf->entity, 0, 0, 1, 0);
|
||||
print '</td></tr>';
|
||||
|
||||
if ($conf->global->TAKEPOS_SUPPLEMENTS)
|
||||
{
|
||||
print '<tr class="oddeven"><td>';
|
||||
print $langs->trans("SupplementCategory");
|
||||
print '</td>';
|
||||
print '<td>';
|
||||
print $form->select_all_categories(Categorie::TYPE_PRODUCT, $conf->global->TAKEPOS_SUPPLEMENTS_CATEGORY, 'TAKEPOS_SUPPLEMENTS_CATEGORY', 64, 0, 0);
|
||||
print ajax_combobox('TAKEPOS_SUPPLEMENTS_CATEGORY');
|
||||
print "</td></tr>\n";
|
||||
}
|
||||
|
||||
print '<tr class="oddeven value"><td>';
|
||||
print 'QR - '.$langs->trans("CustomerMenu");
|
||||
print '</td>';
|
||||
print '<td>';
|
||||
print ajax_constantonoff("TAKEPOS_QR_MENU", array(), $conf->entity, 0, 0, 1, 0);
|
||||
print '</td></tr>';
|
||||
|
||||
print '<tr class="oddeven value"><td>';
|
||||
print 'QR - '.$langs->trans("AutoOrder");
|
||||
print '</td>';
|
||||
print '<td>';
|
||||
print ajax_constantonoff("TAKEPOS_AUTO_ORDER", array(), $conf->entity, 0, 0, 1, 0);
|
||||
print '</td></tr>';
|
||||
|
||||
print '</table>';
|
||||
|
||||
|
||||
if ($conf->global->TAKEPOS_QR_MENU)
|
||||
{
|
||||
$urlwithouturlroot = preg_replace('/'.preg_quote(DOL_URL_ROOT, '/').'$/i', '', trim($dolibarr_main_url_root));
|
||||
$urlwithroot = $urlwithouturlroot.DOL_URL_ROOT; // This is to use external domain name found into config file
|
||||
print '<br>';
|
||||
print '<table class="noborder centpercent">';
|
||||
print '<tr class="liste_titre">';
|
||||
print '<td>'.$langs->trans("URL").'</td><td class="right">'.$langs->trans("QR").'</td>';
|
||||
print "</tr>\n";
|
||||
print '<tr class="oddeven value"><td>';
|
||||
print "<a target='_blank' href='".$urlwithroot."/takepos/public/menu.php'>".$urlwithroot."/takepos/public/menu.php</a>";
|
||||
print '</td>';
|
||||
print '<td class="right">';
|
||||
print "<a target='_blank' href='printqr.php'><img src='".DOL_URL_ROOT."/takepos/genimg/qr.php' height='42' width='42'></a>";
|
||||
print '</td></tr>';
|
||||
print '</table>';
|
||||
}
|
||||
|
||||
if ($conf->global->TAKEPOS_AUTO_ORDER)
|
||||
{
|
||||
print '<br>';
|
||||
print '<table class="noborder centpercent">';
|
||||
print '<tr class="liste_titre">';
|
||||
print '<td>'.$langs->trans("Table").'</td><td>'.$langs->trans("URL").'</td><td class="right">'.$langs->trans("QR").'</td>';
|
||||
print "</tr>\n";
|
||||
|
||||
//global $dolibarr_main_url_root;
|
||||
$urlwithouturlroot = preg_replace('/'.preg_quote(DOL_URL_ROOT, '/').'$/i', '', trim($dolibarr_main_url_root));
|
||||
$urlwithroot = $urlwithouturlroot.DOL_URL_ROOT; // This is to use external domain name found into config file
|
||||
$sql = "SELECT rowid, entity, label, leftpos, toppos, floor FROM ".MAIN_DB_PREFIX."takepos_floor_tables";
|
||||
$resql = $db->query($sql);
|
||||
$rows = array();
|
||||
while ($row = $db->fetch_array($resql)) {
|
||||
print '<tr class="oddeven value"><td>';
|
||||
print $langs->trans("Table")." ".$row['label'];
|
||||
print '</td>';
|
||||
print '<td>';
|
||||
print "<a target='_blank' href='".$urlwithroot."/takepos/public/auto_order.php?key=".dol_encode($row['rowid'])."'>".$urlwithroot."/takepos/public/auto_order.php?key=".dol_encode($row['rowid'])."</a>";
|
||||
print '</td>';
|
||||
print '<td class="right">';
|
||||
print "<a target='_blank' href='printqr.php?id=".$row['rowid']."'><img src='".DOL_URL_ROOT."/takepos/genimg/qr.php?key=".dol_encode($row['rowid'])."' height='42' width='42'></a>";
|
||||
print '</td></tr>';
|
||||
}
|
||||
|
||||
print '</table>';
|
||||
}
|
||||
|
||||
print '</div>';
|
||||
print $langs->trans("EnableBarOrRestaurantFeatures");
|
||||
print ajax_constantonoff("TAKEPOS_BAR_RESTAURANT", array(), $conf->entity, 0, 0, 1, 0);
|
||||
|
||||
print '<br>';
|
||||
|
||||
print '<div class="center"><input type="submit" class="button" value="'.$langs->trans("Save").'"></div>';
|
||||
if ($conf->global->TAKEPOS_BAR_RESTAURANT) {
|
||||
print '<br>';
|
||||
print '<a href="" onclick="Floors(); return false;"><span class="fa fa-glass-cheers"></span> '.$langs->trans("DefineTablePlan").'</a><br>';
|
||||
print '<br><br>';
|
||||
|
||||
print '<div class="div-table-responsive-no-min">';
|
||||
print '<table class="noborder centpercent">';
|
||||
print '<tr class="liste_titre">';
|
||||
print '<td class="titlefieldcreate">'.$langs->trans("Parameters").'</td><td>'.$langs->trans("Value").'</td>';
|
||||
print "</tr>\n";
|
||||
|
||||
if ($conf->global->TAKEPOS_PRINT_METHOD != "browser") {
|
||||
print '<tr class="oddeven value"><td>';
|
||||
print $langs->trans("OrderPrinters").' (<a href="'.DOL_URL_ROOT.'/takepos/admin/orderprinters.php?leftmenu=setup">'.$langs->trans("Setup").'</a>)';
|
||||
print '</td>';
|
||||
print '<td>';
|
||||
print ajax_constantonoff("TAKEPOS_ORDER_PRINTERS", array(), $conf->entity, 0, 0, 1, 0);
|
||||
//print $form->selectyesno("TAKEPOS_ORDER_PRINTERS", $conf->global->TAKEPOS_ORDER_PRINTERS, 1);
|
||||
print '</td></tr>';
|
||||
|
||||
print '<tr class="oddeven value"><td>';
|
||||
print $langs->trans("OrderNotes");
|
||||
print '</td>';
|
||||
print '<td>';
|
||||
print ajax_constantonoff("TAKEPOS_ORDER_NOTES", array(), $conf->entity, 0, 0, 1, 0);
|
||||
//print $form->selectyesno("TAKEPOS_ORDER_NOTES", $conf->global->TAKEPOS_ORDER_NOTES, 1);
|
||||
print '</td></tr>';
|
||||
}
|
||||
|
||||
print '<tr class="oddeven value"><td>';
|
||||
print $langs->trans("BasicPhoneLayout");
|
||||
print '</td>';
|
||||
print '<td>';
|
||||
//print $form->selectyesno("TAKEPOS_PHONE_BASIC_LAYOUT", $conf->global->TAKEPOS_PHONE_BASIC_LAYOUT, 1);
|
||||
print ajax_constantonoff("TAKEPOS_PHONE_BASIC_LAYOUT", array(), $conf->entity, 0, 0, 1, 0);
|
||||
print '</td></tr>';
|
||||
|
||||
print '<tr class="oddeven value"><td>';
|
||||
print $langs->trans("ProductSupplements");
|
||||
print '</td>';
|
||||
print '<td>';
|
||||
//print $form->selectyesno("TAKEPOS_SUPPLEMENTS", $conf->global->TAKEPOS_SUPPLEMENTS, 1);
|
||||
print ajax_constantonoff("TAKEPOS_SUPPLEMENTS", array(), $conf->entity, 0, 0, 1, 0);
|
||||
print '</td></tr>';
|
||||
|
||||
if ($conf->global->TAKEPOS_SUPPLEMENTS)
|
||||
{
|
||||
print '<tr class="oddeven"><td>';
|
||||
print $langs->trans("SupplementCategory");
|
||||
print '</td>';
|
||||
print '<td>';
|
||||
print $form->select_all_categories(Categorie::TYPE_PRODUCT, $conf->global->TAKEPOS_SUPPLEMENTS_CATEGORY, 'TAKEPOS_SUPPLEMENTS_CATEGORY', 64, 0, 0);
|
||||
print ajax_combobox('TAKEPOS_SUPPLEMENTS_CATEGORY');
|
||||
print "</td></tr>\n";
|
||||
}
|
||||
|
||||
print '<tr class="oddeven value"><td>';
|
||||
print 'QR - '.$langs->trans("CustomerMenu");
|
||||
print '</td>';
|
||||
print '<td>';
|
||||
print ajax_constantonoff("TAKEPOS_QR_MENU", array(), $conf->entity, 0, 0, 1, 0);
|
||||
print '</td></tr>';
|
||||
|
||||
print '<tr class="oddeven value"><td>';
|
||||
print 'QR - '.$langs->trans("AutoOrder");
|
||||
print '</td>';
|
||||
print '<td>';
|
||||
print ajax_constantonoff("TAKEPOS_AUTO_ORDER", array(), $conf->entity, 0, 0, 1, 0);
|
||||
print '</td></tr>';
|
||||
|
||||
print '</table>';
|
||||
print '</div>';
|
||||
|
||||
print '<br>';
|
||||
|
||||
print '<div class="center"><input type="submit" class="button" value="'.$langs->trans("Save").'"></div>';
|
||||
}
|
||||
|
||||
if ($conf->global->TAKEPOS_BAR_RESTAURANT) {
|
||||
if ($conf->global->TAKEPOS_QR_MENU)
|
||||
{
|
||||
$urlwithouturlroot = preg_replace('/'.preg_quote(DOL_URL_ROOT, '/').'$/i', '', trim($dolibarr_main_url_root));
|
||||
$urlwithroot = $urlwithouturlroot.DOL_URL_ROOT; // This is to use external domain name found into config file
|
||||
print '<br>';
|
||||
print '<table class="noborder centpercent">';
|
||||
print '<tr class="liste_titre">';
|
||||
print '<td>'.$langs->trans("URL").'</td><td class="right">'.$langs->trans("QR").'</td>';
|
||||
print "</tr>\n";
|
||||
print '<tr class="oddeven value"><td>';
|
||||
print "<a target='_blank' href='".$urlwithroot."/takepos/public/menu.php'>".$urlwithroot."/takepos/public/menu.php</a>";
|
||||
print '</td>';
|
||||
print '<td class="right">';
|
||||
print "<a target='_blank' href='printqr.php'><img src='".DOL_URL_ROOT."/takepos/genimg/qr.php' height='42' width='42'></a>";
|
||||
print '</td></tr>';
|
||||
print '</table>';
|
||||
}
|
||||
|
||||
if ($conf->global->TAKEPOS_AUTO_ORDER)
|
||||
{
|
||||
print '<br>';
|
||||
print '<table class="noborder centpercent">';
|
||||
print '<tr class="liste_titre">';
|
||||
print '<td>'.$langs->trans("Table").'</td><td>'.$langs->trans("URL").'</td><td class="right">'.$langs->trans("QR").'</td>';
|
||||
print "</tr>\n";
|
||||
|
||||
//global $dolibarr_main_url_root;
|
||||
$urlwithouturlroot = preg_replace('/'.preg_quote(DOL_URL_ROOT, '/').'$/i', '', trim($dolibarr_main_url_root));
|
||||
$urlwithroot = $urlwithouturlroot.DOL_URL_ROOT; // This is to use external domain name found into config file
|
||||
$sql = "SELECT rowid, entity, label, leftpos, toppos, floor FROM ".MAIN_DB_PREFIX."takepos_floor_tables";
|
||||
$resql = $db->query($sql);
|
||||
$rows = array();
|
||||
while ($row = $db->fetch_array($resql)) {
|
||||
print '<tr class="oddeven value"><td>';
|
||||
print $langs->trans("Table")." ".$row['label'];
|
||||
print '</td>';
|
||||
print '<td>';
|
||||
print "<a target='_blank' href='".$urlwithroot."/takepos/public/auto_order.php?key=".dol_encode($row['rowid'])."'>".$urlwithroot."/takepos/public/auto_order.php?key=".dol_encode($row['rowid'])."</a>";
|
||||
print '</td>';
|
||||
print '<td class="right">';
|
||||
print "<a target='_blank' href='printqr.php?id=".$row['rowid']."'><img src='".DOL_URL_ROOT."/takepos/genimg/qr.php?key=".dol_encode($row['rowid'])."' height='42' width='42'></a>";
|
||||
print '</td></tr>';
|
||||
}
|
||||
|
||||
print '</table>';
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
print "</form>\n";
|
||||
|
||||
|
||||
@ -87,6 +87,7 @@ print '<input type="hidden" name="action" value="set">';
|
||||
|
||||
print load_fiche_titre($langs->trans("PrintMethod"), '', '');
|
||||
|
||||
print '<div class="div-table-responsive-no-min">';
|
||||
print '<table class="noborder centpercent">';
|
||||
print '<tr class="liste_titre">';
|
||||
print '<td>'.$langs->trans("Name").'</td><td>'.$langs->trans("Description").'</td><td class="right">'.$langs->trans("Status").'</td>';
|
||||
@ -143,14 +144,25 @@ if ($conf->global->TAKEPOS_PRINT_METHOD == "takeposconnector")
|
||||
}
|
||||
print "</td></tr>\n";
|
||||
print '</table>';
|
||||
print '</div>';
|
||||
|
||||
|
||||
print load_fiche_titre($langs->trans("Setup"), '', '');
|
||||
|
||||
print '<div class="div-table-responsive-no-min">';
|
||||
print '<table class="noborder centpercent">';
|
||||
print '<tr class="liste_titre">';
|
||||
print '<td>'.$langs->trans("Parameters").'</td><td>'.$langs->trans("Value").'</td>';
|
||||
print "</tr>\n";
|
||||
|
||||
// VAT Grouped on ticket
|
||||
print '<tr class="oddeven"><td>';
|
||||
print $langs->trans('TicketVatGrouped');
|
||||
print '<td colspan="2">';
|
||||
print ajax_constantonoff("TAKEPOS_TICKET_VAT_GROUPPED", array(), $conf->entity, 0, 0, 1, 0);
|
||||
//print $form->selectyesno("TAKEPOS_TICKET_VAT_GROUPPED", $conf->global->TAKEPOS_TICKET_VAT_GROUPPED, 1);
|
||||
print "</td></tr>\n";
|
||||
|
||||
if ($conf->global->TAKEPOS_PRINT_METHOD == "takeposconnector") {
|
||||
print '<tr class="oddeven value"><td>';
|
||||
print $langs->trans("URL")." / ".$langs->trans("IPAddress").' (<a href="http://en.takepos.com/connector" target="_blank">'.$langs->trans("TakeposConnectorNecesary").'</a>)';
|
||||
@ -214,6 +226,7 @@ print $form->selectyesno("TAKEPOS_AUTO_PRINT_TICKETS", $conf->global->TAKEPOS_AU
|
||||
print "</td></tr>\n";
|
||||
|
||||
print '</table>';
|
||||
print '</div>';
|
||||
|
||||
print '<br>';
|
||||
|
||||
|
||||
@ -274,14 +274,6 @@ print img_object('', 'category', 'class="paddingright"').$form->select_all_categ
|
||||
print ajax_combobox('TAKEPOS_ROOT_CATEGORY_ID');
|
||||
print "</td></tr>\n";
|
||||
|
||||
// VAT Grouped on ticket
|
||||
print '<tr class="oddeven"><td>';
|
||||
print $langs->trans('TicketVatGrouped');
|
||||
print '<td colspan="2">';
|
||||
print ajax_constantonoff("TAKEPOS_TICKET_VAT_GROUPPED", array(), $conf->entity, 0, 0, 1, 0);
|
||||
//print $form->selectyesno("TAKEPOS_TICKET_VAT_GROUPPED", $conf->global->TAKEPOS_TICKET_VAT_GROUPPED, 1);
|
||||
print "</td></tr>\n";
|
||||
|
||||
// Sort product
|
||||
print '<tr class="oddeven"><td>';
|
||||
print $langs->trans("SortProductField");
|
||||
@ -429,14 +421,6 @@ print "</td></tr>\n";
|
||||
//print $form->selectarray('TAKEPOS_ADDON', $array, (empty($conf->global->TAKEPOS_ADDON) ? '0' : $conf->global->TAKEPOS_ADDON), 0);
|
||||
//print "</td></tr>\n";
|
||||
|
||||
print '<tr class="oddeven"><td>';
|
||||
print $langs->trans("EnableBarOrRestaurantFeatures");
|
||||
print '</td>';
|
||||
print '<td colspan="2">';
|
||||
print ajax_constantonoff("TAKEPOS_BAR_RESTAURANT", array(), $conf->entity, 0, 0, 1, 0);
|
||||
//print $form->selectyesno("TAKEPOS_BAR_RESTAURANT", $conf->global->TAKEPOS_BAR_RESTAURANT, 1);
|
||||
print "</td></tr>\n";
|
||||
|
||||
print '</table>';
|
||||
print '</div>';
|
||||
|
||||
|
||||
@ -398,6 +398,7 @@ if ($action == "deleteline") {
|
||||
$invoice->deleteline($deletelineid);
|
||||
$invoice->fetch($placeid);
|
||||
}
|
||||
if (count($invoice->lines)==0) $invoice->delete($user);
|
||||
}
|
||||
|
||||
if ($action == "delete") {
|
||||
|
||||
@ -77,7 +77,12 @@ if (!defined('ISLOADEDBYSTEELSHEET')) die('Must be call by steelsheet'); ?>
|
||||
text-align: center;
|
||||
font-size: 45px;
|
||||
line-height: 90px;
|
||||
background: rgba(0, 0, 0, 0.08) !important
|
||||
background: rgba(0, 0, 0, 0.08) !important;
|
||||
}
|
||||
|
||||
.info-box-module .info-box-icon {
|
||||
padding-top: 5px;
|
||||
padding-bottom: 5px;
|
||||
}
|
||||
.info-box-sm .info-box-icon {
|
||||
height: 80px;
|
||||
@ -436,7 +441,7 @@ if (GETPOSTISSET('THEME_SATURATE_RATIO')) $conf->global->THEME_SATURATE_RATIO =
|
||||
|
||||
|
||||
.info-box-module .info-box-content {
|
||||
height: 6.4em;
|
||||
height: 98px;
|
||||
}
|
||||
/* Disabled. This break the responsive on smartphone
|
||||
.box{
|
||||
|
||||
@ -71,7 +71,7 @@ $colortexttitle = '0,0,0';
|
||||
$colortexttitlelink = '10, 20, 100';
|
||||
$colortext = '0,0,0';
|
||||
$colortextlink = '10, 20, 100';
|
||||
$fontsize = '0.86em';
|
||||
$fontsize = '0.95em';
|
||||
$fontsizesmaller = '0.75em';
|
||||
$topMenuFontSize = '1.1em';
|
||||
$toolTipBgColor = 'rgba(255, 255, 255, 0.96)';
|
||||
|
||||
@ -90,9 +90,9 @@ if ($confirm == 'yes') {
|
||||
if ($action == 'confirm_delete') {
|
||||
$db->begin();
|
||||
|
||||
$res = $objectval->deleteByFkAttribute($object->id);
|
||||
$res = $objectval->deleteByFkAttribute($object->id, $user);
|
||||
|
||||
if ($res < 1 || ($object->delete() < 1)) {
|
||||
if ($res < 1 || ($object->delete($user) < 1)) {
|
||||
$db->rollback();
|
||||
setEventMessages($langs->trans('CoreErrorMessage'), $object->errors, 'errors');
|
||||
header('Location: '.dol_buildpath('/variants/card.php?id='.$object->id, 2));
|
||||
@ -105,7 +105,7 @@ if ($confirm == 'yes') {
|
||||
} elseif ($action == 'confirm_deletevalue')
|
||||
{
|
||||
if ($objectval->fetch($valueid) > 0) {
|
||||
if ($objectval->delete() < 1) {
|
||||
if ($objectval->delete($user) < 1) {
|
||||
setEventMessages($langs->trans('CoreErrorMessage'), $objectval->errors, 'errors');
|
||||
} else {
|
||||
setEventMessages($langs->trans('RecordSaved'), null, 'mesgs');
|
||||
|
||||
@ -16,17 +16,18 @@
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
require_once DOL_DOCUMENT_ROOT.'/core/class/commonobject.class.php';
|
||||
/**
|
||||
* Class ProductAttribute
|
||||
* Used to represent a product attribute
|
||||
*/
|
||||
class ProductAttribute
|
||||
class ProductAttribute extends CommonObject
|
||||
{
|
||||
/**
|
||||
* Database handler
|
||||
* @var DoliDB
|
||||
*/
|
||||
private $db;
|
||||
public $db;
|
||||
|
||||
/**
|
||||
* Id of the product attribute
|
||||
@ -119,7 +120,8 @@ class ProductAttribute
|
||||
|
||||
$return[] = $tmp;
|
||||
}
|
||||
} else dol_print_error($this->db);
|
||||
}
|
||||
else dol_print_error($this->db);
|
||||
|
||||
return $return;
|
||||
}
|
||||
@ -127,11 +129,21 @@ class ProductAttribute
|
||||
/**
|
||||
* Creates a product attribute
|
||||
*
|
||||
* @param User $user Object user that create
|
||||
* @param User $user Object user
|
||||
* @param int $notrigger Do not execute trigger
|
||||
* @return int <0 KO, Id of new variant if OK
|
||||
*/
|
||||
public function create(User $user)
|
||||
public function create(User $user, $notrigger = 0)
|
||||
{
|
||||
if (empty($notrigger)) {
|
||||
// Call trigger
|
||||
$result = $this->call_trigger('PRODUCT_ATTRIBUTE_CREATE', $user);
|
||||
if ($result < 0) {
|
||||
return -1;
|
||||
}
|
||||
// End call triggers
|
||||
}
|
||||
|
||||
//Ref must be uppercase
|
||||
$this->ref = strtoupper($this->ref);
|
||||
|
||||
@ -152,11 +164,21 @@ class ProductAttribute
|
||||
/**
|
||||
* Updates a product attribute
|
||||
*
|
||||
* @param User $user Object user
|
||||
* @param User $user Object user
|
||||
* @param int $notrigger Do not execute trigger
|
||||
* @return int <0 KO, >0 OK
|
||||
*/
|
||||
public function update(User $user)
|
||||
public function update(User $user, $notrigger = 0)
|
||||
{
|
||||
if (empty($notrigger)) {
|
||||
// Call trigger
|
||||
$result = $this->call_trigger('PRODUCT_ATTRIBUTE_MODIFY', $user);
|
||||
if ($result < 0) {
|
||||
return -1;
|
||||
}
|
||||
// End call triggers
|
||||
}
|
||||
|
||||
//Ref must be uppercase
|
||||
$this->ref = trim(strtoupper($this->ref));
|
||||
$this->label = trim($this->label);
|
||||
@ -173,11 +195,21 @@ class ProductAttribute
|
||||
/**
|
||||
* Deletes a product attribute
|
||||
*
|
||||
* @param User $user Object user
|
||||
* @return int <0 KO, >0 OK
|
||||
* @param User $user Object user
|
||||
* @param int $notrigger Do not execute trigger
|
||||
* @return int <0 KO, >0 OK
|
||||
*/
|
||||
public function delete($user = null)
|
||||
public function delete(User $user, $notrigger = 0)
|
||||
{
|
||||
if (empty($notrigger)) {
|
||||
// Call trigger
|
||||
$result = $this->call_trigger('PRODUCT_ATTRIBUTE_DELETE', $user);
|
||||
if ($result < 0) {
|
||||
return -1;
|
||||
}
|
||||
// End call triggers
|
||||
}
|
||||
|
||||
$sql = "DELETE FROM ".MAIN_DB_PREFIX."product_attribute WHERE rowid = ".(int) $this->id;
|
||||
|
||||
if ($this->db->query($sql)) {
|
||||
|
||||
@ -16,17 +16,18 @@
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
require_once DOL_DOCUMENT_ROOT.'/core/class/commonobject.class.php';
|
||||
/**
|
||||
* Class ProductAttributeValue
|
||||
* Used to represent a product attribute value
|
||||
*/
|
||||
class ProductAttributeValue
|
||||
class ProductAttributeValue extends CommonObject
|
||||
{
|
||||
/**
|
||||
* Database handler
|
||||
* @var DoliDB
|
||||
*/
|
||||
private $db;
|
||||
public $db;
|
||||
|
||||
/**
|
||||
* Attribute value id
|
||||
@ -144,10 +145,11 @@ class ProductAttributeValue
|
||||
/**
|
||||
* Creates a value for a product attribute
|
||||
*
|
||||
* @param User $user Object user
|
||||
* @return int <0 KO >0 OK
|
||||
* @param User $user Object user
|
||||
* @param int $notrigger Do not execute trigger
|
||||
* @return int <0 KO >0 OK
|
||||
*/
|
||||
public function create(User $user)
|
||||
public function create(User $user, $notrigger = 0)
|
||||
{
|
||||
if (!$this->fk_product_attribute) {
|
||||
return -1;
|
||||
@ -155,15 +157,25 @@ class ProductAttributeValue
|
||||
|
||||
// Ref must be uppercase
|
||||
$this->ref = strtoupper($this->ref);
|
||||
$this->value = $this->db->escape($this->value);
|
||||
|
||||
$sql = "INSERT INTO ".MAIN_DB_PREFIX."product_attribute_value (fk_product_attribute, ref, value, entity)
|
||||
VALUES ('".(int) $this->fk_product_attribute."', '".$this->db->escape($this->ref)."',
|
||||
'".$this->db->escape($this->value)."', ".(int) $this->entity.")";
|
||||
'".$this->value."', ".(int) $this->entity.")";
|
||||
|
||||
$query = $this->db->query($sql);
|
||||
|
||||
if ($query) {
|
||||
$this->id = $this->db->last_insert_id(MAIN_DB_PREFIX.'product_attribute_value');
|
||||
if (empty($notrigger)) {
|
||||
// Call trigger
|
||||
$result = $this->call_trigger('PRODUCT_ATTRIBUTE_VALUE_CREATE', $user);
|
||||
if ($result < 0) {
|
||||
return -1;
|
||||
}
|
||||
// End call triggers
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
@ -173,11 +185,21 @@ class ProductAttributeValue
|
||||
/**
|
||||
* Updates a product attribute value
|
||||
*
|
||||
* @param User $user Object user
|
||||
* @return int <0 if KO, >0 if OK
|
||||
* @param User $user Object user
|
||||
* @param int $notrigger Do not execute trigger
|
||||
* @return int <0 if KO, >0 if OK
|
||||
*/
|
||||
public function update(User $user)
|
||||
public function update(User $user, $notrigger = 0)
|
||||
{
|
||||
if (empty($notrigger)) {
|
||||
// Call trigger
|
||||
$result = $this->call_trigger('PRODUCT_ATTRIBUTE_VALUE_MODIFY', $user);
|
||||
if ($result < 0) {
|
||||
return -1;
|
||||
}
|
||||
// End call triggers
|
||||
}
|
||||
|
||||
//Ref must be uppercase
|
||||
$this->ref = trim(strtoupper($this->ref));
|
||||
$this->value = trim($this->value);
|
||||
@ -196,33 +218,62 @@ class ProductAttributeValue
|
||||
/**
|
||||
* Deletes a product attribute value
|
||||
*
|
||||
* @param User $user Object user
|
||||
* @param int $notrigger Do not execute trigger
|
||||
* @return int <0 KO, >0 OK
|
||||
*/
|
||||
public function delete()
|
||||
public function delete(User $user, $notrigger = 0)
|
||||
{
|
||||
$sql = "DELETE FROM ".MAIN_DB_PREFIX."product_attribute_value WHERE rowid = ".(int) $this->id;
|
||||
|
||||
if ($this->db->query($sql)) {
|
||||
return 1;
|
||||
}
|
||||
if (empty($notrigger)) {
|
||||
// Call trigger
|
||||
$result = $this->call_trigger('PRODUCT_ATTRIBUTE_VALUE_DELETE', $user);
|
||||
if ($result < 0) {
|
||||
return -1;
|
||||
}
|
||||
// End call triggers
|
||||
}
|
||||
$sql = "DELETE FROM ".MAIN_DB_PREFIX."product_attribute_value WHERE rowid = ".(int) $this->id;
|
||||
if ($this->db->query($sql)) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
return -1;
|
||||
return -1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Deletes all product attribute values by a product attribute id
|
||||
*
|
||||
* @param int $fk_attribute Product attribute id
|
||||
* @param int $fk_attribute Product attribute id
|
||||
* @param User $user Object user
|
||||
* @return int <0 KO, >0 OK
|
||||
*/
|
||||
public function deleteByFkAttribute($fk_attribute)
|
||||
public function deleteByFkAttribute($fk_attribute, User $user)
|
||||
{
|
||||
$sql = "DELETE FROM ".MAIN_DB_PREFIX."product_attribute_value WHERE fk_product_attribute = ".(int) $fk_attribute;
|
||||
$sql = "SELECT rowid FROM ".MAIN_DB_PREFIX."product_attribute_value WHERE fk_product_attribute = ".(int) $fk_attribute;
|
||||
|
||||
if ($this->db->query($sql)) {
|
||||
return 1;
|
||||
}
|
||||
$query = $this->db->query($sql);
|
||||
|
||||
return -1;
|
||||
if (!$query) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (!$this->db->num_rows($query)) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
while ($obj = $this->db->fetch_object($query)) {
|
||||
$tmp = new ProductAttributeValue($this->db);
|
||||
if ($tmp->fetch($obj->rowid) > 0) {
|
||||
$result = $tmp->delete($user);
|
||||
if ($result < 0) {
|
||||
return -1;
|
||||
}
|
||||
} else {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
@ -71,6 +71,12 @@ class ProductCombination
|
||||
*/
|
||||
public $entity;
|
||||
|
||||
/**
|
||||
* Combination price level
|
||||
* @var ProductCombinationLevel[]
|
||||
*/
|
||||
public $combination_price_levels;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
@ -92,6 +98,8 @@ class ProductCombination
|
||||
*/
|
||||
public function fetch($rowid)
|
||||
{
|
||||
global $conf;
|
||||
|
||||
$sql = "SELECT rowid, fk_product_parent, fk_product_child, variation_price, variation_price_percentage, variation_weight FROM ".MAIN_DB_PREFIX."product_attribute_combination WHERE rowid = ".(int) $rowid." AND entity IN (".getEntity('product').")";
|
||||
|
||||
$query = $this->db->query($sql);
|
||||
@ -113,9 +121,118 @@ class ProductCombination
|
||||
$this->variation_price_percentage = $obj->variation_price_percentage;
|
||||
$this->variation_weight = $obj->variation_weight;
|
||||
|
||||
if (!empty($conf->global->PRODUIT_MULTIPRICES)) {
|
||||
$this->fetchCombinationPriceLevels();
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Retrieves combination price levels
|
||||
*
|
||||
* @param int $fk_price_level the price level to fetch, use 0 for all
|
||||
* @param bool $useCache to use cache or not
|
||||
* @return int <0 KO, >0 OK
|
||||
*/
|
||||
public function fetchCombinationPriceLevels($fk_price_level = 0, $useCache = true)
|
||||
{
|
||||
global $conf;
|
||||
|
||||
// Check cache
|
||||
if (!empty($this->combination_price_levels) && $useCache){
|
||||
if ((!empty($fk_price_level) && isset($this->combination_price_levels[$fk_price_level])) || empty($fk_price_level)){
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
if (!is_array($this->combination_price_levels)
|
||||
|| empty($fk_price_level) // if fetch an unique level dont erase all already fetched
|
||||
){
|
||||
$this->combination_price_levels = array();
|
||||
}
|
||||
|
||||
$staticProductCombinationLevel = new ProductCombinationLevel($this->db);
|
||||
$combination_price_levels = $staticProductCombinationLevel->fetchAll($this->id, $fk_price_level);
|
||||
|
||||
if (!is_array($combination_price_levels)) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (empty($combination_price_levels)){
|
||||
|
||||
/**
|
||||
* for auto retrocompatibility with last behavior
|
||||
*/
|
||||
$productCombinationLevel = new ProductCombinationLevel($this->db);
|
||||
$productCombinationLevel->fk_price_level = intval($fk_price_level);
|
||||
$productCombinationLevel->fk_product_attribute_combination = $this->id;
|
||||
$productCombinationLevel->variation_price = $this->variation_price;
|
||||
$productCombinationLevel->variation_price_percentage = $this->variation_price_percentage;
|
||||
|
||||
if ($fk_price_level>0){
|
||||
$combination_price_levels[$fk_price_level] = $productCombinationLevel;
|
||||
}
|
||||
else {
|
||||
for ($i = 1; $i <= $conf->global->PRODUIT_MULTIPRICES_LIMIT; $i++){
|
||||
$combination_price_levels[$i] = $productCombinationLevel;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$this->combination_price_levels = $combination_price_levels;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves combination price levels
|
||||
*
|
||||
* @param int $clean levels off PRODUIT_MULTIPRICES_LIMIT
|
||||
* @return int <0 KO, >0 OK
|
||||
*/
|
||||
public function saveCombinationPriceLevels($clean = 1)
|
||||
{
|
||||
global $conf;
|
||||
|
||||
$errors = 0;
|
||||
|
||||
$staticProductCombinationLevel = new ProductCombinationLevel($this->db);
|
||||
|
||||
// Delete all
|
||||
if (empty($this->combination_price_levels)){
|
||||
return $staticProductCombinationLevel->deleteAllForCombination($this->id);
|
||||
}
|
||||
|
||||
// Clean not needed price levels
|
||||
if ($clean){
|
||||
$res = $staticProductCombinationLevel->clean($this->id);
|
||||
|
||||
if ($res<0){
|
||||
$this->errors[] = 'Fail to clean not needed price levels';
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
foreach ($this->combination_price_levels as $fk_price_level => $combination_price_level){
|
||||
$res = $combination_price_level->save();
|
||||
if ($res<1){
|
||||
$this->error = 'save combination price level '.$fk_price_level . ' '.$combination_price_level->error;
|
||||
$this->errors[] = $this->error;
|
||||
$errors ++;
|
||||
}
|
||||
}
|
||||
|
||||
if ($errors > 0){
|
||||
return $errors*-1;
|
||||
}
|
||||
else {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Retrieves a product combination by a child product row id
|
||||
*
|
||||
@ -124,6 +241,8 @@ class ProductCombination
|
||||
*/
|
||||
public function fetchByFkProductChild($fk_child)
|
||||
{
|
||||
global $conf;
|
||||
|
||||
$sql = "SELECT rowid, fk_product_parent, fk_product_child, variation_price, variation_price_percentage, variation_weight FROM ".MAIN_DB_PREFIX."product_attribute_combination WHERE fk_product_child = ".(int) $fk_child." AND entity IN (".getEntity('product').")";
|
||||
|
||||
$query = $this->db->query($sql);
|
||||
@ -145,6 +264,10 @@ class ProductCombination
|
||||
$this->variation_price_percentage = $result->variation_price_percentage;
|
||||
$this->variation_weight = $result->variation_weight;
|
||||
|
||||
if (!empty($conf->global->PRODUIT_MULTIPRICES)) {
|
||||
$this->fetchCombinationPriceLevels();
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
@ -156,6 +279,8 @@ class ProductCombination
|
||||
*/
|
||||
public function fetchAllByFkProductParent($fk_product_parent)
|
||||
{
|
||||
global $conf;
|
||||
|
||||
$sql = "SELECT rowid, fk_product_parent, fk_product_child, variation_price, variation_price_percentage, variation_weight FROM ".MAIN_DB_PREFIX."product_attribute_combination WHERE fk_product_parent = ".(int) $fk_product_parent." AND entity IN (".getEntity('product').")";
|
||||
|
||||
$query = $this->db->query($sql);
|
||||
@ -175,6 +300,10 @@ class ProductCombination
|
||||
$tmp->variation_price_percentage = $result->variation_price_percentage;
|
||||
$tmp->variation_weight = $result->variation_weight;
|
||||
|
||||
if (!empty($conf->global->PRODUIT_MULTIPRICES)) {
|
||||
$tmp->fetchCombinationPriceLevels();
|
||||
}
|
||||
|
||||
$return[] = $tmp;
|
||||
}
|
||||
|
||||
@ -209,6 +338,8 @@ class ProductCombination
|
||||
*/
|
||||
public function create($user)
|
||||
{
|
||||
global $conf;
|
||||
|
||||
$sql = "INSERT INTO ".MAIN_DB_PREFIX."product_attribute_combination
|
||||
(fk_product_parent, fk_product_child, variation_price, variation_price_percentage, variation_weight, entity)
|
||||
VALUES (".(int) $this->fk_product_parent.", ".(int) $this->fk_product_child.",
|
||||
@ -221,6 +352,13 @@ class ProductCombination
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (!empty($conf->global->PRODUIT_MULTIPRICES)) {
|
||||
$res = $this->saveCombinationPriceLevels();
|
||||
if ($res<0){
|
||||
return -2;
|
||||
}
|
||||
}
|
||||
|
||||
$this->id = $this->db->last_insert_id(MAIN_DB_PREFIX.'product_attribute_combination');
|
||||
|
||||
return 1;
|
||||
@ -234,6 +372,8 @@ class ProductCombination
|
||||
*/
|
||||
public function update(User $user)
|
||||
{
|
||||
global $conf;
|
||||
|
||||
$sql = "UPDATE ".MAIN_DB_PREFIX."product_attribute_combination
|
||||
SET fk_product_parent = ".(int) $this->fk_product_parent.", fk_product_child = ".(int) $this->fk_product_child.",
|
||||
variation_price = ".(float) $this->variation_price.", variation_price_percentage = ".(int) $this->variation_price_percentage.",
|
||||
@ -245,6 +385,14 @@ class ProductCombination
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
if (!empty($conf->global->PRODUIT_MULTIPRICES)) {
|
||||
$res = $this->saveCombinationPriceLevels();
|
||||
if ($res<0){
|
||||
return -2;
|
||||
}
|
||||
}
|
||||
|
||||
$parent = new Product($this->db);
|
||||
$parent->fetch($this->fk_product_parent);
|
||||
|
||||
@ -266,6 +414,12 @@ class ProductCombination
|
||||
$comb2val = new ProductCombination2ValuePair($this->db);
|
||||
$comb2val->deleteByFkCombination($this->id);
|
||||
|
||||
// remove combination price levels
|
||||
if (!$this->db->query("DELETE FROM ".MAIN_DB_PREFIX."product_attribute_combination_price_level WHERE fk_product_attribute_combination = ".(int) $this->id)) {
|
||||
$this->db->rollback();
|
||||
return -1;
|
||||
}
|
||||
|
||||
$sql = "DELETE FROM ".MAIN_DB_PREFIX."product_attribute_combination WHERE rowid = ".(int) $this->id;
|
||||
|
||||
if ($this->db->query($sql)) {
|
||||
@ -341,6 +495,7 @@ class ProductCombination
|
||||
$child->label = $parent->label.$varlabel;;
|
||||
}
|
||||
|
||||
|
||||
if ($child->update($child->id, $user) > 0) {
|
||||
$new_vat = $parent->tva_tx;
|
||||
$new_npr = $parent->tva_npr;
|
||||
@ -349,9 +504,12 @@ class ProductCombination
|
||||
if (!empty($conf->global->PRODUIT_MULTIPRICES)) {
|
||||
for ($i = 1; $i <= $conf->global->PRODUIT_MULTIPRICES_LIMIT; $i++)
|
||||
{
|
||||
if ($parent->multiprices[$i] != '') {
|
||||
if ($parent->multiprices[$i] != '' || isset($this->combination_price_levels[$i]->variation_price)) {
|
||||
$new_type = $parent->multiprices_base_type[$i];
|
||||
$new_min_price = $parent->multiprices_min[$i];
|
||||
$variation_price = doubleval(!isset($this->combination_price_levels[$i]->variation_price) ? $this->variation_price : $this->combination_price_levels[$i]->variation_price);
|
||||
$variation_price_percentage = doubleval(!isset($this->combination_price_levels[$i]->variation_price_percentage) ? $this->variation_price_percentage : $this->combination_price_levels[$i]->variation_price_percentage);
|
||||
|
||||
if ($parent->prices_by_qty_list[$i]) {
|
||||
$new_psq = 1;
|
||||
} else {
|
||||
@ -364,12 +522,12 @@ class ProductCombination
|
||||
$new_price = $parent->multiprices[$i];
|
||||
}
|
||||
|
||||
if ($this->variation_price_percentage) {
|
||||
if ($variation_price_percentage) {
|
||||
if ($new_price != 0) {
|
||||
$new_price *= 1 + ($this->variation_price / 100);
|
||||
$new_price *= 1 + ($variation_price / 100);
|
||||
}
|
||||
} else {
|
||||
$new_price += $this->variation_price;
|
||||
$new_price += $variation_price;
|
||||
}
|
||||
|
||||
$child->updatePrice($new_price, $new_type, $user, $new_vat, $new_min_price, $i, $new_npr, $new_psq);
|
||||
@ -508,7 +666,7 @@ WHERE c.fk_product_parent = ".(int) $productid." AND p.tosell = 1";
|
||||
* @param Product $product Parent product
|
||||
* @param array $combinations Attribute and value combinations.
|
||||
* @param array $variations Price and weight variations
|
||||
* @param bool $price_var_percent Is the price variation a relative variation?
|
||||
* @param bool|array $price_var_percent Is the price variation a relative variation?
|
||||
* @param bool|float $forced_pricevar If the price variation is forced
|
||||
* @param bool|float $forced_weightvar If the weight variation is forced
|
||||
* @param bool|string $forced_refvar If the reference is forced
|
||||
@ -523,6 +681,8 @@ WHERE c.fk_product_parent = ".(int) $productid." AND p.tosell = 1";
|
||||
|
||||
$db->begin();
|
||||
|
||||
$price_impact = array(1=>0); // init level price impact
|
||||
|
||||
$forced_refvar = trim($forced_refvar);
|
||||
|
||||
if (!empty($forced_refvar) && $forced_refvar != $product->ref) {
|
||||
@ -545,7 +705,12 @@ WHERE c.fk_product_parent = ".(int) $productid." AND p.tosell = 1";
|
||||
$weight_impact = (float) $forced_weightvar; // If false, return 0
|
||||
|
||||
//Final price impact
|
||||
$price_impact = (float) $forced_pricevar; // If false, return 0
|
||||
if (!is_array($forced_pricevar)){
|
||||
$price_impact[1] = (float) $forced_pricevar; // If false, return 0
|
||||
}
|
||||
else {
|
||||
$price_impact = $forced_pricevar;
|
||||
}
|
||||
|
||||
$newcomb = new ProductCombination($db);
|
||||
$existingCombination = $newcomb->fetchByProductCombination2ValuePairs($product->id, $combinations);
|
||||
@ -587,7 +752,15 @@ WHERE c.fk_product_parent = ".(int) $productid." AND p.tosell = 1";
|
||||
$weight_impact += (float) price2num($variations[$currcombattr][$currcombval]['weight']);
|
||||
}
|
||||
if ($forced_pricevar === false) {
|
||||
$price_impact += (float) price2num($variations[$currcombattr][$currcombval]['price']);
|
||||
$price_impact[1] += (float) price2num($variations[$currcombattr][$currcombval]['price']);
|
||||
|
||||
// Manage Price levels
|
||||
if ($conf->global->PRODUIT_MULTIPRICES){
|
||||
for ($i = 2; $i <= $conf->global->PRODUIT_MULTIPRICES_LIMIT; $i++)
|
||||
{
|
||||
$price_impact[$i] += (float) price2num($variations[$currcombattr][$currcombval]['price']);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ($forced_refvar === false) {
|
||||
@ -606,9 +779,27 @@ WHERE c.fk_product_parent = ".(int) $productid." AND p.tosell = 1";
|
||||
}
|
||||
|
||||
$newcomb->variation_price_percentage = $price_var_percent;
|
||||
$newcomb->variation_price = $price_impact;
|
||||
$newcomb->variation_price = $price_impact[1];
|
||||
$newcomb->variation_weight = $weight_impact;
|
||||
|
||||
// Init price level
|
||||
if ($conf->global->PRODUIT_MULTIPRICES){
|
||||
for ($i = 1; $i <= $conf->global->PRODUIT_MULTIPRICES_LIMIT; $i++){
|
||||
$productCombinationLevel = new ProductCombinationLevel($this->db);
|
||||
$productCombinationLevel->fk_product_attribute_combination = 0;
|
||||
$productCombinationLevel->fk_price_level = $i;
|
||||
$productCombinationLevel->variation_price = $price_impact[$i];
|
||||
|
||||
if (is_array($price_var_percent)){
|
||||
$productCombinationLevel->variation_price_percentage = !empty($price_var_percent[$i]) ? $price_var_percent[$i] : 0;
|
||||
}else {
|
||||
$productCombinationLevel->variation_price_percentage = $price_var_percent;
|
||||
}
|
||||
|
||||
$newcomb->combination_price_levels[$i] = $productCombinationLevel;
|
||||
}
|
||||
}
|
||||
|
||||
$newproduct->weight += $weight_impact;
|
||||
|
||||
// Now create the product
|
||||
@ -764,3 +955,260 @@ WHERE c.fk_product_parent = ".(int) $productid." AND p.tosell = 1";
|
||||
return $label;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Class ProductCombinationLevel
|
||||
* Used to represent a product combination Level
|
||||
*/
|
||||
class ProductCombinationLevel
|
||||
{
|
||||
/**
|
||||
* Database handler
|
||||
* @var DoliDB
|
||||
*/
|
||||
private $db;
|
||||
|
||||
/**
|
||||
* @var string Name of table without prefix where object is stored
|
||||
*/
|
||||
public $table_element = 'product_attribute_combination_price_level';
|
||||
|
||||
/**
|
||||
* Rowid of combination
|
||||
* @var int
|
||||
*/
|
||||
public $id;
|
||||
|
||||
/**
|
||||
* Rowid of parent product combination
|
||||
* @var int
|
||||
*/
|
||||
public $fk_product_attribute_combination;
|
||||
|
||||
/**
|
||||
* Combination price level
|
||||
* @var int
|
||||
*/
|
||||
public $fk_price_level;
|
||||
|
||||
/**
|
||||
* Price variation
|
||||
* @var float
|
||||
*/
|
||||
public $variation_price;
|
||||
|
||||
/**
|
||||
* Is the price variation a relative variation?
|
||||
* @var bool
|
||||
*/
|
||||
public $variation_price_percentage = false;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param DoliDB $db Database handler
|
||||
*/
|
||||
public function __construct(DoliDB $db)
|
||||
{
|
||||
$this->db = $db;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves a combination level by its rowid
|
||||
*
|
||||
* @param int $rowid Row id
|
||||
* @return int <0 KO, >0 OK
|
||||
*/
|
||||
public function fetch($rowid)
|
||||
{
|
||||
$sql = "SELECT rowid, fk_product_attribute_combination, fk_price_level, variation_price, variation_price_percentage FROM " . MAIN_DB_PREFIX . $this->table_element." WHERE rowid = " . (int) $rowid;
|
||||
|
||||
$obj = $this->db->getRow($sql);
|
||||
|
||||
if ($obj){
|
||||
return $this->fetchFormObj($obj);
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Retrieves combination price levels
|
||||
*
|
||||
* @param int $fk_product_attribute_combination
|
||||
* @param int $fk_price_level the price level to fetch, use 0 for all
|
||||
* @return self[] | -1 on KO
|
||||
*/
|
||||
public function fetchAll($fk_product_attribute_combination, $fk_price_level = 0)
|
||||
{
|
||||
|
||||
$sql = "SELECT rowid, fk_product_attribute_combination, fk_price_level, variation_price, variation_price_percentage"
|
||||
." FROM ".MAIN_DB_PREFIX.$this->table_element
|
||||
." WHERE fk_product_attribute_combination = ".intval($fk_product_attribute_combination);
|
||||
|
||||
if (!empty($fk_price_level)){
|
||||
$sql.= ' AND fk_price_level = '.intval($fk_price_level);
|
||||
}
|
||||
|
||||
$combination_price_levels = $this->db->getRows($sql);
|
||||
|
||||
if (!is_array($combination_price_levels)) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
$result = array();
|
||||
|
||||
if (!empty($combination_price_levels)) {
|
||||
// For more simple usage set level as array key
|
||||
foreach ($combination_price_levels as $k => $row){
|
||||
$productCombinationLevel = new ProductCombinationLevel($this->db);
|
||||
$productCombinationLevel->fetchFormObj($row);
|
||||
$result[$row->fk_price_level] = $productCombinationLevel;
|
||||
}
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* assign vars form an stdclass like sql obj
|
||||
*
|
||||
* @param int $rowid Row id
|
||||
* @return int <0 KO, >0 OK
|
||||
*/
|
||||
public function fetchFormObj($obj)
|
||||
{
|
||||
if (!$obj) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
$this->id = $obj->rowid;
|
||||
$this->fk_product_attribute_combination = doubleval($obj->fk_product_attribute_combination);
|
||||
$this->fk_price_level = intval($obj->fk_price_level);
|
||||
$this->variation_price = doubleval($obj->variation_price);
|
||||
$this->variation_price_percentage = (bool) $obj->variation_price_percentage;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* save
|
||||
*
|
||||
* @return int <0 KO, >0 OK
|
||||
*/
|
||||
public function save()
|
||||
{
|
||||
$errors = 0;
|
||||
|
||||
|
||||
if (empty($this->fk_product_attribute_combination) || empty($this->fk_price_level)){
|
||||
return -1;
|
||||
}
|
||||
|
||||
// check if level exist in DB before add
|
||||
if (empty($this->id)){
|
||||
$sql = "SELECT rowid id"
|
||||
." FROM ".MAIN_DB_PREFIX . $this->table_element
|
||||
." WHERE fk_product_attribute_combination = ".(int) $this->fk_product_attribute_combination
|
||||
.' AND fk_price_level = '.intval($this->fk_price_level);
|
||||
|
||||
$existObj = $this->db->getRow($sql);
|
||||
if ($existObj){
|
||||
$this->id = $existObj->id;
|
||||
}
|
||||
}
|
||||
|
||||
// Update
|
||||
if (!empty($this->id)) {
|
||||
$sql = 'UPDATE ' . MAIN_DB_PREFIX . $this->table_element . ' SET '
|
||||
. ' variation_price = '.doubleval($this->variation_price)
|
||||
. ' , variation_price_percentage = '.intval($this->variation_price_percentage)
|
||||
. ' WHERE rowid = '.intval($this->id);
|
||||
|
||||
$res = $this->db->query($sql);
|
||||
if ($res>0){
|
||||
return $this->id;
|
||||
}
|
||||
else {
|
||||
$this->error = $this->db->error();
|
||||
$this->errors[] = $this->error;
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
else {
|
||||
// ADD
|
||||
$sql = "INSERT INTO " . MAIN_DB_PREFIX . $this->table_element . " ("
|
||||
. " fk_product_attribute_combination, fk_price_level, variation_price, variation_price_percentage"
|
||||
. " ) VALUES ( "
|
||||
. intval($this->fk_product_attribute_combination)
|
||||
. ' , '.intval($this->fk_price_level)
|
||||
. ' , '.doubleval($this->variation_price)
|
||||
. ' , '.intval($this->variation_price_percentage)
|
||||
. " )";
|
||||
|
||||
$res = $this->db->query($sql);
|
||||
if ($res){
|
||||
$this->id = $this->db->last_insert_id(MAIN_DB_PREFIX . $this->table_element);
|
||||
}
|
||||
else {
|
||||
$this->error = $this->db->error();
|
||||
$this->errors[] = $this->error;
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
return $this->id;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* delete
|
||||
*
|
||||
* @return int <0 KO, >0 OK
|
||||
*/
|
||||
public function delete()
|
||||
{
|
||||
$res = $this->db->query("DELETE FROM ".MAIN_DB_PREFIX.$this->table_element
|
||||
." WHERE rowid = ".(int) $this->id);
|
||||
|
||||
return $res ? 1 : -1;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* delete all for a combination
|
||||
*
|
||||
* @param $fk_product_attribute_combination
|
||||
* @return int <0 KO, >0 OK
|
||||
*/
|
||||
public function deleteAllForCombination($fk_product_attribute_combination)
|
||||
{
|
||||
$res = $this->db->query("DELETE FROM ".MAIN_DB_PREFIX.$this->table_element
|
||||
." WHERE fk_product_attribute_combination = ".(int) $fk_product_attribute_combination);
|
||||
|
||||
return $res ? 1 : -1;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Clean not needed price levels for a combination
|
||||
*
|
||||
* @param $fk_product_attribute_combination
|
||||
* @return int <0 KO, >0 OK
|
||||
*/
|
||||
public function clean($fk_product_attribute_combination)
|
||||
{
|
||||
global $conf;
|
||||
|
||||
$res = $this->db->query("DELETE FROM ".MAIN_DB_PREFIX.$this->table_element
|
||||
. " WHERE fk_product_attribute_combination = ".(int) $fk_product_attribute_combination
|
||||
. " AND fk_price_level > ".intval($conf->global->PRODUIT_MULTIPRICES_LIMIT) );
|
||||
|
||||
|
||||
return $res ? 1 : -1;
|
||||
}
|
||||
}
|
||||
|
||||
@ -33,6 +33,10 @@ $ref = GETPOST('ref', 'alpha');
|
||||
$weight_impact = GETPOST('weight_impact', 'alpha');
|
||||
$price_impact = GETPOST('price_impact', 'alpha');
|
||||
$price_impact_percent = (bool) GETPOST('price_impact_percent');
|
||||
|
||||
$level_price_impact = GETPOST('level_price_impact', 'array');
|
||||
$level_price_impact_percent = GETPOST('level_price_impact_percent', 'array');
|
||||
|
||||
$reference = GETPOST('reference', 'alpha');
|
||||
$form = new Form($db);
|
||||
|
||||
@ -112,6 +116,18 @@ if ($_POST) {
|
||||
}
|
||||
$weight_impact = price2num($weight_impact);
|
||||
$price_impact = price2num($price_impact);
|
||||
|
||||
// for conf PRODUIT_MULTIPRICES
|
||||
if ($conf->global->PRODUIT_MULTIPRICES) {
|
||||
$level_price_impact = array_map('price2num', $level_price_impact);
|
||||
$level_price_impact_percent = array_map('price2num', $level_price_impact_percent);
|
||||
}
|
||||
else {
|
||||
$level_price_impact = array(1 => $weight_impact);
|
||||
$level_price_impact_percent = array(1 => $price_impact_percent);
|
||||
}
|
||||
|
||||
|
||||
$sanit_features = array();
|
||||
|
||||
//First, sanitize
|
||||
@ -141,11 +157,10 @@ if ($_POST) {
|
||||
// sanit_feature is an array with 1 (and only 1) value per attribute.
|
||||
// For example: Color->blue, Size->Small, Option->2
|
||||
//var_dump($sanit_features);
|
||||
//var_dump($productCombination2ValuePairs1); exit;
|
||||
|
||||
if (!$prodcomb->fetchByProductCombination2ValuePairs($id, $sanit_features))
|
||||
{
|
||||
$result = $prodcomb->createProductCombination($user, $object, $sanit_features, array(), $price_impact_percent, $price_impact, $weight_impact, $reference);
|
||||
$result = $prodcomb->createProductCombination($user, $object, $sanit_features, array(), $level_price_impact_percent, $level_price_impact, $weight_impact, $reference);
|
||||
if ($result > 0)
|
||||
{
|
||||
setEventMessages($langs->trans('RecordSaved'), null, 'mesgs');
|
||||
@ -227,6 +242,32 @@ if ($_POST) {
|
||||
$prodcomb->variation_price = $price_impact;
|
||||
$prodcomb->variation_weight = $weight_impact;
|
||||
|
||||
// for conf PRODUIT_MULTIPRICES
|
||||
if ($conf->global->PRODUIT_MULTIPRICES) {
|
||||
$level_price_impact = array_map('price2num', $level_price_impact);
|
||||
$level_price_impact_percent = array_map(function ($a) {
|
||||
return !empty($a);}, $level_price_impact_percent);
|
||||
|
||||
$prodcomb->variation_price = $level_price_impact[1];
|
||||
$prodcomb->variation_price_percentage = (bool) $level_price_impact_percent[1];
|
||||
}
|
||||
else {
|
||||
$level_price_impact = array(1 => $weight_impact);
|
||||
$level_price_impact_percent = array(1 => $price_impact_percent);
|
||||
}
|
||||
|
||||
if ($conf->global->PRODUIT_MULTIPRICES){
|
||||
$prodcomb->combination_price_levels = array();
|
||||
for ($i = 1; $i <= $conf->global->PRODUIT_MULTIPRICES_LIMIT; $i++){
|
||||
$productCombinationLevel = new ProductCombinationLevel($db);
|
||||
$productCombinationLevel->fk_product_attribute_combination = $prodcomb->id;
|
||||
$productCombinationLevel->fk_price_level = $i;
|
||||
$productCombinationLevel->variation_price = $level_price_impact[$i];
|
||||
$productCombinationLevel->variation_price_percentage = $level_price_impact_percent[$i];
|
||||
$prodcomb->combination_price_levels[$i] = $productCombinationLevel;
|
||||
}
|
||||
}
|
||||
|
||||
if ($prodcomb->update($user) > 0) {
|
||||
setEventMessages($langs->trans('RecordSaved'), null, 'mesgs');
|
||||
header('Location: '.dol_buildpath('/variants/combinations.php?id='.$id, 2));
|
||||
@ -594,12 +635,33 @@ if (!empty($id) || !empty($ref))
|
||||
<td><label for="reference"><?php echo $langs->trans('Reference') ?></label></td>
|
||||
<td><input type="text" id="reference" name="reference" value="<?php echo trim($reference) ?>"></td>
|
||||
</tr>
|
||||
<?php if (empty($conf->global->PRODUIT_MULTIPRICES)){ ?>
|
||||
<tr>
|
||||
<td><label for="price_impact"><?php echo $langs->trans('PriceImpact') ?></label></td>
|
||||
<td><input type="text" id="price_impact" name="price_impact" value="<?php echo price($price_impact) ?>">
|
||||
<input type="checkbox" id="price_impact_percent" name="price_impact_percent" <?php echo $price_impact_percent ? ' checked' : '' ?>> <label for="price_impact_percent"><?php echo $langs->trans('PercentageVariation') ?></label></td>
|
||||
<input type="checkbox" id="price_impact_percent" name="price_impact_percent" <?php echo $price_impact_percent ? ' checked' : '' ?>> <label for="price_impact_percent"><?php echo $langs->trans('PercentageVariation') ?></label>
|
||||
</td>
|
||||
</tr>
|
||||
<?php
|
||||
<?php }
|
||||
else {
|
||||
$prodcomb->fetchCombinationPriceLevels();
|
||||
|
||||
for ($i = 1; $i <= $conf->global->PRODUIT_MULTIPRICES_LIMIT; $i++)
|
||||
{
|
||||
print '<tr>';
|
||||
print '<td><label for="level_price_impact_'.$i.'">'.$langs->trans('ImpactOnPriceLevel', $i).'</label>';
|
||||
if ($i===1){
|
||||
print ' <a id="apply-price-impact-to-all-level" class="classfortooltip" href="#" title="'.$langs->trans('ApplyToAllPriceImpactLevelHelp').'">('.$langs->trans('ApplyToAllPriceImpactLevel').')</a>';
|
||||
}
|
||||
print '</td>';
|
||||
print '<td><input type="text" class="level_price_impact" id="level_price_impact_'.$i.'" name="level_price_impact['.$i.']" value="'.price($prodcomb->combination_price_levels[$i]->variation_price).'">';
|
||||
print '<input type="checkbox" class="level_price_impact_percent" id="level_price_impact_percent_'.$i.'" name="level_price_impact_percent['.$i.']" '. (!empty($prodcomb->combination_price_levels[$i]->variation_price_percentage) ? ' checked' : '' ).'> <label for="level_price_impact_percent_'.$i.'">'.$langs->trans('PercentageVariation').'</label>';
|
||||
|
||||
print '</td>';
|
||||
print '</tr>';
|
||||
}
|
||||
}
|
||||
|
||||
if ($object->isProduct()) {
|
||||
print '<tr>';
|
||||
print '<td><label for="weight_impact">'.$langs->trans('WeightImpact').'</label></td>';
|
||||
@ -609,9 +671,30 @@ if (!empty($id) || !empty($ref))
|
||||
print '</table>';
|
||||
}
|
||||
|
||||
dol_fiche_end();
|
||||
?>
|
||||
if (!empty($conf->global->PRODUIT_MULTIPRICES)){
|
||||
?>
|
||||
<script>
|
||||
$(document).ready(function() {
|
||||
// Apply level 1 impact to all prices impact levels
|
||||
$('body').on('click', '#apply-price-impact-to-all-level', function(e) {
|
||||
e.preventDefault();
|
||||
let priceImpact = $( "#level_price_impact_1" ).val();
|
||||
let priceImpactPrecent = $( "#level_price_impact_percent_1" ).prop("checked");
|
||||
|
||||
var multipricelimit = <?php print intval($conf->global->PRODUIT_MULTIPRICES_LIMIT); ?>
|
||||
|
||||
for (let i = 2; i <= multipricelimit; i++) {
|
||||
$( "#level_price_impact_" + i ).val(priceImpact);
|
||||
$( "#level_price_impact_percent_" + i ).prop("checked", priceImpactPrecent);
|
||||
}
|
||||
});
|
||||
});
|
||||
</script>
|
||||
<?php
|
||||
}
|
||||
|
||||
dol_fiche_end();
|
||||
?>
|
||||
<div style="text-align: center">
|
||||
<input type="submit" name="create" <?php if (!is_array($productCombination2ValuePairs1)) print ' disabled="disabled"'; ?> value="<?php echo $action == 'add' ? $langs->trans('Create') : $langs->trans('Save') ?>" class="button">
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user