/** * Load an object from its id and create a new one in database * * @param int $fromid Id of object to clone * @return int New id of clone */ function createFromClone($fromid) { global $user, $langs; $error = 0; $object = new Productbatch($this->db); $object->context['createfromclone'] = 'createfromclone'; $this->db->begin(); // Load source object $object->fetch($fromid); $object->id = 0; $object->statut = 0; // Clear fields // ... // Create clone $result = $object->create($user); // Other options if ($result < 0) { $this->error = $object->error; $error++; } if (!$error) { } unset($object->context['createfromclone']); // End if (!$error) { $this->db->commit(); return $object->id; } else { $this->db->rollback(); return -1; } }
/** * Create or update batch record (update table llx_product_batch) * * @param array|int $dluo Could be either * - int if id of product_batch * - or complete array('fk_product_stock'=>, 'eatby'=>, 'sellby'=> , 'batchnumber'=>) * @param int $qty Quantity of product with batch number. May be a negative amount. * @return int <0 if KO, else return productbatch id */ function _create_batch($dluo, $qty) { $pdluo = new Productbatch($this->db); $result = 0; // Try to find an existing record with same batch number or id if (is_numeric($dluo)) { $result = $pdluo->fetch($dluo); if (empty($pdluo->id)) { // We didn't find the line. May be it was deleted before by a previous move in same transaction. $this->error = 'Error. You ask a move on a record for a serial that does not exists anymore. May be you take the same serial on samewarehouse several times in same shipment or it was used by another shipment. Remove this shipment and prepare another one.'; $this->errors[] = $this->error; $result = -2; } } else { if (is_array($dluo)) { if (isset($dluo['fk_product_stock'])) { $vfk_product_stock = $dluo['fk_product_stock']; $veatby = $dluo['eatby']; $vsellby = $dluo['sellby']; $vbatchnumber = $dluo['batchnumber']; $result = $pdluo->find($vfk_product_stock, $veatby, $vsellby, $vbatchnumber); } else { dol_syslog(get_class($this) . "::_create_batch array param dluo must contain at least key fk_product_stock" . $error, LOG_ERR); $result = -1; } } else { dol_syslog(get_class($this) . "::_create_batch error invalid param dluo" . $error, LOG_ERR); $result = -1; } } if ($result >= 0) { // No error if ($pdluo->id > 0) { //print "Avant ".$pdluo->qty." Apres ".($pdluo->qty + $qty)."<br>"; $pdluo->qty += $qty; if ($pdluo->qty == 0) { $result = $pdluo->delete(0, 1); } else { $result = $pdluo->update(0, 1); } } else { $pdluo->fk_product_stock = $vfk_product_stock; $pdluo->qty = $qty; $pdluo->eatby = $veatby; $pdluo->sellby = $vsellby; $pdluo->batch = $vbatchnumber; $result = $pdluo->create(0, 1); if ($result < 0) { $this->error = $pdluo->error; $this->errors = $pdluo->errors; } } } return $result; }
/** * Update a record into database * * @param int $id Id of product * @param User $user Object user making update * @param int $notrigger Disable triggers * @param string $action Current action for hookmanager ('add' or 'update') * @return int 1 if OK, -1 if ref already exists, -2 if other error */ function update($id, $user, $notrigger = false, $action = 'update') { global $langs, $conf, $hookmanager; $error = 0; // Check parameters if (!$this->label) { $this->label = 'MISSING LABEL'; } // Clean parameters $this->ref = dol_string_nospecial(trim($this->ref)); $this->label = trim($this->label); $this->description = trim($this->description); $this->note = isset($this->note) ? trim($this->note) : null; $this->weight = price2num($this->weight); $this->weight_units = trim($this->weight_units); $this->length = price2num($this->length); $this->length_units = trim($this->length_units); $this->surface = price2num($this->surface); $this->surface_units = trim($this->surface_units); $this->volume = price2num($this->volume); $this->volume_units = trim($this->volume_units); if (empty($this->tva_tx)) { $this->tva_tx = 0; } if (empty($this->tva_npr)) { $this->tva_npr = 0; } if (empty($this->localtax1_tx)) { $this->localtax1_tx = 0; } if (empty($this->localtax2_tx)) { $this->localtax2_tx = 0; } if (empty($this->status)) { $this->status = 0; } if (empty($this->status_buy)) { $this->status_buy = 0; } if (empty($this->country_id)) { $this->country_id = 0; } // Barcode value $this->barcode = trim($this->barcode); $this->accountancy_code_buy = trim($this->accountancy_code_buy); $this->accountancy_code_sell = trim($this->accountancy_code_sell); $this->db->begin(); // Check name is required and codes are ok or unique. // If error, this->errors[] is filled if ($action != 'add') { $result = $this->verify(); // We don't check when update called during a create because verify was already done } if ($result >= 0) { if (empty($this->oldcopy)) { $org = new self($this->db); $org->fetch($this->id); $this->oldcopy = $org; } // test if batch management is activated on existing product if ($this->hasbatch() && !$this->oldcopy->hasbatch()) { $this->load_stock(); foreach ($this->stock_warehouse as $idW => $ObjW) { $qty_batch = 0; foreach ($ObjW->detail_batch as $detail) { $qty_batch += $detail->qty; } // Quantities in batch details are not same same as stock quantity // So we add a default batch record if ($ObjW->real != $qty_batch) { $ObjBatch = new Productbatch($this->db); $ObjBatch->batch = $langs->trans('BatchDefaultNumber'); $ObjBatch->qty = $ObjW->real - $qty_batch; $ObjBatch->fk_product_stock = $ObjW->id; if ($ObjBatch->create($user, 1) < 0) { $error++; $this->errors = $ObjBatch->errors; } } } } // For automatic creation if ($this->barcode == -1) { $this->barcode = $this->get_barcode($this, $this->barcode_type_code); } $sql = "UPDATE " . MAIN_DB_PREFIX . "product"; $sql .= " SET label = '" . $this->db->escape($this->label) . "'"; $sql .= ", ref = '" . $this->db->escape($this->ref) . "'"; $sql .= ", ref_ext = " . (!empty($this->ref_ext) ? "'" . $this->db->escape($this->ref_ext) . "'" : "null"); $sql .= ", tva_tx = " . $this->tva_tx; $sql .= ", recuperableonly = " . $this->tva_npr; $sql .= ", localtax1_tx = " . $this->localtax1_tx; $sql .= ", localtax2_tx = " . $this->localtax2_tx; $sql .= ", barcode = " . (empty($this->barcode) ? "null" : "'" . $this->db->escape($this->barcode) . "'"); $sql .= ", fk_barcode_type = " . (empty($this->barcode_type) ? "null" : $this->db->escape($this->barcode_type)); $sql .= ", tosell = " . $this->status; $sql .= ", tobuy = " . $this->status_buy; $sql .= ", tobatch = " . (empty($this->status_batch) || $this->status_batch < 0 ? '0' : $this->status_batch); $sql .= ", finished = " . (!isset($this->finished) || $this->finished < 0 ? "null" : (int) $this->finished); $sql .= ", weight = " . ($this->weight != '' ? "'" . $this->weight . "'" : 'null'); $sql .= ", weight_units = " . ($this->weight_units != '' ? "'" . $this->weight_units . "'" : 'null'); $sql .= ", length = " . ($this->length != '' ? "'" . $this->length . "'" : 'null'); $sql .= ", length_units = " . ($this->length_units != '' ? "'" . $this->length_units . "'" : 'null'); $sql .= ", surface = " . ($this->surface != '' ? "'" . $this->surface . "'" : 'null'); $sql .= ", surface_units = " . ($this->surface_units != '' ? "'" . $this->surface_units . "'" : 'null'); $sql .= ", volume = " . ($this->volume != '' ? "'" . $this->volume . "'" : 'null'); $sql .= ", volume_units = " . ($this->volume_units != '' ? "'" . $this->volume_units . "'" : 'null'); $sql .= ", seuil_stock_alerte = " . (isset($this->seuil_stock_alerte) && $this->seuil_stock_alerte != '' ? "'" . $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) . "'"; $sql .= ", fk_country = " . ($this->country_id > 0 ? $this->country_id : 'null'); $sql .= ", note = " . (isset($this->note) ? "'" . $this->db->escape($this->note) . "'" : 'null'); $sql .= ", duration = '" . $this->db->escape($this->duration_value . $this->duration_unit) . "'"; $sql .= ", accountancy_code_buy = '" . $this->db->escape($this->accountancy_code_buy) . "'"; $sql .= ", accountancy_code_sell= '" . $this->db->escape($this->accountancy_code_sell) . "'"; $sql .= ", desiredstock = " . (isset($this->desiredstock) && $this->desiredstock != '' ? $this->desiredstock : "null"); $sql .= ", fk_unit= " . (!$this->fk_unit ? 'NULL' : $this->fk_unit); $sql .= " WHERE rowid = " . $id; dol_syslog(get_class($this) . "::update", LOG_DEBUG); $resql = $this->db->query($sql); if ($resql) { $this->id = $id; // Multilangs if (!empty($conf->global->MAIN_MULTILANGS)) { if ($this->setMultiLangs() < 0) { $this->error = $langs->trans("Error") . " : " . $this->db->error() . " - " . $sql; return -2; } } $action = 'update'; // Actions on extra fields (by external module or standard code) $hookmanager->initHooks(array('productdao')); $parameters = array('id' => $this->id); $reshook = $hookmanager->executeHooks('insertExtraFields', $parameters, $this, $action); // Note that $action and $object may have been modified by some hooks if (empty($reshook)) { if (empty($conf->global->MAIN_EXTRAFIELDS_DISABLED)) { $result = $this->insertExtraFields(); if ($result < 0) { $error++; } } } else { if ($reshook < 0) { $error++; } } if (!$error && !$notrigger) { // Call trigger $result = $this->call_trigger('PRODUCT_MODIFY', $user); if ($result < 0) { $error++; } // End call triggers } if (!$error && (is_object($this->oldcopy) && $this->oldcopy->ref != $this->ref)) { // We remove directory if ($conf->product->dir_output) { $olddir = $conf->product->dir_output . "/" . dol_sanitizeFileName($this->oldcopy->ref); $newdir = $conf->product->dir_output . "/" . dol_sanitizeFileName($this->ref); if (file_exists($olddir)) { include_once DOL_DOCUMENT_ROOT . '/core/lib/files.lib.php'; $res = dol_move($olddir, $newdir); if (!$res) { $this->error = 'ErrorFailToMoveDir'; $error++; } } } } if (!$error) { $this->db->commit(); return 1; } else { $this->db->rollback(); return -$error; } } else { if ($this->db->errno() == 'DB_ERROR_RECORD_ALREADY_EXISTS') { if (empty($conf->barcode->enabled)) { $this->error = $langs->trans("Error") . " : " . $langs->trans("ErrorProductAlreadyExists", $this->ref); } else { $this->error = $langs->trans("Error") . " : " . $langs->trans("ErrorProductBarCodeAlreadyExists", $this->barcode); } $this->db->rollback(); return -1; } else { $this->error = $langs->trans("Error") . " : " . $this->db->error() . " - " . $sql; $this->db->rollback(); return -2; } } } else { $this->db->rollback(); dol_syslog(get_class($this) . "::Update fails verify " . join(',', $this->errors), LOG_WARNING); return -3; } }
/** * Create or update batch record * * @param variant $dluo Could be either int if id of product_batch or array with at leat fk_product_stock * @param int $qty Quantity of product with batch number * @return int <0 if KO, else return productbatch id */ function _create_batch($dluo, $qty) { $pdluo = new Productbatch($this->db); //Try to find an existing record with batch same batch number or id if (is_numeric($dluo)) { $result = $pdluo->fetch($dluo); } else { if (is_array($dluo)) { if (isset($dluo['fk_product_stock'])) { $vfk_product_stock = $dluo['fk_product_stock']; $veatby = $dluo['eatby']; $vsellby = $dluo['sellby']; $vbatchnumber = $dluo['batchnumber']; $result = $pdluo->find($vfk_product_stock, $veatby, $vsellby, $vbatchnumber); } else { dol_syslog(get_class($this) . "::_create_batch array param dluo must contain at least key fk_product_stock" . $error, LOG_ERR); $result = -1; } } else { dol_syslog(get_class($this) . "::_create_batch error invalid param dluo" . $error, LOG_ERR); $result = -1; } } //batch record found so we update it if ($result > 0) { if ($pdluo->id > 0) { $pdluo->qty += $qty; if ($pdluo->qty == 0) { $result = $pdluo->delete(0, 1); } else { $result = $pdluo->update(0, 1); } } else { $pdluo->fk_product_stock = $vfk_product_stock; $pdluo->qty = $qty; $pdluo->eatby = $veatby; $pdluo->sellby = $vsellby; $pdluo->batch = $vbatchnumber; $result = $pdluo->create(0, 1); } return $result; } else { return -1; } }