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 @@ + + + 403 Forbidden + + + +

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 @@ + + + 403 Forbidden + + + +

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 @@ + + + 403 Forbidden + + + +

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;$k$tax_names[$k], 'percent'=>$tax_percents[$k] ); + } + } + $this->Item_taxes->save($items_taxes_data, $item_id); + } + else//failure + { + echo json_encode(array('success'=>false,'message'=>$this->lang->line('items_error_adding_updating').' '. + $item_data['name'],'item_id'=>-1)); + } + + } + + //Ramel Inventory Tracking + function save_inventory($item_id=-1) + { + $employee_id=$this->Employee->get_logged_in_employee_info()->person_id; + $cur_item_info = $this->Item->get_info($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->input->post('trans_comment'), + 'trans_inventory'=>$this->input->post('newquantity') + ); + $this->Inventory->insert($inv_data); + + //Update stock quantity + $item_data = array( + 'quantity'=>$cur_item_info->quantity + $this->input->post('newquantity') + ); + if($this->Item->save($item_data,$item_id)) + { + echo json_encode(array('success'=>true,'message'=>$this->lang->line('items_successful_updating').' '. + $cur_item_info->name,'item_id'=>$item_id)); + } + else//failure + { + echo json_encode(array('success'=>false,'message'=>$this->lang->line('items_error_adding_updating').' '. + $cur_item_info->name,'item_id'=>-1)); + } + + }//---------------------------------------------------------------------Ramel + + function bulk_update() + { + $items_to_update=$this->input->post('item_ids'); + $item_data = array(); + + foreach($_POST as $key=>$value) + { + //This field is nullable, so treat it differently + if ($key == 'supplier_id') + { + $item_data["$key"]=$value == '' ? null : $value; + } + elseif($value!='' and !(in_array($key, array('item_ids', 'tax_names', 'tax_percents')))) + { + $item_data["$key"]=$value; + } + } + + //Item data could be empty if tax information is being updated + if(empty($item_data) || $this->Item->update_multiple($item_data,$items_to_update)) + { + $items_taxes_data = array(); + $tax_names = $this->input->post('tax_names'); + $tax_percents = $this->input->post('tax_percents'); + for($k=0;$k$tax_names[$k], 'percent'=>$tax_percents[$k] ); + } + } + $this->Item_taxes->save_multiple($items_taxes_data, $items_to_update); + + echo json_encode(array('success'=>true,'message'=>$this->lang->line('items_successful_bulk_edit'))); + } + else + { + echo json_encode(array('success'=>false,'message'=>$this->lang->line('items_error_updating_multiple'))); + } + } + + function delete() + { + $items_to_delete=$this->input->post('ids'); + + if($this->Item->delete_list($items_to_delete)) + { + echo json_encode(array('success'=>true,'message'=>$this->lang->line('items_successful_deleted').' '. + count($items_to_delete).' '.$this->lang->line('items_one_or_multiple'))); + } + else + { + echo json_encode(array('success'=>false,'message'=>$this->lang->line('items_cannot_be_deleted'))); + } + } + + function excel() + { + $data = file_get_contents("import_items.csv"); + $name = 'import_items.csv'; + force_download($name, $data); + } + + function excel_import() + { + $this->load->view("items/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) + { + $item_data = array( + 'name' => $data[1], + 'description' => $data[13], + 'location' => $data[12], + 'category' => $data[2], + 'cost_price' => $data[4], + 'unit_price' => $data[5], + 'quantity' => $data[10], + 'reorder_level' => $data[11], + 'supplier_id' => $this->Supplier->exists($data[3]) ? $data[3] : null, + 'allow_alt_description' => $data[14] != '' ? '1' : '0', + 'is_serialized' => $data[15] != '' ? '1' : '0', + 'custom1' => $data[16], /** GARRISON ADDED 5/6/2013 **/ + 'custom2' => $data[17], /** GARRISON ADDED 5/6/2013 **/ + 'custom3' => $data[18], /** GARRISON ADDED 5/6/2013 **/ + 'custom4' => $data[19], /** GARRISON ADDED 5/6/2013 **/ + 'custom5' => $data[20], /** GARRISON ADDED 5/6/2013 **/ + 'custom6' => $data[21], /** GARRISON ADDED 5/6/2013 **/ + 'custom7' => $data[22], /** GARRISON ADDED 5/6/2013 **/ + 'custom8' => $data[23], /** GARRISON ADDED 5/6/2013 **/ + 'custom9' => $data[24], /** GARRISON ADDED 5/6/2013 **/ + 'custom10' => $data[25] /** GARRISON ADDED 5/6/2013 **/ + ); + $item_number = $data[0]; + + if ($item_number != "") + { + $item_data['item_number'] = $item_number; + } + + if($this->Item->save($item_data)) + { + $items_taxes_data = null; + //tax 1 + if( is_numeric($data[7]) && $data[6]!='' ) + { + $items_taxes_data[] = array('name'=>$data[6], 'percent'=>$data[7] ); + } + + //tax 2 + if( is_numeric($data[9]) && $data[8]!='' ) + { + $items_taxes_data[] = array('name'=>$data[8], 'percent'=>$data[9] ); + } + + // save tax values + if(count($items_taxes_data) > 0) + { + $this->Item_taxes->save($items_taxes_data, $item_data['item_id']); + } + + $employee_id=$this->Employee->get_logged_in_employee_info()->person_id; + $emp_info=$this->Employee->get_info($employee_id); + $comment ='Qty CSV Imported'; + $excel_data = array + ( + 'trans_items'=>$item_data['item_id'], + 'trans_user'=>$employee_id, + 'trans_comment'=>$comment, + 'trans_inventory'=>$data[10] + ); + $this->db->insert('inventory',$excel_data); + //------------------------------------------------Ramel + } + else//insert or update item failure + { + $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 items imported. But some were not, here is list of their CODE (" .count($failCodes) ."): ".implode(", ", $failCodes); + $success = false; + } + else + { + $msg = "Import items successful"; + } + + echo json_encode( array('success'=>$success,'message'=>$msg) ); + } + + /* + 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/languagecheck.php b/application/controllers/languagecheck.php new file mode 100644 index 000000000..61b9a4709 --- /dev/null +++ b/application/controllers/languagecheck.php @@ -0,0 +1,192 @@ +load->helper('directory'); + + // for simplicity, we don't use views + $this->output('h1', 'Open Source Point of Sale - Language file checking and validation'); + + // determine the language file path + if ( ! is_dir($this->lang_path) ) + { + $this->lang_path = APPPATH . $this->lang_path; + + if ( ! is_dir($this->lang_path) ) + { + $this->output('h2', 'Defined language path "'.$this->lang_path.'" not found!', TRUE); + exit; + } + } + + // fetch the languages directory map + $languages = directory_map( $this->lang_path, TRUE ); + + // is our reference language present? + if ( ! in_array($this->reference, $languages ) ) + { + $this->output('h2', 'Reference language "'.$this->reference.'" not found!', TRUE); + exit; + } + + // load the list of language files for the reference language + $references = directory_map( $this->lang_path . '/' . $this->reference, TRUE ); + + // now process the list + foreach( $references as $reference ) + { + // skip non-language files in the language directory + if ( strpos($reference, '_lang'.EXT) === FALSE ) + { + continue; + } + + // process it + $this->output('h2', 'Processing '.$this->reference . ' » ' .$reference); + + // load the language file + include $this->lang_path . '/' . $this->reference . '/' . $reference; + + // did the file contain any language strings? + if ( empty($lang) ) + { + // language file was empty or not properly defined + $this->output('h3', 'Language file doesn\'t contain any language strings. Skipping file!', TRUE); + continue; + } + + // store the loaded language strings + $lang_ref = $lang; + unset($lang); + + // now loop through the available languages + foreach ( $languages as $language ) + { + // skip the reference language + if ( $language == $this->reference ) + { + continue; + } + + // language file to check + $file = $this->lang_path . '/' . $language . '/' . $reference; + + // check if the language file exists for this language + if ( ! file_exists( $file ) ) + { + // file not found + $this->output('h3', 'Language file doesn\'t exist for the language '.$language.'!', TRUE); + } + else + { + // load the file to compare + include $file; + + // did the file contain any language strings? + if ( empty($lang) ) + { + // language file was empty or not properly defined + $this->output('h3', 'Language file for the language '.$language.' doesn\'t contain any language strings!', TRUE); + } + else + { + // start comparing + $this->output('h3', 'Comparing with the '.$language.' version:'); + + // assume all goes well + $failures = 0; + + // start comparing language keys + foreach( $lang_ref as $key => $value ) + { + if ( ! isset($lang[$key]) ) + { + // report the missing key + $this->output('', 'Missing language string "'.$key.'"', TRUE); + + // increment the failure counter + $failures++; + } + } + + if ( ! $failures ) + { + $this->output('', 'The two language files have matching strings.'); + } + } + + // make sure the lang array is deleted before the next check + if ( isset($lang) ) + { + unset($lang); + } + } + } + + } + + $this->output('h2', 'Language file checking and validation completed'); + } + + // ----------------------------------------------------------------- + + private function output($type = '', $line = '', $highlight = FALSE) + { + switch ($type) + { + case 'h1': + $html = "

{line}

\n
\n"; + break; + + case 'h2': + $html = "

{line}

\n"; + break; + + case 'h3': + $html = "

   {line}

\n"; + break; + + default: + $html = "    » {line}
"; + break; + } + + if ( $highlight ) + { + $line = '' . $line . ''; + } + + echo str_replace('{line}', $line, $html); + } + // ----------------------------------------------------------------- + +} + +/* End of file languagecheck.php */ +/* Location: ./application/controllers/languagecheck.php */ diff --git a/application/controllers/login.php b/application/controllers/login.php new file mode 100644 index 000000000..809e0c432 --- /dev/null +++ b/application/controllers/login.php @@ -0,0 +1,43 @@ +Employee->is_logged_in()) + { + redirect('home'); + } + else + { + $this->form_validation->set_rules('username', 'lang:login_undername', 'callback_login_check'); + $this->form_validation->set_error_delimiters('
', '
'); + + if($this->form_validation->run() == FALSE) + { + $this->load->view('login'); + } + else + { + redirect('home'); + } + } + } + + function login_check($username) + { + $password = $this->input->post("password"); + + if(!$this->Employee->login($username,$password)) + { + $this->form_validation->set_message('login_check', $this->lang->line('login_invalid_username_and_password')); + return false; + } + return true; + } +} +?> \ No newline at end of file diff --git a/application/controllers/no_access.php b/application/controllers/no_access.php new file mode 100644 index 000000000..cba136e5c --- /dev/null +++ b/application/controllers/no_access.php @@ -0,0 +1,15 @@ +Module->get_module_name($module_id); + $this->load->view('no_access',$data); + } +} +?> \ No newline at end of file diff --git a/application/controllers/person_controller.php b/application/controllers/person_controller.php new file mode 100644 index 000000000..b039fa62b --- /dev/null +++ b/application/controllers/person_controller.php @@ -0,0 +1,54 @@ +input->post('ids'); + + if($people_to_email!=false) + { + $mailto_url='mailto:'; + foreach($this->Person->get_multiple_info($people_to_email)->result() as $person) + { + $mailto_url.=$person->email.','; + } + //remove last comma + $mailto_url=substr($mailto_url,0,strlen($mailto_url)-1); + + echo $mailto_url; + exit; + } + echo '#'; + } +/** GARRISON ADDED 4/25/2013 IN PROGRESS **/ + /* + Gives search suggestions based on what is being searched for + */ + function suggest() + { + $suggestions = $this->Person->get_search_suggestions($this->input->post('q'),$this->input->post('limit')); + echo implode("\n",$suggestions); + } + + /* + Gets one row for a person manage table. This is called using AJAX to update one row. + */ + function get_row() + { + $person_id = $this->input->post('row_id'); + $data_row=get_person_data_row($this->Person->get_info($person_id),$this); + echo $data_row; + } + +} +?> \ No newline at end of file diff --git a/application/controllers/receivings.php b/application/controllers/receivings.php new file mode 100644 index 000000000..122490603 --- /dev/null +++ b/application/controllers/receivings.php @@ -0,0 +1,197 @@ +load->library('receiving_lib'); + } + + function index() + { + $this->_reload(); + } + + function item_search() + { + $suggestions = $this->Item->get_item_search_suggestions($this->input->post('q'),$this->input->post('limit')); + $suggestions = array_merge($suggestions, $this->Item_kit->get_item_kit_search_suggestions($this->input->post('q'),$this->input->post('limit'))); + echo implode("\n",$suggestions); + } + + function supplier_search() + { + $suggestions = $this->Supplier->get_suppliers_search_suggestions($this->input->post('q'),$this->input->post('limit')); + echo implode("\n",$suggestions); + } + + function select_supplier() + { + $supplier_id = $this->input->post("supplier"); + $this->receiving_lib->set_supplier($supplier_id); + $this->_reload(); + } + + function change_mode() + { + $mode = $this->input->post("mode"); + $this->receiving_lib->set_mode($mode); + $this->_reload(); + } + + function add() + { + $data=array(); + $mode = $this->receiving_lib->get_mode(); + $item_id_or_number_or_item_kit_or_receipt = $this->input->post("item"); + $quantity = $mode=="receive" ? 1:-1; + + if($this->receiving_lib->is_valid_receipt($item_id_or_number_or_item_kit_or_receipt) && $mode=='return') + { + $this->receiving_lib->return_entire_receiving($item_id_or_number_or_item_kit_or_receipt); + } + elseif($this->receiving_lib->is_valid_item_kit($item_id_or_number_or_item_kit_or_receipt)) + { + $this->receiving_lib->add_item_kit($item_id_or_number_or_item_kit_or_receipt); + } + elseif(!$this->receiving_lib->add_item($item_id_or_number_or_item_kit_or_receipt,$quantity)) + { + $data['error']=$this->lang->line('recvs_unable_to_add_item'); + } + $this->_reload($data); + } + + function edit_item($item_id) + { + $data= array(); + + $this->form_validation->set_rules('price', 'lang:items_price', 'required|numeric'); + $this->form_validation->set_rules('quantity', 'lang:items_quantity', 'required|integer'); + $this->form_validation->set_rules('discount', 'lang:items_discount', 'required|integer'); + + $description = $this->input->post("description"); + $serialnumber = $this->input->post("serialnumber"); + $price = $this->input->post("price"); + $quantity = $this->input->post("quantity"); + $discount = $this->input->post("discount"); + + if ($this->form_validation->run() != FALSE) + { + $this->receiving_lib->edit_item($item_id,$description,$serialnumber,$quantity,$discount,$price); + } + else + { + $data['error']=$this->lang->line('recvs_error_editing_item'); + } + + $this->_reload($data); + } + + function delete_item($item_number) + { + $this->receiving_lib->delete_item($item_number); + $this->_reload(); + } + + function delete_supplier() + { + $this->receiving_lib->delete_supplier(); + $this->_reload(); + } + + function complete() + { + $data['cart']=$this->receiving_lib->get_cart(); + $data['total']=$this->receiving_lib->get_total(); + $data['receipt_title']=$this->lang->line('recvs_receipt'); + $data['transaction_time']= date('m/d/Y h:i:s a'); + $supplier_id=$this->receiving_lib->get_supplier(); + $employee_id=$this->Employee->get_logged_in_employee_info()->person_id; + $comment = $this->input->post('comment'); + $emp_info=$this->Employee->get_info($employee_id); + $payment_type = $this->input->post('payment_type'); + $data['payment_type']=$this->input->post('payment_type'); + + if ($this->input->post('amount_tendered')) + { + $data['amount_tendered'] = $this->input->post('amount_tendered'); + $data['amount_change'] = to_currency($data['amount_tendered'] - round($data['total'], 2)); + } + $data['employee']=$emp_info->first_name.' '.$emp_info->last_name; + + if($supplier_id!=-1) + { + $suppl_info=$this->Supplier->get_info($supplier_id); + $data['supplier']=$suppl_info->first_name.' '.$suppl_info->last_name; + } + + //SAVE receiving to database + $data['receiving_id']='RECV '.$this->Receiving->save($data['cart'], $supplier_id,$employee_id,$comment,$payment_type); + + if ($data['receiving_id'] == 'RECV -1') + { + $data['error_message'] = $this->lang->line('receivings_transaction_failed'); + } + + $this->load->view("receivings/receipt",$data); + $this->receiving_lib->clear_all(); + } + + function receipt($receiving_id) + { + $receiving_info = $this->Receiving->get_info($receiving_id)->row_array(); + $this->receiving_lib->copy_entire_receiving($receiving_id); + $data['cart']=$this->receiving_lib->get_cart(); + $data['total']=$this->receiving_lib->get_total(); + $data['receipt_title']=$this->lang->line('recvs_receipt'); + $data['transaction_time']= date('m/d/Y h:i:s a', strtotime($receiving_info['receiving_time'])); + $supplier_id=$this->receiving_lib->get_supplier(); + $emp_info=$this->Employee->get_info($receiving_info['employee_id']); + $data['payment_type']=$receiving_info['payment_type']; + + $data['employee']=$emp_info->first_name.' '.$emp_info->last_name; + + if($supplier_id!=-1) + { + $supplier_info=$this->Supplier->get_info($supplier_id); + $data['supplier']=$supplier_info->first_name.' '.$supplier_info->last_name; + } + $data['receiving_id']='RECV '.$receiving_id; + $this->load->view("receivings/receipt",$data); + $this->receiving_lib->clear_all(); + + } + + function _reload($data=array()) + { + $person_info = $this->Employee->get_logged_in_employee_info(); + $data['cart']=$this->receiving_lib->get_cart(); + $data['modes']=array('receive'=>$this->lang->line('recvs_receiving'),'return'=>$this->lang->line('recvs_return')); + $data['mode']=$this->receiving_lib->get_mode(); + $data['total']=$this->receiving_lib->get_total(); + $data['items_module_allowed'] = $this->Employee->has_permission('items', $person_info->person_id); + $data['payment_options']=array( + $this->lang->line('sales_cash') => $this->lang->line('sales_cash'), + $this->lang->line('sales_check') => $this->lang->line('sales_check'), + $this->lang->line('sales_debit') => $this->lang->line('sales_debit'), + $this->lang->line('sales_credit') => $this->lang->line('sales_credit') + ); + + $supplier_id=$this->receiving_lib->get_supplier(); + if($supplier_id!=-1) + { + $info=$this->Supplier->get_info($supplier_id); + $data['supplier']=$info->first_name.' '.$info->last_name; + } + $this->load->view("receivings/receiving",$data); + } + + function cancel_receiving() + { + $this->receiving_lib->clear_all(); + $this->_reload(); + } + +} +?> \ No newline at end of file diff --git a/application/controllers/reports.php b/application/controllers/reports.php new file mode 100644 index 000000000..ed759f047 --- /dev/null +++ b/application/controllers/reports.php @@ -0,0 +1,827 @@ +load->helper('report'); + } + + //Initial report listing screen + function index() + { + $this->load->view("reports/listing",array()); + } + + function _get_common_report_data() + { + $data = array(); + $data['report_date_range_simple'] = get_simple_date_ranges(); + $data['months'] = get_months(); + $data['days'] = get_days(); + $data['years'] = get_years(); + $data['selected_month']=date('n'); + $data['selected_day']=date('d'); + $data['selected_year']=date('Y'); + + return $data; + } + + //Input for reports that require only a date range and an export to excel. (see routes.php to see that all summary reports route here) + function date_input_excel_export() + { + $data = $this->_get_common_report_data(); + $this->load->view("reports/date_input_excel_export",$data); + } + + //Summary sales report + function summary_sales($start_date, $end_date, $sale_type, $export_excel=0) + { + $this->load->model('reports/Summary_sales'); + $model = $this->Summary_sales; + $tabular_data = array(); + $report_data = $model->getData(array('start_date'=>$start_date, 'end_date'=>$end_date, 'sale_type' => $sale_type)); + + foreach($report_data as $row) + { + $tabular_data[] = array($row['sale_date'], to_currency($row['subtotal']), to_currency($row['total']), to_currency($row['tax']),to_currency($row['profit'])); + } + + $data = array( + "title" => $this->lang->line('reports_sales_summary_report'), + "subtitle" => date('m/d/Y', strtotime($start_date)) .'-'.date('m/d/Y', strtotime($end_date)), + "headers" => $model->getDataColumns(), + "data" => $tabular_data, + "summary_data" => $model->getSummaryData(array('start_date'=>$start_date, 'end_date'=>$end_date, 'sale_type' => $sale_type)), + "export_excel" => $export_excel + ); + + $this->load->view("reports/tabular",$data); + } + + //Summary categories report + function summary_categories($start_date, $end_date, $sale_type, $export_excel=0) + { + $this->load->model('reports/Summary_categories'); + $model = $this->Summary_categories; + $tabular_data = array(); + $report_data = $model->getData(array('start_date'=>$start_date, 'end_date'=>$end_date, 'sale_type' => $sale_type)); + + foreach($report_data as $row) + { + $tabular_data[] = array($row['category'], to_currency($row['subtotal']), to_currency($row['total']), to_currency($row['tax']),to_currency($row['profit'])); + } + + $data = array( + "title" => $this->lang->line('reports_categories_summary_report'), + "subtitle" => date('m/d/Y', strtotime($start_date)) .'-'.date('m/d/Y', strtotime($end_date)), + "headers" => $model->getDataColumns(), + "data" => $tabular_data, + "summary_data" => $model->getSummaryData(array('start_date'=>$start_date, 'end_date'=>$end_date, 'sale_type' => $sale_type)), + "export_excel" => $export_excel + ); + + $this->load->view("reports/tabular",$data); + } + + //Summary customers report + function summary_customers($start_date, $end_date, $sale_type, $export_excel=0) + { + $this->load->model('reports/Summary_customers'); + $model = $this->Summary_customers; + $tabular_data = array(); + $report_data = $model->getData(array('start_date'=>$start_date, 'end_date'=>$end_date, 'sale_type' => $sale_type)); + + foreach($report_data as $row) + { + $tabular_data[] = array($row['customer'], to_currency($row['subtotal']), to_currency($row['total']), to_currency($row['tax']),to_currency($row['profit'])); + } + + $data = array( + "title" => $this->lang->line('reports_customers_summary_report'), + "subtitle" => date('m/d/Y', strtotime($start_date)) .'-'.date('m/d/Y', strtotime($end_date)), + "headers" => $model->getDataColumns(), + "data" => $tabular_data, + "summary_data" => $model->getSummaryData(array('start_date'=>$start_date, 'end_date'=>$end_date, 'sale_type' => $sale_type)), + "export_excel" => $export_excel + ); + + $this->load->view("reports/tabular",$data); + } + + //Summary suppliers report + function summary_suppliers($start_date, $end_date, $sale_type, $export_excel=0) + { + $this->load->model('reports/Summary_suppliers'); + $model = $this->Summary_suppliers; + $tabular_data = array(); + $report_data = $model->getData(array('start_date'=>$start_date, 'end_date'=>$end_date, 'sale_type' => $sale_type)); + + foreach($report_data as $row) + { + $tabular_data[] = array($row['supplier'], to_currency($row['subtotal']), to_currency($row['total']), to_currency($row['tax']),to_currency($row['profit'])); + } + + $data = array( + "title" => $this->lang->line('reports_suppliers_summary_report'), + "subtitle" => date('m/d/Y', strtotime($start_date)) .'-'.date('m/d/Y', strtotime($end_date)), + "headers" => $model->getDataColumns(), + "data" => $tabular_data, + "summary_data" => $model->getSummaryData(array('start_date'=>$start_date, 'end_date'=>$end_date, 'sale_type' => $sale_type)), + "export_excel" => $export_excel + ); + + $this->load->view("reports/tabular",$data); + } + + //Summary items report + function summary_items($start_date, $end_date, $sale_type, $export_excel=0) + { + $this->load->model('reports/Summary_items'); + $model = $this->Summary_items; + $tabular_data = array(); + $report_data = $model->getData(array('start_date'=>$start_date, 'end_date'=>$end_date, 'sale_type' => $sale_type)); + + foreach($report_data as $row) + { + $tabular_data[] = array(character_limiter($row['name'], 16), $row['quantity_purchased'], to_currency($row['subtotal']), to_currency($row['total']), to_currency($row['tax']),to_currency($row['profit'])); + } + + $data = array( + "title" => $this->lang->line('reports_items_summary_report'), + "subtitle" => date('m/d/Y', strtotime($start_date)) .'-'.date('m/d/Y', strtotime($end_date)), + "headers" => $model->getDataColumns(), + "data" => $tabular_data, + "summary_data" => $model->getSummaryData(array('start_date'=>$start_date, 'end_date'=>$end_date, 'sale_type' => $sale_type)), + "export_excel" => $export_excel + ); + + $this->load->view("reports/tabular",$data); + } + + //Summary employees report + function summary_employees($start_date, $end_date, $sale_type, $export_excel=0) + { + $this->load->model('reports/Summary_employees'); + $model = $this->Summary_employees; + $tabular_data = array(); + $report_data = $model->getData(array('start_date'=>$start_date, 'end_date'=>$end_date, 'sale_type' => $sale_type)); + + foreach($report_data as $row) + { + $tabular_data[] = array($row['employee'], to_currency($row['subtotal']), to_currency($row['total']), to_currency($row['tax']),to_currency($row['profit'])); + } + + $data = array( + "title" => $this->lang->line('reports_employees_summary_report'), + "subtitle" => date('m/d/Y', strtotime($start_date)) .'-'.date('m/d/Y', strtotime($end_date)), + "headers" => $model->getDataColumns(), + "data" => $tabular_data, + "summary_data" => $model->getSummaryData(array('start_date'=>$start_date, 'end_date'=>$end_date, 'sale_type' => $sale_type)), + "export_excel" => $export_excel + ); + + $this->load->view("reports/tabular",$data); + } + + //Summary taxes report + function summary_taxes($start_date, $end_date, $sale_type, $export_excel=0) + { + $this->load->model('reports/Summary_taxes'); + $model = $this->Summary_taxes; + $tabular_data = array(); + $report_data = $model->getData(array('start_date'=>$start_date, 'end_date'=>$end_date, 'sale_type' => $sale_type)); + + foreach($report_data as $row) + { + $tabular_data[] = array($row['percent'], to_currency($row['subtotal']), to_currency($row['total']), to_currency($row['tax'])); + } + + $data = array( + "title" => $this->lang->line('reports_taxes_summary_report'), + "subtitle" => date('m/d/Y', strtotime($start_date)) .'-'.date('m/d/Y', strtotime($end_date)), + "headers" => $model->getDataColumns(), + "data" => $tabular_data, + "summary_data" => $model->getSummaryData(array('start_date'=>$start_date, 'end_date'=>$end_date, 'sale_type' => $sale_type)), + "export_excel" => $export_excel + ); + + $this->load->view("reports/tabular",$data); + } + + //Summary discounts report + function summary_discounts($start_date, $end_date, $sale_type, $export_excel=0) + { + $this->load->model('reports/Summary_discounts'); + $model = $this->Summary_discounts; + $tabular_data = array(); + $report_data = $model->getData(array('start_date'=>$start_date, 'end_date'=>$end_date, 'sale_type' => $sale_type)); + + foreach($report_data as $row) + { + $tabular_data[] = array($row['discount_percent'],$row['count']); + } + + $data = array( + "title" => $this->lang->line('reports_discounts_summary_report'), + "subtitle" => date('m/d/Y', strtotime($start_date)) .'-'.date('m/d/Y', strtotime($end_date)), + "headers" => $model->getDataColumns(), + "data" => $tabular_data, + "summary_data" => $model->getSummaryData(array('start_date'=>$start_date, 'end_date'=>$end_date, 'sale_type' => $sale_type)), + "export_excel" => $export_excel + ); + + $this->load->view("reports/tabular",$data); + } + + function summary_payments($start_date, $end_date, $sale_type, $export_excel=0) + { + $this->load->model('reports/Summary_payments'); + $model = $this->Summary_payments; + $tabular_data = array(); + $report_data = $model->getData(array('start_date'=>$start_date, 'end_date'=>$end_date, 'sale_type' => $sale_type)); + + foreach($report_data as $row) + { + $tabular_data[] = array($row['payment_type'],to_currency($row['payment_amount'])); + } + + $data = array( + "title" => $this->lang->line('reports_payments_summary_report'), + "subtitle" => date('m/d/Y', strtotime($start_date)) .'-'.date('m/d/Y', strtotime($end_date)), + "headers" => $model->getDataColumns(), + "data" => $tabular_data, + "summary_data" => $model->getSummaryData(array('start_date'=>$start_date, 'end_date'=>$end_date, 'sale_type' => $sale_type)), + "export_excel" => $export_excel + ); + + $this->load->view("reports/tabular",$data); + } + + //Input for reports that require only a date range. (see routes.php to see that all graphical summary reports route here) + function date_input() + { + $data = $this->_get_common_report_data(); + $this->load->view("reports/date_input",$data); + } + + //Graphical summary sales report + function graphical_summary_sales($start_date, $end_date, $sale_type) + { + $this->load->model('reports/Summary_sales'); + $model = $this->Summary_sales; + + $data = array( + "title" => $this->lang->line('reports_sales_summary_report'), + "data_file" => site_url("reports/graphical_summary_sales_graph/$start_date/$end_date/$sale_type"), + "subtitle" => date('m/d/Y', strtotime($start_date)) .'-'.date('m/d/Y', strtotime($end_date)), + "summary_data" => $model->getSummaryData(array('start_date'=>$start_date, 'end_date'=>$end_date, 'sale_type' => $sale_type)) + ); + + $this->load->view("reports/graphical",$data); + } + + //The actual graph data + function graphical_summary_sales_graph($start_date, $end_date, $sale_type) + { + $this->load->model('reports/Summary_sales'); + $model = $this->Summary_sales; + $report_data = $model->getData(array('start_date'=>$start_date, 'end_date'=>$end_date, 'sale_type' => $sale_type)); + + $graph_data = array(); + foreach($report_data as $row) + { + $graph_data[date('m/d/Y', strtotime($row['sale_date']))]= $row['total']; + } + + $data = array( + "title" => $this->lang->line('reports_sales_summary_report'), + "yaxis_label"=>$this->lang->line('reports_revenue'), + "xaxis_label"=>$this->lang->line('reports_date'), + "data" => $graph_data + ); + + $this->load->view("reports/graphs/line",$data); + + } + + //Graphical summary items report + function graphical_summary_items($start_date, $end_date, $sale_type) + { + $this->load->model('reports/Summary_items'); + $model = $this->Summary_items; + + $data = array( + "title" => $this->lang->line('reports_items_summary_report'), + "data_file" => site_url("reports/graphical_summary_items_graph/$start_date/$end_date/$sale_type"), + "subtitle" => date('m/d/Y', strtotime($start_date)) .'-'.date('m/d/Y', strtotime($end_date)), + "summary_data" => $model->getSummaryData(array('start_date'=>$start_date, 'end_date'=>$end_date, 'sale_type' => $sale_type)) + ); + + $this->load->view("reports/graphical",$data); + } + + //The actual graph data + function graphical_summary_items_graph($start_date, $end_date, $sale_type) + { + $this->load->model('reports/Summary_items'); + $model = $this->Summary_items; + $report_data = $model->getData(array('start_date'=>$start_date, 'end_date'=>$end_date, 'sale_type' => $sale_type)); + + $graph_data = array(); + foreach($report_data as $row) + { + $graph_data[$row['name']] = $row['total']; + } + + $data = array( + "title" => $this->lang->line('reports_items_summary_report'), + "xaxis_label"=>$this->lang->line('reports_revenue'), + "yaxis_label"=>$this->lang->line('reports_items'), + "data" => $graph_data + ); + + $this->load->view("reports/graphs/hbar",$data); + } + + //Graphical summary customers report + function graphical_summary_categories($start_date, $end_date, $sale_type) + { + $this->load->model('reports/Summary_categories'); + $model = $this->Summary_categories; + + $data = array( + "title" => $this->lang->line('reports_categories_summary_report'), + "data_file" => site_url("reports/graphical_summary_categories_graph/$start_date/$end_date/$sale_type"), + "subtitle" => date('m/d/Y', strtotime($start_date)) .'-'.date('m/d/Y', strtotime($end_date)), + "summary_data" => $model->getSummaryData(array('start_date'=>$start_date, 'end_date'=>$end_date, 'sale_type' => $sale_type)) + ); + + $this->load->view("reports/graphical",$data); + } + + //The actual graph data + function graphical_summary_categories_graph($start_date, $end_date, $sale_type) + { + $this->load->model('reports/Summary_categories'); + $model = $this->Summary_categories; + $report_data = $model->getData(array('start_date'=>$start_date, 'end_date'=>$end_date, 'sale_type' => $sale_type)); + + $graph_data = array(); + foreach($report_data as $row) + { + $graph_data[$row['category']] = $row['total']; + } + + $data = array( + "title" => $this->lang->line('reports_categories_summary_report'), + "data" => $graph_data + ); + + $this->load->view("reports/graphs/pie",$data); + } + + function graphical_summary_suppliers($start_date, $end_date, $sale_type) + { + $this->load->model('reports/Summary_suppliers'); + $model = $this->Summary_suppliers; + + $data = array( + "title" => $this->lang->line('reports_suppliers_summary_report'), + "data_file" => site_url("reports/graphical_summary_suppliers_graph/$start_date/$end_date/$sale_type"), + "subtitle" => date('m/d/Y', strtotime($start_date)) .'-'.date('m/d/Y', strtotime($end_date)), + "summary_data" => $model->getSummaryData(array('start_date'=>$start_date, 'end_date'=>$end_date, 'sale_type' => $sale_type)) + ); + + $this->load->view("reports/graphical",$data); + } + + //The actual graph data + function graphical_summary_suppliers_graph($start_date, $end_date, $sale_type) + { + $this->load->model('reports/Summary_suppliers'); + $model = $this->Summary_suppliers; + $report_data = $model->getData(array('start_date'=>$start_date, 'end_date'=>$end_date, 'sale_type' => $sale_type)); + + $graph_data = array(); + foreach($report_data as $row) + { + $graph_data[$row['supplier']] = $row['total']; + } + + $data = array( + "title" => $this->lang->line('reports_suppliers_summary_report'), + "data" => $graph_data + ); + + $this->load->view("reports/graphs/pie",$data); + } + + function graphical_summary_employees($start_date, $end_date, $sale_type) + { + $this->load->model('reports/Summary_employees'); + $model = $this->Summary_employees; + + $data = array( + "title" => $this->lang->line('reports_employees_summary_report'), + "data_file" => site_url("reports/graphical_summary_employees_graph/$start_date/$end_date/$sale_type"), + "subtitle" => date('m/d/Y', strtotime($start_date)) .'-'.date('m/d/Y', strtotime($end_date)), + "summary_data" => $model->getSummaryData(array('start_date'=>$start_date, 'end_date'=>$end_date, 'sale_type' => $sale_type)) + ); + + $this->load->view("reports/graphical",$data); + } + + //The actual graph data + function graphical_summary_employees_graph($start_date, $end_date, $sale_type) + { + $this->load->model('reports/Summary_employees'); + $model = $this->Summary_employees; + $report_data = $model->getData(array('start_date'=>$start_date, 'end_date'=>$end_date, 'sale_type' => $sale_type)); + + $graph_data = array(); + foreach($report_data as $row) + { + $graph_data[$row['employee']] = $row['total']; + } + + $data = array( + "title" => $this->lang->line('reports_employees_summary_report'), + "data" => $graph_data + ); + + $this->load->view("reports/graphs/pie",$data); + } + + function graphical_summary_taxes($start_date, $end_date, $sale_type) + { + $this->load->model('reports/Summary_taxes'); + $model = $this->Summary_taxes; + + $data = array( + "title" => $this->lang->line('reports_taxes_summary_report'), + "data_file" => site_url("reports/graphical_summary_taxes_graph/$start_date/$end_date/$sale_type"), + "subtitle" => date('m/d/Y', strtotime($start_date)) .'-'.date('m/d/Y', strtotime($end_date)), + "summary_data" => $model->getSummaryData(array('start_date'=>$start_date, 'end_date'=>$end_date, 'sale_type' => $sale_type)) + ); + + $this->load->view("reports/graphical",$data); + } + + //The actual graph data + function graphical_summary_taxes_graph($start_date, $end_date, $sale_type) + { + $this->load->model('reports/Summary_taxes'); + $model = $this->Summary_taxes; + $report_data = $model->getData(array('start_date'=>$start_date, 'end_date'=>$end_date, 'sale_type' => $sale_type)); + + $graph_data = array(); + foreach($report_data as $row) + { + $graph_data[$row['percent']] = $row['total']; + } + + $data = array( + "title" => $this->lang->line('reports_taxes_summary_report'), + "data" => $graph_data + ); + + $this->load->view("reports/graphs/pie",$data); + } + + //Graphical summary customers report + function graphical_summary_customers($start_date, $end_date, $sale_type) + { + $this->load->model('reports/Summary_customers'); + $model = $this->Summary_customers; + + $data = array( + "title" => $this->lang->line('reports_customers_summary_report'), + "data_file" => site_url("reports/graphical_summary_customers_graph/$start_date/$end_date/$sale_type"), + "subtitle" => date('m/d/Y', strtotime($start_date)) .'-'.date('m/d/Y', strtotime($end_date)), + "summary_data" => $model->getSummaryData(array('start_date'=>$start_date, 'end_date'=>$end_date, 'sale_type' => $sale_type)) + ); + + $this->load->view("reports/graphical",$data); + } + + //The actual graph data + function graphical_summary_customers_graph($start_date, $end_date, $sale_type) + { + $this->load->model('reports/Summary_customers'); + $model = $this->Summary_customers; + $report_data = $model->getData(array('start_date'=>$start_date, 'end_date'=>$end_date, 'sale_type' => $sale_type)); + + $graph_data = array(); + foreach($report_data as $row) + { + $graph_data[$row['customer']] = $row['total']; + } + + $data = array( + "title" => $this->lang->line('reports_customers_summary_report'), + "xaxis_label"=>$this->lang->line('reports_revenue'), + "yaxis_label"=>$this->lang->line('reports_customers'), + "data" => $graph_data + ); + + $this->load->view("reports/graphs/hbar",$data); + } + + //Graphical summary discounts report + function graphical_summary_discounts($start_date, $end_date, $sale_type) + { + $this->load->model('reports/Summary_discounts'); + $model = $this->Summary_discounts; + + $data = array( + "title" => $this->lang->line('reports_discounts_summary_report'), + "data_file" => site_url("reports/graphical_summary_discounts_graph/$start_date/$end_date/$sale_type"), + "subtitle" => date('m/d/Y', strtotime($start_date)) .'-'.date('m/d/Y', strtotime($end_date)), + "summary_data" => $model->getSummaryData(array('start_date'=>$start_date, 'end_date'=>$end_date, 'sale_type' => $sale_type)) + ); + + $this->load->view("reports/graphical",$data); + } + + //The actual graph data + function graphical_summary_discounts_graph($start_date, $end_date, $sale_type) + { + $this->load->model('reports/Summary_discounts'); + $model = $this->Summary_discounts; + $report_data = $model->getData(array('start_date'=>$start_date, 'end_date'=>$end_date, 'sale_type' => $sale_type)); + + $graph_data = array(); + foreach($report_data as $row) + { + $graph_data[$row['discount_percent']] = $row['count']; + } + + $data = array( + "title" => $this->lang->line('reports_discounts_summary_report'), + "yaxis_label"=>$this->lang->line('reports_count'), + "xaxis_label"=>$this->lang->line('reports_discount_percent'), + "data" => $graph_data + ); + + $this->load->view("reports/graphs/bar",$data); + } + + function graphical_summary_payments($start_date, $end_date, $sale_type) + { + $this->load->model('reports/Summary_payments'); + $model = $this->Summary_payments; + + $data = array( + "title" => $this->lang->line('reports_payments_summary_report'), + "data_file" => site_url("reports/graphical_summary_payments_graph/$start_date/$end_date/$sale_type"), + "subtitle" => date('m/d/Y', strtotime($start_date)) .'-'.date('m/d/Y', strtotime($end_date)), + "summary_data" => $model->getSummaryData(array('start_date'=>$start_date, 'end_date'=>$end_date, 'sale_type' => $sale_type)) + ); + + $this->load->view("reports/graphical",$data); + } + + //The actual graph data + function graphical_summary_payments_graph($start_date, $end_date, $sale_type) + { + $this->load->model('reports/Summary_payments'); + $model = $this->Summary_payments; + $report_data = $model->getData(array('start_date'=>$start_date, 'end_date'=>$end_date, 'sale_type' => $sale_type)); + + $graph_data = array(); + foreach($report_data as $row) + { + $graph_data[$row['payment_type']] = $row['payment_amount']; + } + + $data = array( + "title" => $this->lang->line('reports_payments_summary_report'), + "yaxis_label"=>$this->lang->line('reports_revenue'), + "xaxis_label"=>$this->lang->line('reports_payment_type'), + "data" => $graph_data + ); + + $this->load->view("reports/graphs/pie",$data); + } + function specific_customer_input() + { + $data = $this->_get_common_report_data(); + $data['specific_input_name'] = $this->lang->line('reports_customer'); + + $customers = array(); + foreach($this->Customer->get_all()->result() as $customer) + { + $customers[$customer->person_id] = $customer->first_name .' '.$customer->last_name; + } + $data['specific_input_data'] = $customers; + $this->load->view("reports/specific_input",$data); + } + + function specific_customer($start_date, $end_date, $customer_id, $sale_type, $export_excel=0) + { + $this->load->model('reports/Specific_customer'); + $model = $this->Specific_customer; + + $headers = $model->getDataColumns(); + $report_data = $model->getData(array('start_date'=>$start_date, 'end_date'=>$end_date, 'customer_id' =>$customer_id, 'sale_type' => $sale_type)); + + $summary_data = array(); + $details_data = array(); + + foreach($report_data['summary'] as $key=>$row) + { + $summary_data[] = array(anchor('sales/edit/'.$row['sale_id'], 'POS '.$row['sale_id'], array('target' => '_blank')), $row['sale_date'], $row['items_purchased'], $row['employee_name'], to_currency($row['subtotal']), to_currency($row['total']), to_currency($row['tax']),to_currency($row['profit']), $row['payment_type'], $row['comment']); + + foreach($report_data['details'][$key] as $drow) + { + $details_data[$key][] = array($drow['name'], $drow['category'], $drow['serialnumber'], $drow['description'], $drow['quantity_purchased'], to_currency($drow['subtotal']), to_currency($drow['total']), to_currency($drow['tax']),to_currency($drow['profit']), $drow['discount_percent'].'%'); + } + } + + $customer_info = $this->Customer->get_info($customer_id); + $data = array( + "title" => $customer_info->first_name .' '. $customer_info->last_name.' '.$this->lang->line('reports_report'), + "subtitle" => date('m/d/Y', strtotime($start_date)) .'-'.date('m/d/Y', strtotime($end_date)), + "headers" => $model->getDataColumns(), + "summary_data" => $summary_data, + "details_data" => $details_data, + "overall_summary_data" => $model->getSummaryData(array('start_date'=>$start_date, 'end_date'=>$end_date,'customer_id' =>$customer_id, 'sale_type' => $sale_type)), + "export_excel" => $export_excel + ); + + $this->load->view("reports/tabular_details",$data); + } + + function specific_employee_input() + { + $data = $this->_get_common_report_data(); + $data['specific_input_name'] = $this->lang->line('reports_employee'); + + $employees = array(); + foreach($this->Employee->get_all()->result() as $employee) + { + $employees[$employee->person_id] = $employee->first_name .' '.$employee->last_name; + } + $data['specific_input_data'] = $employees; + $this->load->view("reports/specific_input",$data); + } + + function specific_employee($start_date, $end_date, $employee_id, $sale_type, $export_excel=0) + { + $this->load->model('reports/Specific_employee'); + $model = $this->Specific_employee; + + $headers = $model->getDataColumns(); + $report_data = $model->getData(array('start_date'=>$start_date, 'end_date'=>$end_date, 'employee_id' =>$employee_id, 'sale_type' => $sale_type)); + + $summary_data = array(); + $details_data = array(); + + foreach($report_data['summary'] as $key=>$row) + { + $summary_data[] = array(anchor('sales/edit/'.$row['sale_id'], 'POS '.$row['sale_id'], array('target' => '_blank')), $row['sale_date'], $row['items_purchased'], $row['customer_name'], to_currency($row['subtotal']), to_currency($row['total']), to_currency($row['tax']),to_currency($row['profit']), $row['payment_type'], $row['comment']); + + foreach($report_data['details'][$key] as $drow) + { + $details_data[$key][] = array($drow['name'], $drow['category'], $drow['serialnumber'], $drow['description'], $drow['quantity_purchased'], to_currency($drow['subtotal']), to_currency($drow['total']), to_currency($drow['tax']),to_currency($drow['profit']), $drow['discount_percent'].'%'); + } + } + + $employee_info = $this->Employee->get_info($employee_id); + $data = array( + "title" => $employee_info->first_name .' '. $employee_info->last_name.' '.$this->lang->line('reports_report'), + "subtitle" => date('m/d/Y', strtotime($start_date)) .'-'.date('m/d/Y', strtotime($end_date)), + "headers" => $model->getDataColumns(), + "summary_data" => $summary_data, + "details_data" => $details_data, + "overall_summary_data" => $model->getSummaryData(array('start_date'=>$start_date, 'end_date'=>$end_date,'employee_id' =>$employee_id, 'sale_type' => $sale_type)), + "export_excel" => $export_excel + ); + + $this->load->view("reports/tabular_details",$data); + } + + function detailed_sales($start_date, $end_date, $sale_type, $export_excel=0) + { + $this->load->model('reports/Detailed_sales'); + $model = $this->Detailed_sales; + + $headers = $model->getDataColumns(); + $report_data = $model->getData(array('start_date'=>$start_date, 'end_date'=>$end_date, 'sale_type' => $sale_type)); + + $summary_data = array(); + $details_data = array(); + + foreach($report_data['summary'] as $key=>$row) + { + $summary_data[] = array(anchor('sales/edit/'.$row['sale_id'], 'POS '.$row['sale_id'], array('target' => '_blank')), $row['sale_date'], $row['items_purchased'], $row['employee_name'], $row['customer_name'], to_currency($row['subtotal']), to_currency($row['total']), to_currency($row['tax']),to_currency($row['profit']), $row['payment_type'], $row['comment']); + + foreach($report_data['details'][$key] as $drow) + { + $details_data[$key][] = array($drow['name'], $drow['category'], $drow['serialnumber'], $drow['description'], $drow['quantity_purchased'], to_currency($drow['subtotal']), to_currency($drow['total']), to_currency($drow['tax']),to_currency($drow['profit']), $drow['discount_percent'].'%'); + } + } + + $data = array( + "title" =>$this->lang->line('reports_detailed_sales_report'), + "subtitle" => date('m/d/Y', strtotime($start_date)) .'-'.date('m/d/Y', strtotime($end_date)), + "headers" => $model->getDataColumns(), + "summary_data" => $summary_data, + "details_data" => $details_data, + "overall_summary_data" => $model->getSummaryData(array('start_date'=>$start_date, 'end_date'=>$end_date, 'sale_type' => $sale_type)), + "export_excel" => $export_excel + ); + + $this->load->view("reports/tabular_details",$data); + } + + function detailed_receivings($start_date, $end_date, $sale_type, $export_excel=0) + { + $this->load->model('reports/Detailed_receivings'); + $model = $this->Detailed_receivings; + + $headers = $model->getDataColumns(); + $report_data = $model->getData(array('start_date'=>$start_date, 'end_date'=>$end_date, 'sale_type' => $sale_type)); + + $summary_data = array(); + $details_data = array(); + + foreach($report_data['summary'] as $key=>$row) + { + $summary_data[] = array(anchor('receivings/receipt/'.$row['receiving_id'], 'RECV '.$row['receiving_id'], array('target' => '_blank')), $row['receiving_date'], $row['items_purchased'], $row['employee_name'], $row['supplier_name'], to_currency($row['total']), $row['payment_type'], $row['comment']); + + foreach($report_data['details'][$key] as $drow) + { + $details_data[$key][] = array($drow['name'], $drow['category'], $drow['quantity_purchased'], to_currency($drow['total']), $drow['discount_percent'].'%'); + } + } + + $data = array( + "title" =>$this->lang->line('reports_detailed_receivings_report'), + "subtitle" => date('m/d/Y', strtotime($start_date)) .'-'.date('m/d/Y', strtotime($end_date)), + "headers" => $model->getDataColumns(), + "summary_data" => $summary_data, + "details_data" => $details_data, + "overall_summary_data" => $model->getSummaryData(array('start_date'=>$start_date, 'end_date'=>$end_date, 'sale_type' => $sale_type)), + "export_excel" => $export_excel + ); + + $this->load->view("reports/tabular_details",$data); + } + + function excel_export() + { + $this->load->view("reports/excel_export",array()); + } + + function inventory_low($export_excel=0) + { + $this->load->model('reports/Inventory_low'); + $model = $this->Inventory_low; + $tabular_data = array(); + $report_data = $model->getData(array()); + foreach($report_data as $row) + { + $tabular_data[] = array($row['name'], $row['item_number'], $row['description'], $row['quantity'], $row['reorder_level']); + } + + $data = array( + "title" => $this->lang->line('reports_low_inventory_report'), + "subtitle" => '', + "headers" => $model->getDataColumns(), + "data" => $tabular_data, + "summary_data" => $model->getSummaryData(array()), + "export_excel" => $export_excel + ); + + $this->load->view("reports/tabular",$data); + } + + function inventory_summary($export_excel=0) + { + $this->load->model('reports/Inventory_summary'); + $model = $this->Inventory_summary; + $tabular_data = array(); + $report_data = $model->getData(array()); + foreach($report_data as $row) + { + $tabular_data[] = array($row['name'], $row['item_number'], $row['description'], $row['quantity'], $row['reorder_level']); + } + + $data = array( + "title" => $this->lang->line('reports_inventory_summary_report'), + "subtitle" => '', + "headers" => $model->getDataColumns(), + "data" => $tabular_data, + "summary_data" => $model->getSummaryData(array()), + "export_excel" => $export_excel + ); + + $this->load->view("reports/tabular",$data); + } + +} +?> \ No newline at end of file diff --git a/application/controllers/sales.php b/application/controllers/sales.php new file mode 100644 index 000000000..3e6ddd7f5 --- /dev/null +++ b/application/controllers/sales.php @@ -0,0 +1,431 @@ +load->library('sale_lib'); + } + + function index() + { + $this->_reload(); + } + + function item_search() + { + $suggestions = $this->Item->get_item_search_suggestions($this->input->post('q'),$this->input->post('limit')); + $suggestions = array_merge($suggestions, $this->Item_kit->get_item_kit_search_suggestions($this->input->post('q'),$this->input->post('limit'))); + echo implode("\n",$suggestions); + } + + function customer_search() + { + $suggestions = $this->Customer->get_customer_search_suggestions($this->input->post('q'),$this->input->post('limit')); + echo implode("\n",$suggestions); + } + + function select_customer() + { + $customer_id = $this->input->post("customer"); + $this->sale_lib->set_customer($customer_id); + $this->_reload(); + } + + function change_mode() + { + $mode = $this->input->post("mode"); + $this->sale_lib->set_mode($mode); + $this->_reload(); + } + + function set_comment() + { + $this->sale_lib->set_comment($this->input->post('comment')); + } + + function set_email_receipt() + { + $this->sale_lib->set_email_receipt($this->input->post('email_receipt')); + } + + //Alain Multiple Payments + function add_payment() + { + $data = array(); + $this->form_validation->set_rules( 'amount_tendered', 'lang:sales_amount_tendered', 'numeric' ); + + if ( $this->form_validation->run() == FALSE ) + { + if ( $this->input->post( 'payment_type' ) == $this->lang->line( 'sales_gift_card' ) ) + $data['error']=$this->lang->line('sales_must_enter_numeric_giftcard'); + else + $data['error']=$this->lang->line('sales_must_enter_numeric'); + + $this->_reload( $data ); + return; + } + + $payment_type = $this->input->post( 'payment_type' ); + if ( $payment_type == $this->lang->line( 'sales_giftcard' ) ) + { + $payments = $this->sale_lib->get_payments(); + $payment_type = $this->input->post( 'payment_type' ) . ':' . $payment_amount = $this->input->post( 'amount_tendered' ); + $current_payments_with_giftcard = isset( $payments[$payment_type] ) ? $payments[$payment_type]['payment_amount'] : 0; + $cur_giftcard_value = $this->Giftcard->get_giftcard_value( $this->input->post( 'amount_tendered' ) ) - $current_payments_with_giftcard; + + if ( $cur_giftcard_value <= 0 ) + { + $data['error'] = 'Giftcard balance is ' . to_currency( $this->Giftcard->get_giftcard_value( $this->input->post( 'amount_tendered' ) ) ) . ' !'; + $this->_reload( $data ); + return; + } + + $new_giftcard_value = $this->Giftcard->get_giftcard_value( $this->input->post( 'amount_tendered' ) ) - $this->sale_lib->get_amount_due( ); + $new_giftcard_value = ( $new_giftcard_value >= 0 ) ? $new_giftcard_value : 0; + $data['warning'] = 'Giftcard ' . $this->input->post( 'amount_tendered' ) . ' balance is ' . to_currency( $new_giftcard_value ) . ' !'; + $payment_amount = min( $this->sale_lib->get_amount_due( ), $this->Giftcard->get_giftcard_value( $this->input->post( 'amount_tendered' ) ) ); + } + else + { + $payment_amount = $this->input->post( 'amount_tendered' ); + } + + if( !$this->sale_lib->add_payment( $payment_type, $payment_amount ) ) + { + $data['error']='Unable to Add Payment! Please try again!'; + } + + $this->_reload($data); + } + + //Alain Multiple Payments + function delete_payment( $payment_id ) + { + $this->sale_lib->delete_payment( $payment_id ); + $this->_reload(); + } + + function add() + { + $data=array(); + $mode = $this->sale_lib->get_mode(); + $item_id_or_number_or_item_kit_or_receipt = $this->input->post("item"); + $quantity = $mode=="sale" ? 1:-1; + + if($this->sale_lib->is_valid_receipt($item_id_or_number_or_item_kit_or_receipt) && $mode=='return') + { + $this->sale_lib->return_entire_sale($item_id_or_number_or_item_kit_or_receipt); + } + elseif($this->sale_lib->is_valid_item_kit($item_id_or_number_or_item_kit_or_receipt)) + { + $this->sale_lib->add_item_kit($item_id_or_number_or_item_kit_or_receipt); + } + elseif(!$this->sale_lib->add_item($item_id_or_number_or_item_kit_or_receipt,$quantity)) + { + $data['error']=$this->lang->line('sales_unable_to_add_item'); + } + + if($this->sale_lib->out_of_stock($item_id_or_number_or_item_kit_or_receipt)) + { + $data['warning'] = $this->lang->line('sales_quantity_less_than_zero'); + } + $this->_reload($data); + } + + function edit_item($line) + { + $data= array(); + + $this->form_validation->set_rules('price', 'lang:items_price', 'required|numeric'); + $this->form_validation->set_rules('quantity', 'lang:items_quantity', 'required|numeric'); + + $description = $this->input->post("description"); + $serialnumber = $this->input->post("serialnumber"); + $price = $this->input->post("price"); + $quantity = $this->input->post("quantity"); + $discount = $this->input->post("discount"); + + + if ($this->form_validation->run() != FALSE) + { + $this->sale_lib->edit_item($line,$description,$serialnumber,$quantity,$discount,$price); + } + else + { + $data['error']=$this->lang->line('sales_error_editing_item'); + } + + if($this->sale_lib->out_of_stock($this->sale_lib->get_item_id($line))) + { + $data['warning'] = $this->lang->line('sales_quantity_less_than_zero'); + } + + + $this->_reload($data); + } + + function delete_item($item_number) + { + $this->sale_lib->delete_item($item_number); + $this->_reload(); + } + + function remove_customer() + { + $this->sale_lib->remove_customer(); + $this->_reload(); + } + + function complete() + { + $data['cart']=$this->sale_lib->get_cart(); + $data['subtotal']=$this->sale_lib->get_subtotal(); + $data['taxes']=$this->sale_lib->get_taxes(); + $data['total']=$this->sale_lib->get_total(); + $data['receipt_title']=$this->lang->line('sales_receipt'); + $data['transaction_time']= date('m/d/Y h:i:s a'); + $customer_id=$this->sale_lib->get_customer(); + $employee_id=$this->Employee->get_logged_in_employee_info()->person_id; + $comment = $this->sale_lib->get_comment(); + $emp_info=$this->Employee->get_info($employee_id); + $data['payments']=$this->sale_lib->get_payments(); + $data['amount_change']=to_currency($this->sale_lib->get_amount_due() * -1); + $data['employee']=$emp_info->first_name.' '.$emp_info->last_name; + + if($customer_id!=-1) + { + $cust_info=$this->Customer->get_info($customer_id); + $data['customer']=$cust_info->first_name.' '.$cust_info->last_name; + } + + //SAVE sale to database + $data['sale_id']='POS '.$this->Sale->save($data['cart'], $customer_id,$employee_id,$comment,$data['payments']); + if ($data['sale_id'] == 'POS -1') + { + $data['error_message'] = $this->lang->line('sales_transaction_failed'); + } + else + { + if ($this->sale_lib->get_email_receipt() && !empty($cust_info->email)) + { + $this->load->library('email'); + $config['mailtype'] = 'html'; + $this->email->initialize($config); + $this->email->from($this->config->item('email'), $this->config->item('company')); + $this->email->to($cust_info->email); + + $this->email->subject($this->lang->line('sales_receipt')); + $this->email->message($this->load->view("sales/receipt_email",$data, true)); + $this->email->send(); + } + } + $this->load->view("sales/receipt",$data); + $this->sale_lib->clear_all(); + } + + function receipt($sale_id) + { + $sale_info = $this->Sale->get_info($sale_id)->row_array(); + $this->sale_lib->copy_entire_sale($sale_id); + $data['cart']=$this->sale_lib->get_cart(); + $data['payments']=$this->sale_lib->get_payments(); + $data['subtotal']=$this->sale_lib->get_subtotal(); + $data['taxes']=$this->sale_lib->get_taxes(); + $data['total']=$this->sale_lib->get_total(); + $data['receipt_title']=$this->lang->line('sales_receipt'); + $data['transaction_time']= date('m/d/Y h:i:s a', strtotime($sale_info['sale_time'])); + $customer_id=$this->sale_lib->get_customer(); + $emp_info=$this->Employee->get_info($sale_info['employee_id']); + $data['payment_type']=$sale_info['payment_type']; + $data['amount_change']=to_currency($this->sale_lib->get_amount_due() * -1); + $data['employee']=$emp_info->first_name.' '.$emp_info->last_name; + + if($customer_id!=-1) + { + $cust_info=$this->Customer->get_info($customer_id); + $data['customer']=$cust_info->first_name.' '.$cust_info->last_name; + } + $data['sale_id']='POS '.$sale_id; + $this->load->view("sales/receipt",$data); + $this->sale_lib->clear_all(); + + } + + function edit($sale_id) + { + $data = array(); + + $data['customers'] = array('' => 'No Customer'); + foreach ($this->Customer->get_all()->result() as $customer) + { + $data['customers'][$customer->person_id] = $customer->first_name . ' '. $customer->last_name; + } + + $data['employees'] = array(); + foreach ($this->Employee->get_all()->result() as $employee) + { + $data['employees'][$employee->person_id] = $employee->first_name . ' '. $employee->last_name; + } + + $data['sale_info'] = $this->Sale->get_info($sale_id)->row_array(); + + + $this->load->view('sales/edit', $data); + } + + function delete($sale_id) + { + $data = array(); + + if ($this->Sale->delete($sale_id)) + { + $data['success'] = true; + } + else + { + $data['success'] = false; + } + + $this->load->view('sales/delete', $data); + + } + + function save($sale_id) + { + $sale_data = array( + 'sale_time' => date('Y-m-d', strtotime($this->input->post('date'))), + 'customer_id' => $this->input->post('customer_id') ? $this->input->post('customer_id') : null, + 'employee_id' => $this->input->post('employee_id'), + 'comment' => $this->input->post('comment') + ); + + if ($this->Sale->update($sale_data, $sale_id)) + { + echo json_encode(array('success'=>true,'message'=>$this->lang->line('sales_successfully_updated'))); + } + else + { + echo json_encode(array('success'=>false,'message'=>$this->lang->line('sales_unsuccessfully_updated'))); + } + } + + function _payments_cover_total() + { + $total_payments = 0; + + foreach($this->sale_lib->get_payments() as $payment) + { + $total_payments += $payment['payment_amount']; + } + + /* Changed the conditional to account for floating point rounding */ + if ( ( $this->sale_lib->get_mode() == 'sale' ) && ( ( to_currency_no_money( $this->sale_lib->get_total() ) - $total_payments ) > 1e-6 ) ) + { + return false; + } + + return true; + } + + function _reload($data=array()) + { + $person_info = $this->Employee->get_logged_in_employee_info(); + $data['cart']=$this->sale_lib->get_cart(); + $data['modes']=array('sale'=>$this->lang->line('sales_sale'),'return'=>$this->lang->line('sales_return')); + $data['mode']=$this->sale_lib->get_mode(); + $data['subtotal']=$this->sale_lib->get_subtotal(); + $data['taxes']=$this->sale_lib->get_taxes(); + $data['total']=$this->sale_lib->get_total(); + $data['items_module_allowed'] = $this->Employee->has_permission('items', $person_info->person_id); + $data['comment'] = $this->sale_lib->get_comment(); + $data['email_receipt'] = $this->sale_lib->get_email_receipt(); + $data['payments_total']=$this->sale_lib->get_payments_total(); + $data['amount_due']=$this->sale_lib->get_amount_due(); + $data['payments']=$this->sale_lib->get_payments(); + $data['payment_options']=array( + $this->lang->line('sales_cash') => $this->lang->line('sales_cash'), + $this->lang->line('sales_check') => $this->lang->line('sales_check'), + $this->lang->line('sales_giftcard') => $this->lang->line('sales_giftcard'), + $this->lang->line('sales_debit') => $this->lang->line('sales_debit'), + $this->lang->line('sales_credit') => $this->lang->line('sales_credit') + ); + + $customer_id=$this->sale_lib->get_customer(); + if($customer_id!=-1) + { + $info=$this->Customer->get_info($customer_id); + $data['customer']=$info->first_name.' '.$info->last_name; + $data['customer_email']=$info->email; + } + $data['payments_cover_total'] = $this->_payments_cover_total(); + $this->load->view("sales/register",$data); + } + + function cancel_sale() + { + $this->sale_lib->clear_all(); + $this->_reload(); + + } + + function suspend() + { + $data['cart']=$this->sale_lib->get_cart(); + $data['subtotal']=$this->sale_lib->get_subtotal(); + $data['taxes']=$this->sale_lib->get_taxes(); + $data['total']=$this->sale_lib->get_total(); + $data['receipt_title']=$this->lang->line('sales_receipt'); + $data['transaction_time']= date('m/d/Y h:i:s a'); + $customer_id=$this->sale_lib->get_customer(); + $employee_id=$this->Employee->get_logged_in_employee_info()->person_id; + $comment = $this->input->post('comment'); + $emp_info=$this->Employee->get_info($employee_id); + $payment_type = $this->input->post('payment_type'); + $data['payment_type']=$this->input->post('payment_type'); + //Alain Multiple payments + $data['payments']=$this->sale_lib->get_payments(); + $data['amount_change']=to_currency($this->sale_lib->get_amount_due() * -1); + $data['employee']=$emp_info->first_name.' '.$emp_info->last_name; + + if($customer_id!=-1) + { + $cust_info=$this->Customer->get_info($customer_id); + $data['customer']=$cust_info->first_name.' '.$cust_info->last_name; + } + + $total_payments = 0; + + foreach($data['payments'] as $payment) + { + $total_payments += $payment['payment_amount']; + } + + //SAVE sale to database + $data['sale_id']='POS '.$this->Sale_suspended->save($data['cart'], $customer_id,$employee_id,$comment,$data['payments']); + if ($data['sale_id'] == 'POS -1') + { + $data['error_message'] = $this->lang->line('sales_transaction_failed'); + } + $this->sale_lib->clear_all(); + $this->_reload(array('success' => $this->lang->line('sales_successfully_suspended_sale'))); + } + + function suspended() + { + $data = array(); + $data['suspended_sales'] = $this->Sale_suspended->get_all()->result_array(); + $this->load->view('sales/suspended', $data); + } + + function unsuspend() + { + $sale_id = $this->input->post('suspended_sale_id'); + $this->sale_lib->clear_all(); + $this->sale_lib->copy_entire_suspended_sale($sale_id); + $this->Sale_suspended->delete($sale_id); + $this->_reload(); + } +} +?> \ No newline at end of file diff --git a/application/controllers/secure_area.php b/application/controllers/secure_area.php new file mode 100644 index 000000000..c6daac17c --- /dev/null +++ b/application/controllers/secure_area.php @@ -0,0 +1,29 @@ +load->model('Employee'); + if(!$this->Employee->is_logged_in()) + { + redirect('login'); + } + + if(!$this->Employee->has_permission($module_id,$this->Employee->get_logged_in_employee_info()->person_id)) + { + redirect('no_access/'.$module_id); + } + + //load up global data + $logged_in_employee_info=$this->Employee->get_logged_in_employee_info(); + $data['allowed_modules']=$this->Module->get_allowed_modules($logged_in_employee_info->person_id); + $data['user_info']=$logged_in_employee_info; + $this->load->vars($data); + } +} +?> \ No newline at end of file diff --git a/application/controllers/suppliers.php b/application/controllers/suppliers.php new file mode 100644 index 000000000..d23e27bac --- /dev/null +++ b/application/controllers/suppliers.php @@ -0,0 +1,131 @@ +Supplier->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_supplier_manage_table( $this->Supplier->get_all( $config['per_page'], $this->uri->segment( $config['uri_segment'] ) ), $this ); + $this->load->view('suppliers/manage',$data); + } + + /* + Returns supplier table data rows. This will be called with AJAX. + */ + function search() + { + $search=$this->input->post('search'); + $data_rows=get_supplier_manage_table_data_rows($this->Supplier->search($search),$this); + echo $data_rows; + } + + /* + Gives search suggestions based on what is being searched for + */ + function suggest() + { + $suggestions = $this->Supplier->get_search_suggestions($this->input->post('q'),$this->input->post('limit')); + echo implode("\n",$suggestions); + } + + /* + Loads the supplier edit form + */ + function view($supplier_id=-1) + { + $data['person_info']=$this->Supplier->get_info($supplier_id); + $this->load->view("suppliers/form",$data); + } + + /* + Inserts/updates a supplier + */ + function save($supplier_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') + ); + $supplier_data=array( + 'company_name'=>$this->input->post('company_name'), + 'account_number'=>$this->input->post('account_number')=='' ? null:$this->input->post('account_number'), + ); + if($this->Supplier->save($person_data,$supplier_data,$supplier_id)) + { + //New supplier + if($supplier_id==-1) + { + echo json_encode(array('success'=>true,'message'=>$this->lang->line('suppliers_successful_adding').' '. + $supplier_data['company_name'],'person_id'=>$supplier_data['person_id'])); + } + else //previous supplier + { + echo json_encode(array('success'=>true,'message'=>$this->lang->line('suppliers_successful_updating').' '. + $supplier_data['company_name'],'person_id'=>$supplier_id)); + } + } + else//failure + { + echo json_encode(array('success'=>false,'message'=>$this->lang->line('suppliers_error_adding_updating').' '. + $supplier_data['company_name'],'person_id'=>-1)); + } + } + + /* + This deletes suppliers from the suppliers table + */ + function delete() + { + $suppliers_to_delete=$this->input->post('ids'); + + if($this->Supplier->delete_list($suppliers_to_delete)) + { + echo json_encode(array('success'=>true,'message'=>$this->lang->line('suppliers_successful_deleted').' '. + count($suppliers_to_delete).' '.$this->lang->line('suppliers_one_or_multiple'))); + } + else + { + echo json_encode(array('success'=>false,'message'=>$this->lang->line('suppliers_cannot_be_deleted'))); + } + } + + /* + Gets one row for a supplier manage table. This is called using AJAX to update one row. + */ + function get_row() + { + $person_id = $this->input->post('row_id'); + $data_row=get_supplier_data_row($this->Supplier->get_info($person_id),$this); + echo $data_row; + } + + /* + get the width for the add/edit form + */ + function get_form_width() + { + return 360; + } +} +?> \ No newline at end of file diff --git a/application/core/index.html b/application/core/index.html new file mode 100644 index 000000000..c942a79ce --- /dev/null +++ b/application/core/index.html @@ -0,0 +1,10 @@ + + + 403 Forbidden + + + +

Directory 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 @@ + + + +404 Page Not Found + + + +
+

+ +
+ + \ No newline at end of file diff --git a/application/errors/error_db.php b/application/errors/error_db.php new file mode 100644 index 000000000..b396cda9f --- /dev/null +++ b/application/errors/error_db.php @@ -0,0 +1,62 @@ + + + +Database Error + + + +
+

+ +
+ + \ No newline at end of file diff --git a/application/errors/error_general.php b/application/errors/error_general.php new file mode 100644 index 000000000..fd63ce2c5 --- /dev/null +++ b/application/errors/error_general.php @@ -0,0 +1,62 @@ + + + +Error + + + +
+

+ +
+ + \ No newline at end of file diff --git a/application/errors/error_php.php b/application/errors/error_php.php new file mode 100644 index 000000000..f085c2037 --- /dev/null +++ b/application/errors/error_php.php @@ -0,0 +1,10 @@ +
+ +

A PHP Error was encountered

+ +

Severity:

+

Message:

+

Filename:

+

Line Number:

+ +
\ No newline at end of file diff --git a/application/errors/index.html b/application/errors/index.html new file mode 100644 index 000000000..c942a79ce --- /dev/null +++ b/application/errors/index.html @@ -0,0 +1,10 @@ + + + 403 Forbidden + + + +

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 @@ + + + 403 Forbidden + + + +

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.=''; + foreach($headers as $header) + { + $table.="$header"; + } + $table.=''; + $table.=get_people_manage_table_data_rows($people,$controller); + $table.=''; + return $table; +} + +/* +Gets the html data rows for the people. +*/ +function get_people_manage_table_data_rows($people,$controller) +{ + $CI =& get_instance(); + $table_data_rows=''; + + foreach($people->result() as $person) + { + $table_data_rows.=get_person_data_row($person,$controller); + } + + if($people->num_rows()==0) + { + $table_data_rows.="
".$CI->lang->line('common_no_persons_to_display')."
"; + } + + return $table_data_rows; +} + +function get_person_data_row($person,$controller) +{ + $CI =& get_instance(); + $controller_name=strtolower(get_class($CI)); + $width = $controller->get_form_width(); + + $table_data_row=''; + $table_data_row.=""; + $table_data_row.=''.character_limiter($person->last_name,13).''; + $table_data_row.=''.character_limiter($person->first_name,13).''; + $table_data_row.=''.mailto($person->email,character_limiter($person->email,22)).''; + $table_data_row.=''.character_limiter($person->phone_number,13).''; + $table_data_row.=''.anchor($controller_name."/view/$person->person_id/width:$width", $CI->lang->line('common_edit'),array('class'=>'thickbox','title'=>$CI->lang->line($controller_name.'_update'))).''; + $table_data_row.=''; + + return $table_data_row; +} + +/* +Gets the html table to manage suppliers. +*/ +function get_supplier_manage_table($suppliers,$controller) +{ + $CI =& get_instance(); + $table=''; + + $headers = array('', + $CI->lang->line('suppliers_company_name'), + $CI->lang->line('common_last_name'), + $CI->lang->line('common_first_name'), + $CI->lang->line('common_email'), + $CI->lang->line('common_phone_number'), + ' '); + + $table.=''; + foreach($headers as $header) + { + $table.=""; + } + $table.=''; + $table.=get_supplier_manage_table_data_rows($suppliers,$controller); + $table.='
$header
'; + return $table; +} + +/* +Gets the html data rows for the supplier. +*/ +function get_supplier_manage_table_data_rows($suppliers,$controller) +{ + $CI =& get_instance(); + $table_data_rows=''; + + foreach($suppliers->result() as $supplier) + { + $table_data_rows.=get_supplier_data_row($supplier,$controller); + } + + if($suppliers->num_rows()==0) + { + $table_data_rows.="
".$CI->lang->line('common_no_persons_to_display')."
"; + } + + return $table_data_rows; +} + +function get_supplier_data_row($supplier,$controller) +{ + $CI =& get_instance(); + $controller_name=strtolower(get_class($CI)); + $width = $controller->get_form_width(); + + $table_data_row=''; + $table_data_row.=""; + $table_data_row.=''.character_limiter($supplier->company_name,13).''; + $table_data_row.=''.character_limiter($supplier->last_name,13).''; + $table_data_row.=''.character_limiter($supplier->first_name,13).''; + $table_data_row.=''.mailto($supplier->email,character_limiter($supplier->email,22)).''; + $table_data_row.=''.character_limiter($supplier->phone_number,13).''; + $table_data_row.=''.anchor($controller_name."/view/$supplier->person_id/width:$width", $CI->lang->line('common_edit'),array('class'=>'thickbox','title'=>$CI->lang->line($controller_name.'_update'))).''; + $table_data_row.=''; + + return $table_data_row; +} + +/* +Gets the html table to manage items. +*/ +function get_items_manage_table($items,$controller) +{ + $CI =& get_instance(); + $table=''; + + $headers = array('', + $CI->lang->line('items_item_number'), + $CI->lang->line('items_name'), + $CI->lang->line('items_category'), + $CI->lang->line('items_cost_price'), + $CI->lang->line('items_unit_price'), + $CI->lang->line('items_tax_percents'), + $CI->lang->line('items_quantity'), + ' ', + $CI->lang->line('items_inventory') + ); + + $table.=''; + foreach($headers as $header) + { + $table.=""; + } + $table.=''; + $table.=get_items_manage_table_data_rows($items,$controller); + $table.='
$header
'; + return $table; +} + +/* +Gets the html data rows for the items. +*/ +function get_items_manage_table_data_rows($items,$controller) +{ + $CI =& get_instance(); + $table_data_rows=''; + + foreach($items->result() as $item) + { + $table_data_rows.=get_item_data_row($item,$controller); + } + + if($items->num_rows()==0) + { + $table_data_rows.="
".$CI->lang->line('items_no_items_to_display')."
"; + } + + return $table_data_rows; +} + +function get_item_data_row($item,$controller) +{ + $CI =& get_instance(); + $item_tax_info=$CI->Item_taxes->get_info($item->item_id); + $tax_percents = ''; + foreach($item_tax_info as $tax_info) + { + $tax_percents.=$tax_info['percent']. '%, '; + } + $tax_percents=substr($tax_percents, 0, -2); + $controller_name=strtolower(get_class($CI)); + $width = $controller->get_form_width(); + + $table_data_row=''; + $table_data_row.=""; + $table_data_row.=''.$item->item_number.''; + $table_data_row.=''.$item->name.''; + $table_data_row.=''.$item->category.''; + $table_data_row.=''.to_currency($item->cost_price).''; + $table_data_row.=''.to_currency($item->unit_price).''; + $table_data_row.=''.$tax_percents.''; + $table_data_row.=''.$item->quantity.''; + $table_data_row.=''.anchor($controller_name."/view/$item->item_id/width:$width", $CI->lang->line('common_edit'),array('class'=>'thickbox','title'=>$CI->lang->line($controller_name.'_update'))).''; + + //Ramel Inventory Tracking + $table_data_row.=''.anchor($controller_name."/inventory/$item->item_id/width:$width", $CI->lang->line('common_inv'),array('class'=>'thickbox','title'=>$CI->lang->line($controller_name.'_count')))./*'';//inventory count + $table_data_row.=''*/'    '.anchor($controller_name."/count_details/$item->item_id/width:$width", $CI->lang->line('common_det'),array('class'=>'thickbox','title'=>$CI->lang->line($controller_name.'_details_count'))).'';//inventory details + + $table_data_row.=''; + return $table_data_row; +} + +/* +Gets the html table to manage giftcards. +*/ +function get_giftcards_manage_table( $giftcards, $controller ) +{ + $CI =& get_instance(); + + $table=''; + + $headers = array('', + $CI->lang->line('common_last_name'), + $CI->lang->line('common_first_name'), + $CI->lang->line('giftcards_giftcard_number'), + $CI->lang->line('giftcards_card_value'), + ' ', + ); + + $table.=''; + foreach($headers as $header) + { + $table.=""; + } + $table.=''; + $table.=get_giftcards_manage_table_data_rows( $giftcards, $controller ); + $table.='
$header
'; + return $table; +} + +/* +Gets the html data rows for the giftcard. +*/ +function get_giftcards_manage_table_data_rows( $giftcards, $controller ) +{ + $CI =& get_instance(); + $table_data_rows=''; + + foreach($giftcards->result() as $giftcard) + { + $table_data_rows.=get_giftcard_data_row( $giftcard, $controller ); + } + + if($giftcards->num_rows()==0) + { + $table_data_rows.="
".$CI->lang->line('giftcards_no_giftcards_to_display')."
"; + } + + return $table_data_rows; +} + +/** GARRISON MODIFIED 4/25/2013 **/ +function get_giftcard_data_row($giftcard,$controller) +{ + $CI =& get_instance(); + $controller_name=strtolower(get_class($CI)); + $width = $controller->get_form_width(); + + $table_data_row=''; + $table_data_row.=""; + $table_data_row.=''.$giftcard->last_name.''; + $table_data_row.=''.$giftcard->first_name.''; + $table_data_row.=''.$giftcard->giftcard_number.''; + $table_data_row.=''.to_currency($giftcard->value).''; + $table_data_row.=''.anchor($controller_name."/view/$giftcard->giftcard_id/width:$width", $CI->lang->line('common_edit'),array('class'=>'thickbox','title'=>$CI->lang->line($controller_name.'_update'))).''; + + $table_data_row.=''; + return $table_data_row; +} +/** END GARRISON MODIFIED **/ + +/* +Gets the html table to manage item kits. +*/ +function get_item_kits_manage_table( $item_kits, $controller ) +{ + $CI =& get_instance(); + + $table=''; + + $headers = array('', + $CI->lang->line('item_kits_name'), + $CI->lang->line('item_kits_description'), + ' ', + ); + + $table.=''; + foreach($headers as $header) + { + $table.=""; + } + $table.=''; + $table.=get_item_kits_manage_table_data_rows( $item_kits, $controller ); + $table.='
$header
'; + return $table; +} + +/* +Gets the html data rows for the item kits. +*/ +function get_item_kits_manage_table_data_rows( $item_kits, $controller ) +{ + $CI =& get_instance(); + $table_data_rows=''; + + foreach($item_kits->result() as $item_kit) + { + $table_data_rows.=get_item_kit_data_row( $item_kit, $controller ); + } + + if($item_kits->num_rows()==0) + { + $table_data_rows.="
".$CI->lang->line('item_kits_no_item_kits_to_display')."
"; + } + + return $table_data_rows; +} + +function get_item_kit_data_row($item_kit,$controller) +{ + $CI =& get_instance(); + $controller_name=strtolower(get_class($CI)); + $width = $controller->get_form_width(); + + $table_data_row=''; + $table_data_row.=""; + $table_data_row.=''.$item_kit->name.''; + $table_data_row.=''.character_limiter($item_kit->description, 25).''; + $table_data_row.=''.anchor($controller_name."/view/$item_kit->item_kit_id/width:$width", $CI->lang->line('common_edit'),array('class'=>'thickbox','title'=>$CI->lang->line($controller_name.'_update'))).''; + + $table_data_row.=''; + return $table_data_row; +} + +?> \ No newline at end of file diff --git a/application/hooks/index.html b/application/hooks/index.html new file mode 100644 index 000000000..c942a79ce --- /dev/null +++ b/application/hooks/index.html @@ -0,0 +1,10 @@ + + + 403 Forbidden + + + +

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 @@ + + + 403 Forbidden + + + +

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 @@ + + + 403 Forbidden + + + +

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 @@ + + + 403 Dilarang + + + +

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 @@ + + + 403 Forbidden + + + +

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 @@ + + + 403 Prohibido + + + +

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 @@ + + + 403 Forbidden + + + +

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 @@ + + + 403 Forbidden + + + +

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 + * @author Brett Stimmerman + * @copyright 2005 Michal Migurski + * @version CVS: $Id: JSON.php,v 1.31 2006/06/28 05:54:17 migurski Exp $ + * @license http://www.opensource.org/licenses/bsd-license.php + * @link http://pear.php.net/pepr/pepr-proposal-show.php?id=198 + */ + +/** + * Marker constant for Services_JSON::decode(), used to flag stack state + */ +define('SERVICES_JSON_SLICE', 1); + +/** + * Marker constant for Services_JSON::decode(), used to flag stack state + */ +define('SERVICES_JSON_IN_STR', 2); + +/** + * Marker constant for Services_JSON::decode(), used to flag stack state + */ +define('SERVICES_JSON_IN_ARR', 3); + +/** + * Marker constant for Services_JSON::decode(), used to flag stack state + */ +define('SERVICES_JSON_IN_OBJ', 4); + +/** + * Marker constant for Services_JSON::decode(), used to flag stack state + */ +define('SERVICES_JSON_IN_CMT', 5); + +/** + * Behavior switch for Services_JSON::decode() + */ +define('SERVICES_JSON_LOOSE_TYPE', 16); + +/** + * Behavior switch for Services_JSON::decode() + */ +define('SERVICES_JSON_SUPPRESS_ERRORS', 32); + +/** + * Converts to and from JSON format. + * + * Brief example of use: + * + * + * // 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 @@ + + + 403 Forbidden + + + +

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 @@ + + + 403 Forbidden + + + +

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']).'
'; + } + + $sales_data = array( + 'sale_time' => date('Y-m-d H:i:s'), + 'customer_id'=> $this->Customer->exists($customer_id) ? $customer_id : null, + 'employee_id'=>$employee_id, + 'payment_type'=>$payment_types, + '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('sales',$sales_data); + $sale_id = $this->db->insert_id(); + + foreach($payments as $payment_id=>$payment) + { + if ( substr( $payment['payment_type'], 0, strlen( $this->lang->line('sales_giftcard') ) ) == $this->lang->line('sales_giftcard') ) + { + /* We have a gift card and we have to deduct the used value from the total value of the card. */ + $splitpayment = explode( ':', $payment['payment_type'] ); + $cur_giftcard_value = $this->Giftcard->get_giftcard_value( $splitpayment[1] ); + $this->Giftcard->update_giftcard_value( $splitpayment[1], $cur_giftcard_value - $payment['payment_amount'] ); + } + + $sales_payments_data = array + ( + 'sale_id'=>$sale_id, + 'payment_type'=>$payment['payment_type'], + 'payment_amount'=>$payment['payment_amount'] + ); + $this->db->insert('sales_payments',$sales_payments_data); + } + + foreach($items as $line=>$item) + { + $cur_item_info = $this->Item->get_info($item['item_id']); + + $sales_items_data = array + ( + 'sale_id'=>$sale_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('sales_items',$sales_items_data); + + //Update stock quantity + $item_data = array('quantity'=>$cur_item_info->quantity - $item['quantity']); + $this->Item->save($item_data,$item['item_id']); + + //Ramel Inventory Tracking + //Inventory Count Details + $qty_buy = -$item['quantity']; + $sale_remarks ='POS '.$sale_id; + $inv_data = array + ( + 'trans_date'=>date('Y-m-d H:i:s'), + 'trans_items'=>$item['item_id'], + 'trans_user'=>$employee_id, + 'trans_comment'=>$sale_remarks, + 'trans_inventory'=>$qty_buy + ); + $this->Inventory->insert($inv_data); + //------------------------------------Ramel + + $customer = $this->Customer->get_info($customer_id); + if ($customer_id == -1 or $customer->taxable) + { + foreach($this->Item_taxes->get_info($item['item_id']) as $row) + { + $this->db->insert('sales_items_taxes', array( + 'sale_id' =>$sale_id, + 'item_id' =>$item['item_id'], + 'line' =>$item['line'], + 'name' =>$row['name'], + 'percent' =>$row['percent'] + )); + } + } + } + $this->db->trans_complete(); + + if ($this->db->trans_status() === FALSE) + { + return -1; + } + + return $sale_id; + } + + function delete($sale_id) + { + //Run these queries as a transaction, we want to make sure we do all or nothing + $this->db->trans_start(); + + $this->db->delete('sales_payments', array('sale_id' => $sale_id)); + $this->db->delete('sales_items_taxes', array('sale_id' => $sale_id)); + $this->db->delete('sales_items', array('sale_id' => $sale_id)); + $this->db->delete('sales', array('sale_id' => $sale_id)); + + $this->db->trans_complete(); + + return $this->db->trans_status(); + } + + function get_sale_items($sale_id) + { + $this->db->from('sales_items'); + $this->db->where('sale_id',$sale_id); + return $this->db->get(); + } + + function get_sale_payments($sale_id) + { + $this->db->from('sales_payments'); + $this->db->where('sale_id',$sale_id); + return $this->db->get(); + } + + function get_customer($sale_id) + { + $this->db->from('sales'); + $this->db->where('sale_id',$sale_id); + return $this->Customer->get_info($this->db->get()->row()->customer_id); + } + + //We create a temp table that allows us to do easy report/sales queries + public function create_sales_items_temp_table() + { + $this->db->query("CREATE TEMPORARY TABLE ".$this->db->dbprefix('sales_items_temp')." + (SELECT date(sale_time) as sale_date, ".$this->db->dbprefix('sales_items').".sale_id, comment,payment_type, customer_id, employee_id, + ".$this->db->dbprefix('items').".item_id, supplier_id, quantity_purchased, item_cost_price, item_unit_price, SUM(percent) as item_tax_percent, + discount_percent, (item_unit_price*quantity_purchased-item_unit_price*quantity_purchased*discount_percent/100) as subtotal, + ".$this->db->dbprefix('sales_items').".line as line, serialnumber, ".$this->db->dbprefix('sales_items').".description as description, + ROUND((item_unit_price*quantity_purchased-item_unit_price*quantity_purchased*discount_percent/100)*(1+(SUM(percent)/100)),2) as total, + ROUND((item_unit_price*quantity_purchased-item_unit_price*quantity_purchased*discount_percent/100)*(SUM(percent)/100),2) as tax, + (item_unit_price*quantity_purchased-item_unit_price*quantity_purchased*discount_percent/100) - (item_cost_price*quantity_purchased) as profit + FROM ".$this->db->dbprefix('sales_items')." + INNER JOIN ".$this->db->dbprefix('sales')." ON ".$this->db->dbprefix('sales_items').'.sale_id='.$this->db->dbprefix('sales').'.sale_id'." + INNER JOIN ".$this->db->dbprefix('items')." ON ".$this->db->dbprefix('sales_items').'.item_id='.$this->db->dbprefix('items').'.item_id'." + LEFT OUTER JOIN ".$this->db->dbprefix('suppliers')." ON ".$this->db->dbprefix('items').'.supplier_id='.$this->db->dbprefix('suppliers').'.person_id'." + LEFT OUTER JOIN ".$this->db->dbprefix('sales_items_taxes')." 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'." + GROUP BY sale_id, item_id, line)"); + + //Update null item_tax_percents to be 0 instead of null + $this->db->where('item_tax_percent IS NULL'); + $this->db->update('sales_items_temp', array('item_tax_percent' => 0)); + + //Update null tax to be 0 instead of null + $this->db->where('tax IS NULL'); + $this->db->update('sales_items_temp', array('tax' => 0)); + + //Update null subtotals to be equal to the total as these don't have tax + $this->db->query('UPDATE '.$this->db->dbprefix('sales_items_temp'). ' SET total=subtotal WHERE total IS NULL'); + } + + public function get_giftcard_value( $giftcardNumber ) + { + if ( !$this->Giftcard->exists( $this->Giftcard->get_giftcard_id($giftcardNumber))) + return 0; + + $this->db->from('giftcards'); + $this->db->where('giftcard_number',$giftcardNumber); + return $this->db->get()->row()->value; + } +} +?> diff --git a/application/models/sale_suspended.php b/application/models/sale_suspended.php new file mode 100644 index 000000000..3c46b6274 --- /dev/null +++ b/application/models/sale_suspended.php @@ -0,0 +1,160 @@ +db->from('sales_suspended'); + $this->db->order_by('sale_id'); + return $this->db->get(); + } + + public function get_info($sale_id) + { + $this->db->from('sales_suspended'); + $this->db->where('sale_id',$sale_id); + return $this->db->get(); + } + + function exists($sale_id) + { + $this->db->from('sales_suspended'); + $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_suspended',$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']).'
'; + } + + $sales_data = array( + 'sale_time' => date('Y-m-d H:i:s'), + 'customer_id'=> $this->Customer->exists($customer_id) ? $customer_id : null, + 'employee_id'=>$employee_id, + 'payment_type'=>$payment_types, + '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('sales_suspended',$sales_data); + $sale_id = $this->db->insert_id(); + + foreach($payments as $payment_id=>$payment) + { + $sales_payments_data = array + ( + 'sale_id'=>$sale_id, + 'payment_type'=>$payment['payment_type'], + 'payment_amount'=>$payment['payment_amount'] + ); + $this->db->insert('sales_suspended_payments',$sales_payments_data); + } + + foreach($items as $line=>$item) + { + $cur_item_info = $this->Item->get_info($item['item_id']); + + $sales_items_data = array + ( + 'sale_id'=>$sale_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('sales_suspended_items',$sales_items_data); + + $customer = $this->Customer->get_info($customer_id); + if ($customer_id == -1 or $customer->taxable) + { + foreach($this->Item_taxes->get_info($item['item_id']) as $row) + { + $this->db->insert('sales_suspended_items_taxes', array( + 'sale_id' =>$sale_id, + 'item_id' =>$item['item_id'], + 'line' =>$item['line'], + 'name' =>$row['name'], + 'percent' =>$row['percent'] + )); + } + } + } + $this->db->trans_complete(); + + if ($this->db->trans_status() === FALSE) + { + return -1; + } + + return $sale_id; + } + + function delete($sale_id) + { + //Run these queries as a transaction, we want to make sure we do all or nothing + $this->db->trans_start(); + + $this->db->delete('sales_suspended_payments', array('sale_id' => $sale_id)); + $this->db->delete('sales_suspended_items_taxes', array('sale_id' => $sale_id)); + $this->db->delete('sales_suspended_items', array('sale_id' => $sale_id)); + $this->db->delete('sales_suspended', array('sale_id' => $sale_id)); + + $this->db->trans_complete(); + + return $this->db->trans_status(); + } + + function get_sale_items($sale_id) + { + $this->db->from('sales_suspended_items'); + $this->db->where('sale_id',$sale_id); + return $this->db->get(); + } + + function get_sale_payments($sale_id) + { + $this->db->from('sales_suspended_payments'); + $this->db->where('sale_id',$sale_id); + return $this->db->get(); + } + + function get_customer($sale_id) + { + $this->db->from('sales_suspended'); + $this->db->where('sale_id',$sale_id); + return $this->Customer->get_info($this->db->get()->row()->customer_id); + } + + function get_comment($sale_id) + { + $this->db->from('sales_suspended'); + $this->db->where('sale_id',$sale_id); + return $this->db->get()->row()->comment; + } +} +?> diff --git a/application/models/supplier.php b/application/models/supplier.php new file mode 100644 index 000000000..d5ec68b73 --- /dev/null +++ b/application/models/supplier.php @@ -0,0 +1,260 @@ +db->from('suppliers'); + $this->db->join('people', 'people.person_id = suppliers.person_id'); + $this->db->where('suppliers.person_id',$person_id); + $query = $this->db->get(); + + return ($query->num_rows()==1); + } + + /* + Returns all the suppliers + */ + function get_all($limit=10000, $offset=0) + { + $this->db->from('suppliers'); + $this->db->join('people','suppliers.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('suppliers'); + $this->db->where('deleted',0); + return $this->db->count_all_results(); + } + + /* + Gets information about a particular supplier + */ + function get_info($supplier_id) + { + $this->db->from('suppliers'); + $this->db->join('people', 'people.person_id = suppliers.person_id'); + $this->db->where('suppliers.person_id',$supplier_id); + $query = $this->db->get(); + + if($query->num_rows()==1) + { + return $query->row(); + } + else + { + //Get empty base parent object, as $supplier_id is NOT an supplier + $person_obj=parent::get_info(-1); + + //Get all the fields from supplier table + $fields = $this->db->list_fields('suppliers'); + + //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 suppliers + */ + function get_multiple_info($suppliers_ids) + { + $this->db->from('suppliers'); + $this->db->join('people', 'people.person_id = suppliers.person_id'); + $this->db->where_in('suppliers.person_id',$suppliers_ids); + $this->db->order_by("last_name", "asc"); + return $this->db->get(); + } + + /* + Inserts or updates a suppliers + */ + function save(&$person_data, &$supplier_data,$supplier_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,$supplier_id)) + { + if (!$supplier_id or !$this->exists($supplier_id)) + { + $supplier_data['person_id'] = $person_data['person_id']; + $success = $this->db->insert('suppliers',$supplier_data); + } + else + { + $this->db->where('person_id', $supplier_id); + $success = $this->db->update('suppliers',$supplier_data); + } + + } + + $this->db->trans_complete(); + return $success; + } + + /* + Deletes one supplier + */ + function delete($supplier_id) + { + $this->db->where('person_id', $supplier_id); + return $this->db->update('suppliers', array('deleted' => 1)); + } + + /* + Deletes a list of suppliers + */ + function delete_list($supplier_ids) + { + $this->db->where_in('person_id',$supplier_ids); + return $this->db->update('suppliers', array('deleted' => 1)); + } + + /* + Get search suggestions to find suppliers + */ + function get_search_suggestions($search,$limit=25) + { + $suggestions = array(); + + $this->db->from('suppliers'); + $this->db->join('people','suppliers.person_id=people.person_id'); + $this->db->where('deleted', 0); + $this->db->like("company_name",$search); + $this->db->order_by("company_name", "asc"); + $by_company_name = $this->db->get(); + foreach($by_company_name->result() as $row) + { + $suggestions[]=$row->company_name; + } + + + $this->db->from('suppliers'); + $this->db->join('people','suppliers.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('suppliers'); + $this->db->join('people','suppliers.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('suppliers'); + $this->db->join('people','suppliers.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('suppliers'); + $this->db->join('people','suppliers.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 suppliers + */ + function get_suppliers_search_suggestions($search,$limit=25) + { + $suggestions = array(); + + $this->db->from('suppliers'); + $this->db->join('people','suppliers.person_id=people.person_id'); + $this->db->where('deleted', 0); + $this->db->like("company_name",$search); + $this->db->order_by("company_name", "asc"); + $by_company_name = $this->db->get(); + foreach($by_company_name->result() as $row) + { + $suggestions[]=$row->person_id.'|'.$row->company_name; + } + + + $this->db->from('suppliers'); + $this->db->join('people','suppliers.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; + } + + //only return $limit suggestions + if(count($suggestions > $limit)) + { + $suggestions = array_slice($suggestions, 0,$limit); + } + return $suggestions; + + } + /* + Perform a search on suppliers + */ + function search($search) + { + $this->db->from('suppliers'); + $this->db->join('people','suppliers.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 + company_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/third_party/index.html b/application/third_party/index.html new file mode 100644 index 000000000..c942a79ce --- /dev/null +++ b/application/third_party/index.html @@ -0,0 +1,10 @@ + + + 403 Forbidden + + + +

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 @@ + + + + + + +*/ +/*=============================================================================*/ + + +//----------------------------------------------------------------------------- +// Startup code +//----------------------------------------------------------------------------- + +if(isset($_GET["text"])) $text=$_GET["text"]; +if(isset($_GET["format"])) $format=$_GET["format"]; +if(isset($_GET["quality"])) $quality=$_GET["quality"]; +if(isset($_GET["width"])) $width=$_GET["width"]; +if(isset($_GET["height"])) $height=$_GET["height"]; +if(isset($_GET["type"])) $type=$_GET["type"]; +if(isset($_GET["barcode"])) $barcode=$_GET["barcode"]; + +if (!isset ($text)) $text = ''; +if (!isset ($type)) $type = 1; +if (empty ($quality)) $quality = 100; +if (empty ($width)) $width = 160; +if (empty ($height)) $height = 80; +if (!empty ($format)) $format = strtoupper ($format); + else $format="PNG"; + +switch ($type) +{ + default: + $type = 1; + case 1: + Barcode39 ($barcode, $width, $height, $quality, $format, $text); + break; +} + +//----------------------------------------------------------------------------- +// Generate a Code 3 of 9 barcode +//----------------------------------------------------------------------------- +function Barcode39 ($barcode, $width, $height, $quality, $format, $text) +{ + switch ($format) + { + default: + $format = "JPEG"; + case "JPEG": + header ("Content-type: image/jpeg"); + break; + case "PNG": + header ("Content-type: image/png"); + break; + case "GIF": + header ("Content-type: image/gif"); + break; + } + + + $im = ImageCreate ($width, $height) + or die ("Cannot Initialize new GD image stream"); + $White = ImageColorAllocate ($im, 255, 255, 255); + $Black = ImageColorAllocate ($im, 0, 0, 0); + //ImageColorTransparent ($im, $White); + ImageInterLace ($im, 1); + + + + $NarrowRatio = 20; + $WideRatio = 55; + $QuietRatio = 35; + + + $nChars = (strlen($barcode)+2) * ((6 * $NarrowRatio) + (3 * $WideRatio) + ($QuietRatio)); + $Pixels = $width / $nChars; + $NarrowBar = (int)(20 * $Pixels); + $WideBar = (int)(55 * $Pixels); + $QuietBar = (int)(35 * $Pixels); + + + $ActualWidth = (($NarrowBar * 6) + ($WideBar*3) + $QuietBar) * (strlen ($barcode)+2); + + if (($NarrowBar == 0) || ($NarrowBar == $WideBar) || ($NarrowBar == $QuietBar) || ($WideBar == 0) || ($WideBar == $QuietBar) || ($QuietBar == 0)) + { + ImageString ($im, 1, 0, 0, "Image is too small!", $Black); + OutputImage ($im, $format, $quality); + exit; + } + + $CurrentBarX = (int)(($width - $ActualWidth) / 2); + $Color = $White; + $BarcodeFull = "*".strtoupper ($barcode)."*"; + settype ($BarcodeFull, "string"); + + $FontNum = 3; + $FontHeight = ImageFontHeight ($FontNum); + $FontWidth = ImageFontWidth ($FontNum); + + if ($text != '') + { + $CenterLoc = (int)(($width) / 2) - (int)(($FontWidth * strlen($text)) / 2); + ImageString ($im, $FontNum, $CenterLoc, $height-$FontHeight, "$text", $Black); + } + + + for ($i=0; $i \ No newline at end of file diff --git a/application/views/barcode_sheet.php b/application/views/barcode_sheet.php new file mode 100644 index 000000000..eb196ebf4 --- /dev/null +++ b/application/views/barcode_sheet.php @@ -0,0 +1,28 @@ + + + + <?php echo $this->lang->line('items_generate_barcodes'); ?> + + + + +'; + } + echo ""; + $count++; +} +?> + +
+ + diff --git a/application/views/config.php b/application/views/config.php new file mode 100644 index 000000000..5e46b263a --- /dev/null +++ b/application/views/config.php @@ -0,0 +1,439 @@ +load->view("partial/header"); ?> +
lang->line('module_config'); ?>
+'config_form')); +?> +
+
+
lang->line('common_fields_required_message'); ?>
+
    +lang->line("config_info"); ?> + +
    +lang->line('config_company').':', 'company',array('class'=>'wide required')); ?> +
    + 'company', + 'id'=>'company', + 'value'=>$this->config->item('company')));?> +
    +
    + +
    +lang->line('config_address').':', 'address',array('class'=>'wide required')); ?> +
    + 'address', + 'id'=>'address', + 'rows'=>4, + 'cols'=>17, + 'value'=>$this->config->item('address')));?> +
    +
    + +
    +lang->line('config_phone').':', 'phone',array('class'=>'wide required')); ?> +
    + 'phone', + 'id'=>'phone', + 'value'=>$this->config->item('phone')));?> +
    +
    + +
    +lang->line('config_default_tax_rate_1').':', 'default_tax_1_rate',array('class'=>'wide required')); ?> +
    + 'default_tax_1_name', + 'id'=>'default_tax_1_name', + 'size'=>'10', + 'value'=>$this->config->item('default_tax_1_name')!==FALSE ? $this->config->item('default_tax_1_name') : $this->lang->line('items_sales_tax_1')));?> + + 'default_tax_1_rate', + 'id'=>'default_tax_1_rate', + 'size'=>'4', + 'value'=>$this->config->item('default_tax_1_rate')));?>% +
    +
    + +
    +lang->line('config_default_tax_rate_2').':', 'default_tax_1_rate',array('class'=>'wide')); ?> +
    + 'default_tax_2_name', + 'id'=>'default_tax_2_name', + 'size'=>'10', + 'value'=>$this->config->item('default_tax_2_name')!==FALSE ? $this->config->item('default_tax_2_name') : $this->lang->line('items_sales_tax_2')));?> + + 'default_tax_2_rate', + 'id'=>'default_tax_2_rate', + 'size'=>'4', + 'value'=>$this->config->item('default_tax_2_rate')));?>% +
    +
    + +
    + lang->line('config_currency_symbol').':', 'currency_symbol',array('class'=>'wide')); ?> +
    + 'currency_symbol', + 'id'=>'currency_symbol', + 'value'=>$this->config->item('currency_symbol')));?> +
    + + lang->line('config_currency_side').':', 'currency_side',array('class'=>''));?> +
    + 'currency_side', + 'id'=>'currency_side', + 'value'=>'currency_side', + 'checked'=>$this->config->item('currency_side')));?> +
    +
    + + +
    +lang->line('common_email').':', 'email',array('class'=>'wide')); ?> +
    + 'email', + 'id'=>'email', + 'value'=>$this->config->item('email')));?> +
    +
    + + +
    +lang->line('config_fax').':', 'fax',array('class'=>'wide')); ?> +
    + 'fax', + 'id'=>'fax', + 'value'=>$this->config->item('fax')));?> +
    +
    + +
    +lang->line('config_website').':', 'website',array('class'=>'wide')); ?> +
    + 'website', + 'id'=>'website', + 'value'=>$this->config->item('website')));?> +
    +
    + +
    +lang->line('common_return_policy').':', 'return_policy',array('class'=>'wide required')); ?> +
    + 'return_policy', + 'id'=>'return_policy', + 'rows'=>'4', + 'cols'=>'17', + 'value'=>$this->config->item('return_policy')));?> +
    +
    + +
    +lang->line('config_language').':', 'language',array('class'=>'wide required')); ?> +
    + 'Azerbaijan', + 'BahasaIndonesia' => 'BahasaIndonesia', + 'english' => 'English', + 'Spanish' => 'Spanish', + 'Russian' => 'Russian' + ), + $this->config->item('language')); + ?> +
    +
    + +
    +lang->line('config_timezone').':', 'timezone',array('class'=>'wide required')); ?> +
    + '(GMT-11:00) Midway Island, Samoa', + 'America/Adak'=>'(GMT-10:00) Hawaii-Aleutian', + 'Etc/GMT+10'=>'(GMT-10:00) Hawaii', + 'Pacific/Marquesas'=>'(GMT-09:30) Marquesas Islands', + 'Pacific/Gambier'=>'(GMT-09:00) Gambier Islands', + 'America/Anchorage'=>'(GMT-09:00) Alaska', + 'America/Ensenada'=>'(GMT-08:00) Tijuana, Baja California', + 'Etc/GMT+8'=>'(GMT-08:00) Pitcairn Islands', + 'America/Los_Angeles'=>'(GMT-08:00) Pacific Time (US & Canada)', + 'America/Denver'=>'(GMT-07:00) Mountain Time (US & Canada)', + 'America/Chihuahua'=>'(GMT-07:00) Chihuahua, La Paz, Mazatlan', + 'America/Dawson_Creek'=>'(GMT-07:00) Arizona', + 'America/Belize'=>'(GMT-06:00) Saskatchewan, Central America', + 'America/Cancun'=>'(GMT-06:00) Guadalajara, Mexico City, Monterrey', + 'Chile/EasterIsland'=>'(GMT-06:00) Easter Island', + 'America/Chicago'=>'(GMT-06:00) Central Time (US & Canada)', + 'America/New_York'=>'(GMT-05:00) Eastern Time (US & Canada)', + 'America/Havana'=>'(GMT-05:00) Cuba', + 'America/Bogota'=>'(GMT-05:00) Bogota, Lima, Quito, Rio Branco', + 'America/Caracas'=>'(GMT-04:30) Caracas', + 'America/Santiago'=>'(GMT-04:00) Santiago', + 'America/La_Paz'=>'(GMT-04:00) La Paz', + 'Atlantic/Stanley'=>'(GMT-04:00) Faukland Islands', + 'America/Campo_Grande'=>'(GMT-04:00) Brazil', + 'America/Goose_Bay'=>'(GMT-04:00) Atlantic Time (Goose Bay)', + 'America/Glace_Bay'=>'(GMT-04:00) Atlantic Time (Canada)', + 'America/St_Johns'=>'(GMT-03:30) Newfoundland', + 'America/Araguaina'=>'(GMT-03:00) UTC-3', + 'America/Montevideo'=>'(GMT-03:00) Montevideo', + 'America/Miquelon'=>'(GMT-03:00) Miquelon, St. Pierre', + 'America/Godthab'=>'(GMT-03:00) Greenland', + 'America/Argentina/Buenos_Aires'=>'(GMT-03:00) Buenos Aires', + 'America/Sao_Paulo'=>'(GMT-03:00) Brasilia', + 'America/Noronha'=>'(GMT-02:00) Mid-Atlantic', + 'Atlantic/Cape_Verde'=>'(GMT-01:00) Cape Verde Is.', + 'Atlantic/Azores'=>'(GMT-01:00) Azores', + 'Europe/Belfast'=>'(GMT) Greenwich Mean Time : Belfast', + 'Europe/Dublin'=>'(GMT) Greenwich Mean Time : Dublin', + 'Europe/Lisbon'=>'(GMT) Greenwich Mean Time : Lisbon', + 'Europe/London'=>'(GMT) Greenwich Mean Time : London', + 'Africa/Abidjan'=>'(GMT) Monrovia, Reykjavik', + 'Europe/Amsterdam'=>'(GMT+01:00) Amsterdam, Berlin, Bern, Rome, Stockholm, Vienna', + 'Europe/Belgrade'=>'(GMT+01:00) Belgrade, Bratislava, Budapest, Ljubljana, Prague', + 'Europe/Brussels'=>'(GMT+01:00) Brussels, Copenhagen, Madrid, Paris', + 'Africa/Algiers'=>'(GMT+01:00) West Central Africa', + 'Africa/Windhoek'=>'(GMT+01:00) Windhoek', + 'Asia/Beirut'=>'(GMT+02:00) Beirut', + 'Africa/Cairo'=>'(GMT+02:00) Cairo', + 'Asia/Gaza'=>'(GMT+02:00) Gaza', + 'Africa/Blantyre'=>'(GMT+02:00) Harare, Pretoria', + 'Asia/Jerusalem'=>'(GMT+02:00) Jerusalem', + 'Europe/Minsk'=>'(GMT+02:00) Minsk', + 'Asia/Damascus'=>'(GMT+02:00) Syria', + 'Europe/Moscow'=>'(GMT+03:00) Moscow, St. Petersburg, Volgograd', + 'Africa/Addis_Ababa'=>'(GMT+03:00) Nairobi', + 'Asia/Tehran'=>'(GMT+03:30) Tehran', + 'Asia/Dubai'=>'(GMT+04:00) Abu Dhabi, Muscat', + 'Asia/Yerevan'=>'(GMT+04:00) Yerevan', + 'Asia/Kabul'=>'(GMT+04:30) Kabul', + 'Asia/Baku'=>'(GMT+05:00) Baku',/*GARRISON ADDED 4/20/2013*/ + 'Asia/Yekaterinburg'=>'(GMT+05:00) Ekaterinburg', + 'Asia/Tashkent'=>'(GMT+05:00) Tashkent', + 'Asia/Kolkata'=>'(GMT+05:30) Chennai, Kolkata, Mumbai, New Delhi', + 'Asia/Katmandu'=>'(GMT+05:45) Kathmandu', + 'Asia/Dhaka'=>'(GMT+06:00) Astana, Dhaka', + 'Asia/Novosibirsk'=>'(GMT+06:00) Novosibirsk', + 'Asia/Rangoon'=>'(GMT+06:30) Yangon (Rangoon)', + 'Asia/Bangkok'=>'(GMT+07:00) Bangkok, Hanoi, Jakarta', + 'Asia/Krasnoyarsk'=>'(GMT+07:00) Krasnoyarsk', + 'Asia/Hong_Kong'=>'(GMT+08:00) Beijing, Chongqing, Hong Kong, Urumqi', + 'Asia/Irkutsk'=>'(GMT+08:00) Irkutsk, Ulaan Bataar', + 'Australia/Perth'=>'(GMT+08:00) Perth', + 'Australia/Eucla'=>'(GMT+08:45) Eucla', + 'Asia/Tokyo'=>'(GMT+09:00) Osaka, Sapporo, Tokyo', + 'Asia/Seoul'=>'(GMT+09:00) Seoul', + 'Asia/Yakutsk'=>'(GMT+09:00) Yakutsk', + 'Australia/Adelaide'=>'(GMT+09:30) Adelaide', + 'Australia/Darwin'=>'(GMT+09:30) Darwin', + 'Australia/Brisbane'=>'(GMT+10:00) Brisbane', + 'Australia/Hobart'=>'(GMT+10:00) Hobart', + 'Asia/Vladivostok'=>'(GMT+10:00) Vladivostok', + 'Australia/Lord_Howe'=>'(GMT+10:30) Lord Howe Island', + 'Etc/GMT-11'=>'(GMT+11:00) Solomon Is., New Caledonia', + 'Asia/Magadan'=>'(GMT+11:00) Magadan', + 'Pacific/Norfolk'=>'(GMT+11:30) Norfolk Island', + 'Asia/Anadyr'=>'(GMT+12:00) Anadyr, Kamchatka', + 'Pacific/Auckland'=>'(GMT+12:00) Auckland, Wellington', + 'Etc/GMT-12'=>'(GMT+12:00) Fiji, Kamchatka, Marshall Is.', + 'Pacific/Chatham'=>'(GMT+12:45) Chatham Islands', + 'Pacific/Tongatapu'=>'(GMT+13:00) Nuku\'alofa', + 'Pacific/Kiritimati'=>'(GMT+14:00) Kiritimati' + ), $this->config->item('timezone') ? $this->config->item('timezone') : date_default_timezone_get()); + ?> +
    +
    + +
    +lang->line('config_print_after_sale').':', 'print_after_sale',array('class'=>'wide')); ?> +
    + 'print_after_sale', + 'id'=>'print_after_sale', + 'value'=>'print_after_sale', + 'checked'=>$this->config->item('print_after_sale')));?> +
    +
    + +
    +lang->line('config_custom1').':', 'website',array('class'=>'wide')); ?> +
    + 'custom1_name', + 'id'=>'custom1_name', + 'value'=>$this->config->item('custom1_name')));?> +
    +
    + +
    +lang->line('config_custom2').':', 'website',array('class'=>'wide')); ?> +
    + 'custom2_name', + 'id'=>'custom2_name', + 'value'=>$this->config->item('custom2_name')));?> +
    +
    + +
    +lang->line('config_custom3').':', 'website',array('class'=>'wide')); ?> +
    + 'custom3_name', + 'id'=>'custom3_name', + 'value'=>$this->config->item('custom3_name')));?> +
    +
    + +
    +lang->line('config_custom4').':', 'website',array('class'=>'wide')); ?> +
    + 'custom4_name', + 'id'=>'custom4_name', + 'value'=>$this->config->item('custom4_name')));?> +
    +
    + +
    +lang->line('config_custom5').':', 'website',array('class'=>'wide')); ?> +
    + 'custom5_name', + 'id'=>'custom5_name', + 'value'=>$this->config->item('custom5_name')));?> +
    +
    + +
    +lang->line('config_custom6').':', 'website',array('class'=>'wide')); ?> +
    + 'custom6_name', + 'id'=>'custom6_name', + 'value'=>$this->config->item('custom6_name')));?> +
    +
    + +
    +lang->line('config_custom7').':', 'website',array('class'=>'wide')); ?> +
    + 'custom7_name', + 'id'=>'custom7_name', + 'value'=>$this->config->item('custom7_name')));?> +
    +
    + +
    +lang->line('config_custom8').':', 'website',array('class'=>'wide')); ?> +
    + 'custom8_name', + 'id'=>'custom8_name', + 'value'=>$this->config->item('custom8_name')));?> +
    +
    + +
    +lang->line('config_custom9').':', 'website',array('class'=>'wide')); ?> +
    + 'custom9_name', + 'id'=>'custom9_name', + 'value'=>$this->config->item('custom9_name')));?> +
    +
    + +
    +lang->line('config_custom10').':', 'website',array('class'=>'wide')); ?> +
    + 'custom10_name', + 'id'=>'custom10_name', + 'value'=>$this->config->item('custom10_name')));?> +
    +
    + +'submit', + 'id'=>'submit', + 'value'=>$this->lang->line('common_submit'), + 'class'=>'submit_button float_right') +); +?> +
    +
    + +
    + +load->view("partial/footer"); ?> diff --git a/application/views/customers/excel_import.php b/application/views/customers/excel_import.php new file mode 100644 index 000000000..d46c54a2d --- /dev/null +++ b/application/views/customers/excel_import.php @@ -0,0 +1,63 @@ +'item_form')); +?> +
    Import customers from Excel sheet
    +
      +Download Import Excel Template (CSV) +
      +Import + +
      +'wide')); ?> +
      + 'file_path', + 'id'=>'file_path', + 'value'=>'') + );?> +
      +
      + +'submitf', + 'id'=>'submitf', + 'value'=>$this->lang->line('common_submit'), + 'class'=>'submit_button float_right') +); +?> +
      + + \ No newline at end of file diff --git a/application/views/customers/form.php b/application/views/customers/form.php new file mode 100644 index 000000000..2a1906a7a --- /dev/null +++ b/application/views/customers/form.php @@ -0,0 +1,73 @@ +person_id,array('id'=>'customer_form')); +?> +
      lang->line('common_fields_required_message'); ?>
      +
        +
        +lang->line("customers_basic_information"); ?> +load->view("people/form_basic_info"); ?> +
        +lang->line('customers_account_number').':', 'account_number'); ?> +
        + 'account_number', + 'id'=>'account_number', + 'value'=>$person_info->account_number) + );?> +
        +
        + +
        +lang->line('customers_taxable').':', 'taxable'); ?> +
        + taxable == '' ? TRUE : (boolean)$person_info->taxable);?> +
        +
        + +'submit', + 'id'=>'submit', + 'value'=>$this->lang->line('common_submit'), + 'class'=>'submit_button float_right') +); +?> +
        + + \ No newline at end of file diff --git a/application/views/employees/form.php b/application/views/employees/form.php new file mode 100644 index 000000000..389c04612 --- /dev/null +++ b/application/views/employees/form.php @@ -0,0 +1,158 @@ +person_id,array('id'=>'employee_form')); +?> +
        lang->line('common_fields_required_message'); ?>
        +
          +
          +lang->line("employees_basic_information"); ?> +load->view("people/form_basic_info"); ?> +
          + +
          +lang->line("employees_login_info"); ?> +
          +lang->line('employees_username').':', 'username',array('class'=>'required')); ?> +
          + 'username', + 'id'=>'username', + 'value'=>$person_info->username));?> +
          +
          + +person_id == "" ? array('class'=>'required'):array(); +?> + +
          +lang->line('employees_password').':', 'password',$password_label_attributes); ?> +
          + 'password', + 'id'=>'password' + ));?> +
          +
          + + +
          +lang->line('employees_repeat_password').':', 'repeat_password',$password_label_attributes); ?> +
          + 'repeat_password', + 'id'=>'repeat_password' + ));?> +
          +
          +
          + +
          +lang->line("employees_permission_info"); ?> +

          lang->line("employees_permission_desc"); ?>

          + +
            +result() as $module) +{ +?> +
          • +module_id,$this->Employee->has_permission($module->module_id,$person_info->person_id)); ?> +lang->line('module_'.$module->module_id);?>: +lang->line('module_'.$module->module_id.'_desc');?> +
          • + +
          +'submit', + 'id'=>'submit', + 'value'=>$this->lang->line('common_submit'), + 'class'=>'submit_button float_right') +); + +?> +
          + + \ No newline at end of file diff --git a/application/views/giftcards/form.php b/application/views/giftcards/form.php new file mode 100644 index 000000000..8aac50422 --- /dev/null +++ b/application/views/giftcards/form.php @@ -0,0 +1,108 @@ +
          lang->line('common_fields_required_message'); ?>
          +
            +giftcard_id,array('id'=>'giftcard_form')); +?> +
            +lang->line("giftcards_basic_information"); ?> + + +
            +lang->line('giftcards_person_id').':', 'name',array('class'=>'required wide')); ?> +
            + 'person_id', + 'id'=>'person_id', + 'value'=>$giftcard_info->person_id) + );?> +
            +
            + + +
            +lang->line('giftcards_giftcard_number').':', 'name',array('class'=>'required wide')); ?> +
            + 'giftcard_number', + 'id'=>'giftcard_number', + 'value'=>$giftcard_info->giftcard_number) + );?> +
            +
            + +
            +lang->line('giftcards_card_value').':', 'name',array('class'=>'required wide')); ?> +
            + 'value', + 'id'=>'value', + 'value'=>$giftcard_info->value) + );?> +
            +
            + +'submit', + 'id'=>'submit', + 'value'=>$this->lang->line('common_submit'), + 'class'=>'submit_button float_right') +); +?> +
            + + \ No newline at end of file diff --git a/application/views/giftcards/manage.php b/application/views/giftcards/manage.php new file mode 100644 index 000000000..0a3d49fe8 --- /dev/null +++ b/application/views/giftcards/manage.php @@ -0,0 +1,86 @@ +load->view("partial/header"); ?> + + +
            +
            lang->line('common_list_of').' '.$this->lang->line('module_'.$controller_name); ?>
            +
            + ".$this->lang->line($controller_name.'_new')."
            ", + array('class'=>'thickbox none','title'=>$this->lang->line($controller_name.'_new'))); + ?> +
            + +pagination->create_links();?> +
            +
              +
            • lang->line("common_delete"),array('id'=>'delete')); ?>
            • +
            • + spinner + 'search_form')); ?> + + +
            • +
            +
            + +
            + +
            +
            +load->view("partial/footer"); ?> \ No newline at end of file diff --git a/application/views/home.php b/application/views/home.php new file mode 100644 index 000000000..caaccb417 --- /dev/null +++ b/application/views/home.php @@ -0,0 +1,19 @@ +load->view("partial/header"); ?> +
            +

            lang->line('common_welcome_message'); ?>

            +
            + result() as $module) + { + ?> +
            + module_id");?>"> + Menubar Image
            + module_id");?>">lang->line("module_".$module->module_id) ?> + - lang->line('module_'.$module->module_id.'_desc');?> +
            + +
            +load->view("partial/footer"); ?> \ No newline at end of file diff --git a/application/views/index.html b/application/views/index.html new file mode 100644 index 000000000..c942a79ce --- /dev/null +++ b/application/views/index.html @@ -0,0 +1,10 @@ + + + 403 Forbidden + + + +

            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 @@ +
            lang->line('common_fields_required_message'); ?>
            +
              +item_kit_id,array('id'=>'item_kit_form')); +?> +
              +lang->line("item_kits_info"); ?> + +
              +lang->line('item_kits_name').':', 'name',array('class'=>'wide required')); ?> +
              + 'name', + 'id'=>'name', + 'value'=>$item_kit_info->name) + );?> +
              +
              + +
              +lang->line('item_kits_description').':', 'description',array('class'=>'wide')); ?> +
              + 'description', + 'id'=>'description', + 'value'=>$item_kit_info->description, + 'rows'=>'5', + 'cols'=>'17') + );?> +
              +
              + + +
              +lang->line('item_kits_add_item').':', 'item',array('class'=>'wide')); ?> +
              + 'item', + 'id'=>'item' + ));?> +
              +
              + + + + + + + + + Item_kit_items->get_info($item_kit_info->item_kit_id) as $item_kit_item) {?> + + Item->get_info($item_kit_item['item_id']); + ?> + + + + + +
              lang->line('common_delete');?>lang->line('item_kits_item');?>lang->line('item_kits_quantity');?>
              Xname; ?>' type='text' size='3' name=item_kit_item[] value=''/>
              +'submit', + 'id'=>'submit', + 'value'=>$this->lang->line('common_submit'), + 'class'=>'submit_button float_right') +); +?> +
              + + \ No newline at end of file diff --git a/application/views/item_kits/manage.php b/application/views/item_kits/manage.php new file mode 100644 index 000000000..5c27ffc8b --- /dev/null +++ b/application/views/item_kits/manage.php @@ -0,0 +1,99 @@ +load->view("partial/header"); ?> + + +
              +
              lang->line('common_list_of').' '.$this->lang->line('module_'.$controller_name); ?>
              +
              + ".$this->lang->line($controller_name.'_new')."
              ", + array('class'=>'thickbox none','title'=>$this->lang->line($controller_name.'_new'))); + ?> +
              + + +pagination->create_links();?> +
              +
                +
              • lang->line("common_delete"),array('id'=>'delete')); ?>
              • +
              • lang->line("items_generate_barcodes"),array('id'=>'generate_barcodes', 'target' =>'_blank','title'=>$this->lang->line('items_generate_barcodes'))); ?>
              • +
              • + spinner + 'search_form')); ?> + + +
              • +
              +
              + +
              + +
              +
              +load->view("partial/footer"); ?> \ No newline at end of file diff --git a/application/views/items/count_details.php b/application/views/items/count_details.php new file mode 100644 index 000000000..22b48115c --- /dev/null +++ b/application/views/items/count_details.php @@ -0,0 +1,114 @@ +item_id,array('id'=>'item_form')); +?> +
              +lang->line("items_basic_information"); ?> + + +
              +
              + + + + + + + + + + + + + + + + +
              +lang->line('items_item_number').':', 'name',array('class'=>'wide')); ?> + + 'item_number', + 'id'=>'item_number', + 'value'=>$item_info->item_number, + 'style' => 'border:none', + 'readonly' => 'readonly' + ); + + echo form_input($inumber) + ?> +
              +lang->line('items_name').':', 'name',array('class'=>'wide')); ?> + + 'name', + 'id'=>'name', + 'value'=>$item_info->name, + 'style' => 'border:none', + 'readonly' => 'readonly' + ); + echo form_input($iname); + ?> +
              +lang->line('items_category').':', 'category',array('class'=>'wide')); ?> + + 'category', + 'id'=>'category', + 'value'=>$item_info->category, + 'style' => 'border:none', + 'readonly' => 'readonly' + ); + + echo form_input($cat); + ?> +
              +lang->line('items_current_quantity').':', 'quantity',array('class'=>'wide')); ?> + + 'quantity', + 'id'=>'quantity', + 'value'=>$item_info->quantity, + 'style' => 'border:none', + 'readonly' => 'readonly' + ); + + echo form_input($qty); + ?> +
              + +
              +
              +
              + +
              +
              +
              +
              + + + + +Inventory->get_inventory_data_for_item($item_info->item_id)->result_array() as $row) +{ +?> + + + + + + + + +
              Inventory Data Tracking
              DateEmployeeIn/Out QtyRemarks
              Employee->get_info($person_id); + echo $employee->first_name." ".$employee->last_name; + ?> +
              \ No newline at end of file diff --git a/application/views/items/excel_import.php b/application/views/items/excel_import.php new file mode 100644 index 000000000..2816cd04d --- /dev/null +++ b/application/views/items/excel_import.php @@ -0,0 +1,63 @@ +'item_form')); +?> +
              Import items from Excel sheet
              +
                +Download Import Excel Template (CSV) +
                +Import + +
                +'wide')); ?> +
                + 'file_path', + 'id'=>'file_path', + 'value'=>'') + );?> +
                +
                + +'submitf', + 'id'=>'submitf', + 'value'=>$this->lang->line('common_submit'), + 'class'=>'submit_button float_right') +); +?> +
                + + \ No newline at end of file diff --git a/application/views/items/form.php b/application/views/items/form.php new file mode 100644 index 000000000..1b7f452b2 --- /dev/null +++ b/application/views/items/form.php @@ -0,0 +1,491 @@ +
                lang->line('common_fields_required_message'); ?>
                +
                  +item_id,array('id'=>'item_form')); +?> +
                  +lang->line("items_basic_information"); ?> + +
                  +lang->line('items_item_number').':', 'name',array('class'=>'wide')); ?> +
                  + 'item_number', + 'id'=>'item_number', + 'value'=>$item_info->item_number) + );?> +
                  +
                  + +
                  +lang->line('items_name').':', 'name',array('class'=>'required wide')); ?> +
                  + 'name', + 'id'=>'name', + 'value'=>$item_info->name) + );?> +
                  +
                  + +
                  +lang->line('items_category').':', 'category',array('class'=>'required wide')); ?> +
                  + 'category', + 'id'=>'category', + 'value'=>$item_info->category) + );?> +
                  +
                  + +
                  +lang->line('items_supplier').':', 'supplier',array('class'=>'required wide')); ?> +
                  + +
                  +
                  + +
                  +lang->line('items_cost_price').':', 'cost_price',array('class'=>'required wide')); ?> +
                  + 'cost_price', + 'size'=>'8', + 'id'=>'cost_price', + 'value'=>$item_info->cost_price) + );?> +
                  +
                  + +
                  +lang->line('items_unit_price').':', 'unit_price',array('class'=>'required wide')); ?> +
                  + 'unit_price', + 'size'=>'8', + 'id'=>'unit_price', + 'value'=>$item_info->unit_price) + );?> +
                  +
                  + +
                  +lang->line('items_tax_1').':', 'tax_percent_1',array('class'=>'wide')); ?> +
                  + 'tax_names[]', + 'id'=>'tax_name_1', + 'size'=>'8', + 'value'=> isset($item_tax_info[0]['name']) ? $item_tax_info[0]['name'] : $this->config->item('default_tax_1_name')) + );?> +
                  +
                  + 'tax_percents[]', + 'id'=>'tax_percent_name_1', + 'size'=>'3', + 'value'=> isset($item_tax_info[0]['percent']) ? $item_tax_info[0]['percent'] : $default_tax_1_rate) + );?> + % +
                  +
                  + +
                  +lang->line('items_tax_2').':', 'tax_percent_2',array('class'=>'wide')); ?> +
                  + 'tax_names[]', + 'id'=>'tax_name_2', + 'size'=>'8', + 'value'=> isset($item_tax_info[1]['name']) ? $item_tax_info[1]['name'] : $this->config->item('default_tax_2_name')) + );?> +
                  +
                  + 'tax_percents[]', + 'id'=>'tax_percent_name_2', + 'size'=>'3', + 'value'=> isset($item_tax_info[1]['percent']) ? $item_tax_info[1]['percent'] : $default_tax_2_rate) + );?> + % +
                  +
                  + + +
                  +lang->line('items_quantity').':', 'quantity',array('class'=>'required wide')); ?> +
                  + 'quantity', + 'id'=>'quantity', + 'value'=>$item_info->quantity) + );?> +
                  +
                  + +
                  +lang->line('items_reorder_level').':', 'reorder_level',array('class'=>'required wide')); ?> +
                  + 'reorder_level', + 'id'=>'reorder_level', + 'value'=>$item_info->reorder_level) + );?> +
                  +
                  + +
                  +lang->line('items_location').':', 'location',array('class'=>'wide')); ?> +
                  + 'location', + 'id'=>'location', + 'value'=>$item_info->location) + );?> +
                  +
                  + +
                  +lang->line('items_description').':', 'description',array('class'=>'wide')); ?> +
                  + 'description', + 'id'=>'description', + 'value'=>$item_info->description, + 'rows'=>'5', + 'cols'=>'17') + );?> +
                  +
                  + +
                  +lang->line('items_allow_alt_desciption').':', 'allow_alt_description',array('class'=>'wide')); ?> +
                  + 'allow_alt_description', + 'id'=>'allow_alt_description', + 'value'=>1, + 'checked'=>($item_info->allow_alt_description)? 1 :0) + );?> +
                  +
                  + +
                  +lang->line('items_is_serialized').':', 'is_serialized',array('class'=>'wide')); ?> +
                  + 'is_serialized', + 'id'=>'is_serialized', + 'value'=>1, + 'checked'=>($item_info->is_serialized)? 1 : 0) + );?> +
                  +
                  + + +
                  +config->item('custom1_name') != NULL) +{ + echo form_label($this->config->item('custom1_name').':', 'custom1',array('class'=>'wide')); ?> +
                  + 'custom1', + 'id'=>'custom1', + 'value'=>$item_info->custom1) + );?> +
                  +
                  + + +
                  +config->item('custom2_name') != NULL) +{ + echo form_label($this->config->item('custom2_name').':', 'custom2',array('class'=>'wide')); ?> +
                  + 'custom2', + 'id'=>'custom2', + 'value'=>$item_info->custom2) + );?> +
                  +
                  + + +
                  +config->item('custom3_name') != NULL) +{ + echo form_label($this->config->item('custom3_name').':', 'custom3',array('class'=>'wide')); ?> +
                  + 'custom3', + 'id'=>'custom3', + 'value'=>$item_info->custom3) + );?> +
                  +
                  + + +
                  +config->item('custom4_name') != NULL) +{ + echo form_label($this->config->item('custom4_name').':', 'custom4',array('class'=>'wide')); ?> +
                  + 'custom4', + 'id'=>'custom4', + 'value'=>$item_info->custom4) + );?> +
                  +
                  + + +
                  +config->item('custom5_name') != NULL) +{ + echo form_label($this->config->item('custom5_name').':', 'custom5',array('class'=>'wide')); ?> +
                  + 'custom5', + 'id'=>'custom5', + 'value'=>$item_info->custom5) + );?> +
                  +
                  + + +
                  +config->item('custom6_name') != NULL) +{ + echo form_label($this->config->item('custom6_name').':', 'custom6',array('class'=>'wide')); ?> +
                  + 'custom6', + 'id'=>'custom6', + 'value'=>$item_info->custom6) + );?> +
                  +
                  + + +
                  +config->item('custom7_name') != NULL) +{ + echo form_label($this->config->item('custom7_name').':', 'custom7',array('class'=>'wide')); ?> +
                  + 'custom7', + 'id'=>'custom7', + 'value'=>$item_info->custom7) + );?> +
                  +
                  + + +
                  +config->item('custom8_name') != NULL) +{ + echo form_label($this->config->item('custom8_name').':', 'custom8',array('class'=>'wide')); ?> +
                  + 'custom8', + 'id'=>'custom8', + 'value'=>$item_info->custom8) + );?> +
                  +
                  + + +
                  +config->item('custom9_name') != NULL) +{ + echo form_label($this->config->item('custom9_name').':', 'custom9',array('class'=>'wide')); ?> +
                  + 'custom9', + 'id'=>'custom9', + 'value'=>$item_info->custom9) + );?> +
                  +
                  + + +
                  +config->item('custom10_name') != NULL) +{ + echo form_label($this->config->item('custom10_name').':', 'custom10',array('class'=>'wide')); ?> +
                  + 'custom10', + 'id'=>'custom10', + 'value'=>$item_info->custom10) + );?> +
                  +
                  + + + + +'submit', + 'id'=>'submit', + 'value'=>$this->lang->line('common_submit'), + 'class'=>'submit_button float_right') +); +?> +
                  + + \ No newline at end of file diff --git a/application/views/items/form_bulk.php b/application/views/items/form_bulk.php new file mode 100644 index 000000000..5bfedc9b2 --- /dev/null +++ b/application/views/items/form_bulk.php @@ -0,0 +1,244 @@ +
                  lang->line('items_edit_fields_you_want_to_update'); ?>
                  +
                    +'item_form')); +?> +
                    +lang->line("items_basic_information"); ?> + +
                    +lang->line('items_name').':', 'name',array('class'=>'wide')); ?> +
                    + 'name', + 'id'=>'name') + );?> +
                    +
                    + +
                    +lang->line('items_category').':', 'category',array('class'=>'wide')); ?> +
                    + 'category', + 'id'=>'category') + );?> +
                    +
                    + +
                    +lang->line('items_supplier').':', 'supplier',array('class'=>'wide')); ?> +
                    + +
                    +
                    + + +
                    +lang->line('items_cost_price').':', 'cost_price',array('class'=>'wide')); ?> +
                    + 'cost_price', + 'size'=>'8', + 'id'=>'cost_price') + );?> +
                    +
                    + +
                    +lang->line('items_unit_price').':', 'unit_price',array('class'=>'wide')); ?> +
                    + 'unit_price', + 'size'=>'8', + 'id'=>'unit_price') + );?> +
                    +
                    + +
                    +lang->line('items_tax_1').':', 'tax_percent_1',array('class'=>'wide')); ?> +
                    + 'tax_names[]', + 'id'=>'tax_name_1', + 'size'=>'8', + 'value'=> isset($item_tax_info[0]['name']) ? $item_tax_info[0]['name'] : $this->lang->line('items_sales_tax')) + );?> +
                    +
                    + 'tax_percents[]', + 'id'=>'tax_percent_name_1', + 'size'=>'3', + 'value'=> isset($item_tax_info[0]['percent']) ? $item_tax_info[0]['percent'] : '') + );?> + % +
                    +
                    + +
                    +lang->line('items_tax_2').':', 'tax_percent_2',array('class'=>'wide')); ?> +
                    + 'tax_names[]', + 'id'=>'tax_name_2', + 'size'=>'8', + 'value'=> isset($item_tax_info[1]['name']) ? $item_tax_info[1]['name'] : '') + );?> +
                    +
                    + 'tax_percents[]', + 'id'=>'tax_percent_name_2', + 'size'=>'3', + 'value'=> isset($item_tax_info[1]['percent']) ? $item_tax_info[1]['percent'] : '') + );?> + % +
                    +
                    +
                    +lang->line('items_reorder_level').':', 'reorder_level',array('class'=>'wide')); ?> +
                    + 'reorder_level', + 'id'=>'reorder_level') + );?> +
                    +
                    + +
                    +lang->line('items_location').':', 'location',array('class'=>'wide')); ?> +
                    + 'location', + 'id'=>'location') + );?> +
                    +
                    + +
                    +lang->line('items_description').':', 'description',array('class'=>'wide')); ?> +
                    + 'description', + 'id'=>'description', + 'rows'=>'5', + 'cols'=>'17') + );?> +
                    +
                    + +
                    + +lang->line('items_allow_alt_desciption').':', 'allow_alt_description',array('class'=>'wide')); ?> +
                    + + +
                    + +
                    + + + +
                    + +lang->line('items_is_serialized').':', 'is_serialized',array('class'=>'wide')); ?> +
                    + + +
                    + +
                    + +'submit', + 'id'=>'submit', + 'value'=>$this->lang->line('common_submit'), + 'class'=>'submit_button float_right') +); +?> +
                    + + \ No newline at end of file diff --git a/application/views/items/inventory.php b/application/views/items/inventory.php new file mode 100644 index 000000000..178c2d3b4 --- /dev/null +++ b/application/views/items/inventory.php @@ -0,0 +1,157 @@ +
                    lang->line('common_fields_required_message'); ?>
                    +
                      +item_id,array('id'=>'item_form')); +?> +
                      +lang->line("items_basic_information"); ?> + + +
                      +
                      + + + + + + + + + + + + + + + + +
                      +lang->line('items_item_number').':', 'name',array('class'=>'wide')); ?> + + 'item_number', + 'id'=>'item_number', + 'value'=>$item_info->item_number, + 'style' => 'border:none', + 'readonly' => 'readonly' + ); + + echo form_input($inumber) + ?> +
                      +lang->line('items_name').':', 'name',array('class'=>'wide')); ?> + + 'name', + 'id'=>'name', + 'value'=>$item_info->name, + 'style' => 'border:none', + 'readonly' => 'readonly' + ); + echo form_input($iname); + ?> +
                      +lang->line('items_category').':', 'category',array('class'=>'wide')); ?> + + 'category', + 'id'=>'category', + 'value'=>$item_info->category, + 'style' => 'border:none', + 'readonly' => 'readonly' + ); + + echo form_input($cat); + ?> +
                      +lang->line('items_current_quantity').':', 'quantity',array('class'=>'wide')); ?> + + 'quantity', + 'id'=>'quantity', + 'value'=>$item_info->quantity, + 'style' => 'border:none', + 'readonly' => 'readonly' + ); + + echo form_input($qty); + ?> +
                      + +
                      +lang->line('items_add_minus').':', 'quantity',array('class'=>'required wide')); ?> +
                      + 'newquantity', + 'id'=>'newquantity' + ) + );?> +
                      +
                      + +
                      +lang->line('items_inventory_comments').':', 'description',array('class'=>'wide')); ?> +
                      + 'trans_comment', + 'id'=>'trans_comment', + 'rows'=>'3', + 'cols'=>'17') + );?> +
                      +
                      +'submit', + 'id'=>'submit', + 'value'=>$this->lang->line('common_submit'), + 'class'=>'submit_button float_right') +); +?> +
                      + + \ No newline at end of file diff --git a/application/views/items/manage.php b/application/views/items/manage.php new file mode 100644 index 000000000..094c0702a --- /dev/null +++ b/application/views/items/manage.php @@ -0,0 +1,183 @@ +load->view("partial/header"); ?> + + +
                      +
                      lang->line('common_list_of').' '.$this->lang->line('module_'.$controller_name); ?>
                      +
                      + ".$this->lang->line($controller_name.'_new')."
                      ", + array('class'=>'thickbox none','title'=>$this->lang->line($controller_name.'_new'))); + ?> + Excel Import
                      ", + array('class'=>'thickbox none','title'=>'Import Items from Excel')); + ?> + + + +
                      +
                      Search Options :
                      + + +
                      + +
                      + 'items_filter_form')); ?> + lang->line('items_low_inventory_items').' '.':', 'low_inventory');?> + 'low_inventory','id'=>'low_inventory','value'=>1,'checked'=> isset($low_inventory)? ( ($low_inventory)? 1 : 0) : 0)).' | ';?> + lang->line('items_serialized_items').' '.':', 'is_serialized');?> + 'is_serialized','id'=>'is_serialized','value'=>1,'checked'=> isset($is_serialized)? ( ($is_serialized)? 1 : 0) : 0)).' | ';?> + lang->line('items_no_description_items').' '.':', 'no_description');?> + 'no_description','id'=>'no_description','value'=>1,'checked'=> isset($no_description)? ( ($no_description)? 1 : 0) : 0)).' | ';?> + lang->line('items_search_custom_items').' '.':', 'search_custom');//GARRISON ADDED 4/21/2013?> + 'search_custom','id'=>'search_custom','value'=>1,'checked'=> isset($search_custom)? ( ($search_custom)? 1 : 0) : 0)).' | ';//GARRISON ADDED 4/21/2013?> + + +
                      +pagination->create_links();?> +
                      +
                        +
                      • lang->line("common_delete"),array('id'=>'delete')); ?>
                      • +
                      • lang->line("items_bulk_edit"),array('id'=>'bulk_edit','title'=>$this->lang->line('items_edit_multiple_items'))); ?>
                      • +
                      • lang->line("items_generate_barcodes"),array('id'=>'generate_barcodes', 'target' =>'_blank','title'=>$this->lang->line('items_generate_barcodes'))); ?>
                      • +
                      • + spinner + 'search_form')); ?> + + +
                      • +
                      +
                      + +
                      + +
                      +
                      +load->view("partial/footer"); ?> \ No newline at end of file diff --git a/application/views/login.php b/application/views/login.php new file mode 100644 index 000000000..d0a782c79 --- /dev/null +++ b/application/views/login.php @@ -0,0 +1,52 @@ + + + + + + +Open Source Point Of Sale <?php echo $this->lang->line('login_login'); ?> + + + + +

                      Open Source Point Of Sale config->item('application_version'); ?>

                      + + +
                      + +
                      + lang->line('login_login'); ?> +
                      +
                      +
                      + lang->line('login_welcome_message'); ?> +
                      + +
                      lang->line('login_username'); ?>:
                      +
                      + 'username', + 'size'=>'20')); ?> +
                      + +
                      lang->line('login_password'); ?>:
                      +
                      + 'password', + 'size'=>'20')); ?> + +
                      + +
                      + +
                      +
                      +
                      + + + diff --git a/application/views/no_access.php b/application/views/no_access.php new file mode 100644 index 000000000..bd0db7601 --- /dev/null +++ b/application/views/no_access.php @@ -0,0 +1,3 @@ +lang->line('error_no_permission_module').' '.$module_name; +?> \ No newline at end of file diff --git a/application/views/partial/footer.php b/application/views/partial/footer.php new file mode 100644 index 000000000..fe1c50460 --- /dev/null +++ b/application/views/partial/footer.php @@ -0,0 +1,6 @@ + + + + + \ No newline at end of file diff --git a/application/views/partial/footer_excel.php b/application/views/partial/footer_excel.php new file mode 100644 index 000000000..69fb64a9b --- /dev/null +++ b/application/views/partial/footer_excel.php @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/application/views/partial/header.php b/application/views/partial/header.php new file mode 100644 index 000000000..722c5ac8a --- /dev/null +++ b/application/views/partial/header.php @@ -0,0 +1,70 @@ + + + + + + <?php echo $this->config->item('company').' -- '.$this->lang->line('common_powered_by').' Open Source Point Of Sale' ?> + + + + + + + + + + + + + + + + + + + + + + + + + +
                      +
                      diff --git a/application/views/partial/header_excel.php b/application/views/partial/header_excel.php new file mode 100644 index 000000000..c60a36c20 --- /dev/null +++ b/application/views/partial/header_excel.php @@ -0,0 +1,54 @@ + + + + + <?php echo $this->config->item('company').' -- '.$this->lang->line('common_powered_by').' Open Source Point Of Sale' ?> + + + diff --git a/application/views/people/form_basic_info.php b/application/views/people/form_basic_info.php new file mode 100644 index 000000000..3e36f4889 --- /dev/null +++ b/application/views/people/form_basic_info.php @@ -0,0 +1,114 @@ +
                      +lang->line('common_first_name').':', 'first_name',array('class'=>'required')); ?> +
                      + 'first_name', + 'id'=>'first_name', + 'value'=>$person_info->first_name) + );?> +
                      +
                      +
                      +lang->line('common_last_name').':', 'last_name',array('class'=>'required')); ?> +
                      + 'last_name', + 'id'=>'last_name', + 'value'=>$person_info->last_name) + );?> +
                      +
                      + +
                      +lang->line('common_email').':', 'email'); ?> +
                      + 'email', + 'id'=>'email', + 'value'=>$person_info->email) + );?> +
                      +
                      + +
                      +lang->line('common_phone_number').':', 'phone_number'); ?> +
                      + 'phone_number', + 'id'=>'phone_number', + 'value'=>$person_info->phone_number));?> +
                      +
                      + +
                      +lang->line('common_address_1').':', 'address_1'); ?> +
                      + 'address_1', + 'id'=>'address_1', + 'value'=>$person_info->address_1));?> +
                      +
                      + +
                      +lang->line('common_address_2').':', 'address_2'); ?> +
                      + 'address_2', + 'id'=>'address_2', + 'value'=>$person_info->address_2));?> +
                      +
                      + +
                      +lang->line('common_city').':', 'city'); ?> +
                      + 'city', + 'id'=>'city', + 'value'=>$person_info->city));?> +
                      +
                      + +
                      +lang->line('common_state').':', 'state'); ?> +
                      + 'state', + 'id'=>'state', + 'value'=>$person_info->state));?> +
                      +
                      + +
                      +lang->line('common_zip').':', 'zip'); ?> +
                      + 'zip', + 'id'=>'zip', + 'value'=>$person_info->zip));?> +
                      +
                      + +
                      +lang->line('common_country').':', 'country'); ?> +
                      + 'country', + 'id'=>'country', + 'value'=>$person_info->country));?> +
                      +
                      + +
                      +lang->line('common_comments').':', 'comments'); ?> +
                      + 'comments', + 'id'=>'comments', + 'value'=>$person_info->comments, + 'rows'=>'5', + 'cols'=>'17') + );?> +
                      +
                      \ No newline at end of file diff --git a/application/views/people/manage.php b/application/views/people/manage.php new file mode 100644 index 000000000..8679a7c7a --- /dev/null +++ b/application/views/people/manage.php @@ -0,0 +1,91 @@ +load->view("partial/header"); ?> + + +
                      +
                      lang->line('common_list_of').' '.$this->lang->line('module_'.$controller_name); ?>
                      +
                      + ".$this->lang->line($controller_name.'_new')."
                      ", + array('class'=>'thickbox none','title'=>$this->lang->line($controller_name.'_new'))); + ?> + + Excel Import
                      ", + array('class'=>'thickbox none','title'=>'Import Items from Excel')); + ?> + +
                      +
                      +pagination->create_links();?> +
                      + +
                      +
                      + +
                      +
                      +load->view("partial/footer"); ?> \ No newline at end of file diff --git a/application/views/receivings/receipt.php b/application/views/receivings/receipt.php new file mode 100644 index 000000000..8efc5f307 --- /dev/null +++ b/application/views/receivings/receipt.php @@ -0,0 +1,104 @@ +load->view("partial/header"); ?> +'.$error_message.''; + exit; +} +?> +
                      +
                      +
                      config->item('company'); ?>
                      +
                      config->item('address')); ?>
                      +
                      config->item('phone'); ?>
                      +
                      +
                      +
                      +
                      + +
                      lang->line('suppliers_supplier').": ".$supplier; ?>
                      + +
                      lang->line('recvs_id').": ".$receiving_id; ?>
                      +
                      lang->line('employees_employee').": ".$employee; ?>
                      +
                      + + + + + + + + + + $item) + { + ?> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
                      lang->line('items_item'); ?>lang->line('common_price'); ?>lang->line('sales_quantity'); ?>lang->line('sales_discount'); ?>lang->line('sales_total'); ?>
                      lang->line('sales_total'); ?>
                      lang->line('sales_payment'); ?>
                      lang->line('sales_amount_tendered'); ?>
                      lang->line('sales_change_due'); ?>
                      + +
                      + config->item('return_policy')); ?> +
                      +
                      + "; ?> +
                      +
                      +load->view("partial/footer"); ?> + +Appconfig->get('print_after_sale')) +{ +?> + + \ No newline at end of file diff --git a/application/views/receivings/receiving.php b/application/views/receivings/receiving.php new file mode 100644 index 000000000..da4f19ae3 --- /dev/null +++ b/application/views/receivings/receiving.php @@ -0,0 +1,294 @@ +load->view("partial/header"); ?> + +
                      lang->line('recvs_register'); ?>
                      + +".$error.""; +} +?> + + + +
                      + 'mode_form')); ?> + lang->line('recvs_mode') ?> + + + 'add_item_form')); ?> + +'item','id'=>'item','size'=>'40'));?> +
                      + ".$this->lang->line('sales_new_item')."
                      ", + array('class'=>'thickbox none','title'=>$this->lang->line('sales_new_item'))); + ?> +
                      + + + + + + + + + + + + + + + + + + + + + +$item) + { + echo form_open("receivings/edit_item/$line"); + ?> + + + + + + + + + + + + + + + + + + +
                      lang->line('common_delete'); ?>lang->line('recvs_item_name'); ?>lang->line('recvs_cost'); ?>lang->line('recvs_quantity'); ?>lang->line('recvs_discount'); ?>lang->line('recvs_total'); ?>lang->line('recvs_edit'); ?>
                      +
                      lang->line('sales_no_items_in_cart'); ?>
                      +
                      lang->line('common_delete').']');?>
                      + + +
                      + + + +
                      'price','value'=>$item['price'],'size'=>'6'));?> + 'quantity','value'=>$item['quantity'],'size'=>'2')); + ?> + 'discount','value'=>$item['discount'],'size'=>'3'));?>lang->line('sales_edit_item'));?>
                      + + + + +
                      + lang->line("recvs_supplier").': '.$supplier. '
                      '; + echo anchor("receivings/delete_supplier",'['.$this->lang->line('common_delete').' '.$this->lang->line('suppliers_supplier').']'); + } + else + { + echo form_open("receivings/select_supplier",array('id'=>'select_supplier_form')); ?> + + 'supplier','id'=>'supplier','size'=>'30','value'=>$this->lang->line('recvs_start_typing_supplier_name')));?> + +
                      +

                      lang->line('common_or'); ?>

                      + ".$this->lang->line('recvs_new_supplier')."
                      ", + array('class'=>'thickbox none','title'=>$this->lang->line('recvs_new_supplier'))); + ?> +
                      +
                       
                      + + +
                      +
                      lang->line('sales_total'); ?>:
                      +
                      +
                      + 0) + { + ?> +
                      + 'finish_sale_form')); ?> +
                      + + 'comment','value'=>'','rows'=>'4','cols'=>'23'));?> +

                      + + + + + + + +
                      + lang->line('sales_payment').': ';?> + + +
                      + lang->line('sales_amount_tendered').': ';?> + + 'amount_tendered','value'=>'','size'=>'10')); + ?> +
                      +
                      + ".$this->lang->line('recvs_complete_receiving')."
                      "; + ?> + + + + + 'cancel_sale_form')); ?> +
                      + Cancel +
                      + + + + + +
                       
                      + + +load->view("partial/footer"); ?> + + + \ No newline at end of file diff --git a/application/views/reports/date_input.php b/application/views/reports/date_input.php new file mode 100644 index 000000000..7e98c9bed --- /dev/null +++ b/application/views/reports/date_input.php @@ -0,0 +1,72 @@ +load->view("partial/header"); ?> +
                      lang->line('reports_report_input'); ?>
                      +".$error.""; +} +?> + lang->line('reports_date_range'), 'report_date_range_label', array('class'=>'required')); ?> +
                      + + +
                      + +
                      + + + + + - + + + +
                      + + lang->line('reports_sale_type'), 'reports_sale_type_label', array('class'=>'required')); ?> +
                      + $this->lang->line('reports_all'), 'sales' => $this->lang->line('reports_sales'), 'returns' => $this->lang->line('reports_returns')), 'all', 'id="sale_type"'); ?> +
                      +'generate_report', + 'id'=>'generate_report', + 'content'=>$this->lang->line('common_submit'), + 'class'=>'submit_button') +); +?> + +load->view("partial/footer"); ?> + + \ No newline at end of file diff --git a/application/views/reports/date_input_excel_export.php b/application/views/reports/date_input_excel_export.php new file mode 100644 index 000000000..188e26b79 --- /dev/null +++ b/application/views/reports/date_input_excel_export.php @@ -0,0 +1,83 @@ +load->view("partial/header"); ?> +
                      lang->line('reports_report_input'); ?>
                      +".$error.""; +} +?> + lang->line('reports_date_range'), 'report_date_range_label', array('class'=>'required')); ?> +
                      + + +
                      + +
                      + + + + + - + + + +
                      + + lang->line('reports_sale_type'), 'reports_sale_type_label', array('class'=>'required')); ?> +
                      + $this->lang->line('reports_all'), 'sales' => $this->lang->line('reports_sales'), 'returns' => $this->lang->line('reports_returns')), 'all', 'id="sale_type"'); ?> +
                      + +
                      + Export to Excel: Yes + No +
                      + +'generate_report', + 'id'=>'generate_report', + 'content'=>$this->lang->line('common_submit'), + 'class'=>'submit_button') +); +?> + +load->view("partial/footer"); ?> + + \ No newline at end of file diff --git a/application/views/reports/excel_export.php b/application/views/reports/excel_export.php new file mode 100644 index 000000000..ab628c26a --- /dev/null +++ b/application/views/reports/excel_export.php @@ -0,0 +1,39 @@ +load->view("partial/header"); ?> +
                      lang->line('reports_report_input'); ?>
                      +".$error.""; +} +?> +
                      + Export to Excel: Yes + No +
                      + +'generate_report', + 'id'=>'generate_report', + 'content'=>$this->lang->line('common_submit'), + 'class'=>'submit_button') +); +?> + +load->view("partial/footer"); ?> + + \ No newline at end of file diff --git a/application/views/reports/graphical.php b/application/views/reports/graphical.php new file mode 100644 index 000000000..3a89407ee --- /dev/null +++ b/application/views/reports/graphical.php @@ -0,0 +1,27 @@ +load->view("partial/header"); +?> +
                      +
                      +
                      + + + +
                      +
                      +
                      +
                      +
                      +$value) { ?> +
                      lang->line('reports_'.$name). ': '.to_currency($value); ?>
                      + +
                      +load->view("partial/footer"); +?> \ No newline at end of file diff --git a/application/views/reports/graphs/bar.php b/application/views/reports/graphs/bar.php new file mode 100644 index 000000000..c42baf1cf --- /dev/null +++ b/application/views/reports/graphs/bar.php @@ -0,0 +1,46 @@ +output->set_header("Cache-Control: no-store, no-cache, must-revalidate"); +$this->output->set_header("Pragma: public"); +$bar = new bar_filled( '#4386a1', '#577261' ); + +$bar_labels = array(); +$bar_values = array(); + +foreach($data as $label=>$value) +{ + $bar_labels[] = (string)$label; + $bar_values[] = (float)$value; +} + +$bar->set_values($bar_values); + +$chart = new open_flash_chart(); +$chart->set_title(new title($title)); +$x = new x_axis(); +$x->steps(1); +$x->set_labels_from_array($bar_labels); +$chart->set_x_axis( $x ); + +$y = new y_axis(); +$y->set_tick_length(7); +$y->set_range(0, (count($data) > 0 ? max($data) : 0) + 25, ((count($data) > 0 ? max($data) : 0)+25)/10); +$chart->set_y_axis( $y ); +$chart->set_bg_colour("#f3f3f3"); + +$chart->add_element($bar); + +if (isset($yaxis_label)) +{ + $y_legend = new y_legend($yaxis_label ); + $y_legend->set_style( '{font-size: 20px; color: #000000}' ); + $chart->set_y_legend( $y_legend ); +} + +if (isset($xaxis_label)) +{ + $x_legend = new x_legend($xaxis_label ); + $x_legend->set_style( '{font-size: 20px; color: #000000}' ); + $chart->set_x_legend( $x_legend ); +} +echo $chart->toPrettyString(); +?> \ No newline at end of file diff --git a/application/views/reports/graphs/hbar.php b/application/views/reports/graphs/hbar.php new file mode 100644 index 000000000..10463f5c4 --- /dev/null +++ b/application/views/reports/graphs/hbar.php @@ -0,0 +1,61 @@ +output->set_header("Cache-Control: no-store, no-cache, must-revalidate"); +$this->output->set_header("Pragma: public"); + +$title = new title($title); + +$hbar = new hbar( '#86BBEF' ); +$hbar->set_tooltip($this->lang->line('reports_revenue').': #val#' ); +$y_labels = array(); +$max_value = 0; +foreach($data as $label=>$value) +{ + if ($max_value < $value) + { + $max_value = $value; + } + $y_labels[] = (string)$label; + $hbar->append_value( new hbar_value(0,(float)$value) ); +} +$chart = new open_flash_chart(); +$chart->set_title( $title ); +$chart->add_element( $hbar ); + +$step_count = $max_value > 0 ? $max_value/10 : 1; +$x = new x_axis(); +$x->set_offset( false ); +$x->set_steps($max_value/10); + +$chart->set_x_axis( $x ); + +$y = new y_axis(); +$y->set_offset( true ); +$y->set_labels(array_reverse($y_labels)); +$chart->add_y_axis( $y ); + +if (isset($yaxis_label)) +{ + $y_legend = new y_legend($yaxis_label ); + $y_legend->set_style( '{font-size: 20px; color: #000000}' ); + $chart->set_y_legend( $y_legend ); +} + +if (isset($xaxis_label)) +{ + $x_legend = new x_legend($xaxis_label ); + $x_legend->set_style( '{font-size: 20px; color: #000000}' ); + $chart->set_x_legend( $x_legend ); +} + +$chart->set_bg_colour("#f3f3f3"); + +$tooltip = new tooltip(); +$tooltip->set_hover(); +$tooltip->set_stroke( 1 ); +$tooltip->set_colour( "#000000" ); +$tooltip->set_background_colour( "#ffffff" ); +$chart->set_tooltip( $tooltip ); + + +echo $chart->toPrettyString(); +?> \ No newline at end of file diff --git a/application/views/reports/graphs/line.php b/application/views/reports/graphs/line.php new file mode 100644 index 000000000..62fa570e6 --- /dev/null +++ b/application/views/reports/graphs/line.php @@ -0,0 +1,49 @@ +output->set_header("Cache-Control: no-store, no-cache, must-revalidate"); +$this->output->set_header("Pragma: public"); +$line_data = array(); +$labels = array(); +foreach($data as $label=>$value) +{ + $line_data[] = (float)$value; + $labels[] = (string)$label; +} + +$hol = new hollow_dot(); +$hol->size(3)->halo_size(1)->tooltip('#x_label#
                      #val#'); + +$line = new line(); +$line->set_default_dot_style($hol); +$line->set_values($line_data); + +$chart = new open_flash_chart(); +$chart->set_title(new title($title)); +$chart->add_element($line); + +$x = new x_axis(); +$x->steps(count($data) > 10 ? (int)(count($data)/4) : 1); +$x->set_labels_from_array($labels); +$chart->set_x_axis( $x ); + +$y = new y_axis(); +$y->set_tick_length(7); +$y->set_range(0, (count($data) > 0 ? max($data) : 0) + 25, ((count($data) > 0 ? max($data) : 0)+25)/10); +$chart->set_y_axis( $y ); +$chart->set_bg_colour("#f3f3f3"); + +if (isset($yaxis_label)) +{ + $y_legend = new y_legend($yaxis_label ); + $y_legend->set_style( '{font-size: 20px; color: #000000}' ); + $chart->set_y_legend( $y_legend ); +} + +if (isset($xaxis_label)) +{ + $x_legend = new x_legend($xaxis_label ); + $x_legend->set_style( '{font-size: 20px; color: #000000}' ); + $chart->set_x_legend( $x_legend ); +} + +echo $chart->toPrettyString(); +?> \ No newline at end of file diff --git a/application/views/reports/graphs/pie.php b/application/views/reports/graphs/pie.php new file mode 100644 index 000000000..fda94d8b6 --- /dev/null +++ b/application/views/reports/graphs/pie.php @@ -0,0 +1,25 @@ +output->set_header("Cache-Control: no-store, no-cache, must-revalidate"); +$this->output->set_header("Pragma: public"); +$title = new title($title); + +$pie = new pie(); +$pie->set_alpha(0.6); +$pie->set_start_angle( 35 ); +$pie->add_animation( new pie_fade() ); +$pie->set_tooltip( '#val# of #total#
                      #percent# of 100%' ); +$pie->set_colours(get_random_colors(count($data))); + +$pie_values = array(); +foreach($data as $label=>$value) +{ + $pie_values[] = new pie_value((float)$value, (string)$label); +} +$pie->set_values($pie_values); +$chart = new open_flash_chart(); +$chart->set_title( $title ); +$chart->set_bg_colour("#f3f3f3"); +$chart->add_element( $pie ); +$chart->x_axis = null; +echo $chart->toPrettyString(); +?> \ No newline at end of file diff --git a/application/views/reports/listing.php b/application/views/reports/listing.php new file mode 100644 index 000000000..44728e8c6 --- /dev/null +++ b/application/views/reports/listing.php @@ -0,0 +1,63 @@ + +load->view("partial/header"); ?> +
                      lang->line('reports_reports'); ?>
                      +"; +} +?> +load->view("partial/footer"); ?> + + diff --git a/application/views/reports/specific_input.php b/application/views/reports/specific_input.php new file mode 100644 index 000000000..7bb1710ac --- /dev/null +++ b/application/views/reports/specific_input.php @@ -0,0 +1,90 @@ +load->view("partial/header"); ?> +
                      lang->line('reports_report_input'); ?>
                      +".$error.""; +} +?> + lang->line('reports_date_range'), 'report_date_range_label', array('class'=>'required')); ?> +
                      + + +
                      + +
                      + + + + + - + + + +
                      + + 'required')); ?> + +
                      + +
                      + + lang->line('reports_sale_type'), 'reports_sale_type_label', array('class'=>'required')); ?> +
                      + $this->lang->line('reports_all'), 'sales' => $this->lang->line('reports_sales'), 'returns' => $this->lang->line('reports_returns')), 'all', 'id="sale_type"'); ?> +
                      + +
                      + Export to Excel: Yes + No +
                      + +'generate_report', + 'id'=>'generate_report', + 'content'=>$this->lang->line('common_submit'), + 'class'=>'submit_button') +); +?> + +load->view("partial/footer"); ?> + + \ No newline at end of file diff --git a/application/views/reports/tabular.php b/application/views/reports/tabular.php new file mode 100644 index 000000000..41643227b --- /dev/null +++ b/application/views/reports/tabular.php @@ -0,0 +1,70 @@ +load->view("partial/header_excel"); +}else{ + $this->load->view("partial/header"); +} +?> +
                      +
                      +
                      + + + + + + + + + + + + + + + + + +
                      +
                      +
                      +$value) { ?> +
                      lang->line('reports_'.$name). ': '.to_currency($value); ?>
                      + +
                      +load->view("partial/footer_excel"); + $content = ob_end_flush(); + + $filename = trim($filename); + $filename = str_replace(array(' ', '/', '\\'), '', $title); + $filename .= "_Export.xls"; + header('Content-type: application/ms-excel'); + header('Content-Disposition: attachment; filename='.$filename); + echo $content; + die(); + +}else{ + $this->load->view("partial/footer"); +?> + + + \ No newline at end of file diff --git a/application/views/reports/tabular_details.php b/application/views/reports/tabular_details.php new file mode 100644 index 000000000..133a749a4 --- /dev/null +++ b/application/views/reports/tabular_details.php @@ -0,0 +1,102 @@ +load->view("partial/header_excel"); +}else{ + $this->load->view("partial/header"); +} +?> +
                      +
                      +
                      + + + + + + + + + + + $row) { ?> + + + + + + + + + + + +
                      +
                      +
                      + + + + + + + + + + + + + + + + + + + +
                      + +
                      +
                      +
                      +$value) { ?> +
                      lang->line('reports_'.$name). ': '.to_currency($value); ?>
                      + +
                      +load->view("partial/footer_excel"); + $content = ob_end_flush(); + + $filename = trim($filename); + $filename = str_replace(array(' ', '/', '\\'), '', $title); + $filename .= "_Export.xls"; + header('Content-type: application/ms-excel'); + header('Content-Disposition: attachment; filename='.$filename); + echo $content; + die(); + +}else{ + $this->load->view("partial/footer"); +?> + + \ No newline at end of file diff --git a/application/views/sales/delete.php b/application/views/sales/delete.php new file mode 100644 index 000000000..56d182282 --- /dev/null +++ b/application/views/sales/delete.php @@ -0,0 +1,18 @@ +load->view("partial/header"); ?> +
                      + +

                      lang->line('sales_delete_successful'); ?>

                      + +

                      lang->line('sales_delete_unsuccessful'); ?>

                      + +
                      +load->view("partial/footer"); ?> \ No newline at end of file diff --git a/application/views/sales/edit.php b/application/views/sales/edit.php new file mode 100644 index 000000000..a93f7577f --- /dev/null +++ b/application/views/sales/edit.php @@ -0,0 +1,109 @@ +load->view("partial/header"); ?> +
                      +

                      lang->line('sales_edit_sale'); ?> POS

                      + + 'sales_edit_form')); ?> +
                        + +
                        + lang->line('sales_receipt').':', 'customer'); ?> +
                        + '_blank'));?> +
                        +
                        + +
                        + lang->line('sales_date').':', 'date'); ?> +
                        + 'date','value'=>date('m/d/Y', strtotime($sale_info['sale_time'])), 'id'=>'date'));?> +
                        +
                        + +
                        + lang->line('sales_customer').':', 'customer'); ?> +
                        + +
                        +
                        + +
                        + lang->line('sales_employee').':', 'employee'); ?> +
                        + +
                        +
                        + +
                        + lang->line('sales_comment').':', 'comment'); ?> +
                        + 'comment','value'=>$sale_info['comment'],'rows'=>'4','cols'=>'23', 'id'=>'comment'));?> +
                        +
                        + + 'submit', + 'id'=>'submit', + 'value'=>$this->lang->line('common_submit'), + 'class'=>'submit_button float_left') + ); + ?> + + 'sales_delete_form')); ?> + 'submit', + 'id'=>'submit', + 'value'=>$this->lang->line('sales_delete_entire_sale'), + 'class'=>'delete_button float_right') + ); + ?> + + +
                        +
                        +load->view("partial/footer"); ?> + + \ No newline at end of file diff --git a/application/views/sales/receipt.php b/application/views/sales/receipt.php new file mode 100644 index 000000000..6031cc643 --- /dev/null +++ b/application/views/sales/receipt.php @@ -0,0 +1,120 @@ +load->view("partial/header"); ?> +'.$error_message.''; + exit; +} +?> +
                        +
                        +
                        config->item('company'); ?>
                        +
                        config->item('address')); ?>
                        +
                        config->item('phone'); ?>
                        +
                        +
                        +
                        +
                        + +
                        lang->line('customers_customer').": ".$customer; ?>
                        + +
                        lang->line('sales_id').": ".$sale_id; ?>
                        +
                        lang->line('employees_employee').": ".$employee; ?>
                        +
                        + + + + + + + + + + + $item) + { + ?> + + + + + + + + + + + + + + + + + + + + + + $value) { ?> + + + + + + + + + + + + + + $payment) + { ?> + + + + + + + + + + + + + + +
                        lang->line('sales_item_number'); ?>lang->line('items_item'); ?>lang->line('common_price'); ?>lang->line('sales_quantity'); ?>lang->line('sales_discount'); ?>lang->line('sales_total'); ?>
                        lang->line('sales_sub_total'); ?>
                        :
                        lang->line('sales_total'); ?>
                         
                        lang->line('sales_payment'); ?>
                         
                        lang->line('sales_change_due'); ?>
                        + +
                        + config->item('return_policy')); ?> +
                        +
                        + "; ?> +
                        +
                        +load->view("partial/footer"); ?> + +Appconfig->get('print_after_sale')) +{ +?> + + \ No newline at end of file diff --git a/application/views/sales/receipt_email.php b/application/views/sales/receipt_email.php new file mode 100644 index 000000000..721fc976c --- /dev/null +++ b/application/views/sales/receipt_email.php @@ -0,0 +1,95 @@ +
                        +
                        +
                        config->item('company'); ?>
                        +
                        config->item('address')); ?>
                        +
                        config->item('phone'); ?>
                        +
                        +
                        +
                        +
                        + +
                        lang->line('customers_customer').": ".$customer; ?>
                        + +
                        lang->line('sales_id').": ".$sale_id; ?>
                        +
                        lang->line('employees_employee').": ".$employee; ?>
                        +
                        + + + + + + + + + + + $item) + { + ?> + + + + + + + + + + + + + + + + + + + + + + $value) { ?> + + + + + + + + + + + + + + $payment) + { ?> + + + + + + + + + + + + + + +
                        lang->line('sales_item_number'); ?>lang->line('items_item'); ?>lang->line('common_price'); ?>lang->line('sales_quantity'); ?>lang->line('sales_discount'); ?>lang->line('sales_total'); ?>
                        lang->line('sales_sub_total'); ?>
                        :
                        lang->line('sales_total'); ?>
                         
                        lang->line('sales_payment'); ?>
                         
                        lang->line('sales_change_due'); ?>
                        + +
                        + config->item('return_policy')); ?> +
                        +
                        \ No newline at end of file diff --git a/application/views/sales/register.php b/application/views/sales/register.php new file mode 100644 index 000000000..d206ede20 --- /dev/null +++ b/application/views/sales/register.php @@ -0,0 +1,493 @@ +load->view("partial/header"); ?> +
                        lang->line('sales_register'); ?>
                        +".$error.""; +} + +if (isset($warning)) +{ + echo "
                        ".$warning."
                        "; +} + +if (isset($success)) +{ + echo "
                        ".$success."
                        "; +} +?> +
                        +'mode_form')); ?> + lang->line('sales_mode') ?> + +
                        + ".$this->lang->line('sales_suspended_sales')."
                        ", + array('class'=>'thickbox none','title'=>$this->lang->line('sales_suspended_sales'))); + ?> +
                        + +'add_item_form')); ?> + +'item','id'=>'item','size'=>'40'));?> +
                        + ".$this->lang->line('sales_new_item')."
                        ", + array('class'=>'thickbox none','title'=>$this->lang->line('sales_new_item'))); + ?> + + + + + + + + + + + + + + + + + + + +$item) + { + $cur_item_info = $this->Item->get_info($item['item_id']); + echo form_open("sales/edit_item/$line"); + ?> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
                        lang->line('common_delete'); ?>lang->line('sales_item_number'); ?>lang->line('sales_item_name'); ?>lang->line('sales_price'); ?>lang->line('sales_quantity'); ?>lang->line('sales_discount'); ?>lang->line('sales_total'); ?>lang->line('sales_edit'); ?>
                        +
                        lang->line('sales_no_items_in_cart'); ?>
                        +
                        lang->line('common_delete').']');?>
                        [quantity; ?> in stock]
                        'price','value'=>$item['price'],'size'=>'6'));?> + 'quantity','value'=>$item['quantity'],'size'=>'2')); + } + ?> + 'discount','value'=>$item['discount'],'size'=>'3'));?>lang->line('sales_edit_item'));?>
                        lang->line('sales_description_abbrv').':';?> + + 'description','value'=>$item['description'],'size'=>'20')); + } + else + { + if ($item['description']!='') + { + echo $item['description']; + echo form_hidden('description',$item['description']); + } + else + { + echo 'None'; + echo form_hidden('description',''); + } + } + ?> +   + lang->line('sales_serial').':'; + } + ?> + + 'serialnumber','value'=>$item['serialnumber'],'size'=>'20')); + } + else + { + echo form_hidden('serialnumber', ''); + } + ?> +
                        + + + +
                        + lang->line("sales_customer").': '.$customer. '
                        '; + echo anchor("sales/remove_customer",'['.$this->lang->line('common_remove').' '.$this->lang->line('customers_customer').']'); + } + else + { + echo form_open("sales/select_customer",array('id'=>'select_customer_form')); ?> + + 'customer','id'=>'customer','size'=>'30','value'=>$this->lang->line('sales_start_typing_customer_name')));?> + +
                        +

                        lang->line('common_or'); ?>

                        + ".$this->lang->line('sales_new_customer')."
                        ", + array('class'=>'thickbox none','title'=>$this->lang->line('sales_new_customer'))); + ?> +
                        +
                         
                        + + +
                        +
                        lang->line('sales_sub_total'); ?>:
                        +
                        + + $value) { ?> +
                        :
                        +
                        + + +
                        lang->line('sales_total'); ?>:
                        +
                        +
                        + + + + + 0) + { + ?> + +
                        + 'cancel_sale_form')); ?> +
                        + lang->line('sales_cancel_sale'); ?> +
                        + +
                        +
                         
                        + 0) + { + ?> +
                        + 'finish_sale_form')); ?> + + 'comment', 'id' => 'comment', 'value'=>$comment,'rows'=>'4','cols'=>'23'));?> +

                        + + lang->line('sales_email_receipt'). ': '. form_checkbox(array( + 'name' => 'email_receipt', + 'id' => 'email_receipt', + 'value' => '1', + 'checked' => (boolean)$email_receipt, + )).'
                        ('.$customer_email.')
                        '; + } + + if ($payments_cover_total) + { + echo "
                        ".$this->lang->line('sales_complete_sale')."
                        "; + } + echo "
                        ".$this->lang->line('sales_suspend_sale')."
                        "; + ?> +
                        + + + + + + + + + + + + +
                        + +
                        + +
                        + + 'add_payment_form')); ?> + + + + + + + + + +
                        + lang->line('sales_payment').': ';?> + + +
                        + lang->line( 'sales_amount_tendered' ).': '; ?> + + 'amount_tendered', 'id'=>'amount_tendered', 'value'=>to_currency_no_money($amount_due), 'size'=>'10' ) ); ?> +
                        +
                        + lang->line('sales_add_payment'); ?> +
                        +
                        + + + 0) + { + ?> + + + + + + + + + + + + $payment) + { + echo form_open("sales/edit_payment/$payment_id",array('id'=>'edit_payment_form'.$payment_id)); + ?> + + + + + + + + + + + +
                        lang->line('common_delete'); ?>
                        lang->line('common_delete').']' ); ?>
                        +
                        + + + + +
                        + + + +
                         
                        + + +load->view("partial/footer"); ?> + + diff --git a/application/views/sales/suspended.php b/application/views/sales/suspended.php new file mode 100644 index 000000000..d84667cfe --- /dev/null +++ b/application/views/sales/suspended.php @@ -0,0 +1,46 @@ + + + + + + + + + + + + + + + + + + + + +
                        lang->line('sales_suspended_sale_id'); ?>lang->line('sales_date'); ?>lang->line('sales_customer'); ?>lang->line('sales_comments'); ?>lang->line('sales_unsuspend_and_delete'); ?>
                        + Customer->get_info($suspended_sale['customer_id']); + echo $customer->first_name. ' '. $customer->last_name; + } + else + { + ?> +   + + + +
                        \ No newline at end of file diff --git a/application/views/suppliers/form.php b/application/views/suppliers/form.php new file mode 100644 index 000000000..02ace852e --- /dev/null +++ b/application/views/suppliers/form.php @@ -0,0 +1,78 @@ +person_id,array('id'=>'supplier_form')); +?> +
                        lang->line('common_fields_required_message'); ?>
                        +
                          +
                          +lang->line("suppliers_basic_information"); ?> + +
                          +lang->line('suppliers_company_name').':', 'company_name', array('class'=>'required')); ?> +
                          + 'company_name', + 'id'=>'company_name_input', + 'value'=>$person_info->company_name) + );?> +
                          +
                          + +load->view("people/form_basic_info"); ?> +
                          +lang->line('suppliers_account_number').':', 'account_number'); ?> +
                          + 'account_number', + 'id'=>'account_number', + 'value'=>$person_info->account_number) + );?> +
                          +
                          +'submit', + 'id'=>'submit', + 'value'=>$this->lang->line('common_submit'), + 'class'=>'submit_button float_right') +); +?> +
                          + + \ No newline at end of file diff --git a/application/views/suppliers/manage.php b/application/views/suppliers/manage.php new file mode 100644 index 000000000..db3bb7d71 --- /dev/null +++ b/application/views/suppliers/manage.php @@ -0,0 +1,85 @@ +load->view("partial/header"); ?> + + +
                          +
                          lang->line('common_list_of').' '.$this->lang->line('module_'.$controller_name); ?>
                          +
                          + ".$this->lang->line($controller_name.'_new')."
                          ", + array('class'=>'thickbox none','title'=>$this->lang->line($controller_name.'_new'))); + ?> +
                          + +pagination->create_links();?> +
                          + +
                          +
                          + +
                          +
                          +load->view("partial/footer"); ?> \ No newline at end of file diff --git a/css/autocomplete.css b/css/autocomplete.css new file mode 100644 index 000000000..a062d0410 --- /dev/null +++ b/css/autocomplete.css @@ -0,0 +1,54 @@ +.ac_results +{ + padding: 0px; + border: 1px solid black; + background-color: white; + overflow: hidden; + z-index: 99999; +} + +.ac_results ul +{ + width: 100%; + list-style-position: outside; + list-style: none; + padding: 0; + margin: 0; +} + +.ac_results li +{ + margin: 0px; + padding: 2px 5px; + cursor: default; + display: block; + /* + if width will be 100% horizontal scrollbar will apear + when scroll mode will be used + */ + /*width: 100%;*/ + font: menu; + font-size: 12px; + /* + it is very important, if line-height not setted or setted + in relative units scroll will be broken in firefox + */ + line-height: 16px; + overflow: hidden; +} + +.ac_loading +{ + background: white url('../images/spinner_small.gif') right center no-repeat; +} + +.ac_odd +{ + background-color: #eee; +} + +.ac_over +{ + background-color: #0A246A; + color: white; +} diff --git a/css/datepicker.css b/css/datepicker.css new file mode 100644 index 000000000..2b2a12805 --- /dev/null +++ b/css/datepicker.css @@ -0,0 +1,153 @@ +table.jCalendar { + border: 1px solid #000; + background: #aaa; + border-collapse: separate; + border-spacing: 2px; +} +table.jCalendar th { + background: #333; + color: #fff; + font-weight: bold; + padding: 3px 5px; +} + +table.jCalendar td { + background: #ccc; + color: #000; + padding: 3px 5px; + text-align: center; +} +table.jCalendar td.other-month { + background: #ddd; + color: #aaa; +} +table.jCalendar td.today { + background: #666; + color: #fff; +} +table.jCalendar td.selected { + background: #f66; + color: #fff; +} +table.jCalendar td.selected.dp-hover { + background: #f33; + color: #fff; +} +table.jCalendar td.dp-hover, +table.jCalendar tr.activeWeekHover td { + background: #fff; + color: #000; +} +table.jCalendar tr.selectedWeek td { + background: #f66; + color: #fff; +} +table.jCalendar td.disabled, table.jCalendar td.disabled.dp-hover { + background: #bbb; + color: #888; +} +table.jCalendar td.unselectable, +table.jCalendar td.unselectable:hover, +table.jCalendar td.unselectable.dp-hover { + background: #bbb; + color: #888; +} + +/* For the popup */ + +/* NOTE - you will probably want to style a.dp-choose-date - see how I did it in demo.css */ + +div.dp-popup { + position: relative; + background: #ccc; + font-size: 10px; + font-family: arial, sans-serif; + padding: 2px; + width: 171px; + line-height: 1.2em; +} +div#dp-popup { + position: absolute; + z-index: 199; +} +div.dp-popup h2 { + font-size: 12px; + text-align: center; + margin: 2px 0; + padding: 0; +} +a#dp-close { + font-size: 11px; + padding: 4px 0; + text-align: center; + display: block; +} +a#dp-close:hover { + text-decoration: underline; +} +div.dp-popup a { + color: #000; + text-decoration: none; + padding: 3px 2px 0; +} +div.dp-popup div.dp-nav-prev { + position: absolute; + top: 2px; + left: 4px; + width: 100px; +} +div.dp-popup div.dp-nav-prev a { + float: left; +} +/* Opera needs the rules to be this specific otherwise it doesn't change the cursor back to pointer after you have disabled and re-enabled a link */ +div.dp-popup div.dp-nav-prev a, div.dp-popup div.dp-nav-next a { + cursor: pointer; +} +div.dp-popup div.dp-nav-prev a.disabled, div.dp-popup div.dp-nav-next a.disabled { + cursor: default; +} +div.dp-popup div.dp-nav-next { + position: absolute; + top: 2px; + right: 4px; + width: 100px; +} +div.dp-popup div.dp-nav-next a { + float: right; +} +div.dp-popup a.disabled { + cursor: default; + color: #aaa; +} +div.dp-popup td { + cursor: pointer; +} +div.dp-popup td.disabled { + cursor: default; +} + +/* located in demo.css and creates a little calendar icon + * instead of a text link for "Choose date" + */ +a.dp-choose-date { + float: left; + width: 16px; + height: 16px; + padding: 0; + margin: 0px 3px 0; + display: block; + text-indent: -2000px; + overflow: hidden; + background: url(../images/calendar.png) no-repeat; +} +a.dp-choose-date.dp-disabled { + background-position: 0 -20px; + cursor: default; +} +/* makes the input field shorter once the date picker code + * has run (to allow space for the calendar icon + */ +input.dp-applied { + width: 100px; + float: left; +} \ No newline at end of file diff --git a/css/editsale.css b/css/editsale.css new file mode 100644 index 000000000..2ba8f43a9 --- /dev/null +++ b/css/editsale.css @@ -0,0 +1,11 @@ +#edit_sale_wrapper +{ + margin: 0 auto; + padding-bottom: 50px; + width: 60%; +} + +#edit_sale_wrapper h1 +{ + text-align: center; +} \ No newline at end of file diff --git a/css/general.css b/css/general.css new file mode 100644 index 000000000..5d8373ba9 --- /dev/null +++ b/css/general.css @@ -0,0 +1,154 @@ +.field_row +{ + margin: 0 0 10px 0; +} + +.field_row label +{ + float:left; + width:100px; + text-align:left; + line-height:2.3; +} + +.field_row label.wide +{ + width:150px; +} + +label.required +{ + color:red; +} + +.form_field +{ + float:left; + padding: 3px; + background-color: #f2f2f2; +} + +.form_field input, .form_field textarea +{ + border: 1px solid #ccc; + padding: 4px; +} + +.submit_button +{ + padding: 5px; + color: #fff; + background-color: #0a6184; + border: 2px solid #ddd; +} + +.delete_button +{ + padding: 5px; + color: #fff; + background-color: #ea4729; + border: 2px solid #ddd; +} +.small_button +{ + position:relative; + width:95px; + height:30px; + background-image: url(../images/small_action_button.jpg); + background-repeat:no-repeat; + cursor:pointer; +} +.small_button span +{ + position:absolute; + width:100%; + top:30%; + left:0%; + color:#FFF; + font-size:11px; + font-weight:bold; + text-align:center; +} + +.float_left +{ + float:left; +} + +.float_right +{ + float:right; +} + +.big_button +{ + position:relative; + width:119px; + height:45px; + background-image: url(../images/big_action_button.jpg); + background-repeat:no-repeat; + cursor:pointer; +} + +.big_button span +{ + position:absolute; + width:100%; + top:35%; + color:#FFF; + font-size:13px; + font-weight:bold; + text-align:center; +} + + +.warning_message +{ + text-align:center; + background-color:#fffcdd; + border:1px solid #fff4aa; + font-weight:bold; +} + +.error_message +{ + text-align:center; + background-color:#f68383; + border:1px solid #da3232; + font-weight:bold; +} + +.warning_mesage +{ + text-align:center; + background-color:#FBEC5D; + border:1px solid #da3232; + font-weight:bold; +} + +.success_message +{ + text-align:center; + background-color:#e1ffdd; + border:1px solid #2ca71c; + font-weight:bold; +} + +input +{ + font-family:arial; + padding: 3px; +} + +.clearfix:after +{ + content: "."; + display: block; + clear: both; + visibility: hidden; + line-height: 0; + height: 0; +} +.clearfix { display: inline-block; } +html[xmlns] .clearfix { display: block; } +* html .clearfix { height: 1%; } diff --git a/css/login.css b/css/login.css new file mode 100644 index 000000000..30809f1cf --- /dev/null +++ b/css/login.css @@ -0,0 +1,84 @@ +body +{ + text-align:center; +} +#container +{ + position:relative; + margin-left:auto; + margin-right:auto; + margin-top:20px; + width:360px; + +} + +#top +{ + position:relative; + width:100%; + height:20px; + padding:2px; + background-color:#005B7F; + text-align:center; + font-family:Verdana; + color:white; + font-size:12pt; +} + +#login_form +{ + position:relative; + width:100%; + height:230px; + padding:2px; + font-family:Verdana; + color:white; + font-size:10pt; + background-color:#A7A7A7; +} + +#welcome_message +{ + text-align:center; + margin-top:10px; + margin-bottom:20px; +} + +.error +{ + margin:0 auto; + border:3px solid #d3153b; + background-color:#fbe6f2; + padding:5px; + width:80%; + text-align:center; + font-size:18px; + margin-bottom:20px; + +} + +.form_field_label +{ + float:left; + margin-left:20px; + width:30%; +} + +.form_field +{ + float:left; + width:30%; +} + +#submit_button +{ + position:absolute; + bottom:60px; + right:60px; +} + +input +{ + font-family:Arial; +} + diff --git a/css/menubar.css b/css/menubar.css new file mode 100644 index 000000000..fe2133d1f --- /dev/null +++ b/css/menubar.css @@ -0,0 +1,93 @@ +#menubar +{ + position:relative; + margin:0px; + padding:0px; + background-image: url("../images/menubar/menubar_bg.gif"); + background-repeat: repeat-x; + width:100%; + height:100px; + color:#FFFFFF; + text-align:left; + text-align:center; +} + +#menubar_container +{ + position:relative; + margin:0 auto; + width:875px; + text-align:left; +} + +.menu_item +{ + float:left; + width:65px; + height:100%; + text-align:center; +} + + +#menubar a:link, #menubar a:visited, #menubar a +{ + color:#FFFFFF; + text-decoration:underline; +} + +#menubar a:hover +{ + color:#CCCCCC; + text-decoration:underline; +} + +.menu_item +{ + font-size:8pt; +} + +#menubar_company_info +{ + position:absolute; + left:0px; + top:18px; + width:250px; + height:55%; +} + +#company_title +{ + font-size:14pt; + font-weight:bold; +} + +#menubar_navigation +{ + position:relative; + width:75%; + left:200px; + top:8px; + height:45%; +} + +#menubar_footer +{ + position:absolute; + top:80px; + left:0px; + height:17%; + padding-top:3px; + font-size:8pt; + font-weight:bold; +} + +#menubar_date +{ + position:absolute; + top:80px; + right:0px; + height:17%; + padding-top:3px; + font-size:8pt; + font-weight:bold; +} \ No newline at end of file diff --git a/css/ospos.css b/css/ospos.css new file mode 100644 index 000000000..7cbf4c522 --- /dev/null +++ b/css/ospos.css @@ -0,0 +1,149 @@ +@import url(autocomplete.css); +@import url(menubar.css); +@import url(general.css); +@import url(popupbox.css); +@import url(register.css); +@import url(receipt.css); +@import url(reports.css); +@import url(tables.css); +@import url(thickbox.css); +@import url(datepicker.css); +@import url(editsale.css); + +body +{ + margin:0px; + padding:0px; + background-color:#f7f7f7; +} + +a.none +{ + text-decoration:none; +} + + +#content_area_wrapper +{ + position:relative; + width:100%; + background-color:#FFFFFF; + margin:0px; + padding:0px; + border-bottom:1px solid #CCCCCC; + text-align:center; + +} + +#content_area +{ + position:relative; + margin:0 auto; + width:875px; + text-align:left; + +} + +#title_bar +{ + position:relative; + margin-top:10px; + margin-bottom:10px; + width:100%; + height:50px; +} + +#title +{ + position:absolute; + bottom:0px; + left:0px; + font-size:30px; + font-weight:bold; + color:#000000; +} + +#page_title +{ + margin-top:8px; + font-size:30px; + font-weight:bold; + color:#000000; + text-align:center; + +} + +#page_subtitle +{ + margin-top:8px; + font-size:16px; + font-weight:bold; + color:#000000; + text-align:center; +} + +#new_button +{ + position:absolute; + bottom:-5px; + right:0px; +} + +#spinner +{ + position:absolute; + display:none; + right:21%; + top:5px; +} + +#feedback_bar +{ + position:fixed; + bottom:0; + left:0; + width:100%; + height:55px; + position:fixed; + opacity: 0; + filter: alpha(opacity=0); + z-index:1; + line-height:3.3; +} + +#home_module_list +{ + position: relative; +} + +.module_item +{ + padding: 10px; +} + +#config_wrapper +{ + text-align:center; +} + +#config_info +{ + width:70%; + margin:0 auto; + padding:10px; + margin-bottom:30px; + margin-top:10px; + text-align:left; +} + +#footer +{ + position:relative; + margin-top:25px; + margin-bottom:15px; + text-align:center; + font-size:11px; + color:#777777; + clear:both; + +} diff --git a/css/ospos_print.css b/css/ospos_print.css new file mode 100644 index 000000000..9e29b4149 --- /dev/null +++ b/css/ospos_print.css @@ -0,0 +1,41 @@ +body +{ + background-color:#FFFFFF; + font-size:75%; +} + +#menubar,#footer +{ + display:none; +} + +#content_area +{ + width:100%; +} + +#content_area_wrapper +{ + border:0px; +} + +#sale_return_policy +{ + width:100%; + text-align:center; +} + +.long_name +{ + display:none; +} + +.short_name +{ + display:inline; +} + +#receipt_items td +{ + white-space:nowrap; +} diff --git a/css/popupbox.css b/css/popupbox.css new file mode 100644 index 000000000..f81b2814c --- /dev/null +++ b/css/popupbox.css @@ -0,0 +1,99 @@ +#required_fields_message +{ + width: 100%; + text-align: center; + margin-bottom: 3px; + font-style: italic; +} + +#customer_basic_info,#item_basic_info,#item_number_info,#supplier_basic_info +{ + padding: 5px; +} + +#scan_item_number.loading +{ + background-image: url(../images/spinner_small.gif); + background-position:center right; + background-repeat:no-repeat; +} + +#info_provided_by +{ + display:none; + font-weight:bold; +} + +#employee_basic_info +{ + float:left; + width:47%; + padding:5px; +} + +#employee_login_info +{ + float:left; + width:47%; + margin-left:5px; + padding:5px; +} + +#permission_list +{ + list-style:none; +} + +#permission_list li +{ + padding:5px; +} + +#permission_list input +{ + top:3px; +} + +#employee_permission_info +{ + float:left; + width:47%; + margin-left:5px; + padding:5px; +} +#employee_permission_info p +{ + font-weight:bold; +} + +#employee_permission_info span.small +{ + font-style:italic; + font-size:80%; +} + +#error_message_box +{ + margin-bottom:7px; + margin-left:20px; + color:red; +} +#item_kit_items_title +{ + text-align: center; +} +#item_kit_items +{ + width: 100%; +} + +#item_kit_items th +{ + text-align: center; + font-weight: bold; +} + +#item_kit_items td +{ + text-align: center; +} \ No newline at end of file diff --git a/css/receipt.css b/css/receipt.css new file mode 100644 index 000000000..d891460b4 --- /dev/null +++ b/css/receipt.css @@ -0,0 +1,60 @@ +#receipt_wrapper +{ + font-family:Arial; + width:100%; +} + +#receipt_header +{ + text-align:center; +} + +#company_name +{ + font-size:150%; + font-weight:bold; +} + +#company_phone +{ + margin-bottom:15px; + +} + +#sale_time +{ + margin-bottom:5px; +} + +#receipt_items +{ + position:relative; + border-collapse:collapse; + margin-top:15px; + margin-bottom:15px; + width:100%; +} + +#receipt_items td +{ + position:relative; + padding:3px; +} + +.short_name +{ + display:none; +} + +#sale_return_policy +{ + width:80%; + margin:0 auto; + text-align:center; +} + +#barcode +{ + margin-top:10px; + text-align:center; +} \ No newline at end of file diff --git a/css/register.css b/css/register.css new file mode 100644 index 000000000..090886586 --- /dev/null +++ b/css/register.css @@ -0,0 +1,165 @@ +#register_wrapper +{ + float:left; + width:70%; + font-family:Arial; + font-size:13px; +} +#mode_form +{ + position:relative; + background-color:#DDD; + padding: 8px 0px 8px 0px; +} + +#show_suspended_sales_button +{ + position:absolute; + top:3px; + right:4px; +} + +#mode_form span +{ + font-weight:bold; +} + +#add_item_form +{ + position:relative; + background-color:#BBBBBB; + width:100%; + padding: 8px 0px 8px 0px; + +} + +#new_item_button_register +{ + position:absolute; + top:3px; + right:4px; +} + +#add_item_form input +{ + border: 1px solid #ccc; + padding: 2px; + +} + +#item_label,#customer_label +{ + font-weight:bold; +} + +#add_item_form label +{ + margin: 0px 5px 0px 5px; +} + +#register +{ + position:relative; + width:100%; + padding:0px; + border-collapse:collapse; +} + +#register th +{ + background-color:#4386a1; + padding:5px; + text-align:center; + color:#FFFFFF; +} + +#register td +{ + background-color:#EEEEEE; + padding:3px; + text-align:center; +} + +#overall_sale +{ + float:left; + margin-left:4px; + background-color:#BBBBBB; + width:28%; + padding:5px; + font-family:Arial; + font-size:13px; + +} + +#sale_details +{ + position:relative; + width:100%; + margin-top:5px; + border-top:2px solid #000; +} + +#finish_sale +{ + position:relative; +} + +#Payment_Types +{ + float:left; + width:100%; + margin-top:5px; + border-top:2px solid #000; + background-color:#DDD; + margin-bottom:0px; + clear:both; +} + +#Cancel_sale +{ + float:left; + width:100%; + margin-top:5px; + clear:both; +} +#suspended_sales_table th +{ + text-align:center; +} + +#suspended_sales_table td +{ + padding: 7px; +} + +#credit_card_form fieldset +{ + overflow: auto; + border: 0; + margin: 0; + padding: 0; +} + +#credit_card_form fieldset div +{ + float: left; +} + +#credit_card_form fieldset.centered div +{ + text-align: center; +} + +#credit_card_form label +{ + display: block; + margin-bottom: 5px; +} + +#credit_card_form input.text +{ + border: 1px solid #bfbab4; + margin: 0 4px 8px 0; +} + diff --git a/css/reports.css b/css/reports.css new file mode 100644 index 000000000..088071ab3 --- /dev/null +++ b/css/reports.css @@ -0,0 +1,26 @@ +#report_list li ul li +{ + margin-left: 35px; +} +#report_date_range_simple +{ + margin-bottom: 3px; +} +.report +{ + font-size: .85em; +} +#report_summary +{ + margin: 0 auto; + text-align: center; +} + +#report_summary .summary_row +{ +} + +#chart_wrapper +{ + text-align: center; +} \ No newline at end of file diff --git a/css/tables.css b/css/tables.css new file mode 100644 index 000000000..d734ab881 --- /dev/null +++ b/css/tables.css @@ -0,0 +1,126 @@ +#table_action_header +{ + position:relative; + width:100%; + background-color:#EEEEEE; + background-image:url(../images/checkbox_arrow.gif); + height:20px; + border-top:1px solid #CCCCCC; + background-position:5px 10px; + background-repeat:no-repeat; + padding:3px 0px 3px 0px; +} + +#table_action_header ul +{ + list-style:none; + padding:0px; + margin:0px; + margin-left:15px; +} + +#table_action_header ul li +{ + margin-left:8px; + margin-right:4px; + +} + +#table_action_header ul li span +{ + background-color:#0a6184; + border:2px solid #DDDDDD; + font-size:14px; + padding:2px 5px 2px 5px; + +} + +#table_action_header a +{ + text-decoration:none; + color:#FFF; +} + +#table_holder +{ + position:relative; + margin-bottom:50px; +} + +table.tablesorter +{ + position:relative; + width:100%; + border-top:3px solid #0a6184; + border-collapse:collapse; +} + +table.tablesorter thead tr th, table.tablesorter tfoot tr th +{ + color:#FFFFFF; + text-align:left; + background-color:#4386a1; + padding: 0px 5px 0px 5px; +} + +table.tablesorter thead tr .header +{ + background-image: url(../images/tables/bg.gif); + background-repeat: no-repeat; + background-position: center right; + cursor: pointer; +} + +table.tablesorter tbody td +{ + color: #3D3D3D; + background-color: #FFF; + vertical-align: top; + padding: 0px 5px 0px 5px; + +} + +table.tablesorter tbody td +{ + border-bottom:1px solid #DDDDDD; +} + +table.tablesorter tbody td.over +{ + background-color:#CCCCCC; +} + +table.tablesorter tbody td.selected +{ + background-color:#BBBBBB; +} + +table.tablesorter thead tr .headerSortUp +{ + background-image: url(../images/tables/asc.gif); +} + +table.tablesorter thead tr .headerSortDown +{ + background-image: url(../images/tables/desc.gif); +} + +table.tablesorter thead tr .headerSortDown, table.tablesorter thead tr .headerSortUp +{ + background-color: #8dbdd8; +} + +table.innertable +{ + display: none; +} + +table.innertable thead tr th +{ + background-color: #0a6184; +} + +table.innertable tbody tr td +{ + background-color: #DDD; +} \ No newline at end of file diff --git a/css/thickbox.css b/css/thickbox.css new file mode 100644 index 000000000..57242c5d4 --- /dev/null +++ b/css/thickbox.css @@ -0,0 +1,165 @@ +/* ----------------------------------------------------------------------------------------------------------------*/ +/* ---------->>> global settings needed for thickbox <<<-----------------------------------------------------------*/ +/* ----------------------------------------------------------------------------------------------------------------*/ +*{padding: 0; margin: 0;} + +/* ----------------------------------------------------------------------------------------------------------------*/ +/* ---------->>> thickbox specific link and font settings <<<------------------------------------------------------*/ +/* ----------------------------------------------------------------------------------------------------------------*/ +#TB_window { + font: 12px Arial, Helvetica, sans-serif; + color: #333333; +} + +#TB_secondLine { + font: 10px Arial, Helvetica, sans-serif; + color:#666666; +} + +#TB_window a:link {color: #666666;} +#TB_window a:visited {color: #666666;} +#TB_window a:hover {color: #000;} +#TB_window a:active {color: #666666;} +#TB_window a:focus{color: #666666;} + +/* ----------------------------------------------------------------------------------------------------------------*/ +/* ---------->>> thickbox settings <<<-----------------------------------------------------------------------------*/ +/* ----------------------------------------------------------------------------------------------------------------*/ +#TB_overlay { + position: fixed; + z-index:100; + top: 0px; + left: 0px; + height:100%; + width:100%; +} + +.TB_overlayMacFFBGHack {background: url(macFFBgHack.png) repeat;} +.TB_overlayBG { + background-color:#000; + filter:alpha(opacity=75); + -moz-opacity: 0.75; + opacity: 0.75; +} + +* html #TB_overlay { /* ie6 hack */ + position: absolute; + height: expression(document.body.scrollHeight > document.body.offsetHeight ? document.body.scrollHeight : document.body.offsetHeight + 'px'); +} + +#TB_window { + position: fixed; + background: #ffffff; + z-index: 102; + color:#000000; + display:none; + border: 4px solid #525252; + text-align:left; + bottom:10%; + left:50%; +} + +* html #TB_window { /* ie6 hack */ +position: absolute; +margin-top: expression(0 - parseInt(this.offsetHeight / 2) + (TBWindowMargin = document.documentElement && document.documentElement.scrollTop || document.body.scrollTop) + 'px'); +} + +#TB_window img#TB_Image { + display:block; + margin: 15px 0 0 15px; + border-right: 1px solid #ccc; + border-bottom: 1px solid #ccc; + border-top: 1px solid #666; + border-left: 1px solid #666; +} + +#TB_caption{ + height:25px; + padding:7px 30px 10px 25px; + float:left; +} + +#TB_closeWindow{ + height:25px; + padding:11px 25px 10px 0; + float:right; +} + +#TB_closeAjaxWindow{ + padding:7px 10px 5px 0; + margin-bottom:1px; + text-align:right; + float:right; +} + +#TB_ajaxWindowTitle{ + float:left; + padding:7px 0 5px 10px; + margin-bottom:1px; +} + +#TB_title{ + background-color:#e8e8e8; + font-size:1.25em; + font-weight:bold; + height:27px; +} + +#TB_ajaxContent{ + clear:both; + padding:2px 15px 15px 15px; + overflow:auto; + text-align:left; + line-height:1.4em; +} + +#TB_ajaxContent.TB_modal{ + padding:15px; +} + +#TB_ajaxContent p{ + padding:5px 0px 5px 0px; +} + +#TB_load{ + position: fixed; + display:none; + height:13px; + width:208px; + z-index:103; + top: 50%; + left: 50%; + margin: -6px 0 0 -104px; /* -height/2 0 0 -width/2 */ +} + +* html #TB_load { /* ie6 hack */ +position: absolute; +margin-top: expression(0 - parseInt(this.offsetHeight / 2) + (TBWindowMargin = document.documentElement && document.documentElement.scrollTop || document.body.scrollTop) + 'px'); +} + +#TB_HideSelect{ + z-index:99; + position:fixed; + top: 0; + left: 0; + background-color:#fff; + border:none; + filter:alpha(opacity=0); + -moz-opacity: 0; + opacity: 0; + height:100%; + width:100%; +} + +* html #TB_HideSelect { /* ie6 hack */ + position: absolute; + height: expression(document.body.scrollHeight > document.body.offsetHeight ? document.body.scrollHeight : document.body.offsetHeight + 'px'); +} + +#TB_iframeContent{ + clear:both; + border:none; + margin-bottom:-1px; + margin-top:1px; + _margin-bottom:1px; +} diff --git a/database/database.sql b/database/database.sql new file mode 100644 index 000000000..13e4d0d8f --- /dev/null +++ b/database/database.sql @@ -0,0 +1,696 @@ +-- phpMyAdmin SQL Dump +-- version 3.3.9 +-- http://www.phpmyadmin.net +-- +-- Host: localhost +-- Generation Time: Apr 08, 2011 at 04:27 PM +-- Server version: 5.1.54 +-- PHP Version: 5.3.3 + +-- +-- Database: `pos` +-- + +-- -------------------------------------------------------- + +-- +-- Table structure for table `ospos_app_config` +-- + +CREATE TABLE `ospos_app_config` ( + `key` varchar(255) NOT NULL, + `value` varchar(255) NOT NULL, + PRIMARY KEY (`key`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +-- +-- Dumping data for table `ospos_app_config` +-- + +INSERT INTO `ospos_app_config` (`key`, `value`) VALUES +('address', '123 Nowhere street'), +('company', 'Open Source Point of Sale'), +('default_tax_rate', '8'), +('email', 'admin@pappastech.com'), +('fax', ''), +('phone', '555-555-5555'), +('return_policy', 'Test'), +('timezone', 'America/New_York'), +('website', ''); + +-- -------------------------------------------------------- + +-- +-- Table structure for table `ospos_customers` +-- + +CREATE TABLE `ospos_customers` ( + `person_id` int(10) NOT NULL, + `account_number` varchar(255) DEFAULT NULL, + `taxable` int(1) NOT NULL DEFAULT '1', + `deleted` int(1) NOT NULL DEFAULT '0', + UNIQUE KEY `account_number` (`account_number`), + KEY `person_id` (`person_id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +-- +-- Dumping data for table `ospos_customers` +-- + + +-- -------------------------------------------------------- + +-- +-- Table structure for table `ospos_employees` +-- + +CREATE TABLE `ospos_employees` ( + `username` varchar(255) NOT NULL, + `password` varchar(255) NOT NULL, + `person_id` int(10) NOT NULL, + `deleted` int(1) NOT NULL DEFAULT '0', + UNIQUE KEY `username` (`username`), + KEY `person_id` (`person_id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +-- +-- Dumping data for table `ospos_employees` +-- + +INSERT INTO `ospos_employees` (`username`, `password`, `person_id`, `deleted`) VALUES +('admin', '439a6de57d475c1a0ba9bcb1c39f0af6', 1, 0); + +-- -------------------------------------------------------- + +-- +-- Table structure for table `ospos_giftcards` +-- + +CREATE TABLE `ospos_giftcards` ( + `giftcard_id` int(11) NOT NULL AUTO_INCREMENT, + `giftcard_number` varchar(25) COLLATE utf8_unicode_ci NOT NULL, + `value` double(15,2) NOT NULL, + `deleted` int(1) NOT NULL DEFAULT '0', + `person_id` INT NOT NULL, + PRIMARY KEY (`giftcard_id`), + UNIQUE KEY `giftcard_number` (`giftcard_number`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci AUTO_INCREMENT=48 ; + +-- +-- Dumping data for table `ospos_giftcards` +-- + + +-- -------------------------------------------------------- + +-- +-- Table structure for table `ospos_inventory` +-- + +CREATE TABLE `ospos_inventory` ( + `trans_id` int(11) NOT NULL AUTO_INCREMENT, + `trans_items` int(11) NOT NULL DEFAULT '0', + `trans_user` int(11) NOT NULL DEFAULT '0', + `trans_date` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, + `trans_comment` text NOT NULL, + `trans_inventory` int(11) NOT NULL DEFAULT '0', + PRIMARY KEY (`trans_id`), + KEY `ospos_inventory_ibfk_1` (`trans_items`), + KEY `ospos_inventory_ibfk_2` (`trans_user`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=1 ; + +-- +-- Dumping data for table `ospos_inventory` +-- + + +-- -------------------------------------------------------- + +-- +-- Table structure for table `ospos_items` +-- + +CREATE TABLE `ospos_items` ( + `name` varchar(255) NOT NULL, + `category` varchar(255) NOT NULL, + `supplier_id` int(11) DEFAULT NULL, + `item_number` varchar(255) DEFAULT NULL, + `description` varchar(255) NOT NULL, + `cost_price` double(15,2) NOT NULL, + `unit_price` double(15,2) NOT NULL, + `quantity` double(15,2) NOT NULL DEFAULT '0.00', + `reorder_level` double(15,2) NOT NULL DEFAULT '0.00', + `location` varchar(255) NOT NULL, + `item_id` int(10) NOT NULL AUTO_INCREMENT, + `allow_alt_description` tinyint(1) NOT NULL, + `is_serialized` tinyint(1) NOT NULL, + `deleted` int(1) NOT NULL DEFAULT '0', + `custom1` VARCHAR(25) NOT NULL, + `custom2` VARCHAR(25) NOT NULL, + `custom3` VARCHAR(25) NOT NULL, + `custom4` VARCHAR(25) NOT NULL, + `custom5` VARCHAR(25) NOT NULL, + `custom6` VARCHAR(25) NOT NULL, + `custom7` VARCHAR(25) NOT NULL, + `custom8` VARCHAR(25) NOT NULL, + `custom9` VARCHAR(25) NOT NULL, + `custom10` VARCHAR(25) NOT NULL, + PRIMARY KEY (`item_id`), + UNIQUE KEY `item_number` (`item_number`), + KEY `ospos_items_ibfk_1` (`supplier_id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=1 ; + +-- +-- Dumping data for table `ospos_items` +-- + + +-- -------------------------------------------------------- + +-- +-- Table structure for table `ospos_items_taxes` +-- + +CREATE TABLE `ospos_items_taxes` ( + `item_id` int(10) NOT NULL, + `name` varchar(255) NOT NULL, + `percent` double(15,3) NOT NULL, + PRIMARY KEY (`item_id`,`name`,`percent`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +-- +-- Dumping data for table `ospos_items_taxes` +-- + + +-- -------------------------------------------------------- + +-- +-- Table structure for table `ospos_item_kits` +-- + +CREATE TABLE `ospos_item_kits` ( + `item_kit_id` int(11) NOT NULL AUTO_INCREMENT, + `name` varchar(255) NOT NULL, + `description` varchar(255) NOT NULL, + PRIMARY KEY (`item_kit_id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=1 ; + +-- +-- Dumping data for table `ospos_item_kits` +-- + + +-- -------------------------------------------------------- + +-- +-- Table structure for table `ospos_item_kit_items` +-- + +CREATE TABLE `ospos_item_kit_items` ( + `item_kit_id` int(11) NOT NULL, + `item_id` int(11) NOT NULL, + `quantity` double(15,2) NOT NULL, + PRIMARY KEY (`item_kit_id`,`item_id`,`quantity`), + KEY `ospos_item_kit_items_ibfk_2` (`item_id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +-- +-- Dumping data for table `ospos_item_kit_items` +-- + + +-- -------------------------------------------------------- + +-- +-- Table structure for table `ospos_modules` +-- + +CREATE TABLE `ospos_modules` ( + `name_lang_key` varchar(255) NOT NULL, + `desc_lang_key` varchar(255) NOT NULL, + `sort` int(10) NOT NULL, + `module_id` varchar(255) NOT NULL, + PRIMARY KEY (`module_id`), + UNIQUE KEY `desc_lang_key` (`desc_lang_key`), + UNIQUE KEY `name_lang_key` (`name_lang_key`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +-- +-- Dumping data for table `ospos_modules` +-- + +INSERT INTO `ospos_modules` (`name_lang_key`, `desc_lang_key`, `sort`, `module_id`) VALUES +('module_config', 'module_config_desc', 100, 'config'), +('module_customers', 'module_customers_desc', 10, 'customers'), +('module_employees', 'module_employees_desc', 80, 'employees'), +('module_giftcards', 'module_giftcards_desc', 90, 'giftcards'), +('module_items', 'module_items_desc', 20, 'items'), +('module_item_kits', 'module_item_kits_desc', 30, 'item_kits'), +('module_receivings', 'module_receivings_desc', 60, 'receivings'), +('module_reports', 'module_reports_desc', 50, 'reports'), +('module_sales', 'module_sales_desc', 70, 'sales'), +('module_suppliers', 'module_suppliers_desc', 40, 'suppliers'); + +-- -------------------------------------------------------- + +-- +-- Table structure for table `ospos_people` +-- + +CREATE TABLE `ospos_people` ( + `first_name` varchar(255) NOT NULL, + `last_name` varchar(255) NOT NULL, + `phone_number` varchar(255) NOT NULL, + `email` varchar(255) NOT NULL, + `address_1` varchar(255) NOT NULL, + `address_2` varchar(255) NOT NULL, + `city` varchar(255) NOT NULL, + `state` varchar(255) NOT NULL, + `zip` varchar(255) NOT NULL, + `country` varchar(255) NOT NULL, + `comments` text NOT NULL, + `person_id` int(10) NOT NULL AUTO_INCREMENT, + PRIMARY KEY (`person_id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=2 ; + +-- +-- Dumping data for table `ospos_people` +-- + +INSERT INTO `ospos_people` (`first_name`, `last_name`, `phone_number`, `email`, `address_1`, `address_2`, `city`, `state`, `zip`, `country`, `comments`, `person_id`) VALUES +('John', 'Doe', '555-555-5555', 'admin@pappastech.com', 'Address 1', '', '', '', '', '', '', 1); + +-- -------------------------------------------------------- + +-- +-- Table structure for table `ospos_permissions` +-- + +CREATE TABLE `ospos_permissions` ( + `module_id` varchar(255) NOT NULL, + `person_id` int(10) NOT NULL, + PRIMARY KEY (`module_id`,`person_id`), + KEY `person_id` (`person_id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +-- +-- Dumping data for table `ospos_permissions` +-- + +INSERT INTO `ospos_permissions` (`module_id`, `person_id`) VALUES +('config', 1), +('customers', 1), +('employees', 1), +('giftcards', 1), +('items', 1), +('item_kits', 1), +('receivings', 1), +('reports', 1), +('sales', 1), +('suppliers', 1); + +-- -------------------------------------------------------- + +-- +-- Table structure for table `ospos_receivings` +-- + +CREATE TABLE `ospos_receivings` ( + `receiving_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, + `supplier_id` int(10) DEFAULT NULL, + `employee_id` int(10) NOT NULL DEFAULT '0', + `comment` text NOT NULL, + `receiving_id` int(10) NOT NULL AUTO_INCREMENT, + `payment_type` varchar(20) DEFAULT NULL, + PRIMARY KEY (`receiving_id`), + KEY `supplier_id` (`supplier_id`), + KEY `employee_id` (`employee_id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=1 ; + +-- +-- Dumping data for table `ospos_receivings` +-- + + +-- -------------------------------------------------------- + +-- +-- Table structure for table `ospos_receivings_items` +-- + +CREATE TABLE `ospos_receivings_items` ( + `receiving_id` int(10) NOT NULL DEFAULT '0', + `item_id` int(10) NOT NULL DEFAULT '0', + `description` varchar(30) DEFAULT NULL, + `serialnumber` varchar(30) DEFAULT NULL, + `line` int(3) NOT NULL, + `quantity_purchased` int(10) NOT NULL DEFAULT '0', + `item_cost_price` decimal(15,2) NOT NULL, + `item_unit_price` double(15,2) NOT NULL, + `discount_percent` int(11) NOT NULL DEFAULT '0', + PRIMARY KEY (`receiving_id`,`item_id`,`line`), + KEY `item_id` (`item_id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +-- +-- Dumping data for table `ospos_receivings_items` +-- + + +-- -------------------------------------------------------- + +-- +-- Table structure for table `ospos_sales` +-- + +CREATE TABLE `ospos_sales` ( + `sale_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, + `customer_id` int(10) DEFAULT NULL, + `employee_id` int(10) NOT NULL DEFAULT '0', + `comment` text NOT NULL, + `sale_id` int(10) NOT NULL AUTO_INCREMENT, + `payment_type` varchar(512) DEFAULT NULL, + PRIMARY KEY (`sale_id`), + KEY `customer_id` (`customer_id`), + KEY `employee_id` (`employee_id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=1 ; + +-- +-- Dumping data for table `ospos_sales` +-- + + +-- -------------------------------------------------------- + +-- +-- Table structure for table `ospos_sales_items` +-- + +CREATE TABLE `ospos_sales_items` ( + `sale_id` int(10) NOT NULL DEFAULT '0', + `item_id` int(10) NOT NULL DEFAULT '0', + `description` varchar(30) DEFAULT NULL, + `serialnumber` varchar(30) DEFAULT NULL, + `line` int(3) NOT NULL DEFAULT '0', + `quantity_purchased` double(15,2) NOT NULL DEFAULT '0.00', + `item_cost_price` decimal(15,2) NOT NULL, + `item_unit_price` double(15,2) NOT NULL, + `discount_percent` int(11) NOT NULL DEFAULT '0', + PRIMARY KEY (`sale_id`,`item_id`,`line`), + KEY `item_id` (`item_id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +-- +-- Dumping data for table `ospos_sales_items` +-- + + +-- -------------------------------------------------------- + +-- +-- Table structure for table `ospos_sales_items_taxes` +-- + +CREATE TABLE `ospos_sales_items_taxes` ( + `sale_id` int(10) NOT NULL, + `item_id` int(10) NOT NULL, + `line` int(3) NOT NULL DEFAULT '0', + `name` varchar(255) NOT NULL, + `percent` double(15,3) NOT NULL, + PRIMARY KEY (`sale_id`,`item_id`,`line`,`name`,`percent`), + KEY `item_id` (`item_id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +-- +-- Dumping data for table `ospos_sales_items_taxes` +-- + + +-- -------------------------------------------------------- + +-- +-- Table structure for table `ospos_sales_payments` +-- + +CREATE TABLE `ospos_sales_payments` ( + `sale_id` int(10) NOT NULL, + `payment_type` varchar(40) NOT NULL, + `payment_amount` decimal(15,2) NOT NULL, + PRIMARY KEY (`sale_id`,`payment_type`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +-- +-- Dumping data for table `ospos_sales_payments` +-- + + +-- -------------------------------------------------------- + +-- +-- Table structure for table `ospos_sales_suspended` +-- + +CREATE TABLE `ospos_sales_suspended` ( + `sale_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, + `customer_id` int(10) DEFAULT NULL, + `employee_id` int(10) NOT NULL DEFAULT '0', + `comment` text NOT NULL, + `sale_id` int(10) NOT NULL AUTO_INCREMENT, + `payment_type` varchar(512) DEFAULT NULL, + PRIMARY KEY (`sale_id`), + KEY `customer_id` (`customer_id`), + KEY `employee_id` (`employee_id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=1 ; + +-- +-- Dumping data for table `ospos_sales_suspended` +-- + + +-- -------------------------------------------------------- + +-- +-- Table structure for table `ospos_sales_suspended_items` +-- + +CREATE TABLE `ospos_sales_suspended_items` ( + `sale_id` int(10) NOT NULL DEFAULT '0', + `item_id` int(10) NOT NULL DEFAULT '0', + `description` varchar(30) DEFAULT NULL, + `serialnumber` varchar(30) DEFAULT NULL, + `line` int(3) NOT NULL DEFAULT '0', + `quantity_purchased` double(15,2) NOT NULL DEFAULT '0.00', + `item_cost_price` decimal(15,2) NOT NULL, + `item_unit_price` double(15,2) NOT NULL, + `discount_percent` int(11) NOT NULL DEFAULT '0', + PRIMARY KEY (`sale_id`,`item_id`,`line`), + KEY `item_id` (`item_id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +-- +-- Dumping data for table `ospos_sales_suspended_items` +-- + + +-- -------------------------------------------------------- + +-- +-- Table structure for table `ospos_sales_suspended_items_taxes` +-- + +CREATE TABLE `ospos_sales_suspended_items_taxes` ( + `sale_id` int(10) NOT NULL, + `item_id` int(10) NOT NULL, + `line` int(3) NOT NULL DEFAULT '0', + `name` varchar(255) NOT NULL, + `percent` double(15,3) NOT NULL, + PRIMARY KEY (`sale_id`,`item_id`,`line`,`name`,`percent`), + KEY `item_id` (`item_id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +-- +-- Dumping data for table `ospos_sales_suspended_items_taxes` +-- + + +-- -------------------------------------------------------- + +-- +-- Table structure for table `ospos_sales_suspended_payments` +-- + +CREATE TABLE `ospos_sales_suspended_payments` ( + `sale_id` int(10) NOT NULL, + `payment_type` varchar(40) NOT NULL, + `payment_amount` decimal(15,2) NOT NULL, + PRIMARY KEY (`sale_id`,`payment_type`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +-- +-- Dumping data for table `ospos_sales_suspended_payments` +-- + + +-- -------------------------------------------------------- + +-- +-- Table structure for table `ospos_sessions` +-- + +CREATE TABLE `ospos_sessions` ( + `session_id` varchar(40) NOT NULL DEFAULT '0', + `ip_address` varchar(16) NOT NULL DEFAULT '0', + `user_agent` varchar(120) NOT NULL, + `last_activity` int(10) unsigned NOT NULL DEFAULT '0', + `user_data` text, + PRIMARY KEY (`session_id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +-- +-- Dumping data for table `ospos_sessions` +-- + + +-- -------------------------------------------------------- + +-- +-- Table structure for table `ospos_suppliers` +-- + +CREATE TABLE `ospos_suppliers` ( + `person_id` int(10) NOT NULL, + `company_name` varchar(255) NOT NULL, + `account_number` varchar(255) DEFAULT NULL, + `deleted` int(1) NOT NULL DEFAULT '0', + UNIQUE KEY `account_number` (`account_number`), + KEY `person_id` (`person_id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +-- +-- Dumping data for table `ospos_suppliers` +-- + + +-- +-- Constraints for dumped tables +-- + +-- +-- Constraints for table `ospos_customers` +-- +ALTER TABLE `ospos_customers` + ADD CONSTRAINT `ospos_customers_ibfk_1` FOREIGN KEY (`person_id`) REFERENCES `ospos_people` (`person_id`); + +-- +-- Constraints for table `ospos_employees` +-- +ALTER TABLE `ospos_employees` + ADD CONSTRAINT `ospos_employees_ibfk_1` FOREIGN KEY (`person_id`) REFERENCES `ospos_people` (`person_id`); + +-- +-- Constraints for table `ospos_inventory` +-- +ALTER TABLE `ospos_inventory` + ADD CONSTRAINT `ospos_inventory_ibfk_1` FOREIGN KEY (`trans_items`) REFERENCES `ospos_items` (`item_id`), + ADD CONSTRAINT `ospos_inventory_ibfk_2` FOREIGN KEY (`trans_user`) REFERENCES `ospos_employees` (`person_id`); + +-- +-- Constraints for table `ospos_items` +-- +ALTER TABLE `ospos_items` + ADD CONSTRAINT `ospos_items_ibfk_1` FOREIGN KEY (`supplier_id`) REFERENCES `ospos_suppliers` (`person_id`); + +-- +-- Constraints for table `ospos_items_taxes` +-- +ALTER TABLE `ospos_items_taxes` + ADD CONSTRAINT `ospos_items_taxes_ibfk_1` FOREIGN KEY (`item_id`) REFERENCES `ospos_items` (`item_id`) ON DELETE CASCADE; + +-- +-- Constraints for table `ospos_item_kit_items` +-- +ALTER TABLE `ospos_item_kit_items` + ADD CONSTRAINT `ospos_item_kit_items_ibfk_1` FOREIGN KEY (`item_kit_id`) REFERENCES `ospos_item_kits` (`item_kit_id`) ON DELETE CASCADE, + ADD CONSTRAINT `ospos_item_kit_items_ibfk_2` FOREIGN KEY (`item_id`) REFERENCES `ospos_items` (`item_id`) ON DELETE CASCADE; + +-- +-- Constraints for table `ospos_permissions` +-- +ALTER TABLE `ospos_permissions` + ADD CONSTRAINT `ospos_permissions_ibfk_1` FOREIGN KEY (`person_id`) REFERENCES `ospos_employees` (`person_id`), + ADD CONSTRAINT `ospos_permissions_ibfk_2` FOREIGN KEY (`module_id`) REFERENCES `ospos_modules` (`module_id`); + +-- +-- Constraints for table `ospos_receivings` +-- +ALTER TABLE `ospos_receivings` + ADD CONSTRAINT `ospos_receivings_ibfk_1` FOREIGN KEY (`employee_id`) REFERENCES `ospos_employees` (`person_id`), + ADD CONSTRAINT `ospos_receivings_ibfk_2` FOREIGN KEY (`supplier_id`) REFERENCES `ospos_suppliers` (`person_id`); + +-- +-- Constraints for table `ospos_receivings_items` +-- +ALTER TABLE `ospos_receivings_items` + ADD CONSTRAINT `ospos_receivings_items_ibfk_1` FOREIGN KEY (`item_id`) REFERENCES `ospos_items` (`item_id`), + ADD CONSTRAINT `ospos_receivings_items_ibfk_2` FOREIGN KEY (`receiving_id`) REFERENCES `ospos_receivings` (`receiving_id`); + +-- +-- Constraints for table `ospos_sales` +-- +ALTER TABLE `ospos_sales` + ADD CONSTRAINT `ospos_sales_ibfk_1` FOREIGN KEY (`employee_id`) REFERENCES `ospos_employees` (`person_id`), + ADD CONSTRAINT `ospos_sales_ibfk_2` FOREIGN KEY (`customer_id`) REFERENCES `ospos_customers` (`person_id`); + +-- +-- Constraints for table `ospos_sales_items` +-- +ALTER TABLE `ospos_sales_items` + ADD CONSTRAINT `ospos_sales_items_ibfk_1` FOREIGN KEY (`item_id`) REFERENCES `ospos_items` (`item_id`), + ADD CONSTRAINT `ospos_sales_items_ibfk_2` FOREIGN KEY (`sale_id`) REFERENCES `ospos_sales` (`sale_id`); + +-- +-- Constraints for table `ospos_sales_items_taxes` +-- +ALTER TABLE `ospos_sales_items_taxes` + ADD CONSTRAINT `ospos_sales_items_taxes_ibfk_1` FOREIGN KEY (`sale_id`) REFERENCES `ospos_sales_items` (`sale_id`), + ADD CONSTRAINT `ospos_sales_items_taxes_ibfk_2` FOREIGN KEY (`item_id`) REFERENCES `ospos_items` (`item_id`); + +-- +-- Constraints for table `ospos_sales_payments` +-- +ALTER TABLE `ospos_sales_payments` + ADD CONSTRAINT `ospos_sales_payments_ibfk_1` FOREIGN KEY (`sale_id`) REFERENCES `ospos_sales` (`sale_id`); + +-- +-- Constraints for table `ospos_sales_suspended` +-- +ALTER TABLE `ospos_sales_suspended` + ADD CONSTRAINT `ospos_sales_suspended_ibfk_1` FOREIGN KEY (`employee_id`) REFERENCES `ospos_employees` (`person_id`), + ADD CONSTRAINT `ospos_sales_suspended_ibfk_2` FOREIGN KEY (`customer_id`) REFERENCES `ospos_customers` (`person_id`); + +-- +-- Constraints for table `ospos_sales_suspended_items` +-- +ALTER TABLE `ospos_sales_suspended_items` + ADD CONSTRAINT `ospos_sales_suspended_items_ibfk_1` FOREIGN KEY (`item_id`) REFERENCES `ospos_items` (`item_id`), + ADD CONSTRAINT `ospos_sales_suspended_items_ibfk_2` FOREIGN KEY (`sale_id`) REFERENCES `ospos_sales_suspended` (`sale_id`); + +-- +-- Constraints for table `ospos_sales_suspended_items_taxes` +-- +ALTER TABLE `ospos_sales_suspended_items_taxes` + ADD CONSTRAINT `ospos_sales_suspended_items_taxes_ibfk_1` FOREIGN KEY (`sale_id`) REFERENCES `ospos_sales_suspended_items` (`sale_id`), + ADD CONSTRAINT `ospos_sales_suspended_items_taxes_ibfk_2` FOREIGN KEY (`item_id`) REFERENCES `ospos_items` (`item_id`); + +-- +-- Constraints for table `ospos_sales_suspended_payments` +-- +ALTER TABLE `ospos_sales_suspended_payments` + ADD CONSTRAINT `ospos_sales_suspended_payments_ibfk_1` FOREIGN KEY (`sale_id`) REFERENCES `ospos_sales_suspended` (`sale_id`); + +-- +-- Constraints for table `ospos_suppliers` +-- +ALTER TABLE `ospos_suppliers` + ADD CONSTRAINT `ospos_suppliers_ibfk_1` FOREIGN KEY (`person_id`) REFERENCES `ospos_people` (`person_id`); diff --git a/images/Thumbs.db b/images/Thumbs.db new file mode 100644 index 000000000..10eecf861 Binary files /dev/null and b/images/Thumbs.db differ diff --git a/images/big_action_button.jpg b/images/big_action_button.jpg new file mode 100644 index 000000000..830332960 Binary files /dev/null and b/images/big_action_button.jpg differ diff --git a/images/calendar.png b/images/calendar.png new file mode 100644 index 000000000..94e66d4ba Binary files /dev/null and b/images/calendar.png differ diff --git a/images/checkbox_arrow.gif b/images/checkbox_arrow.gif new file mode 100644 index 000000000..5a9ff8314 Binary files /dev/null and b/images/checkbox_arrow.gif differ diff --git a/images/loading_animation.gif b/images/loading_animation.gif new file mode 100644 index 000000000..82290f483 Binary files /dev/null and b/images/loading_animation.gif differ diff --git a/images/menubar/config.png b/images/menubar/config.png new file mode 100644 index 000000000..49fcee265 Binary files /dev/null and b/images/menubar/config.png differ diff --git a/images/menubar/customers.png b/images/menubar/customers.png new file mode 100644 index 000000000..5b8e6deb9 Binary files /dev/null and b/images/menubar/customers.png differ diff --git a/images/menubar/employees.png b/images/menubar/employees.png new file mode 100644 index 000000000..9e9ba4d97 Binary files /dev/null and b/images/menubar/employees.png differ diff --git a/images/menubar/giftcards.png b/images/menubar/giftcards.png new file mode 100644 index 000000000..8b11c9564 Binary files /dev/null and b/images/menubar/giftcards.png differ diff --git a/images/menubar/home.png b/images/menubar/home.png new file mode 100644 index 000000000..327dc7535 Binary files /dev/null and b/images/menubar/home.png differ diff --git a/images/menubar/item_kits.png b/images/menubar/item_kits.png new file mode 100644 index 000000000..d6266204d Binary files /dev/null and b/images/menubar/item_kits.png differ diff --git a/images/menubar/items.png b/images/menubar/items.png new file mode 100644 index 000000000..948db99ff Binary files /dev/null and b/images/menubar/items.png differ diff --git a/images/menubar/menubar_bg.gif b/images/menubar/menubar_bg.gif new file mode 100644 index 000000000..225df46f4 Binary files /dev/null and b/images/menubar/menubar_bg.gif differ diff --git a/images/menubar/receivings.png b/images/menubar/receivings.png new file mode 100644 index 000000000..f3b1130af Binary files /dev/null and b/images/menubar/receivings.png differ diff --git a/images/menubar/reports.png b/images/menubar/reports.png new file mode 100644 index 000000000..7e1da8961 Binary files /dev/null and b/images/menubar/reports.png differ diff --git a/images/menubar/sales.png b/images/menubar/sales.png new file mode 100644 index 000000000..afc7e21f9 Binary files /dev/null and b/images/menubar/sales.png differ diff --git a/images/menubar/suppliers.png b/images/menubar/suppliers.png new file mode 100644 index 000000000..5ae04c3a7 Binary files /dev/null and b/images/menubar/suppliers.png differ diff --git a/images/menubar/thumb_clock.png b/images/menubar/thumb_clock.png new file mode 100644 index 000000000..40c969bfb Binary files /dev/null and b/images/menubar/thumb_clock.png differ diff --git a/images/menubar/thumb_colorscheme.png b/images/menubar/thumb_colorscheme.png new file mode 100644 index 000000000..acb711ae7 Binary files /dev/null and b/images/menubar/thumb_colorscheme.png differ diff --git a/images/minus.png b/images/minus.png new file mode 100644 index 000000000..1281cd22c Binary files /dev/null and b/images/minus.png differ diff --git a/images/plus.png b/images/plus.png new file mode 100644 index 000000000..34baa374e Binary files /dev/null and b/images/plus.png differ diff --git a/images/psds/big_action_button.psd b/images/psds/big_action_button.psd new file mode 100644 index 000000000..3ef5f3b83 Binary files /dev/null and b/images/psds/big_action_button.psd differ diff --git a/images/psds/small_action_button.psd b/images/psds/small_action_button.psd new file mode 100644 index 000000000..5c17e3b9b Binary files /dev/null and b/images/psds/small_action_button.psd differ diff --git a/images/small_action_button.jpg b/images/small_action_button.jpg new file mode 100644 index 000000000..105913f73 Binary files /dev/null and b/images/small_action_button.jpg differ diff --git a/images/spinner_small.gif b/images/spinner_small.gif new file mode 100644 index 000000000..f0ea9efae Binary files /dev/null and b/images/spinner_small.gif differ diff --git a/images/tables/asc.gif b/images/tables/asc.gif new file mode 100644 index 000000000..74157867f Binary files /dev/null and b/images/tables/asc.gif differ diff --git a/images/tables/bg.gif b/images/tables/bg.gif new file mode 100644 index 000000000..fac668fcf Binary files /dev/null and b/images/tables/bg.gif differ diff --git a/images/tables/desc.gif b/images/tables/desc.gif new file mode 100644 index 000000000..3b30b3c58 Binary files /dev/null and b/images/tables/desc.gif differ diff --git a/import_customers.csv b/import_customers.csv new file mode 100644 index 000000000..b71db6096 --- /dev/null +++ b/import_customers.csv @@ -0,0 +1,2 @@ +First Name,Last Name,E-Mail,Phone Number,Address 1,Address2,City,State,Zip,Country,Comments,Account Number,Taxable +Bob,Smith,bsmith@nowhere.com,585-555-1111,123 Nowhere Street,Apt 4,Awesome,NY,11111,USA,Awesome guy,,y \ No newline at end of file diff --git a/import_items.csv b/import_items.csv new file mode 100644 index 000000000..10f71bc52 --- /dev/null +++ b/import_items.csv @@ -0,0 +1,2 @@ +UPC/EAN/ISBN,Item Name,Category,Supplier ID,Cost Price,Unit Price,Tax 1 Name,Tax 1 Percent,Tax 2 Name ,Tax 2 Percent,Quantity,Reorder Level,Location,Description,Allow Alt Description,Item has Serial Number,custom1,custom2,custom3,custom4,custom5,custom6,custom7,custom8,custom9,custom10 +33333333,Apple iMac,Computers,,800,1200,Tax 1,8,Tax 2,10,10,1,Earth,Best Computer ever,y,,"Oz, Frank",The Bunny and the Hill,"Monkeys,Giraffes,Gorillas",English,New,Apple,,1999,D3lk3jlkjs,Hardbound \ No newline at end of file diff --git a/index.php b/index.php new file mode 100644 index 000000000..54e5e605d --- /dev/null +++ b/index.php @@ -0,0 +1,205 @@ + this.getDate()) + this.addDays(-this.getDate()); + + return this; + }); + + /** + * Add a number of days to the date object. + * + * @example var dtm = new Date("01/12/2008"); + * dtm.addDays(1); + * dtm.toString(); + * @result 'Sun Jan 13 2008 00:00:00' + * + * @name addDays + * @type Date + * @cat Plugins/Methods/Date + */ + add("addDays", function(num) { + //this.setDate(this.getDate() + num); + this.setTime(this.getTime() + (num*86400000) ); + return this; + }); + + /** + * Add a number of hours to the date object. + * + * @example var dtm = new Date("01/12/2008"); + * dtm.addHours(24); + * dtm.toString(); + * @result 'Sun Jan 13 2008 00:00:00' + * + * @name addHours + * @type Date + * @cat Plugins/Methods/Date + */ + add("addHours", function(num) { + this.setHours(this.getHours() + num); + return this; + }); + + /** + * Add a number of minutes to the date object. + * + * @example var dtm = new Date("01/12/2008"); + * dtm.addMinutes(60); + * dtm.toString(); + * @result 'Sat Jan 12 2008 01:00:00' + * + * @name addMinutes + * @type Date + * @cat Plugins/Methods/Date + */ + add("addMinutes", function(num) { + this.setMinutes(this.getMinutes() + num); + return this; + }); + + /** + * Add a number of seconds to the date object. + * + * @example var dtm = new Date("01/12/2008"); + * dtm.addSeconds(60); + * dtm.toString(); + * @result 'Sat Jan 12 2008 00:01:00' + * + * @name addSeconds + * @type Date + * @cat Plugins/Methods/Date + */ + add("addSeconds", function(num) { + this.setSeconds(this.getSeconds() + num); + return this; + }); + + /** + * Sets the time component of this Date to zero for cleaner, easier comparison of dates where time is not relevant. + * + * @example var dtm = new Date(); + * dtm.zeroTime(); + * dtm.toString(); + * @result 'Sat Jan 12 2008 00:01:00' + * + * @name zeroTime + * @type Date + * @cat Plugins/Methods/Date + * @author Kelvin Luck + */ + add("zeroTime", function() { + this.setMilliseconds(0); + this.setSeconds(0); + this.setMinutes(0); + this.setHours(0); + return this; + }); + + /** + * Returns a string representation of the date object according to Date.format. + * (Date.toString may be used in other places so I purposefully didn't overwrite it) + * + * @example var dtm = new Date("01/12/2008"); + * dtm.asString(); + * @result '12/01/2008' // (where Date.format == 'dd/mm/yyyy' + * + * @name asString + * @type Date + * @cat Plugins/Methods/Date + * @author Kelvin Luck + */ + add("asString", function(format) { + var r = format || Date.format; + return r + .split('yyyy').join(this.getFullYear()) + .split('yy').join((this.getFullYear() + '').substring(2)) + .split('mmmm').join(this.getMonthName(false)) + .split('mmm').join(this.getMonthName(true)) + .split('mm').join(_zeroPad(this.getMonth()+1)) + .split('dd').join(_zeroPad(this.getDate())) + .split('hh').join(_zeroPad(this.getHours())) + .split('min').join(_zeroPad(this.getMinutes())) + .split('ss').join(_zeroPad(this.getSeconds())); + }); + + /** + * Returns a new date object created from the passed String according to Date.format or false if the attempt to do this results in an invalid date object + * (We can't simple use Date.parse as it's not aware of locale and I chose not to overwrite it incase it's functionality is being relied on elsewhere) + * + * @example var dtm = Date.fromString("12/01/2008"); + * dtm.toString(); + * @result 'Sat Jan 12 2008 00:00:00' // (where Date.format == 'dd/mm/yyyy' + * + * @name fromString + * @type Date + * @cat Plugins/Methods/Date + * @author Kelvin Luck + */ + Date.fromString = function(s, format) + { + var f = format || Date.format; + var d = new Date('01/01/1977'); + + var mLength = 0; + + var iM = f.indexOf('mmmm'); + if (iM > -1) { + for (var i=0; i -1) { + var mStr = s.substr(iM, 3); + for (var i=0; i -1) { + if (iM < iY) + { + iY += mLength; + } + d.setFullYear(Number(s.substr(iY, 4))); + } else { + if (iM < iY) + { + iY += mLength; + } + // TODO - this doesn't work very well - are there any rules for what is meant by a two digit year? + d.setFullYear(Number(Date.fullYearStart + s.substr(f.indexOf('yy'), 2))); + } + var iD = f.indexOf('dd'); + if (iM < iD) + { + iD += mLength; + } + d.setDate(Number(s.substr(iD, 2))); + if (isNaN(d.getTime())) { + return false; + } + return d; + }; + + // utility method + var _zeroPad = function(num) { + var s = '0'+num; + return s.substring(s.length-2) + //return ('0'+num).substring(-2); // doesn't work on IE :( + }; + +})(); \ No newline at end of file diff --git a/js/datepicker.js b/js/datepicker.js new file mode 100644 index 000000000..5b19e6893 --- /dev/null +++ b/js/datepicker.js @@ -0,0 +1,1216 @@ +/** + * Copyright (c) 2008 Kelvin Luck (http://www.kelvinluck.com/) + * Dual licensed under the MIT (http://www.opensource.org/licenses/mit-license.php) + * and GPL (http://www.opensource.org/licenses/gpl-license.php) licenses. + * . + * $Id: jquery.datePicker.js 102 2010-09-13 14:00:54Z kelvin.luck $ + **/ + +(function($){ + + $.fn.extend({ +/** + * Render a calendar table into any matched elements. + * + * @param Object s (optional) Customize your calendars. + * @option Number month The month to render (NOTE that months are zero based). Default is today's month. + * @option Number year The year to render. Default is today's year. + * @option Function renderCallback A reference to a function that is called as each cell is rendered and which can add classes and event listeners to the created nodes. Default is no callback. + * @option Number showHeader Whether or not to show the header row, possible values are: $.dpConst.SHOW_HEADER_NONE (no header), $.dpConst.SHOW_HEADER_SHORT (first letter of each day) and $.dpConst.SHOW_HEADER_LONG (full name of each day). Default is $.dpConst.SHOW_HEADER_SHORT. + * @option String hoverClass The class to attach to each cell when you hover over it (to allow you to use hover effects in IE6 which doesn't support the :hover pseudo-class on elements other than links). Default is dp-hover. Pass false if you don't want a hover class. + * @type jQuery + * @name renderCalendar + * @cat plugins/datePicker + * @author Kelvin Luck (http://www.kelvinluck.com/) + * + * @example $('#calendar-me').renderCalendar({month:0, year:2007}); + * @desc Renders a calendar displaying January 2007 into the element with an id of calendar-me. + * + * @example + * var testCallback = function($td, thisDate, month, year) + * { + * if ($td.is('.current-month') && thisDate.getDay() == 4) { + * var d = thisDate.getDate(); + * $td.bind( + * 'click', + * function() + * { + * alert('You clicked on ' + d + '/' + (Number(month)+1) + '/' + year); + * } + * ).addClass('thursday'); + * } else if (thisDate.getDay() == 5) { + * $td.html('Friday the ' + $td.html() + 'th'); + * } + * } + * $('#calendar-me').renderCalendar({month:0, year:2007, renderCallback:testCallback}); + * + * @desc Renders a calendar displaying January 2007 into the element with an id of calendar-me. Every Thursday in the current month has a class of "thursday" applied to it, is clickable and shows an alert when clicked. Every Friday on the calendar has the number inside replaced with text. + **/ + renderCalendar : function(s) + { + var dc = function(a) + { + return document.createElement(a); + }; + + s = $.extend({}, $.fn.datePicker.defaults, s); + + if (s.showHeader != $.dpConst.SHOW_HEADER_NONE) { + var headRow = $(dc('tr')); + for (var i=Date.firstDayOfWeek; i 1) firstDayOffset -= 7; + var weeksToDraw = Math.ceil(( (-1*firstDayOffset+1) + currentDate.getDaysInMonth() ) /7); + currentDate.addDays(firstDayOffset-1); + + var doHover = function(firstDayInBounds) + { + return function() + { + if (s.hoverClass) { + var $this = $(this); + if (!s.selectWeek) { + $this.addClass(s.hoverClass); + } else if (firstDayInBounds && !$this.is('.disabled')) { + $this.parent().addClass('activeWeekHover'); + } + } + } + }; + var unHover = function() + { + if (s.hoverClass) { + var $this = $(this); + $this.removeClass(s.hoverClass); + $this.parent().removeClass('activeWeekHover'); + } + }; + + var w = 0; + while (w++ s.dpController.startDate : false; + for (var i=0; i<7; i++) { + var thisMonth = currentDate.getMonth() == month; + var d = $(dc('td')) + .text(currentDate.getDate() + '') + .addClass((thisMonth ? 'current-month ' : 'other-month ') + + (currentDate.isWeekend() ? 'weekend ' : 'weekday ') + + (thisMonth && currentDate.getTime() == today.getTime() ? 'today ' : '') + ) + .data('datePickerDate', currentDate.asString()) + .hover(doHover(firstDayInBounds), unHover) + ; + r.append(d); + if (s.renderCallback) { + s.renderCallback(d, currentDate, month, year); + } + // addDays(1) fails in some locales due to daylight savings. See issue 39. + //currentDate.addDays(1); + // set the time to midday to avoid any weird timezone issues?? + currentDate = new Date(currentDate.getFullYear(), currentDate.getMonth(), currentDate.getDate()+1, 12, 0, 0); + } + tbody.append(r); + } + calendarTable.append(tbody); + + return this.each( + function() + { + $(this).empty().append(calendarTable); + } + ); + }, +/** + * Create a datePicker associated with each of the matched elements. + * + * The matched element will receive a few custom events with the following signatures: + * + * dateSelected(event, date, $td, status) + * Triggered when a date is selected. event is a reference to the event, date is the Date selected, $td is a jquery object wrapped around the TD that was clicked on and status is whether the date was selected (true) or deselected (false) + * + * dpClosed(event, selected) + * Triggered when the date picker is closed. event is a reference to the event and selected is an Array containing Date objects. + * + * dpMonthChanged(event, displayedMonth, displayedYear) + * Triggered when the month of the popped up calendar is changed. event is a reference to the event, displayedMonth is the number of the month now displayed (zero based) and displayedYear is the year of the month. + * + * dpDisplayed(event, $datePickerDiv) + * Triggered when the date picker is created. $datePickerDiv is the div containing the date picker. Use this event to add custom content/ listeners to the popped up date picker. + * + * @param Object s (optional) Customize your date pickers. + * @option Number month The month to render when the date picker is opened (NOTE that months are zero based). Default is today's month. + * @option Number year The year to render when the date picker is opened. Default is today's year. + * @option String startDate The first date date can be selected. + * @option String endDate The last date that can be selected. + * @option Boolean inline Whether to create the datePicker as inline (e.g. always on the page) or as a model popup. Default is false (== modal popup) + * @option Boolean createButton Whether to create a .dp-choose-date anchor directly after the matched element which when clicked will trigger the showing of the date picker. Default is true. + * @option Boolean showYearNavigation Whether to display buttons which allow the user to navigate through the months a year at a time. Default is true. + * @option Boolean closeOnSelect Whether to close the date picker when a date is selected. Default is true. + * @option Boolean displayClose Whether to create a "Close" button within the date picker popup. Default is false. + * @option Boolean selectMultiple Whether a user should be able to select multiple dates with this date picker. Default is false. + * @option Number numSelectable The maximum number of dates that can be selected where selectMultiple is true. Default is a very high number. + * @option Boolean clickInput If the matched element is an input type="text" and this option is true then clicking on the input will cause the date picker to appear. + * @option Boolean rememberViewedMonth Whether the datePicker should remember the last viewed month and open on it. If false then the date picker will always open with the month for the first selected date visible. + * @option Boolean selectWeek Whether to select a complete week at a time... + * @option Number verticalPosition The vertical alignment of the popped up date picker to the matched element. One of $.dpConst.POS_TOP and $.dpConst.POS_BOTTOM. Default is $.dpConst.POS_TOP. + * @option Number horizontalPosition The horizontal alignment of the popped up date picker to the matched element. One of $.dpConst.POS_LEFT and $.dpConst.POS_RIGHT. + * @option Number verticalOffset The number of pixels offset from the defined verticalPosition of this date picker that it should pop up in. Default in 0. + * @option Number horizontalOffset The number of pixels offset from the defined horizontalPosition of this date picker that it should pop up in. Default in 0. + * @option (Function|Array) renderCallback A reference to a function (or an array of separate functions) that is called as each cell is rendered and which can add classes and event listeners to the created nodes. Each callback function will receive four arguments; a jquery object wrapping the created TD, a Date object containing the date this TD represents, a number giving the currently rendered month and a number giving the currently rendered year. Default is no callback. + * @option String hoverClass The class to attach to each cell when you hover over it (to allow you to use hover effects in IE6 which doesn't support the :hover pseudo-class on elements other than links). Default is dp-hover. Pass false if you don't want a hover class. + * @option String autoFocusNextInput Whether focus should be passed onto the next input in the form (true) or remain on this input (false) when a date is selected and the calendar closes + * @type jQuery + * @name datePicker + * @cat plugins/datePicker + * @author Kelvin Luck (http://www.kelvinluck.com/) + * + * @example $('input.date-picker').datePicker(); + * @desc Creates a date picker button next to all matched input elements. When the button is clicked on the value of the selected date will be placed in the corresponding input (formatted according to Date.format). + * + * @example demo/index.html + * @desc See the projects homepage for many more complex examples... + **/ + datePicker : function(s) + { + if (!$.event._dpCache) $.event._dpCache = []; + + // initialise the date picker controller with the relevant settings... + s = $.extend({}, $.fn.datePicker.defaults, s); + + return this.each( + function() + { + var $this = $(this); + var alreadyExists = true; + + if (!this._dpId) { + this._dpId = $.event.guid++; + $.event._dpCache[this._dpId] = new DatePicker(this); + alreadyExists = false; + } + + if (s.inline) { + s.createButton = false; + s.displayClose = false; + s.closeOnSelect = false; + $this.empty(); + } + + var controller = $.event._dpCache[this._dpId]; + + controller.init(s); + + if (!alreadyExists && s.createButton) { + // create it! + controller.button = $('' + $.dpText.TEXT_CHOOSE_DATE + '') + .bind( + 'click', + function() + { + $this.dpDisplay(this); + this.blur(); + return false; + } + ); + $this.after(controller.button); + } + + if (!alreadyExists && $this.is(':text')) { + $this + .bind( + 'dateSelected', + function(e, selectedDate, $td) + { + this.value = selectedDate.asString(); + } + ).bind( + 'change', + function() + { + if (this.value == '') { + controller.clearSelected(); + } else { + var d = Date.fromString(this.value); + if (d) { + controller.setSelected(d, true, true); + } + } + } + ); + if (s.clickInput) { + $this.bind( + 'click', + function() + { + // The change event doesn't happen until the input loses focus so we need to manually trigger it... + $this.trigger('change'); + $this.dpDisplay(); + } + ); + } + var d = Date.fromString(this.value); + if (this.value != '' && d) { + controller.setSelected(d, true, true); + } + } + + $this.addClass('dp-applied'); + + } + ) + }, +/** + * Disables or enables this date picker + * + * @param Boolean s Whether to disable (true) or enable (false) this datePicker + * @type jQuery + * @name dpSetDisabled + * @cat plugins/datePicker + * @author Kelvin Luck (http://www.kelvinluck.com/) + * + * @example $('.date-picker').datePicker(); + * $('.date-picker').dpSetDisabled(true); + * @desc Prevents this date picker from displaying and adds a class of dp-disabled to it (and it's associated button if it has one) for styling purposes. If the matched element is an input field then it will also set the disabled attribute to stop people directly editing the field. + **/ + dpSetDisabled : function(s) + { + return _w.call(this, 'setDisabled', s); + }, +/** + * Updates the first selectable date for any date pickers on any matched elements. + * + * @param String d A string representing the first selectable date (formatted according to Date.format). + * @type jQuery + * @name dpSetStartDate + * @cat plugins/datePicker + * @author Kelvin Luck (http://www.kelvinluck.com/) + * + * @example $('.date-picker').datePicker(); + * $('.date-picker').dpSetStartDate('01/01/2000'); + * @desc Creates a date picker associated with all elements with a class of "date-picker" then sets the first selectable date for each of these to the first day of the millenium. + **/ + dpSetStartDate : function(d) + { + return _w.call(this, 'setStartDate', d); + }, +/** + * Updates the last selectable date for any date pickers on any matched elements. + * + * @param String d A string representing the last selectable date (formatted according to Date.format). + * @type jQuery + * @name dpSetEndDate + * @cat plugins/datePicker + * @author Kelvin Luck (http://www.kelvinluck.com/) + * + * @example $('.date-picker').datePicker(); + * $('.date-picker').dpSetEndDate('01/01/2010'); + * @desc Creates a date picker associated with all elements with a class of "date-picker" then sets the last selectable date for each of these to the first Janurary 2010. + **/ + dpSetEndDate : function(d) + { + return _w.call(this, 'setEndDate', d); + }, +/** + * Gets a list of Dates currently selected by this datePicker. This will be an empty array if no dates are currently selected or NULL if there is no datePicker associated with the matched element. + * + * @type Array + * @name dpGetSelected + * @cat plugins/datePicker + * @author Kelvin Luck (http://www.kelvinluck.com/) + * + * @example $('.date-picker').datePicker(); + * alert($('.date-picker').dpGetSelected()); + * @desc Will alert an empty array (as nothing is selected yet) + **/ + dpGetSelected : function() + { + var c = _getController(this[0]); + if (c) { + return c.getSelected(); + } + return null; + }, +/** + * Selects or deselects a date on any matched element's date pickers. Deselcting is only useful on date pickers where selectMultiple==true. Selecting will only work if the passed date is within the startDate and endDate boundries for a given date picker. + * + * @param String d A string representing the date you want to select (formatted according to Date.format). + * @param Boolean v Whether you want to select (true) or deselect (false) this date. Optional - default = true. + * @param Boolean m Whether you want the date picker to open up on the month of this date when it is next opened. Optional - default = true. + * @param Boolean e Whether you want the date picker to dispatch events related to this change of selection. Optional - default = true. + * @type jQuery + * @name dpSetSelected + * @cat plugins/datePicker + * @author Kelvin Luck (http://www.kelvinluck.com/) + * + * @example $('.date-picker').datePicker(); + * $('.date-picker').dpSetSelected('01/01/2010'); + * @desc Creates a date picker associated with all elements with a class of "date-picker" then sets the selected date on these date pickers to the first Janurary 2010. When the date picker is next opened it will display Janurary 2010. + **/ + dpSetSelected : function(d, v, m, e) + { + if (v == undefined) v=true; + if (m == undefined) m=true; + if (e == undefined) e=true; + return _w.call(this, 'setSelected', Date.fromString(d), v, m, e); + }, +/** + * Sets the month that will be displayed when the date picker is next opened. If the passed month is before startDate then the month containing startDate will be displayed instead. If the passed month is after endDate then the month containing the endDate will be displayed instead. + * + * @param Number m The month you want the date picker to display. Optional - defaults to the currently displayed month. + * @param Number y The year you want the date picker to display. Optional - defaults to the currently displayed year. + * @type jQuery + * @name dpSetDisplayedMonth + * @cat plugins/datePicker + * @author Kelvin Luck (http://www.kelvinluck.com/) + * + * @example $('.date-picker').datePicker(); + * $('.date-picker').dpSetDisplayedMonth(10, 2008); + * @desc Creates a date picker associated with all elements with a class of "date-picker" then sets the selected date on these date pickers to the first Janurary 2010. When the date picker is next opened it will display Janurary 2010. + **/ + dpSetDisplayedMonth : function(m, y) + { + return _w.call(this, 'setDisplayedMonth', Number(m), Number(y), true); + }, +/** + * Displays the date picker associated with the matched elements. Since only one date picker can be displayed at once then the date picker associated with the last matched element will be the one that is displayed. + * + * @param HTMLElement e An element that you want the date picker to pop up relative in position to. Optional - default behaviour is to pop up next to the element associated with this date picker. + * @type jQuery + * @name dpDisplay + * @cat plugins/datePicker + * @author Kelvin Luck (http://www.kelvinluck.com/) + * + * @example $('#date-picker').datePicker(); + * $('#date-picker').dpDisplay(); + * @desc Creates a date picker associated with the element with an id of date-picker and then causes it to pop up. + **/ + dpDisplay : function(e) + { + return _w.call(this, 'display', e); + }, +/** + * Sets a function or array of functions that is called when each TD of the date picker popup is rendered to the page + * + * @param (Function|Array) a A function or an array of functions that are called when each td is rendered. Each function will receive four arguments; a jquery object wrapping the created TD, a Date object containing the date this TD represents, a number giving the currently rendered month and a number giving the currently rendered year. + * @type jQuery + * @name dpSetRenderCallback + * @cat plugins/datePicker + * @author Kelvin Luck (http://www.kelvinluck.com/) + * + * @example $('#date-picker').datePicker(); + * $('#date-picker').dpSetRenderCallback(function($td, thisDate, month, year) + * { + * // do stuff as each td is rendered dependant on the date in the td and the displayed month and year + * }); + * @desc Creates a date picker associated with the element with an id of date-picker and then creates a function which is called as each td is rendered when this date picker is displayed. + **/ + dpSetRenderCallback : function(a) + { + return _w.call(this, 'setRenderCallback', a); + }, +/** + * Sets the position that the datePicker will pop up (relative to it's associated element) + * + * @param Number v The vertical alignment of the created date picker to it's associated element. Possible values are $.dpConst.POS_TOP and $.dpConst.POS_BOTTOM + * @param Number h The horizontal alignment of the created date picker to it's associated element. Possible values are $.dpConst.POS_LEFT and $.dpConst.POS_RIGHT + * @type jQuery + * @name dpSetPosition + * @cat plugins/datePicker + * @author Kelvin Luck (http://www.kelvinluck.com/) + * + * @example $('#date-picker').datePicker(); + * $('#date-picker').dpSetPosition($.dpConst.POS_BOTTOM, $.dpConst.POS_RIGHT); + * @desc Creates a date picker associated with the element with an id of date-picker and makes it so that when this date picker pops up it will be bottom and right aligned to the #date-picker element. + **/ + dpSetPosition : function(v, h) + { + return _w.call(this, 'setPosition', v, h); + }, +/** + * Sets the offset that the popped up date picker will have from it's default position relative to it's associated element (as set by dpSetPosition) + * + * @param Number v The vertical offset of the created date picker. + * @param Number h The horizontal offset of the created date picker. + * @type jQuery + * @name dpSetOffset + * @cat plugins/datePicker + * @author Kelvin Luck (http://www.kelvinluck.com/) + * + * @example $('#date-picker').datePicker(); + * $('#date-picker').dpSetOffset(-20, 200); + * @desc Creates a date picker associated with the element with an id of date-picker and makes it so that when this date picker pops up it will be 20 pixels above and 200 pixels to the right of it's default position. + **/ + dpSetOffset : function(v, h) + { + return _w.call(this, 'setOffset', v, h); + }, +/** + * Closes the open date picker associated with this element. + * + * @type jQuery + * @name dpClose + * @cat plugins/datePicker + * @author Kelvin Luck (http://www.kelvinluck.com/) + * + * @example $('.date-pick') + * .datePicker() + * .bind( + * 'focus', + * function() + * { + * $(this).dpDisplay(); + * } + * ).bind( + * 'blur', + * function() + * { + * $(this).dpClose(); + * } + * ); + **/ + dpClose : function() + { + return _w.call(this, '_closeCalendar', false, this[0]); + }, +/** + * Rerenders the date picker's current month (for use with inline calendars and renderCallbacks). + * + * @type jQuery + * @name dpRerenderCalendar + * @cat plugins/datePicker + * @author Kelvin Luck (http://www.kelvinluck.com/) + * + **/ + dpRerenderCalendar : function() + { + return _w.call(this, '_rerenderCalendar'); + }, + // private function called on unload to clean up any expandos etc and prevent memory links... + _dpDestroy : function() + { + // TODO - implement this? + } + }); + + // private internal function to cut down on the amount of code needed where we forward + // dp* methods on the jQuery object on to the relevant DatePicker controllers... + var _w = function(f, a1, a2, a3, a4) + { + return this.each( + function() + { + var c = _getController(this); + if (c) { + c[f](a1, a2, a3, a4); + } + } + ); + }; + + function DatePicker(ele) + { + this.ele = ele; + + // initial values... + this.displayedMonth = null; + this.displayedYear = null; + this.startDate = null; + this.endDate = null; + this.showYearNavigation = null; + this.closeOnSelect = null; + this.displayClose = null; + this.rememberViewedMonth= null; + this.selectMultiple = null; + this.numSelectable = null; + this.numSelected = null; + this.verticalPosition = null; + this.horizontalPosition = null; + this.verticalOffset = null; + this.horizontalOffset = null; + this.button = null; + this.renderCallback = []; + this.selectedDates = {}; + this.inline = null; + this.context = '#dp-popup'; + this.settings = {}; + }; + $.extend( + DatePicker.prototype, + { + init : function(s) + { + this.setStartDate(s.startDate); + this.setEndDate(s.endDate); + this.setDisplayedMonth(Number(s.month), Number(s.year)); + this.setRenderCallback(s.renderCallback); + this.showYearNavigation = s.showYearNavigation; + this.closeOnSelect = s.closeOnSelect; + this.displayClose = s.displayClose; + this.rememberViewedMonth = s.rememberViewedMonth; + this.selectMultiple = s.selectMultiple; + this.numSelectable = s.selectMultiple ? s.numSelectable : 1; + this.numSelected = 0; + this.verticalPosition = s.verticalPosition; + this.horizontalPosition = s.horizontalPosition; + this.hoverClass = s.hoverClass; + this.setOffset(s.verticalOffset, s.horizontalOffset); + this.inline = s.inline; + this.settings = s; + if (this.inline) { + this.context = this.ele; + this.display(); + } + }, + setStartDate : function(d) + { + if (d) { + this.startDate = Date.fromString(d); + } + if (!this.startDate) { + this.startDate = (new Date()).zeroTime(); + } + this.setDisplayedMonth(this.displayedMonth, this.displayedYear); + }, + setEndDate : function(d) + { + if (d) { + this.endDate = Date.fromString(d); + } + if (!this.endDate) { + this.endDate = (new Date('12/31/2999')); // using the JS Date.parse function which expects mm/dd/yyyy + } + if (this.endDate.getTime() < this.startDate.getTime()) { + this.endDate = this.startDate; + } + this.setDisplayedMonth(this.displayedMonth, this.displayedYear); + }, + setPosition : function(v, h) + { + this.verticalPosition = v; + this.horizontalPosition = h; + }, + setOffset : function(v, h) + { + this.verticalOffset = parseInt(v) || 0; + this.horizontalOffset = parseInt(h) || 0; + }, + setDisabled : function(s) + { + $e = $(this.ele); + $e[s ? 'addClass' : 'removeClass']('dp-disabled'); + if (this.button) { + $but = $(this.button); + $but[s ? 'addClass' : 'removeClass']('dp-disabled'); + $but.attr('title', s ? '' : $.dpText.TEXT_CHOOSE_DATE); + } + if ($e.is(':text')) { + $e.attr('disabled', s ? 'disabled' : ''); + } + }, + setDisplayedMonth : function(m, y, rerender) + { + if (this.startDate == undefined || this.endDate == undefined) { + return; + } + var s = new Date(this.startDate.getTime()); + s.setDate(1); + var e = new Date(this.endDate.getTime()); + e.setDate(1); + + var t; + if ((!m && !y) || (isNaN(m) && isNaN(y))) { + // no month or year passed - default to current month + t = new Date().zeroTime(); + t.setDate(1); + } else if (isNaN(m)) { + // just year passed in - presume we want the displayedMonth + t = new Date(y, this.displayedMonth, 1); + } else if (isNaN(y)) { + // just month passed in - presume we want the displayedYear + t = new Date(this.displayedYear, m, 1); + } else { + // year and month passed in - that's the date we want! + t = new Date(y, m, 1) + } + // check if the desired date is within the range of our defined startDate and endDate + if (t.getTime() < s.getTime()) { + t = s; + } else if (t.getTime() > e.getTime()) { + t = e; + } + var oldMonth = this.displayedMonth; + var oldYear = this.displayedYear; + this.displayedMonth = t.getMonth(); + this.displayedYear = t.getFullYear(); + + if (rerender && (this.displayedMonth != oldMonth || this.displayedYear != oldYear)) + { + this._rerenderCalendar(); + $(this.ele).trigger('dpMonthChanged', [this.displayedMonth, this.displayedYear]); + } + }, + setSelected : function(d, v, moveToMonth, dispatchEvents) + { + if (d < this.startDate || d.zeroTime() > this.endDate.zeroTime()) { + // Don't allow people to select dates outside range... + return; + } + var s = this.settings; + if (s.selectWeek) + { + d = d.addDays(- (d.getDay() - Date.firstDayOfWeek + 7) % 7); + if (d < this.startDate) // The first day of this week is before the start date so is unselectable... + { + return; + } + } + if (v == this.isSelected(d)) // this date is already un/selected + { + return; + } + if (this.selectMultiple == false) { + this.clearSelected(); + } else if (v && this.numSelected == this.numSelectable) { + // can't select any more dates... + return; + } + if (moveToMonth && (this.displayedMonth != d.getMonth() || this.displayedYear != d.getFullYear())) { + this.setDisplayedMonth(d.getMonth(), d.getFullYear(), true); + } + this.selectedDates[d.asString()] = v; + this.numSelected += v ? 1 : -1; + var selectorString = 'td.' + (d.getMonth() == this.displayedMonth ? 'current-month' : 'other-month'); + var $td; + $(selectorString, this.context).each( + function() + { + if ($(this).data('datePickerDate') == d.asString()) { + $td = $(this); + if (s.selectWeek) + { + $td.parent()[v ? 'addClass' : 'removeClass']('selectedWeek'); + } + $td[v ? 'addClass' : 'removeClass']('selected'); + } + } + ); + $('td', this.context).not('.selected')[this.selectMultiple && this.numSelected == this.numSelectable ? 'addClass' : 'removeClass']('unselectable'); + + if (dispatchEvents) + { + var s = this.isSelected(d); + $e = $(this.ele); + var dClone = Date.fromString(d.asString()); + $e.trigger('dateSelected', [dClone, $td, s]); + $e.trigger('change'); + } + }, + isSelected : function(d) + { + return this.selectedDates[d.asString()]; + }, + getSelected : function() + { + var r = []; + for(var s in this.selectedDates) { + if (this.selectedDates[s] == true) { + r.push(Date.fromString(s)); + } + } + return r; + }, + clearSelected : function() + { + this.selectedDates = {}; + this.numSelected = 0; + $('td.selected', this.context).removeClass('selected').parent().removeClass('selectedWeek'); + }, + display : function(eleAlignTo) + { + if ($(this.ele).is('.dp-disabled')) return; + + eleAlignTo = eleAlignTo || this.ele; + var c = this; + var $ele = $(eleAlignTo); + var eleOffset = $ele.offset(); + + var $createIn; + var attrs; + var attrsCalendarHolder; + var cssRules; + + if (c.inline) { + $createIn = $(this.ele); + attrs = { + 'id' : 'calendar-' + this.ele._dpId, + 'class' : 'dp-popup dp-popup-inline' + }; + + $('.dp-popup', $createIn).remove(); + cssRules = { + }; + } else { + $createIn = $('body'); + attrs = { + 'id' : 'dp-popup', + 'class' : 'dp-popup' + }; + cssRules = { + 'top' : eleOffset.top + c.verticalOffset, + 'left' : eleOffset.left + c.horizontalOffset + }; + + var _checkMouse = function(e) + { + var el = e.target; + var cal = $('#dp-popup')[0]; + + while (true){ + if (el == cal) { + return true; + } else if (el == document) { + c._closeCalendar(); + return false; + } else { + el = $(el).parent()[0]; + } + } + }; + this._checkMouse = _checkMouse; + + c._closeCalendar(true); + $(document).bind( + 'keydown.datepicker', + function(event) + { + if (event.keyCode == 27) { + c._closeCalendar(); + } + } + ); + } + + if (!c.rememberViewedMonth) + { + var selectedDate = this.getSelected()[0]; + if (selectedDate) { + selectedDate = new Date(selectedDate); + this.setDisplayedMonth(selectedDate.getMonth(), selectedDate.getFullYear(), false); + } + } + + $createIn + .append( + $('
                          ') + .attr(attrs) + .css(cssRules) + .append( +// $('aaa'), + $('

                          '), + $('
                          ') + .append( + $('<<') + .bind( + 'click', + function() + { + return c._displayNewMonth.call(c, this, 0, -1); + } + ), + $('<') + .bind( + 'click', + function() + { + return c._displayNewMonth.call(c, this, -1, 0); + } + ) + ), + $('
                          ') + .append( + $('>>') + .bind( + 'click', + function() + { + return c._displayNewMonth.call(c, this, 0, 1); + } + ), + $('>') + .bind( + 'click', + function() + { + return c._displayNewMonth.call(c, this, 1, 0); + } + ) + ), + $('
                          ') + ) + .bgIframe() + ); + + var $pop = this.inline ? $('.dp-popup', this.context) : $('#dp-popup'); + + if (this.showYearNavigation == false) { + $('.dp-nav-prev-year, .dp-nav-next-year', c.context).css('display', 'none'); + } + if (this.displayClose) { + $pop.append( + $('' + $.dpText.TEXT_CLOSE + '') + .bind( + 'click', + function() + { + c._closeCalendar(); + return false; + } + ) + ); + } + c._renderCalendar(); + + $(this.ele).trigger('dpDisplayed', $pop); + + if (!c.inline) { + if (this.verticalPosition == $.dpConst.POS_BOTTOM) { + $pop.css('top', eleOffset.top + $ele.height() - $pop.height() + c.verticalOffset); + } + if (this.horizontalPosition == $.dpConst.POS_RIGHT) { + $pop.css('left', eleOffset.left + $ele.width() - $pop.width() + c.horizontalOffset); + } +// $('.selectee', this.context).focus(); + $(document).bind('mousedown.datepicker', this._checkMouse); + } + + }, + setRenderCallback : function(a) + { + if (a == null) return; + if (a && typeof(a) == 'function') { + a = [a]; + } + this.renderCallback = this.renderCallback.concat(a); + }, + cellRender : function ($td, thisDate, month, year) { + var c = this.dpController; + var d = new Date(thisDate.getTime()); + + // add our click handlers to deal with it when the days are clicked... + + $td.bind( + 'click', + function() + { + var $this = $(this); + if (!$this.is('.disabled')) { + c.setSelected(d, !$this.is('.selected') || !c.selectMultiple, false, true); + if (c.closeOnSelect) { + // Focus the next input in the form… + if (c.settings.autoFocusNextInput) { + var ele = c.ele; + var found = false; + $(':input', ele.form).each( + function() + { + if (found) { + $(this).focus(); + return false; + } + if (this == ele) { + found = true; + } + } + ); + } else { + c.ele.focus(); + } + c._closeCalendar(); + } + } + } + ); + if (c.isSelected(d)) { + $td.addClass('selected'); + if (c.settings.selectWeek) + { + $td.parent().addClass('selectedWeek'); + } + } else if (c.selectMultiple && c.numSelected == c.numSelectable) { + $td.addClass('unselectable'); + } + + }, + _applyRenderCallbacks : function() + { + var c = this; + $('td', this.context).each( + function() + { + for (var i=0; i 20) { + $this.addClass('disabled'); + } + } + ); + var d = this.startDate.getDate(); + $('.dp-calendar td.current-month', this.context).each( + function() + { + var $this = $(this); + if (Number($this.text()) < d) { + $this.addClass('disabled'); + } + } + ); + } else { + $('.dp-nav-prev-year', this.context).removeClass('disabled'); + $('.dp-nav-prev-month', this.context).removeClass('disabled'); + var d = this.startDate.getDate(); + if (d > 20) { + // check if the startDate is last month as we might need to add some disabled classes... + var st = this.startDate.getTime(); + var sd = new Date(st); + sd.addMonths(1); + if (this.displayedYear == sd.getFullYear() && this.displayedMonth == sd.getMonth()) { + $('.dp-calendar td.other-month', this.context).each( + function() + { + var $this = $(this); + if (Date.fromString($this.data('datePickerDate')).getTime() < st) { + $this.addClass('disabled'); + } + } + ); + } + } + } + if (this.displayedYear == this.endDate.getFullYear() && this.displayedMonth == this.endDate.getMonth()) { + $('.dp-nav-next-year', this.context).addClass('disabled'); + $('.dp-nav-next-month', this.context).addClass('disabled'); + $('.dp-calendar td.other-month', this.context).each( + function() + { + var $this = $(this); + if (Number($this.text()) < 14) { + $this.addClass('disabled'); + } + } + ); + var d = this.endDate.getDate(); + $('.dp-calendar td.current-month', this.context).each( + function() + { + var $this = $(this); + if (Number($this.text()) > d) { + $this.addClass('disabled'); + } + } + ); + } else { + $('.dp-nav-next-year', this.context).removeClass('disabled'); + $('.dp-nav-next-month', this.context).removeClass('disabled'); + var d = this.endDate.getDate(); + if (d < 13) { + // check if the endDate is next month as we might need to add some disabled classes... + var ed = new Date(this.endDate.getTime()); + ed.addMonths(-1); + if (this.displayedYear == ed.getFullYear() && this.displayedMonth == ed.getMonth()) { + $('.dp-calendar td.other-month', this.context).each( + function() + { + var $this = $(this); + var cellDay = Number($this.text()); + if (cellDay < 13 && cellDay > d) { + $this.addClass('disabled'); + } + } + ); + } + } + } + this._applyRenderCallbacks(); + }, + _closeCalendar : function(programatic, ele) + { + if (!ele || ele == this.ele) + { + $(document).unbind('mousedown.datepicker'); + $(document).unbind('keydown.datepicker'); + this._clearCalendar(); + $('#dp-popup a').unbind(); + $('#dp-popup').empty().remove(); + if (!programatic) { + $(this.ele).trigger('dpClosed', [this.getSelected()]); + } + } + }, + // empties the current dp-calendar div and makes sure that all events are unbound + // and expandos removed to avoid memory leaks... + _clearCalendar : function() + { + // TODO. + $('.dp-calendar td', this.context).unbind(); + $('.dp-calendar', this.context).empty(); + } + } + ); + + // static constants + $.dpConst = { + SHOW_HEADER_NONE : 0, + SHOW_HEADER_SHORT : 1, + SHOW_HEADER_LONG : 2, + POS_TOP : 0, + POS_BOTTOM : 1, + POS_LEFT : 0, + POS_RIGHT : 1, + DP_INTERNAL_FOCUS : 'dpInternalFocusTrigger' + }; + // localisable text + $.dpText = { + TEXT_PREV_YEAR : 'Previous year', + TEXT_PREV_MONTH : 'Previous month', + TEXT_NEXT_YEAR : 'Next year', + TEXT_NEXT_MONTH : 'Next month', + TEXT_CLOSE : 'Close', + TEXT_CHOOSE_DATE : 'Choose date', + HEADER_FORMAT : 'mmmm yyyy' + }; + // version + $.dpVersion = '$Id: jquery.datePicker.js 102 2010-09-13 14:00:54Z kelvin.luck $'; + + $.fn.datePicker.defaults = { + month : undefined, + year : undefined, + showHeader : $.dpConst.SHOW_HEADER_SHORT, + startDate : undefined, + endDate : undefined, + inline : false, + renderCallback : null, + createButton : true, + showYearNavigation : true, + closeOnSelect : true, + displayClose : false, + selectMultiple : false, + numSelectable : Number.MAX_VALUE, + clickInput : false, + rememberViewedMonth : true, + selectWeek : false, + verticalPosition : $.dpConst.POS_TOP, + horizontalPosition : $.dpConst.POS_LEFT, + verticalOffset : 0, + horizontalOffset : 0, + hoverClass : 'dp-hover', + autoFocusNextInput : false + }; + + function _getController(ele) + { + if (ele._dpId) return $.event._dpCache[ele._dpId]; + return false; + }; + + // make it so that no error is thrown if bgIframe plugin isn't included (allows you to use conditional + // comments to only include bgIframe where it is needed in IE without breaking this plugin). + if ($.fn.bgIframe == undefined) { + $.fn.bgIframe = function() {return this; }; + }; + + + // clean-up + $(window) + .bind('unload', function() { + var els = $.event._dpCache || []; + for (var i in els) { + $(els[i].ele)._dpDestroy(); + } + }); + + +})(jQuery); \ No newline at end of file diff --git a/js/jquery-1.2.6.min.js b/js/jquery-1.2.6.min.js new file mode 100644 index 000000000..82b98e1d7 --- /dev/null +++ b/js/jquery-1.2.6.min.js @@ -0,0 +1,32 @@ +/* + * jQuery 1.2.6 - New Wave Javascript + * + * Copyright (c) 2008 John Resig (jquery.com) + * Dual licensed under the MIT (MIT-LICENSE.txt) + * and GPL (GPL-LICENSE.txt) licenses. + * + * $Date: 2008-05-24 14:22:17 -0400 (Sat, 24 May 2008) $ + * $Rev: 5685 $ + */ +(function(){var _jQuery=window.jQuery,_$=window.$;var jQuery=window.jQuery=window.$=function(selector,context){return new jQuery.fn.init(selector,context);};var quickExpr=/^[^<]*(<(.|\s)+>)[^>]*$|^#(\w+)$/,isSimple=/^.[^:#\[\.]*$/,undefined;jQuery.fn=jQuery.prototype={init:function(selector,context){selector=selector||document;if(selector.nodeType){this[0]=selector;this.length=1;return this;}if(typeof selector=="string"){var match=quickExpr.exec(selector);if(match&&(match[1]||!context)){if(match[1])selector=jQuery.clean([match[1]],context);else{var elem=document.getElementById(match[3]);if(elem){if(elem.id!=match[3])return jQuery().find(selector);return jQuery(elem);}selector=[];}}else +return jQuery(context).find(selector);}else if(jQuery.isFunction(selector))return jQuery(document)[jQuery.fn.ready?"ready":"load"](selector);return this.setArray(jQuery.makeArray(selector));},jquery:"1.2.6",size:function(){return this.length;},length:0,get:function(num){return num==undefined?jQuery.makeArray(this):this[num];},pushStack:function(elems){var ret=jQuery(elems);ret.prevObject=this;return ret;},setArray:function(elems){this.length=0;Array.prototype.push.apply(this,elems);return this;},each:function(callback,args){return jQuery.each(this,callback,args);},index:function(elem){var ret=-1;return jQuery.inArray(elem&&elem.jquery?elem[0]:elem,this);},attr:function(name,value,type){var options=name;if(name.constructor==String)if(value===undefined)return this[0]&&jQuery[type||"attr"](this[0],name);else{options={};options[name]=value;}return this.each(function(i){for(name in options)jQuery.attr(type?this.style:this,name,jQuery.prop(this,options[name],type,i,name));});},css:function(key,value){if((key=='width'||key=='height')&&parseFloat(value)<0)value=undefined;return this.attr(key,value,"curCSS");},text:function(text){if(typeof text!="object"&&text!=null)return this.empty().append((this[0]&&this[0].ownerDocument||document).createTextNode(text));var ret="";jQuery.each(text||this,function(){jQuery.each(this.childNodes,function(){if(this.nodeType!=8)ret+=this.nodeType!=1?this.nodeValue:jQuery.fn.text([this]);});});return ret;},wrapAll:function(html){if(this[0])jQuery(html,this[0].ownerDocument).clone().insertBefore(this[0]).map(function(){var elem=this;while(elem.firstChild)elem=elem.firstChild;return elem;}).append(this);return this;},wrapInner:function(html){return this.each(function(){jQuery(this).contents().wrapAll(html);});},wrap:function(html){return this.each(function(){jQuery(this).wrapAll(html);});},append:function(){return this.domManip(arguments,true,false,function(elem){if(this.nodeType==1)this.appendChild(elem);});},prepend:function(){return this.domManip(arguments,true,true,function(elem){if(this.nodeType==1)this.insertBefore(elem,this.firstChild);});},before:function(){return this.domManip(arguments,false,false,function(elem){this.parentNode.insertBefore(elem,this);});},after:function(){return this.domManip(arguments,false,true,function(elem){this.parentNode.insertBefore(elem,this.nextSibling);});},end:function(){return this.prevObject||jQuery([]);},find:function(selector){var elems=jQuery.map(this,function(elem){return jQuery.find(selector,elem);});return this.pushStack(/[^+>] [^+>]/.test(selector)||selector.indexOf("..")>-1?jQuery.unique(elems):elems);},clone:function(events){var ret=this.map(function(){if(jQuery.browser.msie&&!jQuery.isXMLDoc(this)){var clone=this.cloneNode(true),container=document.createElement("div");container.appendChild(clone);return jQuery.clean([container.innerHTML])[0];}else +return this.cloneNode(true);});var clone=ret.find("*").andSelf().each(function(){if(this[expando]!=undefined)this[expando]=null;});if(events===true)this.find("*").andSelf().each(function(i){if(this.nodeType==3)return;var events=jQuery.data(this,"events");for(var type in events)for(var handler in events[type])jQuery.event.add(clone[i],type,events[type][handler],events[type][handler].data);});return ret;},filter:function(selector){return this.pushStack(jQuery.isFunction(selector)&&jQuery.grep(this,function(elem,i){return selector.call(elem,i);})||jQuery.multiFilter(selector,this));},not:function(selector){if(selector.constructor==String)if(isSimple.test(selector))return this.pushStack(jQuery.multiFilter(selector,this,true));else +selector=jQuery.multiFilter(selector,this);var isArrayLike=selector.length&&selector[selector.length-1]!==undefined&&!selector.nodeType;return this.filter(function(){return isArrayLike?jQuery.inArray(this,selector)<0:this!=selector;});},add:function(selector){return this.pushStack(jQuery.unique(jQuery.merge(this.get(),typeof selector=='string'?jQuery(selector):jQuery.makeArray(selector))));},is:function(selector){return!!selector&&jQuery.multiFilter(selector,this).length>0;},hasClass:function(selector){return this.is("."+selector);},val:function(value){if(value==undefined){if(this.length){var elem=this[0];if(jQuery.nodeName(elem,"select")){var index=elem.selectedIndex,values=[],options=elem.options,one=elem.type=="select-one";if(index<0)return null;for(var i=one?index:0,max=one?index+1:options.length;i=0||jQuery.inArray(this.name,value)>=0);else if(jQuery.nodeName(this,"select")){var values=jQuery.makeArray(value);jQuery("option",this).each(function(){this.selected=(jQuery.inArray(this.value,values)>=0||jQuery.inArray(this.text,values)>=0);});if(!values.length)this.selectedIndex=-1;}else +this.value=value;});},html:function(value){return value==undefined?(this[0]?this[0].innerHTML:null):this.empty().append(value);},replaceWith:function(value){return this.after(value).remove();},eq:function(i){return this.slice(i,i+1);},slice:function(){return this.pushStack(Array.prototype.slice.apply(this,arguments));},map:function(callback){return this.pushStack(jQuery.map(this,function(elem,i){return callback.call(elem,i,elem);}));},andSelf:function(){return this.add(this.prevObject);},data:function(key,value){var parts=key.split(".");parts[1]=parts[1]?"."+parts[1]:"";if(value===undefined){var data=this.triggerHandler("getData"+parts[1]+"!",[parts[0]]);if(data===undefined&&this.length)data=jQuery.data(this[0],key);return data===undefined&&parts[1]?this.data(parts[0]):data;}else +return this.trigger("setData"+parts[1]+"!",[parts[0],value]).each(function(){jQuery.data(this,key,value);});},removeData:function(key){return this.each(function(){jQuery.removeData(this,key);});},domManip:function(args,table,reverse,callback){var clone=this.length>1,elems;return this.each(function(){if(!elems){elems=jQuery.clean(args,this.ownerDocument);if(reverse)elems.reverse();}var obj=this;if(table&&jQuery.nodeName(this,"table")&&jQuery.nodeName(elems[0],"tr"))obj=this.getElementsByTagName("tbody")[0]||this.appendChild(this.ownerDocument.createElement("tbody"));var scripts=jQuery([]);jQuery.each(elems,function(){var elem=clone?jQuery(this).clone(true)[0]:this;if(jQuery.nodeName(elem,"script"))scripts=scripts.add(elem);else{if(elem.nodeType==1)scripts=scripts.add(jQuery("script",elem).remove());callback.call(obj,elem);}});scripts.each(evalScript);});}};jQuery.fn.init.prototype=jQuery.fn;function evalScript(i,elem){if(elem.src)jQuery.ajax({url:elem.src,async:false,dataType:"script"});else +jQuery.globalEval(elem.text||elem.textContent||elem.innerHTML||"");if(elem.parentNode)elem.parentNode.removeChild(elem);}function now(){return+new Date;}jQuery.extend=jQuery.fn.extend=function(){var target=arguments[0]||{},i=1,length=arguments.length,deep=false,options;if(target.constructor==Boolean){deep=target;target=arguments[1]||{};i=2;}if(typeof target!="object"&&typeof target!="function")target={};if(length==i){target=this;--i;}for(;i-1;}},swap:function(elem,options,callback){var old={};for(var name in options){old[name]=elem.style[name];elem.style[name]=options[name];}callback.call(elem);for(var name in options)elem.style[name]=old[name];},css:function(elem,name,force){if(name=="width"||name=="height"){var val,props={position:"absolute",visibility:"hidden",display:"block"},which=name=="width"?["Left","Right"]:["Top","Bottom"];function getWH(){val=name=="width"?elem.offsetWidth:elem.offsetHeight;var padding=0,border=0;jQuery.each(which,function(){padding+=parseFloat(jQuery.curCSS(elem,"padding"+this,true))||0;border+=parseFloat(jQuery.curCSS(elem,"border"+this+"Width",true))||0;});val-=Math.round(padding+border);}if(jQuery(elem).is(":visible"))getWH();else +jQuery.swap(elem,props,getWH);return Math.max(0,val);}return jQuery.curCSS(elem,name,force);},curCSS:function(elem,name,force){var ret,style=elem.style;function color(elem){if(!jQuery.browser.safari)return false;var ret=defaultView.getComputedStyle(elem,null);return!ret||ret.getPropertyValue("color")=="";}if(name=="opacity"&&jQuery.browser.msie){ret=jQuery.attr(style,"opacity");return ret==""?"1":ret;}if(jQuery.browser.opera&&name=="display"){var save=style.outline;style.outline="0 solid black";style.outline=save;}if(name.match(/float/i))name=styleFloat;if(!force&&style&&style[name])ret=style[name];else if(defaultView.getComputedStyle){if(name.match(/float/i))name="float";name=name.replace(/([A-Z])/g,"-$1").toLowerCase();var computedStyle=defaultView.getComputedStyle(elem,null);if(computedStyle&&!color(elem))ret=computedStyle.getPropertyValue(name);else{var swap=[],stack=[],a=elem,i=0;for(;a&&color(a);a=a.parentNode)stack.unshift(a);for(;i]*?)\/>/g,function(all,front,tag){return tag.match(/^(abbr|br|col|img|input|link|meta|param|hr|area|embed)$/i)?all:front+">";});var tags=jQuery.trim(elem).toLowerCase(),div=context.createElement("div");var wrap=!tags.indexOf("",""]||!tags.indexOf("",""]||tags.match(/^<(thead|tbody|tfoot|colg|cap)/)&&[1,"","
                          "]||!tags.indexOf("",""]||(!tags.indexOf("",""]||!tags.indexOf("",""]||jQuery.browser.msie&&[1,"div
                          ","
                          "]||[0,"",""];div.innerHTML=wrap[1]+elem+wrap[2];while(wrap[0]--)div=div.lastChild;if(jQuery.browser.msie){var tbody=!tags.indexOf(""&&tags.indexOf("=0;--j)if(jQuery.nodeName(tbody[j],"tbody")&&!tbody[j].childNodes.length)tbody[j].parentNode.removeChild(tbody[j]);if(/^\s/.test(elem))div.insertBefore(context.createTextNode(elem.match(/^\s*/)[0]),div.firstChild);}elem=jQuery.makeArray(div.childNodes);}if(elem.length===0&&(!jQuery.nodeName(elem,"form")&&!jQuery.nodeName(elem,"select")))return;if(elem[0]==undefined||jQuery.nodeName(elem,"form")||elem.options)ret.push(elem);else +ret=jQuery.merge(ret,elem);});return ret;},attr:function(elem,name,value){if(!elem||elem.nodeType==3||elem.nodeType==8)return undefined;var notxml=!jQuery.isXMLDoc(elem),set=value!==undefined,msie=jQuery.browser.msie;name=notxml&&jQuery.props[name]||name;if(elem.tagName){var special=/href|src|style/.test(name);if(name=="selected"&&jQuery.browser.safari)elem.parentNode.selectedIndex;if(name in elem&¬xml&&!special){if(set){if(name=="type"&&jQuery.nodeName(elem,"input")&&elem.parentNode)throw"type property can't be changed";elem[name]=value;}if(jQuery.nodeName(elem,"form")&&elem.getAttributeNode(name))return elem.getAttributeNode(name).nodeValue;return elem[name];}if(msie&¬xml&&name=="style")return jQuery.attr(elem.style,"cssText",value);if(set)elem.setAttribute(name,""+value);var attr=msie&¬xml&&special?elem.getAttribute(name,2):elem.getAttribute(name);return attr===null?undefined:attr;}if(msie&&name=="opacity"){if(set){elem.zoom=1;elem.filter=(elem.filter||"").replace(/alpha\([^)]*\)/,"")+(parseInt(value)+''=="NaN"?"":"alpha(opacity="+value*100+")");}return elem.filter&&elem.filter.indexOf("opacity=")>=0?(parseFloat(elem.filter.match(/opacity=([^)]*)/)[1])/100)+'':"";}name=name.replace(/-([a-z])/ig,function(all,letter){return letter.toUpperCase();});if(set)elem[name]=value;return elem[name];},trim:function(text){return(text||"").replace(/^\s+|\s+$/g,"");},makeArray:function(array){var ret=[];if(array!=null){var i=array.length;if(i==null||array.split||array.setInterval||array.call)ret[0]=array;else +while(i)ret[--i]=array[i];}return ret;},inArray:function(elem,array){for(var i=0,length=array.length;i*",this).remove();while(this.firstChild)this.removeChild(this.firstChild);}},function(name,fn){jQuery.fn[name]=function(){return this.each(fn,arguments);};});jQuery.each(["Height","Width"],function(i,name){var type=name.toLowerCase();jQuery.fn[type]=function(size){return this[0]==window?jQuery.browser.opera&&document.body["client"+name]||jQuery.browser.safari&&window["inner"+name]||document.compatMode=="CSS1Compat"&&document.documentElement["client"+name]||document.body["client"+name]:this[0]==document?Math.max(Math.max(document.body["scroll"+name],document.documentElement["scroll"+name]),Math.max(document.body["offset"+name],document.documentElement["offset"+name])):size==undefined?(this.length?jQuery.css(this[0],type):null):this.css(type,size.constructor==String?size:size+"px");};});function num(elem,prop){return elem[0]&&parseInt(jQuery.curCSS(elem[0],prop,true),10)||0;}var chars=jQuery.browser.safari&&parseInt(jQuery.browser.version)<417?"(?:[\\w*_-]|\\\\.)":"(?:[\\w\u0128-\uFFFF*_-]|\\\\.)",quickChild=new RegExp("^>\\s*("+chars+"+)"),quickID=new RegExp("^("+chars+"+)(#)("+chars+"+)"),quickClass=new RegExp("^([#.]?)("+chars+"*)");jQuery.extend({expr:{"":function(a,i,m){return m[2]=="*"||jQuery.nodeName(a,m[2]);},"#":function(a,i,m){return a.getAttribute("id")==m[2];},":":{lt:function(a,i,m){return im[3]-0;},nth:function(a,i,m){return m[3]-0==i;},eq:function(a,i,m){return m[3]-0==i;},first:function(a,i){return i==0;},last:function(a,i,m,r){return i==r.length-1;},even:function(a,i){return i%2==0;},odd:function(a,i){return i%2;},"first-child":function(a){return a.parentNode.getElementsByTagName("*")[0]==a;},"last-child":function(a){return jQuery.nth(a.parentNode.lastChild,1,"previousSibling")==a;},"only-child":function(a){return!jQuery.nth(a.parentNode.lastChild,2,"previousSibling");},parent:function(a){return a.firstChild;},empty:function(a){return!a.firstChild;},contains:function(a,i,m){return(a.textContent||a.innerText||jQuery(a).text()||"").indexOf(m[3])>=0;},visible:function(a){return"hidden"!=a.type&&jQuery.css(a,"display")!="none"&&jQuery.css(a,"visibility")!="hidden";},hidden:function(a){return"hidden"==a.type||jQuery.css(a,"display")=="none"||jQuery.css(a,"visibility")=="hidden";},enabled:function(a){return!a.disabled;},disabled:function(a){return a.disabled;},checked:function(a){return a.checked;},selected:function(a){return a.selected||jQuery.attr(a,"selected");},text:function(a){return"text"==a.type;},radio:function(a){return"radio"==a.type;},checkbox:function(a){return"checkbox"==a.type;},file:function(a){return"file"==a.type;},password:function(a){return"password"==a.type;},submit:function(a){return"submit"==a.type;},image:function(a){return"image"==a.type;},reset:function(a){return"reset"==a.type;},button:function(a){return"button"==a.type||jQuery.nodeName(a,"button");},input:function(a){return/input|select|textarea|button/i.test(a.nodeName);},has:function(a,i,m){return jQuery.find(m[3],a).length;},header:function(a){return/h\d/i.test(a.nodeName);},animated:function(a){return jQuery.grep(jQuery.timers,function(fn){return a==fn.elem;}).length;}}},parse:[/^(\[) *@?([\w-]+) *([!*$^~=]*) *('?"?)(.*?)\4 *\]/,/^(:)([\w-]+)\("?'?(.*?(\(.*?\))?[^(]*?)"?'?\)/,new RegExp("^([:.#]*)("+chars+"+)")],multiFilter:function(expr,elems,not){var old,cur=[];while(expr&&expr!=old){old=expr;var f=jQuery.filter(expr,elems,not);expr=f.t.replace(/^\s*,\s*/,"");cur=not?elems=f.r:jQuery.merge(cur,f.r);}return cur;},find:function(t,context){if(typeof t!="string")return[t];if(context&&context.nodeType!=1&&context.nodeType!=9)return[];context=context||document;var ret=[context],done=[],last,nodeName;while(t&&last!=t){var r=[];last=t;t=jQuery.trim(t);var foundToken=false,re=quickChild,m=re.exec(t);if(m){nodeName=m[1].toUpperCase();for(var i=0;ret[i];i++)for(var c=ret[i].firstChild;c;c=c.nextSibling)if(c.nodeType==1&&(nodeName=="*"||c.nodeName.toUpperCase()==nodeName))r.push(c);ret=r;t=t.replace(re,"");if(t.indexOf(" ")==0)continue;foundToken=true;}else{re=/^([>+~])\s*(\w*)/i;if((m=re.exec(t))!=null){r=[];var merge={};nodeName=m[2].toUpperCase();m=m[1];for(var j=0,rl=ret.length;j=0;if(!not&&pass||not&&!pass)tmp.push(r[i]);}return tmp;},filter:function(t,r,not){var last;while(t&&t!=last){last=t;var p=jQuery.parse,m;for(var i=0;p[i];i++){m=p[i].exec(t);if(m){t=t.substring(m[0].length);m[2]=m[2].replace(/\\/g,"");break;}}if(!m)break;if(m[1]==":"&&m[2]=="not")r=isSimple.test(m[3])?jQuery.filter(m[3],r,true).r:jQuery(r).not(m[3]);else if(m[1]==".")r=jQuery.classFilter(r,m[2],not);else if(m[1]=="["){var tmp=[],type=m[3];for(var i=0,rl=r.length;i=0)^not)tmp.push(a);}r=tmp;}else if(m[1]==":"&&m[2]=="nth-child"){var merge={},tmp=[],test=/(-?)(\d*)n((?:\+|-)?\d*)/.exec(m[3]=="even"&&"2n"||m[3]=="odd"&&"2n+1"||!/\D/.test(m[3])&&"0n+"+m[3]||m[3]),first=(test[1]+(test[2]||1))-0,last=test[3]-0;for(var i=0,rl=r.length;i=0)add=true;if(add^not)tmp.push(node);}r=tmp;}else{var fn=jQuery.expr[m[1]];if(typeof fn=="object")fn=fn[m[2]];if(typeof fn=="string")fn=eval("false||function(a,i){return "+fn+";}");r=jQuery.grep(r,function(elem,i){return fn(elem,i,m,r);},not);}}return{r:r,t:t};},dir:function(elem,dir){var matched=[],cur=elem[dir];while(cur&&cur!=document){if(cur.nodeType==1)matched.push(cur);cur=cur[dir];}return matched;},nth:function(cur,result,dir,elem){result=result||1;var num=0;for(;cur;cur=cur[dir])if(cur.nodeType==1&&++num==result)break;return cur;},sibling:function(n,elem){var r=[];for(;n;n=n.nextSibling){if(n.nodeType==1&&n!=elem)r.push(n);}return r;}});jQuery.event={add:function(elem,types,handler,data){if(elem.nodeType==3||elem.nodeType==8)return;if(jQuery.browser.msie&&elem.setInterval)elem=window;if(!handler.guid)handler.guid=this.guid++;if(data!=undefined){var fn=handler;handler=this.proxy(fn,function(){return fn.apply(this,arguments);});handler.data=data;}var events=jQuery.data(elem,"events")||jQuery.data(elem,"events",{}),handle=jQuery.data(elem,"handle")||jQuery.data(elem,"handle",function(){if(typeof jQuery!="undefined"&&!jQuery.event.triggered)return jQuery.event.handle.apply(arguments.callee.elem,arguments);});handle.elem=elem;jQuery.each(types.split(/\s+/),function(index,type){var parts=type.split(".");type=parts[0];handler.type=parts[1];var handlers=events[type];if(!handlers){handlers=events[type]={};if(!jQuery.event.special[type]||jQuery.event.special[type].setup.call(elem)===false){if(elem.addEventListener)elem.addEventListener(type,handle,false);else if(elem.attachEvent)elem.attachEvent("on"+type,handle);}}handlers[handler.guid]=handler;jQuery.event.global[type]=true;});elem=null;},guid:1,global:{},remove:function(elem,types,handler){if(elem.nodeType==3||elem.nodeType==8)return;var events=jQuery.data(elem,"events"),ret,index;if(events){if(types==undefined||(typeof types=="string"&&types.charAt(0)=="."))for(var type in events)this.remove(elem,type+(types||""));else{if(types.type){handler=types.handler;types=types.type;}jQuery.each(types.split(/\s+/),function(index,type){var parts=type.split(".");type=parts[0];if(events[type]){if(handler)delete events[type][handler.guid];else +for(handler in events[type])if(!parts[1]||events[type][handler].type==parts[1])delete events[type][handler];for(ret in events[type])break;if(!ret){if(!jQuery.event.special[type]||jQuery.event.special[type].teardown.call(elem)===false){if(elem.removeEventListener)elem.removeEventListener(type,jQuery.data(elem,"handle"),false);else if(elem.detachEvent)elem.detachEvent("on"+type,jQuery.data(elem,"handle"));}ret=null;delete events[type];}}});}for(ret in events)break;if(!ret){var handle=jQuery.data(elem,"handle");if(handle)handle.elem=null;jQuery.removeData(elem,"events");jQuery.removeData(elem,"handle");}}},trigger:function(type,data,elem,donative,extra){data=jQuery.makeArray(data);if(type.indexOf("!")>=0){type=type.slice(0,-1);var exclusive=true;}if(!elem){if(this.global[type])jQuery("*").add([window,document]).trigger(type,data);}else{if(elem.nodeType==3||elem.nodeType==8)return undefined;var val,ret,fn=jQuery.isFunction(elem[type]||null),event=!data[0]||!data[0].preventDefault;if(event){data.unshift({type:type,target:elem,preventDefault:function(){},stopPropagation:function(){},timeStamp:now()});data[0][expando]=true;}data[0].type=type;if(exclusive)data[0].exclusive=true;var handle=jQuery.data(elem,"handle");if(handle)val=handle.apply(elem,data);if((!fn||(jQuery.nodeName(elem,'a')&&type=="click"))&&elem["on"+type]&&elem["on"+type].apply(elem,data)===false)val=false;if(event)data.shift();if(extra&&jQuery.isFunction(extra)){ret=extra.apply(elem,val==null?data:data.concat(val));if(ret!==undefined)val=ret;}if(fn&&donative!==false&&val!==false&&!(jQuery.nodeName(elem,'a')&&type=="click")){this.triggered=true;try{elem[type]();}catch(e){}}this.triggered=false;}return val;},handle:function(event){var val,ret,namespace,all,handlers;event=arguments[0]=jQuery.event.fix(event||window.event);namespace=event.type.split(".");event.type=namespace[0];namespace=namespace[1];all=!namespace&&!event.exclusive;handlers=(jQuery.data(this,"events")||{})[event.type];for(var j in handlers){var handler=handlers[j];if(all||handler.type==namespace){event.handler=handler;event.data=handler.data;ret=handler.apply(this,arguments);if(val!==false)val=ret;if(ret===false){event.preventDefault();event.stopPropagation();}}}return val;},fix:function(event){if(event[expando]==true)return event;var originalEvent=event;event={originalEvent:originalEvent};var props="altKey attrChange attrName bubbles button cancelable charCode clientX clientY ctrlKey currentTarget data detail eventPhase fromElement handler keyCode metaKey newValue originalTarget pageX pageY prevValue relatedNode relatedTarget screenX screenY shiftKey srcElement target timeStamp toElement type view wheelDelta which".split(" ");for(var i=props.length;i;i--)event[props[i]]=originalEvent[props[i]];event[expando]=true;event.preventDefault=function(){if(originalEvent.preventDefault)originalEvent.preventDefault();originalEvent.returnValue=false;};event.stopPropagation=function(){if(originalEvent.stopPropagation)originalEvent.stopPropagation();originalEvent.cancelBubble=true;};event.timeStamp=event.timeStamp||now();if(!event.target)event.target=event.srcElement||document;if(event.target.nodeType==3)event.target=event.target.parentNode;if(!event.relatedTarget&&event.fromElement)event.relatedTarget=event.fromElement==event.target?event.toElement:event.fromElement;if(event.pageX==null&&event.clientX!=null){var doc=document.documentElement,body=document.body;event.pageX=event.clientX+(doc&&doc.scrollLeft||body&&body.scrollLeft||0)-(doc.clientLeft||0);event.pageY=event.clientY+(doc&&doc.scrollTop||body&&body.scrollTop||0)-(doc.clientTop||0);}if(!event.which&&((event.charCode||event.charCode===0)?event.charCode:event.keyCode))event.which=event.charCode||event.keyCode;if(!event.metaKey&&event.ctrlKey)event.metaKey=event.ctrlKey;if(!event.which&&event.button)event.which=(event.button&1?1:(event.button&2?3:(event.button&4?2:0)));return event;},proxy:function(fn,proxy){proxy.guid=fn.guid=fn.guid||proxy.guid||this.guid++;return proxy;},special:{ready:{setup:function(){bindReady();return;},teardown:function(){return;}},mouseenter:{setup:function(){if(jQuery.browser.msie)return false;jQuery(this).bind("mouseover",jQuery.event.special.mouseenter.handler);return true;},teardown:function(){if(jQuery.browser.msie)return false;jQuery(this).unbind("mouseover",jQuery.event.special.mouseenter.handler);return true;},handler:function(event){if(withinElement(event,this))return true;event.type="mouseenter";return jQuery.event.handle.apply(this,arguments);}},mouseleave:{setup:function(){if(jQuery.browser.msie)return false;jQuery(this).bind("mouseout",jQuery.event.special.mouseleave.handler);return true;},teardown:function(){if(jQuery.browser.msie)return false;jQuery(this).unbind("mouseout",jQuery.event.special.mouseleave.handler);return true;},handler:function(event){if(withinElement(event,this))return true;event.type="mouseleave";return jQuery.event.handle.apply(this,arguments);}}}};jQuery.fn.extend({bind:function(type,data,fn){return type=="unload"?this.one(type,data,fn):this.each(function(){jQuery.event.add(this,type,fn||data,fn&&data);});},one:function(type,data,fn){var one=jQuery.event.proxy(fn||data,function(event){jQuery(this).unbind(event,one);return(fn||data).apply(this,arguments);});return this.each(function(){jQuery.event.add(this,type,one,fn&&data);});},unbind:function(type,fn){return this.each(function(){jQuery.event.remove(this,type,fn);});},trigger:function(type,data,fn){return this.each(function(){jQuery.event.trigger(type,data,this,true,fn);});},triggerHandler:function(type,data,fn){return this[0]&&jQuery.event.trigger(type,data,this[0],false,fn);},toggle:function(fn){var args=arguments,i=1;while(i=0){var selector=url.slice(off,url.length);url=url.slice(0,off);}callback=callback||function(){};var type="GET";if(params)if(jQuery.isFunction(params)){callback=params;params=null;}else{params=jQuery.param(params);type="POST";}var self=this;jQuery.ajax({url:url,type:type,dataType:"html",data:params,complete:function(res,status){if(status=="success"||status=="notmodified")self.html(selector?jQuery("
                          ").append(res.responseText.replace(//g,"")).find(selector):res.responseText);self.each(callback,[res.responseText,status,res]);}});return this;},serialize:function(){return jQuery.param(this.serializeArray());},serializeArray:function(){return this.map(function(){return jQuery.nodeName(this,"form")?jQuery.makeArray(this.elements):this;}).filter(function(){return this.name&&!this.disabled&&(this.checked||/select|textarea/i.test(this.nodeName)||/text|hidden|password/i.test(this.type));}).map(function(i,elem){var val=jQuery(this).val();return val==null?null:val.constructor==Array?jQuery.map(val,function(val,i){return{name:elem.name,value:val};}):{name:elem.name,value:val};}).get();}});jQuery.each("ajaxStart,ajaxStop,ajaxComplete,ajaxError,ajaxSuccess,ajaxSend".split(","),function(i,o){jQuery.fn[o]=function(f){return this.bind(o,f);};});var jsc=now();jQuery.extend({get:function(url,data,callback,type){if(jQuery.isFunction(data)){callback=data;data=null;}return jQuery.ajax({type:"GET",url:url,data:data,success:callback,dataType:type});},getScript:function(url,callback){return jQuery.get(url,null,callback,"script");},getJSON:function(url,data,callback){return jQuery.get(url,data,callback,"json");},post:function(url,data,callback,type){if(jQuery.isFunction(data)){callback=data;data={};}return jQuery.ajax({type:"POST",url:url,data:data,success:callback,dataType:type});},ajaxSetup:function(settings){jQuery.extend(jQuery.ajaxSettings,settings);},ajaxSettings:{url:location.href,global:true,type:"GET",timeout:0,contentType:"application/x-www-form-urlencoded",processData:true,async:true,data:null,username:null,password:null,accepts:{xml:"application/xml, text/xml",html:"text/html",script:"text/javascript, application/javascript",json:"application/json, text/javascript",text:"text/plain",_default:"*/*"}},lastModified:{},ajax:function(s){s=jQuery.extend(true,s,jQuery.extend(true,{},jQuery.ajaxSettings,s));var jsonp,jsre=/=\?(&|$)/g,status,data,type=s.type.toUpperCase();if(s.data&&s.processData&&typeof s.data!="string")s.data=jQuery.param(s.data);if(s.dataType=="jsonp"){if(type=="GET"){if(!s.url.match(jsre))s.url+=(s.url.match(/\?/)?"&":"?")+(s.jsonp||"callback")+"=?";}else if(!s.data||!s.data.match(jsre))s.data=(s.data?s.data+"&":"")+(s.jsonp||"callback")+"=?";s.dataType="json";}if(s.dataType=="json"&&(s.data&&s.data.match(jsre)||s.url.match(jsre))){jsonp="jsonp"+jsc++;if(s.data)s.data=(s.data+"").replace(jsre,"="+jsonp+"$1");s.url=s.url.replace(jsre,"="+jsonp+"$1");s.dataType="script";window[jsonp]=function(tmp){data=tmp;success();complete();window[jsonp]=undefined;try{delete window[jsonp];}catch(e){}if(head)head.removeChild(script);};}if(s.dataType=="script"&&s.cache==null)s.cache=false;if(s.cache===false&&type=="GET"){var ts=now();var ret=s.url.replace(/(\?|&)_=.*?(&|$)/,"$1_="+ts+"$2");s.url=ret+((ret==s.url)?(s.url.match(/\?/)?"&":"?")+"_="+ts:"");}if(s.data&&type=="GET"){s.url+=(s.url.match(/\?/)?"&":"?")+s.data;s.data=null;}if(s.global&&!jQuery.active++)jQuery.event.trigger("ajaxStart");var remote=/^(?:\w+:)?\/\/([^\/?#]+)/;if(s.dataType=="script"&&type=="GET"&&remote.test(s.url)&&remote.exec(s.url)[1]!=location.host){var head=document.getElementsByTagName("head")[0];var script=document.createElement("script");script.src=s.url;if(s.scriptCharset)script.charset=s.scriptCharset;if(!jsonp){var done=false;script.onload=script.onreadystatechange=function(){if(!done&&(!this.readyState||this.readyState=="loaded"||this.readyState=="complete")){done=true;success();complete();head.removeChild(script);}};}head.appendChild(script);return undefined;}var requestDone=false;var xhr=window.ActiveXObject?new ActiveXObject("Microsoft.XMLHTTP"):new XMLHttpRequest();if(s.username)xhr.open(type,s.url,s.async,s.username,s.password);else +xhr.open(type,s.url,s.async);try{if(s.data)xhr.setRequestHeader("Content-Type",s.contentType);if(s.ifModified)xhr.setRequestHeader("If-Modified-Since",jQuery.lastModified[s.url]||"Thu, 01 Jan 1970 00:00:00 GMT");xhr.setRequestHeader("X-Requested-With","XMLHttpRequest");xhr.setRequestHeader("Accept",s.dataType&&s.accepts[s.dataType]?s.accepts[s.dataType]+", */*":s.accepts._default);}catch(e){}if(s.beforeSend&&s.beforeSend(xhr,s)===false){s.global&&jQuery.active--;xhr.abort();return false;}if(s.global)jQuery.event.trigger("ajaxSend",[xhr,s]);var onreadystatechange=function(isTimeout){if(!requestDone&&xhr&&(xhr.readyState==4||isTimeout=="timeout")){requestDone=true;if(ival){clearInterval(ival);ival=null;}status=isTimeout=="timeout"&&"timeout"||!jQuery.httpSuccess(xhr)&&"error"||s.ifModified&&jQuery.httpNotModified(xhr,s.url)&&"notmodified"||"success";if(status=="success"){try{data=jQuery.httpData(xhr,s.dataType,s.dataFilter);}catch(e){status="parsererror";}}if(status=="success"){var modRes;try{modRes=xhr.getResponseHeader("Last-Modified");}catch(e){}if(s.ifModified&&modRes)jQuery.lastModified[s.url]=modRes;if(!jsonp)success();}else +jQuery.handleError(s,xhr,status);complete();if(s.async)xhr=null;}};if(s.async){var ival=setInterval(onreadystatechange,13);if(s.timeout>0)setTimeout(function(){if(xhr){xhr.abort();if(!requestDone)onreadystatechange("timeout");}},s.timeout);}try{xhr.send(s.data);}catch(e){jQuery.handleError(s,xhr,null,e);}if(!s.async)onreadystatechange();function success(){if(s.success)s.success(data,status);if(s.global)jQuery.event.trigger("ajaxSuccess",[xhr,s]);}function complete(){if(s.complete)s.complete(xhr,status);if(s.global)jQuery.event.trigger("ajaxComplete",[xhr,s]);if(s.global&&!--jQuery.active)jQuery.event.trigger("ajaxStop");}return xhr;},handleError:function(s,xhr,status,e){if(s.error)s.error(xhr,status,e);if(s.global)jQuery.event.trigger("ajaxError",[xhr,s,e]);},active:0,httpSuccess:function(xhr){try{return!xhr.status&&location.protocol=="file:"||(xhr.status>=200&&xhr.status<300)||xhr.status==304||xhr.status==1223||jQuery.browser.safari&&xhr.status==undefined;}catch(e){}return false;},httpNotModified:function(xhr,url){try{var xhrRes=xhr.getResponseHeader("Last-Modified");return xhr.status==304||xhrRes==jQuery.lastModified[url]||jQuery.browser.safari&&xhr.status==undefined;}catch(e){}return false;},httpData:function(xhr,type,filter){var ct=xhr.getResponseHeader("content-type"),xml=type=="xml"||!type&&ct&&ct.indexOf("xml")>=0,data=xml?xhr.responseXML:xhr.responseText;if(xml&&data.documentElement.tagName=="parsererror")throw"parsererror";if(filter)data=filter(data,type);if(type=="script")jQuery.globalEval(data);if(type=="json")data=eval("("+data+")");return data;},param:function(a){var s=[];if(a.constructor==Array||a.jquery)jQuery.each(a,function(){s.push(encodeURIComponent(this.name)+"="+encodeURIComponent(this.value));});else +for(var j in a)if(a[j]&&a[j].constructor==Array)jQuery.each(a[j],function(){s.push(encodeURIComponent(j)+"="+encodeURIComponent(this));});else +s.push(encodeURIComponent(j)+"="+encodeURIComponent(jQuery.isFunction(a[j])?a[j]():a[j]));return s.join("&").replace(/%20/g,"+");}});jQuery.fn.extend({show:function(speed,callback){return speed?this.animate({height:"show",width:"show",opacity:"show"},speed,callback):this.filter(":hidden").each(function(){this.style.display=this.oldblock||"";if(jQuery.css(this,"display")=="none"){var elem=jQuery("<"+this.tagName+" />").appendTo("body");this.style.display=elem.css("display");if(this.style.display=="none")this.style.display="block";elem.remove();}}).end();},hide:function(speed,callback){return speed?this.animate({height:"hide",width:"hide",opacity:"hide"},speed,callback):this.filter(":visible").each(function(){this.oldblock=this.oldblock||jQuery.css(this,"display");this.style.display="none";}).end();},_toggle:jQuery.fn.toggle,toggle:function(fn,fn2){return jQuery.isFunction(fn)&&jQuery.isFunction(fn2)?this._toggle.apply(this,arguments):fn?this.animate({height:"toggle",width:"toggle",opacity:"toggle"},fn,fn2):this.each(function(){jQuery(this)[jQuery(this).is(":hidden")?"show":"hide"]();});},slideDown:function(speed,callback){return this.animate({height:"show"},speed,callback);},slideUp:function(speed,callback){return this.animate({height:"hide"},speed,callback);},slideToggle:function(speed,callback){return this.animate({height:"toggle"},speed,callback);},fadeIn:function(speed,callback){return this.animate({opacity:"show"},speed,callback);},fadeOut:function(speed,callback){return this.animate({opacity:"hide"},speed,callback);},fadeTo:function(speed,to,callback){return this.animate({opacity:to},speed,callback);},animate:function(prop,speed,easing,callback){var optall=jQuery.speed(speed,easing,callback);return this[optall.queue===false?"each":"queue"](function(){if(this.nodeType!=1)return false;var opt=jQuery.extend({},optall),p,hidden=jQuery(this).is(":hidden"),self=this;for(p in prop){if(prop[p]=="hide"&&hidden||prop[p]=="show"&&!hidden)return opt.complete.call(this);if(p=="height"||p=="width"){opt.display=jQuery.css(this,"display");opt.overflow=this.style.overflow;}}if(opt.overflow!=null)this.style.overflow="hidden";opt.curAnim=jQuery.extend({},prop);jQuery.each(prop,function(name,val){var e=new jQuery.fx(self,opt,name);if(/toggle|show|hide/.test(val))e[val=="toggle"?hidden?"show":"hide":val](prop);else{var parts=val.toString().match(/^([+-]=)?([\d+-.]+)(.*)$/),start=e.cur(true)||0;if(parts){var end=parseFloat(parts[2]),unit=parts[3]||"px";if(unit!="px"){self.style[name]=(end||1)+unit;start=((end||1)/e.cur(true))*start;self.style[name]=start+unit;}if(parts[1])end=((parts[1]=="-="?-1:1)*end)+start;e.custom(start,end,unit);}else +e.custom(start,val,"");}});return true;});},queue:function(type,fn){if(jQuery.isFunction(type)||(type&&type.constructor==Array)){fn=type;type="fx";}if(!type||(typeof type=="string"&&!fn))return queue(this[0],type);return this.each(function(){if(fn.constructor==Array)queue(this,type,fn);else{queue(this,type).push(fn);if(queue(this,type).length==1)fn.call(this);}});},stop:function(clearQueue,gotoEnd){var timers=jQuery.timers;if(clearQueue)this.queue([]);this.each(function(){for(var i=timers.length-1;i>=0;i--)if(timers[i].elem==this){if(gotoEnd)timers[i](true);timers.splice(i,1);}});if(!gotoEnd)this.dequeue();return this;}});var queue=function(elem,type,array){if(elem){type=type||"fx";var q=jQuery.data(elem,type+"queue");if(!q||array)q=jQuery.data(elem,type+"queue",jQuery.makeArray(array));}return q;};jQuery.fn.dequeue=function(type){type=type||"fx";return this.each(function(){var q=queue(this,type);q.shift();if(q.length)q[0].call(this);});};jQuery.extend({speed:function(speed,easing,fn){var opt=speed&&speed.constructor==Object?speed:{complete:fn||!fn&&easing||jQuery.isFunction(speed)&&speed,duration:speed,easing:fn&&easing||easing&&easing.constructor!=Function&&easing};opt.duration=(opt.duration&&opt.duration.constructor==Number?opt.duration:jQuery.fx.speeds[opt.duration])||jQuery.fx.speeds.def;opt.old=opt.complete;opt.complete=function(){if(opt.queue!==false)jQuery(this).dequeue();if(jQuery.isFunction(opt.old))opt.old.call(this);};return opt;},easing:{linear:function(p,n,firstNum,diff){return firstNum+diff*p;},swing:function(p,n,firstNum,diff){return((-Math.cos(p*Math.PI)/2)+0.5)*diff+firstNum;}},timers:[],timerId:null,fx:function(elem,options,prop){this.options=options;this.elem=elem;this.prop=prop;if(!options.orig)options.orig={};}});jQuery.fx.prototype={update:function(){if(this.options.step)this.options.step.call(this.elem,this.now,this);(jQuery.fx.step[this.prop]||jQuery.fx.step._default)(this);if(this.prop=="height"||this.prop=="width")this.elem.style.display="block";},cur:function(force){if(this.elem[this.prop]!=null&&this.elem.style[this.prop]==null)return this.elem[this.prop];var r=parseFloat(jQuery.css(this.elem,this.prop,force));return r&&r>-10000?r:parseFloat(jQuery.curCSS(this.elem,this.prop))||0;},custom:function(from,to,unit){this.startTime=now();this.start=from;this.end=to;this.unit=unit||this.unit||"px";this.now=this.start;this.pos=this.state=0;this.update();var self=this;function t(gotoEnd){return self.step(gotoEnd);}t.elem=this.elem;jQuery.timers.push(t);if(jQuery.timerId==null){jQuery.timerId=setInterval(function(){var timers=jQuery.timers;for(var i=0;ithis.options.duration+this.startTime){this.now=this.end;this.pos=this.state=1;this.update();this.options.curAnim[this.prop]=true;var done=true;for(var i in this.options.curAnim)if(this.options.curAnim[i]!==true)done=false;if(done){if(this.options.display!=null){this.elem.style.overflow=this.options.overflow;this.elem.style.display=this.options.display;if(jQuery.css(this.elem,"display")=="none")this.elem.style.display="block";}if(this.options.hide)this.elem.style.display="none";if(this.options.hide||this.options.show)for(var p in this.options.curAnim)jQuery.attr(this.elem.style,p,this.options.orig[p]);}if(done)this.options.complete.call(this.elem);return false;}else{var n=t-this.startTime;this.state=n/this.options.duration;this.pos=jQuery.easing[this.options.easing||(jQuery.easing.swing?"swing":"linear")](this.state,n,0,1,this.options.duration);this.now=this.start+((this.end-this.start)*this.pos);this.update();}return true;}};jQuery.extend(jQuery.fx,{speeds:{slow:600,fast:200,def:400},step:{scrollLeft:function(fx){fx.elem.scrollLeft=fx.now;},scrollTop:function(fx){fx.elem.scrollTop=fx.now;},opacity:function(fx){jQuery.attr(fx.elem.style,"opacity",fx.now);},_default:function(fx){fx.elem.style[fx.prop]=fx.now+fx.unit;}}});jQuery.fn.offset=function(){var left=0,top=0,elem=this[0],results;if(elem)with(jQuery.browser){var parent=elem.parentNode,offsetChild=elem,offsetParent=elem.offsetParent,doc=elem.ownerDocument,safari2=safari&&parseInt(version)<522&&!/adobeair/i.test(userAgent),css=jQuery.curCSS,fixed=css(elem,"position")=="fixed";if(elem.getBoundingClientRect){var box=elem.getBoundingClientRect();add(box.left+Math.max(doc.documentElement.scrollLeft,doc.body.scrollLeft),box.top+Math.max(doc.documentElement.scrollTop,doc.body.scrollTop));add(-doc.documentElement.clientLeft,-doc.documentElement.clientTop);}else{add(elem.offsetLeft,elem.offsetTop);while(offsetParent){add(offsetParent.offsetLeft,offsetParent.offsetTop);if(mozilla&&!/^t(able|d|h)$/i.test(offsetParent.tagName)||safari&&!safari2)border(offsetParent);if(!fixed&&css(offsetParent,"position")=="fixed")fixed=true;offsetChild=/^body$/i.test(offsetParent.tagName)?offsetChild:offsetParent;offsetParent=offsetParent.offsetParent;}while(parent&&parent.tagName&&!/^body|html$/i.test(parent.tagName)){if(!/^inline|table.*$/i.test(css(parent,"display")))add(-parent.scrollLeft,-parent.scrollTop);if(mozilla&&css(parent,"overflow")!="visible")border(parent);parent=parent.parentNode;}if((safari2&&(fixed||css(offsetChild,"position")=="absolute"))||(mozilla&&css(offsetChild,"position")!="absolute"))add(-doc.body.offsetLeft,-doc.body.offsetTop);if(fixed)add(Math.max(doc.documentElement.scrollLeft,doc.body.scrollLeft),Math.max(doc.documentElement.scrollTop,doc.body.scrollTop));}results={top:top,left:left};}function border(elem){add(jQuery.curCSS(elem,"borderLeftWidth",true),jQuery.curCSS(elem,"borderTopWidth",true));}function add(l,t){left+=parseInt(l,10)||0;top+=parseInt(t,10)||0;}return results;};jQuery.fn.extend({position:function(){var left=0,top=0,results;if(this[0]){var offsetParent=this.offsetParent(),offset=this.offset(),parentOffset=/^body|html$/i.test(offsetParent[0].tagName)?{top:0,left:0}:offsetParent.offset();offset.top-=num(this,'marginTop');offset.left-=num(this,'marginLeft');parentOffset.top+=num(offsetParent,'borderTopWidth');parentOffset.left+=num(offsetParent,'borderLeftWidth');results={top:offset.top-parentOffset.top,left:offset.left-parentOffset.left};}return results;},offsetParent:function(){var offsetParent=this[0].offsetParent;while(offsetParent&&(!/^body|html$/i.test(offsetParent.tagName)&&jQuery.css(offsetParent,'position')=='static'))offsetParent=offsetParent.offsetParent;return jQuery(offsetParent);}});jQuery.each(['Left','Top'],function(i,name){var method='scroll'+name;jQuery.fn[method]=function(val){if(!this[0])return;return val!=undefined?this.each(function(){this==window||this==document?window.scrollTo(!i?val:jQuery(window).scrollLeft(),i?val:jQuery(window).scrollTop()):this[method]=val;}):this[0]==window||this[0]==document?self[i?'pageYOffset':'pageXOffset']||jQuery.boxModel&&document.documentElement[method]||document.body[method]:this[0][method];};});jQuery.each(["Height","Width"],function(i,name){var tl=i?"Left":"Top",br=i?"Right":"Bottom";jQuery.fn["inner"+name]=function(){return this[name.toLowerCase()]()+num(this,"padding"+tl)+num(this,"padding"+br);};jQuery.fn["outer"+name]=function(margin){return this["inner"+name]()+num(this,"border"+tl+"Width")+num(this,"border"+br+"Width")+(margin?num(this,"margin"+tl)+num(this,"margin"+br):0);};});})(); \ No newline at end of file diff --git a/js/jquery.ajax_queue.js b/js/jquery.ajax_queue.js new file mode 100644 index 000000000..ca42082a8 --- /dev/null +++ b/js/jquery.ajax_queue.js @@ -0,0 +1,116 @@ +/** + * Ajax Queue Plugin + * + * Homepage: http://jquery.com/plugins/project/ajaxqueue + * Documentation: http://docs.jquery.com/AjaxQueue + */ + +/** + + +
                            + + */ +/* + * Queued Ajax requests. + * A new Ajax request won't be started until the previous queued + * request has finished. + */ + +/* + * Synced Ajax requests. + * The Ajax request will happen as soon as you call this method, but + * the callbacks (success/error/complete) won't fire until all previous + * synced requests have been completed. + */ + + +(function($) { + + var ajax = $.ajax; + + var pendingRequests = {}; + + var synced = []; + var syncedData = []; + + $.ajax = function(settings) { + // create settings for compatibility with ajaxSetup + settings = jQuery.extend(settings, jQuery.extend({}, jQuery.ajaxSettings, settings)); + + var port = settings.port; + + switch(settings.mode) { + case "abort": + if ( pendingRequests[port] ) { + pendingRequests[port].abort(); + } + return pendingRequests[port] = ajax.apply(this, arguments); + case "queue": + var _old = settings.complete; + settings.complete = function(){ + if ( _old ) + _old.apply( this, arguments ); + jQuery([ajax]).dequeue("ajax" + port );; + }; + + jQuery([ ajax ]).queue("ajax" + port, function(){ + ajax( settings ); + }); + return; + case "sync": + var pos = synced.length; + + synced[ pos ] = { + error: settings.error, + success: settings.success, + complete: settings.complete, + done: false + }; + + syncedData[ pos ] = { + error: [], + success: [], + complete: [] + }; + + settings.error = function(){ syncedData[ pos ].error = arguments; }; + settings.success = function(){ syncedData[ pos ].success = arguments; }; + settings.complete = function(){ + syncedData[ pos ].complete = arguments; + synced[ pos ].done = true; + + if ( pos == 0 || !synced[ pos-1 ] ) + for ( var i = pos; i < synced.length && synced[i].done; i++ ) { + if ( synced[i].error ) synced[i].error.apply( jQuery, syncedData[i].error ); + if ( synced[i].success ) synced[i].success.apply( jQuery, syncedData[i].success ); + if ( synced[i].complete ) synced[i].complete.apply( jQuery, syncedData[i].complete ); + + synced[i] = null; + syncedData[i] = null; + } + }; + } + return ajax.apply(this, arguments); + }; + +})(jQuery); \ No newline at end of file diff --git a/js/jquery.autocomplete.js b/js/jquery.autocomplete.js new file mode 100644 index 000000000..e884e1d2a --- /dev/null +++ b/js/jquery.autocomplete.js @@ -0,0 +1,760 @@ +/* + * Autocomplete - jQuery plugin 1.0.2 + * + * Copyright (c) 2007 Dylan Verheul, Dan G. Switzer, Anjesh Tuladhar, Jörn Zaefferer + * + * Dual licensed under the MIT and GPL licenses: + * http://www.opensource.org/licenses/mit-license.php + * http://www.gnu.org/licenses/gpl.html + * + * Revision: $Id: jquery.autocomplete.js 5747 2008-06-25 18:30:55Z joern.zaefferer $ + * + */ + +;(function($) { + +$.fn.extend({ + autocomplete: function(urlOrData, options) { + var isUrl = typeof urlOrData == "string"; + options = $.extend({}, $.Autocompleter.defaults, { + url: isUrl ? urlOrData : null, + data: isUrl ? null : urlOrData, + delay: isUrl ? $.Autocompleter.defaults.delay : 10, + max: options && !options.scroll ? 10 : 150 + }, options); + + // if highlight is set to false, replace it with a do-nothing function + options.highlight = options.highlight || function(value) { return value; }; + + // if the formatMatch option is not specified, then use formatItem for backwards compatibility + options.formatMatch = options.formatMatch || options.formatItem; + + return this.each(function() { + new $.Autocompleter(this, options); + }); + }, + result: function(handler) { + return this.bind("result", handler); + }, + search: function(handler) { + return this.trigger("search", [handler]); + }, + flushCache: function() { + return this.trigger("flushCache"); + }, + setOptions: function(options){ + return this.trigger("setOptions", [options]); + }, + unautocomplete: function() { + return this.trigger("unautocomplete"); + } +}); + +$.Autocompleter = function(input, options) { + + var KEY = { + UP: 38, + DOWN: 40, + DEL: 46, + TAB: 9, + RETURN: 13, + ESC: 27, + COMMA: 188, + PAGEUP: 33, + PAGEDOWN: 34, + BACKSPACE: 8 + }; + + // Create $ object for input element + var $input = $(input).attr("autocomplete", "off").addClass(options.inputClass); + + var timeout; + var previousValue = ""; + var cache = $.Autocompleter.Cache(options); + var hasFocus = 0; + var lastKeyPressCode; + var config = { + mouseDownOnSelect: false + }; + var select = $.Autocompleter.Select(options, input, selectCurrent, config); + + var blockSubmit; + + // prevent form submit in opera when selecting with return key + $.browser.opera && $(input.form).bind("submit.autocomplete", function() { + if (blockSubmit) { + blockSubmit = false; + return false; + } + }); + + // only opera doesn't trigger keydown multiple times while pressed, others don't work with keypress at all + $input.bind(($.browser.opera ? "keypress" : "keydown") + ".autocomplete", function(event) { + // track last key pressed + lastKeyPressCode = event.keyCode; + switch(event.keyCode) { + + case KEY.UP: + event.preventDefault(); + if ( select.visible() ) { + select.prev(); + } else { + onChange(0, true); + } + break; + + case KEY.DOWN: + event.preventDefault(); + if ( select.visible() ) { + select.next(); + } else { + onChange(0, true); + } + break; + + case KEY.PAGEUP: + event.preventDefault(); + if ( select.visible() ) { + select.pageUp(); + } else { + onChange(0, true); + } + break; + + case KEY.PAGEDOWN: + event.preventDefault(); + if ( select.visible() ) { + select.pageDown(); + } else { + onChange(0, true); + } + break; + + // matches also semicolon + case options.multiple && $.trim(options.multipleSeparator) == "," && KEY.COMMA: + case KEY.TAB: + case KEY.RETURN: + if( selectCurrent() ) { + // stop default to prevent a form submit, Opera needs special handling + event.preventDefault(); + blockSubmit = true; + return false; + } + break; + + case KEY.ESC: + select.hide(); + break; + + default: + clearTimeout(timeout); + timeout = setTimeout(onChange, options.delay); + break; + } + }).focus(function(){ + // track whether the field has focus, we shouldn't process any + // results if the field no longer has focus + hasFocus++; + }).blur(function() { + hasFocus = 0; + if (!config.mouseDownOnSelect) { + hideResults(); + } + }).click(function() { + // show select when clicking in a focused field + if ( hasFocus++ > 1 && !select.visible() ) { + onChange(0, true); + } + }).bind("search", function() { + // TODO why not just specifying both arguments? + var fn = (arguments.length > 1) ? arguments[1] : null; + function findValueCallback(q, data) { + var result; + if( data && data.length ) { + for (var i=0; i < data.length; i++) { + if( data[i].result.toLowerCase() == q.toLowerCase() ) { + result = data[i]; + break; + } + } + } + if( typeof fn == "function" ) fn(result); + else $input.trigger("result", result && [result.data, result.value]); + } + $.each(trimWords($input.val()), function(i, value) { + request(value, findValueCallback, findValueCallback); + }); + }).bind("flushCache", function() { + cache.flush(); + }).bind("setOptions", function() { + $.extend(options, arguments[1]); + // if we've updated the data, repopulate + if ( "data" in arguments[1] ) + cache.populate(); + }).bind("unautocomplete", function() { + select.unbind(); + $input.unbind(); + $(input.form).unbind(".autocomplete"); + }); + + + function selectCurrent() { + var selected = select.selected(); + if( !selected ) + return false; + + var v = selected.result; + previousValue = v; + + if ( options.multiple ) { + var words = trimWords($input.val()); + if ( words.length > 1 ) { + v = words.slice(0, words.length - 1).join( options.multipleSeparator ) + options.multipleSeparator + v; + } + v += options.multipleSeparator; + } + + $input.val(v); + hideResultsNow(); + $input.trigger("result", [selected.data, selected.value]); + return true; + } + + function onChange(crap, skipPrevCheck) { + if( lastKeyPressCode == KEY.DEL ) { + select.hide(); + return; + } + + var currentValue = $input.val(); + + if ( !skipPrevCheck && currentValue == previousValue ) + return; + + previousValue = currentValue; + + currentValue = lastWord(currentValue); + if ( currentValue.length >= options.minChars) { + $input.addClass(options.loadingClass); + if (!options.matchCase) + currentValue = currentValue.toLowerCase(); + request(currentValue, receiveData, hideResultsNow); + } else { + stopLoading(); + select.hide(); + } + }; + + function trimWords(value) { + if ( !value ) { + return [""]; + } + var words = value.split( options.multipleSeparator ); + var result = []; + $.each(words, function(i, value) { + if ( $.trim(value) ) + result[i] = $.trim(value); + }); + return result; + } + + function lastWord(value) { + if ( !options.multiple ) + return value; + var words = trimWords(value); + return words[words.length - 1]; + } + + // fills in the input box w/the first match (assumed to be the best match) + // q: the term entered + // sValue: the first matching result + function autoFill(q, sValue){ + // autofill in the complete box w/the first match as long as the user hasn't entered in more data + // if the last user key pressed was backspace, don't autofill + if( options.autoFill && (lastWord($input.val()).toLowerCase() == q.toLowerCase()) && lastKeyPressCode != KEY.BACKSPACE ) { + // fill in the value (keep the case the user has typed) + $input.val($input.val() + sValue.substring(lastWord(previousValue).length)); + // select the portion of the value not typed by the user (so the next character will erase) + $.Autocompleter.Selection(input, previousValue.length, previousValue.length + sValue.length); + } + }; + + function hideResults() { + clearTimeout(timeout); + timeout = setTimeout(hideResultsNow, 200); + }; + + function hideResultsNow() { + var wasVisible = select.visible(); + select.hide(); + clearTimeout(timeout); + stopLoading(); + if (options.mustMatch) { + // call search and run callback + $input.search( + function (result){ + // if no value found, clear the input box + if( !result ) { + if (options.multiple) { + var words = trimWords($input.val()).slice(0, -1); + $input.val( words.join(options.multipleSeparator) + (words.length ? options.multipleSeparator : "") ); + } + else + $input.val( "" ); + } + } + ); + } + if (wasVisible) + // position cursor at end of input field + $.Autocompleter.Selection(input, input.value.length, input.value.length); + }; + + function receiveData(q, data) { + if ( data && data.length && hasFocus ) { + stopLoading(); + select.display(data, q); + autoFill(q, data[0].value); + select.show(); + } else { + hideResultsNow(); + } + }; + + function request(term, success, failure) { + if (!options.matchCase) + term = term.toLowerCase(); + var data = cache.load(term); + // recieve the cached data + if (data && data.length) { + success(term, data); + // if an AJAX url has been supplied, try loading the data now + } else if( (typeof options.url == "string") && (options.url.length > 0) ){ + + var extraParams = { + timestamp: +new Date() + }; + $.each(options.extraParams, function(key, param) { + extraParams[key] = typeof param == "function" ? param() : param; + }); + + $.ajax({ + // try to leverage ajaxQueue plugin to abort previous requests + mode: "abort", + // limit abortion to this input + port: "autocomplete" + input.name, + dataType: options.dataType, + url: options.url, + type:"POST", + data: $.extend({ + q: lastWord(term), + limit: options.max + }, extraParams), + success: function(data) { + var parsed = options.parse && options.parse(data) || parse(data); + cache.add(term, parsed); + success(term, parsed); + } + }); + } else { + // if we have a failure, we need to empty the list -- this prevents the the [TAB] key from selecting the last successful match + select.emptyList(); + failure(term); + } + }; + + function parse(data) { + var parsed = []; + var rows = data.split("\n"); + for (var i=0; i < rows.length; i++) { + var row = $.trim(rows[i]); + if (row) { + row = row.split("|"); + parsed[parsed.length] = { + data: row, + value: row[0], + result: options.formatResult && options.formatResult(row, row[0]) || row[0] + }; + } + } + return parsed; + }; + + function stopLoading() { + $input.removeClass(options.loadingClass); + }; + +}; + +$.Autocompleter.defaults = { + inputClass: "ac_input", + resultsClass: "ac_results", + loadingClass: "ac_loading", + minChars: 1, + delay: 400, + matchCase: false, + matchSubset: true, + matchContains: false, + cacheLength: 10, + max: 100, + mustMatch: false, + extraParams: {}, + selectFirst: true, + formatItem: function(row) { return row[0]; }, + formatMatch: null, + autoFill: false, + width: 0, + multiple: false, + multipleSeparator: ", ", + highlight: function(value, term) { + return value.replace(new RegExp("(?![^&;]+;)(?!<[^<>]*)(" + term.replace(/([\^\$\(\)\[\]\{\}\*\.\+\?\|\\])/gi, "\\$1") + ")(?![^<>]*>)(?![^&;]+;)", "gi"), "$1"); + }, + scroll: true, + scrollHeight: 180 +}; + +$.Autocompleter.Cache = function(options) { + + var data = {}; + var length = 0; + + function matchSubset(s, sub) { + if (!options.matchCase) + s = s.toLowerCase(); + var i = s.indexOf(sub); + if (i == -1) return false; + return i == 0 || options.matchContains; + }; + + function add(q, value) { + if (length > options.cacheLength){ + flush(); + } + if (!data[q]){ + length++; + } + data[q] = value; + } + + function populate(){ + if( !options.data ) return false; + // track the matches + var stMatchSets = {}, + nullData = 0; + + // no url was specified, we need to adjust the cache length to make sure it fits the local data store + if( !options.url ) options.cacheLength = 1; + + // track all options for minChars = 0 + stMatchSets[""] = []; + + // loop through the array and create a lookup structure + for ( var i = 0, ol = options.data.length; i < ol; i++ ) { + var rawValue = options.data[i]; + // if rawValue is a string, make an array otherwise just reference the array + rawValue = (typeof rawValue == "string") ? [rawValue] : rawValue; + + var value = options.formatMatch(rawValue, i+1, options.data.length); + if ( value === false ) + continue; + + var firstChar = value.charAt(0).toLowerCase(); + // if no lookup array for this character exists, look it up now + if( !stMatchSets[firstChar] ) + stMatchSets[firstChar] = []; + + // if the match is a string + var row = { + value: value, + data: rawValue, + result: options.formatResult && options.formatResult(rawValue) || value + }; + + // push the current match into the set list + stMatchSets[firstChar].push(row); + + // keep track of minChars zero items + if ( nullData++ < options.max ) { + stMatchSets[""].push(row); + } + }; + + // add the data items to the cache + $.each(stMatchSets, function(i, value) { + // increase the cache size + options.cacheLength++; + // add to the cache + add(i, value); + }); + } + + // populate any existing data + setTimeout(populate, 25); + + function flush(){ + data = {}; + length = 0; + } + + return { + flush: flush, + add: add, + populate: populate, + load: function(q) { + if (!options.cacheLength || !length) + return null; + /* + * if dealing w/local data and matchContains than we must make sure + * to loop through all the data collections looking for matches + */ + if( !options.url && options.matchContains ){ + // track all matches + var csub = []; + // loop through all the data grids for matches + for( var k in data ){ + // don't search through the stMatchSets[""] (minChars: 0) cache + // this prevents duplicates + if( k.length > 0 ){ + var c = data[k]; + $.each(c, function(i, x) { + // if we've got a match, add it to the array + if (matchSubset(x.value, q)) { + csub.push(x); + } + }); + } + } + return csub; + } else + // if the exact item exists, use it + if (data[q]){ + return data[q]; + } else + if (options.matchSubset) { + for (var i = q.length - 1; i >= options.minChars; i--) { + var c = data[q.substr(0, i)]; + if (c) { + var csub = []; + $.each(c, function(i, x) { + if (matchSubset(x.value, q)) { + csub[csub.length] = x; + } + }); + return csub; + } + } + } + return null; + } + }; +}; + +$.Autocompleter.Select = function (options, input, select, config) { + var CLASSES = { + ACTIVE: "ac_over" + }; + + var listItems, + active = -1, + data, + term = "", + needsInit = true, + element, + list; + + // Create results + function init() { + if (!needsInit) + return; + element = $("
                            ") + .hide() + .addClass(options.resultsClass) + .css("position", "absolute") + .appendTo(document.body); + + list = $("