diff --git a/README.txt b/README.txt new file mode 100644 index 000000000..493ffb052 --- /dev/null +++ b/README.txt @@ -0,0 +1,13 @@ +How to Install +------------------------- +1. Create/locate a new mysql database to install open source point of sale into +2. Execute the file database/database.sql to create the tables needed +3. unzip and upload Open Source Point of Sale files to web server +4. Copy application/config/database.php.tmpl to application/config/database.php +5. Modify application/config/database.php to connect to your database +6. Modify application/config/config.php encryption key with your own +7. Go to your point of sale install via the browser +8. LOGIN using +username: admin +password:pointofsale +9. Enjoy \ No newline at end of file diff --git a/UPGRADE.txt b/UPGRADE.txt new file mode 100644 index 000000000..af518e482 --- /dev/null +++ b/UPGRADE.txt @@ -0,0 +1,4 @@ +How to Upgrade +------------------------- +1. Replace all code from your point of sale installation with the code downloaded +2. Run the necessary database upgrades from the database folder \ No newline at end of file diff --git a/WHATS_NEW.txt b/WHATS_NEW.txt new file mode 100644 index 000000000..f1acccdc5 --- /dev/null +++ b/WHATS_NEW.txt @@ -0,0 +1,12 @@ +* Ver. 2.1.0 ++ Various upgrades, too numerous to list here. ++ Removed dependancy on ofc upload library due to vulnerability found. +------------------------------------------------------------------------------- +* Ver. 2.0.2 ++ Fixed multiple giftcards issue per Bug #4 reported on Sourceforge where a + second giftcard added would have its balance set to $0 even if the sale did + not require the total of the second giftcard to pay the remaining amount due. ++ Small code cleanup +------------------------------------------------------------------------------- +* Upgrade to CodeIgniter 2.1.0 +* Various small improvements \ No newline at end of file diff --git a/application/.htaccess b/application/.htaccess new file mode 100644 index 000000000..14249c50b --- /dev/null +++ b/application/.htaccess @@ -0,0 +1 @@ +Deny from all \ No newline at end of file diff --git a/application/cache/.htaccess b/application/cache/.htaccess new file mode 100644 index 000000000..3418e55a6 --- /dev/null +++ b/application/cache/.htaccess @@ -0,0 +1 @@ +deny from all \ No newline at end of file diff --git a/application/cache/index.html b/application/cache/index.html new file mode 100644 index 000000000..c942a79ce --- /dev/null +++ b/application/cache/index.html @@ -0,0 +1,10 @@ + +
+Directory access is forbidden.
+ + + \ No newline at end of file diff --git a/application/config/autoload.php b/application/config/autoload.php new file mode 100644 index 000000000..cb62d45fa --- /dev/null +++ b/application/config/autoload.php @@ -0,0 +1,116 @@ + '', + 'xhtml1-strict' => '', + 'xhtml1-trans' => '', + 'xhtml1-frame' => '', + 'html5' => '', + 'html4-strict' => '', + 'html4-trans' => '', + 'html4-frame' => '' + ); + +/* End of file doctypes.php */ +/* Location: ./application/config/doctypes.php */ \ No newline at end of file diff --git a/application/config/foreign_chars.php b/application/config/foreign_chars.php new file mode 100644 index 000000000..14b0d7373 --- /dev/null +++ b/application/config/foreign_chars.php @@ -0,0 +1,64 @@ + 'ae', + '/ö|œ/' => 'oe', + '/ü/' => 'ue', + '/Ä/' => 'Ae', + '/Ü/' => 'Ue', + '/Ö/' => 'Oe', + '/À|Á|Â|Ã|Ä|Å|Ǻ|Ā|Ă|Ą|Ǎ/' => 'A', + '/à|á|â|ã|å|ǻ|ā|ă|ą|ǎ|ª/' => 'a', + '/Ç|Ć|Ĉ|Ċ|Č/' => 'C', + '/ç|ć|ĉ|ċ|č/' => 'c', + '/Ð|Ď|Đ/' => 'D', + '/ð|ď|đ/' => 'd', + '/È|É|Ê|Ë|Ē|Ĕ|Ė|Ę|Ě/' => 'E', + '/è|é|ê|ë|ē|ĕ|ė|ę|ě/' => 'e', + '/Ĝ|Ğ|Ġ|Ģ/' => 'G', + '/ĝ|ğ|ġ|ģ/' => 'g', + '/Ĥ|Ħ/' => 'H', + '/ĥ|ħ/' => 'h', + '/Ì|Í|Î|Ï|Ĩ|Ī|Ĭ|Ǐ|Į|İ/' => 'I', + '/ì|í|î|ï|ĩ|ī|ĭ|ǐ|į|ı/' => 'i', + '/Ĵ/' => 'J', + '/ĵ/' => 'j', + '/Ķ/' => 'K', + '/ķ/' => 'k', + '/Ĺ|Ļ|Ľ|Ŀ|Ł/' => 'L', + '/ĺ|ļ|ľ|ŀ|ł/' => 'l', + '/Ñ|Ń|Ņ|Ň/' => 'N', + '/ñ|ń|ņ|ň|ʼn/' => 'n', + '/Ò|Ó|Ô|Õ|Ō|Ŏ|Ǒ|Ő|Ơ|Ø|Ǿ/' => 'O', + '/ò|ó|ô|õ|ō|ŏ|ǒ|ő|ơ|ø|ǿ|º/' => 'o', + '/Ŕ|Ŗ|Ř/' => 'R', + '/ŕ|ŗ|ř/' => 'r', + '/Ś|Ŝ|Ş|Š/' => 'S', + '/ś|ŝ|ş|š|ſ/' => 's', + '/Ţ|Ť|Ŧ/' => 'T', + '/ţ|ť|ŧ/' => 't', + '/Ù|Ú|Û|Ũ|Ū|Ŭ|Ů|Ű|Ų|Ư|Ǔ|Ǖ|Ǘ|Ǚ|Ǜ/' => 'U', + '/ù|ú|û|ũ|ū|ŭ|ů|ű|ų|ư|ǔ|ǖ|ǘ|ǚ|ǜ/' => 'u', + '/Ý|Ÿ|Ŷ/' => 'Y', + '/ý|ÿ|ŷ/' => 'y', + '/Ŵ/' => 'W', + '/ŵ/' => 'w', + '/Ź|Ż|Ž/' => 'Z', + '/ź|ż|ž/' => 'z', + '/Æ|Ǽ/' => 'AE', + '/ß/'=> 'ss', + '/IJ/' => 'IJ', + '/ij/' => 'ij', + '/Œ/' => 'OE', + '/ƒ/' => 'f' +); + +/* End of file foreign_chars.php */ +/* Location: ./application/config/foreign_chars.php */ \ No newline at end of file diff --git a/application/config/hooks.php b/application/config/hooks.php new file mode 100644 index 000000000..38a5e97fc --- /dev/null +++ b/application/config/hooks.php @@ -0,0 +1,21 @@ + '', + 'function' => 'load_config', + 'filename' => 'load_config.php', + 'filepath' => 'hooks' + ); + + +/* End of file hooks.php */ +/* Location: ./application/config/hooks.php */ \ No newline at end of file diff --git a/application/config/index.html b/application/config/index.html new file mode 100644 index 000000000..c942a79ce --- /dev/null +++ b/application/config/index.html @@ -0,0 +1,10 @@ + + +Directory access is forbidden.
+ + + \ No newline at end of file diff --git a/application/config/migration.php b/application/config/migration.php new file mode 100644 index 000000000..df42a3cae --- /dev/null +++ b/application/config/migration.php @@ -0,0 +1,41 @@ +migration->latest() this is the version that schema will +| be upgraded / downgraded to. +| +*/ +$config['migration_version'] = 0; + + +/* +|-------------------------------------------------------------------------- +| Migrations Path +|-------------------------------------------------------------------------- +| +| Path to your migrations folder. +| Typically, it will be within your application path. +| Also, writing permission is required within the migrations path. +| +*/ +$config['migration_path'] = APPPATH . 'migrations/'; + + +/* End of file migration.php */ +/* Location: ./application/config/migration.php */ \ No newline at end of file diff --git a/application/config/mimes.php b/application/config/mimes.php new file mode 100644 index 000000000..f00e5b6ed --- /dev/null +++ b/application/config/mimes.php @@ -0,0 +1,106 @@ + 'application/mac-binhex40', + 'cpt' => 'application/mac-compactpro', + 'csv' => array('text/x-comma-separated-values', 'text/comma-separated-values', 'application/octet-stream', 'application/vnd.ms-excel', 'application/x-csv', 'text/x-csv', 'text/csv', 'application/csv', 'application/excel', 'application/vnd.msexcel'), + 'bin' => 'application/macbinary', + 'dms' => 'application/octet-stream', + 'lha' => 'application/octet-stream', + 'lzh' => 'application/octet-stream', + 'exe' => array('application/octet-stream', 'application/x-msdownload'), + 'class' => 'application/octet-stream', + 'psd' => 'application/x-photoshop', + 'so' => 'application/octet-stream', + 'sea' => 'application/octet-stream', + 'dll' => 'application/octet-stream', + 'oda' => 'application/oda', + 'pdf' => array('application/pdf', 'application/x-download'), + 'ai' => 'application/postscript', + 'eps' => 'application/postscript', + 'ps' => 'application/postscript', + 'smi' => 'application/smil', + 'smil' => 'application/smil', + 'mif' => 'application/vnd.mif', + 'xls' => array('application/excel', 'application/vnd.ms-excel', 'application/msexcel'), + 'ppt' => array('application/powerpoint', 'application/vnd.ms-powerpoint'), + 'wbxml' => 'application/wbxml', + 'wmlc' => 'application/wmlc', + 'dcr' => 'application/x-director', + 'dir' => 'application/x-director', + 'dxr' => 'application/x-director', + 'dvi' => 'application/x-dvi', + 'gtar' => 'application/x-gtar', + 'gz' => 'application/x-gzip', + 'php' => 'application/x-httpd-php', + 'php4' => 'application/x-httpd-php', + 'php3' => 'application/x-httpd-php', + 'phtml' => 'application/x-httpd-php', + 'phps' => 'application/x-httpd-php-source', + 'js' => 'application/x-javascript', + 'swf' => 'application/x-shockwave-flash', + 'sit' => 'application/x-stuffit', + 'tar' => 'application/x-tar', + 'tgz' => array('application/x-tar', 'application/x-gzip-compressed'), + 'xhtml' => 'application/xhtml+xml', + 'xht' => 'application/xhtml+xml', + 'zip' => array('application/x-zip', 'application/zip', 'application/x-zip-compressed'), + 'mid' => 'audio/midi', + 'midi' => 'audio/midi', + 'mpga' => 'audio/mpeg', + 'mp2' => 'audio/mpeg', + 'mp3' => array('audio/mpeg', 'audio/mpg', 'audio/mpeg3', 'audio/mp3'), + 'aif' => 'audio/x-aiff', + 'aiff' => 'audio/x-aiff', + 'aifc' => 'audio/x-aiff', + 'ram' => 'audio/x-pn-realaudio', + 'rm' => 'audio/x-pn-realaudio', + 'rpm' => 'audio/x-pn-realaudio-plugin', + 'ra' => 'audio/x-realaudio', + 'rv' => 'video/vnd.rn-realvideo', + 'wav' => array('audio/x-wav', 'audio/wave', 'audio/wav'), + 'bmp' => array('image/bmp', 'image/x-windows-bmp'), + 'gif' => 'image/gif', + 'jpeg' => array('image/jpeg', 'image/pjpeg'), + 'jpg' => array('image/jpeg', 'image/pjpeg'), + 'jpe' => array('image/jpeg', 'image/pjpeg'), + 'png' => array('image/png', 'image/x-png'), + 'tiff' => 'image/tiff', + 'tif' => 'image/tiff', + 'css' => 'text/css', + 'html' => 'text/html', + 'htm' => 'text/html', + 'shtml' => 'text/html', + 'txt' => 'text/plain', + 'text' => 'text/plain', + 'log' => array('text/plain', 'text/x-log'), + 'rtx' => 'text/richtext', + 'rtf' => 'text/rtf', + 'xml' => 'text/xml', + 'xsl' => 'text/xml', + 'mpeg' => 'video/mpeg', + 'mpg' => 'video/mpeg', + 'mpe' => 'video/mpeg', + 'qt' => 'video/quicktime', + 'mov' => 'video/quicktime', + 'avi' => 'video/x-msvideo', + 'movie' => 'video/x-sgi-movie', + 'doc' => 'application/msword', + 'docx' => 'application/vnd.openxmlformats-officedocument.wordprocessingml.document', + 'xlsx' => 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet', + 'word' => array('application/msword', 'application/octet-stream'), + 'xl' => 'application/excel', + 'eml' => 'message/rfc822', + 'json' => array('application/json', 'text/json') + ); + + +/* End of file mimes.php */ +/* Location: ./application/config/mimes.php */ diff --git a/application/config/profiler.php b/application/config/profiler.php new file mode 100644 index 000000000..f8a5b1a1e --- /dev/null +++ b/application/config/profiler.php @@ -0,0 +1,17 @@ + array('grin.gif', '19', '19', 'grin'), + ':lol:' => array('lol.gif', '19', '19', 'LOL'), + ':cheese:' => array('cheese.gif', '19', '19', 'cheese'), + ':)' => array('smile.gif', '19', '19', 'smile'), + ';-)' => array('wink.gif', '19', '19', 'wink'), + ';)' => array('wink.gif', '19', '19', 'wink'), + ':smirk:' => array('smirk.gif', '19', '19', 'smirk'), + ':roll:' => array('rolleyes.gif', '19', '19', 'rolleyes'), + ':-S' => array('confused.gif', '19', '19', 'confused'), + ':wow:' => array('surprise.gif', '19', '19', 'surprised'), + ':bug:' => array('bigsurprise.gif', '19', '19', 'big surprise'), + ':-P' => array('tongue_laugh.gif', '19', '19', 'tongue laugh'), + '%-P' => array('tongue_rolleye.gif', '19', '19', 'tongue rolleye'), + ';-P' => array('tongue_wink.gif', '19', '19', 'tongue wink'), + ':P' => array('raspberry.gif', '19', '19', 'raspberry'), + ':blank:' => array('blank.gif', '19', '19', 'blank stare'), + ':long:' => array('longface.gif', '19', '19', 'long face'), + ':ohh:' => array('ohh.gif', '19', '19', 'ohh'), + ':grrr:' => array('grrr.gif', '19', '19', 'grrr'), + ':gulp:' => array('gulp.gif', '19', '19', 'gulp'), + '8-/' => array('ohoh.gif', '19', '19', 'oh oh'), + ':down:' => array('downer.gif', '19', '19', 'downer'), + ':red:' => array('embarrassed.gif', '19', '19', 'red face'), + ':sick:' => array('sick.gif', '19', '19', 'sick'), + ':shut:' => array('shuteye.gif', '19', '19', 'shut eye'), + ':-/' => array('hmm.gif', '19', '19', 'hmmm'), + '>:(' => array('mad.gif', '19', '19', 'mad'), + ':mad:' => array('mad.gif', '19', '19', 'mad'), + '>:-(' => array('angry.gif', '19', '19', 'angry'), + ':angry:' => array('angry.gif', '19', '19', 'angry'), + ':zip:' => array('zip.gif', '19', '19', 'zipper'), + ':kiss:' => array('kiss.gif', '19', '19', 'kiss'), + ':ahhh:' => array('shock.gif', '19', '19', 'shock'), + ':coolsmile:' => array('shade_smile.gif', '19', '19', 'cool smile'), + ':coolsmirk:' => array('shade_smirk.gif', '19', '19', 'cool smirk'), + ':coolgrin:' => array('shade_grin.gif', '19', '19', 'cool grin'), + ':coolhmm:' => array('shade_hmm.gif', '19', '19', 'cool hmm'), + ':coolmad:' => array('shade_mad.gif', '19', '19', 'cool mad'), + ':coolcheese:' => array('shade_cheese.gif', '19', '19', 'cool cheese'), + ':vampire:' => array('vampire.gif', '19', '19', 'vampire'), + ':snake:' => array('snake.gif', '19', '19', 'snake'), + ':exclaim:' => array('exclaim.gif', '19', '19', 'excaim'), + ':question:' => array('question.gif', '19', '19', 'question') // no comma after last item + + ); + +/* End of file smileys.php */ +/* Location: ./application/config/smileys.php */ \ No newline at end of file diff --git a/application/config/user_agents.php b/application/config/user_agents.php new file mode 100644 index 000000000..e2d3c3af0 --- /dev/null +++ b/application/config/user_agents.php @@ -0,0 +1,178 @@ + 'Windows Longhorn', + 'windows nt 5.2' => 'Windows 2003', + 'windows nt 5.0' => 'Windows 2000', + 'windows nt 5.1' => 'Windows XP', + 'windows nt 4.0' => 'Windows NT 4.0', + 'winnt4.0' => 'Windows NT 4.0', + 'winnt 4.0' => 'Windows NT', + 'winnt' => 'Windows NT', + 'windows 98' => 'Windows 98', + 'win98' => 'Windows 98', + 'windows 95' => 'Windows 95', + 'win95' => 'Windows 95', + 'windows' => 'Unknown Windows OS', + 'os x' => 'Mac OS X', + 'ppc mac' => 'Power PC Mac', + 'freebsd' => 'FreeBSD', + 'ppc' => 'Macintosh', + 'linux' => 'Linux', + 'debian' => 'Debian', + 'sunos' => 'Sun Solaris', + 'beos' => 'BeOS', + 'apachebench' => 'ApacheBench', + 'aix' => 'AIX', + 'irix' => 'Irix', + 'osf' => 'DEC OSF', + 'hp-ux' => 'HP-UX', + 'netbsd' => 'NetBSD', + 'bsdi' => 'BSDi', + 'openbsd' => 'OpenBSD', + 'gnu' => 'GNU/Linux', + 'unix' => 'Unknown Unix OS' + ); + + +// The order of this array should NOT be changed. Many browsers return +// multiple browser types so we want to identify the sub-type first. +$browsers = array( + 'Flock' => 'Flock', + 'Chrome' => 'Chrome', + 'Opera' => 'Opera', + 'MSIE' => 'Internet Explorer', + 'Internet Explorer' => 'Internet Explorer', + 'Shiira' => 'Shiira', + 'Firefox' => 'Firefox', + 'Chimera' => 'Chimera', + 'Phoenix' => 'Phoenix', + 'Firebird' => 'Firebird', + 'Camino' => 'Camino', + 'Netscape' => 'Netscape', + 'OmniWeb' => 'OmniWeb', + 'Safari' => 'Safari', + 'Mozilla' => 'Mozilla', + 'Konqueror' => 'Konqueror', + 'icab' => 'iCab', + 'Lynx' => 'Lynx', + 'Links' => 'Links', + 'hotjava' => 'HotJava', + 'amaya' => 'Amaya', + 'IBrowse' => 'IBrowse' + ); + +$mobiles = array( + // legacy array, old values commented out + 'mobileexplorer' => 'Mobile Explorer', +// 'openwave' => 'Open Wave', +// 'opera mini' => 'Opera Mini', +// 'operamini' => 'Opera Mini', +// 'elaine' => 'Palm', + 'palmsource' => 'Palm', +// 'digital paths' => 'Palm', +// 'avantgo' => 'Avantgo', +// 'xiino' => 'Xiino', + 'palmscape' => 'Palmscape', +// 'nokia' => 'Nokia', +// 'ericsson' => 'Ericsson', +// 'blackberry' => 'BlackBerry', +// 'motorola' => 'Motorola' + + // Phones and Manufacturers + 'motorola' => "Motorola", + 'nokia' => "Nokia", + 'palm' => "Palm", + 'iphone' => "Apple iPhone", + 'ipad' => "iPad", + 'ipod' => "Apple iPod Touch", + 'sony' => "Sony Ericsson", + 'ericsson' => "Sony Ericsson", + 'blackberry' => "BlackBerry", + 'cocoon' => "O2 Cocoon", + 'blazer' => "Treo", + 'lg' => "LG", + 'amoi' => "Amoi", + 'xda' => "XDA", + 'mda' => "MDA", + 'vario' => "Vario", + 'htc' => "HTC", + 'samsung' => "Samsung", + 'sharp' => "Sharp", + 'sie-' => "Siemens", + 'alcatel' => "Alcatel", + 'benq' => "BenQ", + 'ipaq' => "HP iPaq", + 'mot-' => "Motorola", + 'playstation portable' => "PlayStation Portable", + 'hiptop' => "Danger Hiptop", + 'nec-' => "NEC", + 'panasonic' => "Panasonic", + 'philips' => "Philips", + 'sagem' => "Sagem", + 'sanyo' => "Sanyo", + 'spv' => "SPV", + 'zte' => "ZTE", + 'sendo' => "Sendo", + + // Operating Systems + 'symbian' => "Symbian", + 'SymbianOS' => "SymbianOS", + 'elaine' => "Palm", + 'palm' => "Palm", + 'series60' => "Symbian S60", + 'windows ce' => "Windows CE", + + // Browsers + 'obigo' => "Obigo", + 'netfront' => "Netfront Browser", + 'openwave' => "Openwave Browser", + 'mobilexplorer' => "Mobile Explorer", + 'operamini' => "Opera Mini", + 'opera mini' => "Opera Mini", + + // Other + 'digital paths' => "Digital Paths", + 'avantgo' => "AvantGo", + 'xiino' => "Xiino", + 'novarra' => "Novarra Transcoder", + 'vodafone' => "Vodafone", + 'docomo' => "NTT DoCoMo", + 'o2' => "O2", + + // Fallback + 'mobile' => "Generic Mobile", + 'wireless' => "Generic Mobile", + 'j2me' => "Generic Mobile", + 'midp' => "Generic Mobile", + 'cldc' => "Generic Mobile", + 'up.link' => "Generic Mobile", + 'up.browser' => "Generic Mobile", + 'smartphone' => "Generic Mobile", + 'cellphone' => "Generic Mobile" + ); + +// There are hundreds of bots but these are the most common. +$robots = array( + 'googlebot' => 'Googlebot', + 'msnbot' => 'MSNBot', + 'slurp' => 'Inktomi Slurp', + 'yahoo' => 'Yahoo', + 'askjeeves' => 'AskJeeves', + 'fastcrawler' => 'FastCrawler', + 'infoseek' => 'InfoSeek Robot 1.0', + 'lycos' => 'Lycos' + ); + +/* End of file user_agents.php */ +/* Location: ./application/config/user_agents.php */ \ No newline at end of file diff --git a/application/controllers/barcode.php b/application/controllers/barcode.php new file mode 100644 index 000000000..0d3d3b7b8 --- /dev/null +++ b/application/controllers/barcode.php @@ -0,0 +1,14 @@ +load->view('barcode'); + } +} +?> \ No newline at end of file diff --git a/application/controllers/config.php b/application/controllers/config.php new file mode 100644 index 000000000..028c4bff5 --- /dev/null +++ b/application/controllers/config.php @@ -0,0 +1,52 @@ +load->view("config"); + } + + function save() + { + $batch_save_data=array( + 'company'=>$this->input->post('company'), + 'address'=>$this->input->post('address'), + 'phone'=>$this->input->post('phone'), + 'email'=>$this->input->post('email'), + 'fax'=>$this->input->post('fax'), + 'website'=>$this->input->post('website'), + 'default_tax_1_rate'=>$this->input->post('default_tax_1_rate'), + 'default_tax_1_name'=>$this->input->post('default_tax_1_name'), + 'default_tax_2_rate'=>$this->input->post('default_tax_2_rate'), + 'default_tax_2_name'=>$this->input->post('default_tax_2_name'), + 'currency_symbol'=>$this->input->post('currency_symbol'), + 'currency_side'=>$this->input->post('currency_side'),/**GARRISON ADDED 4/20/2013**/ + 'return_policy'=>$this->input->post('return_policy'), + 'language'=>$this->input->post('language'), + 'timezone'=>$this->input->post('timezone'), + 'print_after_sale'=>$this->input->post('print_after_sale'), + 'custom1_name'=>$this->input->post('custom1_name'),/**GARRISON ADDED 4/20/2013**/ + 'custom2_name'=>$this->input->post('custom2_name'),/**GARRISON ADDED 4/20/2013**/ + 'custom3_name'=>$this->input->post('custom3_name'),/**GARRISON ADDED 4/20/2013**/ + 'custom4_name'=>$this->input->post('custom4_name'),/**GARRISON ADDED 4/20/2013**/ + 'custom5_name'=>$this->input->post('custom5_name'),/**GARRISON ADDED 4/20/2013**/ + 'custom6_name'=>$this->input->post('custom6_name'),/**GARRISON ADDED 4/20/2013**/ + 'custom7_name'=>$this->input->post('custom7_name'),/**GARRISON ADDED 4/20/2013**/ + 'custom8_name'=>$this->input->post('custom8_name'),/**GARRISON ADDED 4/20/2013**/ + 'custom9_name'=>$this->input->post('custom9_name'),/**GARRISON ADDED 4/20/2013**/ + 'custom10_name'=>$this->input->post('custom10_name')/**GARRISON ADDED 4/20/2013**/ + ); + + if( $this->Appconfig->batch_save( $batch_save_data ) ) + { + echo json_encode(array('success'=>true,'message'=>$this->lang->line('config_saved_successfully'))); + } + } +} +?> \ No newline at end of file diff --git a/application/controllers/customers.php b/application/controllers/customers.php new file mode 100644 index 000000000..9d5de6687 --- /dev/null +++ b/application/controllers/customers.php @@ -0,0 +1,201 @@ +Customer->count_all(); + $config['per_page'] = '20'; + $config['uri_segment'] = 3; + $this->pagination->initialize($config); + + $data['controller_name']=strtolower(get_class()); + $data['form_width']=$this->get_form_width(); + $data['manage_table']=get_people_manage_table( $this->Customer->get_all( $config['per_page'], $this->uri->segment( $config['uri_segment'] ) ), $this ); + $this->load->view('people/manage',$data); + } + + /* + Returns customer table data rows. This will be called with AJAX. + */ + function search() + { + $search=$this->input->post('search'); + $data_rows=get_people_manage_table_data_rows($this->Customer->search($search),$this); + echo $data_rows; + } + + /* + Gives search suggestions based on what is being searched for + */ + function suggest() + { + $suggestions = $this->Customer->get_search_suggestions($this->input->post('q'),$this->input->post('limit')); + echo implode("\n",$suggestions); + } + + /* + Loads the customer edit form + */ + function view($customer_id=-1) + { + $data['person_info']=$this->Customer->get_info($customer_id); + $this->load->view("customers/form",$data); + } + + /* + Inserts/updates a customer + */ + function save($customer_id=-1) + { + $person_data = array( + 'first_name'=>$this->input->post('first_name'), + 'last_name'=>$this->input->post('last_name'), + 'email'=>$this->input->post('email'), + 'phone_number'=>$this->input->post('phone_number'), + 'address_1'=>$this->input->post('address_1'), + 'address_2'=>$this->input->post('address_2'), + 'city'=>$this->input->post('city'), + 'state'=>$this->input->post('state'), + 'zip'=>$this->input->post('zip'), + 'country'=>$this->input->post('country'), + 'comments'=>$this->input->post('comments') + ); + $customer_data=array( + 'account_number'=>$this->input->post('account_number')=='' ? null:$this->input->post('account_number'), + 'taxable'=>$this->input->post('taxable')=='' ? 0:1, + ); + if($this->Customer->save($person_data,$customer_data,$customer_id)) + { + //New customer + if($customer_id==-1) + { + echo json_encode(array('success'=>true,'message'=>$this->lang->line('customers_successful_adding').' '. + $person_data['first_name'].' '.$person_data['last_name'],'person_id'=>$customer_data['person_id'])); + } + else //previous customer + { + echo json_encode(array('success'=>true,'message'=>$this->lang->line('customers_successful_updating').' '. + $person_data['first_name'].' '.$person_data['last_name'],'person_id'=>$customer_id)); + } + } + else//failure + { + echo json_encode(array('success'=>false,'message'=>$this->lang->line('customers_error_adding_updating').' '. + $person_data['first_name'].' '.$person_data['last_name'],'person_id'=>-1)); + } + } + + /* + This deletes customers from the customers table + */ + function delete() + { + $customers_to_delete=$this->input->post('ids'); + + if($this->Customer->delete_list($customers_to_delete)) + { + echo json_encode(array('success'=>true,'message'=>$this->lang->line('customers_successful_deleted').' '. + count($customers_to_delete).' '.$this->lang->line('customers_one_or_multiple'))); + } + else + { + echo json_encode(array('success'=>false,'message'=>$this->lang->line('customers_cannot_be_deleted'))); + } + } + + function excel() + { + $data = file_get_contents("import_customers.csv"); + $name = 'import_customers.csv'; + force_download($name, $data); + } + + function excel_import() + { + $this->load->view("customers/excel_import", null); + } + + function do_excel_import() + { + $msg = 'do_excel_import'; + $failCodes = array(); + if ($_FILES['file_path']['error']!=UPLOAD_ERR_OK) + { + $msg = $this->lang->line('items_excel_import_failed'); + echo json_encode( array('success'=>false,'message'=>$msg) ); + return; + } + else + { + if (($handle = fopen($_FILES['file_path']['tmp_name'], "r")) !== FALSE) + { + //Skip first row + fgetcsv($handle); + + $i=1; + while (($data = fgetcsv($handle)) !== FALSE) + { + $person_data = array( + 'first_name'=>$data[0], + 'last_name'=>$data[1], + 'email'=>$data[2], + 'phone_number'=>$data[3], + 'address_1'=>$data[4], + 'address_2'=>$data[5], + 'city'=>$data[6], + 'state'=>$data[7], + 'zip'=>$data[8], + 'country'=>$data[9], + 'comments'=>$data[10] + ); + + $customer_data=array( + 'account_number'=>$data[11]=='' ? null:$data[11], + 'taxable'=>$data[12]=='' ? 0:1, + ); + + if(!$this->Customer->save($person_data,$customer_data)) + { + $failCodes[] = $i; + } + + $i++; + } + } + else + { + echo json_encode( array('success'=>false,'message'=>'Your upload file has no data or not in supported format.') ); + return; + } + } + + $success = true; + if(count($failCodes) > 1) + { + $msg = "Most customers imported. But some were not, here is list of their CODE (" .count($failCodes) ."): ".implode(", ", $failCodes); + $success = false; + } + else + { + $msg = "Import Customers successful"; + } + + echo json_encode( array('success'=>$success,'message'=>$msg) ); + } + + /* + get the width for the add/edit form + */ + function get_form_width() + { + return 350; + } +} +?> \ No newline at end of file diff --git a/application/controllers/employees.php b/application/controllers/employees.php new file mode 100644 index 000000000..e719cb0cd --- /dev/null +++ b/application/controllers/employees.php @@ -0,0 +1,132 @@ +Employee->count_all(); + $config['per_page'] = '20'; + $config['uri_segment'] = 3; + $this->pagination->initialize($config); + + $data['controller_name']=strtolower(get_class()); + $data['form_width']=$this->get_form_width(); + $data['manage_table']=get_people_manage_table( $this->Employee->get_all( $config['per_page'], $this->uri->segment( $config['uri_segment'] ) ), $this ); + $this->load->view('people/manage',$data); + } + + /* + Returns employee table data rows. This will be called with AJAX. + */ + function search() + { + $search=$this->input->post('search'); + $data_rows=get_people_manage_table_data_rows($this->Employee->search($search),$this); + echo $data_rows; + } + + /* + Gives search suggestions based on what is being searched for + */ + function suggest() + { + $suggestions = $this->Employee->get_search_suggestions($this->input->post('q'),$this->input->post('limit')); + echo implode("\n",$suggestions); + } + + /* + Loads the employee edit form + */ + function view($employee_id=-1) + { + $data['person_info']=$this->Employee->get_info($employee_id); + $data['all_modules']=$this->Module->get_all_modules(); + $this->load->view("employees/form",$data); + } + + /* + Inserts/updates an employee + */ + function save($employee_id=-1) + { + $person_data = array( + 'first_name'=>$this->input->post('first_name'), + 'last_name'=>$this->input->post('last_name'), + 'email'=>$this->input->post('email'), + 'phone_number'=>$this->input->post('phone_number'), + 'address_1'=>$this->input->post('address_1'), + 'address_2'=>$this->input->post('address_2'), + 'city'=>$this->input->post('city'), + 'state'=>$this->input->post('state'), + 'zip'=>$this->input->post('zip'), + 'country'=>$this->input->post('country'), + 'comments'=>$this->input->post('comments') + ); + $permission_data = $this->input->post("permissions")!=false ? $this->input->post("permissions"):array(); + + //Password has been changed OR first time password set + if($this->input->post('password')!='') + { + $employee_data=array( + 'username'=>$this->input->post('username'), + 'password'=>md5($this->input->post('password')) + ); + } + else //Password not changed + { + $employee_data=array('username'=>$this->input->post('username')); + } + + if($this->Employee->save($person_data,$employee_data,$permission_data,$employee_id)) + { + //New employee + if($employee_id==-1) + { + echo json_encode(array('success'=>true,'message'=>$this->lang->line('employees_successful_adding').' '. + $person_data['first_name'].' '.$person_data['last_name'],'person_id'=>$employee_data['person_id'])); + } + else //previous employee + { + echo json_encode(array('success'=>true,'message'=>$this->lang->line('employees_successful_updating').' '. + $person_data['first_name'].' '.$person_data['last_name'],'person_id'=>$employee_id)); + } + } + else//failure + { + echo json_encode(array('success'=>false,'message'=>$this->lang->line('employees_error_adding_updating').' '. + $person_data['first_name'].' '.$person_data['last_name'],'person_id'=>-1)); + } + } + + /* + This deletes employees from the employees table + */ + function delete() + { + $employees_to_delete=$this->input->post('ids'); + + if($this->Employee->delete_list($employees_to_delete)) + { + echo json_encode(array('success'=>true,'message'=>$this->lang->line('employees_successful_deleted').' '. + count($employees_to_delete).' '.$this->lang->line('employees_one_or_multiple'))); + } + else + { + echo json_encode(array('success'=>false,'message'=>$this->lang->line('employees_cannot_be_deleted'))); + } + } + /* + get the width for the add/edit form + */ + function get_form_width() + { + return 650; + } +} +?> \ No newline at end of file diff --git a/application/controllers/giftcards.php b/application/controllers/giftcards.php new file mode 100644 index 000000000..a5989cf02 --- /dev/null +++ b/application/controllers/giftcards.php @@ -0,0 +1,117 @@ +Giftcard->count_all(); + $config['per_page'] = '20'; + $config['uri_segment'] = 3; + $this->pagination->initialize($config); + + $data['controller_name']=strtolower(get_class()); + $data['form_width']=$this->get_form_width(); + $data['manage_table']=get_giftcards_manage_table( $this->Giftcard->get_all( $config['per_page'], $this->uri->segment( $config['uri_segment'] ) ), $this ); + $this->load->view('giftcards/manage',$data); + } + + function search() + { + $search=$this->input->post('search'); + $data_rows=get_giftcards_manage_table_data_rows($this->Giftcard->search($search),$this); + echo $data_rows; + } + + /* + Gives search suggestions based on what is being searched for + */ + function suggest() + { + $suggestions = $this->Giftcard->get_search_suggestions($this->input->post('q'),$this->input->post('limit')); + echo implode("\n",$suggestions); + } +/** GARRISON ADDED 5/3/2013 **/ + /* + Gives search suggestions for person_id based on what is being searched for + */ + function suggest_person() + { + $suggestions = $this->Giftcard->get_person_search_suggestions($this->input->post('q'),$this->input->post('limit')); + echo implode("\n",$suggestions); + } +/** END GARRISON ADDED **/ + function get_row() + { + $giftcard_id = $this->input->post('row_id'); + $data_row=get_giftcard_data_row($this->Giftcard->get_info($giftcard_id),$this); + echo $data_row; + } + + function view($giftcard_id=-1) + { + $data['giftcard_info']=$this->Giftcard->get_info($giftcard_id); + + $this->load->view("giftcards/form",$data); + } + + function save($giftcard_id=-1) + { + $giftcard_data = array( + 'giftcard_number'=>$this->input->post('giftcard_number'), + 'value'=>$this->input->post('value'), + 'person_id'=>$this->input->post('person_id')/**GARRISON ADDED 4/22/2013**/ + ); + + if( $this->Giftcard->save( $giftcard_data, $giftcard_id ) ) + { + //New giftcard + if($giftcard_id==-1) + { + echo json_encode(array('success'=>true,'message'=>$this->lang->line('giftcards_successful_adding').' '. + $giftcard_data['giftcard_number'],'giftcard_id'=>$giftcard_data['giftcard_id'])); + $giftcard_id = $giftcard_data['giftcard_id']; + } + else //previous giftcard + { + echo json_encode(array('success'=>true,'message'=>$this->lang->line('giftcards_successful_updating').' '. + $giftcard_data['giftcard_number'],'giftcard_id'=>$giftcard_id)); + } + } + else//failure + { + echo json_encode(array('success'=>false,'message'=>$this->lang->line('giftcards_error_adding_updating').' '. + $giftcard_data['giftcard_number'],'giftcard_id'=>-1)); + } + } + + function delete() + { + $giftcards_to_delete=$this->input->post('ids'); + + if($this->Giftcard->delete_list($giftcards_to_delete)) + { + echo json_encode(array('success'=>true,'message'=>$this->lang->line('giftcards_successful_deleted').' '. + count($giftcards_to_delete).' '.$this->lang->line('giftcards_one_or_multiple'))); + } + else + { + echo json_encode(array('success'=>false,'message'=>$this->lang->line('giftcards_cannot_be_deleted'))); + } + } + + /* + get the width for the add/edit form + */ + function get_form_width() + { + return 360; + } +} +?> \ No newline at end of file diff --git a/application/controllers/home.php b/application/controllers/home.php new file mode 100644 index 000000000..8e5d307fe --- /dev/null +++ b/application/controllers/home.php @@ -0,0 +1,21 @@ +load->view("home"); + } + + function logout() + { + $this->Employee->logout(); + } +} +?> \ No newline at end of file diff --git a/application/controllers/index.html b/application/controllers/index.html new file mode 100644 index 000000000..c942a79ce --- /dev/null +++ b/application/controllers/index.html @@ -0,0 +1,10 @@ + + +Directory access is forbidden.
+ + + \ No newline at end of file diff --git a/application/controllers/interfaces/idata_controller.php b/application/controllers/interfaces/idata_controller.php new file mode 100644 index 000000000..e05d493d0 --- /dev/null +++ b/application/controllers/interfaces/idata_controller.php @@ -0,0 +1,17 @@ + \ No newline at end of file diff --git a/application/controllers/interfaces/iperson_controller.php b/application/controllers/interfaces/iperson_controller.php new file mode 100644 index 000000000..92cdb1810 --- /dev/null +++ b/application/controllers/interfaces/iperson_controller.php @@ -0,0 +1,11 @@ + \ No newline at end of file diff --git a/application/controllers/item_kits.php b/application/controllers/item_kits.php new file mode 100644 index 000000000..5d4986e99 --- /dev/null +++ b/application/controllers/item_kits.php @@ -0,0 +1,138 @@ +Item_kit->count_all(); + $config['per_page'] = '20'; + $config['uri_segment'] = 3; + $this->pagination->initialize($config); + + $data['controller_name']=strtolower(get_class()); + $data['form_width']=$this->get_form_width(); + $data['manage_table']=get_item_kits_manage_table( $this->Item_kit->get_all( $config['per_page'], $this->uri->segment( $config['uri_segment'] ) ), $this ); + $this->load->view('item_kits/manage',$data); + } + + function search() + { + $search=$this->input->post('search'); + $data_rows=get_item_kits_manage_table_data_rows($this->Item_kit->search($search),$this); + echo $data_rows; + } + + /* + Gives search suggestions based on what is being searched for + */ + function suggest() + { + $suggestions = $this->Item_kit->get_search_suggestions($this->input->post('q'),$this->input->post('limit')); + echo implode("\n",$suggestions); + } + + function get_row() + { + $item_kit_id = $this->input->post('row_id'); + $data_row=get_item_kit_data_row($this->Item_kit->get_info($item_kit_id),$this); + echo $data_row; + } + + function view($item_kit_id=-1) + { + $data['item_kit_info']=$this->Item_kit->get_info($item_kit_id); + $this->load->view("item_kits/form",$data); + } + + function save($item_kit_id=-1) + { + $item_kit_data = array( + 'name'=>$this->input->post('name'), + 'description'=>$this->input->post('description') + ); + + if($this->Item_kit->save($item_kit_data,$item_kit_id)) + { + //New item kit + if($item_kit_id==-1) + { + echo json_encode(array('success'=>true,'message'=>$this->lang->line('item_kits_successful_adding').' '. + $item_kit_data['name'],'item_kit_id'=>$item_kit_data['item_kit_id'])); + $item_kit_id = $item_kit_data['item_kit_id']; + } + else //previous item + { + echo json_encode(array('success'=>true,'message'=>$this->lang->line('item_kits_successful_updating').' '. + $item_kit_data['name'],'item_kit_id'=>$item_kit_id)); + } + + if ($this->input->post('item_kit_item')) + { + $item_kit_items = array(); + foreach($this->input->post('item_kit_item') as $item_id => $quantity) + { + $item_kit_items[] = array( + 'item_id' => $item_id, + 'quantity' => $quantity + ); + } + + $this->Item_kit_items->save($item_kit_items, $item_kit_id); + } + } + else//failure + { + echo json_encode(array('success'=>false,'message'=>$this->lang->line('item_kits_error_adding_updating').' '. + $item_kit_data['name'],'item_kit_id'=>-1)); + } + + } + + function delete() + { + $item_kits_to_delete=$this->input->post('ids'); + + if($this->Item_kit->delete_list($item_kits_to_delete)) + { + echo json_encode(array('success'=>true,'message'=>$this->lang->line('item_kits_successful_deleted').' '. + count($item_kits_to_delete).' '.$this->lang->line('item_kits_one_or_multiple'))); + } + else + { + echo json_encode(array('success'=>false,'message'=>$this->lang->line('item_kits_cannot_be_deleted'))); + } + } + + function generate_barcodes($item_kit_ids) + { + $result = array(); + + $item_kit_ids = explode(':', $item_kit_ids); + foreach ($item_kit_ids as $item_kid_id) + { + $item_kit_info = $this->Item_kit->get_info($item_kid_id); + + $result[] = array('name' =>$item_kit_info->name, 'id'=> 'KIT '.$item_kid_id); + } + + $data['items'] = $result; + $this->load->view("barcode_sheet", $data); + } + + + /* + get the width for the add/edit form + */ + function get_form_width() + { + return 360; + } +} +?> \ No newline at end of file diff --git a/application/controllers/items.php b/application/controllers/items.php new file mode 100644 index 000000000..281c25a11 --- /dev/null +++ b/application/controllers/items.php @@ -0,0 +1,551 @@ +Item->count_all(); + $config['per_page'] = '20'; + $config['uri_segment'] = 3; + $this->pagination->initialize($config); + + $data['controller_name']=strtolower(get_class()); + $data['form_width']=$this->get_form_width(); + $data['manage_table']=get_items_manage_table( $this->Item->get_all( $config['per_page'], $this->uri->segment( $config['uri_segment'] ) ), $this ); + $this->load->view('items/manage',$data); + } + + function refresh() + { + $low_inventory=$this->input->post('low_inventory'); + $is_serialized=$this->input->post('is_serialized'); + $no_description=$this->input->post('no_description'); + $search_custom=$this->input->post('search_custom');//GARRISON ADDED 4/13/2013 + + $data['search_section_state']=$this->input->post('search_section_state'); + $data['low_inventory']=$this->input->post('low_inventory'); + $data['is_serialized']=$this->input->post('is_serialized'); + $data['no_description']=$this->input->post('no_description'); + $data['search_custom']=$this->input->post('search_custom');//GARRISON ADDED 4/13/2013 + $data['controller_name']=strtolower(get_class()); + $data['form_width']=$this->get_form_width(); + $data['manage_table']=get_items_manage_table($this->Item->get_all_filtered($low_inventory,$is_serialized,$no_description,$search_custom),$this);//GARRISON MODIFIED 4/13/2013 + $this->load->view('items/manage',$data); + } + + function find_item_info() + { + $item_number=$this->input->post('scan_item_number'); + echo json_encode($this->Item->find_item_info($item_number)); + } + + function search() + { + $search=$this->input->post('search'); + $data_rows=get_items_manage_table_data_rows($this->Item->search($search),$this); + echo $data_rows; + } + + /* + Gives search suggestions based on what is being searched for + */ + function suggest() + { + $suggestions = $this->Item->get_search_suggestions($this->input->post('q'),$this->input->post('limit')); + echo implode("\n",$suggestions); + } + + function item_search() + { + $suggestions = $this->Item->get_item_search_suggestions($this->input->post('q'),$this->input->post('limit')); + echo implode("\n",$suggestions); + } + + /* + Gives search suggestions based on what is being searched for + */ + function suggest_category() + { + $suggestions = $this->Item->get_category_suggestions($this->input->post('q')); + echo implode("\n",$suggestions); + } + +/**GARRISON ADDED 5/18/2013**/ + /* + Gives search suggestions based on what is being searched for + */ + function suggest_location() + { + $suggestions = $this->Item->get_location_suggestions($this->input->post('q')); + echo implode("\n",$suggestions); + } + + /* + Gives search suggestions based on what is being searched for + */ + function suggest_custom1() + { + $suggestions = $this->Item->get_custom1_suggestions($this->input->post('q')); + echo implode("\n",$suggestions); + } + + /* + Gives search suggestions based on what is being searched for + */ + function suggest_custom2() + { + $suggestions = $this->Item->get_custom2_suggestions($this->input->post('q')); + echo implode("\n",$suggestions); + } + + /* + Gives search suggestions based on what is being searched for + */ + function suggest_custom3() + { + $suggestions = $this->Item->get_custom3_suggestions($this->input->post('q')); + echo implode("\n",$suggestions); + } + + /* + Gives search suggestions based on what is being searched for + */ + function suggest_custom4() + { + $suggestions = $this->Item->get_custom4_suggestions($this->input->post('q')); + echo implode("\n",$suggestions); + } + + /* + Gives search suggestions based on what is being searched for + */ + function suggest_custom5() + { + $suggestions = $this->Item->get_custom5_suggestions($this->input->post('q')); + echo implode("\n",$suggestions); + } + + /* + Gives search suggestions based on what is being searched for + */ + function suggest_custom6() + { + $suggestions = $this->Item->get_custom6_suggestions($this->input->post('q')); + echo implode("\n",$suggestions); + } + + /* + Gives search suggestions based on what is being searched for + */ + function suggest_custom7() + { + $suggestions = $this->Item->get_custom7_suggestions($this->input->post('q')); + echo implode("\n",$suggestions); + } + + /* + Gives search suggestions based on what is being searched for + */ + function suggest_custom8() + { + $suggestions = $this->Item->get_custom8_suggestions($this->input->post('q')); + echo implode("\n",$suggestions); + } + + /* + Gives search suggestions based on what is being searched for + */ + function suggest_custom9() + { + $suggestions = $this->Item->get_custom9_suggestions($this->input->post('q')); + echo implode("\n",$suggestions); + } + + /* + Gives search suggestions based on what is being searched for + */ + function suggest_custom10() + { + $suggestions = $this->Item->get_custom10_suggestions($this->input->post('q')); + echo implode("\n",$suggestions); + } +/**END GARRISON ADDED**/ + + function get_row() + { + $item_id = $this->input->post('row_id'); + $data_row=get_item_data_row($this->Item->get_info($item_id),$this); + echo $data_row; + } + + function view($item_id=-1) + { + $data['item_info']=$this->Item->get_info($item_id); + $data['item_tax_info']=$this->Item_taxes->get_info($item_id); + $suppliers = array('' => $this->lang->line('items_none')); + foreach($this->Supplier->get_all()->result_array() as $row) + { + $suppliers[$row['person_id']] = $row['company_name'] .' ('.$row['first_name'] .' '. $row['last_name'].')'; + } + + $data['suppliers']=$suppliers; + $data['selected_supplier'] = $this->Item->get_info($item_id)->supplier_id; + $data['default_tax_1_rate']=($item_id==-1) ? $this->Appconfig->get('default_tax_1_rate') : ''; + $data['default_tax_2_rate']=($item_id==-1) ? $this->Appconfig->get('default_tax_2_rate') : ''; + $this->load->view("items/form",$data); + } + + //Ramel Inventory Tracking + function inventory($item_id=-1) + { + $data['item_info']=$this->Item->get_info($item_id); + $this->load->view("items/inventory",$data); + } + + function count_details($item_id=-1) + { + $data['item_info']=$this->Item->get_info($item_id); + $this->load->view("items/count_details",$data); + } //------------------------------------------- Ramel + + function generate_barcodes($item_ids) + { + $result = array(); + + $item_ids = explode(':', $item_ids); + foreach ($item_ids as $item_id) + { + $item_info = $this->Item->get_info($item_id); + + $result[] = array('name' =>$item_info->name, 'id'=> $item_id); + } + + $data['items'] = $result; + $this->load->view("barcode_sheet", $data); + } + + function bulk_edit() + { + $data = array(); + $suppliers = array('' => $this->lang->line('items_none')); + foreach($this->Supplier->get_all()->result_array() as $row) + { + $suppliers[$row['person_id']] = $row['first_name'] .' '. $row['last_name']; + } + $data['suppliers'] = $suppliers; + $data['allow_alt_desciption_choices'] = array( + ''=>$this->lang->line('items_do_nothing'), + 1 =>$this->lang->line('items_change_all_to_allow_alt_desc'), + 0 =>$this->lang->line('items_change_all_to_not_allow_allow_desc')); + + $data['serialization_choices'] = array( + ''=>$this->lang->line('items_do_nothing'), + 1 =>$this->lang->line('items_change_all_to_serialized'), + 0 =>$this->lang->line('items_change_all_to_unserialized')); + $this->load->view("items/form_bulk", $data); + } + + function save($item_id=-1) + { + $item_data = array( + 'name'=>$this->input->post('name'), + 'description'=>$this->input->post('description'), + 'category'=>$this->input->post('category'), + 'supplier_id'=>$this->input->post('supplier_id')=='' ? null:$this->input->post('supplier_id'), + 'item_number'=>$this->input->post('item_number')=='' ? null:$this->input->post('item_number'), + 'cost_price'=>$this->input->post('cost_price'), + 'unit_price'=>$this->input->post('unit_price'), + 'quantity'=>$this->input->post('quantity'), + 'reorder_level'=>$this->input->post('reorder_level'), + 'location'=>$this->input->post('location'), + 'allow_alt_description'=>$this->input->post('allow_alt_description'), + 'is_serialized'=>$this->input->post('is_serialized'), + 'custom1'=>$this->input->post('custom1'), /**GARRISON ADDED 4/21/2013**/ + 'custom2'=>$this->input->post('custom2'),/**GARRISON ADDED 4/21/2013**/ + 'custom3'=>$this->input->post('custom3'),/**GARRISON ADDED 4/21/2013**/ + 'custom4'=>$this->input->post('custom4'),/**GARRISON ADDED 4/21/2013**/ + 'custom5'=>$this->input->post('custom5'),/**GARRISON ADDED 4/21/2013**/ + 'custom6'=>$this->input->post('custom6'),/**GARRISON ADDED 4/21/2013**/ + 'custom7'=>$this->input->post('custom7'),/**GARRISON ADDED 4/21/2013**/ + 'custom8'=>$this->input->post('custom8'),/**GARRISON ADDED 4/21/2013**/ + 'custom9'=>$this->input->post('custom9'),/**GARRISON ADDED 4/21/2013**/ + 'custom10'=>$this->input->post('custom10')/**GARRISON ADDED 4/21/2013**/ + ); + + $employee_id=$this->Employee->get_logged_in_employee_info()->person_id; + $cur_item_info = $this->Item->get_info($item_id); + + + if($this->Item->save($item_data,$item_id)) + { + //New item + if($item_id==-1) + { + echo json_encode(array('success'=>true,'message'=>$this->lang->line('items_successful_adding').' '. + $item_data['name'],'item_id'=>$item_data['item_id'])); + $item_id = $item_data['item_id']; + } + else //previous item + { + echo json_encode(array('success'=>true,'message'=>$this->lang->line('items_successful_updating').' '. + $item_data['name'],'item_id'=>$item_id)); + } + + $inv_data = array + ( + 'trans_date'=>date('Y-m-d H:i:s'), + 'trans_items'=>$item_id, + 'trans_user'=>$employee_id, + 'trans_comment'=>$this->lang->line('items_manually_editing_of_quantity'), + 'trans_inventory'=>$cur_item_info ? $this->input->post('quantity') - $cur_item_info->quantity : $this->input->post('quantity') + ); + $this->Inventory->insert($inv_data); + $items_taxes_data = array(); + $tax_names = $this->input->post('tax_names'); + $tax_percents = $this->input->post('tax_percents'); + for($k=0;$kDirectory access is forbidden.
+ + + \ No newline at end of file diff --git a/application/errors/error_404.php b/application/errors/error_404.php new file mode 100644 index 000000000..792726a67 --- /dev/null +++ b/application/errors/error_404.php @@ -0,0 +1,62 @@ + + + +Severity:
+Message:
+Filename:
+Line Number:
+ +Directory access is forbidden.
+ + + \ No newline at end of file diff --git a/application/helpers/currency_helper.php b/application/helpers/currency_helper.php new file mode 100644 index 000000000..744c854ef --- /dev/null +++ b/application/helpers/currency_helper.php @@ -0,0 +1,28 @@ +config->item('currency_symbol') ? $CI->config->item('currency_symbol') : '$'; + if($number >= 0) + { + if($CI->config->item('currency_side') !== 'currency_side') + return $currency_symbol.number_format($number, 2, '.', ''); + else + return number_format($number, 2, '.', '').$currency_symbol; + } + else + { + if($CI->config->item('currency_side') !== 'currency_side') + return '-'.$currency_symbol.number_format(abs($number), 2, '.', ''); + else + return '-'.number_format(abs($number), 2, '.', '').$currency_symbol; + } +} +/** END MODIFIED **/ + +function to_currency_no_money($number) +{ + return number_format($number, 2, '.', ''); +} +?> \ No newline at end of file diff --git a/application/helpers/index.html b/application/helpers/index.html new file mode 100644 index 000000000..c942a79ce --- /dev/null +++ b/application/helpers/index.html @@ -0,0 +1,10 @@ + + +Directory access is forbidden.
+ + + \ No newline at end of file diff --git a/application/helpers/report_helper.php b/application/helpers/report_helper.php new file mode 100644 index 000000000..2b380e316 --- /dev/null +++ b/application/helpers/report_helper.php @@ -0,0 +1,87 @@ +load->language('reports'); + $today = date('Y-m-d'); + $yesterday = date('Y-m-d', mktime(0,0,0,date("m"),date("d")-1,date("Y"))); + $six_days_ago = date('Y-m-d', mktime(0,0,0,date("m"),date("d")-6,date("Y"))); + $start_of_this_month = date('Y-m-d', mktime(0,0,0,date("m"),1,date("Y"))); + $end_of_this_month = date('Y-m-d',strtotime('-1 second',strtotime('+1 month',strtotime(date('m').'/01/'.date('Y').' 00:00:00')))); + $start_of_last_month = date('Y-m-d', mktime(0,0,0,date("m")-1,1,date("Y"))); + $end_of_last_month = date('Y-m-d',strtotime('-1 second',strtotime('+1 month',strtotime((date('m') - 1).'/01/'.date('Y').' 00:00:00')))); + $start_of_this_year = date('Y-m-d', mktime(0,0,0,1,1,date("Y"))); + $end_of_this_year = date('Y-m-d', mktime(0,0,0,12,31,date("Y"))); + $start_of_last_year = date('Y-m-d', mktime(0,0,0,1,1,date("Y")-1)); + $end_of_last_year = date('Y-m-d', mktime(0,0,0,12,31,date("Y")-1)); + $start_of_time = date('Y-m-d', 0); + + return array( + $today. '/' . $today => $CI->lang->line('reports_today'), + $yesterday. '/' . $yesterday => $CI->lang->line('reports_yesterday'), + $six_days_ago. '/' . $today => $CI->lang->line('reports_last_7'), + $start_of_this_month . '/' . $end_of_this_month => $CI->lang->line('reports_this_month'), + $start_of_last_month . '/' . $end_of_last_month => $CI->lang->line('reports_last_month'), + $start_of_this_year . '/' . $end_of_this_year => $CI->lang->line('reports_this_year'), + $start_of_last_year . '/' . $end_of_last_year => $CI->lang->line('reports_last_year'), + $start_of_time . '/' . $today => $CI->lang->line('reports_all_time'), + ); +} + +function get_months() +{ + $months = array(); + for($k=1;$k<=12;$k++) + { + $cur_month = mktime(0, 0, 0, $k, 1, 2000); + $months[date("m", $cur_month)] = date("M",$cur_month); + } + + return $months; +} + +function get_days() +{ + $days = array(); + + for($k=1;$k<=31;$k++) + { + $cur_day = mktime(0, 0, 0, 1, $k, 2000); + $days[date('d',$cur_day)] = date('j',$cur_day); + } + + return $days; +} + +function get_years() +{ + $years = array(); + for($k=0;$k<10;$k++) + { + $years[date("Y")-$k] = date("Y")-$k; + } + + return $years; +} + +function get_random_colors($how_many) +{ + $colors = array(); + + for($k=0;$k<$how_many;$k++) + { + $colors[] = '#'.random_color(); + } + + return $colors; +} + +function random_color() +{ + mt_srand((double)microtime()*1000000); + $c = ''; + while(strlen($c)<6){ + $c .= sprintf("%02X", mt_rand(0, 255)); + } + return $c; +} \ No newline at end of file diff --git a/application/helpers/sale_helper.php b/application/helpers/sale_helper.php new file mode 100644 index 000000000..e69de29bb diff --git a/application/helpers/table_helper.php b/application/helpers/table_helper.php new file mode 100644 index 000000000..9f5927a11 --- /dev/null +++ b/application/helpers/table_helper.php @@ -0,0 +1,350 @@ +'; + + $headers = array('', + $CI->lang->line('common_last_name'), + $CI->lang->line('common_first_name'), + $CI->lang->line('common_email'), + $CI->lang->line('common_phone_number'), + ' '); + + $table.='| $header | "; + } + $table.='
|---|
| $header | "; + } + $table.='
|---|
| $header | "; + } + $table.='
|---|
| $header | "; + } + $table.='
|---|
Directory access is forbidden.
+ + + \ No newline at end of file diff --git a/application/hooks/load_config.php b/application/hooks/load_config.php new file mode 100644 index 000000000..7f24ea02c --- /dev/null +++ b/application/hooks/load_config.php @@ -0,0 +1,32 @@ +Appconfig->get_all()->result() as $app_config ) + { + $CI->config->set_item( $app_config->key, $app_config->value ); + } + + if ( $CI->config->item( 'language' ) ) + { + $CI->config->set_item( 'language', $CI->config->item( 'language' ) ); + $loaded = $CI->lang->is_loaded; + $CI->lang->is_loaded = array(); + + foreach($loaded as $file) + { + $CI->lang->load( str_replace( '_lang.php', '', $file ) ); + } + } + + if ( $CI->config->item( 'timezone' ) ) + { + date_default_timezone_set( $CI->config->item( 'timezone' ) ); + } + else + { + date_default_timezone_set( 'America/New_York' ); + } +} +?> \ No newline at end of file diff --git a/application/index.html b/application/index.html new file mode 100644 index 000000000..c942a79ce --- /dev/null +++ b/application/index.html @@ -0,0 +1,10 @@ + + +Directory access is forbidden.
+ + + \ No newline at end of file diff --git a/application/language/Azerbaijan/common_lang.php b/application/language/Azerbaijan/common_lang.php new file mode 100644 index 000000000..3ddf42837 --- /dev/null +++ b/application/language/Azerbaijan/common_lang.php @@ -0,0 +1,41 @@ + \ No newline at end of file diff --git a/application/language/Azerbaijan/config_lang.php b/application/language/Azerbaijan/config_lang.php new file mode 100644 index 000000000..6c7686880 --- /dev/null +++ b/application/language/Azerbaijan/config_lang.php @@ -0,0 +1,35 @@ + \ No newline at end of file diff --git a/application/language/Azerbaijan/customers_lang.php b/application/language/Azerbaijan/customers_lang.php new file mode 100644 index 000000000..d6978d458 --- /dev/null +++ b/application/language/Azerbaijan/customers_lang.php @@ -0,0 +1,16 @@ + diff --git a/application/language/Azerbaijan/employees_lang.php b/application/language/Azerbaijan/employees_lang.php new file mode 100644 index 000000000..a30c32b99 --- /dev/null +++ b/application/language/Azerbaijan/employees_lang.php @@ -0,0 +1,27 @@ + diff --git a/application/language/Azerbaijan/error_lang.php b/application/language/Azerbaijan/error_lang.php new file mode 100644 index 000000000..cfcd2f0c9 --- /dev/null +++ b/application/language/Azerbaijan/error_lang.php @@ -0,0 +1,4 @@ + diff --git a/application/language/Azerbaijan/giftcards_lang.php b/application/language/Azerbaijan/giftcards_lang.php new file mode 100644 index 000000000..edd7fc95b --- /dev/null +++ b/application/language/Azerbaijan/giftcards_lang.php @@ -0,0 +1,70 @@ + diff --git a/application/language/Azerbaijan/index.html b/application/language/Azerbaijan/index.html new file mode 100644 index 000000000..7f684dff4 --- /dev/null +++ b/application/language/Azerbaijan/index.html @@ -0,0 +1,10 @@ + + +Directory access is forbidden.
+ + + diff --git a/application/language/Azerbaijan/item_kits_lang.php b/application/language/Azerbaijan/item_kits_lang.php new file mode 100644 index 000000000..601fae62d --- /dev/null +++ b/application/language/Azerbaijan/item_kits_lang.php @@ -0,0 +1,20 @@ + diff --git a/application/language/Azerbaijan/items_lang.php b/application/language/Azerbaijan/items_lang.php new file mode 100644 index 000000000..c0ed72e0a --- /dev/null +++ b/application/language/Azerbaijan/items_lang.php @@ -0,0 +1,80 @@ + diff --git a/application/language/Azerbaijan/login_lang.php b/application/language/Azerbaijan/login_lang.php new file mode 100644 index 000000000..a5aa1bb26 --- /dev/null +++ b/application/language/Azerbaijan/login_lang.php @@ -0,0 +1,8 @@ + diff --git a/application/language/Azerbaijan/module_lang.php b/application/language/Azerbaijan/module_lang.php new file mode 100644 index 000000000..9e95a2d81 --- /dev/null +++ b/application/language/Azerbaijan/module_lang.php @@ -0,0 +1,34 @@ + diff --git a/application/language/Azerbaijan/receivings_lang.php b/application/language/Azerbaijan/receivings_lang.php new file mode 100644 index 000000000..9f73af7b6 --- /dev/null +++ b/application/language/Azerbaijan/receivings_lang.php @@ -0,0 +1,26 @@ + diff --git a/application/language/Azerbaijan/reports_lang.php b/application/language/Azerbaijan/reports_lang.php new file mode 100644 index 000000000..12e1f3598 --- /dev/null +++ b/application/language/Azerbaijan/reports_lang.php @@ -0,0 +1,87 @@ + diff --git a/application/language/Azerbaijan/sales_lang.php b/application/language/Azerbaijan/sales_lang.php new file mode 100644 index 000000000..836446372 --- /dev/null +++ b/application/language/Azerbaijan/sales_lang.php @@ -0,0 +1,79 @@ + \ No newline at end of file diff --git a/application/language/Azerbaijan/suppliers_lang.php b/application/language/Azerbaijan/suppliers_lang.php new file mode 100644 index 000000000..fdcb86fbb --- /dev/null +++ b/application/language/Azerbaijan/suppliers_lang.php @@ -0,0 +1,17 @@ + diff --git a/application/language/BahasaIndonesia/common_lang.php b/application/language/BahasaIndonesia/common_lang.php new file mode 100644 index 000000000..53e4e9c6d --- /dev/null +++ b/application/language/BahasaIndonesia/common_lang.php @@ -0,0 +1,41 @@ + diff --git a/application/language/BahasaIndonesia/config_lang.php b/application/language/BahasaIndonesia/config_lang.php new file mode 100644 index 000000000..b28d95ff8 --- /dev/null +++ b/application/language/BahasaIndonesia/config_lang.php @@ -0,0 +1,24 @@ + \ No newline at end of file diff --git a/application/language/BahasaIndonesia/customers_lang.php b/application/language/BahasaIndonesia/customers_lang.php new file mode 100644 index 000000000..4ce03c357 --- /dev/null +++ b/application/language/BahasaIndonesia/customers_lang.php @@ -0,0 +1,16 @@ + \ No newline at end of file diff --git a/application/language/BahasaIndonesia/employees_lang.php b/application/language/BahasaIndonesia/employees_lang.php new file mode 100644 index 000000000..5f2fc811e --- /dev/null +++ b/application/language/BahasaIndonesia/employees_lang.php @@ -0,0 +1,27 @@ + \ No newline at end of file diff --git a/application/language/BahasaIndonesia/error_lang.php b/application/language/BahasaIndonesia/error_lang.php new file mode 100644 index 000000000..5fb55ba97 --- /dev/null +++ b/application/language/BahasaIndonesia/error_lang.php @@ -0,0 +1,4 @@ + \ No newline at end of file diff --git a/application/language/BahasaIndonesia/giftcards_lang.php b/application/language/BahasaIndonesia/giftcards_lang.php new file mode 100644 index 000000000..c6ba2ebe1 --- /dev/null +++ b/application/language/BahasaIndonesia/giftcards_lang.php @@ -0,0 +1,71 @@ + \ No newline at end of file diff --git a/application/language/BahasaIndonesia/index.html b/application/language/BahasaIndonesia/index.html new file mode 100644 index 000000000..04879110a --- /dev/null +++ b/application/language/BahasaIndonesia/index.html @@ -0,0 +1,10 @@ + + +Akses direktori dilarang.
+ + + \ No newline at end of file diff --git a/application/language/BahasaIndonesia/item_kits_lang.php b/application/language/BahasaIndonesia/item_kits_lang.php new file mode 100644 index 000000000..ebd06926b --- /dev/null +++ b/application/language/BahasaIndonesia/item_kits_lang.php @@ -0,0 +1,20 @@ + \ No newline at end of file diff --git a/application/language/BahasaIndonesia/items_lang.php b/application/language/BahasaIndonesia/items_lang.php new file mode 100644 index 000000000..2cc620e96 --- /dev/null +++ b/application/language/BahasaIndonesia/items_lang.php @@ -0,0 +1,78 @@ + diff --git a/application/language/BahasaIndonesia/login_lang.php b/application/language/BahasaIndonesia/login_lang.php new file mode 100644 index 000000000..7b0150f00 --- /dev/null +++ b/application/language/BahasaIndonesia/login_lang.php @@ -0,0 +1,8 @@ + diff --git a/application/language/BahasaIndonesia/module_lang.php b/application/language/BahasaIndonesia/module_lang.php new file mode 100644 index 000000000..b45605a1f --- /dev/null +++ b/application/language/BahasaIndonesia/module_lang.php @@ -0,0 +1,33 @@ + diff --git a/application/language/BahasaIndonesia/receivings_lang.php b/application/language/BahasaIndonesia/receivings_lang.php new file mode 100644 index 000000000..54c908e04 --- /dev/null +++ b/application/language/BahasaIndonesia/receivings_lang.php @@ -0,0 +1,26 @@ + \ No newline at end of file diff --git a/application/language/BahasaIndonesia/reports_lang.php b/application/language/BahasaIndonesia/reports_lang.php new file mode 100644 index 000000000..a32b1bd22 --- /dev/null +++ b/application/language/BahasaIndonesia/reports_lang.php @@ -0,0 +1,85 @@ + diff --git a/application/language/BahasaIndonesia/sales_lang.php b/application/language/BahasaIndonesia/sales_lang.php new file mode 100644 index 000000000..089c3ef23 --- /dev/null +++ b/application/language/BahasaIndonesia/sales_lang.php @@ -0,0 +1,78 @@ + diff --git a/application/language/BahasaIndonesia/suppliers_lang.php b/application/language/BahasaIndonesia/suppliers_lang.php new file mode 100644 index 000000000..54e373e94 --- /dev/null +++ b/application/language/BahasaIndonesia/suppliers_lang.php @@ -0,0 +1,17 @@ + \ No newline at end of file diff --git a/application/language/Russian/common_lang.php b/application/language/Russian/common_lang.php new file mode 100644 index 000000000..c501ddf2e --- /dev/null +++ b/application/language/Russian/common_lang.php @@ -0,0 +1,41 @@ + \ No newline at end of file diff --git a/application/language/Russian/config_lang.php b/application/language/Russian/config_lang.php new file mode 100644 index 000000000..05f6082ee --- /dev/null +++ b/application/language/Russian/config_lang.php @@ -0,0 +1,35 @@ + \ No newline at end of file diff --git a/application/language/Russian/customers_lang.php b/application/language/Russian/customers_lang.php new file mode 100644 index 000000000..685e72bc1 --- /dev/null +++ b/application/language/Russian/customers_lang.php @@ -0,0 +1,16 @@ + diff --git a/application/language/Russian/employees_lang.php b/application/language/Russian/employees_lang.php new file mode 100644 index 000000000..4de2d6300 --- /dev/null +++ b/application/language/Russian/employees_lang.php @@ -0,0 +1,27 @@ + diff --git a/application/language/Russian/error_lang.php b/application/language/Russian/error_lang.php new file mode 100644 index 000000000..3efc57ae5 --- /dev/null +++ b/application/language/Russian/error_lang.php @@ -0,0 +1,4 @@ + diff --git a/application/language/Russian/giftcards_lang.php b/application/language/Russian/giftcards_lang.php new file mode 100644 index 000000000..8885c5fac --- /dev/null +++ b/application/language/Russian/giftcards_lang.php @@ -0,0 +1,70 @@ + diff --git a/application/language/Russian/index.html b/application/language/Russian/index.html new file mode 100644 index 000000000..7f684dff4 --- /dev/null +++ b/application/language/Russian/index.html @@ -0,0 +1,10 @@ + + +Directory access is forbidden.
+ + + diff --git a/application/language/Russian/item_kits_lang.php b/application/language/Russian/item_kits_lang.php new file mode 100644 index 000000000..f7bb918d3 --- /dev/null +++ b/application/language/Russian/item_kits_lang.php @@ -0,0 +1,20 @@ + diff --git a/application/language/Russian/items_lang.php b/application/language/Russian/items_lang.php new file mode 100644 index 000000000..8972dd6fe --- /dev/null +++ b/application/language/Russian/items_lang.php @@ -0,0 +1,80 @@ + diff --git a/application/language/Russian/login_lang.php b/application/language/Russian/login_lang.php new file mode 100644 index 000000000..b0bdae042 --- /dev/null +++ b/application/language/Russian/login_lang.php @@ -0,0 +1,8 @@ + diff --git a/application/language/Russian/module_lang.php b/application/language/Russian/module_lang.php new file mode 100644 index 000000000..c618f6e73 --- /dev/null +++ b/application/language/Russian/module_lang.php @@ -0,0 +1,34 @@ + diff --git a/application/language/Russian/receivings_lang.php b/application/language/Russian/receivings_lang.php new file mode 100644 index 000000000..4753d1ce9 --- /dev/null +++ b/application/language/Russian/receivings_lang.php @@ -0,0 +1,26 @@ + diff --git a/application/language/Russian/reports_lang.php b/application/language/Russian/reports_lang.php new file mode 100644 index 000000000..e47cac200 --- /dev/null +++ b/application/language/Russian/reports_lang.php @@ -0,0 +1,87 @@ + diff --git a/application/language/Russian/sales_lang.php b/application/language/Russian/sales_lang.php new file mode 100644 index 000000000..ff9426671 --- /dev/null +++ b/application/language/Russian/sales_lang.php @@ -0,0 +1,79 @@ + \ No newline at end of file diff --git a/application/language/Russian/suppliers_lang.php b/application/language/Russian/suppliers_lang.php new file mode 100644 index 000000000..2a5fb704d --- /dev/null +++ b/application/language/Russian/suppliers_lang.php @@ -0,0 +1,17 @@ + diff --git a/application/language/Spanish/common_lang.php b/application/language/Spanish/common_lang.php new file mode 100644 index 000000000..474db8325 --- /dev/null +++ b/application/language/Spanish/common_lang.php @@ -0,0 +1,40 @@ + diff --git a/application/language/Spanish/config_lang.php b/application/language/Spanish/config_lang.php new file mode 100644 index 000000000..a39aa873e --- /dev/null +++ b/application/language/Spanish/config_lang.php @@ -0,0 +1,24 @@ + diff --git a/application/language/Spanish/customers_lang.php b/application/language/Spanish/customers_lang.php new file mode 100644 index 000000000..d36370d53 --- /dev/null +++ b/application/language/Spanish/customers_lang.php @@ -0,0 +1,16 @@ + diff --git a/application/language/Spanish/employees_lang.php b/application/language/Spanish/employees_lang.php new file mode 100644 index 000000000..52be3d99c --- /dev/null +++ b/application/language/Spanish/employees_lang.php @@ -0,0 +1,27 @@ + diff --git a/application/language/Spanish/error_lang.php b/application/language/Spanish/error_lang.php new file mode 100644 index 000000000..aef9e8c43 --- /dev/null +++ b/application/language/Spanish/error_lang.php @@ -0,0 +1,4 @@ + diff --git a/application/language/Spanish/giftcards_lang.php b/application/language/Spanish/giftcards_lang.php new file mode 100644 index 000000000..4a358491c --- /dev/null +++ b/application/language/Spanish/giftcards_lang.php @@ -0,0 +1,69 @@ + diff --git a/application/language/Spanish/index.html b/application/language/Spanish/index.html new file mode 100644 index 000000000..d9dd8677a --- /dev/null +++ b/application/language/Spanish/index.html @@ -0,0 +1,10 @@ + + +El acceso a los directorios está prohibido.
+ + + diff --git a/application/language/Spanish/item_kits_lang.php b/application/language/Spanish/item_kits_lang.php new file mode 100644 index 000000000..2ffd7b807 --- /dev/null +++ b/application/language/Spanish/item_kits_lang.php @@ -0,0 +1,20 @@ + diff --git a/application/language/Spanish/items_lang.php b/application/language/Spanish/items_lang.php new file mode 100644 index 000000000..cc4f39bed --- /dev/null +++ b/application/language/Spanish/items_lang.php @@ -0,0 +1,77 @@ + diff --git a/application/language/Spanish/login_lang.php b/application/language/Spanish/login_lang.php new file mode 100644 index 000000000..8c60ff3a4 --- /dev/null +++ b/application/language/Spanish/login_lang.php @@ -0,0 +1,8 @@ + diff --git a/application/language/Spanish/module_lang.php b/application/language/Spanish/module_lang.php new file mode 100644 index 000000000..d00dc9862 --- /dev/null +++ b/application/language/Spanish/module_lang.php @@ -0,0 +1,33 @@ + diff --git a/application/language/Spanish/receivings_lang.php b/application/language/Spanish/receivings_lang.php new file mode 100644 index 000000000..bd1bb0ccb --- /dev/null +++ b/application/language/Spanish/receivings_lang.php @@ -0,0 +1,26 @@ + diff --git a/application/language/Spanish/reports_lang.php b/application/language/Spanish/reports_lang.php new file mode 100644 index 000000000..94d67239c --- /dev/null +++ b/application/language/Spanish/reports_lang.php @@ -0,0 +1,85 @@ + diff --git a/application/language/Spanish/sales_lang.php b/application/language/Spanish/sales_lang.php new file mode 100644 index 000000000..d1612d701 --- /dev/null +++ b/application/language/Spanish/sales_lang.php @@ -0,0 +1,78 @@ + diff --git a/application/language/Spanish/suppliers_lang.php b/application/language/Spanish/suppliers_lang.php new file mode 100644 index 000000000..f3b6a9c5b --- /dev/null +++ b/application/language/Spanish/suppliers_lang.php @@ -0,0 +1,17 @@ + diff --git a/application/language/english/common_lang.php b/application/language/english/common_lang.php new file mode 100644 index 000000000..3ddf42837 --- /dev/null +++ b/application/language/english/common_lang.php @@ -0,0 +1,41 @@ + \ No newline at end of file diff --git a/application/language/english/config_lang.php b/application/language/english/config_lang.php new file mode 100644 index 000000000..6c7686880 --- /dev/null +++ b/application/language/english/config_lang.php @@ -0,0 +1,35 @@ + \ No newline at end of file diff --git a/application/language/english/customers_lang.php b/application/language/english/customers_lang.php new file mode 100644 index 000000000..d6978d458 --- /dev/null +++ b/application/language/english/customers_lang.php @@ -0,0 +1,16 @@ + diff --git a/application/language/english/employees_lang.php b/application/language/english/employees_lang.php new file mode 100644 index 000000000..a30c32b99 --- /dev/null +++ b/application/language/english/employees_lang.php @@ -0,0 +1,27 @@ + diff --git a/application/language/english/error_lang.php b/application/language/english/error_lang.php new file mode 100644 index 000000000..cfcd2f0c9 --- /dev/null +++ b/application/language/english/error_lang.php @@ -0,0 +1,4 @@ + diff --git a/application/language/english/giftcards_lang.php b/application/language/english/giftcards_lang.php new file mode 100644 index 000000000..cfd96a74e --- /dev/null +++ b/application/language/english/giftcards_lang.php @@ -0,0 +1,70 @@ + diff --git a/application/language/english/index.html b/application/language/english/index.html new file mode 100644 index 000000000..7f684dff4 --- /dev/null +++ b/application/language/english/index.html @@ -0,0 +1,10 @@ + + +Directory access is forbidden.
+ + + diff --git a/application/language/english/item_kits_lang.php b/application/language/english/item_kits_lang.php new file mode 100644 index 000000000..601fae62d --- /dev/null +++ b/application/language/english/item_kits_lang.php @@ -0,0 +1,20 @@ + diff --git a/application/language/english/items_lang.php b/application/language/english/items_lang.php new file mode 100644 index 000000000..7535f42bb --- /dev/null +++ b/application/language/english/items_lang.php @@ -0,0 +1,80 @@ + diff --git a/application/language/english/login_lang.php b/application/language/english/login_lang.php new file mode 100644 index 000000000..a5aa1bb26 --- /dev/null +++ b/application/language/english/login_lang.php @@ -0,0 +1,8 @@ + diff --git a/application/language/english/module_lang.php b/application/language/english/module_lang.php new file mode 100644 index 000000000..9e95a2d81 --- /dev/null +++ b/application/language/english/module_lang.php @@ -0,0 +1,34 @@ + diff --git a/application/language/english/receivings_lang.php b/application/language/english/receivings_lang.php new file mode 100644 index 000000000..9f73af7b6 --- /dev/null +++ b/application/language/english/receivings_lang.php @@ -0,0 +1,26 @@ + diff --git a/application/language/english/reports_lang.php b/application/language/english/reports_lang.php new file mode 100644 index 000000000..12e1f3598 --- /dev/null +++ b/application/language/english/reports_lang.php @@ -0,0 +1,87 @@ + diff --git a/application/language/english/sales_lang.php b/application/language/english/sales_lang.php new file mode 100644 index 000000000..836446372 --- /dev/null +++ b/application/language/english/sales_lang.php @@ -0,0 +1,79 @@ + \ No newline at end of file diff --git a/application/language/english/suppliers_lang.php b/application/language/english/suppliers_lang.php new file mode 100644 index 000000000..fdcb86fbb --- /dev/null +++ b/application/language/english/suppliers_lang.php @@ -0,0 +1,17 @@ + diff --git a/application/libraries/MY_Language.php b/application/libraries/MY_Language.php new file mode 100644 index 000000000..a9b69505b --- /dev/null +++ b/application/libraries/MY_Language.php @@ -0,0 +1,26 @@ +config->set_item( 'language', $idiom ); + $loaded = $this->is_loaded; + $this->is_loaded = array(); + + foreach($loaded as $file) + { + $this->load( str_replace( '_lang.php', '', $file ) ); + } + } + } +} + +?> diff --git a/application/libraries/Receiving_lib.php b/application/libraries/Receiving_lib.php new file mode 100644 index 000000000..52716ee4a --- /dev/null +++ b/application/libraries/Receiving_lib.php @@ -0,0 +1,251 @@ +CI =& get_instance(); + } + + function get_cart() + { + if(!$this->CI->session->userdata('cartRecv')) + $this->set_cart(array()); + + return $this->CI->session->userdata('cartRecv'); + } + + function set_cart($cart_data) + { + $this->CI->session->set_userdata('cartRecv',$cart_data); + } + + function get_supplier() + { + if(!$this->CI->session->userdata('supplier')) + $this->set_supplier(-1); + + return $this->CI->session->userdata('supplier'); + } + + function set_supplier($supplier_id) + { + $this->CI->session->set_userdata('supplier',$supplier_id); + } + + function get_mode() + { + if(!$this->CI->session->userdata('recv_mode')) + $this->set_mode('receive'); + + return $this->CI->session->userdata('recv_mode'); + } + + function set_mode($mode) + { + $this->CI->session->set_userdata('recv_mode',$mode); + } + + function add_item($item_id,$quantity=1,$discount=0,$price=null,$description=null,$serialnumber=null) + { + //make sure item exists in database. + if(!$this->CI->Item->exists($item_id)) + { + //try to get item id given an item_number + $item_id = $this->CI->Item->get_item_id($item_id); + + if(!$item_id) + return false; + } + + //Get items in the receiving so far. + $items = $this->get_cart(); + + //We need to loop through all items in the cart. + //If the item is already there, get it's key($updatekey). + //We also need to get the next key that we are going to use in case we need to add the + //item to the list. Since items can be deleted, we can't use a count. we use the highest key + 1. + + $maxkey=0; //Highest key so far + $itemalreadyinsale=FALSE; //We did not find the item yet. + $insertkey=0; //Key to use for new entry. + $updatekey=0; //Key to use to update(quantity) + + foreach ($items as $item) + { + //We primed the loop so maxkey is 0 the first time. + //Also, we have stored the key in the element itself so we can compare. + //There is an array function to get the associated key for an element, but I like it better + //like that! + + if($maxkey <= $item['line']) + { + $maxkey = $item['line']; + } + + if($item['item_id']==$item_id) + { + $itemalreadyinsale=TRUE; + $updatekey=$item['line']; + } + } + + $insertkey=$maxkey+1; + + //array records are identified by $insertkey and item_id is just another field. + $item = array(($insertkey)=> + array( + 'item_id'=>$item_id, + 'line'=>$insertkey, + 'name'=>$this->CI->Item->get_info($item_id)->name, + 'description'=>$description!=null ? $description: $this->CI->Item->get_info($item_id)->description, + 'serialnumber'=>$serialnumber!=null ? $serialnumber: '', + 'allow_alt_description'=>$this->CI->Item->get_info($item_id)->allow_alt_description, + 'is_serialized'=>$this->CI->Item->get_info($item_id)->is_serialized, + 'quantity'=>$quantity, + 'discount'=>$discount, + 'price'=>$price!=null ? $price: $this->CI->Item->get_info($item_id)->cost_price + ) + ); + + //Item already exists + if($itemalreadyinsale) + { + $items[$updatekey]['quantity']+=$quantity; + } + else + { + //add to existing array + $items+=$item; + } + + $this->set_cart($items); + return true; + + } + + function edit_item($line,$description,$serialnumber,$quantity,$discount,$price) + { + $items = $this->get_cart(); + if(isset($items[$line])) + { + $items[$line]['description'] = $description; + $items[$line]['serialnumber'] = $serialnumber; + $items[$line]['quantity'] = $quantity; + $items[$line]['discount'] = $discount; + $items[$line]['price'] = $price; + $this->set_cart($items); + } + + return false; + } + + function is_valid_receipt($receipt_receiving_id) + { + //RECV # + $pieces = explode(' ',$receipt_receiving_id); + + if(count($pieces)==2) + { + return $this->CI->Receiving->exists($pieces[1]); + } + + return false; + } + + function is_valid_item_kit($item_kit_id) + { + //KIT # + $pieces = explode(' ',$item_kit_id); + + if(count($pieces)==2) + { + return $this->CI->Item_kit->exists($pieces[1]); + } + + return false; + } + + function return_entire_receiving($receipt_receiving_id) + { + //POS # + $pieces = explode(' ',$receipt_receiving_id); + $receiving_id = $pieces[1]; + + $this->empty_cart(); + $this->delete_supplier(); + + foreach($this->CI->Receiving->get_receiving_items($receiving_id)->result() as $row) + { + $this->add_item($row->item_id,-$row->quantity_purchased,$row->discount_percent,$row->item_unit_price,$row->description,$row->serialnumber); + } + $this->set_supplier($this->CI->Receiving->get_supplier($receiving_id)->person_id); + } + + function add_item_kit($external_item_kit_id) + { + //KIT # + $pieces = explode(' ',$external_item_kit_id); + $item_kit_id = $pieces[1]; + + foreach ($this->CI->Item_kit_items->get_info($item_kit_id) as $item_kit_item) + { + $this->add_item($item_kit_item['item_id'], $item_kit_item['quantity']); + } + } + + function copy_entire_receiving($receiving_id) + { + $this->empty_cart(); + $this->delete_supplier(); + + foreach($this->CI->Receiving->get_receiving_items($receiving_id)->result() as $row) + { + $this->add_item($row->item_id,$row->quantity_purchased,$row->discount_percent,$row->item_unit_price,$row->description,$row->serialnumber); + } + $this->set_supplier($this->CI->Receiving->get_supplier($receiving_id)->person_id); + + } + + function delete_item($line) + { + $items=$this->get_cart(); + unset($items[$line]); + $this->set_cart($items); + } + + function empty_cart() + { + $this->CI->session->unset_userdata('cartRecv'); + } + + function delete_supplier() + { + $this->CI->session->unset_userdata('supplier'); + } + + function clear_mode() + { + $this->CI->session->unset_userdata('receiving_mode'); + } + + function clear_all() + { + $this->clear_mode(); + $this->empty_cart(); + $this->delete_supplier(); + } + + function get_total() + { + $total = 0; + foreach($this->get_cart() as $item) + { + $total+=($item['price']*$item['quantity']-$item['price']*$item['quantity']*$item['discount']/100); + } + + return $total; + } +} +?> \ No newline at end of file diff --git a/application/libraries/Sale_lib.php b/application/libraries/Sale_lib.php new file mode 100644 index 000000000..f7c75eb44 --- /dev/null +++ b/application/libraries/Sale_lib.php @@ -0,0 +1,498 @@ +CI =& get_instance(); + } + + function get_cart() + { + if(!$this->CI->session->userdata('cart')) + $this->set_cart(array()); + + return $this->CI->session->userdata('cart'); + } + + function set_cart($cart_data) + { + $this->CI->session->set_userdata('cart',$cart_data); + } + + //Alain Multiple Payments + function get_payments() + { + if( !$this->CI->session->userdata( 'payments' ) ) + $this->set_payments( array( ) ); + + return $this->CI->session->userdata('payments'); + } + + //Alain Multiple Payments + function set_payments($payments_data) + { + $this->CI->session->set_userdata('payments',$payments_data); + } + + function get_comment() + { + return $this->CI->session->userdata('comment'); + } + + function set_comment($comment) + { + $this->CI->session->set_userdata('comment', $comment); + } + + function clear_comment() + { + $this->CI->session->unset_userdata('comment'); + } + + function get_email_receipt() + { + return $this->CI->session->userdata('email_receipt'); + } + + function set_email_receipt($email_receipt) + { + $this->CI->session->set_userdata('email_receipt', $email_receipt); + } + + function clear_email_receipt() + { + $this->CI->session->unset_userdata('email_receipt'); + } + + function add_payment( $payment_id, $payment_amount ) + { + $payments = $this->get_payments(); + $payment = array( $payment_id=> + array( + 'payment_type' => $payment_id, + 'payment_amount' => $payment_amount + ) + ); + + //payment_method already exists, add to payment_amount + if( isset( $payments[$payment_id] ) ) + { + $payments[$payment_id]['payment_amount'] += $payment_amount; + } + else + { + //add to existing array + $payments += $payment; + } + + $this->set_payments( $payments ); + return true; + + } + + //Alain Multiple Payments + function edit_payment($payment_id,$payment_amount) + { + $payments = $this->get_payments(); + if(isset($payments[$payment_id])) + { + $payments[$payment_id]['payment_type'] = $payment_id; + $payments[$payment_id]['payment_amount'] = $payment_amount; + $this->set_payments($payment_id); + } + + return false; + } + + //Alain Multiple Payments + function delete_payment( $payment_id ) + { + $payments = $this->get_payments(); + unset( $payments[urldecode( $payment_id )] ); + $this->set_payments( $payments ); + } + + //Alain Multiple Payments + function empty_payments() + { + $this->CI->session->unset_userdata('payments'); + } + + //Alain Multiple Payments + function get_payments_total() + { + $subtotal = 0; + foreach($this->get_payments() as $payments) + { + $subtotal+=$payments['payment_amount']; + } + return to_currency_no_money($subtotal); + } + + //Alain Multiple Payments + function get_amount_due() + { + $amount_due=0; + $payment_total = $this->get_payments_total(); + $sales_total=$this->get_total(); + $amount_due=to_currency_no_money($sales_total - $payment_total); + return $amount_due; + } + + function get_customer() + { + if(!$this->CI->session->userdata('customer')) + $this->set_customer(-1); + + return $this->CI->session->userdata('customer'); + } + + function set_customer($customer_id) + { + $this->CI->session->set_userdata('customer',$customer_id); + } + + function get_mode() + { + if(!$this->CI->session->userdata('sale_mode')) + $this->set_mode('sale'); + + return $this->CI->session->userdata('sale_mode'); + } + + function set_mode($mode) + { + $this->CI->session->set_userdata('sale_mode',$mode); + } + + function add_item($item_id,$quantity=1,$discount=0,$price=null,$description=null,$serialnumber=null) + { + //make sure item exists + if(!$this->CI->Item->exists($item_id)) + { + //try to get item id given an item_number + $item_id = $this->CI->Item->get_item_id($item_id); + + if(!$item_id) + return false; + } + + + //Alain Serialization and Description + + //Get all items in the cart so far... + $items = $this->get_cart(); + + //We need to loop through all items in the cart. + //If the item is already there, get it's key($updatekey). + //We also need to get the next key that we are going to use in case we need to add the + //item to the cart. Since items can be deleted, we can't use a count. we use the highest key + 1. + + $maxkey=0; //Highest key so far + $itemalreadyinsale=FALSE; //We did not find the item yet. + $insertkey=0; //Key to use for new entry. + $updatekey=0; //Key to use to update(quantity) + + foreach ($items as $item) + { + //We primed the loop so maxkey is 0 the first time. + //Also, we have stored the key in the element itself so we can compare. + + if($maxkey <= $item['line']) + { + $maxkey = $item['line']; + } + + if($item['item_id']==$item_id) + { + $itemalreadyinsale=TRUE; + $updatekey=$item['line']; + } + } + + $insertkey=$maxkey+1; + + //array/cart records are identified by $insertkey and item_id is just another field. + $item = array(($insertkey)=> + array( + 'item_id'=>$item_id, + 'line'=>$insertkey, + 'name'=>$this->CI->Item->get_info($item_id)->name, + 'item_number'=>$this->CI->Item->get_info($item_id)->item_number, + 'description'=>$description!=null ? $description: $this->CI->Item->get_info($item_id)->description, + 'serialnumber'=>$serialnumber!=null ? $serialnumber: '', + 'allow_alt_description'=>$this->CI->Item->get_info($item_id)->allow_alt_description, + 'is_serialized'=>$this->CI->Item->get_info($item_id)->is_serialized, + 'quantity'=>$quantity, + 'discount'=>$discount, + 'price'=>$price!=null ? $price: $this->CI->Item->get_info($item_id)->unit_price + ) + ); + + //Item already exists and is not serialized, add to quantity + if($itemalreadyinsale && ($this->CI->Item->get_info($item_id)->is_serialized ==0) ) + { + $items[$updatekey]['quantity']+=$quantity; + } + else + { + //add to existing array + $items+=$item; + } + + $this->set_cart($items); + return true; + + } + + function out_of_stock($item_id) + { + //make sure item exists + if(!$this->CI->Item->exists($item_id)) + { + //try to get item id given an item_number + $item_id = $this->CI->Item->get_item_id($item_id); + + if(!$item_id) + return false; + } + + $item = $this->CI->Item->get_info($item_id); + $quanity_added = $this->get_quantity_already_added($item_id); + + if ($item->quantity - $quanity_added < 0) + { + return true; + } + + return false; + } + + function get_quantity_already_added($item_id) + { + $items = $this->get_cart(); + $quanity_already_added = 0; + foreach ($items as $item) + { + if($item['item_id']==$item_id) + { + $quanity_already_added+=$item['quantity']; + } + } + + return $quanity_already_added; + } + + function get_item_id($line_to_get) + { + $items = $this->get_cart(); + + foreach ($items as $line=>$item) + { + if($line==$line_to_get) + { + return $item['item_id']; + } + } + + return -1; + } + + function edit_item($line,$description,$serialnumber,$quantity,$discount,$price) + { + $items = $this->get_cart(); + if(isset($items[$line])) + { + $items[$line]['description'] = $description; + $items[$line]['serialnumber'] = $serialnumber; + $items[$line]['quantity'] = $quantity; + $items[$line]['discount'] = $discount; + $items[$line]['price'] = $price; + $this->set_cart($items); + } + + return false; + } + + function is_valid_receipt($receipt_sale_id) + { + //POS # + $pieces = explode(' ',$receipt_sale_id); + + if(count($pieces)==2) + { + return $this->CI->Sale->exists($pieces[1]); + } + + return false; + } + + function is_valid_item_kit($item_kit_id) + { + //KIT # + $pieces = explode(' ',$item_kit_id); + + if(count($pieces)==2) + { + return $this->CI->Item_kit->exists($pieces[1]); + } + + return false; + } + + function return_entire_sale($receipt_sale_id) + { + //POS # + $pieces = explode(' ',$receipt_sale_id); + $sale_id = $pieces[1]; + + $this->empty_cart(); + $this->remove_customer(); + + foreach($this->CI->Sale->get_sale_items($sale_id)->result() as $row) + { + $this->add_item($row->item_id,-$row->quantity_purchased,$row->discount_percent,$row->item_unit_price,$row->description,$row->serialnumber); + } + $this->set_customer($this->CI->Sale->get_customer($sale_id)->person_id); + } + + function add_item_kit($external_item_kit_id) + { + //KIT # + $pieces = explode(' ',$external_item_kit_id); + $item_kit_id = $pieces[1]; + + foreach ($this->CI->Item_kit_items->get_info($item_kit_id) as $item_kit_item) + { + $this->add_item($item_kit_item['item_id'], $item_kit_item['quantity']); + } + } + + function copy_entire_sale($sale_id) + { + $this->empty_cart(); + $this->remove_customer(); + + foreach($this->CI->Sale->get_sale_items($sale_id)->result() as $row) + { + $this->add_item($row->item_id,$row->quantity_purchased,$row->discount_percent,$row->item_unit_price,$row->description,$row->serialnumber); + } + foreach($this->CI->Sale->get_sale_payments($sale_id)->result() as $row) + { + $this->add_payment($row->payment_type,$row->payment_amount); + } + $this->set_customer($this->CI->Sale->get_customer($sale_id)->person_id); + + } + + function copy_entire_suspended_sale($sale_id) + { + $this->empty_cart(); + $this->remove_customer(); + + foreach($this->CI->Sale_suspended->get_sale_items($sale_id)->result() as $row) + { + $this->add_item($row->item_id,$row->quantity_purchased,$row->discount_percent,$row->item_unit_price,$row->description,$row->serialnumber); + } + foreach($this->CI->Sale_suspended->get_sale_payments($sale_id)->result() as $row) + { + $this->add_payment($row->payment_type,$row->payment_amount); + } + $this->set_customer($this->CI->Sale_suspended->get_customer($sale_id)->person_id); + $this->set_comment($this->CI->Sale_suspended->get_comment($sale_id)); + } + + function delete_item($line) + { + $items=$this->get_cart(); + unset($items[$line]); + $this->set_cart($items); + } + + function empty_cart() + { + $this->CI->session->unset_userdata('cart'); + } + + function remove_customer() + { + $this->CI->session->unset_userdata('customer'); + } + + function clear_mode() + { + $this->CI->session->unset_userdata('sale_mode'); + } + + function clear_all() + { + $this->clear_mode(); + $this->empty_cart(); + $this->clear_comment(); + $this->clear_email_receipt(); + $this->empty_payments(); + $this->remove_customer(); + } + + function get_taxes() + { + $customer_id = $this->get_customer(); + $customer = $this->CI->Customer->get_info($customer_id); + + //Do not charge sales tax if we have a customer that is not taxable + if (!$customer->taxable and $customer_id!=-1) + { + return array(); + } + + $taxes = array(); + foreach($this->get_cart() as $line=>$item) + { + $tax_info = $this->CI->Item_taxes->get_info($item['item_id']); + + foreach($tax_info as $tax) + { + $name = $tax['percent'].'% ' . $tax['name']; + $tax_amount=($item['price']*$item['quantity']-$item['price']*$item['quantity']*$item['discount']/100)*(($tax['percent'])/100); + + + if (!isset($taxes[$name])) + { + $taxes[$name] = 0; + } + $taxes[$name] += $tax_amount; + } + } + + return $taxes; + } + + function get_subtotal() + { + $subtotal = 0; + foreach($this->get_cart() as $item) + { + $subtotal+=($item['price']*$item['quantity']-$item['price']*$item['quantity']*$item['discount']/100); + } + return to_currency_no_money($subtotal); + } + + function get_total() + { + $total = 0; + foreach($this->get_cart() as $item) + { + $total += ( $item['price'] * $item['quantity'] - $item['price'] * $item['quantity'] * $item['discount'] / 100); + } + + foreach($this->get_taxes() as $tax) + { + $total+=$tax; + } + + return to_currency_no_money($total); + } +} +?> \ No newline at end of file diff --git a/application/libraries/index.html b/application/libraries/index.html new file mode 100644 index 000000000..c942a79ce --- /dev/null +++ b/application/libraries/index.html @@ -0,0 +1,10 @@ + + +Directory access is forbidden.
+ + + \ No newline at end of file diff --git a/application/libraries/ofc-library/JSON.php b/application/libraries/ofc-library/JSON.php new file mode 100644 index 000000000..0cddbddb4 --- /dev/null +++ b/application/libraries/ofc-library/JSON.php @@ -0,0 +1,806 @@ + + * @author Matt Knapp
+ * // create a new instance of Services_JSON
+ * $json = new Services_JSON();
+ *
+ * // convert a complexe value to JSON notation, and send it to the browser
+ * $value = array('foo', 'bar', array(1, 2, 'baz'), array(3, array(4)));
+ * $output = $json->encode($value);
+ *
+ * print($output);
+ * // prints: ["foo","bar",[1,2,"baz"],[3,[4]]]
+ *
+ * // accept incoming POST data, assumed to be in JSON notation
+ * $input = file_get_contents('php://input', 1000000);
+ * $value = $json->decode($input);
+ *
+ */
+class Services_JSON
+{
+ /**
+ * constructs a new JSON instance
+ *
+ * @param int $use object behavior flags; combine with boolean-OR
+ *
+ * possible values:
+ * - SERVICES_JSON_LOOSE_TYPE: loose typing.
+ * "{...}" syntax creates associative arrays
+ * instead of objects in decode().
+ * - SERVICES_JSON_SUPPRESS_ERRORS: error suppression.
+ * Values which can't be encoded (e.g. resources)
+ * appear as NULL instead of throwing errors.
+ * By default, a deeply-nested resource will
+ * bubble up with an error, so all return values
+ * from encode() should be checked with isError()
+ */
+ function Services_JSON($use = 0)
+ {
+ $this->use = $use;
+ }
+
+ /**
+ * convert a string from one UTF-16 char to one UTF-8 char
+ *
+ * Normally should be handled by mb_convert_encoding, but
+ * provides a slower PHP-only method for installations
+ * that lack the multibye string extension.
+ *
+ * @param string $utf16 UTF-16 character
+ * @return string UTF-8 character
+ * @access private
+ */
+ function utf162utf8($utf16)
+ {
+ // oh please oh please oh please oh please oh please
+ if(function_exists('mb_convert_encoding')) {
+ return mb_convert_encoding($utf16, 'UTF-8', 'UTF-16');
+ }
+
+ $bytes = (ord($utf16{0}) << 8) | ord($utf16{1});
+
+ switch(true) {
+ case ((0x7F & $bytes) == $bytes):
+ // this case should never be reached, because we are in ASCII range
+ // see: http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
+ return chr(0x7F & $bytes);
+
+ case (0x07FF & $bytes) == $bytes:
+ // return a 2-byte UTF-8 character
+ // see: http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
+ return chr(0xC0 | (($bytes >> 6) & 0x1F))
+ . chr(0x80 | ($bytes & 0x3F));
+
+ case (0xFFFF & $bytes) == $bytes:
+ // return a 3-byte UTF-8 character
+ // see: http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
+ return chr(0xE0 | (($bytes >> 12) & 0x0F))
+ . chr(0x80 | (($bytes >> 6) & 0x3F))
+ . chr(0x80 | ($bytes & 0x3F));
+ }
+
+ // ignoring UTF-32 for now, sorry
+ return '';
+ }
+
+ /**
+ * convert a string from one UTF-8 char to one UTF-16 char
+ *
+ * Normally should be handled by mb_convert_encoding, but
+ * provides a slower PHP-only method for installations
+ * that lack the multibye string extension.
+ *
+ * @param string $utf8 UTF-8 character
+ * @return string UTF-16 character
+ * @access private
+ */
+ function utf82utf16($utf8)
+ {
+ // oh please oh please oh please oh please oh please
+ if(function_exists('mb_convert_encoding')) {
+ return mb_convert_encoding($utf8, 'UTF-16', 'UTF-8');
+ }
+
+ switch(strlen($utf8)) {
+ case 1:
+ // this case should never be reached, because we are in ASCII range
+ // see: http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
+ return $utf8;
+
+ case 2:
+ // return a UTF-16 character from a 2-byte UTF-8 char
+ // see: http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
+ return chr(0x07 & (ord($utf8{0}) >> 2))
+ . chr((0xC0 & (ord($utf8{0}) << 6))
+ | (0x3F & ord($utf8{1})));
+
+ case 3:
+ // return a UTF-16 character from a 3-byte UTF-8 char
+ // see: http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
+ return chr((0xF0 & (ord($utf8{0}) << 4))
+ | (0x0F & (ord($utf8{1}) >> 2)))
+ . chr((0xC0 & (ord($utf8{1}) << 6))
+ | (0x7F & ord($utf8{2})));
+ }
+
+ // ignoring UTF-32 for now, sorry
+ return '';
+ }
+
+ /**
+ * encodes an arbitrary variable into JSON format
+ *
+ * @param mixed $var any number, boolean, string, array, or object to be encoded.
+ * see argument 1 to Services_JSON() above for array-parsing behavior.
+ * if var is a strng, note that encode() always expects it
+ * to be in ASCII or UTF-8 format!
+ *
+ * @return mixed JSON string representation of input var or an error if a problem occurs
+ * @access public
+ */
+ function encode($var)
+ {
+ switch (gettype($var)) {
+ case 'boolean':
+ return $var ? 'true' : 'false';
+
+ case 'NULL':
+ return 'null';
+
+ case 'integer':
+ return (int) $var;
+
+ case 'double':
+ case 'float':
+ return (float) $var;
+
+ case 'string':
+ // STRINGS ARE EXPECTED TO BE IN ASCII OR UTF-8 FORMAT
+ $ascii = '';
+ $strlen_var = strlen($var);
+
+ /*
+ * Iterate over every character in the string,
+ * escaping with a slash or encoding to UTF-8 where necessary
+ */
+ for ($c = 0; $c < $strlen_var; ++$c) {
+
+ $ord_var_c = ord($var{$c});
+
+ switch (true) {
+ case $ord_var_c == 0x08:
+ $ascii .= '\b';
+ break;
+ case $ord_var_c == 0x09:
+ $ascii .= '\t';
+ break;
+ case $ord_var_c == 0x0A:
+ $ascii .= '\n';
+ break;
+ case $ord_var_c == 0x0C:
+ $ascii .= '\f';
+ break;
+ case $ord_var_c == 0x0D:
+ $ascii .= '\r';
+ break;
+
+ case $ord_var_c == 0x22:
+ case $ord_var_c == 0x2F:
+ case $ord_var_c == 0x5C:
+ // double quote, slash, slosh
+ $ascii .= '\\'.$var{$c};
+ break;
+
+ case (($ord_var_c >= 0x20) && ($ord_var_c <= 0x7F)):
+ // characters U-00000000 - U-0000007F (same as ASCII)
+ $ascii .= $var{$c};
+ break;
+
+ case (($ord_var_c & 0xE0) == 0xC0):
+ // characters U-00000080 - U-000007FF, mask 110XXXXX
+ // see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
+ $char = pack('C*', $ord_var_c, ord($var{$c + 1}));
+ $c += 1;
+ $utf16 = $this->utf82utf16($char);
+ $ascii .= sprintf('\u%04s', bin2hex($utf16));
+ break;
+
+ case (($ord_var_c & 0xF0) == 0xE0):
+ // characters U-00000800 - U-0000FFFF, mask 1110XXXX
+ // see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
+ $char = pack('C*', $ord_var_c,
+ ord($var{$c + 1}),
+ ord($var{$c + 2}));
+ $c += 2;
+ $utf16 = $this->utf82utf16($char);
+ $ascii .= sprintf('\u%04s', bin2hex($utf16));
+ break;
+
+ case (($ord_var_c & 0xF8) == 0xF0):
+ // characters U-00010000 - U-001FFFFF, mask 11110XXX
+ // see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
+ $char = pack('C*', $ord_var_c,
+ ord($var{$c + 1}),
+ ord($var{$c + 2}),
+ ord($var{$c + 3}));
+ $c += 3;
+ $utf16 = $this->utf82utf16($char);
+ $ascii .= sprintf('\u%04s', bin2hex($utf16));
+ break;
+
+ case (($ord_var_c & 0xFC) == 0xF8):
+ // characters U-00200000 - U-03FFFFFF, mask 111110XX
+ // see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
+ $char = pack('C*', $ord_var_c,
+ ord($var{$c + 1}),
+ ord($var{$c + 2}),
+ ord($var{$c + 3}),
+ ord($var{$c + 4}));
+ $c += 4;
+ $utf16 = $this->utf82utf16($char);
+ $ascii .= sprintf('\u%04s', bin2hex($utf16));
+ break;
+
+ case (($ord_var_c & 0xFE) == 0xFC):
+ // characters U-04000000 - U-7FFFFFFF, mask 1111110X
+ // see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
+ $char = pack('C*', $ord_var_c,
+ ord($var{$c + 1}),
+ ord($var{$c + 2}),
+ ord($var{$c + 3}),
+ ord($var{$c + 4}),
+ ord($var{$c + 5}));
+ $c += 5;
+ $utf16 = $this->utf82utf16($char);
+ $ascii .= sprintf('\u%04s', bin2hex($utf16));
+ break;
+ }
+ }
+
+ return '"'.$ascii.'"';
+
+ case 'array':
+ /*
+ * As per JSON spec if any array key is not an integer
+ * we must treat the the whole array as an object. We
+ * also try to catch a sparsely populated associative
+ * array with numeric keys here because some JS engines
+ * will create an array with empty indexes up to
+ * max_index which can cause memory issues and because
+ * the keys, which may be relevant, will be remapped
+ * otherwise.
+ *
+ * As per the ECMA and JSON specification an object may
+ * have any string as a property. Unfortunately due to
+ * a hole in the ECMA specification if the key is a
+ * ECMA reserved word or starts with a digit the
+ * parameter is only accessible using ECMAScript's
+ * bracket notation.
+ */
+
+ // treat as a JSON object
+ if (is_array($var) && count($var) && (array_keys($var) !== range(0, sizeof($var) - 1))) {
+ $properties = array_map(array($this, 'name_value'),
+ array_keys($var),
+ array_values($var));
+
+ foreach($properties as $property) {
+ if(Services_JSON::isError($property)) {
+ return $property;
+ }
+ }
+
+ return '{' . join(',', $properties) . '}';
+ }
+
+ // treat it like a regular array
+ $elements = array_map(array($this, 'encode'), $var);
+
+ foreach($elements as $element) {
+ if(Services_JSON::isError($element)) {
+ return $element;
+ }
+ }
+
+ return '[' . join(',', $elements) . ']';
+
+ case 'object':
+ $vars = get_object_vars($var);
+
+ $properties = array_map(array($this, 'name_value'),
+ array_keys($vars),
+ array_values($vars));
+
+ foreach($properties as $property) {
+ if(Services_JSON::isError($property)) {
+ return $property;
+ }
+ }
+
+ return '{' . join(',', $properties) . '}';
+
+ default:
+ return ($this->use & SERVICES_JSON_SUPPRESS_ERRORS)
+ ? 'null'
+ : new Services_JSON_Error(gettype($var)." can not be encoded as JSON string");
+ }
+ }
+
+ /**
+ * array-walking function for use in generating JSON-formatted name-value pairs
+ *
+ * @param string $name name of key to use
+ * @param mixed $value reference to an array element to be encoded
+ *
+ * @return string JSON-formatted name-value pair, like '"name":value'
+ * @access private
+ */
+ function name_value($name, $value)
+ {
+ $encoded_value = $this->encode($value);
+
+ if(Services_JSON::isError($encoded_value)) {
+ return $encoded_value;
+ }
+
+ return $this->encode(strval($name)) . ':' . $encoded_value;
+ }
+
+ /**
+ * reduce a string by removing leading and trailing comments and whitespace
+ *
+ * @param $str string string value to strip of comments and whitespace
+ *
+ * @return string string value stripped of comments and whitespace
+ * @access private
+ */
+ function reduce_string($str)
+ {
+ $str = preg_replace(array(
+
+ // eliminate single line comments in '// ...' form
+ '#^\s*//(.+)$#m',
+
+ // eliminate multi-line comments in '/* ... */' form, at start of string
+ '#^\s*/\*(.+)\*/#Us',
+
+ // eliminate multi-line comments in '/* ... */' form, at end of string
+ '#/\*(.+)\*/\s*$#Us'
+
+ ), '', $str);
+
+ // eliminate extraneous space
+ return trim($str);
+ }
+
+ /**
+ * decodes a JSON string into appropriate variable
+ *
+ * @param string $str JSON-formatted string
+ *
+ * @return mixed number, boolean, string, array, or object
+ * corresponding to given JSON input string.
+ * See argument 1 to Services_JSON() above for object-output behavior.
+ * Note that decode() always returns strings
+ * in ASCII or UTF-8 format!
+ * @access public
+ */
+ function decode($str)
+ {
+ $str = $this->reduce_string($str);
+
+ switch (strtolower($str)) {
+ case 'true':
+ return true;
+
+ case 'false':
+ return false;
+
+ case 'null':
+ return null;
+
+ default:
+ $m = array();
+
+ if (is_numeric($str)) {
+ // Lookie-loo, it's a number
+
+ // This would work on its own, but I'm trying to be
+ // good about returning integers where appropriate:
+ // return (float)$str;
+
+ // Return float or int, as appropriate
+ return ((float)$str == (integer)$str)
+ ? (integer)$str
+ : (float)$str;
+
+ } elseif (preg_match('/^("|\').*(\1)$/s', $str, $m) && $m[1] == $m[2]) {
+ // STRINGS RETURNED IN UTF-8 FORMAT
+ $delim = substr($str, 0, 1);
+ $chrs = substr($str, 1, -1);
+ $utf8 = '';
+ $strlen_chrs = strlen($chrs);
+
+ for ($c = 0; $c < $strlen_chrs; ++$c) {
+
+ $substr_chrs_c_2 = substr($chrs, $c, 2);
+ $ord_chrs_c = ord($chrs{$c});
+
+ switch (true) {
+ case $substr_chrs_c_2 == '\b':
+ $utf8 .= chr(0x08);
+ ++$c;
+ break;
+ case $substr_chrs_c_2 == '\t':
+ $utf8 .= chr(0x09);
+ ++$c;
+ break;
+ case $substr_chrs_c_2 == '\n':
+ $utf8 .= chr(0x0A);
+ ++$c;
+ break;
+ case $substr_chrs_c_2 == '\f':
+ $utf8 .= chr(0x0C);
+ ++$c;
+ break;
+ case $substr_chrs_c_2 == '\r':
+ $utf8 .= chr(0x0D);
+ ++$c;
+ break;
+
+ case $substr_chrs_c_2 == '\\"':
+ case $substr_chrs_c_2 == '\\\'':
+ case $substr_chrs_c_2 == '\\\\':
+ case $substr_chrs_c_2 == '\\/':
+ if (($delim == '"' && $substr_chrs_c_2 != '\\\'') ||
+ ($delim == "'" && $substr_chrs_c_2 != '\\"')) {
+ $utf8 .= $chrs{++$c};
+ }
+ break;
+
+ case preg_match('/\\\u[0-9A-F]{4}/i', substr($chrs, $c, 6)):
+ // single, escaped unicode character
+ $utf16 = chr(hexdec(substr($chrs, ($c + 2), 2)))
+ . chr(hexdec(substr($chrs, ($c + 4), 2)));
+ $utf8 .= $this->utf162utf8($utf16);
+ $c += 5;
+ break;
+
+ case ($ord_chrs_c >= 0x20) && ($ord_chrs_c <= 0x7F):
+ $utf8 .= $chrs{$c};
+ break;
+
+ case ($ord_chrs_c & 0xE0) == 0xC0:
+ // characters U-00000080 - U-000007FF, mask 110XXXXX
+ //see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
+ $utf8 .= substr($chrs, $c, 2);
+ ++$c;
+ break;
+
+ case ($ord_chrs_c & 0xF0) == 0xE0:
+ // characters U-00000800 - U-0000FFFF, mask 1110XXXX
+ // see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
+ $utf8 .= substr($chrs, $c, 3);
+ $c += 2;
+ break;
+
+ case ($ord_chrs_c & 0xF8) == 0xF0:
+ // characters U-00010000 - U-001FFFFF, mask 11110XXX
+ // see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
+ $utf8 .= substr($chrs, $c, 4);
+ $c += 3;
+ break;
+
+ case ($ord_chrs_c & 0xFC) == 0xF8:
+ // characters U-00200000 - U-03FFFFFF, mask 111110XX
+ // see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
+ $utf8 .= substr($chrs, $c, 5);
+ $c += 4;
+ break;
+
+ case ($ord_chrs_c & 0xFE) == 0xFC:
+ // characters U-04000000 - U-7FFFFFFF, mask 1111110X
+ // see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
+ $utf8 .= substr($chrs, $c, 6);
+ $c += 5;
+ break;
+
+ }
+
+ }
+
+ return $utf8;
+
+ } elseif (preg_match('/^\[.*\]$/s', $str) || preg_match('/^\{.*\}$/s', $str)) {
+ // array, or object notation
+
+ if ($str{0} == '[') {
+ $stk = array(SERVICES_JSON_IN_ARR);
+ $arr = array();
+ } else {
+ if ($this->use & SERVICES_JSON_LOOSE_TYPE) {
+ $stk = array(SERVICES_JSON_IN_OBJ);
+ $obj = array();
+ } else {
+ $stk = array(SERVICES_JSON_IN_OBJ);
+ $obj = new stdClass();
+ }
+ }
+
+ array_push($stk, array('what' => SERVICES_JSON_SLICE,
+ 'where' => 0,
+ 'delim' => false));
+
+ $chrs = substr($str, 1, -1);
+ $chrs = $this->reduce_string($chrs);
+
+ if ($chrs == '') {
+ if (reset($stk) == SERVICES_JSON_IN_ARR) {
+ return $arr;
+
+ } else {
+ return $obj;
+
+ }
+ }
+
+ //print("\nparsing {$chrs}\n");
+
+ $strlen_chrs = strlen($chrs);
+
+ for ($c = 0; $c <= $strlen_chrs; ++$c) {
+
+ $top = end($stk);
+ $substr_chrs_c_2 = substr($chrs, $c, 2);
+
+ if (($c == $strlen_chrs) || (($chrs{$c} == ',') && ($top['what'] == SERVICES_JSON_SLICE))) {
+ // found a comma that is not inside a string, array, etc.,
+ // OR we've reached the end of the character list
+ $slice = substr($chrs, $top['where'], ($c - $top['where']));
+ array_push($stk, array('what' => SERVICES_JSON_SLICE, 'where' => ($c + 1), 'delim' => false));
+ //print("Found split at {$c}: ".substr($chrs, $top['where'], (1 + $c - $top['where']))."\n");
+
+ if (reset($stk) == SERVICES_JSON_IN_ARR) {
+ // we are in an array, so just push an element onto the stack
+ array_push($arr, $this->decode($slice));
+
+ } elseif (reset($stk) == SERVICES_JSON_IN_OBJ) {
+ // we are in an object, so figure
+ // out the property name and set an
+ // element in an associative array,
+ // for now
+ $parts = array();
+
+ if (preg_match('/^\s*(["\'].*[^\\\]["\'])\s*:\s*(\S.*),?$/Uis', $slice, $parts)) {
+ // "name":value pair
+ $key = $this->decode($parts[1]);
+ $val = $this->decode($parts[2]);
+
+ if ($this->use & SERVICES_JSON_LOOSE_TYPE) {
+ $obj[$key] = $val;
+ } else {
+ $obj->$key = $val;
+ }
+ } elseif (preg_match('/^\s*(\w+)\s*:\s*(\S.*),?$/Uis', $slice, $parts)) {
+ // name:value pair, where name is unquoted
+ $key = $parts[1];
+ $val = $this->decode($parts[2]);
+
+ if ($this->use & SERVICES_JSON_LOOSE_TYPE) {
+ $obj[$key] = $val;
+ } else {
+ $obj->$key = $val;
+ }
+ }
+
+ }
+
+ } elseif ((($chrs{$c} == '"') || ($chrs{$c} == "'")) && ($top['what'] != SERVICES_JSON_IN_STR)) {
+ // found a quote, and we are not inside a string
+ array_push($stk, array('what' => SERVICES_JSON_IN_STR, 'where' => $c, 'delim' => $chrs{$c}));
+ //print("Found start of string at {$c}\n");
+
+ } elseif (($chrs{$c} == $top['delim']) &&
+ ($top['what'] == SERVICES_JSON_IN_STR) &&
+ ((strlen(substr($chrs, 0, $c)) - strlen(rtrim(substr($chrs, 0, $c), '\\'))) % 2 != 1)) {
+ // found a quote, we're in a string, and it's not escaped
+ // we know that it's not escaped becase there is _not_ an
+ // odd number of backslashes at the end of the string so far
+ array_pop($stk);
+ //print("Found end of string at {$c}: ".substr($chrs, $top['where'], (1 + 1 + $c - $top['where']))."\n");
+
+ } elseif (($chrs{$c} == '[') &&
+ in_array($top['what'], array(SERVICES_JSON_SLICE, SERVICES_JSON_IN_ARR, SERVICES_JSON_IN_OBJ))) {
+ // found a left-bracket, and we are in an array, object, or slice
+ array_push($stk, array('what' => SERVICES_JSON_IN_ARR, 'where' => $c, 'delim' => false));
+ //print("Found start of array at {$c}\n");
+
+ } elseif (($chrs{$c} == ']') && ($top['what'] == SERVICES_JSON_IN_ARR)) {
+ // found a right-bracket, and we're in an array
+ array_pop($stk);
+ //print("Found end of array at {$c}: ".substr($chrs, $top['where'], (1 + $c - $top['where']))."\n");
+
+ } elseif (($chrs{$c} == '{') &&
+ in_array($top['what'], array(SERVICES_JSON_SLICE, SERVICES_JSON_IN_ARR, SERVICES_JSON_IN_OBJ))) {
+ // found a left-brace, and we are in an array, object, or slice
+ array_push($stk, array('what' => SERVICES_JSON_IN_OBJ, 'where' => $c, 'delim' => false));
+ //print("Found start of object at {$c}\n");
+
+ } elseif (($chrs{$c} == '}') && ($top['what'] == SERVICES_JSON_IN_OBJ)) {
+ // found a right-brace, and we're in an object
+ array_pop($stk);
+ //print("Found end of object at {$c}: ".substr($chrs, $top['where'], (1 + $c - $top['where']))."\n");
+
+ } elseif (($substr_chrs_c_2 == '/*') &&
+ in_array($top['what'], array(SERVICES_JSON_SLICE, SERVICES_JSON_IN_ARR, SERVICES_JSON_IN_OBJ))) {
+ // found a comment start, and we are in an array, object, or slice
+ array_push($stk, array('what' => SERVICES_JSON_IN_CMT, 'where' => $c, 'delim' => false));
+ $c++;
+ //print("Found start of comment at {$c}\n");
+
+ } elseif (($substr_chrs_c_2 == '*/') && ($top['what'] == SERVICES_JSON_IN_CMT)) {
+ // found a comment end, and we're in one now
+ array_pop($stk);
+ $c++;
+
+ for ($i = $top['where']; $i <= $c; ++$i)
+ $chrs = substr_replace($chrs, ' ', $i, 1);
+
+ //print("Found end of comment at {$c}: ".substr($chrs, $top['where'], (1 + $c - $top['where']))."\n");
+
+ }
+
+ }
+
+ if (reset($stk) == SERVICES_JSON_IN_ARR) {
+ return $arr;
+
+ } elseif (reset($stk) == SERVICES_JSON_IN_OBJ) {
+ return $obj;
+
+ }
+
+ }
+ }
+ }
+
+ /**
+ * @todo Ultimately, this should just call PEAR::isError()
+ */
+ function isError($data, $code = null)
+ {
+ if (class_exists('pear')) {
+ return PEAR::isError($data, $code);
+ } elseif (is_object($data) && (get_class($data) == 'services_json_error' ||
+ is_subclass_of($data, 'services_json_error'))) {
+ return true;
+ }
+
+ return false;
+ }
+}
+
+if (class_exists('PEAR_Error')) {
+
+ class Services_JSON_Error extends PEAR_Error
+ {
+ function Services_JSON_Error($message = 'unknown error', $code = null,
+ $mode = null, $options = null, $userinfo = null)
+ {
+ parent::PEAR_Error($message, $code, $mode, $options, $userinfo);
+ }
+ }
+
+} else {
+
+ /**
+ * @todo Ultimately, this class shall be descended from PEAR_Error
+ */
+ class Services_JSON_Error
+ {
+ function Services_JSON_Error($message = 'unknown error', $code = null,
+ $mode = null, $options = null, $userinfo = null)
+ {
+
+ }
+ }
+
+}
+
+?>
diff --git a/application/libraries/ofc-library/README.txt b/application/libraries/ofc-library/README.txt
new file mode 100644
index 000000000..012fbfd52
--- /dev/null
+++ b/application/libraries/ofc-library/README.txt
@@ -0,0 +1,16 @@
+Open Flash Chart - PHP libraries. These help create data files for Open Flash Chart.
+Copyright (C) 2007
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License, or (at your option) any later version.
+
+This library 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
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
\ No newline at end of file
diff --git a/application/libraries/ofc-library/dot_base.php b/application/libraries/ofc-library/dot_base.php
new file mode 100644
index 000000000..5772efcd9
--- /dev/null
+++ b/application/libraries/ofc-library/dot_base.php
@@ -0,0 +1,231 @@
+type = $type;
+ if( isset( $value ) )
+ $this->value( $value );
+ }
+
+ /**
+ * For line charts that only require a Y position
+ * for each point.
+ * @param $value as integer, the Y position
+ */
+ function value( $value )
+ {
+ $this->value = $value;
+ }
+
+ /**
+ * For scatter charts that require an X and Y position for
+ * each point.
+ *
+ * @param $x as integer
+ * @param $y as integer
+ */
+ function position( $x, $y )
+ {
+ $this->x = $x;
+ $this->y = $y;
+ }
+
+ /**
+ * @param $colour is a string, HEX colour, e.g. '#FF0000' red
+ */
+ function colour($colour)
+ {
+ $this->colour = $colour;
+ return $this;
+ }
+
+ /**
+ * The tooltip for this dot.
+ */
+ function tooltip( $tip )
+ {
+ $this->tip = $tip;
+ return $this;
+ }
+
+ /**
+ * @param $size is an integer. Size of the dot.
+ */
+ function size($size)
+ {
+ $tmp = 'dot-size';
+ $this->$tmp = $size;
+ return $this;
+ }
+
+ /**
+ * a private method
+ */
+ function type( $type )
+ {
+ $this->type = $type;
+ return $this;
+ }
+
+ /**
+ * @param $size is an integer. The size of the hollow 'halo' around the dot that masks the line.
+ */
+ function halo_size( $size )
+ {
+ $tmp = 'halo-size';
+ $this->$tmp = $size;
+ return $this;
+ }
+
+ /**
+ * @param $do as string. One of three options (examples):
+ * - "http://example.com" - browse to this URL
+ * - "https://example.com" - browse to this URL
+ * - "trace:message" - print this message in the FlashDevelop debug pane
+ * - all other strings will be called as Javascript functions, so a string "hello_world"
+ * will call the JS function "hello_world(index)". It passes in the index of the
+ * point.
+ */
+ function on_click( $do )
+ {
+ $tmp = 'on-click';
+ $this->$tmp = $do;
+ }
+}
+
+/**
+ * Draw a hollow dot
+ */
+class hollow_dot extends dot_base
+{
+ function hollow_dot($value=null)
+ {
+ parent::dot_base( 'hollow-dot', $value );
+ }
+}
+
+/**
+ * Draw a star
+ */
+class star extends dot_base
+{
+ /**
+ * The constructor, takes an optional $value
+ */
+ function star($value=null)
+ {
+ parent::dot_base( 'star', $value );
+ }
+
+ /**
+ * @param $angle is an integer.
+ */
+ function rotation($angle)
+ {
+ $this->rotation = $angle;
+ return $this;
+ }
+
+ /**
+ * @param $is_hollow is a boolean.
+ */
+ function hollow($is_hollow)
+ {
+ $this->hollow = $is_hollow;
+ }
+}
+
+/**
+ * Draw a 'bow tie' shape.
+ */
+class bow extends dot_base
+{
+ /**
+ * The constructor, takes an optional $value
+ */
+ function bow($value=null)
+ {
+ parent::dot_base( 'bow', $value );
+ }
+
+ /**
+ * Rotate the anchor object.
+ * @param $angle is an integer.
+ */
+ function rotation($angle)
+ {
+ $this->rotation = $angle;
+ return $this;
+ }
+}
+
+/**
+ * An n sided shape.
+ */
+class anchor extends dot_base
+{
+ /**
+ * The constructor, takes an optional $value
+ */
+ function anchor($value=null)
+ {
+ parent::dot_base( 'anchor', $value );
+ }
+
+ /**
+ * Rotate the anchor object.
+ * @param $angle is an integer.
+ */
+ function rotation($angle)
+ {
+ $this->rotation = $angle;
+ return $this;
+ }
+
+ /**
+ * @param $sides is an integer. Number of sides this shape has.
+ */
+ function sides($sides)
+ {
+ $this->sides = $sides;
+ return $this;
+ }
+}
+
+/**
+ * A simple dot
+ */
+class dot extends dot_base
+{
+ /**
+ * The constructor, takes an optional $value
+ */
+ function dot($value=null)
+ {
+ parent::dot_base( 'dot', $value );
+ }
+}
+
+/**
+ * A simple dot
+ */
+class solid_dot extends dot_base
+{
+ /**
+ * The constructor, takes an optional $value
+ */
+ function solid_dot($value=null)
+ {
+ parent::dot_base( 'solid-dot', $value );
+ }
+}
\ No newline at end of file
diff --git a/application/libraries/ofc-library/json_format.php b/application/libraries/ofc-library/json_format.php
new file mode 100644
index 000000000..b8e3de5cb
--- /dev/null
+++ b/application/libraries/ofc-library/json_format.php
@@ -0,0 +1,86 @@
+ 0 && $json[$c-1] != '\\')
+ {
+ $in_string = !$in_string;
+ }
+ default:
+ $new_json .= $char;
+ break;
+ }
+ }
+
+ return $new_json;
+}
\ No newline at end of file
diff --git a/application/libraries/ofc-library/ofc_area_base.php b/application/libraries/ofc-library/ofc_area_base.php
new file mode 100644
index 000000000..a6e811fd5
--- /dev/null
+++ b/application/libraries/ofc-library/ofc_area_base.php
@@ -0,0 +1,40 @@
+type = "area";
+ }
+
+ /**
+ * the fill colour
+ */
+ function set_fill_colour( $colour )
+ {
+ $this->fill = $colour;
+ }
+
+ /**
+ * sugar: see set_fill_colour
+ */
+ function fill_colour( $colour )
+ {
+ $this->set_fill_colour( $colour );
+ return $this;
+ }
+
+ function set_fill_alpha( $alpha )
+ {
+ $tmp = "fill-alpha";
+ $this->$tmp = $alpha;
+ }
+
+ function set_loop()
+ {
+ $this->loop = true;
+ }
+}
diff --git a/application/libraries/ofc-library/ofc_area_hollow.php b/application/libraries/ofc-library/ofc_area_hollow.php
new file mode 100644
index 000000000..4293af0b6
--- /dev/null
+++ b/application/libraries/ofc-library/ofc_area_hollow.php
@@ -0,0 +1,10 @@
+type = "area_hollow";
+ parent::area_base();
+ }
+}
diff --git a/application/libraries/ofc-library/ofc_area_line.php b/application/libraries/ofc-library/ofc_area_line.php
new file mode 100644
index 000000000..5731391a3
--- /dev/null
+++ b/application/libraries/ofc-library/ofc_area_line.php
@@ -0,0 +1,10 @@
+type = "area_line";
+ parent::area_base();
+ }
+}
diff --git a/application/libraries/ofc-library/ofc_arrow.php b/application/libraries/ofc-library/ofc_arrow.php
new file mode 100644
index 000000000..3c2c6e9dc
--- /dev/null
+++ b/application/libraries/ofc-library/ofc_arrow.php
@@ -0,0 +1,27 @@
+type = "arrow";
+ $this->start = array("x"=>$x, "y"=>$y);
+ $this->end = array("x"=>$a, "y"=>$b);
+ $this->colour($colour);
+ $this->{"barb-length"} = $barb_length;
+ }
+
+ function colour( $colour )
+ {
+ $this->colour = $colour;
+ return $this;
+ }
+}
diff --git a/application/libraries/ofc-library/ofc_bar.php b/application/libraries/ofc-library/ofc_bar.php
new file mode 100644
index 000000000..6ddda4274
--- /dev/null
+++ b/application/libraries/ofc-library/ofc_bar.php
@@ -0,0 +1,34 @@
+top = $top;
+
+ if( isset( $bottom ) )
+ $this->bottom = $bottom;
+ }
+
+ function set_colour( $colour )
+ {
+ $this->colour = $colour;
+ }
+
+ function set_tooltip( $tip )
+ {
+ $this->tip = $tip;
+ }
+}
+
+class bar extends bar_base
+{
+ function bar()
+ {
+ $this->type = "bar";
+ parent::bar_base();
+ }
+}
+
diff --git a/application/libraries/ofc-library/ofc_bar_3d.php b/application/libraries/ofc-library/ofc_bar_3d.php
new file mode 100644
index 000000000..47552184c
--- /dev/null
+++ b/application/libraries/ofc-library/ofc_bar_3d.php
@@ -0,0 +1,22 @@
+top = $top;
+ }
+
+ function set_colour( $colour )
+ {
+ $this->colour = $colour;
+ }
+
+ function set_tooltip( $tip )
+ {
+ $this->tip = $tip;
+ }
+}
+
diff --git a/application/libraries/ofc-library/ofc_bar_base.php b/application/libraries/ofc-library/ofc_bar_base.php
new file mode 100644
index 000000000..c1303b86b
--- /dev/null
+++ b/application/libraries/ofc-library/ofc_bar_base.php
@@ -0,0 +1,97 @@
+text = $text;
+ $tmp = 'font-size';
+ $this->$tmp = $size;
+ }
+
+ /**
+ * syntatical sugar.
+ */
+ function key( $text, $size )
+ {
+ $this->set_key( $text, $size );
+ }
+
+ /**
+ * @param $v as an array, a mix of:
+ * - a bar_value class. You can use this to customise the paramters of each bar.
+ * - integer. This is the Y position of the top of the bar.
+ */
+ function set_values( $v )
+ {
+ $this->values = $v;
+ }
+
+ /**
+ * see set_values
+ */
+ function append_value( $v )
+ {
+ $this->values[] = $v;
+ }
+
+ /**
+ * @param $colour as string, a HEX colour, e.g. '#ff0000' red
+ */
+ function set_colour( $colour )
+ {
+ $this->colour = $colour;
+ }
+
+ /**
+ *syntatical sugar
+ */
+ function colour( $colour )
+ {
+ $this->set_colour( $colour );
+ }
+
+ /**
+ * @param $alpha as real number (range 0 to 1), e.g. 0.5 is half transparent
+ */
+ function set_alpha( $alpha )
+ {
+ $this->alpha = $alpha;
+ }
+
+ /**
+ * @param $tip as string, the tip to show. May contain various magic variables.
+ */
+ function set_tooltip( $tip )
+ {
+ $this->tip = $tip;
+ }
+
+ /**
+ *@param $on_show as line_on_show object
+ */
+ function set_on_show($on_show)
+ {
+ $this->{'on-show'} = $on_show;
+ }
+
+ function set_on_click( $text )
+ {
+ $tmp = 'on-click';
+ $this->$tmp = $text;
+ }
+
+ function attach_to_right_y_axis()
+ {
+ $this->axis = 'right';
+ }
+}
+
diff --git a/application/libraries/ofc-library/ofc_bar_filled.php b/application/libraries/ofc-library/ofc_bar_filled.php
new file mode 100644
index 000000000..837c1fc45
--- /dev/null
+++ b/application/libraries/ofc-library/ofc_bar_filled.php
@@ -0,0 +1,39 @@
+$tmp = $outline_colour;
+ }
+}
+
+class bar_filled extends bar_base
+{
+ function bar_filled( $colour=null, $outline_colour=null )
+ {
+ $this->type = "bar_filled";
+ parent::bar_base();
+
+ if( isset( $colour ) )
+ $this->set_colour( $colour );
+
+ if( isset( $outline_colour ) )
+ $this->set_outline_colour( $outline_colour );
+ }
+
+ function set_outline_colour( $outline_colour )
+ {
+ $tmp = 'outline-colour';
+ $this->$tmp = $outline_colour;
+ }
+}
+
diff --git a/application/libraries/ofc-library/ofc_bar_glass.php b/application/libraries/ofc-library/ofc_bar_glass.php
new file mode 100644
index 000000000..e83350151
--- /dev/null
+++ b/application/libraries/ofc-library/ofc_bar_glass.php
@@ -0,0 +1,131 @@
+type = $type;
+ $this->cascade = (float)$cascade;
+ $this->delay = (float)$delay;
+ }
+}
+
+class bar_value
+{
+ /**
+ * @param $top as integer. The Y value of the top of the bar
+ * @param OPTIONAL $bottom as integer. The Y value of the bottom of the bar, defaults to Y min.
+ */
+ function bar_value( $top, $bottom=null )
+ {
+ $this->top = $top;
+
+ if( isset( $bottom ) )
+ $this->bottom = $bottom;
+ }
+
+ function set_colour( $colour )
+ {
+ $this->colour = $colour;
+ }
+
+ function set_tooltip( $tip )
+ {
+ $this->tip = $tip;
+ }
+}
+
+class bar extends bar_base
+{
+ function bar()
+ {
+ $this->type = "bar";
+ parent::bar_base();
+ }
+}
+
+class bar_glass extends bar_base
+{
+ function bar_glass()
+ {
+ $this->type = "bar_glass";
+ parent::bar_base();
+ }
+}
+
+class bar_cylinder extends bar_base
+{
+ function bar_cylinder()
+ {
+ $this->type = "bar_cylinder";
+ parent::bar_base();
+ }
+}
+
+class bar_cylinder_outline extends bar_base
+{
+ function bar_cylinder_outline()
+ {
+ $this->type = "bar_cylinder_outline";
+ parent::bar_base();
+ }
+}
+
+class bar_rounded_glass extends bar_base
+{
+ function bar_rounded_glass()
+ {
+ $this->type = "bar_round_glass";
+ parent::bar_base();
+ }
+}
+
+class bar_round extends bar_base
+{
+ function bar_round()
+ {
+ $this->type = "bar_round";
+ parent::bar_base();
+ }
+}
+
+class bar_dome extends bar_base
+{
+ function bar_dome()
+ {
+ $this->type = "bar_dome";
+ parent::bar_base();
+ }
+}
+
+class bar_round3d extends bar_base
+{
+ function bar_round3d()
+ {
+ $this->type = "bar_round3d";
+ parent::bar_base();
+ }
+}
+
+class bar_3d extends bar_base
+{
+ function bar_3d()
+ {
+ $this->type = "bar_3d";
+ parent::bar_base();
+ }
+}
\ No newline at end of file
diff --git a/application/libraries/ofc-library/ofc_bar_sketch.php b/application/libraries/ofc-library/ofc_bar_sketch.php
new file mode 100644
index 000000000..ce1bcccf8
--- /dev/null
+++ b/application/libraries/ofc-library/ofc_bar_sketch.php
@@ -0,0 +1,29 @@
+type = "bar_sketch";
+ parent::bar_base();
+
+ $this->set_colour( $colour );
+ $this->set_outline_colour( $outline_colour );
+ $this->offset = $fun_factor;
+ }
+
+ function set_outline_colour( $outline_colour )
+ {
+ $tmp = 'outline-colour';
+ $this->$tmp = $outline_colour;
+ }
+}
+
diff --git a/application/libraries/ofc-library/ofc_bar_stack.php b/application/libraries/ofc-library/ofc_bar_stack.php
new file mode 100644
index 000000000..3d9f8d9f0
--- /dev/null
+++ b/application/libraries/ofc-library/ofc_bar_stack.php
@@ -0,0 +1,55 @@
+type = "bar_stack";
+ parent::bar_base();
+ }
+
+ function append_stack( $v )
+ {
+ $this->append_value( $v );
+ }
+
+ // an array of HEX colours strings
+ // e.g. array( '#ff0000', '#00ff00' );
+ function set_colours( $colours )
+ {
+ $this->colours = $colours;
+ }
+
+ // an array of bar_stack_value
+ function set_keys( $keys )
+ {
+ $this->keys = $keys;
+ }
+}
+
+class bar_stack_value
+{
+ function bar_stack_value( $val, $colour )
+ {
+ $this->val = $val;
+ $this->colour = $colour;
+ }
+
+ function set_tooltip( $tip )
+ {
+ $this->tip = $tip;
+ }
+}
+
+class bar_stack_key
+{
+ function bar_stack_key( $colour, $text, $font_size )
+ {
+ $this->colour = $colour;
+ $this->text = $text;
+ $tmp = 'font-size';
+ $this->$tmp = $font_size;
+ }
+}
\ No newline at end of file
diff --git a/application/libraries/ofc-library/ofc_candle.php b/application/libraries/ofc-library/ofc_candle.php
new file mode 100644
index 000000000..21ad67f8d
--- /dev/null
+++ b/application/libraries/ofc-library/ofc_candle.php
@@ -0,0 +1,41 @@
+high = $high;
+ $this->top = $open;
+ $this->bottom = $close;
+ $this->low = $low;
+ }
+
+ function set_colour( $colour )
+ {
+ $this->colour = $colour;
+ }
+
+ function set_tooltip( $tip )
+ {
+ $this->tip = $tip;
+ }
+}
+
+class candle extends bar_base
+{
+ function candle($colour, $negative_colour=null)
+ {
+ $this->type = "candle";
+ parent::bar_base();
+
+ $this->set_colour( $colour );
+ if(!is_null($negative_colour))
+ $this->{'negative-colour'} = $negative_colour;
+ }
+}
+
diff --git a/application/libraries/ofc-library/ofc_hbar.php b/application/libraries/ofc-library/ofc_hbar.php
new file mode 100644
index 000000000..6f8c0e451
--- /dev/null
+++ b/application/libraries/ofc-library/ofc_hbar.php
@@ -0,0 +1,64 @@
+left = $left;
+ $this->right = $right;
+ }
+ else
+ $this->right = $left;
+ }
+
+ function set_colour( $colour )
+ {
+ $this->colour = $colour;
+ }
+
+ function set_tooltip( $tip )
+ {
+ $this->tip = $tip;
+ }
+}
+
+class hbar
+{
+ function hbar( $colour )
+ {
+ $this->type = "hbar";
+ $this->values = array();
+ $this->set_colour( $colour );
+ }
+
+ function append_value( $v )
+ {
+ $this->values[] = $v;
+ }
+
+ function set_values( $v )
+ {
+ foreach( $v as $val )
+ $this->append_value( new hbar_value( $val ) );
+ }
+
+ function set_colour( $colour )
+ {
+ $this->colour = $colour;
+ }
+
+ function set_key( $text, $size )
+ {
+ $this->text = $text;
+ $tmp = 'font-size';
+ $this->$tmp = $size;
+ }
+
+ function set_tooltip( $tip )
+ {
+ $this->tip = $tip;
+ }
+}
+
diff --git a/application/libraries/ofc-library/ofc_line.php b/application/libraries/ofc-library/ofc_line.php
new file mode 100644
index 000000000..e635f2c02
--- /dev/null
+++ b/application/libraries/ofc-library/ofc_line.php
@@ -0,0 +1,157 @@
+type = $type;
+ $this->cascade = (float)$cascade;
+ $this->delay = (float)$delay;
+ }
+}
+
+class line
+{
+ function line()
+ {
+ $this->type = "line";
+ $this->values = array();
+ }
+
+ /**
+ * Set the default dot that all the real
+ * dots inherit their properties from. If you set the
+ * default dot to be red, all values in your chart that
+ * do not specify a colour will be red. Same for all the
+ * other attributes such as tooltip, on-click, size etc...
+ *
+ * @param $style as any class that inherits base_dot
+ */
+ function set_default_dot_style( $style )
+ {
+ $tmp = 'dot-style';
+ $this->$tmp = $style;
+ }
+
+ /**
+ * @param $v as array, can contain any combination of:
+ * - integer, Y position of the point
+ * - any class that inherits from dot_base
+ * - null
+ */
+ function set_values( $v )
+ {
+ $this->values = $v;
+ }
+
+ /**
+ * Append a value to the line.
+ *
+ * @param mixed $v
+ */
+ function append_value($v)
+ {
+ $this->values[] = $v;
+ }
+
+ function set_width( $width )
+ {
+ $this->width = $width;
+ }
+
+ function set_colour( $colour )
+ {
+ $this->colour = $colour;
+ }
+
+ /**
+ * sytnatical sugar for set_colour
+ */
+ function colour( $colour )
+ {
+ $this->set_colour( $colour );
+ return $this;
+ }
+
+ function set_halo_size( $size )
+ {
+ $tmp = 'halo-size';
+ $this->$tmp = $size;
+ }
+
+ function set_key( $text, $font_size )
+ {
+ $this->text = $text;
+ $tmp = 'font-size';
+ $this->$tmp = $font_size;
+ }
+
+ function set_tooltip( $tip )
+ {
+ $this->tip = $tip;
+ }
+
+ /**
+ * @param $text as string. A javascript function name as a string. The chart will
+ * try to call this function, it will pass the chart id as the only parameter into
+ * this function. E.g:
+ *
+ */
+ function set_on_click( $text )
+ {
+ $tmp = 'on-click';
+ $this->$tmp = $text;
+ }
+
+ function loop()
+ {
+ $this->loop = true;
+ }
+
+ function line_style( $s )
+ {
+ $tmp = "line-style";
+ $this->$tmp = $s;
+ }
+
+ /**
+ * Sets the text for the line.
+ *
+ * @param string $text
+ */
+ function set_text($text)
+ {
+ $this->text = $text;
+ }
+
+ function attach_to_right_y_axis()
+ {
+ $this->axis = 'right';
+ }
+
+ /**
+ *@param $on_show as line_on_show object
+ */
+ function set_on_show($on_show)
+ {
+ $this->{'on-show'} = $on_show;
+ }
+
+ function on_show($on_show)
+ {
+ $this->set_on_show($on_show);
+ return $this;
+ }
+}
\ No newline at end of file
diff --git a/application/libraries/ofc-library/ofc_line_base.php b/application/libraries/ofc-library/ofc_line_base.php
new file mode 100644
index 000000000..fa45cbc89
--- /dev/null
+++ b/application/libraries/ofc-library/ofc_line_base.php
@@ -0,0 +1,92 @@
+type = "line";
+ $this->text = "Page views";
+ $tmp = 'font-size';
+ $this->$tmp = 10;
+
+ $this->values = array();
+ }
+
+ function set_values( $v )
+ {
+ $this->values = $v;
+ }
+
+ /**
+ * Append a value to the line.
+ *
+ * @param mixed $v
+ */
+ function append_value($v)
+ {
+ $this->values[] = $v;
+ }
+
+ function set_width( $width )
+ {
+ $this->width = $width;
+ }
+
+ function set_colour( $colour )
+ {
+ $this->colour = $colour;
+ }
+
+ function set_dot_size( $size )
+ {
+ $tmp = 'dot-size';
+ $this->$tmp = $size;
+ }
+
+ function set_halo_size( $size )
+ {
+ $tmp = 'halo-size';
+ $this->$tmp = $size;
+ }
+
+ function set_key( $text, $font_size )
+ {
+ $this->text = $text;
+ $tmp = 'font-size';
+ $this->$tmp = $font_size;
+ }
+
+ function set_tooltip( $tip )
+ {
+ $this->tip = $tip;
+ }
+
+ function set_on_click( $text )
+ {
+ $tmp = 'on-click';
+ $this->$tmp = $text;
+ }
+
+ function loop()
+ {
+ $this->loop = true;
+ }
+
+ function line_style( $s )
+ {
+ $tmp = "line-style";
+ $this->$tmp = $s;
+ }
+
+ /**
+ * Sets the text for the line.
+ *
+ * @param string $text
+ */
+ function set_text($text)
+ {
+ $this->text = $text;
+ }
+
+
+}
\ No newline at end of file
diff --git a/application/libraries/ofc-library/ofc_line_dot.php b/application/libraries/ofc-library/ofc_line_dot.php
new file mode 100644
index 000000000..146691173
--- /dev/null
+++ b/application/libraries/ofc-library/ofc_line_dot.php
@@ -0,0 +1,33 @@
+value = $value;
+ $this->colour = $colour;
+ }
+
+ function set_colour( $colour )
+ {
+ $this->colour = $colour;
+ }
+
+ function set_size( $size )
+ {
+ $this->size = $size;
+ }
+
+ function set_tooltip( $tip )
+ {
+ $this->tip = $tip;
+ }
+}
+
+class line_dot extends line_base
+{
+ function line_dot()
+ {
+ $this->type = "line_dot";
+ }
+}
\ No newline at end of file
diff --git a/application/libraries/ofc-library/ofc_line_hollow.php b/application/libraries/ofc-library/ofc_line_hollow.php
new file mode 100644
index 000000000..512bb07d9
--- /dev/null
+++ b/application/libraries/ofc-library/ofc_line_hollow.php
@@ -0,0 +1,9 @@
+type = "line_hollow";
+ }
+}
\ No newline at end of file
diff --git a/application/libraries/ofc-library/ofc_line_style.php b/application/libraries/ofc-library/ofc_line_style.php
new file mode 100644
index 000000000..4f538cf9d
--- /dev/null
+++ b/application/libraries/ofc-library/ofc_line_style.php
@@ -0,0 +1,11 @@
+style = "dash";
+ $this->on = $on;
+ $this->off = $off;
+ }
+}
\ No newline at end of file
diff --git a/application/libraries/ofc-library/ofc_menu.php b/application/libraries/ofc-library/ofc_menu.php
new file mode 100644
index 000000000..0750a09c2
--- /dev/null
+++ b/application/libraries/ofc-library/ofc_menu.php
@@ -0,0 +1,56 @@
+type = "text";
+ $this->text = $text;
+ $tmp = 'javascript-function';
+ $this->$tmp = $javascript_function_name;
+ }
+}
+
+class ofc_menu_item_camera
+{
+ /**
+ * @param $text as string. The menu item text.
+ * @param $javascript_function_name as string. The javascript function name, the
+ * js function takes one parameter, the chart ID. So for example, our js function
+ * could look like this:
+ *
+ * function save_image( chart_id )
+ * {
+ * alert( chart_id );
+ * }
+ *
+ * to make a menu item call this: ofc_menu_item_camera('Save chart', 'save_image');
+ */
+ function ofc_menu_item_camera($text, $javascript_function_name)
+ {
+ $this->type = "camera-icon";
+ $this->text = $text;
+ $tmp = 'javascript-function';
+ $this->$tmp = $javascript_function_name;
+ }
+}
+
+class ofc_menu
+{
+ function ofc_menu($colour, $outline_colour)
+ {
+ $this->colour = $colour;
+ $this->outline_colour = $outline_colour;
+ }
+
+ function values($values)
+ {
+ $this->values = $values;
+ }
+}
\ No newline at end of file
diff --git a/application/libraries/ofc-library/ofc_pie.php b/application/libraries/ofc-library/ofc_pie.php
new file mode 100644
index 000000000..bf779c554
--- /dev/null
+++ b/application/libraries/ofc-library/ofc_pie.php
@@ -0,0 +1,257 @@
+value = $value;
+ $this->label = $label;
+ }
+
+ function set_colour( $colour )
+ {
+ $this->colour = $colour;
+ }
+
+ function set_label( $label, $label_colour, $font_size )
+ {
+ $this->label = $label;
+
+ $tmp = 'label-colour';
+ $this->$tmp = $label_colour;
+
+ $tmp = 'font-size';
+ $this->$tmp = $font_size;
+
+ }
+
+ function set_tooltip( $tip )
+ {
+ $this->tip = $tip;
+ }
+
+ function on_click( $event )
+ {
+ $tmp = 'on-click';
+ $this->$tmp = $event;
+ }
+
+
+ /**
+ * An object that inherits from base_pie_animation
+ */
+ function add_animation( $animation )
+ {
+ if( !isset( $this->animate ) )
+ $this->animate = array();
+
+ $this->animate[] = $animation;
+
+ return $this;
+ }
+}
+
+class base_pie_animation{}
+
+/**
+ * fade the pie slice from $alpha (pie set_alpha) to 100% opaque.
+ */
+class pie_fade extends base_pie_animation
+{
+ function pie_fade()
+ {
+ $this->type="fade";
+ }
+}
+
+/**
+ * Bounce the pie slice out a little
+ */
+class pie_bounce extends base_pie_animation
+{
+ /**
+ * @param $distance as integer, distance to bounce in pixels
+ */
+ function pie_bounce( $distance )
+ {
+ $this->type="bounce";
+ $this->distance = $distance;
+ }
+}
+
+/**
+ * Make a pie chart and fill it with pie slices
+ */
+class pie
+{
+ function pie()
+ {
+ $this->type = 'pie';
+ }
+
+ function set_colours( $colours )
+ {
+ $this->colours = $colours;
+ }
+
+ /**
+ * Sugar wrapped around set_colours
+ */
+ function colours( $colours )
+ {
+ $this->set_colours( $colours );
+ return $this;
+ }
+
+ /**
+ * @param $alpha as float (0-1) 0.75 = 3/4 visible
+ */
+ function set_alpha( $alpha )
+ {
+ $this->alpha = $alpha;
+ }
+
+ /**
+ *sugar wrapped set_alpha
+ **/
+ function alpha( $alpha )
+ {
+ $this->set_alpha( $alpha );
+ return $this;
+ }
+
+ /**
+ * @param $v as array containing one of
+ * - null
+ * - real or integer number
+ * - a pie_value object
+ */
+ function set_values( $v )
+ {
+ $this->values = $v;
+ }
+
+ /**
+ * sugar for set_values
+ */
+ function values( $v )
+ {
+ $this->set_values( $v );
+ return $this;
+ }
+
+ /**
+ * HACK to keep old code working.
+ */
+ function set_animate( $bool )
+ {
+ if( $bool )
+ $this->add_animation( new pie_fade() );
+
+ }
+
+ /**
+ * An object that inherits from base_pie_animation
+ */
+ function add_animation( $animation )
+ {
+ if( !isset( $this->animate ) )
+ $this->animate = array();
+
+ $this->animate[] = $animation;
+
+ return $this;
+ }
+
+ /**
+ * @param $angle as real number
+ */
+ function set_start_angle( $angle )
+ {
+ $tmp = 'start-angle';
+ $this->$tmp = $angle;
+ }
+
+ /**
+ * sugar for set_start_angle
+ */
+ function start_angle($angle)
+ {
+ $this->set_start_angle( $angle );
+ return $this;
+ }
+
+ /**
+ * @param $tip as string. The tooltip text. May contain magic varibles
+ */
+ function set_tooltip( $tip )
+ {
+ $this->tip = $tip;
+ }
+
+ /**
+ * sugar for set_tooltip
+ */
+ function tooltip( $tip )
+ {
+ $this->set_tooltip( $tip );
+ return $this;
+ }
+
+ function set_gradient_fill()
+ {
+ $tmp = 'gradient-fill';
+ $this->$tmp = true;
+ }
+
+ function gradient_fill()
+ {
+ $this->set_gradient_fill();
+ return $this;
+ }
+
+ /**
+ * By default each label is the same colour as the slice,
+ * but you can ovveride that behaviour using this method.
+ *
+ * @param $label_colour as string HEX colour;
+ */
+ function set_label_colour( $label_colour )
+ {
+ $tmp = 'label-colour';
+ $this->$tmp = $label_colour;
+ }
+
+ function label_colour( $label_colour )
+ {
+ $this->set_label_colour( $label_colour );
+ return $this;
+ }
+
+ /**
+ * Turn off the labels
+ */
+ function set_no_labels()
+ {
+ $tmp = 'no-labels';
+ $this->$tmp = true;
+ }
+
+ function on_click( $event )
+ {
+ $tmp = 'on-click';
+ $this->$tmp = $event;
+ }
+
+ /**
+ * Fix the radius of the pie chart. Take a look at the magic variable #radius#
+ * for helping figure out what radius to set it to.
+ *
+ * @param $radius as number
+ */
+ function radius( $radius )
+ {
+ $this->radius = $radius;
+ return $this;
+ }
+}
diff --git a/application/libraries/ofc-library/ofc_radar_axis.php b/application/libraries/ofc-library/ofc_radar_axis.php
new file mode 100644
index 000000000..909c41af8
--- /dev/null
+++ b/application/libraries/ofc-library/ofc_radar_axis.php
@@ -0,0 +1,47 @@
+set_max( $max );
+ }
+
+ function set_max( $max )
+ {
+ $this->max = $max;
+ }
+
+ function set_steps( $steps )
+ {
+ $this->steps = $steps;
+ }
+
+ function set_stroke( $s )
+ {
+ $this->stroke = $s;
+ }
+
+ function set_colour( $colour )
+ {
+ $this->colour = $colour;
+ }
+
+ function set_grid_colour( $colour )
+ {
+ $tmp = 'grid-colour';
+ $this->$tmp = $colour;
+ }
+
+ function set_labels( $labels )
+ {
+ $this->labels = $labels;
+ }
+
+ function set_spoke_labels( $labels )
+ {
+ $tmp = 'spoke-labels';
+ $this->$tmp = $labels;
+ }
+}
+
diff --git a/application/libraries/ofc-library/ofc_radar_axis_labels.php b/application/libraries/ofc-library/ofc_radar_axis_labels.php
new file mode 100644
index 000000000..22d485e4e
--- /dev/null
+++ b/application/libraries/ofc-library/ofc_radar_axis_labels.php
@@ -0,0 +1,15 @@
+labels = $labels;
+ }
+
+ function set_colour( $colour )
+ {
+ $this->colour = $colour;
+ }
+}
\ No newline at end of file
diff --git a/application/libraries/ofc-library/ofc_radar_spoke_labels.php b/application/libraries/ofc-library/ofc_radar_spoke_labels.php
new file mode 100644
index 000000000..51ba25e9a
--- /dev/null
+++ b/application/libraries/ofc-library/ofc_radar_spoke_labels.php
@@ -0,0 +1,15 @@
+labels = $labels;
+ }
+
+ function set_colour( $colour )
+ {
+ $this->colour = $colour;
+ }
+}
\ No newline at end of file
diff --git a/application/libraries/ofc-library/ofc_scatter.php b/application/libraries/ofc-library/ofc_scatter.php
new file mode 100644
index 000000000..7159a3a64
--- /dev/null
+++ b/application/libraries/ofc-library/ofc_scatter.php
@@ -0,0 +1,47 @@
+x = $x;
+ $this->y = $y;
+
+ if( $dot_size > 0 )
+ {
+ $tmp = 'dot-size';
+ $this->$tmp = $dot_size;
+ }
+ }
+}
+
+class scatter
+{
+ function scatter( $colour )
+ {
+ $this->type = "scatter";
+ $this->set_colour( $colour );
+ }
+
+ function set_colour( $colour )
+ {
+ $this->colour = $colour;
+ }
+
+ function set_default_dot_style( $style )
+ {
+ $tmp = 'dot-style';
+ $this->$tmp = $style;
+ }
+
+ /**
+ * @param $v as array, can contain any combination of:
+ * - integer, Y position of the point
+ * - any class that inherits from scatter_value
+ * - null
+ */
+ function set_values( $values )
+ {
+ $this->values = $values;
+ }
+}
diff --git a/application/libraries/ofc-library/ofc_scatter_line.php b/application/libraries/ofc-library/ofc_scatter_line.php
new file mode 100644
index 000000000..d667d7e8c
--- /dev/null
+++ b/application/libraries/ofc-library/ofc_scatter_line.php
@@ -0,0 +1,49 @@
+type = "scatter_line";
+ $this->set_colour( $colour );
+ $this->set_width( $width );
+ }
+
+ function set_default_dot_style( $style )
+ {
+ $tmp = 'dot-style';
+ $this->$tmp = $style;
+ }
+
+ function set_colour( $colour )
+ {
+ $this->colour = $colour;
+ }
+
+ function set_width( $width )
+ {
+ $this->width = $width;
+ }
+
+ function set_values( $values )
+ {
+ $this->values = $values;
+ }
+
+ function set_step_horizontal()
+ {
+ $this->stepgraph = 'horizontal';
+ }
+
+ function set_step_vertical()
+ {
+ $this->stepgraph = 'vertical';
+ }
+
+ function set_key( $text, $font_size )
+ {
+ $this->text = $text;
+ $tmp = 'font-size';
+ $this->$tmp = $font_size;
+ }
+}
\ No newline at end of file
diff --git a/application/libraries/ofc-library/ofc_shape.php b/application/libraries/ofc-library/ofc_shape.php
new file mode 100644
index 000000000..0cfe39f9b
--- /dev/null
+++ b/application/libraries/ofc-library/ofc_shape.php
@@ -0,0 +1,25 @@
+x = $x;
+ $this->y = $y;
+ }
+}
+
+class shape
+{
+ function shape( $colour )
+ {
+ $this->type = "shape";
+ $this->colour = $colour;
+ $this->values = array();
+ }
+
+ function append_value( $p )
+ {
+ $this->values[] = $p;
+ }
+}
\ No newline at end of file
diff --git a/application/libraries/ofc-library/ofc_sugar.php b/application/libraries/ofc-library/ofc_sugar.php
new file mode 100644
index 000000000..a9e85555e
--- /dev/null
+++ b/application/libraries/ofc-library/ofc_sugar.php
@@ -0,0 +1,43 @@
+colour($colour)->size($size);
+ }
+}
+
+class s_box extends anchor
+{
+ /**
+ * I use this wrapper for default dot types,
+ * it just makes the code easier to read.
+ */
+ function s_box($colour, $size)
+ {
+ parent::anchor();
+ $this->colour($colour)->size($size)->rotation(45)->sides(4);
+ }
+}
+
+class s_hollow_dot extends hollow_dot
+{
+ /**
+ * I use this wrapper for default dot types,
+ * it just makes the code easier to read.
+ */
+ function s_hollow_dot($colour, $size)
+ {
+ parent::hollow_dot();
+ $this->colour($colour)->size($size);
+ }
+}
\ No newline at end of file
diff --git a/application/libraries/ofc-library/ofc_tags.php b/application/libraries/ofc-library/ofc_tags.php
new file mode 100644
index 000000000..7e7e24454
--- /dev/null
+++ b/application/libraries/ofc-library/ofc_tags.php
@@ -0,0 +1,133 @@
+type = "tags";
+ $this->values = array();
+ }
+
+ function colour( $colour )
+ {
+ $this->colour = $colour;
+ return $this;
+ }
+
+ /**
+ *@param $font as string. e.g. "Verdana"
+ *@param $size as integer. Size in px
+ */
+ function font($font, $size)
+ {
+ $this->font = $font;
+ $this->{'font-size'} = $size;
+ return $this;
+ }
+
+ /**
+ *@param $x as integer. Size of x padding in px
+ *@param $y as integer. Size of y padding in px
+ */
+ function padding($x, $y)
+ {
+ $this->{"pad-x"} = $x;
+ $this->{"pad-y"} = $y;
+ return $this;
+ }
+
+ function rotate($angle)
+ {
+ $this->rotate($angle);
+ return $this;
+ }
+
+ function align_x_center()
+ {
+ $this->{"align-x"} = "center";
+ return $this;
+ }
+
+ function align_x_left()
+ {
+ $this->{"align-x"} = "left";
+ return $this;
+ }
+
+ function align_x_right()
+ {
+ $this->{"align-x"} = "right";
+ return $this;
+ }
+
+ function align_y_above()
+ {
+ $this->{"align-y"} = "above";
+ return $this;
+ }
+
+ function align_y_below()
+ {
+ $this->{"align-y"} = "below";
+ return $this;
+ }
+
+ function align_y_center()
+ {
+ $this->{"align-y"} = "center";
+ return $this;
+ }
+
+ /**
+ * This can contain some HTML, e.g:
+ * - "More info"
+ * - "ofc"
+ */
+ function text($text)
+ {
+ $this->text = $text;
+ return $this;
+ }
+
+ /**
+ * This works, but to get the mouse pointer to change
+ * to a little hand you need to use "stuff"-- see text()
+ */
+ function on_click($on_click)
+ {
+ $this->{'on-click'} = $on_click;
+ return $this;
+ }
+
+ /**
+ *@param $bold boolean.
+ *@param $underline boolean.
+ *@param $border boolean.
+ *@prarm $alpha real (0 to 1.0)
+ */
+ function style($bold, $underline, $border, $alpha )
+ {
+ $this->bold = $bold;
+ $this->border = $underline;
+ $this->underline = $border;
+ $this->alpha = $alpha;
+ return $this;
+ }
+
+ /**
+ *@param $tag as ofc_tag
+ */
+ function append_tag($tag)
+ {
+ $this->values[] = $tag;
+ }
+}
+
+class ofc_tag extends ofc_tags
+{
+ function ofc_tag($x, $y)
+ {
+ $this->x = $x;
+ $this->y = $y;
+ }
+}
\ No newline at end of file
diff --git a/application/libraries/ofc-library/ofc_title.php b/application/libraries/ofc-library/ofc_title.php
new file mode 100644
index 000000000..cda1de006
--- /dev/null
+++ b/application/libraries/ofc-library/ofc_title.php
@@ -0,0 +1,39 @@
+text = $text;
+ }
+
+ /**
+ * A css string. Can optionally contain:
+ * - font-size
+ * - font-family
+ * - font-weight
+ * - color
+ * - background-color
+ * - text-align
+ * - margin
+ * - margin-left
+ * - margin-right
+ * - margin-top
+ * - margin-bottom
+ * - padding
+ * - padding-left
+ * - padding-right
+ * - padding-top
+ * - padding-bottom
+ * just like the css we use all the time :-)
+ */
+ function set_style( $css )
+ {
+ $this->style = $css;
+ //"{font-size: 20px; color:#0000ff; font-family: Verdana; text-align: center;}";
+ }
+}
\ No newline at end of file
diff --git a/application/libraries/ofc-library/ofc_tooltip.php b/application/libraries/ofc-library/ofc_tooltip.php
new file mode 100644
index 000000000..3104ee33b
--- /dev/null
+++ b/application/libraries/ofc-library/ofc_tooltip.php
@@ -0,0 +1,67 @@
+shadow = $shadow;
+ }
+
+ /**
+ * @param $stroke as integer, border width in pixels (e.g. 5 )
+ */
+ function set_stroke( $stroke )
+ {
+ $this->stroke = $stroke;
+ }
+
+ /**
+ * @param $colour as string, HEX colour e.g. '#0000ff'
+ */
+ function set_colour( $colour )
+ {
+ $this->colour = $colour;
+ }
+
+ /**
+ * @param $bg as string, HEX colour e.g. '#0000ff'
+ */
+ function set_background_colour( $bg )
+ {
+ $this->background = $bg;
+ }
+
+ /**
+ * @param $style as string. A css style.
+ */
+ function set_title_style( $style )
+ {
+ $this->title = $style;
+ }
+
+ /**
+ * @param $style as string. A css style.
+ */
+ function set_body_style( $style )
+ {
+ $this->body = $style;
+ }
+
+ function set_proximity()
+ {
+ $this->mouse = 1;
+ }
+
+ function set_hover()
+ {
+ $this->mouse = 2;
+ }
+}
+
diff --git a/application/libraries/ofc-library/ofc_x_axis.php b/application/libraries/ofc-library/ofc_x_axis.php
new file mode 100644
index 000000000..da1c7672b
--- /dev/null
+++ b/application/libraries/ofc-library/ofc_x_axis.php
@@ -0,0 +1,140 @@
+stroke = $stroke;
+ }
+
+ function stroke( $stroke )
+ {
+ $this->set_stroke( $stroke );
+ return $this;
+ }
+
+ /**
+ *@param $colour as string HEX colour
+ *@param $grid_colour as string HEX colour
+ */
+ function set_colours( $colour, $grid_colour )
+ {
+ $this->set_colour( $colour );
+ $this->set_grid_colour( $grid_colour );
+ }
+
+ /**
+ *@param $colour as string HEX colour
+ */
+ function set_colour( $colour )
+ {
+ $this->colour = $colour;
+ }
+
+ function colour( $colour )
+ {
+ $this->set_colour($colour);
+ return $this;
+ }
+
+ function set_tick_height( $height )
+ {
+ $tmp = 'tick-height';
+ $this->$tmp = $height;
+ }
+
+ function tick_height( $height )
+ {
+ $this->set_tick_height($height);
+ return $this;
+ }
+
+ function set_grid_colour( $colour )
+ {
+ $tmp = 'grid-colour';
+ $this->$tmp = $colour;
+ }
+
+ function grid_colour( $colour )
+ {
+ $this->set_grid_colour($colour);
+ return $this;
+ }
+
+ /**
+ * @param $o is a boolean. If true, the X axis start half a step in
+ * This defaults to True
+ */
+ function set_offset( $o )
+ {
+ $this->offset = $o?true:false;
+ }
+
+ function offset( $o )
+ {
+ $this->set_offset($o);
+ return $this;
+ }
+
+ /**
+ * @param $steps as integer. Which grid lines and ticks are visible.
+ */
+ function set_steps( $steps )
+ {
+ $this->steps = $steps;
+ }
+
+ function steps( $steps )
+ {
+ $this->set_steps($steps);
+ return $this;
+ }
+
+ /**
+ * @param $val as an integer, the height in pixels of the 3D bar. Mostly
+ * used for the 3D bar chart.
+ */
+ function set_3d( $val )
+ {
+ $tmp = '3d';
+ $this->$tmp = $val;
+ }
+
+ /**
+ * @param $x_axis_labels as an x_axis_labels object
+ * Use this to customize the labels (colour, font, etc...)
+ */
+ function set_labels( $x_axis_labels )
+ {
+ //$this->labels = $v;
+ $this->labels = $x_axis_labels;
+ }
+
+ /**
+ * Sugar syntax: helper function to make the examples simpler.
+ * @param $a is an array of labels
+ */
+ function set_labels_from_array( $a )
+ {
+ $x_axis_labels = new x_axis_labels();
+ $x_axis_labels->set_labels( $a );
+ $this->labels = $x_axis_labels;
+
+ if( isset( $this->steps ) )
+ $x_axis_labels->set_steps( $this->steps );
+ }
+
+ /**
+ * min and max.
+ */
+ function set_range( $min, $max )
+ {
+ $this->min = $min;
+ $this->max = $max;
+ }
+}
\ No newline at end of file
diff --git a/application/libraries/ofc-library/ofc_x_axis_label.php b/application/libraries/ofc-library/ofc_x_axis_label.php
new file mode 100644
index 000000000..cf116f15f
--- /dev/null
+++ b/application/libraries/ofc-library/ofc_x_axis_label.php
@@ -0,0 +1,45 @@
+set_text( $text );
+ $this->set_colour( $colour );
+ $this->set_size( $size );
+ $this->set_rotate( $rotate );
+ }
+
+ function set_text( $text )
+ {
+ $this->text = $text;
+ }
+
+ function set_colour( $colour )
+ {
+ $this->colour = $colour;
+ }
+
+ function set_size( $size )
+ {
+ $this->size = $size;
+ }
+
+ function set_rotate( $rotate )
+ {
+ $this->rotate = $rotate;
+ }
+
+ function set_vertical()
+ {
+ $this->rotate = "vertical";
+ }
+
+ function set_visible()
+ {
+ $this->visible = true;
+ }
+}
\ No newline at end of file
diff --git a/application/libraries/ofc-library/ofc_x_axis_labels.php b/application/libraries/ofc-library/ofc_x_axis_labels.php
new file mode 100644
index 000000000..af4540f95
--- /dev/null
+++ b/application/libraries/ofc-library/ofc_x_axis_labels.php
@@ -0,0 +1,69 @@
+steps = $steps;
+ }
+
+ /**
+ * @param $steps as integer which labels are visible
+ */
+ function visible_steps( $steps )
+ {
+ $this->{"visible-steps"} = $steps;
+ return $this;
+ }
+
+ /**
+ *
+ * @param $labels as an array of [x_axis_label or string]
+ */
+ function set_labels( $labels )
+ {
+ $this->labels = $labels;
+ }
+
+ function set_colour( $colour )
+ {
+ $this->colour = $colour;
+ }
+
+ /**
+ * font size in pixels
+ */
+ function set_size( $size )
+ {
+ $this->size = $size;
+ }
+
+ /**
+ * rotate labels
+ */
+ function set_vertical()
+ {
+ $this->rotate = 270;
+ }
+
+ /**
+ * @param @angle as real. The angle of the text.
+ */
+ function rotate( $angle )
+ {
+ $this->rotate = $angle;
+ }
+
+ /**
+ * @param $text as string. Replace and magic variables with actual x axis position.
+ */
+ function text( $text )
+ {
+ $this->text = $text;
+ }
+}
\ No newline at end of file
diff --git a/application/libraries/ofc-library/ofc_x_legend.php b/application/libraries/ofc-library/ofc_x_legend.php
new file mode 100644
index 000000000..7a25af0c2
--- /dev/null
+++ b/application/libraries/ofc-library/ofc_x_legend.php
@@ -0,0 +1,15 @@
+text = $text;
+ }
+
+ function set_style( $css )
+ {
+ $this->style = $css;
+ //"{font-size: 20px; color:#0000ff; font-family: Verdana; text-align: center;}";
+ }
+}
\ No newline at end of file
diff --git a/application/libraries/ofc-library/ofc_y_axis.php b/application/libraries/ofc-library/ofc_y_axis.php
new file mode 100644
index 000000000..3846c9285
--- /dev/null
+++ b/application/libraries/ofc-library/ofc_y_axis.php
@@ -0,0 +1,17 @@
+$tmp = $colour;
+ }
+
+}
\ No newline at end of file
diff --git a/application/libraries/ofc-library/ofc_y_axis_base.php b/application/libraries/ofc-library/ofc_y_axis_base.php
new file mode 100644
index 000000000..8093a09e5
--- /dev/null
+++ b/application/libraries/ofc-library/ofc_y_axis_base.php
@@ -0,0 +1,116 @@
+stroke = $s;
+ }
+
+ /**
+ * @param $val as integer. The length of the ticks in pixels
+ */
+ function set_tick_length( $val )
+ {
+ $tmp = 'tick-length';
+ $this->$tmp = $val;
+ }
+
+ function set_colours( $colour, $grid_colour )
+ {
+ $this->set_colour( $colour );
+ $this->set_grid_colour( $grid_colour );
+ }
+
+ function set_colour( $colour )
+ {
+ $this->colour = $colour;
+ }
+
+ function set_grid_colour( $colour )
+ {
+ $tmp = 'grid-colour';
+ $this->$tmp = $colour;
+ }
+
+ /**
+ * Set min and max values, also (optionally) set the steps value.
+ * You can reverse the chart by setting min larger than max, e.g. min = 10
+ * and max = 0.
+ *
+ * @param $min as integer
+ * @param $max as integer
+ * @param $steps as integer.
+ */
+ function set_range( $min, $max, $steps=1 )
+ {
+ $this->min = $min;
+ $this->max = $max;
+ $this->set_steps( $steps );
+ }
+
+ /**
+ * Sugar for set_range
+ */
+ function range( $min, $max, $steps=1 )
+ {
+ $this->set_range( $min, $max, $steps );
+ return $this;
+ }
+
+ /**
+ * @param $off as Boolean. If true the Y axis is nudged up half a step.
+ */
+ function set_offset( $off )
+ {
+ $this->offset = $off?1:0;
+ }
+
+ /**
+ * @param $y_axis_labels as an y_axis_labels object
+ * Use this to customize the labels (colour, font, etc...)
+ */
+ function set_labels( $y_axis_labels )
+ {
+ $this->labels = $y_axis_labels;
+ }
+
+ /**
+ * Pass in some text for each label. This can contain magic variables "#val#" which
+ * will get replaced with the value for that Y axis label. Useful for:
+ * - "#val#"
+ * - "#val#%"
+ * - "#val# million"
+ *
+ * @param $text as string.
+ */
+ function set_label_text( $text )
+ {
+ $tmp = new y_axis_labels();
+ $tmp->set_text( $text );
+ $this->labels = $tmp;
+ }
+
+ /**
+ * @param $steps as integer.
+ *
+ * Only show every $steps label, e.g. every 10th
+ */
+ function set_steps( $steps )
+ {
+ $this->steps = $steps;
+ }
+
+ /**
+ * Make the labels show vertical
+ */
+ function set_vertical()
+ {
+ $this->rotate = "vertical";
+ }
+}
\ No newline at end of file
diff --git a/application/libraries/ofc-library/ofc_y_axis_label.php b/application/libraries/ofc-library/ofc_y_axis_label.php
new file mode 100644
index 000000000..f2616f537
--- /dev/null
+++ b/application/libraries/ofc-library/ofc_y_axis_label.php
@@ -0,0 +1,38 @@
+y = $y;
+ $this->set_text( $text );
+ }
+
+ function set_text( $text )
+ {
+ $this->text = $text;
+ }
+
+ function set_colour( $colour )
+ {
+ $this->colour = $colour;
+ }
+
+ function set_size( $size )
+ {
+ $this->size = $size;
+ }
+
+ function set_rotate( $rotate )
+ {
+ $this->rotate = $rotate;
+ }
+
+ function set_vertical()
+ {
+ $this->rotate = "vertical";
+ }
+}
\ No newline at end of file
diff --git a/application/libraries/ofc-library/ofc_y_axis_labels.php b/application/libraries/ofc-library/ofc_y_axis_labels.php
new file mode 100644
index 000000000..c0708ab21
--- /dev/null
+++ b/application/libraries/ofc-library/ofc_y_axis_labels.php
@@ -0,0 +1,57 @@
+steps = $steps;
+ }
+
+ /**
+ *
+ * @param $labels as an array of [y_axis_label or string]
+ */
+ function set_labels( $labels )
+ {
+ $this->labels = $labels;
+ }
+
+ function set_colour( $colour )
+ {
+ $this->colour = $colour;
+ }
+
+ /**
+ * font size in pixels
+ */
+ function set_size( $size )
+ {
+ $this->size = $size;
+ }
+
+ /**
+ * rotate labels
+ */
+ function set_vertical()
+ {
+ $this->rotate = 270;
+ }
+
+ function rotate( $angle )
+ {
+ $this->rotate = $angle;
+ }
+
+ /**
+ * @param $text default text that all labels inherit
+ */
+ function set_text( $text )
+ {
+ $this->text = $text;
+ }
+}
\ No newline at end of file
diff --git a/application/libraries/ofc-library/ofc_y_axis_right.php b/application/libraries/ofc-library/ofc_y_axis_right.php
new file mode 100644
index 000000000..71f7c2984
--- /dev/null
+++ b/application/libraries/ofc-library/ofc_y_axis_right.php
@@ -0,0 +1,6 @@
+text = $text;
+ }
+
+ function set_style( $css )
+ {
+ $this->style = $css;
+ //"{font-size: 20px; color:#0000ff; font-family: Verdana; text-align: center;}";
+ }
+}
\ No newline at end of file
diff --git a/application/libraries/ofc-library/open-flash-chart-object.php b/application/libraries/ofc-library/open-flash-chart-object.php
new file mode 100644
index 000000000..6e1129f46
--- /dev/null
+++ b/application/libraries/ofc-library/open-flash-chart-object.php
@@ -0,0 +1,109 @@
+';
+
+ if( !isset( $open_flash_chart_seqno ) )
+ {
+ $open_flash_chart_seqno = 1;
+ $out[] = '';
+ }
+ else
+ {
+ $open_flash_chart_seqno++;
+ $obj_id .= '_'. $open_flash_chart_seqno;
+ $div_name .= '_'. $open_flash_chart_seqno;
+ }
+
+ if( $use_swfobject )
+ {
+ // Using library for auto-enabling Flash object on IE, disabled-Javascript proof
+ $out[] = '';
+ $out[] = '';
+ $out[] = '';
+ }
+
+ return implode("\n",$out);
+}
+?>
\ No newline at end of file
diff --git a/application/libraries/ofc-library/open-flash-chart.php b/application/libraries/ofc-library/open-flash-chart.php
new file mode 100644
index 000000000..b017097d0
--- /dev/null
+++ b/application/libraries/ofc-library/open-flash-chart.php
@@ -0,0 +1,178 @@
+title = new title( "Many data lines" );
+ $this->elements = array();
+ }
+
+ function set_title( $t )
+ {
+ $this->title = $t;
+ }
+
+ function set_x_axis( $x )
+ {
+ $this->x_axis = $x;
+ }
+
+ function set_y_axis( $y )
+ {
+ $this->y_axis = $y;
+ }
+
+ function add_y_axis( $y )
+ {
+ $this->y_axis = $y;
+ }
+
+ function set_y_axis_right( $y )
+ {
+ $this->y_axis_right = $y;
+ }
+
+ function add_element( $e )
+ {
+ $this->elements[] = $e;
+ }
+
+ function set_x_legend( $x )
+ {
+ $this->x_legend = $x;
+ }
+
+ function set_y_legend( $y )
+ {
+ $this->y_legend = $y;
+ }
+
+ function set_bg_colour( $colour )
+ {
+ $this->bg_colour = $colour;
+ }
+
+ function set_radar_axis( $radar )
+ {
+ $this->radar_axis = $radar;
+ }
+
+ function set_tooltip( $tooltip )
+ {
+ $this->tooltip = $tooltip;
+ }
+
+ /**
+ * This is a bit funky :(
+ *
+ * @param $num_decimals as integer. Truncate the decimals to $num_decimals, e.g. set it
+ * to 5 and 3.333333333 will display as 3.33333. 2.0 will display as 2 (or 2.00000 - see below)
+ * @param $is_fixed_num_decimals_forced as boolean. If true it will pad the decimals.
+ * @param $is_decimal_separator_comma as boolean
+ * @param $is_thousand_separator_disabled as boolean
+ *
+ * This needs a bit of love and attention
+ */
+ function set_number_format($num_decimals, $is_fixed_num_decimals_forced, $is_decimal_separator_comma, $is_thousand_separator_disabled )
+ {
+ $this->num_decimals = $num_decimals;
+ $this->is_fixed_num_decimals_forced = $is_fixed_num_decimals_forced;
+ $this->is_decimal_separator_comma = $is_decimal_separator_comma;
+ $this->is_thousand_separator_disabled = $is_thousand_separator_disabled;
+ }
+
+ /**
+ * This is experimental and will change as we make it work
+ *
+ * @param $m as ofc_menu
+ */
+ function set_menu($m)
+ {
+ $this->menu = $m;
+ }
+
+ function toString()
+ {
+ if (function_exists('json_encode'))
+ {
+ return json_encode($this);
+ }
+ else
+ {
+ $json = new Services_JSON();
+ return $json->encode( $this );
+ }
+ }
+
+ function toPrettyString()
+ {
+ return json_format( $this->toString() );
+ }
+}
+
+
+
+//
+// there is no PHP end tag so we don't mess the headers up!
+//
\ No newline at end of file
diff --git a/application/logs/index.html b/application/logs/index.html
new file mode 100644
index 000000000..c942a79ce
--- /dev/null
+++ b/application/logs/index.html
@@ -0,0 +1,10 @@
+
+
+ Directory access is forbidden.
+ + + \ No newline at end of file diff --git a/application/models/appconfig.php b/application/models/appconfig.php new file mode 100644 index 000000000..6f0879148 --- /dev/null +++ b/application/models/appconfig.php @@ -0,0 +1,81 @@ +db->from('app_config'); + $this->db->where('app_config.key',$key); + $query = $this->db->get(); + + return ($query->num_rows()==1); + } + + function get_all() + { + $this->db->from('app_config'); + $this->db->order_by("key", "asc"); + return $this->db->get(); + } + + function get($key) + { + $query = $this->db->get_where('app_config', array('key' => $key), 1); + + if($query->num_rows()==1) + { + return $query->row()->value; + } + + return ""; + + } + + function save($key,$value) + { + $config_data=array( + 'key'=>$key, + 'value'=>$value + ); + + if (!$this->exists($key)) + { + return $this->db->insert('app_config',$config_data); + } + + $this->db->where('key', $key); + return $this->db->update('app_config',$config_data); + } + + function batch_save($data) + { + $success=true; + + //Run these queries as a transaction, we want to make sure we do all or nothing + $this->db->trans_start(); + foreach($data as $key=>$value) + { + if(!$this->save($key,$value)) + { + $success=false; + break; + } + } + + $this->db->trans_complete(); + return $success; + + } + + function delete($key) + { + return $this->db->delete('app_config', array('key' => $key)); + } + + function delete_all() + { + return $this->db->empty_table('app_config'); + } +} + +?> \ No newline at end of file diff --git a/application/models/customer.php b/application/models/customer.php new file mode 100644 index 000000000..8b0e54913 --- /dev/null +++ b/application/models/customer.php @@ -0,0 +1,245 @@ +db->from('customers'); + $this->db->join('people', 'people.person_id = customers.person_id'); + $this->db->where('customers.person_id',$person_id); + $query = $this->db->get(); + + return ($query->num_rows()==1); + } + + /* + Returns all the customers + */ + function get_all($limit=10000, $offset=0) + { + $this->db->from('customers'); + $this->db->join('people','customers.person_id=people.person_id'); + $this->db->where('deleted',0); + $this->db->order_by("last_name", "asc"); + $this->db->limit($limit); + $this->db->offset($offset); + return $this->db->get(); + } + + function count_all() + { + $this->db->from('customers'); + $this->db->where('deleted',0); + return $this->db->count_all_results(); + } + + /* + Gets information about a particular customer + */ + function get_info($customer_id) + { + $this->db->from('customers'); + $this->db->join('people', 'people.person_id = customers.person_id'); + $this->db->where('customers.person_id',$customer_id); + $query = $this->db->get(); + + if($query->num_rows()==1) + { + return $query->row(); + } + else + { + //Get empty base parent object, as $customer_id is NOT an customer + $person_obj=parent::get_info(-1); + + //Get all the fields from customer table + $fields = $this->db->list_fields('customers'); + + //append those fields to base parent object, we we have a complete empty object + foreach ($fields as $field) + { + $person_obj->$field=''; + } + + return $person_obj; + } + } + + /* + Gets information about multiple customers + */ + function get_multiple_info($customer_ids) + { + $this->db->from('customers'); + $this->db->join('people', 'people.person_id = customers.person_id'); + $this->db->where_in('customers.person_id',$customer_ids); + $this->db->order_by("last_name", "asc"); + return $this->db->get(); + } + + /* + Inserts or updates a customer + */ + function save(&$person_data, &$customer_data,$customer_id=false) + { + $success=false; + //Run these queries as a transaction, we want to make sure we do all or nothing + $this->db->trans_start(); + + if(parent::save($person_data,$customer_id)) + { + if (!$customer_id or !$this->exists($customer_id)) + { + $customer_data['person_id'] = $person_data['person_id']; + $success = $this->db->insert('customers',$customer_data); + } + else + { + $this->db->where('person_id', $customer_id); + $success = $this->db->update('customers',$customer_data); + } + + } + + $this->db->trans_complete(); + return $success; + } + + /* + Deletes one customer + */ + function delete($customer_id) + { + $this->db->where('person_id', $customer_id); + return $this->db->update('customers', array('deleted' => 1)); + } + + /* + Deletes a list of customers + */ + function delete_list($customer_ids) + { + $this->db->where_in('person_id',$customer_ids); + return $this->db->update('customers', array('deleted' => 1)); + } + + /* + Get search suggestions to find customers + */ + function get_search_suggestions($search,$limit=25) + { + $suggestions = array(); + + $this->db->from('customers'); + $this->db->join('people','customers.person_id=people.person_id'); + $this->db->where("(first_name LIKE '%".$this->db->escape_like_str($search)."%' or + last_name LIKE '%".$this->db->escape_like_str($search)."%' or + CONCAT(`first_name`,' ',`last_name`) LIKE '%".$this->db->escape_like_str($search)."%') and deleted=0"); + $this->db->order_by("last_name", "asc"); + $by_name = $this->db->get(); + foreach($by_name->result() as $row) + { + $suggestions[]=$row->first_name.' '.$row->last_name; + } + + $this->db->from('customers'); + $this->db->join('people','customers.person_id=people.person_id'); + $this->db->where('deleted',0); + $this->db->like("email",$search); + $this->db->order_by("email", "asc"); + $by_email = $this->db->get(); + foreach($by_email->result() as $row) + { + $suggestions[]=$row->email; + } + + $this->db->from('customers'); + $this->db->join('people','customers.person_id=people.person_id'); + $this->db->where('deleted',0); + $this->db->like("phone_number",$search); + $this->db->order_by("phone_number", "asc"); + $by_phone = $this->db->get(); + foreach($by_phone->result() as $row) + { + $suggestions[]=$row->phone_number; + } + + $this->db->from('customers'); + $this->db->join('people','customers.person_id=people.person_id'); + $this->db->where('deleted',0); + $this->db->like("account_number",$search); + $this->db->order_by("account_number", "asc"); + $by_account_number = $this->db->get(); + foreach($by_account_number->result() as $row) + { + $suggestions[]=$row->account_number; + } + + //only return $limit suggestions + if(count($suggestions > $limit)) + { + $suggestions = array_slice($suggestions, 0,$limit); + } + return $suggestions; + } + + /* + Get search suggestions to find customers + */ + function get_customer_search_suggestions($search,$limit=25) + { + $suggestions = array(); + + $this->db->from('customers'); + $this->db->join('people','customers.person_id=people.person_id'); + $this->db->where("(first_name LIKE '%".$this->db->escape_like_str($search)."%' or + last_name LIKE '%".$this->db->escape_like_str($search)."%' or + CONCAT(`first_name`,' ',`last_name`) LIKE '%".$this->db->escape_like_str($search)."%') and deleted=0"); + $this->db->order_by("last_name", "asc"); + $by_name = $this->db->get(); + foreach($by_name->result() as $row) + { + $suggestions[]=$row->person_id.'|'.$row->first_name.' '.$row->last_name; + } + + $this->db->from('customers'); + $this->db->join('people','customers.person_id=people.person_id'); + $this->db->where('deleted',0); + $this->db->like("account_number",$search); + $this->db->order_by("account_number", "asc"); + $by_account_number = $this->db->get(); + foreach($by_account_number->result() as $row) + { + $suggestions[]=$row->person_id.'|'.$row->account_number; + } + + //only return $limit suggestions + if(count($suggestions > $limit)) + { + $suggestions = array_slice($suggestions, 0,$limit); + } + return $suggestions; + + } + /* + Preform a search on customers + */ + function search($search) + { + $this->db->from('customers'); + $this->db->join('people','customers.person_id=people.person_id'); + $this->db->where("(first_name LIKE '%".$this->db->escape_like_str($search)."%' or + last_name LIKE '%".$this->db->escape_like_str($search)."%' or + email LIKE '%".$this->db->escape_like_str($search)."%' or + phone_number LIKE '%".$this->db->escape_like_str($search)."%' or + account_number LIKE '%".$this->db->escape_like_str($search)."%' or + CONCAT(`first_name`,' ',`last_name`) LIKE '%".$this->db->escape_like_str($search)."%') and deleted=0"); + $this->db->order_by("last_name", "asc"); + + return $this->db->get(); + } + +} +?> diff --git a/application/models/employee.php b/application/models/employee.php new file mode 100644 index 000000000..e0d0b3606 --- /dev/null +++ b/application/models/employee.php @@ -0,0 +1,325 @@ +db->from('employees'); + $this->db->join('people', 'people.person_id = employees.person_id'); + $this->db->where('employees.person_id',$person_id); + $query = $this->db->get(); + + return ($query->num_rows()==1); + } + + /* + Returns all the employees + */ + function get_all($limit=10000, $offset=0) + { + $this->db->from('employees'); + $this->db->where('deleted',0); + $this->db->join('people','employees.person_id=people.person_id'); + $this->db->order_by("last_name", "asc"); + $this->db->limit($limit); + $this->db->offset($offset); + return $this->db->get(); + } + + function count_all() + { + $this->db->from('employees'); + $this->db->where('deleted',0); + return $this->db->count_all_results(); + } + + /* + Gets information about a particular employee + */ + function get_info($employee_id) + { + $this->db->from('employees'); + $this->db->join('people', 'people.person_id = employees.person_id'); + $this->db->where('employees.person_id',$employee_id); + $query = $this->db->get(); + + if($query->num_rows()==1) + { + return $query->row(); + } + else + { + //Get empty base parent object, as $employee_id is NOT an employee + $person_obj=parent::get_info(-1); + + //Get all the fields from employee table + $fields = $this->db->list_fields('employees'); + + //append those fields to base parent object, we we have a complete empty object + foreach ($fields as $field) + { + $person_obj->$field=''; + } + + return $person_obj; + } + } + + /* + Gets information about multiple employees + */ + function get_multiple_info($employee_ids) + { + $this->db->from('employees'); + $this->db->join('people', 'people.person_id = employees.person_id'); + $this->db->where_in('employees.person_id',$employee_ids); + $this->db->order_by("last_name", "asc"); + return $this->db->get(); + } + + /* + Inserts or updates an employee + */ + function save(&$person_data, &$employee_data,&$permission_data,$employee_id=false) + { + $success=false; + + //Run these queries as a transaction, we want to make sure we do all or nothing + $this->db->trans_start(); + + if(parent::save($person_data,$employee_id)) + { + if (!$employee_id or !$this->exists($employee_id)) + { + $employee_data['person_id'] = $employee_id = $person_data['person_id']; + $success = $this->db->insert('employees',$employee_data); + } + else + { + $this->db->where('person_id', $employee_id); + $success = $this->db->update('employees',$employee_data); + } + + //We have either inserted or updated a new employee, now lets set permissions. + if($success) + { + //First lets clear out any permissions the employee currently has. + $success=$this->db->delete('permissions', array('person_id' => $employee_id)); + + //Now insert the new permissions + if($success) + { + foreach($permission_data as $allowed_module) + { + $success = $this->db->insert('permissions', + array( + 'module_id'=>$allowed_module, + 'person_id'=>$employee_id)); + } + } + } + + } + + $this->db->trans_complete(); + return $success; + } + + /* + Deletes one employee + */ + function delete($employee_id) + { + $success=false; + + //Don't let employee delete their self + if($employee_id==$this->get_logged_in_employee_info()->person_id) + return false; + + //Run these queries as a transaction, we want to make sure we do all or nothing + $this->db->trans_start(); + + //Delete permissions + if($this->db->delete('permissions', array('person_id' => $employee_id))) + { + $this->db->where('person_id', $employee_id); + $success = $this->db->update('employees', array('deleted' => 1)); + } + $this->db->trans_complete(); + return $success; + } + + /* + Deletes a list of employees + */ + function delete_list($employee_ids) + { + $success=false; + + //Don't let employee delete their self + if(in_array($this->get_logged_in_employee_info()->person_id,$employee_ids)) + return false; + + //Run these queries as a transaction, we want to make sure we do all or nothing + $this->db->trans_start(); + + $this->db->where_in('person_id',$employee_ids); + //Delete permissions + if ($this->db->delete('permissions')) + { + //delete from employee table + $this->db->where_in('person_id',$employee_ids); + $success = $this->db->update('employees', array('deleted' => 1)); + } + $this->db->trans_complete(); + return $success; + } + + /* + Get search suggestions to find employees + */ + function get_search_suggestions($search,$limit=5) + { + $suggestions = array(); + + $this->db->from('employees'); + $this->db->join('people','employees.person_id=people.person_id'); + $this->db->where("(first_name LIKE '%".$this->db->escape_like_str($search)."%' or + last_name LIKE '%".$this->db->escape_like_str($search)."%' or + CONCAT(`first_name`,' ',`last_name`) LIKE '%".$this->db->escape_like_str($search)."%') and deleted=0"); + $this->db->order_by("last_name", "asc"); + $by_name = $this->db->get(); + foreach($by_name->result() as $row) + { + $suggestions[]=$row->first_name.' '.$row->last_name; + } + + $this->db->from('employees'); + $this->db->join('people','employees.person_id=people.person_id'); + $this->db->where('deleted', 0); + $this->db->like("email",$search); + $this->db->order_by("email", "asc"); + $by_email = $this->db->get(); + foreach($by_email->result() as $row) + { + $suggestions[]=$row->email; + } + + $this->db->from('employees'); + $this->db->join('people','employees.person_id=people.person_id'); + $this->db->where('deleted', 0); + $this->db->like("username",$search); + $this->db->order_by("username", "asc"); + $by_username = $this->db->get(); + foreach($by_username->result() as $row) + { + $suggestions[]=$row->username; + } + + + $this->db->from('employees'); + $this->db->join('people','employees.person_id=people.person_id'); + $this->db->where('deleted', 0); + $this->db->like("phone_number",$search); + $this->db->order_by("phone_number", "asc"); + $by_phone = $this->db->get(); + foreach($by_phone->result() as $row) + { + $suggestions[]=$row->phone_number; + } + + + //only return $limit suggestions + if(count($suggestions > $limit)) + { + $suggestions = array_slice($suggestions, 0,$limit); + } + return $suggestions; + + } + + /* + Preform a search on employees + */ + function search($search) + { + $this->db->from('employees'); + $this->db->join('people','employees.person_id=people.person_id'); + $this->db->where("(first_name LIKE '%".$this->db->escape_like_str($search)."%' or + last_name LIKE '%".$this->db->escape_like_str($search)."%' or + email LIKE '%".$this->db->escape_like_str($search)."%' or + phone_number LIKE '%".$this->db->escape_like_str($search)."%' or + username LIKE '%".$this->db->escape_like_str($search)."%' or + CONCAT(`first_name`,' ',`last_name`) LIKE '%".$this->db->escape_like_str($search)."%') and deleted=0"); + $this->db->order_by("last_name", "asc"); + + return $this->db->get(); + } + + /* + Attempts to login employee and set session. Returns boolean based on outcome. + */ + function login($username, $password) + { + $query = $this->db->get_where('employees', array('username' => $username,'password'=>md5($password), 'deleted'=>0), 1); + if ($query->num_rows() ==1) + { + $row=$query->row(); + $this->session->set_userdata('person_id', $row->person_id); + return true; + } + return false; + } + + /* + Logs out a user by destorying all session data and redirect to login + */ + function logout() + { + $this->session->sess_destroy(); + redirect('login'); + } + + /* + Determins if a employee is logged in + */ + function is_logged_in() + { + return $this->session->userdata('person_id')!=false; + } + + /* + Gets information about the currently logged in employee. + */ + function get_logged_in_employee_info() + { + if($this->is_logged_in()) + { + return $this->get_info($this->session->userdata('person_id')); + } + + return false; + } + + /* + Determins whether the employee specified employee has access the specific module. + */ + function has_permission($module_id,$person_id) + { + //if no module_id is null, allow access + if($module_id==null) + { + return true; + } + + $query = $this->db->get_where('permissions', array('person_id' => $person_id,'module_id'=>$module_id), 1); + return $query->num_rows() == 1; + + + return false; + } + +} +?> diff --git a/application/models/giftcard.php b/application/models/giftcard.php new file mode 100644 index 000000000..5c3f2d673 --- /dev/null +++ b/application/models/giftcard.php @@ -0,0 +1,255 @@ +db->from('giftcards'); + $this->db->where('giftcard_id',$giftcard_id); + $this->db->where('deleted',0); + $query = $this->db->get(); + + return ($query->num_rows()==1); + } + + /* + Returns all the giftcards + */ + function get_all($limit=10000, $offset=0) + { + $this->db->from('giftcards'); + $this->db->join('people','people.person_id=giftcards.person_id');//GARRISON ADDED 4/25/2013 + $this->db->where('deleted',0); + $this->db->order_by("giftcard_number", "asc"); + $this->db->limit($limit); + $this->db->offset($offset); + return $this->db->get(); + } + + function count_all() + { + $this->db->from('giftcards'); + $this->db->where('deleted',0); + return $this->db->count_all_results(); + } + + /* + Gets information about a particular giftcard + */ + function get_info($giftcard_id) + { + $this->db->from('giftcards'); + $this->db->where('giftcard_id',$giftcard_id); + $this->db->where('deleted',0); + + $query = $this->db->get(); + + if($query->num_rows()==1) + { + return $query->row(); + } + else + { + //Get empty base parent object, as $giftcard_id is NOT an giftcard + $giftcard_obj=new stdClass(); + + //Get all the fields from giftcards table + $fields = $this->db->list_fields('giftcards'); + + foreach ($fields as $field) + { + $giftcard_obj->$field=''; + } + + return $giftcard_obj; + } + } + + /* + Get an giftcard id given an giftcard number + */ + function get_giftcard_id($giftcard_number) + { + $this->db->from('giftcards'); + $this->db->where('giftcard_number',$giftcard_number); + $this->db->where('deleted',0); + + $query = $this->db->get(); + + if($query->num_rows()==1) + { + return $query->row()->giftcard_id; + } + + return false; + } + + /* + Gets information about multiple giftcards + */ + function get_multiple_info($giftcard_ids) + { + $this->db->from('giftcards'); + $this->db->where_in('giftcard_id',$giftcard_ids); + $this->db->where('deleted',0); + $this->db->order_by("giftcard_number", "asc"); + return $this->db->get(); + } + + /* + Inserts or updates a giftcard + */ + function save(&$giftcard_data,$giftcard_id=false) + { + if (!$giftcard_id or !$this->exists($giftcard_id)) + { + if($this->db->insert('giftcards',$giftcard_data)) + { + $giftcard_data['giftcard_id']=$this->db->insert_id(); + return true; + } + return false; + } + + $this->db->where('giftcard_id', $giftcard_id); + return $this->db->update('giftcards',$giftcard_data); + } + + /* + Updates multiple giftcards at once + */ + function update_multiple($giftcard_data,$giftcard_ids) + { + $this->db->where_in('giftcard_id',$giftcard_ids); + return $this->db->update('giftcards',$giftcard_data); + } + + /* + Deletes one giftcard + */ + function delete($giftcard_id) + { + $this->db->where('giftcard_id', $giftcard_id); + return $this->db->update('giftcards', array('deleted' => 1)); + } + + /* + Deletes a list of giftcards + */ + function delete_list($giftcard_ids) + { + $this->db->where_in('giftcard_id',$giftcard_ids); + return $this->db->update('giftcards', array('deleted' => 1)); + } + + /* + Get search suggestions to find giftcards + */ + function get_search_suggestions($search,$limit=25) + { + $suggestions = array(); + + $this->db->from('giftcards'); + $this->db->like('giftcard_number', $search); + $this->db->where('deleted',0); + $this->db->order_by("giftcard_number", "asc"); + $by_number = $this->db->get(); + + foreach($by_number->result() as $row) + { + $suggestions[]=$row->giftcard_number; + } + +/** GARRISON MODIFIED 4/24/2013 **/ + $this->db->from('customers'); + $this->db->join('people','customers.person_id=people.person_id'); + $this->db->like("first_name",$this->db->escape_like_str($search)); + $this->db->or_like("last_name",$this->db->escape_like_str($search)); + $this->db->or_like("CONCAT(`first_name`,' ',`last_name`)",$this->db->escape_like_str($search)); + $this->db->where("deleted","0"); + $this->db->order_by("last_name", "asc"); + $by_name = $this->db->get(); + + foreach($by_name->result() as $row) + { + $suggestions[]=$row->first_name.' '.$row->last_name; + } +/** END GARRISON MODIFIED **/ + + //only return $limit suggestions + if(count($suggestions > $limit)) + { + $suggestions = array_slice($suggestions, 0,$limit); + } + return $suggestions; + } + + /** GARRISON ADDED 5/3/2013 **/ + /* + Get search suggestions to find customers + */ + function get_person_search_suggestions($search,$limit=25) + { + $suggestions = array(); + + $this->db->select('person_id'); + $this->db->from('people'); + $this->db->like('person_id',$this->db->escape_like_str($search)); + $this->db->or_like('first_name',$this->db->escape_like_str($search)); + $this->db->or_like('last_name',$this->db->escape_like_str($search)); + $this->db->or_like("CONCAT(`first_name`,' ',`last_name`)",$this->db->escape_like_str($search)); + $this->db->or_like('email',$this->db->escape_like_str($search)); + $this->db->or_like('phone_number',$this->db->escape_like_str($search)); + $this->db->order_by('person_id', 'asc'); + $by_person_id = $this->db->get(); + + foreach($by_person_id->result() as $row) + { + $suggestions[]=$row->person_id; + } + + //only return $limit suggestions + if(count($suggestions > $limit)) + { + $suggestions = array_slice($suggestions, 0,$limit); + } + return $suggestions; + } + +/** GARRISON MODIFIED 4/24/2013 **/ + /* + Preform a search on giftcards + */ + function search($search) + { + $this->db->from('giftcards'); + $this->db->join('people','giftcards.person_id=people.person_id'); + $this->db->like("first_name",$this->db->escape_like_str($search)); + $this->db->or_like("last_name",$this->db->escape_like_str($search)); + $this->db->or_like("CONCAT(`first_name`,' ',`last_name`)",$this->db->escape_like_str($search)); + $this->db->or_like("giftcard_number",$this->db->escape_like_str($search)); + $this->db->or_like("giftcards.person_id",$this->db->escape_like_str($search)); + $this->db->where('deleted',$this->db->escape('0')); + $this->db->order_by("giftcard_number", "asc"); + return $this->db->get(); + } + + public function get_giftcard_value( $giftcard_number ) + { + if ( !$this->exists( $this->get_giftcard_id($giftcard_number))) + return 0; + + $this->db->from('giftcards'); + $this->db->where('giftcard_number',$giftcard_number); + return $this->db->get()->row()->value; + } + + function update_giftcard_value( $giftcard_number, $value ) + { + $this->db->where('giftcard_number', $giftcard_number); + $this->db->update('giftcards', array('value' => $value)); + } +} +?> diff --git a/application/models/index.html b/application/models/index.html new file mode 100644 index 000000000..c942a79ce --- /dev/null +++ b/application/models/index.html @@ -0,0 +1,10 @@ + + +Directory access is forbidden.
+ + + \ No newline at end of file diff --git a/application/models/inventory.php b/application/models/inventory.php new file mode 100644 index 000000000..2c18e0277 --- /dev/null +++ b/application/models/inventory.php @@ -0,0 +1,18 @@ +db->insert('inventory',$inventory_data); + } + + function get_inventory_data_for_item($item_id) + { + $this->db->from('inventory'); + $this->db->where('trans_items',$item_id); + $this->db->order_by("trans_date", "desc"); + return $this->db->get(); + } +} + +?> \ No newline at end of file diff --git a/application/models/item.php b/application/models/item.php new file mode 100644 index 000000000..d1a7aa51c --- /dev/null +++ b/application/models/item.php @@ -0,0 +1,579 @@ +db->from('items'); + $this->db->where('item_id',$item_id); + $query = $this->db->get(); + + return ($query->num_rows()==1); + } + + /* + Returns all the items + */ + function get_all($limit=10000, $offset=0) + { + $this->db->from('items'); + $this->db->where('deleted',0); + $this->db->order_by("name", "asc"); + $this->db->limit($limit); + $this->db->offset($offset); + return $this->db->get(); + } + + function count_all() + { + $this->db->from('items'); + $this->db->where('deleted',0); + return $this->db->count_all_results(); + } + + function get_all_filtered($low_inventory=0,$is_serialized=0,$no_description,$search_custom)/**GARRISON MODIFIED 4/21/2013**/ + { + $this->db->from('items'); + if ($low_inventory !=0 ) + { + $this->db->where('quantity <=','reorder_level', false); + } + if ($is_serialized !=0 ) + { + $this->db->where('is_serialized',1); + } + if ($no_description!=0 ) + { + $this->db->where('description',''); + } +/**GARRISON SECTION ADDED 4/21/2013**/ +/** + if ($search_custom!=0 ) + { + $this->db->like('custom1',$search); + $this->db->or_like('custom2',$search); + $this->db->or_like('custom3',$search); + $this->db->or_like('custom4',$search); + $this->db->or_like('custom5',$search); + $this->db->or_like('custom6',$search); + $this->db->or_like('custom7',$search); + $this->db->or_like('custom8',$search); + $this->db->or_like('custom9',$search); + $this->db->or_like('custom10',$search); + } +**/ + $this->db->where('deleted',0); + $this->db->order_by("name", "asc"); + return $this->db->get(); + } + + /* + Gets information about a particular item + */ + function get_info($item_id) + { + $this->db->from('items'); + $this->db->where('item_id',$item_id); + + $query = $this->db->get(); + + if($query->num_rows()==1) + { + return $query->row(); + } + else + { + //Get empty base parent object, as $item_id is NOT an item + $item_obj=new stdClass(); + + //Get all the fields from items table + $fields = $this->db->list_fields('items'); + + foreach ($fields as $field) + { + $item_obj->$field=''; + } + + return $item_obj; + } + } + + /* + Get an item id given an item number + */ + function get_item_id($item_number) + { + $this->db->from('items'); + $this->db->where('item_number',$item_number); + + $query = $this->db->get(); + + if($query->num_rows()==1) + { + return $query->row()->item_id; + } + + return false; + } + + /* + Gets information about multiple items + */ + function get_multiple_info($item_ids) + { + $this->db->from('items'); + $this->db->where_in('item_id',$item_ids); + $this->db->order_by("item", "asc"); + return $this->db->get(); + } + + /* + Inserts or updates a item + */ + function save(&$item_data,$item_id=false) + { + if (!$item_id or !$this->exists($item_id)) + { + if($this->db->insert('items',$item_data)) + { + $item_data['item_id']=$this->db->insert_id(); + return true; + } + return false; + } + + $this->db->where('item_id', $item_id); + return $this->db->update('items',$item_data); + } + + /* + Updates multiple items at once + */ + function update_multiple($item_data,$item_ids) + { + $this->db->where_in('item_id',$item_ids); + return $this->db->update('items',$item_data); + } + + /* + Deletes one item + */ + function delete($item_id) + { + $this->db->where('item_id', $item_id); + return $this->db->update('items', array('deleted' => 1)); + } + + /* + Deletes a list of items + */ + function delete_list($item_ids) + { + $this->db->where_in('item_id',$item_ids); + return $this->db->update('items', array('deleted' => 1)); + } + + /* + Get search suggestions to find items + */ + function get_search_suggestions($search,$limit=25) + { + $suggestions = array(); + + $this->db->from('items'); + $this->db->like('name', $search); + $this->db->where('deleted',0); + $this->db->order_by("name", "asc"); + $by_name = $this->db->get(); + foreach($by_name->result() as $row) + { + $suggestions[]=$row->name; + } + + $this->db->select('category'); + $this->db->from('items'); + $this->db->where('deleted',0); + $this->db->distinct(); + $this->db->like('category', $search); + $this->db->order_by("category", "asc"); + $by_category = $this->db->get(); + foreach($by_category->result() as $row) + { + $suggestions[]=$row->category; + } + + $this->db->from('items'); + $this->db->like('item_number', $search); + $this->db->where('deleted',0); + $this->db->order_by("item_number", "asc"); + $by_item_number = $this->db->get(); + foreach($by_item_number->result() as $row) + { + $suggestions[]=$row->item_number; + } +/** GARRISON ADDED 4/21/2013 **/ + //Search by description + $this->db->from('items'); + $this->db->like('description', $search); + $this->db->where('deleted',0); + $this->db->order_by("description", "asc"); + $by_name = $this->db->get(); + foreach($by_name->result() as $row) + { + $suggestions[]=$row->name; + } +/** END GARRISON ADDED **/ + +/** GARRISON ADDED 4/22/2013 **/ + //Search by custom fields + $this->db->from('items'); + $this->db->like('custom1', $search); + $this->db->or_like('custom2', $search); + $this->db->or_like('custom3', $search); + $this->db->or_like('custom4', $search); + $this->db->or_like('custom5', $search); + $this->db->or_like('custom6', $search); + $this->db->or_like('custom7', $search); + $this->db->or_like('custom8', $search); + $this->db->or_like('custom9', $search); + $this->db->or_like('custom10', $search); + $this->db->where('deleted',0); + $this->db->order_by("name", "asc"); + $by_name = $this->db->get(); + foreach($by_name->result() as $row) + { + $suggestions[]=$row->name; + } +/** END GARRISON ADDED **/ + + //only return $limit suggestions + if(count($suggestions > $limit)) + { + $suggestions = array_slice($suggestions, 0,$limit); + } + return $suggestions; + + } + + function get_item_search_suggestions($search,$limit=25) + { + $suggestions = array(); + + $this->db->from('items'); + $this->db->where('deleted',0); + $this->db->like('name', $search); + $this->db->order_by("name", "asc"); + $by_name = $this->db->get(); + foreach($by_name->result() as $row) + { + $suggestions[]=$row->item_id.'|'.$row->name; + } + + $this->db->from('items'); + $this->db->where('deleted',0); + $this->db->like('item_number', $search); + $this->db->order_by("item_number", "asc"); + $by_item_number = $this->db->get(); + foreach($by_item_number->result() as $row) + { + $suggestions[]=$row->item_id.'|'.$row->item_number; + } +/** GARRISON ADDED 4/21/2013 **/ + //Search by description + $this->db->from('items'); + $this->db->where('deleted',0); + $this->db->like('description', $search); + $this->db->order_by("description", "asc"); + $by_description = $this->db->get(); + foreach($by_description->result() as $row) + { + $suggestions[]=$row->item_id.'|'.$row->name; + } +/** END GARRISON ADDED **/ + /** GARRISON ADDED 4/22/2013 **/ + //Search by custom fields + $this->db->from('items'); + $this->db->where('deleted',0); + $this->db->like('custom1', $search); + $this->db->or_like('custom2', $search); + $this->db->or_like('custom3', $search); + $this->db->or_like('custom4', $search); + $this->db->or_like('custom5', $search); + $this->db->or_like('custom6', $search); + $this->db->or_like('custom7', $search); + $this->db->or_like('custom8', $search); + $this->db->or_like('custom9', $search); + $this->db->or_like('custom10', $search); + $this->db->order_by("name", "asc"); + $by_description = $this->db->get(); + foreach($by_description->result() as $row) + { + $suggestions[]=$row->item_id.'|'.$row->name; + } + /** END GARRISON ADDED **/ + + //only return $limit suggestions + if(count($suggestions > $limit)) + { + $suggestions = array_slice($suggestions, 0,$limit); + } + return $suggestions; + } + + function get_category_suggestions($search) + { + $suggestions = array(); + $this->db->distinct(); + $this->db->select('category'); + $this->db->from('items'); + $this->db->like('category', $search); + $this->db->where('deleted', 0); + $this->db->order_by("category", "asc"); + $by_category = $this->db->get(); + foreach($by_category->result() as $row) + { + $suggestions[]=$row->category; + } + + return $suggestions; + } + +/** GARRISON ADDED 5/18/2013 **/ + function get_location_suggestions($search) + { + $suggestions = array(); + $this->db->distinct(); + $this->db->select('location'); + $this->db->from('items'); + $this->db->like('location', $search); + $this->db->where('deleted', 0); + $this->db->order_by("location", "asc"); + $by_category = $this->db->get(); + foreach($by_category->result() as $row) + { + $suggestions[]=$row->location; + } + + return $suggestions; + } + + function get_custom1_suggestions($search) + { + $suggestions = array(); + $this->db->distinct(); + $this->db->select('custom1'); + $this->db->from('items'); + $this->db->like('custom1', $search); + $this->db->where('deleted', 0); + $this->db->order_by("custom1", "asc"); + $by_category = $this->db->get(); + foreach($by_category->result() as $row) + { + $suggestions[]=$row->custom1; + } + + return $suggestions; + } + + function get_custom2_suggestions($search) + { + $suggestions = array(); + $this->db->distinct(); + $this->db->select('custom2'); + $this->db->from('items'); + $this->db->like('custom2', $search); + $this->db->where('deleted', 0); + $this->db->order_by("custom2", "asc"); + $by_category = $this->db->get(); + foreach($by_category->result() as $row) + { + $suggestions[]=$row->custom2; + } + + return $suggestions; + } + + function get_custom3_suggestions($search) + { + $suggestions = array(); + $this->db->distinct(); + $this->db->select('custom3'); + $this->db->from('items'); + $this->db->like('custom3', $search); + $this->db->where('deleted', 0); + $this->db->order_by("custom3", "asc"); + $by_category = $this->db->get(); + foreach($by_category->result() as $row) + { + $suggestions[]=$row->custom3; + } + + return $suggestions; + } + + function get_custom4_suggestions($search) + { + $suggestions = array(); + $this->db->distinct(); + $this->db->select('custom4'); + $this->db->from('items'); + $this->db->like('custom4', $search); + $this->db->where('deleted', 0); + $this->db->order_by("custom4", "asc"); + $by_category = $this->db->get(); + foreach($by_category->result() as $row) + { + $suggestions[]=$row->custom4; + } + + return $suggestions; + } + + function get_custom5_suggestions($search) + { + $suggestions = array(); + $this->db->distinct(); + $this->db->select('custom5'); + $this->db->from('items'); + $this->db->like('custom5', $search); + $this->db->where('deleted', 0); + $this->db->order_by("custom5", "asc"); + $by_category = $this->db->get(); + foreach($by_category->result() as $row) + { + $suggestions[]=$row->custom5; + } + + return $suggestions; + } + + function get_custom6_suggestions($search) + { + $suggestions = array(); + $this->db->distinct(); + $this->db->select('custom6'); + $this->db->from('items'); + $this->db->like('custom6', $search); + $this->db->where('deleted', 0); + $this->db->order_by("custom6", "asc"); + $by_category = $this->db->get(); + foreach($by_category->result() as $row) + { + $suggestions[]=$row->custom6; + } + + return $suggestions; + } + + function get_custom7_suggestions($search) + { + $suggestions = array(); + $this->db->distinct(); + $this->db->select('custom7'); + $this->db->from('items'); + $this->db->like('custom7', $search); + $this->db->where('deleted', 0); + $this->db->order_by("custom7", "asc"); + $by_category = $this->db->get(); + foreach($by_category->result() as $row) + { + $suggestions[]=$row->custom7; + } + + return $suggestions; + } + + function get_custom8_suggestions($search) + { + $suggestions = array(); + $this->db->distinct(); + $this->db->select('custom8'); + $this->db->from('items'); + $this->db->like('custom8', $search); + $this->db->where('deleted', 0); + $this->db->order_by("custom8", "asc"); + $by_category = $this->db->get(); + foreach($by_category->result() as $row) + { + $suggestions[]=$row->custom8; + } + + return $suggestions; + } + + function get_custom9_suggestions($search) + { + $suggestions = array(); + $this->db->distinct(); + $this->db->select('custom9'); + $this->db->from('items'); + $this->db->like('custom9', $search); + $this->db->where('deleted', 0); + $this->db->order_by("custom9", "asc"); + $by_category = $this->db->get(); + foreach($by_category->result() as $row) + { + $suggestions[]=$row->custom9; + } + + return $suggestions; + } + + function get_custom10_suggestions($search) + { + $suggestions = array(); + $this->db->distinct(); + $this->db->select('custom10'); + $this->db->from('items'); + $this->db->like('custom10', $search); + $this->db->where('deleted', 0); + $this->db->order_by("custom10", "asc"); + $by_category = $this->db->get(); + foreach($by_category->result() as $row) + { + $suggestions[]=$row->custom10; + } + + return $suggestions; + } +/** END GARRISON ADDED **/ + /* + Preform a search on items + */ + function search($search) + { + $this->db->from('items'); + $this->db->where("( + name LIKE '%".$this->db->escape_like_str($search)."%' or + item_number LIKE '%".$this->db->escape_like_str($search)."%' or + description LIKE '%".$this->db->escape_like_str($search)."%' or/**GARRISON ADDED 4/21/2013**/ + custom1 LIKE '%".$this->db->escape_like_str($search)."%' or/**GARRISON ADDED 4/22/2013**/ + custom2 LIKE '%".$this->db->escape_like_str($search)."%' or/**GARRISON ADDED 4/22/2013**/ + custom3 LIKE '%".$this->db->escape_like_str($search)."%' or/**GARRISON ADDED 4/22/2013**/ + custom4 LIKE '%".$this->db->escape_like_str($search)."%' or/**GARRISON ADDED 4/22/2013**/ + custom5 LIKE '%".$this->db->escape_like_str($search)."%' or/**GARRISON ADDED 4/22/2013**/ + custom6 LIKE '%".$this->db->escape_like_str($search)."%' or/**GARRISON ADDED 4/22/2013**/ + custom7 LIKE '%".$this->db->escape_like_str($search)."%' or/**GARRISON ADDED 4/22/2013**/ + custom8 LIKE '%".$this->db->escape_like_str($search)."%' or/**GARRISON ADDED 4/22/2013**/ + custom9 LIKE '%".$this->db->escape_like_str($search)."%' or/**GARRISON ADDED 4/22/2013**/ + custom10 LIKE '%".$this->db->escape_like_str($search)."%' or/**GARRISON ADDED 4/22/2013**/ + category LIKE '%".$this->db->escape_like_str($search)."%') and + deleted=0"); + $this->db->order_by("name", "asc"); + return $this->db->get(); + } + + function get_categories() + { + $this->db->select('category'); + $this->db->from('items'); + $this->db->where('deleted',0); + $this->db->distinct(); + $this->db->order_by("category", "asc"); + + return $this->db->get(); + } +} +?> diff --git a/application/models/item_kit.php b/application/models/item_kit.php new file mode 100644 index 000000000..84fcc7807 --- /dev/null +++ b/application/models/item_kit.php @@ -0,0 +1,171 @@ +db->from('item_kits'); + $this->db->where('item_kit_id',$item_kit_id); + $query = $this->db->get(); + + return ($query->num_rows()==1); + } + + /* + Returns all the item kits + */ + function get_all($limit=10000, $offset=0) + { + $this->db->from('item_kits'); + $this->db->order_by("name", "asc"); + $this->db->limit($limit); + $this->db->offset($offset); + return $this->db->get(); + } + + function count_all() + { + $this->db->from('item_kits'); + return $this->db->count_all_results(); + } + + /* + Gets information about a particular item kit + */ + function get_info($item_kit_id) + { + $this->db->from('item_kits'); + $this->db->where('item_kit_id',$item_kit_id); + + $query = $this->db->get(); + + if($query->num_rows()==1) + { + return $query->row(); + } + else + { + //Get empty base parent object, as $item_kit_id is NOT an item kit + $item_obj=new stdClass(); + + //Get all the fields from items table + $fields = $this->db->list_fields('item_kits'); + + foreach ($fields as $field) + { + $item_obj->$field=''; + } + + return $item_obj; + } + } + + /* + Gets information about multiple item kits + */ + function get_multiple_info($item_kit_ids) + { + $this->db->from('item_kits'); + $this->db->where_in('item_kit_id',$item_kit_ids); + $this->db->order_by("name", "asc"); + return $this->db->get(); + } + + /* + Inserts or updates an item kit + */ + function save(&$item_kit_data,$item_kit_id=false) + { + if (!$item_kit_id or !$this->exists($item_kit_id)) + { + if($this->db->insert('item_kits',$item_kit_data)) + { + $item_kit_data['item_kit_id']=$this->db->insert_id(); + return true; + } + return false; + } + + $this->db->where('item_kit_id', $item_kit_id); + return $this->db->update('item_kits',$item_kit_data); + } + + /* + Deletes one item kit + */ + function delete($item_kit_id) + { + return $this->db->delete('item_kits', array('item_kit_id' => $id)); + } + + /* + Deletes a list of item kits + */ + function delete_list($item_kit_ids) + { + $this->db->where_in('item_kit_id',$item_kit_ids); + return $this->db->delete('item_kits'); + } + + /* + Get search suggestions to find kits + */ + function get_search_suggestions($search,$limit=25) + { + $suggestions = array(); + + $this->db->from('item_kits'); + $this->db->like('name', $search); + $this->db->order_by("name", "asc"); + $by_name = $this->db->get(); + foreach($by_name->result() as $row) + { + $suggestions[]=$row->name; + } + + //only return $limit suggestions + if(count($suggestions > $limit)) + { + $suggestions = array_slice($suggestions, 0,$limit); + } + return $suggestions; + + } + + function get_item_kit_search_suggestions($search, $limit=25) + { + $suggestions = array(); + + $this->db->from('item_kits'); + $this->db->like('name', $search); + $this->db->order_by("name", "asc"); + $by_name = $this->db->get(); + foreach($by_name->result() as $row) + { + $suggestions[]='KIT '.$row->item_kit_id.'|'.$row->name; + } + + //only return $limit suggestions + if(count($suggestions > $limit)) + { + $suggestions = array_slice($suggestions, 0,$limit); + } + return $suggestions; + + } + + /* + Preform a search on items + */ + function search($search) + { + $this->db->from('item_kits'); + $this->db->where("name LIKE '%".$this->db->escape_like_str($search)."%' or + description LIKE '%".$this->db->escape_like_str($search)."%'"); + $this->db->order_by("name", "asc"); + return $this->db->get(); + } +} +?> \ No newline at end of file diff --git a/application/models/item_kit_items.php b/application/models/item_kit_items.php new file mode 100644 index 000000000..e69598b7e --- /dev/null +++ b/application/models/item_kit_items.php @@ -0,0 +1,43 @@ +db->from('item_kit_items'); + $this->db->where('item_kit_id',$item_kit_id); + //return an array of item kit items for an item + return $this->db->get()->result_array(); + } + + /* + Inserts or updates an item kit's items + */ + function save(&$item_kit_items_data, $item_kit_id) + { + //Run these queries as a transaction, we want to make sure we do all or nothing + $this->db->trans_start(); + + $this->delete($item_kit_id); + + foreach ($item_kit_items_data as $row) + { + $row['item_kit_id'] = $item_kit_id; + $this->db->insert('item_kit_items',$row); + } + + $this->db->trans_complete(); + return true; + } + + /* + Deletes item kit items given an item kit + */ + function delete($item_kit_id) + { + return $this->db->delete('item_kit_items', array('item_kit_id' => $item_kit_id)); + } +} +?> diff --git a/application/models/item_taxes.php b/application/models/item_taxes.php new file mode 100644 index 000000000..18033baa7 --- /dev/null +++ b/application/models/item_taxes.php @@ -0,0 +1,51 @@ +db->from('items_taxes'); + $this->db->where('item_id',$item_id); + //return an array of taxes for an item + return $this->db->get()->result_array(); + } + + /* + Inserts or updates an item's taxes + */ + function save(&$items_taxes_data, $item_id) + { + //Run these queries as a transaction, we want to make sure we do all or nothing + $this->db->trans_start(); + + $this->delete($item_id); + + foreach ($items_taxes_data as $row) + { + $row['item_id'] = $item_id; + $this->db->insert('items_taxes',$row); + } + + $this->db->trans_complete(); + return true; + } + + function save_multiple(&$items_taxes_data, $item_ids) + { + foreach($item_ids as $item_id) + { + $this->save($items_taxes_data, $item_id); + } + } + + /* + Deletes taxes given an item + */ + function delete($item_id) + { + return $this->db->delete('items_taxes', array('item_id' => $item_id)); + } +} +?> diff --git a/application/models/module.php b/application/models/module.php new file mode 100644 index 000000000..1e14c6d85 --- /dev/null +++ b/application/models/module.php @@ -0,0 +1,50 @@ +db->get_where('modules', array('module_id' => $module_id), 1); + + if ($query->num_rows() ==1) + { + $row = $query->row(); + return $this->lang->line($row->name_lang_key); + } + + return $this->lang->line('error_unknown'); + } + + function get_module_desc($module_id) + { + $query = $this->db->get_where('modules', array('module_id' => $module_id), 1); + if ($query->num_rows() ==1) + { + $row = $query->row(); + return $this->lang->line($row->desc_lang_key); + } + + return $this->lang->line('error_unknown'); + } + + function get_all_modules() + { + $this->db->from('modules'); + $this->db->order_by("sort", "asc"); + return $this->db->get(); + } + + function get_allowed_modules($person_id) + { + $this->db->from('modules'); + $this->db->join('permissions','permissions.module_id=modules.module_id'); + $this->db->where("permissions.person_id",$person_id); + $this->db->order_by("sort", "asc"); + return $this->db->get(); + } +} +?> diff --git a/application/models/person.php b/application/models/person.php new file mode 100644 index 000000000..ba87d8bc0 --- /dev/null +++ b/application/models/person.php @@ -0,0 +1,137 @@ +db->from('people'); + $this->db->where('people.person_id',$person_id); + $query = $this->db->get(); + + return ($query->num_rows()==1); + } + + /*Gets all people*/ + function get_all($limit=10000, $offset=0) + { + $this->db->from('people'); + $this->db->order_by("last_name", "asc"); + $this->db->limit($limit); + $this->db->offset($offset); + return $this->db->get(); + } + + function count_all() + { + $this->db->from('people'); + $this->db->where('deleted',0); + return $this->db->count_all_results(); + } + + /* + Gets information about a person as an array. + */ + function get_info($person_id) + { + $query = $this->db->get_where('people', array('person_id' => $person_id), 1); + + if($query->num_rows()==1) + { + return $query->row(); + } + else + { + //create object with empty properties. + $fields = $this->db->list_fields('people'); + $person_obj = new stdClass; + + foreach ($fields as $field) + { + $person_obj->$field=''; + } + + return $person_obj; + } + } + + /* + Get people with specific ids + */ + function get_multiple_info($person_ids) + { + $this->db->from('people'); + $this->db->where_in('person_id',$person_ids); + $this->db->order_by("last_name", "asc"); + return $this->db->get(); + } + + /* + Inserts or updates a person + */ + function save(&$person_data,$person_id=false) + { + if (!$person_id or !$this->exists($person_id)) + { + if ($this->db->insert('people',$person_data)) + { + $person_data['person_id']=$this->db->insert_id(); + return true; + } + + return false; + } + + $this->db->where('person_id', $person_id); + return $this->db->update('people',$person_data); + } +/** GARRISON ADDED 4/25/2013 IN PROGRESS **/ + /* + Get search suggestions to find customers + */ + function get_search_suggestions($search,$limit=25) + { + $suggestions = array(); + +// $this->db->select("person_id"); +// $this->db->from('people'); +// $this->db->where('deleted',0); +// $this->db->where('person_id',$this->db->escape($search)); +// $this->db->like('first_name',$this->db->escape_like_str($search)); +// $this->db->or_like('last_name',$this->db->escape_like_str($search)); +// $this->db->or_like("CONCAT(`first_name`,' ',`last_name`)",$this->db->escape_like_str($search)); +// $this->db->or_like('email',$search); +// $this->db->or_like('phone_number',$search); +// $this->db->order_by('last_name', "asc"); + $by_person_id = $this->db->get(); + + foreach($by_person_id->result() as $row) + { + $suggestions[]=$row->person_id; + } + + //only return $limit suggestions + if(count($suggestions > $limit)) + { + $suggestions = array_slice($suggestions, 0,$limit); + } + return $suggestions; + } + + /* + Deletes one Person (doesn't actually do anything) + */ + function delete($person_id) + { + return true;; + } + + /* + Deletes a list of people (doesn't actually do anything) + */ + function delete_list($person_ids) + { + return true; + } + +} +?> diff --git a/application/models/receiving.php b/application/models/receiving.php new file mode 100644 index 000000000..e47f46348 --- /dev/null +++ b/application/models/receiving.php @@ -0,0 +1,118 @@ +db->from('receivings'); + $this->db->where('receiving_id',$receiving_id); + return $this->db->get(); + } + + function exists($receiving_id) + { + $this->db->from('receivings'); + $this->db->where('receiving_id',$receiving_id); + $query = $this->db->get(); + + return ($query->num_rows()==1); + } + + function save ($items,$supplier_id,$employee_id,$comment,$payment_type,$receiving_id=false) + { + if(count($items)==0) + return -1; + + $receivings_data = array( + 'supplier_id'=> $this->Supplier->exists($supplier_id) ? $supplier_id : null, + 'employee_id'=>$employee_id, + 'payment_type'=>$payment_type, + 'comment'=>$comment + ); + + //Run these queries as a transaction, we want to make sure we do all or nothing + $this->db->trans_start(); + + $this->db->insert('receivings',$receivings_data); + $receiving_id = $this->db->insert_id(); + + + foreach($items as $line=>$item) + { + $cur_item_info = $this->Item->get_info($item['item_id']); + + $receivings_items_data = array + ( + 'receiving_id'=>$receiving_id, + 'item_id'=>$item['item_id'], + 'line'=>$item['line'], + 'description'=>$item['description'], + 'serialnumber'=>$item['serialnumber'], + 'quantity_purchased'=>$item['quantity'], + 'discount_percent'=>$item['discount'], + 'item_cost_price' => $cur_item_info->cost_price, + 'item_unit_price'=>$item['price'] + ); + + $this->db->insert('receivings_items',$receivings_items_data); + + //Update stock quantity + $item_data = array('quantity'=>$cur_item_info->quantity + $item['quantity']); + $this->Item->save($item_data,$item['item_id']); + + $qty_recv = $item['quantity']; + $recv_remarks ='RECV '.$receiving_id; + $inv_data = array + ( + 'trans_date'=>date('Y-m-d H:i:s'), + 'trans_items'=>$item['item_id'], + 'trans_user'=>$employee_id, + 'trans_comment'=>$recv_remarks, + 'trans_inventory'=>$qty_recv + ); + $this->Inventory->insert($inv_data); + + $supplier = $this->Supplier->get_info($supplier_id); + } + $this->db->trans_complete(); + + if ($this->db->trans_status() === FALSE) + { + return -1; + } + + return $receiving_id; + } + + function get_receiving_items($receiving_id) + { + $this->db->from('receivings_items'); + $this->db->where('receiving_id',$receiving_id); + return $this->db->get(); + } + + function get_supplier($receiving_id) + { + $this->db->from('receivings'); + $this->db->where('receiving_id',$receiving_id); + return $this->Supplier->get_info($this->db->get()->row()->supplier_id); + } + + //We create a temp table that allows us to do easy report/receiving queries + public function create_receivings_items_temp_table() + { + $this->db->query("CREATE TEMPORARY TABLE ".$this->db->dbprefix('receivings_items_temp')." + (SELECT date(receiving_time) as receiving_date, ".$this->db->dbprefix('receivings_items').".receiving_id, comment,payment_type, employee_id, + ".$this->db->dbprefix('items').".item_id, ".$this->db->dbprefix('receivings').".supplier_id, quantity_purchased, item_cost_price, item_unit_price, + discount_percent, (item_unit_price*quantity_purchased-item_unit_price*quantity_purchased*discount_percent/100) as subtotal, + ".$this->db->dbprefix('receivings_items').".line as line, serialnumber, ".$this->db->dbprefix('receivings_items').".description as description, + ROUND((item_unit_price*quantity_purchased-item_unit_price*quantity_purchased*discount_percent/100),2) as total, + (item_unit_price*quantity_purchased-item_unit_price*quantity_purchased*discount_percent/100) - (item_cost_price*quantity_purchased) as profit + FROM ".$this->db->dbprefix('receivings_items')." + INNER JOIN ".$this->db->dbprefix('receivings')." ON ".$this->db->dbprefix('receivings_items').'.receiving_id='.$this->db->dbprefix('receivings').'.receiving_id'." + INNER JOIN ".$this->db->dbprefix('items')." ON ".$this->db->dbprefix('receivings_items').'.item_id='.$this->db->dbprefix('items').'.item_id'." + GROUP BY receiving_id, item_id, line)"); + } + + +} +?> diff --git a/application/models/reports/detailed_receivings.php b/application/models/reports/detailed_receivings.php new file mode 100644 index 000000000..0af71d504 --- /dev/null +++ b/application/models/reports/detailed_receivings.php @@ -0,0 +1,67 @@ + array($this->lang->line('reports_receiving_id'), $this->lang->line('reports_date'), $this->lang->line('reports_items_received'), $this->lang->line('reports_received_by'), $this->lang->line('reports_supplied_by'), $this->lang->line('reports_total'), $this->lang->line('reports_payment_type'), $this->lang->line('reports_comments')), + 'details' => array($this->lang->line('reports_name'), $this->lang->line('reports_category'), $this->lang->line('reports_quantity_purchased'), $this->lang->line('reports_total'), $this->lang->line('reports_discount')) + ); + } + + public function getData(array $inputs) + { + $this->db->select('receiving_id, receiving_date, sum(quantity_purchased) as items_purchased, CONCAT(employee.first_name," ",employee.last_name) as employee_name, CONCAT(supplier.first_name," ",supplier.last_name) as supplier_name, sum(total) as total, sum(profit) as profit, payment_type, comment', false); + $this->db->from('receivings_items_temp'); + $this->db->join('people as employee', 'receivings_items_temp.employee_id = employee.person_id'); + $this->db->join('people as supplier', 'receivings_items_temp.supplier_id = supplier.person_id', 'left'); + $this->db->where('receiving_date BETWEEN "'. $inputs['start_date']. '" and "'. $inputs['end_date'].'"'); + if ($inputs['sale_type'] == 'sales') + { + $this->db->where('quantity_purchased > 0'); + } + elseif ($inputs['sale_type'] == 'returns') + { + $this->db->where('quantity_purchased < 0'); + } + $this->db->group_by('receiving_id'); + $this->db->order_by('receiving_date'); + + $data = array(); + $data['summary'] = $this->db->get()->result_array(); + $data['details'] = array(); + + foreach($data['summary'] as $key=>$value) + { + $this->db->select('name, category, quantity_purchased, serialnumber,total, discount_percent'); + $this->db->from('receivings_items_temp'); + $this->db->join('items', 'receivings_items_temp.item_id = items.item_id'); + $this->db->where('receiving_id = '.$value['receiving_id']); + $data['details'][$key] = $this->db->get()->result_array(); + } + + return $data; + } + + public function getSummaryData(array $inputs) + { + $this->db->select('sum(total) as total'); + $this->db->from('receivings_items_temp'); + $this->db->where('receiving_date BETWEEN "'. $inputs['start_date']. '" and "'. $inputs['end_date'].'"'); + if ($inputs['sale_type'] == 'sales') + { + $this->db->where('quantity_purchased > 0'); + } + elseif ($inputs['sale_type'] == 'returns') + { + $this->db->where('quantity_purchased < 0'); + } + return $this->db->get()->row_array(); + } +} +?> \ No newline at end of file diff --git a/application/models/reports/detailed_sales.php b/application/models/reports/detailed_sales.php new file mode 100644 index 000000000..a1776c8fa --- /dev/null +++ b/application/models/reports/detailed_sales.php @@ -0,0 +1,68 @@ + array($this->lang->line('reports_sale_id'), $this->lang->line('reports_date'), $this->lang->line('reports_items_purchased'), $this->lang->line('reports_sold_by'), $this->lang->line('reports_sold_to'), $this->lang->line('reports_subtotal'), $this->lang->line('reports_total'), $this->lang->line('reports_tax'), $this->lang->line('reports_profit'), $this->lang->line('reports_payment_type'), $this->lang->line('reports_comments')), + 'details' => array($this->lang->line('reports_name'), $this->lang->line('reports_category'), $this->lang->line('reports_serial_number'), $this->lang->line('reports_description'), $this->lang->line('reports_quantity_purchased'), $this->lang->line('reports_subtotal'), $this->lang->line('reports_total'), $this->lang->line('reports_tax'), $this->lang->line('reports_profit'),$this->lang->line('reports_discount')) + ); + } + + public function getData(array $inputs) + { + $this->db->select('sale_id, sale_date, sum(quantity_purchased) as items_purchased, CONCAT(employee.first_name," ",employee.last_name) as employee_name, CONCAT(customer.first_name," ",customer.last_name) as customer_name, sum(subtotal) as subtotal, sum(total) as total, sum(tax) as tax, sum(profit) as profit, payment_type, comment', false); + $this->db->from('sales_items_temp'); + $this->db->join('people as employee', 'sales_items_temp.employee_id = employee.person_id'); + $this->db->join('people as customer', 'sales_items_temp.customer_id = customer.person_id', 'left'); + $this->db->where('sale_date BETWEEN "'. $inputs['start_date']. '" and "'. $inputs['end_date'].'"'); + if ($inputs['sale_type'] == 'sales') + { + $this->db->where('quantity_purchased > 0'); + } + elseif ($inputs['sale_type'] == 'returns') + { + $this->db->where('quantity_purchased < 0'); + } + $this->db->group_by('sale_id'); + $this->db->order_by('sale_date'); + + $data = array(); + $data['summary'] = $this->db->get()->result_array(); + $data['details'] = array(); + + foreach($data['summary'] as $key=>$value) + { + $this->db->select('name, category, quantity_purchased, serialnumber, sales_items_temp.description, subtotal,total, tax, profit, discount_percent'); + $this->db->from('sales_items_temp'); + $this->db->join('items', 'sales_items_temp.item_id = items.item_id'); + $this->db->where('sale_id = '.$value['sale_id']); + $data['details'][$key] = $this->db->get()->result_array(); + } + + return $data; + } + + public function getSummaryData(array $inputs) + { + $this->db->select('sum(subtotal) as subtotal, sum(total) as total, sum(tax) as tax, sum(profit) as profit'); + $this->db->from('sales_items_temp'); + $this->db->where('sale_date BETWEEN "'. $inputs['start_date']. '" and "'. $inputs['end_date'].'"'); + if ($inputs['sale_type'] == 'sales') + { + $this->db->where('quantity_purchased > 0'); + } + elseif ($inputs['sale_type'] == 'returns') + { + $this->db->where('quantity_purchased < 0'); + } + + return $this->db->get()->row_array(); + } +} +?> \ No newline at end of file diff --git a/application/models/reports/inventory_low.php b/application/models/reports/inventory_low.php new file mode 100644 index 000000000..98652e6a7 --- /dev/null +++ b/application/models/reports/inventory_low.php @@ -0,0 +1,31 @@ +lang->line('reports_item_name'), $this->lang->line('reports_item_number'), $this->lang->line('reports_description'), $this->lang->line('reports_count'), $this->lang->line('reports_reorder_level')); + } + + public function getData(array $inputs) + { + $this->db->select('name, item_number, quantity, reorder_level, description'); + $this->db->from('items'); + $this->db->where('quantity <= reorder_level and deleted=0'); + $this->db->order_by('name'); + + return $this->db->get()->result_array(); + + } + + public function getSummaryData(array $inputs) + { + return array(); + } +} +?> \ No newline at end of file diff --git a/application/models/reports/inventory_summary.php b/application/models/reports/inventory_summary.php new file mode 100644 index 000000000..a6130f891 --- /dev/null +++ b/application/models/reports/inventory_summary.php @@ -0,0 +1,31 @@ +lang->line('reports_item_name'), $this->lang->line('reports_item_number'), $this->lang->line('reports_description'), $this->lang->line('reports_count'), $this->lang->line('reports_reorder_level')); + } + + public function getData(array $inputs) + { + $this->db->select('name, item_number, quantity, reorder_level, description'); + $this->db->from('items'); + $this->db->where('deleted', 0); + $this->db->order_by('name'); + + return $this->db->get()->result_array(); + + } + + public function getSummaryData(array $inputs) + { + return array(); + } +} +?> \ No newline at end of file diff --git a/application/models/reports/report.php b/application/models/reports/report.php new file mode 100644 index 000000000..0a7f6e31a --- /dev/null +++ b/application/models/reports/report.php @@ -0,0 +1,28 @@ +output->set_header("Last-Modified: " . gmdate("D, d M Y H:i:s") . " GMT"); + $this->output->set_header("Cache-Control: no-store, no-cache, must-revalidate"); + $this->output->set_header("Cache-Control: post-check=0, pre-check=0", false); + $this->output->set_header("Pragma: no-cache"); + + //Create our temp tables to work with the data in our report + $this->Sale->create_sales_items_temp_table(); + $this->Receiving->create_receivings_items_temp_table(); + } + + //Returns the column names used for the report + public abstract function getDataColumns(); + + //Returns all the data to be populated into the report + public abstract function getData(array $inputs); + + //Returns key=>value pairing of summary data for the report + public abstract function getSummaryData(array $inputs); +} +?> \ No newline at end of file diff --git a/application/models/reports/specific_customer.php b/application/models/reports/specific_customer.php new file mode 100644 index 000000000..0b2f8c342 --- /dev/null +++ b/application/models/reports/specific_customer.php @@ -0,0 +1,66 @@ + array($this->lang->line('reports_sale_id'), $this->lang->line('reports_date'), $this->lang->line('reports_items_purchased'), $this->lang->line('reports_sold_by'), $this->lang->line('reports_subtotal'), $this->lang->line('reports_total'), $this->lang->line('reports_tax'), $this->lang->line('reports_profit'), $this->lang->line('reports_payment_type'), $this->lang->line('reports_comments')), + 'details' => array($this->lang->line('reports_name'), $this->lang->line('reports_category'),$this->lang->line('reports_serial_number'), $this->lang->line('reports_description'), $this->lang->line('reports_quantity_purchased'), $this->lang->line('reports_subtotal'), $this->lang->line('reports_total'), $this->lang->line('reports_tax'), $this->lang->line('reports_profit'),$this->lang->line('reports_discount')) + ); + } + + public function getData(array $inputs) + { + $this->db->select('sale_id, sale_date, sum(quantity_purchased) as items_purchased, CONCAT(first_name," ",last_name) as employee_name, sum(subtotal) as subtotal, sum(total) as total, sum(tax) as tax, sum(profit) as profit, payment_type, comment', false); + $this->db->from('sales_items_temp'); + $this->db->join('people', 'sales_items_temp.employee_id = people.person_id'); + $this->db->where('sale_date BETWEEN "'. $inputs['start_date']. '" and "'. $inputs['end_date'].'" and customer_id='.$inputs['customer_id']); + if ($inputs['sale_type'] == 'sales') + { + $this->db->where('quantity_purchased > 0'); + } + elseif ($inputs['sale_type'] == 'returns') + { + $this->db->where('quantity_purchased < 0'); + } + $this->db->group_by('sale_id'); + $this->db->order_by('sale_date'); + + $data = array(); + $data['summary'] = $this->db->get()->result_array(); + $data['details'] = array(); + + foreach($data['summary'] as $key=>$value) + { + $this->db->select('name, category, serialnumber, sales_items_temp.description, quantity_purchased, subtotal,total, tax, profit, discount_percent'); + $this->db->from('sales_items_temp'); + $this->db->join('items', 'sales_items_temp.item_id = items.item_id'); + $this->db->where('sale_id = '.$value['sale_id']); + $data['details'][$key] = $this->db->get()->result_array(); + } + + return $data; + } + + public function getSummaryData(array $inputs) + { + $this->db->select('sum(subtotal) as subtotal, sum(total) as total, sum(tax) as tax, sum(profit) as profit'); + $this->db->from('sales_items_temp'); + $this->db->where('sale_date BETWEEN "'. $inputs['start_date']. '" and "'. $inputs['end_date'].'" and customer_id='.$inputs['customer_id']); + if ($inputs['sale_type'] == 'sales') + { + $this->db->where('quantity_purchased > 0'); + } + elseif ($inputs['sale_type'] == 'returns') + { + $this->db->where('quantity_purchased < 0'); + } + return $this->db->get()->row_array(); + } +} +?> \ No newline at end of file diff --git a/application/models/reports/specific_employee.php b/application/models/reports/specific_employee.php new file mode 100644 index 000000000..39fff80f9 --- /dev/null +++ b/application/models/reports/specific_employee.php @@ -0,0 +1,68 @@ + array($this->lang->line('reports_sale_id'), $this->lang->line('reports_date'), $this->lang->line('reports_items_purchased'), $this->lang->line('reports_sold_to'), $this->lang->line('reports_subtotal'), $this->lang->line('reports_total'), $this->lang->line('reports_tax'), $this->lang->line('reports_profit'), $this->lang->line('reports_payment_type'), $this->lang->line('reports_comments')), + 'details' => array($this->lang->line('reports_name'), $this->lang->line('reports_category'), $this->lang->line('reports_serial_number'), $this->lang->line('reports_description'), $this->lang->line('reports_quantity_purchased'), $this->lang->line('reports_subtotal'), $this->lang->line('reports_total'), $this->lang->line('reports_tax'), $this->lang->line('reports_profit'),$this->lang->line('reports_discount')) + ); + } + + public function getData(array $inputs) + { + $this->db->select('sale_id, sale_date, sum(quantity_purchased) as items_purchased, CONCAT(first_name," ",last_name) as customer_name, sum(subtotal) as subtotal, sum(total) as total, sum(tax) as tax, sum(profit) as profit, payment_type, comment', false); + $this->db->from('sales_items_temp'); + $this->db->join('people', 'sales_items_temp.customer_id = people.person_id', 'left'); + $this->db->where('sale_date BETWEEN "'. $inputs['start_date']. '" and "'. $inputs['end_date'].'" and employee_id='.$inputs['employee_id']); + + if ($inputs['sale_type'] == 'sales') + { + $this->db->where('quantity_purchased > 0'); + } + elseif ($inputs['sale_type'] == 'returns') + { + $this->db->where('quantity_purchased < 0'); + } + + $this->db->group_by('sale_id'); + $this->db->order_by('sale_date'); + + $data = array(); + $data['summary'] = $this->db->get()->result_array(); + $data['details'] = array(); + + foreach($data['summary'] as $key=>$value) + { + $this->db->select('name, category, serialnumber, sales_items_temp.description, quantity_purchased, subtotal,total, tax, profit, discount_percent'); + $this->db->from('sales_items_temp'); + $this->db->join('items', 'sales_items_temp.item_id = items.item_id'); + $this->db->where('sale_id = '.$value['sale_id']); + $data['details'][$key] = $this->db->get()->result_array(); + } + + return $data; + } + + public function getSummaryData(array $inputs) + { + $this->db->select('sum(subtotal) as subtotal, sum(total) as total, sum(tax) as tax, sum(profit) as profit'); + $this->db->from('sales_items_temp'); + $this->db->where('sale_date BETWEEN "'. $inputs['start_date']. '" and "'. $inputs['end_date'].'" and employee_id='.$inputs['employee_id']); + if ($inputs['sale_type'] == 'sales') + { + $this->db->where('quantity_purchased > 0'); + } + elseif ($inputs['sale_type'] == 'returns') + { + $this->db->where('quantity_purchased < 0'); + } + return $this->db->get()->row_array(); + } +} +?> \ No newline at end of file diff --git a/application/models/reports/summary_categories.php b/application/models/reports/summary_categories.php new file mode 100644 index 000000000..27c30ae46 --- /dev/null +++ b/application/models/reports/summary_categories.php @@ -0,0 +1,53 @@ +lang->line('reports_category'), $this->lang->line('reports_subtotal'), $this->lang->line('reports_total'), $this->lang->line('reports_tax'), $this->lang->line('reports_profit')); + } + + public function getData(array $inputs) + { + $this->db->select('category, sum(subtotal) as subtotal, sum(total) as total, sum(tax) as tax, sum(profit) as profit'); + $this->db->from('sales_items_temp'); + $this->db->join('items', 'sales_items_temp.item_id = items.item_id'); + $this->db->where('sale_date BETWEEN "'. $inputs['start_date']. '" and "'. $inputs['end_date'].'"'); + if ($inputs['sale_type'] == 'sales') + { + $this->db->where('quantity_purchased > 0'); + } + elseif ($inputs['sale_type'] == 'returns') + { + $this->db->where('quantity_purchased < 0'); + } + $this->db->group_by('category'); + $this->db->order_by('category'); + + return $this->db->get()->result_array(); + } + + public function getSummaryData(array $inputs) + { + $this->db->select('sum(subtotal) as subtotal, sum(total) as total, sum(tax) as tax, sum(profit) as profit'); + $this->db->from('sales_items_temp'); + $this->db->join('items', 'sales_items_temp.item_id = items.item_id'); + $this->db->where('sale_date BETWEEN "'. $inputs['start_date']. '" and "'. $inputs['end_date'].'"'); + if ($inputs['sale_type'] == 'sales') + { + $this->db->where('quantity_purchased > 0'); + } + elseif ($inputs['sale_type'] == 'returns') + { + $this->db->where('quantity_purchased < 0'); + } + + return $this->db->get()->row_array(); + } +} +?> \ No newline at end of file diff --git a/application/models/reports/summary_customers.php b/application/models/reports/summary_customers.php new file mode 100644 index 000000000..1f8fa6aea --- /dev/null +++ b/application/models/reports/summary_customers.php @@ -0,0 +1,54 @@ +lang->line('reports_customer'), $this->lang->line('reports_subtotal'), $this->lang->line('reports_total'), $this->lang->line('reports_tax'), $this->lang->line('reports_profit')); + } + + public function getData(array $inputs) + { + $this->db->select('CONCAT(first_name, " ",last_name) as customer, sum(subtotal) as subtotal, sum(total) as total, sum(tax) as tax,sum(profit) as profit', false); + $this->db->from('sales_items_temp'); + $this->db->join('customers', 'customers.person_id = sales_items_temp.customer_id'); + $this->db->join('people', 'customers.person_id = people.person_id'); + $this->db->where('sale_date BETWEEN "'. $inputs['start_date']. '" and "'. $inputs['end_date'].'"'); + if ($inputs['sale_type'] == 'sales') + { + $this->db->where('quantity_purchased > 0'); + } + elseif ($inputs['sale_type'] == 'returns') + { + $this->db->where('quantity_purchased < 0'); + } + $this->db->group_by('customer_id'); + $this->db->order_by('last_name'); + + return $this->db->get()->result_array(); + } + + public function getSummaryData(array $inputs) + { + $this->db->select('sum(subtotal) as subtotal, sum(total) as total, sum(tax) as tax, sum(profit) as profit'); + $this->db->from('sales_items_temp'); + $this->db->join('customers', 'customers.person_id = sales_items_temp.customer_id'); + $this->db->join('people', 'customers.person_id = people.person_id'); + $this->db->where('sale_date BETWEEN "'. $inputs['start_date']. '" and "'. $inputs['end_date'].'"'); + if ($inputs['sale_type'] == 'sales') + { + $this->db->where('quantity_purchased > 0'); + } + elseif ($inputs['sale_type'] == 'returns') + { + $this->db->where('quantity_purchased < 0'); + } + return $this->db->get()->row_array(); + } +} +?> \ No newline at end of file diff --git a/application/models/reports/summary_discounts.php b/application/models/reports/summary_discounts.php new file mode 100644 index 000000000..6b3949eb0 --- /dev/null +++ b/application/models/reports/summary_discounts.php @@ -0,0 +1,49 @@ +lang->line('reports_discount_percent'),$this->lang->line('reports_count')); + } + + public function getData(array $inputs) + { + $this->db->select('CONCAT(discount_percent, "%") as discount_percent, count(*) as count', false); + $this->db->from('sales_items_temp'); + $this->db->where('sale_date BETWEEN "'. $inputs['start_date']. '" and "'. $inputs['end_date'].'" and discount_percent > 0'); + if ($inputs['sale_type'] == 'sales') + { + $this->db->where('quantity_purchased > 0'); + } + elseif ($inputs['sale_type'] == 'returns') + { + $this->db->where('quantity_purchased < 0'); + } + $this->db->group_by('sales_items_temp.discount_percent'); + $this->db->order_by('discount_percent'); + return $this->db->get()->result_array(); + } + + public function getSummaryData(array $inputs) + { + $this->db->select('sum(subtotal) as subtotal, sum(total) as total, sum(tax) as tax,sum(profit) as profit'); + $this->db->from('sales_items_temp'); + $this->db->where('sale_date BETWEEN "'. $inputs['start_date']. '" and "'. $inputs['end_date'].'"'); + if ($inputs['sale_type'] == 'sales') + { + $this->db->where('quantity_purchased > 0'); + } + elseif ($inputs['sale_type'] == 'returns') + { + $this->db->where('quantity_purchased < 0'); + } + return $this->db->get()->row_array(); + } +} +?> \ No newline at end of file diff --git a/application/models/reports/summary_employees.php b/application/models/reports/summary_employees.php new file mode 100644 index 000000000..5308e8e95 --- /dev/null +++ b/application/models/reports/summary_employees.php @@ -0,0 +1,55 @@ +lang->line('reports_employee'), $this->lang->line('reports_subtotal'), $this->lang->line('reports_total'), $this->lang->line('reports_tax'), $this->lang->line('reports_profit')); + } + + public function getData(array $inputs) + { + $this->db->select('CONCAT(first_name, " ",last_name) as employee, sum(subtotal) as subtotal, sum(total) as total, sum(tax) as tax, sum(profit) as profit', false); + $this->db->from('sales_items_temp'); + $this->db->join('employees', 'employees.person_id = sales_items_temp.employee_id'); + $this->db->join('people', 'employees.person_id = people.person_id'); + $this->db->where('sale_date BETWEEN "'. $inputs['start_date']. '" and "'. $inputs['end_date'].'"'); + if ($inputs['sale_type'] == 'sales') + { + $this->db->where('quantity_purchased > 0'); + } + elseif ($inputs['sale_type'] == 'returns') + { + $this->db->where('quantity_purchased < 0'); + } + $this->db->group_by('employee_id'); + $this->db->order_by('last_name'); + + return $this->db->get()->result_array(); + } + + public function getSummaryData(array $inputs) + { + $this->db->select('sum(subtotal) as subtotal, sum(total) as total, sum(tax) as tax, sum(profit) as profit'); + $this->db->from('sales_items_temp'); + $this->db->join('employees', 'employees.person_id = sales_items_temp.employee_id'); + $this->db->join('people', 'employees.person_id = people.person_id'); + $this->db->where('sale_date BETWEEN "'. $inputs['start_date']. '" and "'. $inputs['end_date'].'"'); + if ($inputs['sale_type'] == 'sales') + { + $this->db->where('quantity_purchased > 0'); + } + elseif ($inputs['sale_type'] == 'returns') + { + $this->db->where('quantity_purchased < 0'); + } + + return $this->db->get()->row_array(); + } +} +?> \ No newline at end of file diff --git a/application/models/reports/summary_items.php b/application/models/reports/summary_items.php new file mode 100644 index 000000000..8aefb5475 --- /dev/null +++ b/application/models/reports/summary_items.php @@ -0,0 +1,52 @@ +lang->line('reports_item'),$this->lang->line('reports_quantity_purchased'), $this->lang->line('reports_subtotal'), $this->lang->line('reports_total'), $this->lang->line('reports_tax'),$this->lang->line('reports_profit')); + } + + public function getData(array $inputs) + { + $this->db->select('name, sum(quantity_purchased) as quantity_purchased, sum(subtotal) as subtotal, sum(total) as total, sum(tax) as tax, sum(profit) as profit'); + $this->db->from('sales_items_temp'); + $this->db->join('items', 'sales_items_temp.item_id = items.item_id'); + $this->db->where('sale_date BETWEEN "'. $inputs['start_date']. '" and "'. $inputs['end_date'].'"'); + if ($inputs['sale_type'] == 'sales') + { + $this->db->where('quantity_purchased > 0'); + } + elseif ($inputs['sale_type'] == 'returns') + { + $this->db->where('quantity_purchased < 0'); + } + $this->db->group_by('items.item_id'); + $this->db->order_by('name'); + + return $this->db->get()->result_array(); + } + + public function getSummaryData(array $inputs) + { + $this->db->select('sum(subtotal) as subtotal, sum(total) as total, sum(tax) as tax, sum(profit) as profit'); + $this->db->from('sales_items_temp'); + $this->db->join('items', 'sales_items_temp.item_id = items.item_id'); + $this->db->where('sale_date BETWEEN "'. $inputs['start_date']. '" and "'. $inputs['end_date'].'"'); + if ($inputs['sale_type'] == 'sales') + { + $this->db->where('quantity_purchased > 0'); + } + elseif ($inputs['sale_type'] == 'returns') + { + $this->db->where('quantity_purchased < 0'); + } + return $this->db->get()->row_array(); + } +} +?> \ No newline at end of file diff --git a/application/models/reports/summary_payments.php b/application/models/reports/summary_payments.php new file mode 100644 index 000000000..2c95ac69c --- /dev/null +++ b/application/models/reports/summary_payments.php @@ -0,0 +1,50 @@ +lang->line('reports_payment_type'), $this->lang->line('reports_total')); + } + + public function getData(array $inputs) + { + $this->db->select('sales_payments.payment_type, SUM(payment_amount) as payment_amount', false); + $this->db->from('sales_payments'); + $this->db->join('sales', 'sales.sale_id=sales_payments.sale_id'); + $this->db->where('date(sale_time) BETWEEN "'. $inputs['start_date']. '" and "'. $inputs['end_date'].'"'); + if ($inputs['sale_type'] == 'sales') + { + $this->db->where('payment_amount > 0'); + } + elseif ($inputs['sale_type'] == 'returns') + { + $this->db->where('payment_amount < 0'); + } + $this->db->group_by("payment_type"); + return $this->db->get()->result_array(); + } + + public function getSummaryData(array $inputs) + { + $this->db->select('sum(subtotal) as subtotal, sum(total) as total, sum(tax) as tax, sum(profit) as profit'); + $this->db->from('sales_items_temp'); + $this->db->join('items', 'sales_items_temp.item_id = items.item_id'); + $this->db->where('sale_date BETWEEN "'. $inputs['start_date']. '" and "'. $inputs['end_date'].'"'); + if ($inputs['sale_type'] == 'sales') + { + $this->db->where('quantity_purchased > 0'); + } + elseif ($inputs['sale_type'] == 'returns') + { + $this->db->where('quantity_purchased < 0'); + } + return $this->db->get()->row_array(); + } +} +?> \ No newline at end of file diff --git a/application/models/reports/summary_sales.php b/application/models/reports/summary_sales.php new file mode 100644 index 000000000..e7914a9ee --- /dev/null +++ b/application/models/reports/summary_sales.php @@ -0,0 +1,51 @@ +lang->line('reports_date'), $this->lang->line('reports_subtotal'), $this->lang->line('reports_total'), $this->lang->line('reports_tax'), $this->lang->line('reports_profit')); + } + + public function getData(array $inputs) + { + $this->db->select('sale_date, sum(subtotal) as subtotal, sum(total) as total, sum(tax) as tax,sum(profit) as profit'); + $this->db->from('sales_items_temp'); + if ($inputs['sale_type'] == 'sales') + { + $this->db->where('quantity_purchased > 0'); + } + elseif ($inputs['sale_type'] == 'returns') + { + $this->db->where('quantity_purchased < 0'); + } + + $this->db->group_by('sale_date'); + $this->db->having('sale_date BETWEEN "'. $inputs['start_date']. '" and "'. $inputs['end_date'].'"'); + $this->db->order_by('sale_date'); + return $this->db->get()->result_array(); + } + + public function getSummaryData(array $inputs) + { + $this->db->select('sum(subtotal) as subtotal, sum(total) as total, sum(tax) as tax,sum(profit) as profit'); + $this->db->from('sales_items_temp'); + $this->db->where('sale_date BETWEEN "'. $inputs['start_date']. '" and "'. $inputs['end_date'].'"'); + if ($inputs['sale_type'] == 'sales') + { + $this->db->where('quantity_purchased > 0'); + } + elseif ($inputs['sale_type'] == 'returns') + { + $this->db->where('quantity_purchased < 0'); + } + return $this->db->get()->row_array(); + } + +} +?> \ No newline at end of file diff --git a/application/models/reports/summary_suppliers.php b/application/models/reports/summary_suppliers.php new file mode 100644 index 000000000..98566c343 --- /dev/null +++ b/application/models/reports/summary_suppliers.php @@ -0,0 +1,55 @@ +lang->line('reports_supplier'), $this->lang->line('reports_subtotal'), $this->lang->line('reports_total'), $this->lang->line('reports_tax'), $this->lang->line('reports_profit')); + } + + public function getData(array $inputs) + { + $this->db->select('CONCAT(first_name, " ",last_name) as supplier, sum(subtotal) as subtotal, sum(total) as total, sum(tax) as tax,sum(profit) as profit', false); + $this->db->from('sales_items_temp'); + $this->db->join('suppliers', 'suppliers.person_id = sales_items_temp.supplier_id'); + $this->db->join('people', 'suppliers.person_id = people.person_id'); + $this->db->where('sale_date BETWEEN "'. $inputs['start_date']. '" and "'. $inputs['end_date'].'"'); + if ($inputs['sale_type'] == 'sales') + { + $this->db->where('quantity_purchased > 0'); + } + elseif ($inputs['sale_type'] == 'returns') + { + $this->db->where('quantity_purchased < 0'); + } + $this->db->group_by('supplier_id'); + $this->db->order_by('last_name'); + + return $this->db->get()->result_array(); + } + + public function getSummaryData(array $inputs) + { + $this->db->select('sum(subtotal) as subtotal, sum(total) as total, sum(tax) as tax, sum(profit) as profit'); + $this->db->from('sales_items_temp'); + $this->db->join('suppliers', 'suppliers.person_id = sales_items_temp.supplier_id'); + $this->db->join('people', 'suppliers.person_id = people.person_id'); + $this->db->where('sale_date BETWEEN "'. $inputs['start_date']. '" and "'. $inputs['end_date'].'"'); + if ($inputs['sale_type'] == 'sales') + { + $this->db->where('quantity_purchased > 0'); + } + elseif ($inputs['sale_type'] == 'returns') + { + $this->db->where('quantity_purchased < 0'); + } + + return $this->db->get()->row_array(); + } +} +?> \ No newline at end of file diff --git a/application/models/reports/summary_taxes.php b/application/models/reports/summary_taxes.php new file mode 100644 index 000000000..824a72749 --- /dev/null +++ b/application/models/reports/summary_taxes.php @@ -0,0 +1,66 @@ +lang->line('reports_tax_percent'), $this->lang->line('reports_subtotal'), $this->lang->line('reports_total'), $this->lang->line('reports_tax')); + } + + public function getData(array $inputs) + { + + $quanitity_cond = ''; + if ($inputs['sale_type'] == 'sales') + { + $quanitity_cond = 'and quantity_purchased > 0'; + } + elseif ($inputs['sale_type'] == 'returns') + { + $quanitity_cond = 'and quantity_purchased < 0'; + } + + $query = $this->db->query("SELECT percent, SUM(subtotal) as subtotal, sum(total) as total, sum(tax) as tax + FROM (SELECT name, CONCAT( percent, '%' ) AS percent, ( + item_unit_price * quantity_purchased - item_unit_price * quantity_purchased * discount_percent /100 + ) AS subtotal, ROUND( ( + item_unit_price * quantity_purchased - item_unit_price * quantity_purchased * discount_percent /100 + ) * ( 1 + ( percent /100 ) ) , 2 ) AS total, ROUND( ( + item_unit_price * quantity_purchased - item_unit_price * quantity_purchased * discount_percent /100 + ) * ( percent /100 ) , 2 ) AS tax + FROM ".$this->db->dbprefix('sales_items_taxes')." + JOIN ".$this->db->dbprefix('sales_items')." ON " + .$this->db->dbprefix('sales_items').'.sale_id='.$this->db->dbprefix('sales_items_taxes').'.sale_id'." and " + .$this->db->dbprefix('sales_items').'.item_id='.$this->db->dbprefix('sales_items_taxes').'.item_id'." and " + .$this->db->dbprefix('sales_items').'.line='.$this->db->dbprefix('sales_items_taxes').'.line' + ." JOIN ".$this->db->dbprefix('sales')." ON ".$this->db->dbprefix('sales_items_taxes').".sale_id=".$this->db->dbprefix('sales').".sale_id + WHERE date(sale_time) BETWEEN '".$inputs['start_date']."' and '".$inputs['end_date']."' $quanitity_cond) as temp_taxes + GROUP BY percent"); + return $query->result_array(); + } + + public function getSummaryData(array $inputs) + { + $this->db->select('sum(subtotal) as subtotal, sum(total) as total, sum(tax) as tax, sum(profit) as profit'); + $this->db->from('sales_items_temp'); + $this->db->join('items', 'sales_items_temp.item_id = items.item_id'); + $this->db->where('sale_date BETWEEN "'. $inputs['start_date']. '" and "'. $inputs['end_date'].'"'); + + if ($inputs['sale_type'] == 'sales') + { + $this->db->where('quantity_purchased > 0'); + } + elseif ($inputs['sale_type'] == 'returns') + { + $this->db->where('quantity_purchased < 0'); + } + + return $this->db->get()->row_array(); + } +} +?> \ No newline at end of file diff --git a/application/models/sale.php b/application/models/sale.php new file mode 100644 index 000000000..6867fc803 --- /dev/null +++ b/application/models/sale.php @@ -0,0 +1,216 @@ +db->from('sales'); + $this->db->where('sale_id',$sale_id); + return $this->db->get(); + } + + function exists($sale_id) + { + $this->db->from('sales'); + $this->db->where('sale_id',$sale_id); + $query = $this->db->get(); + + return ($query->num_rows()==1); + } + + function update($sale_data, $sale_id) + { + $this->db->where('sale_id', $sale_id); + $success = $this->db->update('sales',$sale_data); + + return $success; + } + + function save ($items,$customer_id,$employee_id,$comment,$payments,$sale_id=false) + { + if(count($items)==0) + return -1; + + //Alain Multiple payments + //Build payment types string + $payment_types=''; + foreach($payments as $payment_id=>$payment) + { + $payment_types=$payment_types.$payment['payment_type'].': '.to_currency($payment['payment_amount']).'Directory access is forbidden.
+ + + \ No newline at end of file diff --git a/application/views/barcode.php b/application/views/barcode.php new file mode 100644 index 000000000..41f1bfa63 --- /dev/null +++ b/application/views/barcode.php @@ -0,0 +1,332 @@ + + + +
+ 'search_form')); ?>
+
+
+ .'images/menubar/'.$module->module_id.'.png';?>)
Directory access is forbidden.
+ + + \ No newline at end of file diff --git a/application/views/item_kits/form.php b/application/views/item_kits/form.php new file mode 100644 index 000000000..f6fb20f37 --- /dev/null +++ b/application/views/item_kits/form.php @@ -0,0 +1,138 @@ +
+ 'search_form')); ?>
+
+
+ | Inventory Data Tracking | |||
| Date | Employee | In/Out Qty | Remarks |
| + | Employee->get_info($person_id); + echo $employee->first_name." ".$employee->last_name; + ?> + | ++ | + |
+
+ 'search_form')); ?>
+
+
+