maison_alexandra/www/system-brs-core/library/cNumbers/cNumbers.php

435 lines
12 KiB
PHP

<?php
namespace BRSystems\Core\Library\cNumbers;
use BRSystems\Core\App\pubDocuments\inc\pubDocumentsModule;
use BRSystems\Core\Library\cDb\cDb;
/**
* cNumbers module
*
* @category LIB numbers
* @author Mareks Keišs <mareks.keiss@brsystems.lv>
* @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 <mareks.keiss@brsystems.lv>
* @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 <mareks.keiss@brsystems.lv>
* @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 <mareks.keiss@brsystems.lv>
* @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 <info@brsystems.lv>
* @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 <info@brsystems.lv>
* @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 <mareks.keiss@brsystems.lv>
* @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 <mareks.keiss@brsystems.lv>
* @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 <mareks.keiss@brsystems.lv>
* @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 <mareks.keiss@brsystems.lv>
* @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 <mareks.keiss@brsystems.lv>
* @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 <mareks.keiss@brsystems.lv>
* @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 <mareks.keiss@brsystems.lv>
* @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 <mareks.keiss@brsystems.lv>
* @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 <mareks.keiss@brsystems.lv>
* @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;
}
}