* @since Version 1.0 */ // Sequence procedure MYSQL // ---------------------------------------------------------- //SET GLOBAL log_bin_trust_function_creators = 1$$ //CREATE FUNCTION `nextnum`(`seq_name` VARCHAR(100), `skip` INT)RETURNS BIGINT(20) NOT DETERMINISTIC //BEGIN // DECLARE // cur_val int; // SELECT // next_index INTO cur_val // FROM // mod_sequences // WHERE // name = seq_name; // // IF skip IS NULL THEN // set skip = 1; // END IF; // IF cur_val IS NOT NULL THEN // UPDATE mod_sequences SET next_index = cur_val+skip WHERE name = seq_name; // ELSE // set cur_val = skip; // INSERT INTO mod_sequences (name, next_index) VALUES (seq_name, 2); // END IF; // // RETURN cur_val; //END$$ // ---------------------------------------------------------- class cNumbers { private $db; private $name; const SEQ_PARTNER_CODE = 'SEQ_PARTNER_CODE'; const SEQ_ROUTES_CODE = 'SEQ_ROUTES'; /** * Class constructor * @param bool|string $sDbName - DB name to use in connection */ public function __construct($sDbName = false) { $this->name = get_class(); $sDbName = (strlen($sDbName) ? $sDbName : DB_NAME); $this->db = cDb::getInstance(DB_HOST, DB_USR, DB_PWD, DB_PORT, $sDbName); } /** * Function to get sequence next id for numbers by name * * @author Mareks Keišs * @category cNumbers * @param string $name - sequence name * @param int $skip_nums - skip numbers in sequence * @return int next valid value */ public function getSequenceByName($name, $skip_nums = 1) { $sSql = "SELECT nextnum('" . $name . "', " . $skip_nums . ");"; $this->db->query($sSql); if ($val = $this->db->getOne()) { return $val; } else { return false; } } /** * Function to get bonus product number * * @author Mareks Keišs * @category cNumbers * @param int $numLen - length of the num * @return int next valid number */ public function getProductNumber($numLen = 6){ // 12X = date(260911) - number 00000N $num = $this->getSequenceByName('SEQ_PRODUCT_NUMBER'); while (strlen($num)<$numLen) { $num = '0' . $num; } return date('dmy') . $num; } /** * Function to get bonus product number * * @author Mareks Keišs * @category cNumbers * @param int $iType - bill type * @param int $iNrLength - number length width leading zeros * @return int next valid number */ public function getProductDocumentNumber($iType, $iNrLength = 4) { // 12X = date(260911) - number 00000N $num = $this->getSequenceByName(pubDocumentsModule::SEQ_DOC_TYPES . $iType); return str_pad($num, $iNrLength, '0', STR_PAD_LEFT); } /** * Function to get advance invoice number * * X = number 00000N * * * @author Aivars Žukovskis * @category cNumbers * @return int next valid number */ public function getAdvanceInvoiceNumber(){ $num = $this->getSequenceByName('SEQ_ADVANCE_INVOICE_NUMBER'); while (strlen($num)<4) $num = '0' . $num; return $num; } /** * Function to get PNA number * * X = number 00000N * * * @author Aivars Žukovskis * @category cNumbers * @return int next valid number */ public function getPNANumber(){ $num = $this->getSequenceByName('SEQ_PNA_NUMBER'); while (strlen($num)<4) $num = '0' . $num; return $num; } /** * Function to get unique number by seq name * * @author Mareks Keišs * @category cNumbers * @param string $sSeqTitle - sequence title to use * @param int $iNrLength - number length width leading zeros * @return int next valid formatted number */ public function getUniqueNumber($sSeqTitle = 'SEQ_DEFAULT', $iNrLength = 4){ // number 00000N $num = $this->getSequenceByName($sSeqTitle); return str_pad($num, $iNrLength, '0', STR_PAD_LEFT); } /** * Function to get bonus product number * * @author Mareks Keišs * @category cNumbers * @return int next valid number */ public function getBonusNumber(){ // Hx42 - B = 420000N $num = $this->getSequenceByName('SEQ_BONUS_NUMBER'); while (strlen($num)<5) { $num = '0' . $num; } return '42' . $num; } /** * Function to get bonus product exchange number * * @author Mareks Keišs * @category cNumbers * @return int next valid number */ public function getBonusExchangeNumber(){ // Hx45 - E = 450000N $num = $this->getSequenceByName('SEQ_BONUS_EXCH_NUMBER'); while (strlen($num)<5) { $num = '0' . $num; } return '45' . $num; } /** * Function to get bonus product barcode * * @author Mareks Keišs * @category cNumbers * @return int next valid number */ public function getBonusBarcode(){ // 12X = date(260911) - number 00000N $num = $this->getSequenceByName('SEQ_BONUS_BARCODE'); while (strlen($num)<6) { $num = '0' . $num; } return date('dmy') . $num; } /** * Function to convert number to string * * @author Mareks Keišs * @category cNumbers * @param array - $inst - instance for callable translation function * @param array - $sum - number to translate * @param string - $currKey - currency key to use * @return string - number in words */ public static function num2words(&$inst, $sum, $currKey = 'euros'){ if($sum){ $words = self::translateWords($inst); $num = number_format($sum, 2, '.', ''); $num = explode('.', $num); if(count($num) > 1){ $prefix = ''; // Add negative sign prefix if ((int)$num[0] < 0) { $num[0] = (int)$num[0] * -1; $prefix = $words['-'] . ' '; } $w1 = trim(self::no_to_words($words, (int)$num[0])); $w1 = ($w1 ? $w1 : $words['zero']); $decNum = (int)$num[1]; $w = trim(self::no_to_words($words, $decNum)); $w = ($w ? $w : $words['zero']); return "{$prefix}{$w1} {$words[$currKey]} {$words['and']} {$w} " . self::getWordInflection($words['cents'], $decNum); } } } /** * Function to translate number words * * @author Mareks Keišs * @category cNumbers * @param array - $words - translated arry * @param array - $no - number to translate * @return string - number in words */ private static function translateWords($inst){ $words = [ '-' => 'minus', 'euros' => 'euros', 'cents' => 'cents', 'and' => 'and', 'zero' => 'zero', '0' => '', '1' => 'one', '2' => 'two', '3' => 'three', '4' => 'four', '5' => 'five', '6' => 'six', '7' => 'seven', '8' => 'eight', '9' => 'nine', '10' => 'ten', '11' => 'eleven', '12' => 'twelve', '13' => 'thirteen', '14' => 'fouteen', '15' => 'fifteen', '16' => 'sixteen', '17' => 'seventeen', '18' => 'eighteen', '19' => 'nineteen', '20' => 'twenty', '30' => 'thirty', '40' => 'fourty', '50' => 'fifty', '60' => 'sixty', '70' => 'seventy', '80' => 'eighty', '90' => 'ninty', '100' => 'hundred &', '1000' => 'thousand', '1000000' => 'million', //'10000000' => 'crore', ]; foreach ($words as &$v) { $v = $inst->gM($v); } unset($v); return $words; } /** * Function can only convert nos up to 999 millions * * @author Mareks Keišs * @category cNumbers * @param array - $words - translated array * @param array - $no - number to translate * @return string - number in words */ private static function no_to_words(array &$words, $nr): string { if ($nr == 0) { return ' '; } elseif ($nr < 100) { if (!isset($words[(string)$nr])) { $highNr = ((int)($nr / 10)) * 10; $remainNr = $nr % 10; return $words[(string)$highNr] . ' ' . $words[(string)$remainNr]; } else { return $words[(string)$nr]; } } else { $highNr = 0; $remainNr = 0; $start = 10; $b1 = 100; $b2 = 1000; $w = ''; while ($nr > $start) { if (($b1 <= $nr) && ($nr < $b2)) { $highNr = (int)($nr / $b1); $w = self::getWordInflection($words[(string)$b1], $highNr); $remainNr = $nr % $b1; break; } $start *= 10; $b1 = $b2; $b2 = $b1 * 1000; } // Set base number if (!isset($words[(string)$highNr])) { $sStr = self::no_to_words($words, $highNr) . " $w"; } else { $sStr = $words[(string)$highNr] . " $w"; } // Send remaining part for calculation if (!isset($words[(string)$remainNr])) { $sStr .= " " . self::no_to_words($words, $remainNr); } else { $w = self::getWordInflection($words[(string)$remainNr]); $sStr .= " $w"; } return $sStr; } } /** * Function to generate word inflection * * @author Mareks Keišs * @category cNumbers * @param string $word - word * @param int $highNr - number before * @return string - word in correct inflection */ private static function getWordInflection($word, $highNr = 0){ $nParts = explode("|", $word); if(count($nParts) == 1){ $w = $word; }elseIf(count($nParts) > 1 && $highNr == 1){ $w = $nParts[0] . $nParts[1]; }elseIf(count($nParts) > 1 && ($highNr > 1 || $highNr == 0)){ $w = $nParts[0] . $nParts[2]; } return $w; } /** * Function to generate random length string for passwords example * * @author Mareks Keišs * @category cNumbers * @param int $length - length to create string * @param bool $nums - include numbers * @return string - number in words */ public static function getRandomChString($length = 8, $nums = false) { $new_pass = ""; for($i=0;$i<$length;$i++){ switch (rand(0, ($nums?2:1))){ case 0: $new_pass.= chr(rand(65,90)); // only big letters break; case 1: $new_pass.= chr(rand(97,122)); // only small letters break; case 2: $new_pass.= chr(rand(48,57)); // only small letters break; } } return $new_pass; } public function getProductBillNumber(): string { // 12X = date(260911) - number 00000N $num = $this->getSequenceByName('SEQ_BILL_NUMBER'); while (strlen($num) < 4) { $num = '0' . $num; } return date('ym') . $num; } }