* * Stundenzettel - Business Object Klasse */ require_once DOL_DOCUMENT_ROOT.'/core/class/commonobject.class.php'; /** * Class Stundenzettel */ class Stundenzettel extends CommonObject { /** * @var string ID to identify managed object */ public $element = 'stundenzettel'; /** * @var string Name of table without prefix */ public $table_element = 'stundenzettel'; /** * @var string Picto */ public $picto = 'clock'; // Status constants const STATUS_DRAFT = 0; const STATUS_VALIDATED = 1; const STATUS_INVOICED = 2; const STATUS_CANCELED = 9; /** * @var string Ref */ public $ref; /** * @var int Auftrag ID */ public $fk_commande; /** * @var int Rechnung ID (nach Übertrag) */ public $fk_facture; /** * @var int Kunde ID */ public $fk_soc; /** * @var int Ersteller */ public $fk_user_author; /** * @var int Freigebender User */ public $fk_user_valid; /** * @var int|string Datum des Stundenzettels */ public $date_stundenzettel; /** * @var int|string Erstelldatum */ public $datec; /** * @var int|string Freigabedatum */ public $date_valid; /** * @var int Status */ public $status; /** * @var string Private Notizen */ public $note_private; /** * @var string Öffentliche Notizen */ public $note_public; /** * @var array Leistungen */ public $leistungen = array(); /** * @var array Produkte */ public $products = array(); /** * @var array Notizen (abhakbare Merkzettel) */ public $notes = array(); /** * Constructor * * @param DoliDB $db Database handler */ public function __construct($db) { $this->db = $db; } /** * Create object into database * * @param User $user User that creates * @param bool $notrigger false=launch triggers after, true=disable triggers * @return int <0 if KO, Id of created object if OK */ public function create($user, $notrigger = false) { global $conf; $error = 0; // Generate ref if (empty($this->ref)) { $this->ref = $this->getNextNumRef(); } $this->db->begin(); $sql = "INSERT INTO ".MAIN_DB_PREFIX.$this->table_element." ("; $sql .= "ref, entity, fk_commande, fk_soc, fk_user_author,"; $sql .= "date_stundenzettel, datec, status, note_private, note_public"; $sql .= ") VALUES ("; $sql .= "'".$this->db->escape($this->ref)."',"; $sql .= ((int)$conf->entity).","; $sql .= ((int)$this->fk_commande).","; $sql .= ((int)$this->fk_soc).","; $sql .= ((int)$user->id).","; $sql .= "'".$this->db->idate($this->date_stundenzettel)."',"; $sql .= "'".$this->db->idate(dol_now())."',"; $sql .= "0,"; // STATUS_DRAFT $sql .= ($this->note_private ? "'".$this->db->escape($this->note_private)."'" : "NULL").","; $sql .= ($this->note_public ? "'".$this->db->escape($this->note_public)."'" : "NULL"); $sql .= ")"; dol_syslog(get_class($this)."::create", LOG_DEBUG); $resql = $this->db->query($sql); if (!$resql) { $error++; $this->errors[] = "Error ".$this->db->lasterror(); } if (!$error) { $this->id = $this->db->last_insert_id(MAIN_DB_PREFIX.$this->table_element); } if (!$error) { $this->db->commit(); return $this->id; } else { $this->db->rollback(); return -1; } } /** * Load object in memory from the database * * @param int $id Id object * @param string $ref Ref * @return int <0 if KO, 0 if not found, >0 if OK */ public function fetch($id, $ref = null) { $sql = "SELECT s.rowid, s.ref, s.entity, s.fk_commande, s.fk_facture, s.fk_soc,"; $sql .= " s.fk_user_author, s.fk_user_valid, s.date_stundenzettel, s.datec,"; $sql .= " s.date_valid, s.status, s.note_private, s.note_public, s.tms"; $sql .= " FROM ".MAIN_DB_PREFIX.$this->table_element." as s"; if ($ref) { $sql .= " WHERE s.ref = '".$this->db->escape($ref)."'"; } else { $sql .= " WHERE s.rowid = ".((int)$id); } dol_syslog(get_class($this)."::fetch", LOG_DEBUG); $resql = $this->db->query($sql); if ($resql) { if ($this->db->num_rows($resql)) { $obj = $this->db->fetch_object($resql); $this->id = $obj->rowid; $this->ref = $obj->ref; $this->entity = $obj->entity; $this->fk_commande = $obj->fk_commande; $this->fk_facture = $obj->fk_facture; $this->fk_soc = $obj->fk_soc; $this->fk_user_author = $obj->fk_user_author; $this->fk_user_valid = $obj->fk_user_valid; $this->date_stundenzettel = $this->db->jdate($obj->date_stundenzettel); $this->datec = $this->db->jdate($obj->datec); $this->date_valid = $this->db->jdate($obj->date_valid); $this->status = $obj->status; $this->note_private = $obj->note_private; $this->note_public = $obj->note_public; // Load lines $this->fetchLeistungen(); $this->fetchProducts(); $this->fetchNotes(); return 1; } else { return 0; } } else { $this->error = "Error ".$this->db->lasterror(); return -1; } } /** * Update object into database * * @param User $user User that modifies * @param bool $notrigger false=launch triggers after, true=disable triggers * @return int <0 if KO, >0 if OK */ public function update($user, $notrigger = false) { $error = 0; $sql = "UPDATE ".MAIN_DB_PREFIX.$this->table_element." SET"; $sql .= " date_stundenzettel = '".$this->db->idate($this->date_stundenzettel)."',"; $sql .= " note_private = ".($this->note_private ? "'".$this->db->escape($this->note_private)."'" : "NULL").","; $sql .= " note_public = ".($this->note_public ? "'".$this->db->escape($this->note_public)."'" : "NULL"); $sql .= " WHERE rowid = ".((int)$this->id); dol_syslog(get_class($this)."::update", LOG_DEBUG); $resql = $this->db->query($sql); if (!$resql) { $error++; $this->errors[] = "Error ".$this->db->lasterror(); } if (!$error) { return 1; } else { return -1; } } /** * Validate object * * @param User $user User that validates * @return int <0 if KO, >0 if OK */ public function validate($user) { $error = 0; $this->db->begin(); $sql = "UPDATE ".MAIN_DB_PREFIX.$this->table_element." SET"; $sql .= " status = ".self::STATUS_VALIDATED.","; $sql .= " fk_user_valid = ".((int)$user->id).","; $sql .= " date_valid = '".$this->db->idate(dol_now())."'"; $sql .= " WHERE rowid = ".((int)$this->id); dol_syslog(get_class($this)."::validate", LOG_DEBUG); $resql = $this->db->query($sql); if (!$resql) { $error++; $this->errors[] = "Error ".$this->db->lasterror(); } if (!$error) { $this->status = self::STATUS_VALIDATED; $this->fk_user_valid = $user->id; $this->date_valid = dol_now(); // Update tracking table $this->updateTracking(); $this->db->commit(); return 1; } else { $this->db->rollback(); return -1; } } /** * Set to draft * * @param User $user User that reopens * @return int <0 if KO, >0 if OK */ public function setDraft($user) { $sql = "UPDATE ".MAIN_DB_PREFIX.$this->table_element." SET"; $sql .= " status = ".self::STATUS_DRAFT.","; $sql .= " fk_user_valid = NULL,"; $sql .= " date_valid = NULL"; $sql .= " WHERE rowid = ".((int)$this->id); dol_syslog(get_class($this)."::setDraft", LOG_DEBUG); $resql = $this->db->query($sql); if ($resql) { $this->status = self::STATUS_DRAFT; return 1; } else { $this->error = "Error ".$this->db->lasterror(); return -1; } } /** * Delete object in database * * @param User $user User that deletes * @param bool $notrigger false=launch triggers after, true=disable triggers * @return int <0 if KO, >0 if OK */ public function delete($user, $notrigger = false) { $error = 0; $this->db->begin(); // Delete notes $sql = "DELETE FROM ".MAIN_DB_PREFIX."stundenzettel_note WHERE fk_stundenzettel = ".((int)$this->id); $resql = $this->db->query($sql); if (!$resql) $error++; // Delete leistungen $sql = "DELETE FROM ".MAIN_DB_PREFIX."stundenzettel_leistung WHERE fk_stundenzettel = ".((int)$this->id); $resql = $this->db->query($sql); if (!$resql) $error++; // Delete products $sql = "DELETE FROM ".MAIN_DB_PREFIX."stundenzettel_product WHERE fk_stundenzettel = ".((int)$this->id); $resql = $this->db->query($sql); if (!$resql) $error++; // Delete main record if (!$error) { $sql = "DELETE FROM ".MAIN_DB_PREFIX.$this->table_element." WHERE rowid = ".((int)$this->id); $resql = $this->db->query($sql); if (!$resql) $error++; } if (!$error) { $this->db->commit(); return 1; } else { $this->db->rollback(); return -1; } } /** * Load leistungen * * @return int <0 if KO, number of lines if OK */ public function fetchLeistungen() { $this->leistungen = array(); $sql = "SELECT rowid, fk_user, date_leistung, time_start, time_end, duration, description, rang"; $sql .= " FROM ".MAIN_DB_PREFIX."stundenzettel_leistung"; $sql .= " WHERE fk_stundenzettel = ".((int)$this->id); $sql .= " ORDER BY rang, date_leistung, time_start"; $resql = $this->db->query($sql); if ($resql) { while ($obj = $this->db->fetch_object($resql)) { $this->leistungen[] = $obj; } return count($this->leistungen); } return -1; } /** * Load products * * @return int <0 if KO, number of lines if OK */ public function fetchProducts() { $this->products = array(); // Produkte laden, bei Freitext-Produkten Beschreibung aus commandedet holen falls leer $sql = "SELECT sp.rowid, sp.fk_product, sp.fk_commandedet, sp.fk_manager_line,"; $sql .= " sp.product_ref, sp.product_label,"; $sql .= " CASE WHEN sp.description IS NULL OR sp.description = '' THEN cd.description ELSE sp.description END as description,"; $sql .= " sp.qty_original, sp.qty_done, sp.qty_cumulated, sp.origin, sp.rang"; $sql .= " FROM ".MAIN_DB_PREFIX."stundenzettel_product as sp"; $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."commandedet as cd ON cd.rowid = sp.fk_commandedet"; $sql .= " WHERE sp.fk_stundenzettel = ".((int)$this->id); $sql .= " ORDER BY sp.rang"; $resql = $this->db->query($sql); if ($resql) { while ($obj = $this->db->fetch_object($resql)) { $this->products[] = $obj; } return count($this->products); } return -1; } /** * Add a leistung * * @param User $user User * @param string $date Date * @param string $time_start Start time * @param string $time_end End time * @param string $description Description * @return int <0 if KO, >0 if OK */ public function addLeistung($user, $date, $time_start = null, $time_end = null, $description = '') { global $langs; // Calculate duration $duration = 0; if ($time_start && $time_end) { $start = strtotime($time_start); $end = strtotime($time_end); $duration = ($end - $start) / 60; // in minutes } // Überlappungsprüfung: Prüfen ob für diese Zeit bereits eine Leistung existiert if ($time_start && $time_end) { $sqlCheck = "SELECT rowid, time_start, time_end FROM ".MAIN_DB_PREFIX."stundenzettel_leistung"; $sqlCheck .= " WHERE fk_stundenzettel = ".((int)$this->id); $sqlCheck .= " AND time_start IS NOT NULL AND time_end IS NOT NULL"; $resqlCheck = $this->db->query($sqlCheck); if ($resqlCheck) { $newStart = strtotime($time_start); $newEnd = strtotime($time_end); while ($objCheck = $this->db->fetch_object($resqlCheck)) { $existStart = strtotime($objCheck->time_start); $existEnd = strtotime($objCheck->time_end); // Überlappung: Start1 < End2 UND Start2 < End1 if ($newStart < $existEnd && $existStart < $newEnd) { $this->error = $langs->trans("ErrorTimeOverlap", $objCheck->time_start, $objCheck->time_end); return -2; } } } } // Get next rang $sql = "SELECT MAX(rang) as maxrang FROM ".MAIN_DB_PREFIX."stundenzettel_leistung WHERE fk_stundenzettel = ".((int)$this->id); $resql = $this->db->query($sql); $rang = 0; if ($resql) { $obj = $this->db->fetch_object($resql); $rang = $obj->maxrang + 1; } $sql = "INSERT INTO ".MAIN_DB_PREFIX."stundenzettel_leistung ("; $sql .= "fk_stundenzettel, fk_user, date_leistung, time_start, time_end, duration, description, rang"; $sql .= ") VALUES ("; $sql .= ((int)$this->id).","; $sql .= ((int)$user->id).","; $sql .= "'".$this->db->idate($date)."',"; $sql .= ($time_start ? "'".$this->db->escape($time_start)."'" : "NULL").","; $sql .= ($time_end ? "'".$this->db->escape($time_end)."'" : "NULL").","; $sql .= ((int)$duration).","; $sql .= "'".$this->db->escape($description)."',"; $sql .= ((int)$rang); $sql .= ")"; $resql = $this->db->query($sql); if ($resql) { return $this->db->last_insert_id(MAIN_DB_PREFIX."stundenzettel_leistung"); } return -1; } /** * Update a leistung * * @param int $leistung_id Leistung ID * @param string $date Date * @param string $time_start Start time * @param string $time_end End time * @param string $description Description * @return int <0 if KO, >0 if OK */ public function updateLeistung($leistung_id, $date, $time_start = null, $time_end = null, $description = '') { global $langs; // Calculate duration $duration = 0; if ($time_start && $time_end) { $start = strtotime($time_start); $end = strtotime($time_end); $duration = ($end - $start) / 60; // in minutes } // Überlappungsprüfung: Prüfen ob für diese Zeit bereits eine andere Leistung existiert if ($time_start && $time_end) { $sqlCheck = "SELECT rowid, time_start, time_end FROM ".MAIN_DB_PREFIX."stundenzettel_leistung"; $sqlCheck .= " WHERE fk_stundenzettel = ".((int)$this->id); $sqlCheck .= " AND rowid != ".((int)$leistung_id); // Aktuelle Leistung ausschließen $sqlCheck .= " AND time_start IS NOT NULL AND time_end IS NOT NULL"; $resqlCheck = $this->db->query($sqlCheck); if ($resqlCheck) { $newStart = strtotime($time_start); $newEnd = strtotime($time_end); while ($objCheck = $this->db->fetch_object($resqlCheck)) { $existStart = strtotime($objCheck->time_start); $existEnd = strtotime($objCheck->time_end); // Überlappung: Start1 < End2 UND Start2 < End1 if ($newStart < $existEnd && $existStart < $newEnd) { $this->error = $langs->trans("ErrorTimeOverlap", $objCheck->time_start, $objCheck->time_end); return -2; } } } } $sql = "UPDATE ".MAIN_DB_PREFIX."stundenzettel_leistung SET"; $sql .= " date_leistung = '".$this->db->idate($date)."',"; $sql .= " time_start = ".($time_start ? "'".$this->db->escape($time_start)."'" : "NULL").","; $sql .= " time_end = ".($time_end ? "'".$this->db->escape($time_end)."'" : "NULL").","; $sql .= " duration = ".((int)$duration).","; $sql .= " description = '".$this->db->escape($description)."'"; $sql .= " WHERE rowid = ".((int)$leistung_id); $sql .= " AND fk_stundenzettel = ".((int)$this->id); $resql = $this->db->query($sql); if ($resql) { return 1; } $this->error = $this->db->lasterror(); return -1; } /** * Delete a leistung * * @param int $leistung_id Leistung ID * @return int <0 if KO, >0 if OK */ public function deleteLeistung($leistung_id) { $sql = "DELETE FROM ".MAIN_DB_PREFIX."stundenzettel_leistung"; $sql .= " WHERE rowid = ".((int)$leistung_id); $sql .= " AND fk_stundenzettel = ".((int)$this->id); $resql = $this->db->query($sql); if ($resql) { return 1; } $this->error = $this->db->lasterror(); return -1; } /** * Add a product * * @param int $fk_product Product ID * @param int $fk_commandedet Commandedet ID * @param int $fk_manager_line Manager line ID * @param float $qty_original Original qty * @param float $qty_done Done qty * @param string $origin Origin (order or added) * @param string $description Description (for free-text products) * @return int <0 if KO, >0 if OK */ public function addProduct($fk_product, $fk_commandedet = null, $fk_manager_line = null, $qty_original = 0, $qty_done = 0, $origin = 'order', $description = '') { global $db; // Get product info $product_ref = ''; $product_label = ''; if ($fk_product > 0) { require_once DOL_DOCUMENT_ROOT.'/product/class/product.class.php'; $prod = new Product($this->db); if ($prod->fetch($fk_product) > 0) { $product_ref = $prod->ref; $product_label = $prod->label; } } // Get next rang $sql = "SELECT MAX(rang) as maxrang FROM ".MAIN_DB_PREFIX."stundenzettel_product WHERE fk_stundenzettel = ".((int)$this->id); $resql = $this->db->query($sql); $rang = 0; if ($resql) { $obj = $this->db->fetch_object($resql); $rang = $obj->maxrang + 1; } $sql = "INSERT INTO ".MAIN_DB_PREFIX."stundenzettel_product ("; $sql .= "fk_stundenzettel, fk_product, fk_commandedet, fk_manager_line,"; $sql .= "product_ref, product_label, description, qty_original, qty_done, origin, rang"; $sql .= ") VALUES ("; $sql .= ((int)$this->id).","; $sql .= ($fk_product > 0 ? (int)$fk_product : "NULL").","; $sql .= ($fk_commandedet > 0 ? (int)$fk_commandedet : "NULL").","; $sql .= ($fk_manager_line > 0 ? (int)$fk_manager_line : "NULL").","; $sql .= "'".$this->db->escape($product_ref)."',"; $sql .= "'".$this->db->escape($product_label)."',"; $sql .= "'".$this->db->escape($description)."',"; $sql .= ((float)$qty_original).","; $sql .= ((float)$qty_done).","; $sql .= "'".$this->db->escape($origin)."',"; $sql .= ((int)$rang); $sql .= ")"; $resql = $this->db->query($sql); if ($resql) { return $this->db->last_insert_id(MAIN_DB_PREFIX."stundenzettel_product"); } return -1; } /** * Update product qty_done * * @param int $line_id Line ID * @param float $qty_done Done qty * @return int <0 if KO, >0 if OK */ public function updateProductQty($line_id, $qty_done) { $sql = "UPDATE ".MAIN_DB_PREFIX."stundenzettel_product SET"; $sql .= " qty_done = ".((float)$qty_done); $sql .= " WHERE rowid = ".((int)$line_id); $sql .= " AND fk_stundenzettel = ".((int)$this->id); $resql = $this->db->query($sql); return $resql ? 1 : -1; } /** * Delete product from stundenzettel * * @param int $line_id Line ID * @return int <0 if KO, >0 if OK */ public function deleteProduct($line_id) { $sql = "DELETE FROM ".MAIN_DB_PREFIX."stundenzettel_product"; $sql .= " WHERE rowid = ".((int)$line_id); $sql .= " AND fk_stundenzettel = ".((int)$this->id); $resql = $this->db->query($sql); return $resql ? 1 : -1; } /** * Update tracking table * * @return int <0 if KO, >0 if OK */ public function updateTracking() { // Sum up all products for this order across all stundenzettels foreach ($this->products as $prod) { if (!$prod->fk_commandedet) continue; // Get total done qty for this commandedet $sql = "SELECT SUM(qty_done) as total_done FROM ".MAIN_DB_PREFIX."stundenzettel_product sp"; $sql .= " JOIN ".MAIN_DB_PREFIX."stundenzettel s ON s.rowid = sp.fk_stundenzettel"; $sql .= " WHERE sp.fk_commandedet = ".((int)$prod->fk_commandedet); $sql .= " AND s.status >= ".self::STATUS_VALIDATED; $resql = $this->db->query($sql); $total_done = 0; if ($resql && ($obj = $this->db->fetch_object($resql))) { $total_done = $obj->total_done; } // Update or insert tracking $sql = "SELECT rowid FROM ".MAIN_DB_PREFIX."stundenzettel_tracking"; $sql .= " WHERE fk_commande = ".((int)$this->fk_commande); $sql .= " AND fk_commandedet = ".((int)$prod->fk_commandedet); $resql = $this->db->query($sql); if ($resql && $this->db->num_rows($resql) > 0) { // Update $obj = $this->db->fetch_object($resql); $remaining = $prod->qty_original - $total_done; $status = 'open'; if ($total_done >= $prod->qty_original) { $status = 'done'; } elseif ($total_done > 0) { $status = 'partial'; } $sql = "UPDATE ".MAIN_DB_PREFIX."stundenzettel_tracking SET"; $sql .= " qty_delivered = ".((float)$total_done).","; $sql .= " qty_remaining = ".((float)$remaining).","; $sql .= " status = '".$this->db->escape($status)."'"; $sql .= " WHERE rowid = ".((int)$obj->rowid); $this->db->query($sql); } else { // Insert $sql = "INSERT INTO ".MAIN_DB_PREFIX."stundenzettel_tracking ("; $sql .= "fk_commande, fk_product, fk_commandedet, fk_manager_line,"; $sql .= "product_ref, product_label, qty_ordered, qty_delivered, qty_remaining, status"; $sql .= ") VALUES ("; $sql .= ((int)$this->fk_commande).","; $sql .= ($prod->fk_product > 0 ? (int)$prod->fk_product : "NULL").","; $sql .= ((int)$prod->fk_commandedet).","; $sql .= ($prod->fk_manager_line > 0 ? (int)$prod->fk_manager_line : "NULL").","; $sql .= "'".$this->db->escape($prod->product_ref)."',"; $sql .= "'".$this->db->escape($prod->product_label)."',"; $sql .= ((float)$prod->qty_original).","; $sql .= ((float)$total_done).","; $sql .= ((float)($prod->qty_original - $total_done)).","; $sql .= "'open'"; $sql .= ")"; $this->db->query($sql); } } return 1; } /** * Get next reference number * * @return string Next ref */ public function getNextNumRef() { global $conf; $prefix = 'SZ'; $year = date('Y'); $sql = "SELECT MAX(CAST(SUBSTRING(ref, ".(strlen($prefix.$year.'-') + 1).") AS UNSIGNED)) as maxnum"; $sql .= " FROM ".MAIN_DB_PREFIX.$this->table_element; $sql .= " WHERE ref LIKE '".$this->db->escape($prefix.$year)."-%'"; $sql .= " AND entity = ".((int)$conf->entity); $resql = $this->db->query($sql); if ($resql) { $obj = $this->db->fetch_object($resql); $num = $obj->maxnum + 1; } else { $num = 1; } return $prefix.$year.'-'.sprintf('%05d', $num); } /** * Get status label * * @param int $mode 0=long label, 1=short label, 2=Picto + short label, 3=Picto, 4=Picto + long label, 5=Short label + Picto * @return string Label */ public function getLibStatut($mode = 0) { return $this->LibStatut($this->status, $mode); } /** * Return label of status * * @param int $status Status * @param int $mode Mode * @return string Label */ public function LibStatut($status, $mode = 0) { global $langs; $langs->load("stundenzettel@stundenzettel"); if ($status == self::STATUS_DRAFT) { $statusType = 'status0'; $label = $langs->trans("StatusDraft"); } elseif ($status == self::STATUS_VALIDATED) { $statusType = 'status4'; $label = $langs->trans("StatusValidated"); } elseif ($status == self::STATUS_INVOICED) { $statusType = 'status6'; $label = $langs->trans("StatusInvoiced"); } elseif ($status == self::STATUS_CANCELED) { $statusType = 'status9'; $label = $langs->trans("StatusCanceled"); } return dolGetStatus($label, '', '', $statusType, $mode); } /** * Return URL link * * @param int $withpicto Picto * @param string $option Option * @return string Link */ public function getNomUrl($withpicto = 0, $option = '') { $result = ''; $url = dol_buildpath('/stundenzettel/card.php?id='.$this->id, 1); $label = ''.$this->ref.''; if ($withpicto) { $result .= img_object('', $this->picto, 'class="pictofixedwidth"'); } $result .= ''.$this->ref.''; return $result; } /** * Load notes (checkable memos) * * @return int <0 if KO, number of notes if OK */ public function fetchNotes() { $this->notes = array(); $sql = "SELECT rowid, fk_user, note, checked, rang, datec"; $sql .= " FROM ".MAIN_DB_PREFIX."stundenzettel_note"; $sql .= " WHERE fk_stundenzettel = ".((int)$this->id); $sql .= " ORDER BY rang, datec"; $resql = $this->db->query($sql); if ($resql) { while ($obj = $this->db->fetch_object($resql)) { $this->notes[] = $obj; } return count($this->notes); } return -1; } /** * Add a note * * @param User $user User * @param string $note Note text * @return int <0 if KO, >0 if OK (rowid) */ public function addNote($user, $note) { if (empty($note)) { return -1; } // Get next rang $sql = "SELECT MAX(rang) as maxrang FROM ".MAIN_DB_PREFIX."stundenzettel_note WHERE fk_stundenzettel = ".((int)$this->id); $resql = $this->db->query($sql); $rang = 0; if ($resql) { $obj = $this->db->fetch_object($resql); $rang = $obj->maxrang + 1; } $sql = "INSERT INTO ".MAIN_DB_PREFIX."stundenzettel_note ("; $sql .= "fk_stundenzettel, fk_user, note, checked, rang, datec"; $sql .= ") VALUES ("; $sql .= ((int)$this->id).","; $sql .= ((int)$user->id).","; $sql .= "'".$this->db->escape($note)."',"; $sql .= "0,"; // not checked $sql .= ((int)$rang).","; $sql .= "'".$this->db->idate(dol_now())."'"; $sql .= ")"; $resql = $this->db->query($sql); if ($resql) { return $this->db->last_insert_id(MAIN_DB_PREFIX."stundenzettel_note"); } return -1; } /** * Update note checked status * * @param int $note_id Note ID * @param int $checked 0=unchecked, 1=checked * @return int <0 if KO, >0 if OK */ public function updateNoteStatus($note_id, $checked) { $sql = "UPDATE ".MAIN_DB_PREFIX."stundenzettel_note SET"; $sql .= " checked = ".((int)$checked); $sql .= " WHERE rowid = ".((int)$note_id); $sql .= " AND fk_stundenzettel = ".((int)$this->id); $resql = $this->db->query($sql); return $resql ? 1 : -1; } /** * Delete a note * * @param int $note_id Note ID * @return int <0 if KO, >0 if OK */ public function deleteNote($note_id) { $sql = "DELETE FROM ".MAIN_DB_PREFIX."stundenzettel_note"; $sql .= " WHERE rowid = ".((int)$note_id); $sql .= " AND fk_stundenzettel = ".((int)$this->id); $resql = $this->db->query($sql); return $resql ? 1 : -1; } /** * Get unchecked notes (for display on order page) * * @return array Array of unchecked notes */ public function getUncheckedNotes() { $notes = array(); $sql = "SELECT rowid, fk_user, note, rang, datec"; $sql .= " FROM ".MAIN_DB_PREFIX."stundenzettel_note"; $sql .= " WHERE fk_stundenzettel = ".((int)$this->id); $sql .= " AND checked = 0"; $sql .= " ORDER BY rang, datec"; $resql = $this->db->query($sql); if ($resql) { while ($obj = $this->db->fetch_object($resql)) { $notes[] = $obj; } } return $notes; } }