228 Commits
Author SHA1 Message Date
OpenXE 5ccd0edbb9 refresh githash.txt on login screen, removed cronjob githash.php part 2 2022-12-12 16:16:49 +00:00
OpenXE 0ad4b9600c refresh githash.txt on login screen, removed cronjob githash.php 2022-12-12 13:57:32 +00:00
OpenXE a731d0f5df htaccess warning now not preventing login 2022-12-09 08:54:14 +00:00
OpenXE 3ea5c0e478 upgrade added external connection option, optimized db_schema.json (views now with brackets around expressions) 2022-12-09 07:13:12 +00:00
OpenXE 68554f91c1 CheckHtaccess changed from mixed to none to allow php < 8 2022-12-08 15:41:00 +00:00
OpenXE d44fa8ddb0 upgrade added export option, added export, check and creation of VIEWS 2022-12-08 14:01:32 +00:00
OpenXE 7a530e1274 .htaccess security check feature with automatic repair upon login - amended - removed writing to .htaccess 2022-12-08 12:48:49 +00:00
OpenXE e3b7634581 .htaccess security check feature with automatic repair upon login - amended 2022-12-08 11:15:24 +00:00
OpenXE 87e941516e .htacces security check feature with automatic repair upon login 2022-12-07 21:31:26 +00:00
OpenXE e5637b226e upgrade added utf8_bin for utf8_fix 2022-12-06 21:25:51 +01:00
OpenXE 08262cce5c upgrade from frontend improvements 2022-12-06 20:05:41 +00:00
OpenXE ce268dca0e upgrade and database_compare combined, database_compare removed. View "belegeregs" removed. 2022-12-06 17:02:00 +00:00
OpenXE 77393c186e mustal utf8fix 2022-12-06 14:43:02 +00:00
OpenXE 8159ae4346 Upgrade added SET SESSION innodb_strict_mode=OFF, for row size too large problem 2022-12-06 12:16:01 +00:00
OpenXE 264bc56365 upgrade improvements regarding error handling and display 2022-12-06 12:13:14 +00:00
OpenXE e4773da6f0 Upgrade from frontend 2022-12-05 22:29:48 +00:00
OpenXE c248cb16fb cronjob githash.php modified to work with ZIP-installed system too 2022-12-04 18:59:10 +00:00
OpenXE 23f390a74f upgrade initialize git repository if there is none 2022-12-03 16:27:00 +00:00
OpenXE 8cc64aee19 bugfix mustal, upgrade remove stash, do reset instead 2022-12-03 15:59:00 +00:00
OpenXE 36501a5013 Mustal upgrade tool & utf8mb3 definition 2022-12-03 15:43:30 +00:00
OpenXE c1c963624d Mustal upgrade tool & utf8mb3 definition 2022-12-03 12:06:01 +00:00
OpenXE a041c6a82c Merge branch 'master' into develop 2022-12-03 11:43:11 +00:00
OpenXE 4815e61883 Upgrade system with git and database upgrade 2022-12-03 11:41:52 +00:00
OpenXE 1a343b4b55 Bugfix www/pages/shopimporter_shopware6.php typo 2022-12-03 10:03:28 +00:00
OpenXE b70676f4a0 Merge branch 'master' into develop 2022-12-02 13:25:22 +00:00
OpenXE 6df7be74b7 Bugfixes for project specific PDF background -> UPGRADE DB with database_compare 2022-12-02 13:21:43 +00:00
OpenXE a3c253a13b Bugfix when using multidb.conf.php Error when using cronjob # /usr/bin/php8.1 /var/www/html/openxe-v.1.6/cronjobs/starter2.php 2022-12-02 12:22:23 +00:00
OpenXE b5926ee039 Bugfix www/pages/shopimporter_shopware6.php 2022-12-02 12:19:42 +00:00
OpenXE 9b62b7c247 Merge branch 'master' into develop 2022-12-02 12:15:36 +00:00
OpenXE d41745ceda Bugfix of bugfix ClearSqlCache TIMESTAMPDIFF 2022-12-02 12:13:49 +00:00
OpenXE 8c1eb6c3cc Bugfixes www/lib/dokumente/class.briefpapier.php 2022-12-02 12:04:23 +00:00
OpenXE d6dcc9f4c6 bugfix ClearSqlCache TIMESTAMPDIFF 2022-12-02 11:31:15 +00:00
OpenXE ae261d7a47 Removed xentral update functions 2022-12-02 11:20:02 +00:00
OpenXE c443496462 database compare now successfull at updating xentral oss 20.1 to OpenXE 1.6 2022-12-01 20:57:13 +00:00
OpenXE 5d1319b419 database compare key handling WIP 2022-11-30 21:39:24 +00:00
OpenXE d31c7a8961 database compare bugfix keys 2022-11-30 19:17:27 +00:00
OpenXE 1351def3bd database compare with execution WIP 2022-11-30 18:32:10 +01:00
OpenXE cdfb234393 database compare with JSON export 2022-11-29 19:05:19 +00:00
OpenXE 483a002014 database compare removed keys -> will be implemented with SHOW KEYS 2022-11-28 12:08:13 +00:00
OpenXE e25ffdd1f1 database compare remove duplicate SQL statements 2022-11-25 17:03:17 +00:00
OpenXE 84483f0444 database compare create upgrade SQL 2022-11-25 11:53:06 +00:00
OpenXE 1c955a5bca database compare generate SQL WIP 2022-11-24 22:16:50 +00:00
OpenXE 6dad06e07d database compare now looks at table type 2022-11-24 14:18:48 +00:00
OpenXE 9da2e33077 database compare code cleanup with functions 2022-11-24 13:59:49 +00:00
OpenXE 9087f4f01d database compare output improvement 2022-11-24 13:04:13 +00:00
OpenXE e82685d280 database compare optimizations, renamed from export 2022-11-24 12:42:45 +01:00
OpenXE e2869af239 database_compare bugfix if no difference 2022-11-24 12:37:20 +01:00
OpenXE beb004f374 database_compare two-way 2022-11-24 11:23:54 +00:00
OpenXE e6baa612a5 Database tool optimized 2022-11-24 09:21:37 +00:00
OpenXE c641d41219 tool database_export 2022-11-23 14:57:42 +00:00
OpenXE 76603076cd Produktion typo bugfix 2022-11-21 11:48:51 +00:00
OpenXE 461b262e16 Release 1.6 2022-11-21 09:33:11 +00:00
OpenXE 17fa438529 Produktion show no available material when no lager selected, Lager renamed Materiallager 2022-11-18 16:58:16 +01:00
OpenXE 14e64b8f4b Produktion Lager verfuegbar alle 2022-11-18 16:22:34 +01:00
OpenXE df028888e9 Produktion remove old msg on submit 2022-11-18 16:14:02 +01:00
OpenXE 625b9627e8 Produktion minor bugfixes 2022-11-17 17:56:58 +01:00
OpenXE 3ee518af03 Produktion ziellagerplatz, use lagerplatz of artikel or produktion 2022-11-16 12:17:16 +00:00
OpenXE 8518e327aa Produktion cosmetic 2022-11-15 16:40:37 +00:00
OpenXE 84cdd8754a Produktion Protokoll 2022-11-15 16:24:21 +00:00
OpenXE 7c468dbced Produktion minidetail 2022-11-15 14:50:59 +00:00
OpenXE ba31fc62cf Produktion copy 2022-11-15 11:30:25 +00:00
OpenXE f6a1315192 Produktion go to edit after new item 2022-11-15 09:16:58 +00:00
OpenXE c219c32212 Bugfix Produktion new item 2022-11-11 17:07:42 +00:00
OpenXE e1b8b7864f Produktion filter list 2022-11-11 15:14:59 +00:00
OpenXE 822960b9f0 Bugfix Produktion refresh all icons on list action 2022-11-11 15:22:04 +01:00
OpenXE 0fef7146c6 Produktion refresh all icons on list action 2022-11-11 14:16:46 +00:00
OpenXE 27d48a55bb Produktion adjust reservation if there is scrap, fixed icons TBD: cronjob for icon update 2022-11-10 21:42:53 +00:00
OpenXE 06dbb9b8b8 Produktion improvement using functions, production progress with reserved quantity 2022-11-10 19:48:34 +00:00
OpenXE 99d5804ffa Added user edit check DisableModuls 2022-11-10 16:00:25 +00:00
OpenXE c601ac17df Changed permissiondenied page from Xentral to OpenXE 2022-11-10 15:39:24 +00:00
OpenXE 3d37049ea1 Produktion menge anpassen 2022-11-10 12:08:30 +01:00
OpenXE 1bf8f567b4 Bugfix Produktion reservieren 2022-11-10 10:32:03 +01:00
OpenXE 39e741a595 Bugfix Produktion teilproduktion preserve old values, bugfix list view artikel name 2022-11-10 10:10:04 +01:00
OpenXE e2120d1862 Bugfix Produktion auslagern 2022-11-09 17:19:20 +01:00
OpenXE 8c67d97728 Produktion teilen, leeren 2022-11-09 14:48:09 +00:00
OpenXE 3b804ef745 Produktion Teilproduktion WIP 2022-11-08 22:22:27 +00:00
OpenXE aea469320f Bugfix Produktion material per artikel 2022-11-08 15:52:33 +01:00
OpenXE a9cab336d0 Lager reservierungen added column Artikelnummer 2022-11-07 18:15:10 +00:00
OpenXE 4b27887dd2 Bugfix Produktuion display of stock numbers 2022-11-07 17:09:19 +00:00
OpenXE 230d1b03f2 module creator added alignright 2022-11-07 15:54:57 +00:00
OpenXE 8c559bf5cf Produktion column alignment of numbers 2022-11-07 15:52:16 +00:00
OpenXE ef8b6f7a1f Bugfix produktion list 2022-11-07 16:23:16 +01:00
OpenXE 348d946637 Bugfix intial produktion status 2022-11-07 16:08:25 +01:00
OpenXE cadbf08376 Produktion show open quantities 2022-11-07 16:05:56 +01:00
OpenXE 68723b7c4b Bugfix Produktion number format 2022-11-07 14:00:51 +00:00
OpenXE e6188d9153 Bugfix Produktion list artikel 2022-11-07 13:28:35 +00:00
OpenXE ea5ac90b13 Bugfix Produktion empty status 2022-11-07 11:29:43 +00:00
OpenXE 20c64a97ea module_creator with column selection 2022-11-07 10:11:33 +00:00
OpenXE 8032bf779a Merge branch 'master' into develop 2022-11-06 20:17:17 +00:00
OpenXE ed5d1690ef Bugfix Produktion icons 2022-11-06 18:46:57 +00:00
OpenXE c0380142ba WIP Produktion edit postions 2022-11-06 18:42:42 +00:00
OpenXE cfbc602443 WIP Produktion material needed per item 2022-11-06 15:18:54 +00:00
OpenXE e249d5a715 WIP Produktion formatting 2022-11-06 15:06:13 +00:00
OpenXE e39f56cb24 Produktion Icons sql for angelegt, abgeschlossen, storniert 2022-11-06 11:59:31 +00:00
OpenXE 411ab85359 WIP Produktion process with stock removal, reservation and stock adding 2022-11-04 15:39:12 +00:00
OpenXE 9f616fc0e5 Produktion WIP list view improvements 2022-11-03 21:48:12 +00:00
OpenXE 2e6d57e93a Produktion WIP reservieren bugfix 2022-11-03 21:30:14 +00:00
OpenXE dc6827fc1e Produktion WIP aggregated view on material items 2022-11-03 14:49:42 +00:00
OpenXE 13d776750e Produktion WIP reservieren 2022-11-03 12:23:53 +00:00
OpenXE 20e69d9291 Bugfix datei_list 2022-11-01 10:02:10 +00:00
OpenXE 202892b9da Produktion UI minor changes 2022-11-01 09:28:20 +00:00
OpenXE d774d9d349 added id field to module_creator inputs, inputs size 20 2022-10-28 10:05:39 +00:00
OpenXE a277250ee0 Produktion UI WIP 2022-10-27 15:55:24 +00:00
OpenXE f0b1f1731e Merge remote-tracking branch 'github/develop' into develop 2022-10-26 14:13:08 +00:00
OpenXE d5f60e73c1 Produktion edit view with positions 2022-10-26 13:52:50 +00:00
OpenXE-ERP 2b5d01b52a Merge pull request #25 from 0xAF7/add-gitignore
Add gitignore file
2022-10-26 11:46:54 +02:00
0xAF7 7e73d30805 Add gitignore file 2022-10-25 20:29:30 +02:00
OpenXE feddd00896 Bugfix module creator dropnbox 2022-10-22 12:33:28 +00:00
OpenXE d1991b3f72 Production monitor icons 2022-10-22 12:31:37 +00:00
OpenXE 880f4cbdf1 Produktion list WIP 2022-10-21 20:40:47 +00:00
OpenXE 278d4b631b Produktion initial 2022-10-21 16:12:46 +00:00
OpenXE debe733f13 module_creator expanded now with minidetail and select in list 2022-10-21 16:11:56 +00:00
OpenXE-ERP a243d3b330 Update SERVER_INSTALL.md 2022-10-20 21:46:54 +02:00
OpenXE-ERP bbcb6f5c52 Add files via upload
Optimized login screen picture
2022-10-20 18:21:20 +02:00
Xenomporio 1ce413a763 OpenXE rebranding 2022-10-14 14:22:08 +02:00
OpenXE-ERP 9d6b86b5f9 Add files via upload 2022-10-13 10:16:58 +02:00
OpenXE-ERP ba030de75c Update README.md 2022-10-13 10:09:11 +02:00
OpenXE-ERP 8684f7d68f Update README.md 2022-10-13 10:08:28 +02:00
xenomporio bf126c2704 Update README.md 2022-10-11 10:45:33 +02:00
Xenomporio bd10919ea1 Removed www/pages/content/rahmen70red_ohne_form.tpl:w 2022-10-11 10:32:55 +02:00
Xenomporio 7457acbdc1 Merge https://github.com/xenomporio-org/Xenomporio 2022-10-11 10:26:25 +02:00
xenomporio fe08ee7125 Update README.md 2022-10-05 10:56:31 +02:00
Xenomporio 764e19f67b Added sprache to table verbindlichkeit 2022-09-15 15:40:47 +02:00
root 445ba3529c Bugfix in fpdi (external lib) rewrite of function each() 2022-09-13 06:58:13 +00:00
root f625c4b880 Fix compatibility to verbindlichkeit 2022-09-12 15:23:56 +00:00
Xenomporio a78571aa45 1.3.1 2022-09-07 17:16:04 +02:00
Xenomporio f64f6f64cb Bugfix yui autocompletebestellung (was commented out) 2022-09-07 11:42:22 +02:00
Xenomporio af4c64359b Wareneingang also for non stock artikel 2022-09-07 11:41:21 +02:00
root 383524f348 Improved compatibility to Xentral 20 database 2022-09-04 09:57:00 +00:00
Xenomporio 2bb3130b00 Release V.1.3 Readme 2022-08-20 12:20:03 +02:00
Xenomporio d808676489 Bugfix typo 2022-08-20 12:09:07 +02:00
Xenomporio 954eebcdc1 Ticket system bugfixes with filename handling 2022-08-20 11:59:32 +02:00
Xenomporio 84cd447f49 Ticket system cosmetic changes to xentral 20 compatibility assistents 2022-08-19 14:24:13 +02:00
Xenomporio d05cd92b3b ticket system migration helper for ticket date from xentral 20 2022-08-18 21:36:42 +02:00
Xenomporio 3f75bfad7d ticket system migration helper for ticket status from xentral 20 2022-08-18 20:45:09 +02:00
Xenomporio b16b19f2d6 ticket system switched message text display to iframe 2022-08-18 20:41:44 +02:00
Xenomporio c24be3f1c7 ticket system bugfix display of ticket subjects when notiz IS NULL (xentral 20 compatibility) 2022-08-15 23:43:36 +02:00
Xenomporio db1c9cc4ce Ticket system added database compatibility to xentral 20 enterprise ticket system 2022-08-15 18:52:36 +02:00
Xenomporio f3dfd870c2 Bugfix ticket system attachments with UTF-8 URL-encoded filenames 2022-08-14 20:18:15 +02:00
Xenomporio f08c9ecc09 Some changes for file management module dateien 2022-08-12 20:13:15 +02:00
Xenomporio 1e6812dbd4 edit.png -> edit.svg 2022-08-08 16:16:41 +02:00
Xenomporio 29cf035d2e small modifications to welcome.php 2022-08-08 15:52:45 +02:00
Xenomporio 37e100d7ff Bugfix SQL_CALC_FOUND_ROWS for all live tables 2022-08-08 14:06:22 +02:00
Xenomporio 7ff7e6bfd6 Ticket system bugfix received recipients 2022-08-07 12:07:55 +02:00
Xenomporio 17f0efcc68 module creator changed edit icon from png to svg 2022-08-07 11:50:57 +02:00
Xenomporio dfdad1b8c4 Ticket system implemented ticketregeln (ticket rules) 2022-08-07 11:50:13 +02:00
Xenomporio cdaecb3969 Ticket system link from ticket to adresse, changed icon from png to svg 2022-08-06 11:31:43 +02:00
Xenomporio a10933583c Some improvements in adresse CRM 2022-08-06 10:57:29 +02:00
Xenomporio 4c98f6966b CRM new email with prefilled text 2022-08-06 10:41:47 +02:00
Xenomporio 4af7eacfd8 Ticket system / sendmail, changes to response citation and html chars handling 2022-08-06 10:40:58 +02:00
Xenomporio 3c1e7e0949 Bugfix htmlentities in ckeditor e.g. <mail@server> 2022-08-05 21:16:58 +02:00
Xenomporio 18dde9387e Ticket send mail with signature 2022-08-05 19:02:50 +02:00
Xenomporio 6a41075086 Fill out mail adress in new ticket message 2022-08-05 17:19:01 +02:00
Xenomporio a1aa642849 Bugfix incoming tickets select warteschlange and adresse 2022-08-05 17:08:41 +02:00
Xenomporio e1e886e8e6 Ticket system fix display of user edited fields wth htmlentities 2022-08-04 17:58:09 +02:00
Xenomporio b57362ecba Added tickets to CRM view in adresse minidetail 2022-08-04 17:15:11 +02:00
Xenomporio eed70bf673 Bugfix for email address handling in ticket system 2022-08-04 16:50:22 +02:00
Xenomporio fd076040c2 Ticket system default sorting by time 2022-08-03 18:08:32 +02:00
Xenomporio d5a85858bd Ticket System save timestamp on mass edit, new ticket with standard project 2022-08-03 17:43:45 +02:00
Xenomporio 93da199f12 Bugfix ticket system display and handling of recipients 2022-08-03 17:24:28 +02:00
Xenomporio 731f67a9b9 adresse included tickets in crm view 2022-08-02 17:04:58 +02:00
Xenomporio 67bad8d911 Bugfix Ticket System empty cc 2022-08-02 11:50:43 +02:00
Xenomporio 244d30faa9 Bugfix display of open tickets in sidebar 2022-08-01 22:56:28 +02:00
Xenomporio 3238206446 Ticket system rework of the recipients, cc organisation, mail display and more 2022-08-01 22:55:52 +02:00
Xenomporio 6e7e27d289 Ticket system stapelverarbeitung multi processing 2022-07-31 22:32:36 +02:00
Xenomporio 7ca19d7bac Ticket system tag functionality as well as sort/search bugfix 2022-07-31 21:45:38 +02:00
Xenomporio 11f9e7e24e Ticket system filters, notiz adding, time of last action 2022-07-31 18:23:43 +02:00
Xenomporio 3c540cf48a Ticket system minidetail 2022-07-30 14:29:02 +02:00
Xenomporio ecf45792d6 Ticket prio with checkbox and highlight 2022-07-30 13:36:18 +02:00
Xenomporio 7bbcdf206b Ticket system now with drafts and attachement of sent mails 2022-07-30 10:49:47 +02:00
Xenomporio a9c85b0c81 Ticket new message with draft 2022-07-29 14:45:16 +02:00
Xenomporio 11def529a3 Only one RE: when answering tickets 2022-07-27 21:26:59 +02:00
Xenomporio 7efbe5bd0b Changes regarding ticket incoming file attachments 2022-07-27 18:05:24 +02:00
Xenomporio b7f468e62d Added log to einstellungen 2022-07-26 18:38:12 +02:00
Xenomporio b5caed416a Ticket sending works now, attachments tbd 2022-07-26 18:37:54 +02:00
Xenomporio eed061776a Some improvements erpapi mail 2022-07-26 17:35:16 +02:00
Xenomporio a5be988a43 Ticketsystem reading of mails and import
Todo frontend details and sending. Also there is a no timestamp error at import on some mails (error returns e.g.)
2022-07-24 21:11:25 +02:00
Xenomporio 9b9e6d13c5 Storing sent mails to IMAP folder now works 2022-07-23 21:11:01 +02:00
Xenomporio a4449204b5 Ticket module primitive list view 2022-07-22 17:42:03 +02:00
Xenomporio 8a1bfda324 Added IMAP testing function to emailbackup accounts 2022-07-22 17:27:42 +02:00
Xenomporio 881267a00e Sendmail force html, IMAP folder simple implementation but wothout attachments. Also display of new tickets modifed 2022-07-22 17:17:12 +02:00
Xenomporio c6fe8a736b module creator extended to use short table alias 2022-07-22 11:55:58 +02:00
Xenomporio dbf5201c20 Reimplemented module ticket wartschlangen 2022-07-22 11:15:27 +02:00
Xenomporio 910a8544a4 Some frontend adaption for the ticket system 2022-07-22 11:15:15 +02:00
Xenomporio b2610079d6 Importing of tickets from email
Everything needed went into TicketImportHelper, with LegacyDB. Functions taken from TicketService, Gateway and AddressWrapper
2022-07-21 23:44:48 +02:00
Xenomporio 6cbc0bd08e cronjob tickets first version, processing tbd 2022-07-21 17:21:24 +02:00
Xenomporio 68965e87cd Merge branch 'develop' 2022-07-21 11:51:45 +02:00
Xenomporio 89671797a1 changed wareneingang default menu to list 2022-07-20 17:14:08 +02:00
Xenomporio 0ed0cc8bbb Reorganised wareneingang and lager menu 2022-07-20 16:51:41 +02:00
Xenomporio e9e292c2e2 wareneingang some sorting renaming of files 2022-07-20 16:45:00 +02:00
Xenomporio bd556796e2 Bugfix wareneingang, additional columns renr & lsnr 2022-07-20 13:45:22 +02:00
Xenomporio ba1157dbfc Removed select from steuerregelngruppe, table does not exist 2022-07-20 12:29:51 +02:00
Xenomporio e3e9e52ff5 Many modifications to wareneingang and paketdistribution 2022-07-20 12:27:12 +02:00
Xenomporio 70e3289df5 Merge branch 'develop' 2022-07-19 17:20:14 +02:00
Xenomporio b27b5d155e Small changes versandzentrum 2022-07-19 17:15:51 +02:00
Xenomporio 3b03a9e684 Deactivated 2 step commissioning in frontend 2022-07-19 10:33:56 +02:00
Xenomporio 49c912cb45 Auftragversand -> Send mail after printing 2022-07-19 10:33:27 +02:00
Xenomporio 5b6062f9be Show number of order auftrag drafts in bearbeitung 2022-07-19 10:16:06 +02:00
Xenomporio d9240e184d Autoversand_manuell cronjob now able to send orders with delivery date in the future, if selected by user 2022-07-18 20:27:17 +02:00
Xenomporio fc64ced7ea Bugfix versandzentrum ajax filters 2022-07-18 20:05:47 +02:00
Xenomporio 99bbbdca42 Bugfix in IMAP put mail into sentfolder 2022-07-17 23:25:34 +02:00
Xenomporio 02bf9af08e Implemented cronjob order processing (manual)
orders have to be marked in the versandzentrum beforehand
2022-07-17 12:50:52 +02:00
Xenomporio bb3e18d7b4 Added auftrag versandzentrum order queue warteschlange
-> Cronjob processing tbd
2022-07-16 19:29:37 +02:00
Xenomporio 032b03a6c9 Removed order process options in project settings. -> cronjob processing as well as two step process is not implemented and missing in the sources (kommissionierlauf.php) 2022-07-15 10:36:38 +02:00
Xenomporio ee4f7ab88a changed abkuerzung in projekt to varchar(128) because of index 2022-07-14 20:57:50 +02:00
Xenomporio 989974d556 versandzentrum fast lane display harmonised 2022-07-14 20:43:40 +02:00
Xenomporio 6ff92c0900 Fixed versandzentrum filters 2022-07-14 18:23:57 +02:00
Xenomporio b52354b1ad Automatic order processing manually
Cronjob based not working yes. Expanded process options in project settings.
2022-07-14 14:06:30 +02:00
Xenomporio 90de642685 Minor bugfix for emailaccount testmail 2022-07-13 11:23:38 +02:00
Xenomporio b14c419f3f removed.upgrade.host 2022-07-13 10:45:03 +02:00
Xenomporio eff711a539 Minidetail versandzentrum added 2022-07-12 17:23:02 +02:00
Xenomporio ff7f9160e4 Bugfix auto increment of document IDs 2022-07-12 11:33:14 +02:00
Xenomporio 3ef58b681f Bugfix auto increment of document IDs 2022-07-11 21:57:48 +02:00
Xenomporio 2a5f01004b Fixed autoversand 2022-07-11 17:49:59 +02:00
xenomporio b618ea78d4 Update README.md 2022-07-08 14:31:19 +02:00
xenomporio 161e6ea929 Update SERVER_INSTALL.md 2022-07-08 14:30:42 +02:00
xenomporio 9eb590f7ba Update SERVER_INSTALL.md 2022-07-08 14:27:37 +02:00
xenomporio c4e0494417 Update INSTALL.md 2022-07-08 14:21:53 +02:00
xenomporio c15fa08427 Add files via upload 2022-07-08 14:21:32 +02:00
xenomporio d937436f9e Add files via upload 2022-07-08 14:17:59 +02:00
xenomporio 8e4b58b7cc Update INSTALL.md 2022-07-08 14:17:20 +02:00
xenomporio d0ebab936a Add files via upload 2022-07-08 14:07:19 +02:00
xenomporio ba9307f01c Create stub 2022-07-08 14:06:51 +02:00
xenomporio 298b88331b Update SERVER_INSTALL.md 2022-07-08 11:42:06 +02:00
xenomporio e7f01f7e10 Update SERVER_INSTALL.md 2022-07-08 11:41:47 +02:00
xenomporio ffd58bb196 Update INSTALL.md 2022-07-08 11:40:09 +02:00
xenomporio 0b5fa939d5 Update SERVER_INSTALL.md 2022-07-08 10:59:14 +02:00
xenomporio 758328a8ef Create SERVER_INSTALL.md 2022-07-08 10:45:25 +02:00
126 changed files with 369877 additions and 33917 deletions
+5
View File
@@ -0,0 +1,5 @@
conf/user.inc.php
conf/user_defined.php
userdata/cronjobkey.txt
userdata/tmp/
www/cache/
+19
View File
@@ -0,0 +1,19 @@
# Generated file from class.acl.php
# For detection of htaccess functionality
SetEnv OPENXE_HTACCESS on
# Disable directory browsing
Options -Indexes
# Set default page to index.php
DirectoryIndex "index.php"
# Deny general access
Order deny,allow
<FilesMatch ".">
Order Allow,Deny
Deny from all
</FilesMatch>
# Allow index.php
<Files "index.php">
Order Allow,Deny
Allow from all
</Files>
# end
+24 -7
View File
@@ -1,10 +1,27 @@
# Xentral Installation # OpenXE installation
1. aktuelle .tar.gz entpacken in einem Ordner ## Place the installation files into a folder in /var/www/html/.
2. per Browser auf auf Verzeichnis gehen
3. setup durchfuehren (trotz Hinweis der Rechte (diese muessen passen) weiter klicken)
4. Der Webserver-Pfad sollte dringend auf www gesetzte werden, sodass die
Firmen kritischen Dateien auf keinen Fall durch eine fehlerhafte .htaccess
Datei jemals online stehen (es geht primaer um den Ordner userdata und conf).
`cd /var/www/html`
e.g. Release 1.0:
`sudo wget https://github.com/openxe-org/OpenXE/archive/refs/tags/V.1.0.zip`
`unzip V.1.0.zip`
## Set folder permissions:
`sudo chown www-data:www-data OpenXE-V.1.0 -R`
## Fire up the setup page in a browser
http://yourserverip/OpenXE-V.1.0 (watch out, its case sensitive)
<img src="doc/Install-10.png" width="800px">
<img src="doc/Install-20.png" width="800px">
<img src="doc/Install-30.png" width="800px">
<img src="doc/Install-40.png" width="800px">
<img src="doc/Install-50.png" width="800px">
<img src="doc/Install-60.png" width="800px">
<img src="doc/Install-done.png" width="800px">
+27 -4
View File
@@ -1,8 +1,8 @@
# Xenomporio - The free ERP # OpenXE - The free ERP
![Xenomporio overview](https://github.com/xenomporio-org/Xenomporio/blob/master/www/themes/new/images/login_screen_picture.jpg "Xenomporio") ![OpenXE overview](https://github.com/openxe-org/OpenXE/blob/master/www/themes/new/images/login_screen_picture.jpg "OpenXE")
Xenomporio ist eine umfassende webbasierte Anwendung zur Abwicklung aller kaufmännischen Prozesse. Zu den Funktionen gehören unter Anderem: OpenXE ist eine umfassende webbasierte Anwendung zur Abwicklung aller kaufmännischen Prozesse. Zu den Funktionen gehören unter Anderem:
* Erstellung von Angeboten * Erstellung von Angeboten
* Auftragsabwicklung * Auftragsabwicklung
@@ -13,4 +13,27 @@ Xenomporio ist eine umfassende webbasierte Anwendung zur Abwicklung aller kaufm
* Aufgaben- und Terminverwaltung * Aufgaben- und Terminverwaltung
* Zeitabrechnung * Zeitabrechnung
Xenomporio ist freie Software, lizensiert unter AGPL 3 und basiert auf der Open Source Version von Xentral https://xentral.com/ # Neue Community-Seite: https://openxe.org/
An alle Interessenten:
Dieses Projekt startet mit einer leistungsfähigen Software, aber gerade am Anfang ist es schwierig, die potenziellen Anwender abzuschätzen. Das ist jedoch eine wichtige Information und auch Motivation für alle, die sich aktiv am Projekt beteiligen. Wir bitten daher, alle Interessenten für OpenXE, sich hier anzumelden. Die Anmeldung ist kostenfrei und mit keinerlei Verpflichtungen versehen. Ausserdem habt Ihr den Vorteil, Euch bei Fragen direkt im Communitybereich zu melden oder selber aktiv mitzugestalten.
Wir freuen uns über Eure Teilnahme, egal ob als stiller Mitleser oder aktiver User.
# Letzte Änderungen: Ticket System
Neu in [V.1.3](https://github.com/openxe-org/OpenXE/releases/tag/V.1.3):
Neuimplementierung des Xentral 20 Enterprise Ticketsystems mit vielen Verbesserungen, z.B.:
- Anhänge werden auch bei ausgehenden Nachrichten gespeichert
- Verbesserte Kommentarfunktion
- Unterstützung mehrerer Empfänger und CC
- Verbesserte Stapelverarbeitung
# Installation
[Hier gehts zur Server Installation](SERVER_INSTALL.md)
[Hier gehts zur OpenXE Installation](INSTALL.md)
OpenXE ist freie Software, lizensiert unter AGPL 3 und basiert auf der Open Source Version von Xentral https://xentral.com/
+188
View File
@@ -0,0 +1,188 @@
# Server Install (Example for ubuntu-22.04-live-server-amd64.iso)
## Create new server instance
e.g. 8 GB RAM, 128 GB hard drive, 4 CPUs.
## Install the operating system
(...)
It is recommended install OpenSSH during install.
## Refresh the update system
`sudo apt-get update`
## Install the webserver
`sudo apt-get install apache2`
-> Test the webserver (http://IP_ADDRESS)
It should show the "Apache2 Default Page".
## Install PHP (8.1)
`sudo apt-get install php libapache2-mod-php`
`php -v` should output:
```PHP 8.1.2 (cli) (built: Jun 13 2022 13:52:54) (NTS)
Copyright (c) The PHP Group
Zend Engine v4.1.2, Copyright (c) Zend Technologies
with Zend OPcache v8.1.2, Copyright (c), by Zend Technologies
```
## Install PHP modules
`sudo apt-get install php-mysql php-cli php-imap php-curl php-xml php-soap php-zip php-mbstring php-gd`
## Configure PHP
Add the following lines to `/etc/php/8.1/apache2/php.ini` and `/etc/php/8.1/cli/php.ini`:
```
disable_functions = pcntl_alarm,pcntl_fork,pcntl_waitpid,pcntl_wait,pcntl_wifexited,pcntl_wifstopped,pcntl_wifsignaled,pcntl_wexitstatus,pcntl_wtermsig,pcntl_wstopsig,pcntl_signal,pcntl_signal_dispatch,pcntl_get_last_error,pcntl_strerror,pcntl_sigprocmask,pcntl_sigwaitinfo,pcntl_sigtimedwait,pcntl_exec,pcntl_getpriority,pcntl_setpriority,dl,highlight_file,show_source,proc_open,popen
post_max_size = 100M
upload_max_filesize = 100M
max_execution_time = 3600
max_input_time = 3600
magic_quotes_gpc = Off
file_uploads = Yes
max_file_uploads = 20
short_open_tag = On
max_input_vars=3000
memory_limit = 256M
```
## Install additional zip
`sudo apt-get install zip`
## Install mysql client
`sudo apt-get install mysql-client`
## Install database server
`sudo apt-get install mariadb-server`
## Configure database server
`sudo mysql_secure_installation`
```
NOTE: RUNNING ALL PARTS OF THIS SCRIPT IS RECOMMENDED FOR ALL MariaDB
SERVERS IN PRODUCTION USE! PLEASE READ EACH STEP CAREFULLY!
In order to log into MariaDB to secure it, we'll need the current
password for the root user. If you've just installed MariaDB, and
haven't set the root password yet, you should just press enter here.
Enter current password for root (enter for none):
OK, successfully used password, moving on...
Setting the root password or using the unix_socket ensures that nobody
can log into the MariaDB root user without the proper authorisation.
You already have your root account protected, so you can safely answer 'n'.
Switch to unix_socket authentication [Y/n] n
... skipping.
You already have your root account protected, so you can safely answer 'n'.
Change the root password? [Y/n] y
New password:
Re-enter new password:
Password updated successfully!
Reloading privilege tables..
... Success!
By default, a MariaDB installation has an anonymous user, allowing anyone
to log into MariaDB without having to have a user account created for
them. This is intended only for testing, and to make the installation
go a bit smoother. You should remove them before moving into a
production environment.
Remove anonymous users? [Y/n] y
... Success!
Normally, root should only be allowed to connect from 'localhost'. This
ensures that someone cannot guess at the root password from the network.
Disallow root login remotely? [Y/n] y
... Success!
By default, MariaDB comes with a database named 'test' that anyone can
access. This is also intended only for testing, and should be removed
before moving into a production environment.
Remove test database and access to it? [Y/n] y
- Dropping test database...
... Success!
- Removing privileges on test database...
... Success!
Reloading the privilege tables will ensure that all changes made so far
will take effect immediately.
Reload privilege tables now? [Y/n] y
... Success!
Cleaning up...
All done! If you've completed all of the above steps, your MariaDB
installation should now be secure.
Thanks for using MariaDB!
```
## Create database for openxe
`mysql -u root -p`
```
Welcome to the MariaDB monitor. Commands end with ; or \g.
Your MariaDB connection id is 41
Server version: 10.6.7-MariaDB-2ubuntu1 Ubuntu 22.04
Copyright (c) 2000, 2018, Oracle, MariaDB Corporation Ab and others.
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
MariaDB [(none)]> CREATE DATABASE openxe;
Query OK, 1 row affected (0.001 sec)
MariaDB [(none)]> CREATE USER 'openxe'@'localhost' IDENTIFIED BY 'enteryourpasswordhere';
Query OK, 0 rows affected (0.015 sec)
MariaDB [(none)]> GRANT ALL PRIVILEGES ON openxe.* TO 'openxe'@'localhost' WITH GRANT OPTION;
Query OK, 0 rows affected (0.012 sec)
MariaDB [(none)]> FLUSH PRIVILEGES;
Query OK, 0 rows affected (0.002 sec)
MariaDB [(none)]> quit
Bye
```
You can test your database like this:
`mysql -u openxe -p`
```
Enter password:
Welcome to the MariaDB monitor. Commands end with ; or \g.
Your MariaDB connection id is 44
Server version: 10.6.7-MariaDB-2ubuntu1 Ubuntu 22.04
Copyright (c) 2000, 2018, Oracle, MariaDB Corporation Ab and others.
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
MariaDB [(none)]> show databases;
+--------------------+
| Database |
+--------------------+
| information_schema |
| openxe |
+--------------------+
2 rows in set (0.001 sec)
MariaDB [(none)]> quit
Bye
```
## --> Reset your server
Continue with [OpenXE Installation](INSTALL.md)
@@ -70,6 +70,7 @@ class MailAttachmentData implements MailAttachmentInterface
throw new InvalidArgumentException('missing header: "Content-Disposition"'); throw new InvalidArgumentException('missing header: "Content-Disposition"');
} }
$disposition = $dispositionHeader->getValue(); $disposition = $dispositionHeader->getValue();
if (!preg_match('/(.+);\s*filename="([^"]+)".*$/m', $disposition, $matches)) { if (!preg_match('/(.+);\s*filename="([^"]+)".*$/m', $disposition, $matches)) {
throw new InvalidArgumentException( throw new InvalidArgumentException(
sprintf('unexpected header value "Content-Disposition" = %s', $disposition) sprintf('unexpected header value "Content-Disposition" = %s', $disposition)
@@ -77,6 +78,17 @@ class MailAttachmentData implements MailAttachmentInterface
} }
$isInline = strtolower($matches[1]) === 'inline'; $isInline = strtolower($matches[1]) === 'inline';
$filename = $matches[2]; $filename = $matches[2];
// Thunderbird UTF URL-Format
$UTF_pos = strpos($filename,'UTF-8\'\'');
if ($UTF_pos !== false) {
$wasUTF = "JA";
$filename = substr($filename,$UTF_pos);
$filename = rawurldecode($filename);
}
$cid = null; $cid = null;
$contentIdHeader = $part->getHeader('content-id'); $contentIdHeader = $part->getHeader('content-id');
if ($contentIdHeader !== null) { if ($contentIdHeader !== null) {
@@ -23,7 +23,7 @@ final class FactoryMethodDefinition
if (!is_callable($callable, false)) { if (!is_callable($callable, false)) {
/* /*
xenomporio OpenXE-todo
unknown compatibility issue unknown compatibility issue
commented out as hotfix commented out as hotfix
+1 -1
View File
@@ -20,7 +20,7 @@ final class ErrorPageData implements JsonSerializable
public function __construct($exception, $title = null) public function __construct($exception, $title = null)
{ {
$this->exception = $exception; $this->exception = $exception;
$this->title = !empty($title) ? (string)$title : 'Xenomporio: Es ist ein unerwarteter Fehler aufgetreten!'; $this->title = !empty($title) ? (string)$title : 'OpenXE: Es ist ein unerwarteter Fehler aufgetreten!';
} }
@@ -48,7 +48,11 @@ final class MultiDbArrayHydrator
$description = !empty($item['description']) ? $item['description'] : $defaultConfig->WFdbname; $description = !empty($item['description']) ? $item['description'] : $defaultConfig->WFdbname;
// Cronjobs nur aktivieren, wenn Einstellung vorhanden und gesetzt (Default `false`). // Cronjobs nur aktivieren, wenn Einstellung vorhanden und gesetzt (Default `false`).
$cronjobsActive = (int)$item['cronjob'] === 1; if (array_key_exists('cronjob',$item)) {
$cronjobsActive = (int)$item['cronjob'] === 1;
} else {
$cronjobsActive = false;
}
if(!empty($item['dbname']) && $defaultConfig->WFdbname === $item['dbname']) { if(!empty($item['dbname']) && $defaultConfig->WFdbname === $item['dbname']) {
$item = []; $item = [];
@@ -145,8 +145,11 @@ final class SystemMailer
$email = new EmailMessage($subject, $body, $recipients, $ccs, $bccs); $email = new EmailMessage($subject, $body, $recipients, $ccs, $bccs);
foreach ($attachFiles as $file) { foreach ($attachFiles as $file) {
$this->logger->debug("Attaching file", ['filename' => $file]);
if ($file !== null && file_exists($file)) { if ($file !== null && file_exists($file)) {
$email->addAttachment(new FileAttachment($file)); $email->addAttachment(new FileAttachment($file));
} else {
$this->logger->debug("Attaching file failed", ['filename' => $file]);
} }
} }
+611 -255
View File
@@ -14,9 +14,13 @@ use Xentral\Components\MailClient\Client\MailClientInterface;
use Xentral\Components\MailClient\Data\MailMessageInterface; use Xentral\Components\MailClient\Data\MailMessageInterface;
use Xentral\Modules\SystemMailer\Data\EmailBackupAccount; use Xentral\Modules\SystemMailer\Data\EmailBackupAccount;
use Xentral\Modules\Ticket\Importer\TicketFormatter; use Xentral\Modules\Ticket\Importer\TicketFormatter;
use Xentral\Modules\Ticket\Exception\NumberGeneratorException;
use Xentral\Modules\Ticket\Exception\InvalidArgumentException;
/** /**
* Utility functions for tickets_google cronjob for improved testability * Utility functions for tickets cronjob for improved testability
* This is used to create and update tickets from emailbackup, called by the tickets.php cronjob
* It uses the TicketService to process the tickets
*/ */
class TicketImportHelper class TicketImportHelper
{ {
@@ -49,7 +53,7 @@ class TicketImportHelper
/** /**
* @param LegacyDataBase $db * @param LegacyDataBase $db
* @param erpAPI $erpApi * @param erpAPI $erpApi
* @param TicketModule $ticketModule * @param TicketModule $ticketModule
* @param LegacyConfig $config * @param LegacyConfig $config
* @param TicketFormatter $formatter * @param TicketFormatter $formatter
* @param MailClientInterface $mailClient * @param MailClientInterface $mailClient
@@ -76,6 +80,400 @@ class TicketImportHelper
$this->config = $config; $this->config = $config;
} }
/* Function from AddressWrapper...
Still using legacy db
*/
public function tryGetAddressIdByEmailAddress(string $emailAddress): ?int
{
$searchByEmail = 'SELECT a.id FROM `adresse` AS `a`
WHERE a.email LIKE \''.$emailAddress.'\' AND a.geloescht = 0
ORDER BY a.id DESC';
$id = $this->db->Select($searchByEmail);
if ($id !== null && $id > 0) {
return (int) $id;
}
$searchByResponsePerson = 'SELECT ap.adresse FROM `ansprechpartner` AS `ap`
WHERE ap.email LIKE \''.$emailAddress.'\'
ORDER BY ap.id DESC';
$id = $this->db->Select($searchByResponsePerson);
if ($id !== null && $id > 0) {
return (int) $id;
}
$searchByContactInfo = 'SELECT ak.adresse FROM `adresse_kontakte` AS `ak`
WHERE ak.kontakt LIKE \''.$emailAddress.'\' ORDER BY ak.id DESC';
$id = $this->db->Select($searchByContactInfo);
return (int) $id;
}
/* Some functions taken from TicketService (sorry...) */
/**
* @param string $ticketNumber
*
* @return void
*/
public function markTicketMessagesCompleted(string $ticketNumber): void
{
$this->setTicketMessagesStatus($ticketNumber, 'abgeschlossen'); // TicketGateway::STATUS_COMPLETED);
}
/**
* @param string $ticketNumber
* @param string $status
*
* @return void
*/
private function setTicketMessagesStatus(string $ticketNumber, string $status): void
{
$sql = "UPDATE `ticket_nachricht` SET `status` = '".$status."' WHERE `ticket` = '".$ticketNumber."';";
$this->db->Update($sql);
}
/**
* @param string $ticketNumber
*
* @throws InvalidArgumentException
*
* @return void
*/
public function resetTicketStatus(string $ticketNumber): void
{
$this->ensureTicketNumberExists($ticketNumber);
$sql = "UPDATE `ticket` SET
`status` = 'neu',
`zugewiesen` = '0',
`inbearbeitung` = '0',
`zeit` = now()
WHERE `schluessel` LIKE '".$ticketNumber."'";
$this->db->Update($sql);
}
/**
* @param string $ticketNumber
*
* @return void
*/
public function updateTicketMessagesCount(string $ticketNumber): void
{
$this->ensureTicketNumberExists($ticketNumber);
$count = $this->getMessageCountByTicketNumber($ticketNumber);
$count++;
$sql = "UPDATE `ticket` SET `nachrichten_anz` = '".$count."' WHERE schluessel = '".$tickerNumber."';";
$this->db->Update($sql);
}
/**
* @param string $ticketNumber
*
* @return void
*/
private function ensureTicketNumberExists(string $ticketNumber): void
{
if ($ticketNumber == '') {
throw new InvalidArgumentException(
sprintf('ticket number empty')
);
}
if (!$this->db->Select('SELECT id FROM ticket WHERE schluessel = '.$ticketNumber)) {
throw new InvalidArgumentException(
sprintf('ticket number "%s" does not exist', $ticketNumber)
);
}
}
/**
* @throws NumberGeneratorException
*
* @return string
*/
private function generateRandomTicketNumber(): string
{
$random = rand(300,700);
$loopCounter = 0;
while(true) {
$candidate = sprintf('%s%04d', date('Ymd'), $random++);
/* if (!$this->gateway->existsTicketNumber($candidate)) {
return $candidate;
}*/
if (!$this->db->Select('SELECT id FROM ticket WHERE schluessel = '.$candidate)) {
return($candidate);
}
if ($loopCounter > 99) {
throw new NumberGeneratorException('ticket number generation failed');
}
$loopCounter++;
}
}
/* Functions from Gateway */
/**
* @param string $ticketNumber
*
* @return int
*/
public function getMessageCountByTicketNumber(string $ticketNumber): int
{
$sql = "SELECT COUNT(tm.id) FROM `ticket_nachricht` AS `tm` WHERE tm.ticket = '".$ticketNumber."';";
$count = $this->db->Select($sql);
if ($count === null) {
return 0;
}
return (int) $count;
}
/**
* @param string $recipientMail
* @param string $senderMail
* @param string $senderName
* @param string $subject
*
* @return array
*/
public function getTicketRules(
string $recipientMail,
string $senderMail,
string $senderName,
string $subject
): array {
/*
$sql = "SELECT
tr.spam AS `is_spam`,
tr.dsgvo AS `is_gdpr_relevant`,
tr.prio AS `priority`,
tr.persoenlich AS `is_private`,
tr.warteschlange AS `queue_id`
FROM `ticket_regeln` AS `tr`
WHERE
tr.aktiv = 1
AND (tr.empfaenger_email LIKE :source_email OR empfaenger_email = '')
AND (
tr.sender_email LIKE :sender_email
OR (tr.sender_email LIKE '@%' AND :sender_email LIKE CONCAT('%', tr.sender_email))
OR tr.sender_email = ''
)
AND (tr.name LIKE :sender_name OR tr.name = '')
AND (tr.betreff LIKE :subject OR tr.betreff = '')";
$values = [
'source_email' => $recipientMail,
'sender_email' => $senderMail,
'sender_name' => $senderName,
'subject' => $subject,
];
return $this->db->fetchAll($sql, $values);
*/
// Legacy DB implementation:
$sql = "SELECT
tr.id,
tr.spam AS `is_spam`,
tr.dsgvo AS `is_gdpr_relevant`,
tr.prio AS `priority`,
tr.persoenlich AS `is_private`,
tr.warteschlange AS `queue_id`
FROM `ticket_regeln` AS `tr`
WHERE
tr.aktiv = 1
AND ('".$recipientMail."' LIKE tr.empfaenger_email OR tr.empfaenger_email = '')
AND ('".$senderMail."' LIKE tr.sender_email OR tr.sender_email = '')
AND ('".$senderMail."' LIKE tr.name OR tr.name = '')
AND ('".$subject."' LIKE tr.betreff OR tr.betreff = '')";
$this->logger->debug('ticket rule',['sql' => $sql]);
$result = $this->db->SelectArr($sql);
if ($result != null) {
$this->logger->debug('ticket rules',['count',count($result)]);
return ($result);
} else {
$this->logger->debug('no ticket rules applicable',['']);
return(array());
}
}
/* END Functions from Gateway */
public function createTicket(
int $projectId,
string $senderName,
string $senderAddress,
string $subject,
int $timestamp,
string $replyToName,
string $replyToAddress
): string
{
$AddressId = $this->tryGetAddressIdByEmailAddress($senderAddress);
$ticketNumber = $this->generateRandomTicketNumber();
if($projectId < 1) {
$projectId = $this->mailAccount->getProjectId();
}
if ($this->mailAccount->isTicketMarkAsFinishedEnabled()) {
$status = 'abgeschlossen'; //TicketGateway::STATUS_COMPLETED;
} else {
$status = 'neu'; //TicketGateway::STATUS_NEW;
}
$queue_id = $this->mailAccount->getTicketQueueId();
if (!empty($queue_id)) {
$queue_label = $this->db->Select("SELECT label FROM warteschlangen WHERE id = ".$queue_id." LIMIT 1");
}
$insertTicket = "INSERT INTO `ticket` (
`schluessel`, `zeit`, `projekt`, `quelle`, `status`, `kunde`,
`mailadresse`, `prio`, `betreff`,`warteschlange`,`adresse`
) VALUES (
'".$ticketNumber."',
'".date('Y-m-d H:i:s', $timestamp)."',
'".$projectId."',
'".$this->mailAccount->getEmailAddress()."',
'".$status."',
'".$senderName."',
'".$senderAddress."',
'".'3'."',
'".$subject."',
'".$queue_label."',
'".$AddressId."');";
$this->db->Insert($insertTicket);
$ticketId = $this->db->GetInsertID();
$this->logger->debug('inserted ticket',['id' => $ticketId,'ticketnr' => $ticketNumber, 'projekt' => $projectId, 'warteschlange' => $this->mailAccount->getTicketQueueId(), 'adresse' => $AddressId]);
// todo als rueckgabe ticketnachricht
return $ticketNumber;
}
public function addTicketMessage(
string $ticketNumber,
int $timestamp,
string $message,
string $subject,
string $senderName,
string $senderAddress,
string $status,
string $replyToName,
string $replyToAddress
): int
{
// $this->db->beginTransaction();
try {
$sql = "INSERT INTO `ticket_nachricht` (
`ticket`, `zeit`, `text`, `betreff`, `medium`,
`verfasser`, `mail`,`status`, `verfasser_replyto`, `mail_replyto`
) VALUES (
'".$ticketNumber."',
'".date('Y-m-d H:i:s', $timestamp)."',
'".$message."',
'".$subject."',
'".'email'."',
'".$senderName."',
'".$senderAddress."',
'".$status."',
'".$replyToName."',
'".$replyToAddress."');";
$this->logger->debug('database insert',['query' => $sql]);
$this->db->Insert($sql);
$messageId = $this->db->GetInsertID();
$this->logger->debug('inserted',['id' => $messageId, 'schluessel' => $ticketNumber]);
$this->updateTicketMessagesCount($ticketNumber);
$this->resetTicketStatus($ticketNumber);
// $this->db->commit();
$result = $messageId;
$this->markTicketMessagesCompleted($ticketNumber);
} catch (Throwable $e) {
// $this->db->rollBack();
$result = 0;
$this->logger->error('Failed to insert ticket message into db', ['exception' => $e]);
}
$this->applyTicketRules($messageId);
return($result);
}
public function applyTicketRules(int $ticketMessageId): void
{
/* $ticketData = $this->gateway->tryGetTicketDataByByMessage($ticketMessageId); */
$ticketData = $this->db->SelectArr("SELECT t.id, tn.mail as sender_email, tn.verfasser as sender_name, tn.betreff as subject, t.quelle as source_email FROM ticket t INNER JOIN ticket_nachricht tn ON tn.ticket = t.schluessel WHERE tn.id = '".$ticketMessageId."'")[0];
if ($ticketData === null) {
throw new InvalidArgumentException('cannot find ticket by message id');
}
$ticketId = $ticketData['id'];
$senderMail = $ticketData['sender_email'];
$senderName = $ticketData['sender_name'];
$subject = $ticketData['subject'];
$source = $ticketData['source_email'];
$this->logger->debug('check ticket rules',['tn_id' => $ticketMessageId, 'sender_email' => $senderMail, 'subject' => $subject]);
//TODO: richtig loggen: $this->app->erp->LogFile("Empfaengermail: $quelle Sendermail: $mailadresse Kunde: $kunde Betreff: $betreff");
$ruleArray = $this->getTicketRules($source, $senderMail, $senderName, $subject);
if (empty($ruleArray)) {
return;
}
foreach ($ruleArray as $rule) {
$this->logger->debug('ticket rule applies',['rule_id' => $rule['id']]);
/*
$update = $this->db->update();
$update->table('ticket');
if ($rule['is_spam'] === 1) {
$update->set('inbearbeitung', 0);
$update->set('zugewiesen', 1);
$this->db->perform(
'UPDATE `ticket_nachricht` SET `status` = :status WHERE `ticket` = :ticket_id',
['status' => TicketGateway::STATUS_SPAM, 'ticket_id' => $ticketId]
);
}
$update->set('dsgvo', $rule['is_gdpr_relevant']);
$update->set('privat', $rule['is_private'] );
$update->set('prio', $rule['priority'] );
$update->where('id = :ticket_id');
$sql = $update->getStatement();
$this->db->perform($sql, ['ticket_id' => $ticketId]);
*/
if ($rule['is_spam'] === 1) {
$sql = "UPDATE `ticket_nachricht` SET `status` = \'spam\' WHERE `id` = '".$ticketMessageId."'";
$this->db->Update($sql);
}
$sql = "UPDATE `ticket` SET `dsgvo` = '".$rule['is_gdpr_relevant']."', `privat` = '".$rule['is_private']."', `prio` = '".$rule['priority']."', `warteschlange` = '".$rule['queue_id']."' WHERE `id` = '".$ticketId."'";
$this->db->Update($sql);
}
}
/* End TicketService */
/** /**
* @param array $inboxMessageIds * @param array $inboxMessageIds
* *
@@ -92,6 +490,9 @@ class TicketImportHelper
continue; continue;
} }
try { try {
$this->logger->debug('Start import', ['message' => $message->getSubject()]);
$this->importMessage($message); $this->importMessage($message);
$insertedMailsCount++; $insertedMailsCount++;
if ($this->mailAccount->isDeleteAfterImportEnabled()) { if ($this->mailAccount->isDeleteAfterImportEnabled()) {
@@ -125,6 +526,7 @@ class TicketImportHelper
// extract email data // extract email data
$subject = $this->formatter->encodeToUtf8($message->getSubject()); $subject = $this->formatter->encodeToUtf8($message->getSubject());
$from = $this->formatter->encodeToUtf8($message->getSender()->getEmail()); $from = $this->formatter->encodeToUtf8($message->getSender()->getEmail());
$fromname = $this->formatter->encodeToUtf8($message->getSender()->getName());
$ccs = $message->getCcRecipients(); $ccs = $message->getCcRecipients();
$cc_recv = []; $cc_recv = [];
foreach ($ccs as $cc) { foreach ($ccs as $cc) {
@@ -146,14 +548,16 @@ class TicketImportHelper
if (strlen($action_html) < strlen($action)) { if (strlen($action_html) < strlen($action)) {
$action_html = nl2br($action); $action_html = nl2br($action);
} }
$name_sender = $this->formatter->encodeToUtf8($message->getSender()->getName());
$mail_replyto = $this->formatter->encodeToUtf8($message->getReplyToAddress());
$verfasser_replyto = $this->formatter->encodeToUtf8($message->getSender()->getName());
//check if email exists in database //check if email exists in database
$date = $message->getDate(); $date = $message->getDate();
$timestamp = $date->getTimestamp(); if (is_null($date)) { // This should not be happening -> Todo check getDate function
$frommd5 = md5($from . $subject . $timestamp); $this->logger->debug('Null date',['subject' => $message->getSubject()]);
$frommd5 = md5($from . $subject);
} else {
$timestamp = $date->getTimestamp();
$frommd5 = md5($from . $subject . $timestamp);
}
$empfang = $date->format('Y-m-d H:i:s'); $empfang = $date->format('Y-m-d H:i:s');
$sql = "SELECT COUNT(id) $sql = "SELECT COUNT(id)
FROM `emailbackup_mails` FROM `emailbackup_mails`
@@ -161,7 +565,13 @@ class TicketImportHelper
AND `empfang`='$empfang' AND `empfang`='$empfang'
AND `webmail`='" . $this->mailAccount->getId() . "'"; AND `webmail`='" . $this->mailAccount->getId() . "'";
$this->logger->debug('Importing message '.$from.' '.$fromname);
if ($this->db->Select($sql) == 0) { if ($this->db->Select($sql) == 0) {
$this->logger->debug('Importing message',['']);
$attachments = $message->getAttachments(); $attachments = $message->getAttachments();
$anhang = count($attachments) > 0 ? 1 : 0; $anhang = count($attachments) > 0 ? 1 : 0;
$mailacc = $this->mailAccount->getEmailAddress(); $mailacc = $this->mailAccount->getEmailAddress();
@@ -201,291 +611,237 @@ class TicketImportHelper
$this->db->InsertWithoutLog($sql); $this->db->InsertWithoutLog($sql);
$id = $this->db->GetInsertID(); $id = $this->db->GetInsertID();
} }
}
if ($DEBUG) {
echo "ticket suchen oder anlegen\n";
}
if ($DEBUG) { $ticketNumber = null;
echo "ticket suchen oder anlegen\n"; $ticketexists = null;
} if (preg_match("/Ticket #[0-9]{12}/i", $subject, $matches)) {
$ticketNumber = str_replace('Ticket #', '', $matches[0]);
$ticketexists = $this->db->Select(
"SELECT schluessel
FROM ticket
WHERE schluessel LIKE '" . $ticketNumber . "'
AND schluessel!='' LIMIT 1"
);
}
$ticketnachricht = null;
$_schluessel = null; if (!$ticketexists) {
$schluessel = null;
$ticketexits = null;
if (preg_match("/Ticket #[0-9]{12}/i", $subject, $matches)) {
$schluessel = str_replace('Ticket #', '', $matches[0]);
$ticketexits = $this->db->Select(
"SELECT schluessel
FROM ticket
WHERE schluessel LIKE '" . $schluessel . "'
AND schluessel!='' LIMIT 1"
);
}
$ticketnachricht = null;
if ($ticketexits) {
if ($DEBUG) {
echo "ticket nummer in betreff gefunden\n";
}
$schluessel = str_replace('Ticket #', '', $matches[0]); $this->logger->debug('New ticket',['']);
if ($action_html != '') { $ticketNumber = $this->createTicket(
$sql = "INSERT INTO `ticket_nachricht` $this->projectId,
( $fromname,
`id`, $from,
`ticket`, $subject,
`zeit`, $timestamp,
`text`, $fromname,
`betreff`, $from
`medium`, );
`verfasser`,
`mail`, } else {
`status`, $this->logger->debug('Add message to existing ticket',['ticketnummer' => $ticketNumber]);
`verfasser_replyto`, }
`mail_replyto`
) VALUES ( // Add message to new or existing ticket
NULL, $ticketnachricht = $this->addTicketMessage(
'$schluessel', (string) $ticketNumber,
FROM_UNIXTIME($timestamp), $timestamp,
'" . $this->db->real_escape_string($action_html) . "', $action_html, //?
'" . $this->db->real_escape_string($subject) . "', $subject,
'email', $fromname,
'" . $this->db->real_escape_string($name_sender) . "', $from,
'" . $this->db->real_escape_string($from) . "', 'neu',
'neu', $fromname,
'" . $this->db->real_escape_string($verfasser_replyto) . "', $from
'" . $this->db->real_escape_string($mail_replyto) . "' );
);";
} else { if ($ticketnachricht > 0 && $id > 0) {
$sql = "INSERT INTO `ticket_nachricht` $this->db->Update(
( "UPDATE `emailbackup_mails`
`id`, SET ticketnachricht='$ticketnachricht'
`ticket`, WHERE id='$id' LIMIT 1"
`zeit`, );
`text`,
`betreff`,
`medium`,
`verfasser`,
`mail`,
`status`,
`verfasser_replyto`,
`mail_replyto`
) VALUES (
NULL,
'$schluessel',
FROM_UNIXTIME($timestamp),
'" . $this->db->real_escape_string($action) . "',
'" . $this->db->real_escape_string($subject) . "',
'email',
'" . $this->db->real_escape_string($name_sender) . "',
'" . $this->db->real_escape_string($from) . "',
'neu',
'" . $this->db->real_escape_string($verfasser_replyto) . "',
'" . $this->db->real_escape_string($mail_replyto) . "'
);";
}
if (!$DEBUG) { // Add all the ccs to the header table
$this->db->InsertWithoutLog( if (is_array($cc_recv)) {
"UPDATE ticket_nachricht foreach ($cc_recv as $mail) {
SET status = 'abgeschlossen' if ($mail['name'] != '') {
WHERE ticket LIKE '$schluessel'" $cc_value =
); $this->db->real_escape_string($mail['name'])
$this->db->InsertWithoutLog($sql); . ' <'
$ticketnachricht = $this->db->GetInsertID(); . $this->db->real_escape_string($mail['email'])
$this->db->InsertWithoutLog( . ">";
"UPDATE ticket
SET status='neu', zugewiesen = 0, inbearbeitung=0
WHERE schluessel LIKE '$schluessel'"
);
$this->db->Update(
"UPDATE `ticket` AS `t`
INNER JOIN (
SELECT COUNT(`id`) AS `co`, `ticket`
FROM `ticket_nachricht`
GROUP BY `ticket`
) AS `tn` ON t.schluessel = tn.ticket
SET t.nachrichten_anz = tn.co
WHERE t.schluessel = '$schluessel'"
);
}
} else {
if (!$DEBUG) {
if ($action_html != '') {
$ticketnachricht = $this->ticketModule->CreateTicket(
$this->projectId,
$mailacc,
$name_sender,
$from,
$subject,
$action_html,
$timestamp,
"email",
null,
$verfasser_replyto,
$mail_replyto
); // ACHTUNG immer Projekt eprooshop
} else { } else {
$ticketnachricht = $this->ticketModule->CreateTicket( $cc_value = $this->db->real_escape_string($mail['email']);
$this->projectId, }
$mailacc, if ($cc_value != '') {
$name_sender, $sql = "INSERT INTO ticket_header
$from, (`id`,`ticket_nachricht`,`type`,`value`)
$subject, VALUES
$action, ('', '$ticketnachricht', 'cc', '" . $cc_value . "')";
$timestamp, $this->db->InsertWithoutLog($sql);
"email",
null,
$verfasser_replyto,
$mail_replyto
); // ACHTUNG immer Projekt eprooshop
} }
$schluessel = $this->db->Select(
"SELECT `ticket`
FROM `ticket_nachricht`
WHERE `id`='$ticketnachricht' LIMIT 1"
);
} else {
echo "Lege neues Ticket an\n";
} }
$cc_recv = [];
} }
if ($ticketnachricht > 0 && $id > 0) { $this->logger->debug('Add recipients to header',['count' => count($message->getRecipients())]);
$this->db->Update(
"UPDATE `emailbackup_mails` // Add all the recipients to the header table
SET ticketnachricht='$ticketnachricht' if (count($message->getRecipients()) > 0) {
WHERE id='$id' LIMIT 1"
); foreach ($message->getRecipients() as $recipient) {
if (is_array($cc_recv)) { $recipient_address = $this->db->real_escape_string($recipient->getEmail());
foreach ($cc_recv as $mail) {
if ($mail['name'] != '') { $this->logger->debug('Add recipient to header',['address' => $recipient_address]);
$cc_value =
$this->db->real_escape_string($mail['name']) if ($recipient_address != '') {
. ' <' $sql = "INSERT INTO ticket_header
. $this->db->real_escape_string($mail['email']) (`id`,`ticket_nachricht`,`type`,`value`)
. ">"; VALUES
} else { ('', '$ticketnachricht', 'to', '" . $recipient_address . "')";
$cc_value = $this->db->real_escape_string($mail['email']); $this->db->InsertWithoutLog($sql);
}
if ($cc_value != '') {
$sql = "INSERT INTO ticket_header
(`id`,`ticket_nachricht`,`type`,`value`)
VALUES
('', '$ticketnachricht', 'cc', '" . $cc_value . "')";
$this->db->InsertWithoutLog($sql);
}
} }
$cc_recv = [];
} }
} }
}
// Prüfen ob Ordner vorhanden ansonsten anlegen
$ordner = $this->config->WFuserdata . '/emailbackup/' . $this->config->WFdbname . "/$id";
if (!is_dir($ordner) && $id > 0) {
if (!mkdir($ordner, 0777, true) && !is_dir($ordner)) {
}
$raw_full_email = $message->getRawContent();
file_put_contents($ordner . '/mail.txt', $raw_full_email);
}
//speichere anhang als datei
if ($anhang == 1 && $id > 0) {
$ordner = $this->config->WFuserdata . '/emailbackup/' . $this->config->WFdbname;
if (!is_dir($ordner)) {
if (!mkdir($ordner, 0777, true) && !is_dir($ordner)) {
$this->logger->error("Folder \"{folder}\" was not created", ['folder' => $ordner]);
}
}
// Prüfen ob Ordner vorhanden ansonsten anlegen // Prüfen ob Ordner vorhanden ansonsten anlegen
$ordner = $this->config->WFuserdata . '/emailbackup/' . $this->config->WFdbname . "/$id"; $ordner = $this->config->WFuserdata . '/emailbackup/' . $this->config->WFdbname . "/$id";
if (!is_dir($ordner) && $id > 0) { if (!is_dir($ordner)) {
if (!mkdir($ordner, 0777, true) && !is_dir($ordner)) { if ($DEBUG) {
} echo "mkdir $ordner\n";
$raw_full_email = $message->getRawContent(); } else {
file_put_contents($ordner . '/mail.txt', $raw_full_email);
}
//speichere anhang als datei
if ($anhang == 1 && $id > 0) {
$ordner = $this->config->WFuserdata . '/emailbackup/' . $this->config->WFdbname;
if (!is_dir($ordner)) {
if (!mkdir($ordner, 0777, true) && !is_dir($ordner)) { if (!mkdir($ordner, 0777, true) && !is_dir($ordner)) {
$this->logger->error("Folder \"{folder}\" was not created", ['folder' => $ordner]); $this->logger->error("Folder \"{folder}\" was not created", ['folder' => $ordner]);
} }
} }
// Prüfen ob Ordner vorhanden ansonsten anlegen }
$ordner = $this->config->WFuserdata . '/emailbackup/' . $this->config->WFdbname . "/$id";
if (!is_dir($ordner)) { $this->logger->debug('Add attachments',['ticketnummer' => $ticketNumber, 'nachricht' => $ticketnachricht, 'count' => count($attachments)]);
foreach ($attachments as $attachment) {
if ($attachment->getFileName() !== '') {
if ($DEBUG) { if ($DEBUG) {
echo "mkdir $ordner\n";
} else { } else {
if (!mkdir($ordner, 0777, true) && !is_dir($ordner)) { $handle = fopen($ordner . '/' . $attachment->getFileName(), 'wb');
$this->logger->error("Folder \"{folder}\" was not created", ['folder' => $ordner]); if ($handle) {
fwrite($handle, $attachment->getContent());
fclose($handle);
} }
} }
} //Schreibe Anhänge in Datei-Tabelle
$datei = $ordner . '/' . $attachment->getFileName();
$dateiname = $attachment->getFileName();
foreach ($attachments as $attachment) { $this->logger->debug("Attachment", ['filename' => $dateiname]);
if ($attachment->getFileName() !== '') {
if ($DEBUG) {
} else {
$handle = fopen($ordner . '/' . $attachment->getFileName(), 'wb');
if ($handle) {
fwrite($handle, $attachment->getContent());
fclose($handle);
}
}
//Schreibe Anhänge in Datei-Tabelle
$datei = $ordner . '/' . $attachment->getFileName();
$dateiname = $attachment->getFileName();
if (stripos($dateiname, '=?utf-8') !== false) {
$dateiname = $this->formatter->encodeToUtf8($dateiname);
$dateiname = htmlspecialchars_decode($dateiname);
}
if (stripos($dateiname, '=?iso-8859') !== false) {
$dateiname = $this->formatter->encodeToUtf8($dateiname);
$dateiname = htmlspecialchars_decode($dateiname);
}
if ($DEBUG) { if (stripos(strtoupper($dateiname), '=?UTF-8') !== false) {
echo "CreateDatei($dateiname,{$dateiname},\"\",\"\",\"datei\",\"Support Mail\",true," $dateiname = $this->formatter->encodeToUtf8($dateiname);
. $this->config->WFuserdata . "/dms/" . $this->config->WFdbname . ")\n"; $dateiname = htmlspecialchars_decode($dateiname);
} else { }
$tmpid = $this->erpApi->CreateDatei( if (stripos(strtoupper($dateiname), '=?ISO-8859') !== false) {
$dateiname, $dateiname = $this->formatter->encodeToUtf8($dateiname);
$dateiname, $dateiname = htmlspecialchars_decode($dateiname);
'', }
'', if (stripos(strtoupper($dateiname), 'UTF-8\'\'') === 0) {
$datei, $dateiname = $this->formatter->encodeToUtf8(urldecode(substr($dateiname,7)));
'Support Mail', $dateiname = htmlspecialchars_decode($dateiname);
true, }
$this->config->WFuserdata . '/dms/' . $this->config->WFdbname
);
}
if ($DEBUG) { $this->logger->debug("Attachment cleaned", ['filename' => $dateiname]);
echo "AddDateiStichwort $tmpid,'Anhang','Ticket',$ticketnachricht,true)\n";
} else { if ($DEBUG) {
$this->erpApi->AddDateiStichwort( echo "CreateDatei($dateiname,{$dateiname},\"\",\"\",\"datei\",\"Support Mail\",true,"
$tmpid, . $this->config->WFuserdata . "/dms/" . $this->config->WFdbname . ")\n";
'Anhang', } else {
'Ticket', $tmpid = $this->erpApi->CreateDatei(
$ticketnachricht, $dateiname,
true $dateiname,
); '',
} '',
$datei,
'Support Mail',
true,
$this->config->WFuserdata . '/dms/' . $this->config->WFdbname
);
}
if ($DEBUG) {
echo "AddDateiStichwort $tmpid,'Anhang','Ticket',$ticketnachricht,true)\n";
} else {
$this->logger->debug('Add attachment',['ticketnummer' => $ticketNumber,'id' => $tmpid, 'nachricht' => $ticketnachricht]);
$this->erpApi->AddDateiStichwort(
$tmpid,
'Anhang',
'Ticket',
$ticketnachricht,
true
);
} }
} }
} }
}
if (
$this->mailAccount->isAutoresponseEnabled()
&& $this->mailAccount->getAutoresponseText() !== ''
&& (
$this->erpApi->AutoresponderBlacklist($from) !== 1
|| $this->mailAccount->isAutoresponseLimitEnabled() === false
)
) {
$text = $this->mailAccount->getAutoresponseText(); $text = $this->mailAccount->getAutoresponseText();
$betreff = $this->mailAccount->getAutoresponseSubject(); $betreff = $this->mailAccount->getAutoresponseSubject();
$text = str_replace('{TICKET}', $schluessel, $text);
if (empty($text)) $text = '';
if (empty($betreff)) $betreff = '';
$text = str_replace('{TICKET}', $ticketNumber, $text);
$text = str_replace('{BETREFF}', $subject, $text); $text = str_replace('{BETREFF}', $subject, $text);
$betreff = str_replace('{TICKET}', $schluessel, $betreff); $betreff = str_replace('{TICKET}', $ticketNumber, $betreff);
$betreff = str_replace('{BETREFF}', $subject, $betreff); $betreff = str_replace('{BETREFF}', $subject, $betreff);
if (
$this->mailAccount->isAutoresponseEnabled() if (!$this->erpApi->isHTML($text)) {
&& $this->mailAccount->getAutoresponseText() !== '' $text = str_replace("\r\n", '<br>', $text);
&& (
$this->erpApi->AutoresponderBlacklist($from) !== 1
|| $this->mailAccount->isAutoresponseLimitEnabled() === false
)
) {
if (!$this->erpApi->isHTML($text)) {
$text = str_replace("\r\n", '<br>', $text);
}
$this->erpApi->MailSend(
$this->mailAccount->getSenderEmailAddress(),
'',
$from,
$name_sender,
$betreff,
$text
);
} }
$this->erpApi->MailSend(
$this->mailAccount->getSenderEmailAddress(),
'',
$from,
$name_sender,
$betreff,
$text
);
} }
} }
} }
+1 -1
View File
@@ -12,7 +12,7 @@
class Config class Config
{ {
/** @var string */ /** @var string */
public $updateHost = 'update.xentral.biz'; public $updateHost = 'removed.upgrade.host';
public function __construct() public function __construct()
{ {
+114
View File
@@ -0,0 +1,114 @@
<?php
/*
include(dirname(__FILE__)."/../conf/main.conf.php");
include(dirname(__FILE__)."/../phpwf/plugins/class.mysql.php");
include(dirname(__FILE__)."/../www/lib/imap.inc.php");
include(dirname(__FILE__)."/../www/lib/class.erpapi.php");
class app_t {
var $DB;
var $user;
}
*/
// ende debug
/*
$debugfile = "/var/www/html/Xenomporio/debug.txt";
function file_append($filename,$text) {
$oldtext = file_get_contents($filename);
file_put_contents($filename,$oldtext.$text);
}
file_put_contents($debugfile,"1");
*/
if(empty($app)){
$app = new app_t();
}
$DEBUG = 0;
if(empty($app->Conf)){
$conf = new Config();
$app->Conf = $conf;
}
if(empty($app->DB) || empty($app->DB->connection)){
$app->DB = new DB($app->Conf->WFdbhost, $app->Conf->WFdbname, $app->Conf->WFdbuser, $app->Conf->WFdbpass, null, $app->Conf->WFdbport);
}
if(empty($app->erp)){
if(class_exists('erpAPICustom')){
$erp = new erpAPICustom($app);
}else{
$erp = new erpAPI($app);
}
$app->erp = $erp;
}
$app->String = new WawiString();
if(class_exists('RemoteCustom'))
{
$app->remote = new RemoteCustom($app);
}else{
$app->remote = new Remote($app);
}
$app->Secure = new Secure($app);
$app->User = new User($app);
if(!defined('FPDF_FONTPATH'))
{
define('FPDF_FONTPATH',dirname(__DIR__) . '/www/lib/pdf/font/');
}
$cronjobname = 'autoversand_manuell';
$mutex = $app->DB->Select(
"SELECT MAX(`mutex`) FROM `prozessstarter` WHERE (`parameter` = '".$cronjobname."')"
);
if($mutex){
$app->DB->Update(
"UPDATE `prozessstarter`
SET `mutexcounter`=`mutexcounter`+1
WHERE `mutex` = 1 AND (`parameter` = '".$cronjobname."')"
);
file_append($debugfile,"MUTEX");
return;
}
$app->DB->Update(
"UPDATE `prozessstarter` SET `mutex`='1', `mutexcounter` = 0 WHERE (`parameter` = '".$cronjobname."')"
);
// START APPLICATION
$objAuftrag = $app->loadModule('auftrag');
if($objAuftrag == null || !method_exists($objAuftrag, 'AuftragVersand')) {
$app->erp->LogFile($cronjobname." failed. Error while loading module 'auftrag'.");
exit;
}
$pendingorders = $app->DB->SelectArr(
"SELECT id
FROM auftrag AS a
WHERE a.id!='' AND (a.belegnr!=0 OR a.belegnr!='')
AND a.status='freigegeben' AND a.cronjobkommissionierung > 0"
);
if (!is_null($pendingorders)) {
$processed_orders_num = 0;
foreach ($pendingorders as $pendingorder) {
/* Process each order */
if($objAuftrag->AuftragVersand($pendingorder['id'],true)) { // Ignore shipdate -> The order has been marked, send it
$processed_orders_num++;
} else {
}
// Limit to 10 per call
if ($processed_orders_num > 10) {
break;
}
}
}
// END APPLICATION
$app->DB->Update("UPDATE prozessstarter SET mutex = 0 , mutexcounter = 0, letzteausfuerhung = now() WHERE (parameter = '".$cronjobname."' ) AND aktiv = 1");
+1 -1
View File
@@ -421,7 +421,7 @@ function GetHtmlMessage($receipientName, $messageTotalCount, $messages = [])
<head> <head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"> <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>[Xenomporio] Ungelesene Chat-Nachrichten</title> <title>[OpenXE] Ungelesene Chat-Nachrichten</title>
<style type="text/css"> <style type="text/css">
body { font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; width: 100%; max-width: 100%; font-size: 17px; line-height: 24px; color: #48494B; background: #F5F5F5; } body { font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; width: 100%; max-width: 100%; font-size: 17px; line-height: 24px; color: #48494B; background: #F5F5F5; }
h1, h2, h3, h4 { color: #42B8C4; margin-bottom: 12px; line-height: 26px; } h1, h2, h3, h4 { color: #42B8C4; margin-bottom: 12px; line-height: 26px; }
-16
View File
@@ -1,16 +0,0 @@
<?php
/* Copyright (c) 2022 Xenomporio project */
/*
Refresh the githash number in githash.txt
*/
$path = '../.git/';
if (!is_dir($path)) {
return;
}
$head = trim(substr(file_get_contents($path . 'HEAD'), 4));
$hash = trim(file_get_contents(sprintf($path . $head)));
if (!empty($hash)) {
file_put_contents("../githash.txt", $hash);
}
?>
+171
View File
@@ -0,0 +1,171 @@
<?php
/*
* Fetch all mails for accounts with ticket function
* Create tickets or sort mails to existing tickets
*/
use Xentral\Components\Logger\Logger;
use Xentral\Components\MailClient\MailClientFactory;
use Xentral\Modules\SystemMailClient\MailClientConfigProvider;
use Xentral\Modules\SystemMailer\Service\EmailAccountGateway;
use Xentral\Modules\Ticket\Importer\TicketFormatter;
use Xentral\Modules\Ticket\Task\TicketImportHelperFactory;
$DEBUG = 0;
/*
$debugfile = "/var/www/html/Xenomporio/debug.txt";
function file_append($filename,$text) {
$oldtext = file_get_contents($filename);
file_put_contents($filename,$oldtext.$text);
}
file_put_contents($debugfile,"0");
*/
/** @var ApplicationCore $app */
$erp = $app->erp;
$conf = $app->Conf;
/** @var Logger $logger */
$logger = $app->Container->get('Logger');
$cronjobname = 'tickets';
/*
$mutex = $app->DB->Select(
"SELECT MAX(`mutex`) FROM `prozessstarter` WHERE (`parameter` = '".$cronjobname."')"
);
if($mutex){
$app->DB->Update(
"UPDATE `prozessstarter`
SET `mutexcounter`=`mutexcounter`+1
WHERE `mutex` = 1 AND (`parameter` = '".$cronjobname."')"
);
return;
}
$app->DB->Update(
"UPDATE `prozessstarter` SET `mutex`='1', `mutexcounter` = 0 WHERE (`parameter` = '".$cronjobname."')"
);
*/
// get all email Accounts that have the ticket system active
/** @var EmailAccountGateway $accountGateway */
$accountGateway = $app->Container->get('EmailAccountGateway');
$accounts = $accountGateway->getAccountsWithTicketActive();
// only load services if there is at least one account to import (performance)
$ticketModule = null;
$factory = null;
$configProvider = null;
$formatHelper = null;
$importHelperFactory = null;
if(!empty($accounts)){
/** @var Ticket $ticketModule */
$ticketModule = $app->erp->LoadModul('ticket');
/** @var MailClientFactory $factory */
$factory = $app->Container->get('MailClientFactory');
/** @var MailClientConfigProvider $configProvider */
$configProvider = $app->Container->get('MailClientConfigProvider');
/** @var TicketFormatter $formatHelper */
$formatHelper = $app->Container->get('TicketFormatter');
/** @var TicketImportHelperFactory $importHelperFactory */
$importHelperFactory = $app->Container->get('TicketImportHelperFactory');
}
$totalEmailsImportCount = 0;
foreach ($accounts as $account) {
$logger->debug(
'Start imap ticket import for {email}',
['email' => $account->getEmailAddress(), 'account' => $account]
);
// create mail client
try {
$mailConfig = $configProvider->createImapConfigFromAccount($account);
$mailClient = $factory->createImapClient($mailConfig);
} catch (Exception $e) {
$logger->error('Failed to create email client', ['error' => (string)$e, 'account' => $account]);
continue;
}
// connect mail client
try {
$mailClient->connect();
} catch (Exception $e) {
$logger->error('Error during imap connection', ['error' => (string)$e, 'account' => $account]);
continue;
}
// connet to INBOX folder
try {
$mailClient->selectFolder('INBOX');
} catch (Exception $e) {
$logger->error('Failed to select INBOX folder', ['error' => (string)$e, 'account' => $account]);
continue;
}
$projectId = $account->getProjectId() > 0 ? $account->getProjectId() : 1;
$delete_msg = 0;
$daysold = $account->getBackupDeleteAfterDays();
// determine search criteria for new messages
$datet = '2012-12-24';
if ($account->getImportStartDateAsString() !== '0000-00-00') {
$datesince = date('d-M-Y', strtotime($account->getImportStartDateAsString()));
$criteria = 'UNSEEN SINCE ' . $datesince;
} else {
$criteria = 'UNSEEN';
}
// search new messages
try {
$searchResult = $mailClient->searchMessages($criteria);
} catch (Exception $e) {
$logger->error('Error during imap search', ['exception' => $e]);
continue;
}
$logger->debug('unread emails to import: {message_count}', ['message_count' => count($searchResult)]);
// set mutex if there is more than 5 emails to import
if (count($searchResult) > 5) {
$app->DB->Update(
"UPDATE `prozessstarter`
SET `mutex`=1, `mutexcounter` = 0, `letzteausfuerhung` = NOW()
WHERE (`parameter` = '".$cronjobname."')"
);
}
$importer = $importHelperFactory->create($mailClient, $account, $projectId);
$insertedMailsCount = $importer->importMessages($searchResult); // TicketImportHelper->importMessages()
$totalEmailsImportCount += $insertedMailsCount;
// set mutex if the total amount of imported emails is more than 10
if ($totalEmailsImportCount > 10) {
$app->DB->Update(
"UPDATE `prozessstarter`
SET `mutex`=1, `mutexcounter` = 0, `letzteausfuerhung` = NOW()
WHERE (`parameter` = '".$cronjobname."')"
);
}
$mailClient->expunge();
$mailClient->disconnect();
if (
method_exists($app->erp, 'canRunCronjob')
&& !$app->erp->canRunCronjob(['supportmails', 'tickets'])
) {
$logger->error('Tickets error');
return;
}
$app->DB->Update(
"UPDATE `prozessstarter`
SET `mutex`=1, `mutexcounter` = 0, `letzteausfuerhung` = NOW()
WHERE (`parameter` = '".$cronjobname."')"
);
}
$app->DB->Update(
"UPDATE `prozessstarter` SET `mutex`=0,`mutexcounter`=0 WHERE (`parameter` = '".$cronjobname."')"
);
+10 -10
View File
@@ -9571,7 +9571,7 @@ CREATE TABLE IF NOT EXISTS `produktion` (
`angebot` varchar(255) NOT NULL, `angebot` varchar(255) NOT NULL,
`freitext` text NOT NULL, `freitext` text NOT NULL,
`internebemerkung` text NOT NULL, `internebemerkung` text NOT NULL,
`status` varchar(64) NOT NULL, `status` varchar(64) NOT NULL default 'angelegt',
`adresse` int(11) NOT NULL, `adresse` int(11) NOT NULL,
`name` varchar(255) NOT NULL, `name` varchar(255) NOT NULL,
`abteilung` varchar(255) NOT NULL, `abteilung` varchar(255) NOT NULL,
@@ -10365,7 +10365,7 @@ CREATE TABLE IF NOT EXISTS `proformarechnung_protokoll` (
CREATE TABLE IF NOT EXISTS `projekt` ( CREATE TABLE IF NOT EXISTS `projekt` (
`id` int(10) NOT NULL AUTO_INCREMENT, `id` int(10) NOT NULL AUTO_INCREMENT,
`name` text NOT NULL, `name` text NOT NULL,
`abkuerzung` text NOT NULL, `abkuerzung` varchar(128) NOT NULL,
`verantwortlicher` text NOT NULL, `verantwortlicher` text NOT NULL,
`beschreibung` text NOT NULL, `beschreibung` text NOT NULL,
`sonstiges` text NOT NULL, `sonstiges` text NOT NULL,
@@ -14355,16 +14355,16 @@ CREATE TABLE IF NOT EXISTS `ticket_nachricht` (
`id` int(11) NOT NULL AUTO_INCREMENT, `id` int(11) NOT NULL AUTO_INCREMENT,
`ticket` varchar(255) NOT NULL, `ticket` varchar(255) NOT NULL,
`verfasser` varchar(255) NOT NULL, `verfasser` varchar(255) NOT NULL,
`bearbeiter` varchar(255) NOT NULL, `bearbeiter` varchar(255) NOT NULL DEFAULT '',
`mail` varchar(255) NOT NULL, `mail` varchar(255) NOT NULL,
`zeit` datetime NOT NULL, `zeit` datetime NOT NULL,
`zeitausgang` datetime NOT NULL, `zeitausgang` datetime NULL,
`text` longtext NOT NULL, `text` longtext NOT NULL,
`textausgang` longtext NOT NULL, `textausgang` longtext NOT NULL DEFAULT '',
`betreff` varchar(255) NOT NULL, `betreff` varchar(255) NOT NULL,
`bemerkung` text NOT NULL, `bemerkung` text NOT NULL DEFAULT '',
`medium` varchar(255) NOT NULL, `medium` varchar(255) NOT NULL,
`versendet` varchar(255) NOT NULL, `versendet` varchar(255) NOT NULL DEFAULT '',
`status` varchar(64) NOT NULL, `status` varchar(64) NOT NULL,
`mail_cc` varchar(128) NOT NULL DEFAULT '', `mail_cc` varchar(128) NOT NULL DEFAULT '',
`verfasser_replyto` varchar(255) NOT NULL, `verfasser_replyto` varchar(255) NOT NULL,
@@ -15208,6 +15208,7 @@ CREATE TABLE IF NOT EXISTS `verbindlichkeit` (
`klaergrund` varchar(255) NOT NULL DEFAULT '', `klaergrund` varchar(255) NOT NULL DEFAULT '',
`skonto_erhalten` decimal(10,2) NOT NULL DEFAULT '0.00', `skonto_erhalten` decimal(10,2) NOT NULL DEFAULT '0.00',
`kurs` decimal(18,8) NOT NULL DEFAULT '0.00000000', `kurs` decimal(18,8) NOT NULL DEFAULT '0.00000000',
`sprache` varchar(25) NOT NULL DEFAULT '',
PRIMARY KEY (`id`), PRIMARY KEY (`id`),
KEY `adresse` (`adresse`), KEY `adresse` (`adresse`),
KEY `bestellung` (`bestellung`) KEY `bestellung` (`bestellung`)
@@ -16797,8 +16798,7 @@ INSERT INTO `prozessstarter` (`id`, `bezeichnung`, `bedingung`, `art`, `startzei
(6, 'Überzahlte Rechnungen', '', 'uhrzeit', '2015-10-25 23:00:00', '0000-00-00 00:00:00', '', 'cronjob', 'ueberzahlterechnungen', 0, 0, 0, 1, ''), (6, 'Überzahlte Rechnungen', '', 'uhrzeit', '2015-10-25 23:00:00', '0000-00-00 00:00:00', '', 'cronjob', 'ueberzahlterechnungen', 0, 0, 0, 1, ''),
(7, 'Umsatzstatistik', '', 'uhrzeit', '2015-10-25 23:30:00', '0000-00-00 00:00:00', '', 'cronjob', 'umsatzstatistik', 0, 0, 0, 1, ''), (7, 'Umsatzstatistik', '', 'uhrzeit', '2015-10-25 23:30:00', '0000-00-00 00:00:00', '', 'cronjob', 'umsatzstatistik', 0, 0, 0, 1, ''),
(8, 'Paketmarken Tracking Download', '', 'uhrzeit', '2015-10-25 14:00:00', '0000-00-00 00:00:00', '', 'cronjob', 'wgettracking', 0, 0, 0, 1, ''), (8, 'Paketmarken Tracking Download', '', 'uhrzeit', '2015-10-25 14:00:00', '0000-00-00 00:00:00', '', 'cronjob', 'wgettracking', 0, 0, 0, 1, ''),
(9, 'Chat-Benachrichtigung', '', 'periodisch', '0000-00-00 00:00:00', '0000-00-00 00:00:00', '60', 'cronjob', 'chat', 0, 0, 0, 1, ''), (9, 'Chat-Benachrichtigung', '', 'periodisch', '0000-00-00 00:00:00', '0000-00-00 00:00:00', '60', 'cronjob', 'chat', 0, 0, 0, 1, '');
(10, 'Git Revision einlesen', '', 'periodisch', '0000-00-00 00:00:00', '0000-00-00 00:00:00', '120', 'cronjob', 'githash', 1, 0, 0, 1, '');
INSERT INTO `user` (`id`, `username`, `password`, `repassword`, `description`, `settings`, `parentuser`, `activ`, `type`, `adresse`, `fehllogins`, `standarddrucker`, `firma`, `logdatei`, `startseite`, `hwtoken`, `hwkey`, `hwcounter`, `motppin`, `motpsecret`, `passwordmd5`, `externlogin`, `projekt_bevorzugen`, `email_bevorzugen`, `projekt`, `rfidtag`, `vorlage`, `kalender_passwort`, `kalender_ausblenden`, `kalender_aktiv`, `gpsstechuhr`, `standardetikett`, `standardfax`, `internebezeichnung`, `hwdatablock`, `standardversanddrucker`, `passwordsha512`, `salt`) VALUES INSERT INTO `user` (`id`, `username`, `password`, `repassword`, `description`, `settings`, `parentuser`, `activ`, `type`, `adresse`, `fehllogins`, `standarddrucker`, `firma`, `logdatei`, `startseite`, `hwtoken`, `hwkey`, `hwcounter`, `motppin`, `motpsecret`, `passwordmd5`, `externlogin`, `projekt_bevorzugen`, `email_bevorzugen`, `projekt`, `rfidtag`, `vorlage`, `kalender_passwort`, `kalender_ausblenden`, `kalender_aktiv`, `gpsstechuhr`, `standardetikett`, `standardfax`, `internebezeichnung`, `hwdatablock`, `standardversanddrucker`, `passwordsha512`, `salt`) VALUES
(1, 'admin', 'qnvEQ1sFWNdIg', 0, 'Administrator', 'firstinstall', 0, 1, 'admin', 1, 0, 0, 1, '2016-08-05 08:34:59', NULL, NULL, NULL, NULL, NULL, NULL, '21232f297a57a5a743894a0e4a801fc3', 1, 0, 1, 0, '', NULL, NULL, 0, NULL, NULL, 0, 0, NULL, NULL, 0, '', ''); (1, 'admin', 'qnvEQ1sFWNdIg', 0, 'Administrator', 'firstinstall', 0, 1, 'admin', 1, 0, 0, 1, '2016-08-05 08:34:59', NULL, NULL, NULL, NULL, NULL, NULL, '21232f297a57a5a743894a0e4a801fc3', 1, 0, 1, 0, '', NULL, NULL, 0, NULL, NULL, 0, 0, NULL, NULL, 0, '', '');
@@ -18167,7 +18167,7 @@ INSERT INTO `wiedervorlage_stages` (`id`, `kurzbezeichnung`, `name`, `hexcolor`,
(12, 'Stay', 'Stay (Erhalt)', '#A2D624', 0, 1, 4, 4, NULL), (12, 'Stay', 'Stay (Erhalt)', '#A2D624', 0, 1, 4, 4, NULL),
(13, 'Okay', 'Okay (Befürwortung)', '#A2D624', 0, 1, 5, 4, NULL); (13, 'Okay', 'Okay (Befürwortung)', '#A2D624', 0, 1, 5, 4, NULL);
INSERT INTO `wiki` (`id`, `name`, `content`, `lastcontent`) VALUES INSERT INTO `wiki` (`id`, `name`, `content`, `lastcontent`) VALUES
(1, 'StartseiteWiki', '\n<p>Herzlich Willkommen in Ihrem Xenomporio, dem freien ERP.<br><br>Wir freuen uns Sie als Benutzer begrüßen zu dürfen. Mit Xenomporio organisieren Sie Ihre Firma schnell und einfach. Sie haben alle wichtigen Zahlen und Vorgänge im Überblick.<br><br>Für Einsteiger sind die folgenden Themen wichtig:<br><br></p>\n<ul>\n<li> <a href="index.php?module=firmendaten&amp;action=edit" target="_blank"> Firmendaten</a> (dort richten Sie Ihr Briefpapier ein)</li>\n<li> <a href="index.php?module=adresse&amp;action=list" target="_blank"> Stammdaten / Adressen</a> (Kunden und Lieferanten anlegen)</li>\n<li> <a href="index.php?module=artikel&amp;action=list" target="_blank"> Artikel anlegen</a> (Ihr Artikelstamm)</li>\n<li> <a href="index.php?module=angebot&amp;action=list" target="_blank"> Angebot</a> / <a href="index.php?module=auftrag&amp;action=list" target="_blank"> Auftrag</a> (Alle Dokumente für Ihr Geschäft)</li>\n<li> <a href="index.php?module=rechnung&amp;action=list" target="_blank"> Rechnung</a> / <a href="index.php?module=gutschrift&amp;action=list" target="_blank"> Gutschrift</a></li>\n<li> <a href="index.php?module=lieferschein&amp;action=list" target="_blank"> Lieferschein</a></li>\n</ul>\n<p><br><br>Kennen Sie unsere Zusatzmodule die Struktur und Organisation in das tägliche Geschäft bringen?<br><br></p>\n<ul>\n<li> <a href="index.php?module=kalender&amp;action=list" target="_blank"> Kalender</a></li>\n<li> <a href="index.php?module=wiki&amp;action=list" target="_blank"> Wiki</a></li>\n</ul>', NULL); (1, 'StartseiteWiki', '\n<p>Herzlich Willkommen in Ihrem OpenXE, dem freien ERP.<br><br>Wir freuen uns Sie als Benutzer begrüßen zu dürfen. Mit OpenXE organisieren Sie Ihre Firma schnell und einfach. Sie haben alle wichtigen Zahlen und Vorgänge im Überblick.<br><br>Für Einsteiger sind die folgenden Themen wichtig:<br><br></p>\n<ul>\n<li> <a href="index.php?module=firmendaten&amp;action=edit" target="_blank"> Firmendaten</a> (dort richten Sie Ihr Briefpapier ein)</li>\n<li> <a href="index.php?module=adresse&amp;action=list" target="_blank"> Stammdaten / Adressen</a> (Kunden und Lieferanten anlegen)</li>\n<li> <a href="index.php?module=artikel&amp;action=list" target="_blank"> Artikel anlegen</a> (Ihr Artikelstamm)</li>\n<li> <a href="index.php?module=angebot&amp;action=list" target="_blank"> Angebot</a> / <a href="index.php?module=auftrag&amp;action=list" target="_blank"> Auftrag</a> (Alle Dokumente für Ihr Geschäft)</li>\n<li> <a href="index.php?module=rechnung&amp;action=list" target="_blank"> Rechnung</a> / <a href="index.php?module=gutschrift&amp;action=list" target="_blank"> Gutschrift</a></li>\n<li> <a href="index.php?module=lieferschein&amp;action=list" target="_blank"> Lieferschein</a></li>\n</ul>\n<p><br><br>Kennen Sie unsere Zusatzmodule die Struktur und Organisation in das tägliche Geschäft bringen?<br><br></p>\n<ul>\n<li> <a href="index.php?module=kalender&amp;action=list" target="_blank"> Kalender</a></li>\n<li> <a href="index.php?module=wiki&amp;action=list" target="_blank"> Wiki</a></li>\n</ul>', NULL);
INSERT INTO `konten` (`id`, `bezeichnung`, `kurzbezeichnung`, `type`, `erstezeile`, `datevkonto`, `blz`, `konto`, `swift`, `iban`, `lastschrift`, `hbci`, `hbcikennung`, `inhaber`, `aktiv`, `keineemail`, `firma`, `schreibbar`, `importletztenzeilenignorieren`, `liveimport`, `liveimport_passwort`, `liveimport_online`, `importtrennzeichen`, `codierung`, `importerstezeilenummer`, `importdatenmaskierung`, `importnullbytes`, `glaeubiger`, `geloescht`, `projekt`, `saldo_summieren`, `saldo_betrag`, `saldo_datum`, `importfelddatum`, `importfelddatumformat`, `importfelddatumformatausgabe`, `importfeldbetrag`, `importfeldbetragformat`, `importfeldbuchungstext`, `importfeldbuchungstextformat`, `importfeldwaehrung`, `importfeldwaehrungformat`, `importfeldhabensollkennung`, `importfeldkennunghaben`, `importfeldkennungsoll`, `importextrahabensoll`, `importfeldhaben`, `importfeldsoll`, `cronjobaktiv`, `cronjobverbuchen`) VALUES INSERT INTO `konten` (`id`, `bezeichnung`, `kurzbezeichnung`, `type`, `erstezeile`, `datevkonto`, `blz`, `konto`, `swift`, `iban`, `lastschrift`, `hbci`, `hbcikennung`, `inhaber`, `aktiv`, `keineemail`, `firma`, `schreibbar`, `importletztenzeilenignorieren`, `liveimport`, `liveimport_passwort`, `liveimport_online`, `importtrennzeichen`, `codierung`, `importerstezeilenummer`, `importdatenmaskierung`, `importnullbytes`, `glaeubiger`, `geloescht`, `projekt`, `saldo_summieren`, `saldo_betrag`, `saldo_datum`, `importfelddatum`, `importfelddatumformat`, `importfelddatumformatausgabe`, `importfeldbetrag`, `importfeldbetragformat`, `importfeldbuchungstext`, `importfeldbuchungstextformat`, `importfeldwaehrung`, `importfeldwaehrungformat`, `importfeldhabensollkennung`, `importfeldkennunghaben`, `importfeldkennungsoll`, `importextrahabensoll`, `importfeldhaben`, `importfeldsoll`, `cronjobaktiv`, `cronjobverbuchen`) VALUES
Binary file not shown.

After

Width:  |  Height:  |  Size: 80 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 52 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 49 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 48 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 116 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 71 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 74 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 147 KiB

+1
View File
@@ -0,0 +1 @@
+1315 -1198
View File
File diff suppressed because it is too large Load Diff
-726
View File
@@ -1,726 +0,0 @@
<?php
/*
**** COPYRIGHT & LICENSE NOTICE *** DO NOT REMOVE ****
*
* Xentral (c) Xentral ERP Sorftware GmbH, Fuggerstrasse 11, D-86150 Augsburg, * Germany 2019
*
* This file is licensed under the Embedded Projects General Public License *Version 3.1.
*
* You should have received a copy of this license from your vendor and/or *along with this file; If not, please visit www.wawision.de/Lizenzhinweis
* to obtain the text of the corresponding license version.
*
**** END OF COPYRIGHT & LICENSE NOTICE *** DO NOT REMOVE ****
*/
?>
<?php
final class DatabaseUpgrade
{
/** @var Application $app */
private $app;
/** @var array $CheckColumnTableCache */
private $CheckColumnTableCache;
/** @var bool $check_column_missing_run */
private $check_column_missing_run=false;
/** @var array $check_column_missing */
private $check_column_missing=array();
/** @var array $check_index_missing */
private $check_index_missing=array();
/** @var array */
private $allTables = [];
/** @var array */
private $indexe = [];
/**
* @param Application $app
*/
public function __construct($app)
{
$this->app = $app;
}
public function emptyTableCache(){
$this->CheckColumnTableCache = [];
$this->allTables = [];
$this->indexe = [];
}
/**
* @var bool $force
*
* @return array
*/
public function getAllTables($force = false)
{
if($force || empty($this->allTables)) {
$this->allTables = $this->app->DB->SelectFirstCols('SHOW TABLES');
}
return $this->allTables;
}
/**
* @param string $table
* @param string $pk
*/
public function createTable($table, $pk = 'id')
{
$sql = "CREATE TABLE `$table` (`".$pk."` INT NOT NULL AUTO_INCREMENT, PRIMARY KEY (`".$pk."`)) ENGINE = InnoDB DEFAULT CHARSET=utf8";
$this->app->DB->Query($sql);
$this->addPrimary($table, $pk);
}
/**
* @param string $table
* @param string $pk
*/
public function addPrimary($table, $pk = 'id')
{
$this->CheckAlterTable(
"ALTER TABLE `$table`
ADD PRIMARY KEY (`".$pk."`)",
true
);
$this->CheckAlterTable(
"ALTER TABLE `$table`
MODIFY `".$pk."` int(11) NOT NULL AUTO_INCREMENT,AUTO_INCREMENT=1",
true
);
}
/**
* @param string $table
* @param bool $force
*
* @return array
*/
public function getIndexeCached($table, $force = false)
{
if($force || !isset($this->indexe[$table])){
$this->indexe[$table] = $this->app->DB->SelectArr(sprintf('SHOW INDEX FROM `%s`', $table));
if($this->indexe[$table] === null) {
$this->indexe[$table] = [];
}
}
return $this->indexe[$table];
}
/**
* @param string $table
*/
public function clearIndexCached($table)
{
if(!isset($this->indexe[$table])) {
return;
}
unset($this->indexe[$table]);
}
/**
* @param string $table
* @param string $pk
*/
public function hasPrimaryKey($table, $pk = 'id')
{
$indexe = $this->getIndexeCached($table);
if(empty($indexe)) {
return false;
}
foreach($indexe as $index) {
if($index['Column_name'] === $pk
&& $index['Key_name'] === 'PRIMARY'
&& (int)$index['Non_unique'] === 0
) {
return true;
}
}
return false;
}
/**
* @param string $table
* @param string $pk
*
* @return void
*/
function CheckTable($table, $pk = 'id')
{
if($pk === 'id') {
$tables = $this->getAllTables();
if(!empty($tables)){
if(!in_array($table, $tables)){
$this->createTable($table, $pk);
return;
}
if(!$this->hasPrimaryKey($table, $pk)) {
$this->addPrimary($table, $pk);
}
return;
}
}
$found = false;
$tables = $this->getAllTables(true);
if($tables) {
$found = in_array($table, $tables);
}
else{
$check = $this->app->DB->Select("SELECT $pk FROM `$table` LIMIT 1");
if($check) {
$found = true;
}
}
if($found==false)
{
$sql = "CREATE TABLE `$table` (`".$pk."` INT NOT NULL AUTO_INCREMENT, PRIMARY KEY (`".$pk."`)) ENGINE = InnoDB DEFAULT CHARSET=utf8";
$this->app->DB->Update($sql);
$this->CheckAlterTable("ALTER TABLE `$table`
ADD PRIMARY KEY (`".$pk."`)");
$this->CheckAlterTable("ALTER TABLE `$table`
MODIFY `".$pk."` int(11) NOT NULL AUTO_INCREMENT,AUTO_INCREMENT=1");
}
if($pk !== 'id') {
$this->CheckColumn('created_at','timestamp',$table,"DEFAULT CURRENT_TIMESTAMP NOT NULL");
}
}
/**
* @param string $column
* @param string $type
* @param string $table
* @param string $default
*
* @return void
*/
function UpdateColumn($column,$type,$table,$default="NOT NULL")
{
$fields = $this->app->DB->SelectArr("show columns from `".$table."`");
if($fields)
{
foreach($fields as $val)
{
$field_array[] = $val['Field'];
}
}
if (in_array($column, $field_array))
{
$this->app->DB->Query('ALTER TABLE `'.$table.'` CHANGE `'.$column.'` `'.$column.'` '.$type.' '.$default.';');
}
}
/**
* @param string $column
* @param string $table
*
* @return void
*/
public function DeleteColumn($column,$table)
{
$this->app->DB->Query('ALTER TABLE `'.$table.'` DROP `'.$column.'`;');
}
/**
* @param string $column
* @param string $type
* @param string $table
* @param string $default
*
* @return void
*/
public function CheckColumn($column,$type,$table,$default="")
{
if($table === 'firmendaten')
{
if($this->app->DB->Select("SELECT `id` FROM `firmendaten_werte` WHERE `name` = '$column' LIMIT 1"))return;
}
if(!isset($this->CheckColumnTableCache[$table]))
{
$tmp=$this->app->DB->SelectArr("show columns from `".$table."`");
if($tmp)
{
foreach($tmp as $val)
{
$this->CheckColumnTableCache[$table][] = $val['Field'];
//$types[$val['Field']] = strtolower($val['Type']);
}
}
}
if (isset($this->CheckColumnTableCache[$table]) && !in_array($column, $this->CheckColumnTableCache[$table]))
{
if($this->check_column_missing_run)
{
//$result = mysqli_query($this->app->DB->connection,'ALTER TABLE `'.$table.'` ADD `'.$column.'` '.$type.' '.$default.';');
$this->check_column_missing[$table][]=$column;
} else {
$result = $this->app->DB->Query('ALTER TABLE `'.$table.'` ADD `'.$column.'` '.$type.' '.$default.';');
if($table === 'firmendaten' && $this->app->DB->error())
{
if((method_exists($this->app->DB, 'errno2') && $this->app->DB->errno() == '1118')
|| strpos($this->app->DB->error(),'Row size too large') !== false
)
{
$this->ChangeFirmendatenToMyIsam();
$this->app->DB->Query('ALTER TABLE `'.$table.'` ADD `'.$column.'` '.$type.' '.$default.';');
}
}
}
}
}
/**
* @param array $indexe
*
* @return array
*/
protected function getGroupedIndexe($indexe)
{
if(empty($indexe)) {
return $indexe;
}
$return = [];
foreach($indexe as $index) {
$keyName = $index['Key_name'];
$isUnique = $index['Non_unique'] == '0';
$seq = $index['Seq_in_index'];
$columnName = $index['Column_name'];
$return[$isUnique?'unique':'index'][$keyName][(int)$seq - 1] = $columnName;
}
return $return;
}
/**
* @param array $indexe
*
* @return array
*/
protected function getDoubleIndexeFromGroupedIndexe($indexe)
{
if(empty($indexe)) {
return [];
}
$ret = [];
foreach($indexe as $type => $indexArrs) {
$columnStrings = [];
foreach($indexArrs as $indexKey => $columns) {
$columnString = implode('|', $columns);
if(in_array($columnString, $columnStrings)) {
$ret[$type][] = $indexKey;
continue;
}
$columnStrings[] = $columnString;
}
}
return $ret;
}
/**
* @param string $table
* @param array $indexe
* @param bool $noCache
*
* @return array|null
*/
public function CheckDoubleIndex($table, $indexe, $noCache = false)
{
$query = $noCache?null:$this->CheckAlterTable("SHOW INDEX FROM `$table`");
if(!$query) {
$indexeGrouped = $this->getGroupedIndexe($indexe);
$doubleIndexe = $this->getDoubleIndexeFromGroupedIndexe($indexeGrouped);
if(!empty($doubleIndexe)) {
$indexe = $this->getIndexeCached($table, true);
$indexeGrouped = $this->getGroupedIndexe($indexe);
$doubleIndexe = $this->getDoubleIndexeFromGroupedIndexe($indexeGrouped);
if(empty($doubleIndexe)) {
return $indexe;
}
foreach($doubleIndexe as $type => $doubleIndex) {
foreach($doubleIndex as $indexName) {
$this->app->DB->Query("ALTER TABLE `".$table."` DROP INDEX `".$indexName."`");
}
}
}
elseif($noCache) {
return $indexe;
}
$this->CheckAlterTable("SHOW INDEX FROM `$table`", true);
return $this->getIndexeCached($table, true);
}
if(empty($indexe) || count($indexe) == 1){
return $indexe;
}
$uniquearr = array();
$indexarr = array();
foreach($indexe as $index)
{
if($index['Key_name'] !== 'PRIMARY' && !empty($index['Column_name']))
{
if($index['Non_unique'])
{
$indexarr[$index['Key_name']][] = $index['Column_name'];
}else{
$uniquearr[$index['Key_name']][] = $index['Column_name'];
}
}
}
$cindex = count($indexarr);
$cuniqe = count($uniquearr);
$changed = false;
if($cindex > 1)
{
$check = array();
foreach($indexarr as $key => $value)
{
if(empty($value))
{
continue;
}
if(count($value) > 1){
sort($value);
}
$vstr = implode(',', $value);
if(in_array($vstr, $check))
{
$this->app->DB->Query("DROP INDEX `".$key."` ON `".$table."`");
$changed = true;
}else{
$check[] = $vstr;
}
}
}
if($cuniqe > 1)
{
$check = array();
foreach($uniquearr as $key => $value)
{
if(empty($value))
{
continue;
}
if(count($value) > 1){
sort($value);
}
$vstr = implode(',', $value);
if(in_array($vstr, $check))
{
$this->app->DB->Query("DROP UNIQUE `".$key."` ON `".$table."`");
$changed = true;
}else{
$check[] = $vstr;
}
}
}
if($changed) {
return $this->getIndexeCached($table, true);
}
return $indexe;
}
/**
* @param string $table
* @param string|array $column
*
* @return bool
*/
public function CheckFulltextIndex($table,$column)
{
if(empty($table) || empty($column))
{
return false;
}
if(!is_array($column))
{
$column = [$column];
}
$columnmasked = [];
foreach($column as $keyColumn => $valueColumn)
{
if(!empty($valueColumn))
{
$columnmasked[] = "`$valueColumn`";
}else{
unset($column[$keyColumn]);
}
}
if(empty($column))
{
return false;
}
$columnsFound = [];
$indexe = $this->getIndexeCached($table, true);
$indexeFound = [];
if(!empty($indexe))
{
foreach($indexe as $index)
{
if($index['Index_type'] === 'FULLTEXT')
{
$indexeFound[] = $index['Column_name'];
if(!in_array($index['Column_name'], $columnsFound))
{
$columnsFound[] = $index['Column_name'];
}
}
}
$cindexeFound = count($indexeFound);
$column = count($column);
if(($column === $cindexeFound) && (count($columnsFound) === $column))
{
return true;
}
if($cindexeFound > 0)
{
return false;
}
}
$this->app->DB->Query(
"ALTER TABLE `$table`
ADD FULLTEXT INDEX `FullText`
(".implode(',',$columnmasked).");"
);
$error = $this->app->DB->error();
return empty($error);
}
/**
* @param string $table
* @param string $column
* @param bool $unique
*
* @return void
*/
function CheckIndex($table, $column, $unique = false)
{
$indexex = null;
$indexexother = null;
$indexe = $this->getIndexeCached($table);
if($indexe)
{
$indexe = $this->CheckDoubleIndex($table, $indexe, true);
foreach($indexe as $index)
{
if(is_array($column) && $index['Key_name'] !== 'PRIMARY')
{
if($unique && !$index['Non_unique'])
{
if(in_array($index['Column_name'], $column))
{
$indexex[$index['Key_name']][$index['Column_name']] = true;
}else{
$indexexother[$index['Key_name']][$index['Column_name']] = true;
}
}
elseif(!$unique){
if(in_array($index['Column_name'], $column)) {
$indexex[$index['Key_name']][$index['Column_name']] = true;
}
}
}
elseif(!is_array($column)){
if($index['Column_name'] == $column)
{
return;
}
}
}
if($this->check_column_missing_run)
{
$this->check_index_missing[$table][] = $column;
}
if(!$unique)
{
if(is_array($column))
{
if($indexex)
{
foreach($indexex as $k => $v) {
if(count($v) === 1 && count($column) > 1) {
$this->app->DB->Query("DROP INDEX `".$k."` ON `".$table."`");
$this->clearIndexCached($table);
unset($indexex[$k]);
}
}
foreach($indexex as $k => $v)
{
if(count($v) == count($column)){
return;
}
}
foreach($indexex as $k => $v)
{
if(!isset($indexexother[$k]))
{
$this->app->DB->Query("DROP INDEX `".$k."` ON `".$table."`");
$cols = null;
foreach($column as $c) {
$cols[] = "`$c`";
}
$this->CheckAlterTable("ALTER TABLE `$table` ADD INDEX(".implode(', ',$cols)."); ",true);
$this->clearIndexCached($table);
return;
}
}
}
$cols = null;
foreach($column as $c) {
$cols[] = "`$c`";
}
$this->CheckAlterTable("ALTER TABLE `$table` ADD INDEX(".implode(', ',$cols)."); ", true);
$this->clearIndexCached($table);
}
else{
$this->CheckAlterTable("ALTER TABLE `$table` ADD INDEX(`$column`); ", true);
$this->clearIndexCached($table);
}
}
else{
if(is_array($column))
{
if($indexex)
{
foreach($indexex as $k => $v)
{
if(count($v) == count($column))
{
return;
}
}
foreach($indexex as $k => $v)
{
if(!isset($indexexother[$k]))
{
$this->app->DB->Query("DROP INDEX `".$k."` ON `".$table."`");
$cols = null;
foreach($column as $c) {
$cols[] = "`$c`";
}
$this->CheckAlterTable("ALTER TABLE `$table` ADD UNIQUE(".implode(', ',$cols)."); ", true);
$this->clearIndexCached($table);
return;
}
}
}
$cols = null;
foreach($column as $c) {
$cols[] = "`$c`";
}
$this->CheckAlterTable("ALTER TABLE `$table` ADD UNIQUE(".implode(', ',$cols)."); ", true);
$this->clearIndexCached($table);
}else{
$this->CheckAlterTable("ALTER TABLE `$table` ADD UNIQUE(`$column`); ", true);
$this->clearIndexCached($table);
}
}
}
elseif(!is_array($column))
{
if(!$unique)
{
$this->CheckAlterTable("ALTER TABLE `$table` ADD INDEX(`$column`); ");
}else{
$this->CheckAlterTable("ALTER TABLE `$table` ADD UNIQUE(`$column`); ");
}
$this->clearIndexCached($table);
}
elseif(is_array($column))
{
$cols = null;
foreach($column as $c) {
$cols[] = "`$c`";
}
$this->CheckAlterTable("ALTER TABLE `$table` ADD UNIQUE(".implode(', ',$cols)."); ");
$this->clearIndexCached($table);
}
}
/**
* @param string $sql
* @param bool $force
*
* @return mysqli_result|bool
*/
function CheckAlterTable($sql, $force = false)
{
$sqlmd5 = md5($sql);
$check = $this->app->DB->Select("SELECT id FROM checkaltertable WHERE checksum='$sqlmd5' LIMIT 1");
if($check > 0 && !$force) return;
$query = $this->app->DB->Query($sql);
if($query && empty($check) && !$this->app->DB->error()){
$this->app->DB->Insert("INSERT INTO checkaltertable (id,checksum) VALUES ('','$sqlmd5')");
}
return $query;
}
/**
* @return void
*/
public function ChangeFirmendatenToMyIsam()
{
$this->app->DB->Query("ALTER TABLE firmendaten ENGINE = MyISAM;");
}
/**
* @param string $table
*
* @return array
*/
public function getSortedIndexColumnsByIndexName($table): array
{
$indexesByName = [];
$indexes = $this->app->DB->SelectArr(sprintf('SHOW INDEX FROM `%s`', $table));
if(empty($indexes)) {
return $indexesByName;
}
foreach($indexes as $index) {
$indexesByName[$index['Key_name']][] = $index['Column_name'];
}
foreach($indexesByName as $indexName => $columns) {
$columns = array_unique($columns);
sort($columns);
$indexesByName[$indexName] = $columns;
}
return $indexesByName;
}
/**
* @deprecated will be removed in 21.4
*
* @param string $table
* @param array $columns
*/
public function dropIndex($table, $columns): void
{
if(empty($table) || empty($columns)) {
return;
}
$columns = array_unique($columns);
sort($columns);
$countColumns = count($columns);
$indexes = $this->getSortedIndexColumnsByIndexName($table);
if(empty($indexes)) {
return;
}
foreach($indexes as $indexName => $indexColumns) {
if(count($indexColumns) !== $countColumns) {
continue;
}
if(count(array_intersect($indexColumns, $columns)) === $countColumns) {
$this->app->DB->Query(sprintf('ALTER TABLE `%s` DROP INDEX `%s`', $table, $indexName));
}
}
}
}
+144 -48
View File
@@ -3552,6 +3552,67 @@ class YUI {
'</td></tr></table>')"; '</td></tr></table>')";
} }
function IconsSQL_produktion($tablename) {
$freigegeben = "<img src=\"./themes/{$this->app->Conf->WFconf['defaulttheme']}/images/produkton_laeuft.png\" title=\"Produktion freigegeben\" border=\"0\" style=\"margin-right:1px\">";
$angelegt = "<img src=\"./themes/{$this->app->Conf->WFconf['defaulttheme']}/images/blue.png\" title=\"Produktion angelegt\" border=\"0\" style=\"margin-right:1px\">";
$abgeschlossen = "<img src=\"./themes/{$this->app->Conf->WFconf['defaulttheme']}/images/grey.png\" title=\"Produktion abgeschlossen\" border=\"0\" style=\"margin-right:1px\">";
$gestartet = "<img src=\"./themes/{$this->app->Conf->WFconf['defaulttheme']}/images/produkton_green.png\" title=\"Produktion gestartet\" border=\"0\" style=\"margin-right:1px\">";
$storniert = "<img src=\"./themes/{$this->app->Conf->WFconf['defaulttheme']}/images/storno.png\" title=\"Produktion storniert\" border=\"0\" style=\"margin-right:1px\">";
for ($z = 0;$z < 6;$z++) {
$angelegt_6 .= $angelegt;
$abgeschlossen_6 .= $abgeschlossen;
$storniert_6 .= $storniert;
}
$lager_ok = "<img src=\"./themes/{$this->app->Conf->WFconf['defaulttheme']}/images/lagergo.png\" style=\"margin-right:1px\" title=\"Artikel ist im Lager\" border=\"0\">";
$lager_nicht_ok = "<img src=\"./themes/{$this->app->Conf->WFconf['defaulttheme']}/images/lagerstop.png\" style=\"margin-right:1px\" title=\"Artikel fehlt im Lager\" border=\"0\">";
$reserviert_ok = "<img src=\"./themes/{$this->app->Conf->WFconf['defaulttheme']}/images/ware_bestellt.png\" style=\"margin-right:1px\" title=\"Artikel reserviert\" border=\"0\">";
$reserviert_nicht_ok = "<img src=\"./themes/{$this->app->Conf->WFconf['defaulttheme']}/images/ware_nicht_bestellt.png\" style=\"margin-right:1px\" title=\"Artikel nicht reserviert\" border=\"0\">";
$auslagern_ok = "<img src=\"./themes/{$this->app->Conf->WFconf['defaulttheme']}/images/ausgelagert.png\" title=\"Produktion ausgelagert\" border=\"0\" style=\"margin-right:1px\">";
$auslagern_nicht_ok = "<img src=\"./themes/{$this->app->Conf->WFconf['defaulttheme']}/images/nicht_ausgelagert.png\" title=\"Produktion ausgelagert\" border=\"0\" style=\"margin-right:1px\">";
$einlagern_ok = "<img src=\"./themes/{$this->app->Conf->WFconf['defaulttheme']}/images/eingelagert.png\" title=\"Produktion eingelagert\" border=\"0\" style=\"margin-right:1px\">";
$einlagern_nicht_ok = "<img src=\"./themes/{$this->app->Conf->WFconf['defaulttheme']}/images/nicht_eingelagert.png\" title=\"Produktion eingelagert\" border=\"0\" style=\"margin-right:1px\">";
$zeit_ok = "<img src=\"./themes/{$this->app->Conf->WFconf['defaulttheme']}/images/zeit_dreiviertel.png\" style=\"margin-right:1px\" title=\"Zeiten erfasst\" border=\"0\">";
$zeit_nicht_ok = "<img src=\"./themes/{$this->app->Conf->WFconf['defaulttheme']}/images/keine_zeiten.png\" style=\"margin-right:1px\" title=\"Zeiten nicht erfasst\" border=\"0\">";
$versand_ok = "<img src=\"./themes/{$this->app->Conf->WFconf['defaulttheme']}/images/liefersperrego.png\" style=\"margin-right:1px\" title=\"Versand ok\" border=\"0\">";
$versand_nicht_ok = "<img src=\"./themes/{$this->app->Conf->WFconf['defaulttheme']}/images/liefersperrestop.png\" style=\"margin-right:1px\" title=\"Versand nicht ok\" border=\"0\">";
return "CONCAT('<table><tr><td nowrap>',
CASE
WHEN $tablename.status = 'freigegeben' THEN '$freigegeben'
WHEN $tablename.status = 'abgeschlossen' THEN '$abgeschlossen'
WHEN $tablename.status = 'angelegt' THEN '$angelegt'
WHEN $tablename.status = 'gestartet' THEN '$gestartet'
ELSE
'$storniert'
end,
CASE
WHEN FIND_IN_SET($tablename.status, 'freigegeben,gestartet') THEN
CONCAT (
if($tablename.lager_ok,'$lager_ok','$lager_nicht_ok'),
if($tablename.reserviert_ok,'$reserviert_ok','$reserviert_nicht_ok'),
if($tablename.auslagern_ok,'$auslagern_ok','$auslagern_nicht_ok'),
if($tablename.einlagern_ok,'$einlagern_ok','$einlagern_nicht_ok'),
if($tablename.zeit_ok,'$zeit_ok','$zeit_nicht_ok'),
if($tablename.versand_ok,'$versand_ok','$versand_nicht_ok')
)
ELSE
CASE
WHEN $tablename.status = 'angelegt' THEN '$angelegt_6'
WHEN $tablename.status = 'abgeschlossen' THEN '$abgeschlossen_6'
ELSE
'$storniert_6'
END
END,
'</td></tr></table>')";
}
function TablePositionSearch($parsetarget, $name, $callback = "show", $gener) { function TablePositionSearch($parsetarget, $name, $callback = "show", $gener) {
$id = $this->app->Secure->GetGET("id"); $id = $this->app->Secure->GetGET("id");
@@ -9459,64 +9520,90 @@ a.land as land, p.abkuerzung as projekt, a.zahlungsweise as zahlungsweise,
'; ';
if($this->app->erp->RechteVorhanden('wiedervorlage','list')){ if($this->app->erp->RechteVorhanden('wiedervorlage','list')){
if($this->app->erp->GetKonfiguration('adresse_crm_collateerror') && method_exists($this,'ConvertLatin1UTF')) if($this->app->erp->GetKonfiguration('adresse_crm_collateerror') && method_exists($this,'ConvertLatin1UTF'))
{ {
$sql .= ' $sql .= '
UNION ALL UNION ALL
( (
SELECT SELECT
w.id,"<img src=./themes/' . $this->app->Conf->WFconf['defaulttheme'] . '/images/details_open.png class=details>" as open, w.id,"<img src=./themes/' . $this->app->Conf->WFconf['defaulttheme'] . '/images/details_open.png class=details>" as open,
CONCAT(DATE_FORMAT(datum_erinnerung, "%Y-%m-%d"), " ", IF(zeit_erinnerung IS NULL OR DATE_FORMAT(zeit_erinnerung, "%H:%i")="00:00", "", DATE_FORMAT(zeit_erinnerung, "%H:%i")) ) as datum, CONCAT(DATE_FORMAT(datum_erinnerung, "%Y-%m-%d"), " ", IF(zeit_erinnerung IS NULL OR DATE_FORMAT(zeit_erinnerung, "%H:%i")="00:00", "", DATE_FORMAT(zeit_erinnerung, "%H:%i")) ) as datum,
'. $this->ConvertLatin1UTF('w.bezeichnung').' as title,\'\' as ansprechpartner, '. $this->ConvertLatin1UTF('w.bezeichnung').' as title,\'\' as ansprechpartner,
'. $this->ConvertLatin1UTF('p.abkuerzung').' as abkuerzung, '. $this->ConvertLatin1UTF('p.abkuerzung').' as abkuerzung,
adr.name COLLATE utf8_general_ci as bearbeiter, adr.name COLLATE utf8_general_ci as bearbeiter,
CONCAT("Wiedervorlage") as art, CONCAT("Wiedervorlage") as art,
CONCAT("<a data-type=wiedervorlage data-id=", w.id, "></a>") as gesendet, CONCAT("<a data-type=wiedervorlage data-id=", w.id, "></a>") as gesendet,
"" as pdf, "" as pdf,
concat("5","-",w.id) as did,'. $this->ConvertLatin1UTF('w.beschreibung').' as suchtext,\'\' as internebezeichnung concat("5","-",w.id) as did,'. $this->ConvertLatin1UTF('w.beschreibung').' as suchtext,\'\' as internebezeichnung
FROM FROM
wiedervorlage w left join adresse adr on w.bearbeiter = adr.id wiedervorlage w left join adresse adr on w.bearbeiter = adr.id
LEFT JOIN projekt p ON p.id=w.projekt LEFT JOIN projekt p ON p.id=w.projekt
WHERE WHERE
w.adresse = ' . $adresseId . ' w.adresse = ' . $adresseId . '
)'; )';
}else{ } else {
$sql .= ' $sql .= '
UNION ALL UNION ALL
( (
SELECT SELECT
w.id,"<img src=./themes/' . $this->app->Conf->WFconf['defaulttheme'] . '/images/details_open.png class=details>" as open, w.id,
CONCAT(DATE_FORMAT(datum_erinnerung, "%Y-%m-%d"), " ", IF(zeit_erinnerung IS NULL OR DATE_FORMAT(zeit_erinnerung, "%H:%i")="00:00", "", DATE_FORMAT(zeit_erinnerung, "%H:%i")) ) as datum, "<img src=./themes/' . $this->app->Conf->WFconf['defaulttheme'] . '/images/details_open.png class=details>" as open,
w.bezeichnung COLLATE utf8_general_ci as title,\'\' as ansprechpartner, CONCAT(DATE_FORMAT(datum_erinnerung, "%Y-%m-%d"), " ", IF(zeit_erinnerung IS NULL OR DATE_FORMAT(zeit_erinnerung, "%H:%i")="00:00", "", DATE_FORMAT(zeit_erinnerung, "%H:%i")) ) as datum,
p.abkuerzung COLLATE utf8_general_ci as abkuerzung, w.bezeichnung COLLATE utf8_general_ci as title,
adr.name COLLATE utf8_general_ci as bearbeiter, \'\' as ansprechpartner,
CONCAT("Wiedervorlage") as art, p.abkuerzung COLLATE utf8_general_ci as abkuerzung,
CONCAT("<a data-type=wiedervorlage data-id=", w.id, "></a>") as gesendet, adr.name COLLATE utf8_general_ci as bearbeiter,
"" as pdf, CONCAT("Wiedervorlage") as art,
concat("5","-",w.id) as did,w.beschreibung COLLATE utf8_general_ci as suchtext,\'\' as internebezeichnung CONCAT("<a data-type=wiedervorlage data-id=", w.id, "></a>") as gesendet,
FROM "" as pdf,
wiedervorlage w left join adresse adr on w.bearbeiter = adr.id concat("5","-",w.id) as did,
LEFT JOIN projekt p ON p.id=w.projekt w.beschreibung COLLATE utf8_general_ci as suchtext,
WHERE \'\' as internebezeichnung
w.adresse = ' . $adresseId . ' FROM
)'; wiedervorlage w left join adresse adr on w.bearbeiter = adr.id
LEFT JOIN projekt p ON p.id=w.projekt
WHERE
w.adresse = ' . $adresseId . '
)';
} }
} } // RechteVorhanden wiedervorlage
$sql .='
) a
';
$sql .= 'UNION ALL
(
SELECT
t.id,
"<img src=./themes/' . $this->app->Conf->WFconf['defaulttheme'] . '/images/details_open.png class=details>" as open,
tn.zeit,
tn.betreff,
ifnull((SELECT name FROM ansprechpartner ap WHERE ap.adresse = a.id AND ap.email = tn.mail LIMIT 1),tn.mail) as ansprechpartner,
p.abkuerzung,
tn.verfasser,
\'Ticketnachricht\' as art,
CONCAT(IF(tn.versendet = 1, "JA", "NEIN"),"<a data-type=ticket_nachricht data-id=", t.id, "></a>") as gesendet,
\'\' as PDF,
concat("4","-",tn.id) as did,
CONCAT(tn.text,t.notiz) as suchtext,
\'\' as intern
FROM
ticket_nachricht tn
INNER JOIN ticket t ON
tn.ticket = t.schluessel
INNER JOIN adresse a ON t.adresse = a.id
LEFT JOIN projekt p on t.projekt = p.id
WHERE t.adresse = '.$adresseId.' AND !(tn.versendet = 1 AND tn.zeitausgang IS NULL)
)
';
$sql .= ') a ';
$moreinfo = true; $moreinfo = true;
$doppelteids = true; $doppelteids = true;
$moreinfoaction = 'brief'; $moreinfoaction = 'brief';
$menucol = 9; $menucol = 9;
$more_data1 = $this->app->Secure->GetGET("more_data1"); $more_data1 = $this->app->Secure->GetGET("more_data1");
$more_data2 = $this->app->Secure->GetGET("more_data2"); $more_data2 = $this->app->Secure->GetGET("more_data2");
$more_data3 = $this->app->Secure->GetGET("more_data3"); $more_data3 = $this->app->Secure->GetGET("more_data3");
@@ -9531,12 +9618,18 @@ a.land as land, p.abkuerzung as projekt, a.zahlungsweise as zahlungsweise,
if ($more_data1 == 1) { if ($more_data1 == 1) {
$subWhereConditions[] = 'art LIKE "brief%"'; $subWhereConditions[] = 'art LIKE "brief%"';
} }
if ($more_data2 == 1) {
$subWhereConditions[] = 'art LIKE "email"';
}
if ($more_data3 == 1) { if ($more_data3 == 1) {
$subWhereConditions[] = 'art LIKE "telefon"'; $subWhereConditions[] = 'art LIKE "telefon"';
} }
if ($more_data4 == 1) { if ($more_data4 == 1) {
$subWhereConditions[] = 'art LIKE "notiz"'; $subWhereConditions[] = 'art LIKE "notiz"';
} }
if ($more_data5 == 1) {
$subWhereConditions[] = 'art LIKE "ticket%"';
}
if ($more_data10 == 1) { if ($more_data10 == 1) {
$subWhereConditions[] = 'art LIKE "wiedervorlage"'; $subWhereConditions[] = 'art LIKE "wiedervorlage"';
} }
@@ -12213,7 +12306,7 @@ source: "index.php?module=ajax&action=filter&filtername=' . $filter . $extendurl
} }
return str_replace($replace, $new, $sql); return str_replace($replace, $new, $sql);
} }
function AutoCompleteBestellung($fieldname, $filter, $onlyfirst = 0, $extendurl = "") { function AutoCompleteBestellung($fieldname, $filter, $onlyfirst = 0, $extendurl = "") {
$module = $this->app->Secure->GetGET("module"); $module = $this->app->Secure->GetGET("module");
@@ -12243,7 +12336,7 @@ source: "index.php?module=ajax&action=filter&filtername=' . $filter . '"
$this->app->Tpl->Set(strtoupper($fieldname) . 'START', '<div style="font-size: 8pt;"><div class="ui-widget" style="font-size: 8pt;">'); $this->app->Tpl->Set(strtoupper($fieldname) . 'START', '<div style="font-size: 8pt;"><div class="ui-widget" style="font-size: 8pt;">');
$this->app->Tpl->Set(strtoupper($fieldname) . 'ENDE', '</div></div>'); $this->app->Tpl->Set(strtoupper($fieldname) . 'ENDE', '</div></div>');
} }
function AutoCompleteAddCut($fieldname, $filter, $onlyfirst = 0, $extendurl = "") { function AutoCompleteAddCut($fieldname, $filter, $onlyfirst = 0, $extendurl = "") {
@@ -12296,6 +12389,7 @@ return false;
$this->app->Tpl->Set(strtoupper($fieldname) . 'START', '<div style="font-size: 8pt;"><div class="ui-widget" style="font-size: 8pt;">'); $this->app->Tpl->Set(strtoupper($fieldname) . 'START', '<div style="font-size: 8pt;"><div class="ui-widget" style="font-size: 8pt;">');
$this->app->Tpl->Set(strtoupper($fieldname) . 'ENDE', '</div></div>'); $this->app->Tpl->Set(strtoupper($fieldname) . 'ENDE', '</div></div>');
} }
function AutoCompleteAdd($fieldname, $filter, $onlyfirst = 0, $extendurl = "") { function AutoCompleteAdd($fieldname, $filter, $onlyfirst = 0, $extendurl = "") {
@@ -12350,7 +12444,8 @@ return false;
$this->app->Tpl->Set(strtoupper($fieldname) . 'START', '<div style="font-size: 8pt;"><div class="ui-widget" style="font-size: 8pt;">'); $this->app->Tpl->Set(strtoupper($fieldname) . 'START', '<div style="font-size: 8pt;"><div class="ui-widget" style="font-size: 8pt;">');
$this->app->Tpl->Set(strtoupper($fieldname) . 'ENDE', '</div></div>'); $this->app->Tpl->Set(strtoupper($fieldname) . 'ENDE', '</div></div>');
} }
function AutoCompleteAddEvent($fieldname, $filter, $onlyfirst = 0, $extendurl = "") { function AutoCompleteAddEvent($fieldname, $filter, $onlyfirst = 0, $extendurl = "") {
if ($onlyfirst) { if ($onlyfirst) {
$tpl = ' $tpl = '
@@ -12367,7 +12462,8 @@ source: "index.php?module=ajax&action=filter&filtername=' . $filter . $extendurl
$this->app->Tpl->Set(strtoupper($fieldname) . 'START', '<div style="font-size: 8pt;"><div class="ui-widget" style="font-size: 8pt;">'); $this->app->Tpl->Set(strtoupper($fieldname) . 'START', '<div style="font-size: 8pt;"><div class="ui-widget" style="font-size: 8pt;">');
$this->app->Tpl->Set(strtoupper($fieldname) . 'ENDE', '</div></div>'); $this->app->Tpl->Set(strtoupper($fieldname) . 'ENDE', '</div></div>');
} }
function AutoCompleteJSON($fieldname, $filter, $onlyfirst = 0, $extendurl = "", $extendedelement = "", $extendurl2 ="", $extendedelement2 = "", $appendto = "", $return = false) function AutoCompleteJSON($fieldname, $filter, $onlyfirst = 0, $extendurl = "", $extendedelement = "", $extendurl2 ="", $extendedelement2 = "", $appendto = "", $return = false)
{ {
if($extendedelement) if($extendedelement)
@@ -0,0 +1,6 @@
{
"host": "localhost",
"database": "openxe",
"user": "openxe",
"passwd": "openxe"
}
+343
View File
@@ -0,0 +1,343 @@
<?php
/*
* Helper to compare database structures from files vs. database
*
* Copyright (c) 2022 OpenXE project
*
*/
/*
MariaDB [openxe]> SHOW FULL db_def;
+----------------------------------------------+------------+
| Tables_in_openxe | Table_type |
+----------------------------------------------+------------+
| abrechnungsartikel | BASE TABLE |
| abrechnungsartikel_gruppe | BASE TABLE |
| abschlagsrechnung_rechnung | BASE TABLE |
| accordion | BASE TABLE |
| adapterbox | BASE TABLE |
| adapterbox_log | BASE TABLE |
| adapterbox_request_log | BASE TABLE |
| adresse | BASE TABLE |
| adresse_abosammelrechnungen | BASE TABLE |
| adresse_accounts | BASE TABLE |
| adresse_filter | BASE TABLE |
| adresse_filter_gruppen | BASE TABLE |
...
MariaDB [openxe]> SHOW FULL COLUMNS FROM wiki;
+-------------------+--------------+--------------------+------+-----+---------+----------------+---------------------------------+---------+
| Field | Type | Collation | Null | Key | Default | Extra | Privileges | Comment |
+-------------------+--------------+--------------------+------+-----+---------+----------------+---------------------------------+---------+
| id | int(11) | NULL | NO | PRI | NULL | auto_increment | select,insert,update,references | |
| name | varchar(255) | utf8mb3_general_ci | YES | MUL | NULL | | select,insert,update,references | |
| content | longtext | utf8mb3_general_ci | NO | | NULL | | select,insert,update,references | |
| lastcontent | longtext | utf8mb3_general_ci | NO | | NULL | | select,insert,update,references | |
| wiki_workspace_id | int(11) | NULL | NO | | 0 | | select,insert,update,references | |
| parent_id | int(11) | NULL | NO | | 0 | | select,insert,update,references | |
| language | varchar(32) | utf8mb3_general_ci | NO | | | | select,insert,update,references | |
+-------------------+--------------+--------------------+------+-----+---------+----------------+---------------------------------+---------+
MariaDB [openxe]> show keys from wiki;
+-------+------------+----------+--------------+-------------------+-----------+-------------+----------+--------+------+------------+---------+---------------+---------+
| Table | Non_unique | Key_name | Seq_in_index | Column_name | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment | Index_comment | Ignored |
+-------+------------+----------+--------------+-------------------+-----------+-------------+----------+--------+------+------------+---------+---------------+---------+
| wiki | 0 | PRIMARY | 1 | id | A | 244 | NULL | NULL | | BTREE | | | NO |
| wiki | 0 | suche | 1 | name | A | 244 | NULL | NULL | YES | BTREE | | | NO |
| wiki | 0 | suche | 2 | wiki_workspace_id | A | 244 | NULL | NULL | | BTREE | | | NO |
| wiki | 1 | name | 1 | name | A | 244 | NULL | NULL | YES | BTREE | | | NO |
+-------+------------+----------+--------------+-------------------+-----------+-------------+----------+--------+------+------------+---------+---------------+---------+
*/
require('mustal_mysql_upgrade_tool.php');
$connection_info_file_name = "connection_info.json";
$target_folder = ".";
$tables_file_name_wo_folder = "db_schema.json";
$tables_file_name_w_folder = $target_folder."/".$tables_file_name_wo_folder;
$delimiter = ";";
$quote = '"';
$sql_file_name = "upgrade.sql";
$color_red = "\033[31m";
$color_green = "\033[32m";
$color_yellow = "\033[33m";
$color_default = "\033[39m";
// -------------------------------- START
echo("\n");
if ($argc > 1) {
if (in_array('-v', $argv)) {
$verbose = true;
} else {
$verbose = false;
}
if (in_array('-f', $argv)) {
$force = true;
} else {
$force = false;
}
if (in_array('-e', $argv)) {
$export = true;
} else {
$export = false;
}
if (in_array('-c', $argv)) {
$compare = true;
} else {
$compare = false;
}
if (in_array('-i', $argv)) {
$onlytables = true;
} else {
$onlytables = false;
}
if (in_array('-upgrade', $argv)) {
$upgrade = true;
} else {
$upgrade = false;
}
if (in_array('-do', $argv)) {
$doupgrade = true;
} else {
$doupgrade = false;
}
if (in_array('-clean', $argv)) {
$clean = true;
} else {
$clean = false;
}
if (in_array('-utf8fix', $argv)) {
$utf8fix = true;
} else {
$utf8fix = false;
}
$connection_info_contents = file_get_contents($connection_info_file_name);
if (!$connection_info_contents) {
echo("Unable to load $connection_info_file_name\n");
exit;
}
$connection_info = json_decode($connection_info_contents, true);
$host = $connection_info['host'];
$user = $connection_info['user'];
$passwd = $connection_info['passwd'];
$schema = $connection_info['database'];
echo("--------------- Loading from database '$schema@$host'... ---------------\n");
$db_def = mustal_load_tables_from_db($host, $schema, $user, $passwd, $mustal_replacers);
if (empty($db_def)) {
echo ("Could not load from $schema@$host\n");
exit;
}
echo("--------------- Loading from database '$schema@$host' complete. ---------------\n");
if ($export) {
echo("--------------- Export to JSON... ---------------\n");
// $result = save_tables_to_csv($db_def, $target_folder, $tables_file_name_wo_folder, $delimiter, $quote, $keys_postfix, $force);
$result = mustal_save_tables_to_json($db_def, $target_folder, $tables_file_name_wo_folder, $force);
if ($result != 0) {
$result_texts = array("ok","key postfix error","table list file error","table file error","key file error");
echo ("Could not save to JSON (".$result_texts[$result]."). To overwrite, use -f.\n");
exit;
}
echo("Exported ".count($db_def['tables'])." tables.\n");
echo("--------------- Export to JSON ($tables_file_name_w_folder) complete. ---------------\n");
}
if ($compare || $upgrade) {
// Results here as ['text'] ['diff']
$compare_differences = array();
echo("--------------- Loading from JSON... ---------------\n");
$compare_def = mustal_load_tables_from_json($target_folder, $tables_file_name_wo_folder);
if (empty($compare_def)) {
echo ("Could not load from JSON $tables_file_name_w_folder\n");
exit;
}
echo("--------------- Loading from JSON complete. ---------------\n");
// Do the comparison
/*
echo("--------------- Comparing JSON '".$compare_def['database']."@".$compare_def['host']."' vs. database '$schema@$host' ---------------\n");
echo(count($compare_def['tables'])." tables in JSON, ".count($db_def['tables'])." tables in database.\n");
$compare_differences = compare_table_array($db_def,"in DB",$compare_def,"in JSON",false);
echo("Comparison found ".(empty($compare_differences)?0:count($compare_differences))." differences.\n");
if ($verbose) {
foreach ($compare_differences as $compare_difference) {
$comma = "";
foreach ($compare_difference as $key => $value) {
echo($comma."$key => '$value'");
$comma = ", ";
}
echo("\n");
}
}*/
echo("--------------- Comparing database '$schema@$host' vs. JSON '".$compare_def['database']."@".$compare_def['host']."' ---------------\n");
if($utf8fix) {
$column_collation_aliases = array(
['utf8mb3_general_ci','utf8_general_ci']
);
} else {
$column_collation_aliases = array();
}
$compare_differences = mustal_compare_table_array($compare_def,"in JSON",$db_def,"in DB",true,$column_collation_aliases);
echo((empty($compare_differences)?0:count($compare_differences))." differences.\n");
if ($verbose) {
foreach ($compare_differences as $compare_difference) {
$comma = "";
foreach ($compare_difference as $key => $value) {
echo($comma."$key => [$value]");
$comma = ", ";
}
echo("\n");
}
}
echo("--------------- Comparison complete. ---------------\n");
}
if ($upgrade) {
// First create all db_def that are missing in the db
echo("--------------- Calculating database upgrade for '$schema@$host'... ---------------\n");
$upgrade_sql = array();
$result = mustal_calculate_db_upgrade($compare_def, $db_def, $upgrade_sql, $mustal_replacers);
if ($result != 0) {
echo("Error: $result\n");
exit;
}
if (!empty($result)) {
echo(count($result)." errors.\n");
if ($verbose) {
foreach($result as $error) {
echo("Code: ".$error[0]." '".$error[1]."'.");
}
}
return(-1);
}
echo("--------------- Database upgrade for '$schema@$host'... ---------------\n");
if ($verbose) {
foreach($upgrade_sql as $statement) {
echo($statement."\n");
}
}
echo(count($upgrade_sql)." upgrade statements\n");
echo("--------------- Database upgrade calculated for '$schema@$host' (show SQL with -v). ---------------\n");
if ($doupgrade) {
echo("--------------- Executing database upgrade for '$schema@$host' database will be written! ---------------\n");
// First get the contents of the database table structure
$mysqli = mysqli_connect($host, $user, $passwd, $schema);
/* Check if the connection succeeded */
if (!$mysqli) {
echo ("Failed to connect!\n");
} else {
$counter = 0;
$error_counter = 0;
$number_of_statements = count($upgrade_sql);
foreach ($upgrade_sql as $sql) {
$counter++;
echo("\rUpgrade step $counter of $number_of_statements... ");
if ($verbose) {
echo("(".substr($sql,0,100)."...) ");
}
$query_result = mysqli_query($mysqli, $sql);
if (!$query_result) {
$error = " not ok: ". mysqli_error($mysqli)."\n";
echo($error);
file_put_contents("./errors.txt",$error.$sql."\n",FILE_APPEND);
$error_counter++;
} else {
echo("ok.\r");
}
}
echo("--------------- Executing database upgrade for '$schema@$host' executed. ---------------\n");
echo("$error_counter errors.\n");
echo("--------------- Executing database upgrade for '$schema@$host' done. ---------------\n");
echo("--------------- Checking database upgrade for '$schema@$host'... ---------------\n");
$db_def = mustal_load_tables_from_db($host, $schema, $user, $passwd, $mustal_replacers);
echo("--------------- Comparing database '$schema@$host' vs. JSON '".$compare_def['database']."@".$compare_def['host']."' ---------------\n");
$compare_differences = mustal_compare_table_array($compare_def,"in JSON",$db_def,"in DB",true);
echo((empty($compare_differences)?0:count($compare_differences))." differences.\n");
}
}
} // upgrade
echo("--------------- Done. ---------------\n");
echo("\n");
} else {
info();
exit;
}
function info() {
echo("OpenXE database compare\n");
echo("Copyright 2022 (c) OpenXE project\n");
echo("\n");
echo("Export database structures in a defined format for database comparison / upgrade\n");
echo("Options:\n");
echo("\t-v: verbose output\n");
echo("\t-f: force override of existing files\n");
echo("\t-e: export database structure to files\n");
echo("\t-c: compare content of files with database structure\n");
echo("\t-i: ignore column definitions\n");
echo("\t-utf8fix: apply fix for 'utf8' != 'utf8mb3'\n");
echo("\t-upgrade: Create the needed SQL to upgrade the database to match the JSON\n");
echo("\t-do: Execute the SQL to upgrade the database to match the JSON (risky!)\n");
echo("\t-clean: (not yet implemented) Create the needed SQL to remove items from the database not in the JSON\n");
echo("\n");
}
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,661 @@
<?php
/*
MUSTAL Mysql Upgrade Schema Tool by Alex Ledis
Helper to compare database structures from JSON files vs. database and upgrade database
Copyright (c) 2022 Alex Ledis
Licensed under AGPL v3
Version 1.0
function mustal_load_tables_from_db(string $host, string $schema, string $user, string $passwd, $replacers) : array
Load structure from db connection to an array.
function mustal_save_tables_to_json(array $db_def, string $path, string $tables_file_name, bool $force) : int
Save structure from array to a JSON file.
function mustal_load_tables_from_json(string $path, string $tables_file_name) : array
Load structure from JSON file into array.
function mustal_compare_table_array(array $nominal, string $nominal_name, array $actual, string $actual_name, bool $check_column_definitions) : array
Compare two database structures
Returns a structured array containing information on all the differences.
function mustal_calculate_db_upgrade(array $compare_def, array $db_def, array &$upgrade_sql) : int
Generate the SQL needed to upgrade the database to match the definition, based on a comparison.
Data structure in Array and JSON
{
"host": "hostname",
"database": "schemaname",
"user": "username",
"tables": [
{
"name": "",
"type": "",
"columns": [
{
"Field": "",
"Type": "",
"Collation": "",
"Null": "",
"Key": "",
"Default": "",
"Extra": "",
"Privileges": "",
"Comment": ""
}
],
"keys": [
{
"Key_name": "",
"columns": [
"",
""
]
}
]
}
]
}
*/
// These default values will not be in quotes, converted to lowercase and be replaced by the second entry
$mustal_replacers = [
['current_timestamp','current_timestamp()'],
['on update current_timestamp','on update current_timestamp()']
];
// Load all db_def from a DB connection into a db_def array
function mustal_load_tables_from_db(string $host, string $schema, string $user, string $passwd, $replacers) : array {
// First get the contents of the database table structure
$mysqli = mysqli_connect($host, $user, $passwd, $schema);
/* Check if the connection succeeded */
if (!$mysqli) {
return(array());
}
// Get db_def and views
$sql = "SHOW FULL tables";
$query_result = mysqli_query($mysqli, $sql);
if (!$query_result) {
return(array());
}
while ($row = mysqli_fetch_assoc($query_result)) {
$table = array();
$table['name'] = $row['Tables_in_'.$schema];
$table['type'] = $row['Table_type'];
$tables[] = $table; // Add table to list of tables
}
// Get and add columns of the table
foreach ($tables as &$table) {
$sql = "SHOW FULL COLUMNS FROM ".$table['name'];
$query_result = mysqli_query($mysqli, $sql);
if (!$query_result) {
return(array());
}
$columns = array();
while ($column = mysqli_fetch_assoc($query_result)) {
// Do some harmonization
if ($column['Default'] !== NULL) {
mustal_sql_replace_reserved_functions($column,$replacers);
$column['Default'] = mustal_mysql_put_text_type_in_quotes($column['Type'],$column['Default']);
}
$columns[] = $column; // Add column to list of columns
}
$table['columns'] = $columns;
$sql = "SHOW KEYS FROM ".$table['name'];
$query_result = mysqli_query($mysqli, $sql);
if (!$query_result) {
return(array());
}
$keys = array();
while ($key = mysqli_fetch_assoc($query_result)) {
$keys[] = $key; // Add key to list of keys
}
// Compose comparable format for keys
$composed_keys = array();
foreach ($keys as $key) {
// Check if this key exists already
$key_pos = array_search($key['Key_name'],array_column($composed_keys,'Key_name'));
if ($key_pos == false) {
// New key
$composed_key = array();
$composed_key['Key_name'] = $key['Key_name'];
$composed_key['Index_type'] = $key['Index_type'];
$composed_key['columns'][] = $key['Column_name'];
$composed_keys[] = $composed_key;
} else {
// Given key, add column
$composed_keys[$key_pos]['columns'][] .= $key['Column_name'];
}
}
unset($key);
$table['keys'] = $composed_keys;
unset($composed_keys);
}
unset($table);
$result = array();
$result['host'] = $host;
$result['database'] = $schema;
$result['user'] = $user;
$result['tables'] = $tables;
return($result);
}
function mustal_save_tables_to_json(array $db_def, string $path, string $tables_file_name, bool $force) : int {
// Prepare db_def file
if (!is_dir($path)) {
mkdir($path);
}
if (!$force && file_exists($path."/".$tables_file_name)) {
return(2);
}
$tables_file = fopen($path."/".$tables_file_name, "w");
if (empty($tables_file)) {
return(2);
}
fwrite($tables_file, json_encode($db_def,JSON_PRETTY_PRINT));
fclose($tables_file);
return(0);
}
// Load all db_def from JSON file
function mustal_load_tables_from_json(string $path, string $tables_file_name) : array {
$db_def = array();
$contents = file_get_contents($path."/".$tables_file_name);
if (!$contents) {
return(array());
}
$db_def = json_decode($contents, true);
if (!$db_def) {
return(array());
}
return($db_def);
}
// Compare two definitions
// Report based on the first array
// Return Array
// $column_collation_aliases may contain synonyms for collations e.g. utf8mb3_general_ci vs utf8_general_ci
function mustal_compare_table_array(array $nominal, string $nominal_name, array $actual, string $actual_name, bool $check_column_definitions, array $column_collation_aliases = array()) : array {
$compare_differences = array();
if (count($nominal['tables']) != count($actual['tables'])) {
$compare_difference = array();
$compare_difference['type'] = "Table count";
$compare_difference[$nominal_name] = count($nominal['tables']);
$compare_difference[$actual_name] = count($actual['tables']);
$compare_differences[] = $compare_difference;
}
foreach ($nominal['tables'] as $database_table) {
$found_table = array();
foreach ($actual['tables'] as $compare_table) {
if ($database_table['name'] == $compare_table['name']) {
$found_table = $compare_table;
break;
}
}
unset($compare_table);
if ($found_table) {
// Check type table vs view
if ($database_table['type'] != $found_table['type']) {
$compare_difference = array();
$compare_difference['type'] = "Table type";
$compare_difference['table'] = $database_table['name'];
$compare_difference[$nominal_name] = $database_table['type'];
$compare_difference[$actual_name] = $found_table['type'];
$compare_differences[] = $compare_difference;
}
// Only BASE TABLE supported now
if ($found_table['type'] != 'BASE TABLE') {
continue;
}
// Check columns
$compare_table_columns = array_column($found_table['columns'],'Field');
foreach ($database_table['columns'] as $column) {
$column_name_to_find = $column['Field'];
$column_key = array_search($column_name_to_find,$compare_table_columns,true);
if ($column_key !== false) {
// Compare the properties of the columns
if ($check_column_definitions) {
$found_column = $found_table['columns'][$column_key];
foreach ($column as $key => $value) {
// Apply aliases
if (!empty($column_collation_aliases)) {
foreach($column_collation_aliases as $column_collation_alias) {
if ($value == $column_collation_alias[0]) {
$value = $column_collation_alias[1];
}
if ($found_column[$key] == $column_collation_alias[0]) {
$found_column[$key] = $column_collation_alias[1];
}
}
}
if ($found_column[$key] != $value) {
if ($key != 'Key') { // Keys will be handled separately
$compare_difference = array();
$compare_difference['type'] = "Column definition";
$compare_difference['table'] = $database_table['name'];
$compare_difference['column'] = $column['Field'];
$compare_difference['property'] = $key;
$compare_difference[$nominal_name] = $value;
$compare_difference[$actual_name] = $found_column[$key];
$compare_differences[] = $compare_difference;
}
}
}
unset($value);
} // $check_column_definitions
} else {
$compare_difference = array();
$compare_difference['type'] = "Column existence";
$compare_difference['table'] = $database_table['name'];
$compare_difference[$nominal_name] = $column['Field'];
$compare_differences[] = $compare_difference;
}
}
unset($column);
// Check keys
$compare_table_sql_indexs = array_column($found_table['keys'],'Key_name');
foreach ($database_table['keys'] as $sql_index) {
$sql_index_name_to_find = $sql_index['Key_name'];
$sql_index_key = array_search($sql_index_name_to_find,$compare_table_sql_indexs,true);
if ($sql_index_key !== false) {
// Compare the properties of the sql_indexs
if ($check_column_definitions) {
$found_sql_index = $found_table['keys'][$sql_index_key];
foreach ($sql_index as $key => $value) {
if ($found_sql_index[$key] != $value) {
// if ($key != 'permissions') {
$compare_difference = array();
$compare_difference['type'] = "Key definition";
$compare_difference['table'] = $database_table['name'];
$compare_difference['key'] = $sql_index['Key_name'];
$compare_difference['property'] = $key;
$compare_difference[$nominal_name] = implode(',',$value);
$compare_difference[$actual_name] = implode(',',$found_sql_index[$key]);
$compare_differences[] = $compare_difference;
// }
}
}
unset($value);
} // $check_sql_index_definitions
} else {
$compare_difference = array();
$compare_difference['type'] = "Key existence";
$compare_difference['table'] = $database_table['name'];
$compare_difference[$nominal_name] = $sql_index['Key_name'];
$compare_differences[] = $compare_difference;
}
}
unset($sql_index);
} else {
$compare_difference = array();
$compare_difference['type'] = "Table existence";
$compare_difference[$nominal_name] = $database_table['name'];
$compare_differences[] = $compare_difference;
}
}
unset($database_table);
return($compare_differences);
}
// Generate SQL to create or modify column
function mustal_column_sql_definition(string $table_name, array $column, array $reserved_words_without_quote) : string {
foreach($column as $key => &$value) {
$value = (string) $value;
$value = mustal_column_sql_create_property_definition($key,$value,$reserved_words_without_quote);
}
// Default handling here
if ($column['Default'] == " DEFAULT ''") {
$column['Default'] = "";
}
$sql =
$column['Type'].
$column['Null'].
$column['Default'].
$column['Extra'].
$column['Collation'];
return($sql);
}
// Generate SQL to modify a single column property
function mustal_column_sql_create_property_definition(string $property, string $property_value, array $reserved_words_without_quote) : string {
switch ($property) {
case 'Type':
break;
case 'Null':
if ($property_value == "NO") {
$property_value = " NOT NULL"; // Idiotic...
}
if ($property_value == "YES") {
$property_value = " NULL"; // Also Idiotic...
}
break;
case 'Default':
// Check for MYSQL function mustal_call as default
if (in_array(strtolower($property_value),$reserved_words_without_quote)) {
$quote = "";
} else {
// Remove quotes if there are
$property_value = trim($property_value,"'");
$quote = "'";
}
$property_value = " DEFAULT $quote".$property_value."$quote";
break;
case 'Extra':
if ($property_value != '') {
$property_value = " ".$property_value;
}
break;
case 'Collation':
if ($property_value != '') {
$property_value = " COLLATE ".$property_value;
}
break;
default:
$property_value = "";
break;
}
return($property_value);
}
// Replaces different variants of the same function mustal_to allow comparison
function mustal_sql_replace_reserved_functions(array &$column, array $replacers) {
$result = strtolower($column['Default']);
foreach ($replacers as $replace) {
if ($result == $replace[0]) {
$result = $replace[1];
}
}
$column['Default'] = $result;
$result = strtolower($column['Extra']);
foreach ($replacers as $replace) {
if ($result == $replace[0]) {
$result = $replace[1];
}
}
$column['Extra'] = $result;
}
// Is it a text type? -> Use quotes then
function mustal_mysql_put_text_type_in_quotes(string $checktype, string $value) : string {
$types = array('char','varchar','tinytext','text','mediumtext','longtext');
foreach($types as $type) {
if (stripos($checktype, $type) !== false) {
return("'".$value."'");
}
}
return($value);
}
function mustal_implode_with_quote(string $quote, string $delimiter, array $array_to_implode) : string {
return($quote.implode($quote.$delimiter.$quote, $array_to_implode).$quote);
}
// Calculate the sql neccessary to update the database
// returns array(code,text)
// Error codes:
// 0 ok
// 1 Upgrade type of table not supported
// 2 Error on table upgrade
// 3 Error on column existence upgrade
// 4 Error on column existence upgrade
// 5 Error on column definition upgrade
// 6 Error on column definition upgrade
// 7 Error on key existence upgrade
// 8 Error on key existence upgrade
// 9 Error on key definition upgrade
// 10 Error on key definition upgrade
// 11 Table type upgrade not supported
// 12 Upgrade type not supported
function mustal_calculate_db_upgrade(array $compare_def, array $db_def, array &$upgrade_sql, array $replacers) : array {
$result = array();
$upgrade_sql = array();
$compare_differences = mustal_compare_table_array($compare_def,"in JSON",$db_def,"in DB",true);
if (count($compare_differences) > 0) {
$upgrade_sql[] = ("SET SQL_MODE='ALLOW_INVALID_DATES';");
$upgrade_sql[] = ("SET SESSION innodb_strict_mode=OFF;");
}
foreach ($compare_differences as $compare_difference) {
switch ($compare_difference['type']) {
case 'Table existence':
// Get table definition from JSON
$table_name = $compare_difference['in JSON'];
$table_key = array_search($table_name,array_column($compare_def['tables'],'name'));
if ($table_key !== false) {
$table = $compare_def['tables'][$table_key];
switch ($table['type']) {
case 'BASE TABLE':
// Create table in DB
$sql = "";
$sql = "CREATE TABLE `".$table['name']."` (";
$comma = "";
foreach ($table['columns'] as $column) {
$sql .= $comma."`".$column['Field']."` ".mustal_column_sql_definition($table_name, $column,array_column($replacers,1));
$comma = ", ";
}
// Add keys
$comma = ", ";
foreach ($table['keys'] as $key) {
if ($key['Key_name'] == 'PRIMARY') {
$keystring = "PRIMARY KEY ";
} else {
if(array_key_exists('Index_type', $key)) {
$index_type = $key['Index_type'];
} else {
$index_type = "";
}
$keystring = $index_type." KEY `".$key['Key_name']."` ";
}
$sql .= $comma.$keystring."(`".implode("`,`",$key['columns'])."`) ";
}
$sql .= ")";
$upgrade_sql[] = $sql;
break;
default:
$result[] = array(1,"Upgrade type '".$table['type']."' on table '".$table['name']."' not supported.");
break;
}
} else {
$result[] = array(2,"Error table_key while creating upgrade for table existence `$table_name`.");
}
break;
case 'Column existence':
$table_name = $compare_difference['table'];
$column_name = $compare_difference['in JSON'];
$table_key = array_search($table_name,array_column($compare_def['tables'],'name'));
if ($table_key !== false) {
$table = $compare_def['tables'][$table_key];
$columns = $table['columns'];
$column_key = array_search($column_name,array_column($columns,'Field'));
if ($column_key !== false) {
$column = $table['columns'][$column_key];
$sql = "ALTER TABLE `$table_name` ADD COLUMN `".$column_name."` ";
$sql .= mustal_column_sql_definition($table_name, $column, array_column($replacers,1));
$sql .= ";";
$upgrade_sql[] = $sql;
}
else {
$result[] = array(3,"Error column_key while creating column '$column_name' in table '".$table['name']."'.");
}
}
else {
$result[] = array(4,"Error table_key while creating upgrade for column existence '$column_name' in table '$table_name'.");
}
// Add Column in DB
break;
case 'Column definition':
$table_name = $compare_difference['table'];
$column_name = $compare_difference['column'];
$table_key = array_search($table_name,array_column($compare_def['tables'],'name'));
if ($table_key !== false) {
$table = $compare_def['tables'][$table_key];
$columns = $table['columns'];
$column_names = array_column($columns,'Field');
$column_key = array_search($column_name,$column_names);
if ($column_key !== false) {
$column = $table['columns'][$column_key];
$sql = "ALTER TABLE `$table_name` MODIFY COLUMN `".$column_name."` ";
$sql .= mustal_column_sql_definition($table_name, $column,array_column($replacers,1));
$sql .= ";";
$upgrade_sql[] = $sql;
}
else {
$result[] = array(5,"Error column_key while modifying column '$column_name' in table '".$table['name']."'.");
}
}
else {
$result[] = array(6,"Error table_key while modifying column '$column_name' in table '$table_name'.");
return(6);
}
// Modify Column in DB
break;
case 'Key existence':
$table_name = $compare_difference['table'];
$key_name = $compare_difference['in JSON'];
$table_key = array_search($table_name,array_column($compare_def['tables'],'name'));
if ($table_key !== false) {
$table = $compare_def['tables'][$table_key];
$keys = $table['keys'];
$key_names = array_column($keys,'Key_name');
$key_key = array_search($key_name,$key_names);
if ($key_key !== false) {
$key = $table['keys'][$key_key];
$sql = "ALTER TABLE `$table_name` ADD KEY `".$key_name."` ";
$sql .= "(`".implode("`,`",$key['columns'])."`)";
$sql .= ";";
$upgrade_sql[] = $sql;
}
else {
$result[] = array(7,"Error key_key while adding key '$key_name' in table '".$table['name']."'.");
}
}
else {
$result[] = array(8,"Error table_key while adding key '$key_name' in table '$table_name'.");
}
break;
case "Key definition":
$table_name = $compare_difference['table'];
$key_name = $compare_difference['key'];
$table_key = array_search($table_name,array_column($compare_def['tables'],'name'));
if ($table_key !== false) {
$table = $compare_def['tables'][$table_key];
$keys = $table['keys'];
$key_names = array_column($keys,'Key_name');
$key_key = array_search($key_name,$key_names);
if ($key_key !== false) {
$key = $table['keys'][$key_key];
$sql = "ALTER TABLE `$table_name` DROP KEY `".$key_name."`;";
$upgrade_sql[] = $sql;
$sql = "ALTER TABLE `$table_name` ADD KEY `".$key_name."` ";
$sql .= "(`".implode("`,`",$key['columns'])."`)";
$sql .= ";";
$upgrade_sql[] = $sql;
}
else {
$result[] = array(9, "Error key_key while changing key '$key_name' in table '".$table['name']."'.");
}
}
else {
$result[] = array(10,"Error table_key while changing key '$key_name' in table '$table_name'.");
}
break;
case 'Table count':
// Nothing to do
break;
case 'Table type':
$result[] = array(11,"Upgrade type '".$compare_difference['type']."' on table '".$compare_difference['table']."' not supported.");
break;
default:
$result[] = array(12,"Upgrade type '".$compare_difference['type']."' not supported.");
break;
}
}
$upgrade_sql = array_unique($upgrade_sql);
return($result);
}
+81 -36
View File
@@ -4,7 +4,7 @@
* Create module for listing and editing based on SQL table * Create module for listing and editing based on SQL table
* Create template files accordingly * Create template files accordingly
* *
* Copyright (c) 2022 Xenomporio project * Copyright (c) 2022 OpenXE project
* *
* Placeholders: * Placeholders:
* PLACEHOLDER_MODULENAME * PLACEHOLDER_MODULENAME
@@ -13,7 +13,7 @@
* PLACEHOLDER_EDIT * PLACEHOLDER_EDIT
* PLACEHOLDER_DELETE * PLACEHOLDER_DELETE
* PLACEHOLDER_SQL_LIST * PLACEHOLDER_SQL_LIST
* PLACEHOLDER_SQL_LIST * PLACEHOLDER_DROPNBOX
* PLACEHOLDER_GET_INPUT * PLACEHOLDER_GET_INPUT
* PLACEHOLDER_SET_INPUT * PLACEHOLDER_SET_INPUT
* PLACEHOLDER_COLUMNS * PLACEHOLDER_COLUMNS
@@ -21,9 +21,11 @@
*/ */
$host = 'localhost'; $host = 'localhost';
$user = 'xenomporiodev'; $user = 'openxe';
$passwd = 'xenomporiodev'; $passwd = 'openxe';
$schema = 'xenomporiodev'; $schema = 'openxe';
echo("\n");
if ($argc >= 2) { if ($argc >= 2) {
@@ -39,12 +41,34 @@ if ($argc >= 2) {
$force = false; $force = false;
} }
if (!str_starts_with($argv[1],'-')) { if (strpos($argv[1],'-') == 0) {
$module_name = $argv[1]; $module_name = $argv[1];
} else { } else {
info(); info();
exit; exit;
} }
// column selection
$selected_columns = array();
// Set selected_columns here or per parameter -c col1,col2,col3
// $selected_columns = array('belegnr','adresse','projekt');
if (in_array('-c', $argv)) {
$pos = array_keys($argv, '-c')[0];
$pos++;
if (isset($argv[$pos])) {
$selected_columns = explode(',',$argv[$pos]);
}
}
if (empty($selected_columns)) {
echo("Selected all columns.\n");
} else {
echo("Selected ".count($selected_columns)." columns,\n");
}
$module_class_name = ucfirst($module_name); $module_class_name = ucfirst($module_name);
$php_file_name = $module_name . ".php"; $php_file_name = $module_name . ".php";
$php_template_file_name = "module_creator_php_template.txt"; $php_template_file_name = "module_creator_php_template.txt";
@@ -52,6 +76,7 @@ if ($argc >= 2) {
$template_edit_file_name = $module_name . "_edit.tpl"; $template_edit_file_name = $module_name . "_edit.tpl";
$target_php_folder = "../../www/pages/"; $target_php_folder = "../../www/pages/";
$target_tpl_folder = "../../www/pages/content/"; $target_tpl_folder = "../../www/pages/content/";
$table_short_name = substr($module_name,0,1);
if (!$force && file_exists($target_php_folder.$php_file_name)) { if (!$force && file_exists($target_php_folder.$php_file_name)) {
echo("File exists: ." .$target_php_folder.$php_file_name . "\n"); echo("File exists: ." .$target_php_folder.$php_file_name . "\n");
@@ -82,50 +107,66 @@ if ($argc >= 2) {
} }
$columns = array(); $columns = array();
$sql_columns = array();
$edit_form = ""; $edit_form = "";
/* Iterate through the result set */ /* Iterate through the result set */
echo "FIELD\t\t\t\tType\t\tNull\tKey\tDefault\tExtra\n"; echo "FIELD\t\t\t\tType\t\tNull\tKey\tDefault\tExtra\n";
while ($row = mysqli_fetch_assoc($result)) { while ($row = mysqli_fetch_assoc($result)) {
foreach ($row as $key => $value) {
echo($value);
switch ($key) { $column_processed = false;
case 'Field':
$colwidth = 32;
if ($value != 'id') { if (empty($selected_columns) || in_array($row['Field'],$selected_columns) || $row['Field'] == 'id') {
$columns[] = $value;
}
break; foreach ($row as $key => $value) {
case 'Type':
$colwidth = 16; echo($value);
break;
default: switch ($key) {
$colwidth = 8; case 'Field':
break; $colwidth = 32;
if ($value != 'id') {
$column_processed = true;
$columns[] = $value;
$sql_columns[] = $table_short_name.".".$value;
}
break;
case 'Type':
$colwidth = 16;
break;
default:
$colwidth = 8;
break;
}
for ($filler = strlen($value); $filler < $colwidth; $filler++) {
echo(" ");
}
} }
for ($filler = strlen($value); $filler < $colwidth; $filler++) { // Build edit form
echo(" "); // <tr><td>{|Bezeichnung|}:*</td><td><input type="text" id="bezeichnung" name="bezeichnung" value="[BEZEICHNUNG]" size="40"></td></tr>
}
if ($row['Field'] != 'id') {
$edit_form = $edit_form . '<tr><td>{|' . ucfirst($row['Field']) . '|}:</td><td><input type="text" name="' . $row['Field'].'" id="'.$row['Field'].'" value="[' . strtoupper($row['Field']) . ']" size="20"></td></tr>' . "\n";
}
echo("\n");
} }
}
// Build edit form if (empty($columns)) {
// <tr><td>{|Bezeichnung|}:*</td><td><input type="text" id="bezeichnung" name="bezeichnung" value="[BEZEICHNUNG]" size="40"></td></tr> echo("No matching columns found!\n");
exit();
if ($row['Field'] != 'id') {
$edit_form = $edit_form . '<tr><td>{|' . ucfirst($row['Field']) . '|}:</td><td><input type="text" name="' . $row['Field'] . '" value="[' . strtoupper($row['Field']) . ']" size="40"></td></tr>' . "\n";
}
echo("\n");
} }
// Create php file // Create php file
$list_of_columns = implode(', ', $columns); $list_of_columns = implode(', ', $columns);
$list_of_columns_in_quotes = "'" . implode('\', \'', $columns) . "'"; $list_of_columns_in_quotes = "'" . implode('\', \'', $columns) . "'";
$sql_list_of_columns = implode(', ', $sql_columns);
$sql_list_of_columns_in_quotes = "'" . implode('\', \'', $sql_columns) . "'";
$get_input = ""; $get_input = "";
$set_input = ""; $set_input = "";
@@ -147,11 +188,13 @@ if ($argc >= 2) {
$php_file_contents = str_replace('PLACEHOLDER_LIST', $module_name . "_list", $php_file_contents); $php_file_contents = str_replace('PLACEHOLDER_LIST', $module_name . "_list", $php_file_contents);
$php_file_contents = str_replace('PLACEHOLDER_EDIT', $module_name . "_edit", $php_file_contents); $php_file_contents = str_replace('PLACEHOLDER_EDIT', $module_name . "_edit", $php_file_contents);
$php_file_contents = str_replace('PLACEHOLDER_DELETE', $module_name . "_delete", $php_file_contents); $php_file_contents = str_replace('PLACEHOLDER_DELETE', $module_name . "_delete", $php_file_contents);
$php_file_contents = str_replace('PLACEHOLDER_SQL_LIST', "SELECT id, $list_of_columns, id FROM $module_name", $php_file_contents); $php_file_contents = str_replace('PLACEHOLDER_DROPNBOX',"'<img src=./themes/new/images/details_open.png class=details>' AS `open`, CONCAT('<input type=\\\"checkbox\\\" name=\\\"auswahl[]\\\" value=\\\"',".$table_short_name.".id,'\\\" />') AS `auswahl`", $php_file_contents);
$php_file_contents = str_replace('PLACEHOLDER_SQL_LIST', "SELECT SQL_CALC_FOUND_ROWS $table_short_name.id, \$dropnbox, $sql_list_of_columns, $table_short_name.id FROM $module_name $table_short_name", $php_file_contents);
$php_file_contents = str_replace('PLACEHOLDER_SQL_EDIT', "INSERT INTO $module_name ($list_of_columns, id) values ('\".implode('\', \'',\$input).\"', \$id) ON DUPLICATE KEY UPDATE SET ", $php_file_contents); $php_file_contents = str_replace('PLACEHOLDER_SQL_EDIT', "INSERT INTO $module_name ($list_of_columns, id) values ('\".implode('\', \'',\$input).\"', \$id) ON DUPLICATE KEY UPDATE SET ", $php_file_contents);
$php_file_contents = str_replace('PLACEHOLDER_GET_INPUT', $get_input, $php_file_contents); $php_file_contents = str_replace('PLACEHOLDER_GET_INPUT', $get_input, $php_file_contents);
$php_file_contents = str_replace('PLACEHOLDER_SET_INPUT', $set_input, $php_file_contents); $php_file_contents = str_replace('PLACEHOLDER_SET_INPUT', $set_input, $php_file_contents);
$php_file_contents = str_replace('PLACEHOLDER_COLUMNS', $list_of_columns_in_quotes, $php_file_contents); $php_file_contents = str_replace('PLACEHOLDER_COLUMNS', $list_of_columns_in_quotes, $php_file_contents);
$php_file_contents = str_replace('PLACEHOLDER_SQL_COLUMNS', $sql_list_of_columns_in_quotes, $php_file_contents);
$php_file = fopen($target_php_folder . $php_file_name, "w"); $php_file = fopen($target_php_folder . $php_file_name, "w");
if (empty($php_file)) { if (empty($php_file)) {
@@ -208,13 +251,15 @@ if ($argc >= 2) {
} }
function info() { function info() {
echo("\nXenomporio module creator\n"); echo("\nOpenXE module creator\n");
echo("Copyright 2022 (c) Xenomporio project\n\n"); echo("Copyright 2022 (c) OpenXE project\n\n");
echo("Create a module.php file, a template for listing and a template for editing, based on a SQL table\n"); echo("Create a module.php file, a template for listing and a template for editing, based on a SQL table\n");
echo("\n"); echo("\n");
echo("arg1: SQL table name\n"); echo("arg1: SQL table name\n");
echo("Options\n"); echo("Options\n");
echo("\t-v: verbose output\n"); echo("\t-v: verbose output\n");
echo("\t-f: force override of existing files\n");
echo("\t-c: select columns like this: -c col1,col2,col3,col3\n");
echo("\n"); echo("\n");
} }
@@ -1,7 +1,7 @@
<?php <?php
/* /*
* Copyright (c) 2022 Xenomporio project * Copyright (c) 2022 OpenXE project
*/ */
use Xentral\Components\Database\Exception\QueryFailureException; use Xentral\Components\Database\Exception\QueryFailureException;
@@ -30,16 +30,21 @@ class PLACEHOLDER_MODULECLASSNAME {
switch ($name) { switch ($name) {
case "PLACEHOLDER_LIST": case "PLACEHOLDER_LIST":
$allowed['PLACEHOLDER_LIST'] = array('list'); $allowed['PLACEHOLDER_LIST'] = array('list');
$heading = array(PLACEHOLDER_COLUMNS, 'Men&uuml;'); $heading = array('','',PLACEHOLDER_COLUMNS, 'Men&uuml;');
$width = array('10%'); // Fill out manually later $width = array('1%','1%','10%'); // Fill out manually later
$findcols = array(PLACEHOLDER_COLUMNS); // columns that are aligned right (numbers etc)
$searchsql = array(PLACEHOLDER_COLUMNS); // $alignright = array(4,5,6,7,8);
$findcols = array(PLACEHOLDER_SQL_COLUMNS);
$searchsql = array(PLACEHOLDER_SQL_COLUMNS);
$defaultorder = 1; $defaultorder = 1;
$defaultorderdesc = 0; $defaultorderdesc = 0;
$menu = "<table cellpadding=0 cellspacing=0><tr><td nowrap>" . "<a href=\"index.php?module=PLACEHOLDER_MODULENAME&action=edit&id=%value%\"><img src=\"./themes/{$app->Conf->WFconf['defaulttheme']}/images/edit.png\" border=\"0\"></a>&nbsp;<a href=\"#\" onclick=DeleteDialog(\"index.php?module=PLACEHOLDER_MODULENAME&action=delete&id=%value%\");>" . "<img src=\"themes/{$app->Conf->WFconf['defaulttheme']}/images/delete.svg\" border=\"0\"></a>" . "</td></tr></table>"; $dropnbox = "PLACEHOLDER_DROPNBOX";
$menu = "<table cellpadding=0 cellspacing=0><tr><td nowrap>" . "<a href=\"index.php?module=PLACEHOLDER_MODULENAME&action=edit&id=%value%\"><img src=\"./themes/{$app->Conf->WFconf['defaulttheme']}/images/edit.svg\" border=\"0\"></a>&nbsp;<a href=\"#\" onclick=DeleteDialog(\"index.php?module=PLACEHOLDER_MODULENAME&action=delete&id=%value%\");>" . "<img src=\"themes/{$app->Conf->WFconf['defaulttheme']}/images/delete.svg\" border=\"0\"></a>" . "</td></tr></table>";
$sql = "PLACEHOLDER_SQL_LIST"; $sql = "PLACEHOLDER_SQL_LIST";
@@ -86,6 +91,12 @@ class PLACEHOLDER_MODULECLASSNAME {
function PLACEHOLDER_EDIT() { function PLACEHOLDER_EDIT() {
$id = $this->app->Secure->GetGET('id'); $id = $this->app->Secure->GetGET('id');
// Check if other users are editing this id
if($this->app->erp->DisableModul('artikel',$id))
{
return;
}
$this->app->Tpl->Set('ID', $id); $this->app->Tpl->Set('ID', $id);
@@ -141,6 +152,7 @@ class PLACEHOLDER_MODULECLASSNAME {
// Load values again from database // Load values again from database
$dropnbox = "PLACEHOLDER_DROPNBOX";
$result = $this->app->DB->SelectArr("PLACEHOLDER_SQL_LIST"." WHERE id=$id"); $result = $this->app->DB->SelectArr("PLACEHOLDER_SQL_LIST"." WHERE id=$id");
foreach ($result[0] as $key => $value) { foreach ($result[0] as $key => $value) {
-2
View File
@@ -1,2 +0,0 @@
<?php
header('Location: ./www/update.php?rand=' . sha1(mt_rand()));
-3
View File
@@ -1,3 +0,0 @@
<?php
include("upgradesystemclient2.php");
include("upgradedbonly.php");
+16
View File
@@ -0,0 +1,16 @@
Upgrade the OpenXE system.
NOTE:
The upgrade system is for use in LINUX only and needs to have git installed.
1. get files from git
2. run database upgrade
Files in this directory:
UPGRADE.md -> This file
upgrade.php -> The upgrade program
Files in the data subdirectory:
.in_progress.flag -> if this file exists, an upgrade is in progress, system will be locked
db_schema.json -> Contains the nominal database structure
remote.json -> Contains the git remote & branch which should be used for upgrade
File diff suppressed because it is too large Load Diff
+4
View File
@@ -0,0 +1,4 @@
{
"host": "https://github.com/openxe-org/openxe.git",
"branch": "master"
}
+466
View File
@@ -0,0 +1,466 @@
<?php
/*
* Upgrader using git for file upgrade and mustal to update the database definition
*
* Copyright (c) 2022 OpenXE project
*
*/
$upgrade_echo_out_file_name = "";
function upgrade_set_out_file_name(string $filename) {
GLOBAL $upgrade_echo_out_file_name;
$upgrade_echo_out_file_name = $filename;
}
function echo_out(string $text) {
GLOBAL $upgrade_echo_out_file_name;
if ($upgrade_echo_out_file_name == "") {
echo($text);
} else {
file_put_contents($upgrade_echo_out_file_name,$text, FILE_APPEND);
}
}
function echo_output(array $output) {
echo_out(implode("\n",$output)."\n");
}
function abort(string $message) {
echo_out($message."\n");
echo_out("--------------- Aborted! ---------------\n");
echo_out("--------------- ".date("Y-m-d H:i:s")." ---------------\n");
}
function git(string $command, &$output, bool $show_command, bool $show_output, string $error_text) : int {
$output = array();
if ($show_command) {
echo_out("git ".$command."\n");
}
exec("git ".$command,$output,$retval);
if (!empty($output)) {
if ($show_output || $retval != 0) {
echo_output($output);
}
}
return($retval);
}
// -------------------------------- START
// Check for correct call method
$directory = "";
if (php_sapi_name() == "cli") {
$cli = true;
$directory = ".";
} else if (basename(getcwd()) != 'upgrade') {
// Started from "www"
$directory = "../upgrade";
} else {
abort("Must be executed from 'upgrade' directory.");
return(-1);
}
if ($cli) {
$check_git = false;
$do_git = false;
$check_db = false;
$do_db = false;
$do = false;
if ($argc > 1) {
if (in_array('-v', $argv)) {
$verbose = true;
} else {
$verbose = false;
}
if (in_array('-e', $argv)) {
$export_db = true;
} else {
$export_db = false;
}
if (in_array('-f', $argv)) {
$force = true;
} else {
$force = false;
}
if (in_array('-connection', $argv)) {
$connection = true;
} else {
$connection = false;
}
if (in_array('-s', $argv)) {
$check_git = true;
} else {
}
if (in_array('-db', $argv)) {
$check_db = true;
} else {
}
if (in_array('-do', $argv)) {
if (!$check_git && !$check_db) {
$do_git = true;
$do_db = true;
}
if ($check_git) {
$do_git = true;
}
if ($check_db) {
$do_db = true;
}
}
if ($check_git || $check_db || $do_git || $do_db) {
upgrade_main($directory,$verbose,$check_git,$do_git,$export_db,$check_db,$do_db,$force,$connection);
} else {
info();
}
} else {
info();
}
}
// -------------------------------- END
function upgrade_main(string $directory,bool $verbose, bool $check_git, bool $do_git, bool $export_db, bool $check_db, bool $do_db, bool $force, bool $connection) {
if ($connection) {
$connection_file_name = $directory."/data/connection.json";
$connection_file_contents = file_get_contents($connection_file_name);
if (!$connection_file_contents) {
abort("Unable to load $connection_file_name");
return(-1);
}
$connection_info = json_decode($connection_file_contents, true);
$host = $connection_info['host'];
$user = $connection_info['user'];
$passwd = $connection_info['passwd'];
$schema = $connection_info['schema'];
} else {
class DatabaseConnectionInfo {
function __construct($dir) {
require($dir."/../conf/user.inc.php");
}
}
$dbci = new DatabaseConnectionInfo($directory);
$host = $dbci->WFdbhost;
$user = $dbci->WFdbuser;
$passwd = $dbci->WFdbpass;
$schema = $dbci->WFdbname;
}
require_once($directory.'/../vendor/mustal/mustal_mysql_upgrade_tool.php');
$datafolder = $directory."/data";
$lockfile_name = $datafolder."/.in_progress.flag";
$remote_file_name = $datafolder."/remote.json";
$schema_file_name = "db_schema.json";
echo_out("--------------- OpenXE upgrade ---------------\n");
echo_out("--------------- ".date("Y-m-d H:i:s")." ---------------\n");
//require_once($directory.'/../cronjobs/githash.php');
$remote_info_contents = file_get_contents($remote_file_name);
if (!$remote_info_contents) {
abort("Unable to load $remote_file_name");
return(-1);
}
$remote_info = json_decode($remote_info_contents, true);
$modified_files = false;
if ($check_git || $do_git) {
// Get changed files on system -> Should be empty
$output = array();
$retval = git("ls-files -m ..", $output,$verbose,false,"Git not initialized.");
if (!empty($output)) {
$modified_files = true;
echo_out("There are modified files:\n");
echo_output($output);
}
// Not a git repository -> Create it and then go ahead
if ($retval == 128) {
echo_out("Setting up git...");
$retval = git("init ..", $output,$verbose,$verbose,"Error while initializing git!");
if ($retval != 0) {
abort("");
return(-1);
}
$retval = git("add ../.", $output,$verbose,$verbose,"Error while initializing git!");
if ($retval != 0) {
abort("");
return(-1);
}
$retval = git("fetch ".$remote_info['host']." ".$remote_info['branch'],$output,$verbose,$verbose,"Error while initializing git!");
if ($retval != 0) {
abort("");
return(-1);
}
$retval = git("checkout FETCH_HEAD -f", $output,$verbose,$verbose,"Error while initializing git!");
if ($retval != 0) {
abort("");
return(-1);
}
} else if ($retval != 0) {
abort("Error while executing git!");
return(-1);
}
if ($verbose) {
echo_out("--------------- Upgrade history ---------------\n");
$retval = git("log --date=short-local --pretty=\"%cd (%h): %s\" HEAD --not HEAD~5",$output,$verbose,$verbose,"Error while showing history!");
if ($retval != 0) {
abort("");
return(-1);
}
} else {
echo_out("--------------- Current version ---------------\n");
$retval = git("log -1 --date=short-local --pretty=\"%cd (%h): %s\" HEAD",$output,$verbose,true,"Error while showing history!");
if ($retval != 0) {
return(-1);
}
}
if ($do_git) {
if ($modified_files && !$force) {
abort("Clear modified files or use -f");
return(-1);
}
echo_out("--------------- Pulling files... ---------------\n");
if ($force) {
$retval = git("reset --hard",$output,$verbose,$verbose,"Error while resetting modified files!");
if ($retval != 0) {
abort("");
return(-1);
}
}
$retval = git("pull ".$remote_info['host']." ".$remote_info['branch'],$output,$verbose,$verbose,"Error while pulling files!");
if ($retval != 0) {
abort("");
return(-1);
}
$retval = git("reset --hard",$output,$verbose,$verbose,"Error while applying files!");
if ($retval != 0) {
abort("");
return(-1);
}
echo_out("--------------- Files upgrade completed ---------------\n");
$retval = git("log -1 ",$output,$verbose,$verbose,"Error while checking files!");
if ($retval != 0) {
abort("");
return(-1);
}
echo_output($output);
} // $do_git
else { // Dry run
echo_out("--------------- Dry run, use -do to upgrade ---------------\n");
echo_out("--------------- Fetching files... ---------------\n");
$retval = git("fetch ".$remote_info['host']." ".$remote_info['branch'],$output,$verbose,$verbose,"Error while fetching files!");
if ($retval != 0) {
abort("");
}
echo_out("--------------- Pending upgrades: ---------------\n");
$retval = git("log --date=short-local --pretty=\"%cd (%h): %s\" FETCH_HEAD --not HEAD",$output,$verbose,true,"Error while fetching files!");
if (empty($output)) {
echo_out("No upgrades pending.\n");
}
if ($retval != 0) {
abort("");
}
} // Dry run
} // $check_git
if ($check_db || $do_db || $export_db) {
echo_out("--------------- Loading from database '$schema@$host'... ---------------\n");
$db_def = mustal_load_tables_from_db($host, $schema, $user, $passwd, $mustal_replacers);
if (empty($db_def)) {
echo_out("Could not load from $schema@$host\n");
exit;
}
if ($export_db) {
$export_file_name = "exported_db_schema.json";
if (mustal_save_tables_to_json($db_def, $datafolder, $export_file_name, true) == 0) {
echo_out("Database exported to $datafolder/$export_file_name\n");
}
else {
echo_out("Could not export database to $datafolder/$export_file_name\n");
}
}
$compare_differences = array();
echo_out("--------------- Loading from JSON... ---------------\n");
$compare_def = mustal_load_tables_from_json($datafolder, $schema_file_name);
if (empty($compare_def)) {
abort("Could not load from JSON $schema_file_name\n");
return(-1);
}
echo_out("Table count database ".count($db_def['tables'])." vs. JSON ".count($compare_def['tables'])."\n");
echo_out("--------------- Comparing JSON '".$compare_def['database']."@".$compare_def['host']."' vs. database '$schema@$host' ---------------\n");
$compare_differences = mustal_compare_table_array($db_def,"in DB",$compare_def,"in JSON",false,true);
if ($verbose) {
foreach ($compare_differences as $compare_difference) {
$comma = "";
foreach ($compare_difference as $key => $value) {
echo_out($comma."$key => [$value]");
$comma = ", ";
}
echo_out("\n");
}
}
echo_out((empty($compare_differences)?0:count($compare_differences))." differences.\n");
echo_out("--------------- Comparing database '$schema@$host' vs. JSON '".$compare_def['database']."@".$compare_def['host']."' ---------------\n");
$compare_differences = mustal_compare_table_array($compare_def,"in JSON",$db_def,"in DB",true,true);
if ($verbose) {
foreach ($compare_differences as $compare_difference) {
$comma = "";
foreach ($compare_difference as $key => $value) {
echo_out($comma."$key => [$value]");
$comma = ", ";
}
echo_out("\n");
}
}
echo_out((empty($compare_differences)?0:count($compare_differences))." differences.\n");
echo_out("--------------- Calculating database upgrade for '$schema@$host'... ---------------\n");
$upgrade_sql = array();
$result = mustal_calculate_db_upgrade($compare_def, $db_def, $upgrade_sql, $mustal_replacers);
if (!empty($result)) {
abort(count($result)." errors.\n");
if ($verbose) {
foreach($result as $error) {
echo_out("Code: ".$error[0]." '".$error[1]."'\n");
}
}
return(-1);
}
if ($verbose) {
foreach($upgrade_sql as $statement) {
echo_out($statement."\n");
}
}
echo_out(count($upgrade_sql)." upgrade statements\n");
if ($do_db) {
echo_out("--------------- Executing database upgrade for '$schema@$host' database... ---------------\n");
// First get the contents of the database table structure
$mysqli = mysqli_connect($host, $user, $passwd, $schema);
/* Check if the connection succeeded */
if (!$mysqli) {
echo ("Failed to connect!\n");
} else {
$counter = 0;
$error_counter = 0;
$number_of_statements = count($upgrade_sql);
foreach ($upgrade_sql as $sql) {
$counter++;
echo_out("\rUpgrade step $counter of $number_of_statements... ");
$query_result = mysqli_query($mysqli, $sql);
if (!$query_result) {
$error = " not ok: ". mysqli_error($mysqli);
echo_out($error);
echo_out("\n");
// file_put_contents("./errors.txt",date()." ".$error.$sql."\n",FILE_APPEND);
$error_counter++;
} else {
echo_out("ok.\r");
}
}
echo_out("\n");
echo_out("$error_counter errors.\n");
if ($error_counter > 0) {
// echo_out("See 'errors.txt'\n");
}
echo_out("--------------- Checking database upgrade for '$schema@$host'... ---------------\n");
$db_def = mustal_load_tables_from_db($host, $schema, $user, $passwd, $mustal_replacers);
echo_out("--------------- Comparing database '$schema@$host' vs. JSON '".$compare_def['database']."@".$compare_def['host']."' ---------------\n");
$compare_differences = mustal_compare_table_array($compare_def,"in JSON",$db_def,"in DB",true,true);
echo_out((empty($compare_differences)?0:count($compare_differences))." differences.\n");
}
} // $do_db
} // $check_db
/*
echo_out("--------------- Locking system ---------------\n");
if (file_exists($lockfile_name)) {
echo_out("System is already locked.\n");
} else {
file_put_contents($lockfile_name," ");
}
echo_out("--------------- Unlocking system ---------------\n");
unlink($lockfile_name);
*/
echo_out("--------------- Done! ---------------\n");
echo_out("--------------- ".date("Y-m-d H:i:s")." ---------------\n");
return(0);
}
function info() {
echo_out("OpenXE upgrade tool\n");
echo_out("Copyright 2022 (c) OpenXE project\n");
echo_out("\n");
echo_out("Upgrade files and database\n");
echo_out("Options:\n");
echo_out("\t-s: check/do system upgrades\n");
echo_out("\t-db: check/do database upgrades\n");
echo_out("\t-e: export database schema\n");
echo_out("\t-do: execute all upgrades\n");
echo_out("\t-v: verbose output\n");
echo_out("\t-f: force override of existing files\n");
echo_out("\t-connection use connection.json in data folder instead of user.inc.php\n");
echo_out("\t-clean: (not yet implemented) create the needed SQL to remove items from the database not in the JSON\n");
echo_out("\n");
}
-98
View File
@@ -1,98 +0,0 @@
<?php
//include("wawision.inc.php");
use Xentral\Core\Installer\Installer;
use Xentral\Core\Installer\InstallerCacheConfig;
use Xentral\Core\Installer\InstallerCacheWriter;
use Xentral\Core\Installer\ClassMapGenerator;
use Xentral\Core\Installer\Psr4ClassNameResolver;
use Xentral\Core\Installer\TableSchemaEnsurer;
use Xentral\Components\Database\DatabaseConfig;
// Nur einfache Fehler melden
error_reporting(E_ERROR | E_COMPILE_ERROR | E_CORE_ERROR | E_RECOVERABLE_ERROR | E_USER_ERROR | E_PARSE);
if(file_exists(__DIR__.'/xentral_autoloader.php')){
include_once (__DIR__.'/xentral_autoloader.php');
}
include_once("conf/main.conf.php");
include_once("phpwf/plugins/class.mysql.php");
include_once("www/lib/class.erpapi.php");
if(file_exists("www/lib/class.erpapi_custom.php")){
include_once("www/lib/class.erpapi_custom.php");
}
/*
class app_t
{
var $DB;
var $user;
var $Conf;
}
$app = new app_t();
*/
$config = new Config();
// Delete ServiceMap-CacheFile
$installConf = new InstallerCacheConfig($config->WFuserdata . '/tmp/' . $config->WFdbname);
$serviceCacheFile = $installConf->getServiceCacheFile();
@unlink($serviceCacheFile);
$app = new ApplicationCore();
$DEBUG = 0;
$app->Conf = $config;
$app->DB = new DB($app->Conf->WFdbhost,$app->Conf->WFdbname,$app->Conf->WFdbuser,$app->Conf->WFdbpass, $app, $app->Conf->WFdbport);
if(class_exists('erpAPICustom'))
{
$erp = new erpAPICustom($app);
}else{
$erp = new erpAPI($app);
}
echo "STARTE DB Upgrade\r\n";
$erp->UpgradeDatabase();
echo "ENDE DB Upgrade\r\n\r\n";
try {
echo "STARTE Installer\r\n";
$resolver = new Psr4ClassNameResolver();
$resolver->addNamespace('Xentral\\', __DIR__ . '/classes');
$resolver->excludeFile(__DIR__ . '/classes/bootstrap.php');
$generator = new ClassMapGenerator($resolver, __DIR__);
$installer = new Installer($generator, $resolver);
$writer = new InstallerCacheWriter($installConf, $installer);
$dbConfig = new DatabaseConfig(
$app->Conf->WFdbhost,
$app->Conf->WFdbuser,
$app->Conf->WFdbpass,
$app->Conf->WFdbname,
null,
$app->Conf->WFdbport
);
$tableSchemaCreator = new TableSchemaEnsurer(
$app->Container->get('SchemaCreator'),
$installConf,
$dbConfig
);
echo "SCHREIBE ServiceMap\r\n";
$writer->writeServiceCache();
echo "SCHREIBE JavascriptMap\r\n";
$writer->writeJavascriptCache();
echo "ERZEUGE Table Schemas\r\n";
$schemaCollection = $installer->getTableSchemas();
$tableSchemaCreator->ensureSchemas($schemaCollection);
echo "ENDE Installer\r\n";
//
} catch (Exception $e) {
echo "FEHLER " . $e->getMessage() . "\r\n";
}
-7
View File
@@ -1,7 +0,0 @@
<?php
$intern = true;
if(!empty($argv[1]) && strtolower($argv[1]) === 'changeversion'){
$allowChangeVersion = true;
}
include __DIR__.'/www/update.php';
-812
View File
@@ -1,812 +0,0 @@
<?php
//include("wawision.inc.php");
// Nur einfache Fehler melden
//error_reporting(E_ERROR | E_WARNING | E_PARSE);
error_reporting(E_ERROR | E_PARSE);
include_once("conf/main.conf.php");
include_once("phpwf/plugins/class.mysql.php");
include_once("www/lib/class.erpapi.php");
class app_t {
var $DB;
var $user;
var $Conf;
}
$app = new app_t();
$DEBUG = 0;
$app->Conf = new Config();
$app->DB = new DB($app->Conf->WFdbhost,$app->Conf->WFdbname,$app->Conf->WFdbuser,$app->Conf->WFdbpass,null,$app->Conf->WFdbport);
$erp = new erpAPI($app);
$WAWISION['host'] = $app->Conf->updateHost ?? 'removed.upgrade.host';
$WAWISION['port']="443";
$myUpd = new UpgradeClient($WAWISION);
echo "STARTE UPDATE\n";
echo "Im folgenden stehen die Dateien die geaendert wurden.\n
Erscheinen keine Dateien sind Sie auf der neusten Version.\n";
$myUpd->Connect();
//$myUpd->CheckCRT();
$myUpd->CheckUpdate();
$myUpd->CheckUpdateCustom();
$myUpd->CheckUpdateModules();
echo "ENDE UPDATE\n";
//echo "STARTE DB UPGRADE\n";
//$erp->UpgradeDatabase();
//echo "ENDE DB UPGRADE\n";
//include("version.php");
//echo "\r\nRevision: $version_revision\r\n";
//$myUpd->Request();
//echo
class UpgradeClient
{
var $localmd5sums;
function __construct($conf)
{
$this->conf = $conf;
}
function Connect()
{
// check connection then stop
}
function CheckCRT()
{
$cert = shell_exec("openssl s_client -connect {$this->conf['host']}:{$this->conf['port']} < /dev/null 2>/dev/null | openssl x509 -in /dev/stdin");
if($cert==$this->conf['cert']."\n") return 1;
else {
echo "wrong\n";
exit;
}
}
function CheckUpdate()
{
$parameter['version']=@$this->conf['version'];
$result = $this->Request("md5list",$parameter);
if($result=="ERROR") { echo "Updates: ERROR FROM SERVER (Perhaps a wrong license?)\n"; return;}
$rows = explode(";",$result);
if(count($rows)>0)
{
foreach($rows as $value)
{
unset($single_row);
$single_row = explode(":",$value);
if(count($single_row)>=2 && strlen($single_row[0])>3 && strlen($single_row[1])>3)
{
$file = $single_row[0];
$md5sum = $single_row[1];
$parameter['file']=$file;
$parameter['md5sum']=$md5sum;
if($file=="./upgradesystemclient.php")
{
}
else if(is_file($file))
{
// pruefe md5sum
if(md5_file($file)!=$md5sum)
{
// wenn update dann UPD_
echo "update <- $file\n";
$result = $this->Request("getfile",$parameter);
$output = (base64_decode($result));
//$output = preg_replace('/[^(\x22-\x7F)\x0A]*/','', $output);
file_put_contents($file."UPD", $output);
/*
$fp = fopen($file."UPD","wb+");
fwrite($fp,base64_decode($result));
fclose($fp);
*/
// pruefsuemme neu berechnen wenn passt umbenennen und ins archiv
echo md5_file($file."UPD");
echo "-".$md5sum."\n";
if(md5_file($file."UPD")==$md5sum)
{
echo "update ok $file\n";
rename($file."UPD",$file);
}
}
} else if($file!="") {
echo "datei <- $file\n";
// pruefe ob es verzeichnis gibt
$verzeichnis = dirname($file);
if(!is_dir($verzeichnis))
{
echo "verzeichnis <- $verzeichnis\n";
mkdir($verzeichnis,0777,true);
}
$result = $this->Request("getfile",$parameter);
$output = base64_decode($result);
//$output = iconv("UTF-8","ISO-8859-1//IGNORE",$output);
//$output = iconv("ISO-8859-1","UTF-8",$output);
//$output = preg_replace('/[^(\x20-\x7F)\x0A]*/','', $output);
file_put_contents($file."NEW", $output);
/*$fp = fopen($file."NEW","wb+");
fwrite($fp,base64_decode($result));
fclose($fp);
*/
if(md5_file($file."NEW")==$md5sum)
{
echo "datei ok $file\n";
rename($file."NEW",$file);
} else {
// echo "datei XX $file local: ".md5_file($file."NEW")." remote: ".$md5sum."\n";
}
} else { }
}
}
}
//pruefe, update, lege verzeichnis an, lege datei an, loesche datei????
// download all files with UPD_ prefix
// get md5 liste von server
// pruefe ob alle dateien passen, wenn ja dann alle updaten am schluss
// wenn nein fehler abbrechen und ganzen prozess nochmal starten
//echo $md5sums;
}
function CheckUpdateModules()
{
$parameter['version']=@$this->conf['version'];
$result = $this->Request("md5listmodules",$parameter);
if($result=="ERROR") { echo "Modules: ERROR FROM SERVER (Perhaps a wrong license?)\n"; return;}
$rows = explode(";",$result);
if(count($rows)>0)
{
foreach($rows as $value)
{
unset($single_row);
$single_row = explode(":",$value);
if(count($single_row)>=2 && strlen($single_row[0])>3 && strlen($single_row[1])>3)
{
$file = $single_row[0];
$md5sum = $single_row[1];
$parameter['file']=$file;
$parameter['md5sum']=$md5sum;
if($file=="./upgradesystemclient.php")
{
}
else if(is_file($file))
{
// pruefe md5sum
if(md5_file($file)!=$md5sum)
{
// wenn update dann UPD_
echo "update (M) <- $file\n";
$result = $this->Request("getfilemodules",$parameter);
$output = (base64_decode($result));
//$output = preg_replace('/[^(\x22-\x7F)\x0A]*/','', $output);
file_put_contents($file."UPD", $output);
/*
$fp = fopen($file."UPD","wb+");
fwrite($fp,base64_decode($result));
fclose($fp);
*/
// pruefsuemme neu berechnen wenn passt umbenennen und ins archiv
echo md5_file($file."UPD");
echo "-".$md5sum."\n";
if(md5_file($file."UPD")==$md5sum)
{
echo "update (M) ok $file\n";
rename($file."UPD",$file);
}
}
} else if($file!="") {
echo "datei (M) <- $file\n";
// pruefe ob es verzeichnis gibt
$verzeichnis = dirname($file);
if(!is_dir($verzeichnis))
{
echo "verzeichnis (M) <- $verzeichnis\n";
mkdir($verzeichnis,0777,true);
}
$result = $this->Request("getfilemodules",$parameter);
$output = base64_decode($result);
//$output = iconv("UTF-8","ISO-8859-1//IGNORE",$output);
//$output = iconv("ISO-8859-1","UTF-8",$output);
//$output = preg_replace('/[^(\x20-\x7F)\x0A]*/','', $output);
file_put_contents($file."NEW", $output);
/*$fp = fopen($file."NEW","wb+");
fwrite($fp,base64_decode($result));
fclose($fp);
*/
if(md5_file($file."NEW")==$md5sum)
{
echo "datei (M) ok $file\n";
rename($file."NEW",$file);
} else {
// echo "datei XX $file local: ".md5_file($file."NEW")." remote: ".$md5sum."\n";
}
} else { }
}
}
}
//pruefe, update, lege verzeichnis an, lege datei an, loesche datei????
// download all files with UPD_ prefix
// get md5 liste von server
// pruefe ob alle dateien passen, wenn ja dann alle updaten am schluss
// wenn nein fehler abbrechen und ganzen prozess nochmal starten
//echo $md5sums;
}
function CheckUpdateCustom()
{
$parameter['version']=@$this->conf['version'];
$result = $this->Request("md5listcustom",$parameter);
if($result=="ERROR") { echo "Custom: ERROR FROM SERVER (Perhaps a wrong license?)\n"; return;}
$rows = explode(";",$result);
if(count($rows)>0)
{
foreach($rows as $value)
{
unset($single_row);
$single_row = explode(":",$value);
if(count($single_row)>=2 && strlen($single_row[0])>3 && strlen($single_row[1])>3)
{
$file = $single_row[0];
$md5sum = $single_row[1];
$parameter['file']=$file;
$parameter['md5sum']=$md5sum;
if($file=="./upgradesystemclient.php")
{
}
else if(is_file($file))
{
// pruefe md5sum
if(md5_file($file)!=$md5sum)
{
// wenn update dann UPD_
echo "update (C) <- $file\n";
$result = $this->Request("getfilecustom",$parameter);
$output = (base64_decode($result));
//$output = preg_replace('/[^(\x22-\x7F)\x0A]*/','', $output);
file_put_contents($file."UPD", $output);
/*
$fp = fopen($file."UPD","wb+");
fwrite($fp,base64_decode($result));
fclose($fp);
*/
// pruefsuemme neu berechnen wenn passt umbenennen und ins archiv
echo md5_file($file."UPD");
echo "-".$md5sum."\n";
if(md5_file($file."UPD")==$md5sum)
{
echo "update (C) ok $file\n";
rename($file."UPD",$file);
}
}
} else if($file!="") {
echo "datei (C) <- $file\n";
// pruefe ob es verzeichnis gibt
$verzeichnis = dirname($file);
if(!is_dir($verzeichnis))
{
echo "verzeichnis (C) <- $verzeichnis\n";
mkdir($verzeichnis,0777,true);
}
$result = $this->Request("getfilecustom",$parameter);
$output = base64_decode($result);
//$output = iconv("UTF-8","ISO-8859-1//IGNORE",$output);
//$output = iconv("ISO-8859-1","UTF-8",$output);
//$output = preg_replace('/[^(\x20-\x7F)\x0A]*/','', $output);
file_put_contents($file."NEW", $output);
/*$fp = fopen($file."NEW","wb+");
fwrite($fp,base64_decode($result));
fclose($fp);
*/
if(md5_file($file."NEW")==$md5sum)
{
echo "datei (C) ok $file\n";
rename($file."NEW",$file);
} else {
// echo "datei XX $file local: ".md5_file($file."NEW")." remote: ".$md5sum."\n";
}
} else { }
}
}
}
//pruefe, update, lege verzeichnis an, lege datei an, loesche datei????
// download all files with UPD_ prefix
// get md5 liste von server
// pruefe ob alle dateien passen, wenn ja dann alle updaten am schluss
// wenn nein fehler abbrechen und ganzen prozess nochmal starten
//echo $md5sums;
}
function DownloadUpdate()
{
}
function CheckDownloadedUpdate()
{
}
function ExecuteUpdate()
{
}
function Request($command,$parameter)
{
global $erp;
$auth['serial']=trim($erp->Firmendaten("lizenz"));//$this->conf['serial'];
$auth['authkey']=trim($erp->Firmendaten("schluessel"));//$this->conf['authkey'];
$auth = base64_encode(json_encode($auth));
$parameter = base64_encode(json_encode($parameter));
$client = new HttpClient($this->conf['host'],$this->conf['port']);
$client->post('/upgradesystem.php', array( "authjson" => $auth, "parameterjson"=>$parameter,"command"=>"$command" ));
$pageContents = $client->getContent();
return $pageContents;
}
function dir_rekursiv($verzeichnis)
{
$handle = opendir($verzeichnis);
while ($datei = readdir($handle))
{
if ($datei != "." && $datei != "..")
{
if (is_dir($verzeichnis.$datei)) // Wenn Verzeichniseintrag ein Verzeichnis ist
{
// Erneuter Funktionsaufruf, um das aktuelle Verzeichnis auszulesen
$this->dir_rekursiv($verzeichnis.$datei.'/');
}
else
{
// Wenn Verzeichnis-Eintrag eine Datei ist, diese ausgeben
$this->localmd5sums[$verzeichnis.$datei] = md5_file($verzeichnis.$datei);
}
}
}
closedir($handle);
}
}
/* Version 0.9, 6th April 2003 - Simon Willison ( http://simon.incutio.com/ )
Manual: http://scripts.incutio.com/httpclient/
*/
class HttpClient {
// Request vars
var $host;
var $port;
var $path;
var $method;
var $postdata = '';
var $cookies = array();
var $referer;
var $accept = 'text/xml,application/xml,application/xhtml+xml,text/html,text/plain,image/png,image/jpeg,image/gif,*/*';
var $accept_encoding = 'gzip';
var $accept_language = 'en-us';
var $user_agent = 'Incutio HttpClient v0.9';
// Options
var $timeout = 20;
var $use_gzip = true;
var $persist_cookies = true; // If true, received cookies are placed in the $this->cookies array ready for the next request
// Note: This currently ignores the cookie path (and time) completely. Time is not important,
// but path could possibly lead to security problems.
var $persist_referers = true; // For each request, sends path of last request as referer
var $debug = false;
var $handle_redirects = true; // Auaomtically redirect if Location or URI header is found
var $max_redirects = 5;
var $headers_only = false; // If true, stops receiving once headers have been read.
// Basic authorization variables
var $username;
var $password;
// Response vars
var $status;
var $headers = array();
var $content = '';
var $errormsg;
// Tracker variables
var $redirect_count = 0;
var $cookie_host = '';
function __construct($host, $port=80) {
$this->host = $host;
$this->port = $port;
}
function get($path, $data = false) {
$this->path = $path;
$this->method = 'GET';
if ($data) {
$this->path .= '?'.$this->buildQueryString($data);
}
return $this->doRequest();
}
function post($path, $data) {
$this->path = $path;
$this->method = 'POST';
$this->postdata = $this->buildQueryString($data);
return $this->doRequest();
}
function buildQueryString($data) {
$querystring = '';
if (is_array($data)) {
// Change data in to postable data
foreach ($data as $key => $val) {
if (is_array($val)) {
foreach ($val as $val2) {
$querystring .= urlencode($key).'='.urlencode($val2).'&';
}
} else {
$querystring .= urlencode($key).'='.urlencode($val).'&';
}
}
$querystring = substr($querystring, 0, -1); // Eliminate unnecessary &
} else {
$querystring = $data;
}
return $querystring;
}
function doRequest() {
// Performs the actual HTTP request, returning true or false depending on outcome
if(!fsockopen("ssl://".$this->host, $this->port, $errno, $errstr, $this->timeout) && $this->port==443)
{
$this->port=80;
}
if($this->port==443)
$url = "ssl://".$this->host;
else
$url = $this->host;
if (!$fp = @fsockopen($url, $this->port, $errno, $errstr, $this->timeout)) {
// Set error message
switch($errno) {
case -3:
$this->errormsg = 'Socket creation failed (-3)';
case -4:
$this->errormsg = 'DNS lookup failure (-4)';
case -5:
$this->errormsg = 'Connection refused or timed out (-5)';
default:
$this->errormsg = 'Connection failed ('.$errno.')';
$this->errormsg .= ' '.$errstr;
$this->debug($this->errormsg);
}
return false;
}
stream_set_timeout($fp, $this->timeout);
$request = $this->buildRequest();
$this->debug('Request', $request);
fwrite($fp, $request);
// Reset all the variables that should not persist between requests
$this->headers = array();
$this->content = '';
$this->errormsg = '';
// Set a couple of flags
$inHeaders = true;
$atStart = true;
// Now start reading back the response
while (!feof($fp)) {
$line = fgets($fp, 4096);
if ($atStart) {
// Deal with first line of returned data
$atStart = false;
if (!preg_match('/HTTP\/(\\d\\.\\d)\\s*(\\d+)\\s*(.*)/', $line, $m)) {
$this->errormsg = "Status code line invalid: ".htmlentities($line);
$this->debug($this->errormsg);
//return false;
}
$http_version = $m[1]; // not used
$this->status = $m[2];
$status_string = $m[3]; // not used
$this->debug(trim($line));
continue;
}
if ($inHeaders) {
if (trim($line) == '') {
$inHeaders = false;
$this->debug('Received Headers', $this->headers);
if ($this->headers_only) {
break; // Skip the rest of the input
}
continue;
}
if (!preg_match('/([^:]+):\\s*(.*)/', $line, $m)) {
// Skip to the next header
continue;
}
$key = strtolower(trim($m[1]));
$val = trim($m[2]);
// Deal with the possibility of multiple headers of same name
if (isset($this->headers[$key])) {
if (is_array($this->headers[$key])) {
$this->headers[$key][] = $val;
} else {
$this->headers[$key] = array($this->headers[$key], $val);
}
} else {
$this->headers[$key] = $val;
}
continue;
}
// We're not in the headers, so append the line to the contents
$this->content .= $line;
}
fclose($fp);
// If data is compressed, uncompress it
if (isset($this->headers['content-encoding']) && $this->headers['content-encoding'] == 'gzip') {
$this->debug('Content is gzip encoded, unzipping it');
$this->content = substr($this->content, 10); // See http://www.php.net/manual/en/function.gzencode.php
$this->content = gzinflate($this->content);
}
// If $persist_cookies, deal with any cookies
if ($this->persist_cookies && isset($this->headers['set-cookie']) && $this->host == $this->cookie_host) {
$cookies = $this->headers['set-cookie'];
if (!is_array($cookies)) {
$cookies = array($cookies);
}
foreach ($cookies as $cookie) {
if (preg_match('/([^=]+)=([^;]+);/', $cookie, $m)) {
$this->cookies[$m[1]] = $m[2];
}
}
// Record domain of cookies for security reasons
$this->cookie_host = $this->host;
}
// If $persist_referers, set the referer ready for the next request
if ($this->persist_referers) {
$this->debug('Persisting referer: '.$this->getRequestURL());
$this->referer = $this->getRequestURL();
}
// Finally, if handle_redirects and a redirect is sent, do that
if ($this->handle_redirects) {
if (++$this->redirect_count >= $this->max_redirects) {
$this->errormsg = 'Number of redirects exceeded maximum ('.$this->max_redirects.')';
$this->debug($this->errormsg);
$this->redirect_count = 0;
return false;
}
$location = isset($this->headers['location']) ? $this->headers['location'] : '';
$uri = isset($this->headers['uri']) ? $this->headers['uri'] : '';
if ($location || $uri) {
$url = parse_url($location.$uri);
// This will FAIL if redirect is to a different site
return $this->get($url['path']);
}
}
return true;
}
function buildRequest() {
$headers = array();
$headers[] = "{$this->method} {$this->path} HTTP/1.0"; // Using 1.1 leads to all manner of problems, such as "chunked" encoding
$headers[] = "Host: {$this->host}";
$headers[] = "User-Agent: {$this->user_agent}";
$headers[] = "Accept: {$this->accept}";
if ($this->use_gzip) {
$headers[] = "Accept-encoding: {$this->accept_encoding}";
}
$headers[] = "Accept-language: {$this->accept_language}";
if ($this->referer) {
$headers[] = "Referer: {$this->referer}";
}
// Cookies
if ($this->cookies) {
$cookie = 'Cookie: ';
foreach ($this->cookies as $key => $value) {
$cookie .= "$key=$value; ";
}
$headers[] = $cookie;
}
// Basic authentication
if ($this->username && $this->password) {
$headers[] = 'Authorization: BASIC '.base64_encode($this->username.':'.$this->password);
}
// If this is a POST, set the content type and length
if ($this->postdata) {
$headers[] = 'Content-Type: application/x-www-form-urlencoded';
$headers[] = 'Content-Length: '.strlen($this->postdata);
}
$request = implode("\r\n", $headers)."\r\n\r\n".$this->postdata;
return $request;
}
function getStatus() {
return $this->status;
}
function getContent() {
return $this->content;
}
function getHeaders() {
return $this->headers;
}
function getHeader($header) {
$header = strtolower($header);
if (isset($this->headers[$header])) {
return $this->headers[$header];
} else {
return false;
}
}
function getError() {
return $this->errormsg;
}
function getCookies() {
return $this->cookies;
}
function getRequestURL() {
$url = 'http://'.$this->host;
if ($this->port != 80) {
$url .= ':'.$this->port;
}
$url .= $this->path;
return $url;
}
// Setter methods
function setUserAgent($string) {
$this->user_agent = $string;
}
function setAuthorization($username, $password) {
$this->username = $username;
$this->password = $password;
}
function setCookies($array) {
$this->cookies = $array;
}
// Option setting methods
function useGzip($boolean) {
$this->use_gzip = $boolean;
}
function setPersistCookies($boolean) {
$this->persist_cookies = $boolean;
}
function setPersistReferers($boolean) {
$this->persist_referers = $boolean;
}
function setHandleRedirects($boolean) {
$this->handle_redirects = $boolean;
}
function setMaxRedirects($num) {
$this->max_redirects = $num;
}
function setHeadersOnly($boolean) {
$this->headers_only = $boolean;
}
function setDebug($boolean) {
$this->debug = $boolean;
}
// "Quick" static methods
function quickGet($url) {
$bits = parse_url($url);
$host = $bits['host'];
$port = isset($bits['port']) ? $bits['port'] : 80;
$path = isset($bits['path']) ? $bits['path'] : '/';
if (isset($bits['query'])) {
$path .= '?'.$bits['query'];
}
$client = new HttpClient($host, $port);
if (!$client->get($path)) {
return false;
} else {
return $client->getContent();
}
}
function quickPost($url, $data) {
$bits = parse_url($url);
$host = $bits['host'];
$port = isset($bits['port']) ? $bits['port'] : 80;
$path = isset($bits['path']) ? $bits['path'] : '/';
$client = new HttpClient($host, $port);
if (!$client->post($path, $data)) {
return false;
} else {
return $client->getContent();
}
}
function debug($msg, $object = false) {
if ($this->debug) {
print '<div style="border: 1px solid red; padding: 0.5em; margin: 0.5em;"><strong>HttpClient Debug:</strong> '.$msg;
if ($object) {
ob_start();
print_r($object);
$content = htmlentities(ob_get_contents());
ob_end_clean();
print '<pre>'.$content.'</pre>';
}
print '</div>';
}
}
}
-783
View File
@@ -1,783 +0,0 @@
<?php
require_once __DIR__ . '/xentral_autoloader.php';
if (class_exists(Config::class)){
$config = new Config();
$updateHost = $config->updateHost ?: 'removed.upgrade.host';
}else{
$updateHost = 'removed.upgrade.host';
}
$WAWISION['host']=$updateHost;
$WAWISION['port']="443";
$myUpd = new UpgradeClient($WAWISION,$this->app);
echo "STARTE UPDATE\n";
echo "Im folgenden stehen die Dateien die geaendert wurden.\n
Erscheinen keine Dateien sind Sie auf der neusten Version.\n";
$myUpd->Connect();
//$myUpd->CheckCRT();
$myUpd->CheckUpdate();
$myUpd->CheckUpdateCustom();
$myUpd->CheckUpdateModules();
class UpgradeClient
{
var $localmd5sums;
function __construct($conf,&$app)
{
$this->conf = $conf;
$this->app=&$app;
}
function Connect()
{
// check connection then stop
}
function CheckCRT()
{
$cert = shell_exec("openssl s_client -connect update.embedded-projects.net:443 < /dev/null 2>/dev/null | openssl x509 -in /dev/stdin");
if($cert==$this->conf['cert']."\n") return 1;
else {
echo "wrong\n";
exit;
}
}
function CheckUpdate()
{
$parameter['version']=@$this->conf['version'];
$result = $this->Request("md5list",$parameter);
if($result=="ERROR") { echo "Updates: ERROR FROM SERVER (Perhaps a wrong license?)\n"; return;}
$rows = explode(";",$result);
if(count($rows)>0)
{
foreach($rows as $value)
{
unset($single_row);
$single_row = explode(":",$value);
if(count($single_row)>=2 && strlen($single_row[0])>3 && strlen($single_row[1])>3)
{
$filename = $single_row[0];
$file = __DIR__."/".$single_row[0];
$md5sum = $single_row[1];
$parameter['file']=$filename;
$parameter['md5sum']=$md5sum;
if($file=="./upgradesystemclient.php")
{
}
else if(is_file($file))
{
// pruefe md5sum
if(md5_file($file)!=$md5sum)
{
// wenn update dann UPD_
echo "update <- $file\n";
$result = $this->Request("getfile",$parameter);
$output = (base64_decode($result));
//$output = preg_replace('/[^(\x22-\x7F)\x0A]*/','', $output);
file_put_contents($file."UPD", $output);
/*
$fp = fopen($file."UPD","wb+");
fwrite($fp,base64_decode($result));
fclose($fp);
*/
// pruefsuemme neu berechnen wenn passt umbenennen und ins archiv
echo md5_file($file."UPD");
echo "-".$md5sum."\n";
if(md5_file($file."UPD")==$md5sum)
{
echo "update ok $file\n";
rename($file."UPD",$file);
}
}
} else if($file!="") {
echo "datei <- $file\n";
// pruefe ob es verzeichnis gibt
$verzeichnis = dirname($file);
if(!is_dir($verzeichnis))
{
echo "verzeichnis <- $verzeichnis\n";
mkdir($verzeichnis,0777,true);
}
$result = $this->Request("getfile",$parameter);
$output = base64_decode($result);
//$output = iconv("UTF-8","ISO-8859-1//IGNORE",$output);
//$output = iconv("ISO-8859-1","UTF-8",$output);
//$output = preg_replace('/[^(\x20-\x7F)\x0A]*/','', $output);
file_put_contents($file."NEW", $output);
/*$fp = fopen($file."NEW","wb+");
fwrite($fp,base64_decode($result));
fclose($fp);
*/
if(md5_file($file."NEW")==$md5sum)
{
echo "datei ok $file\n";
rename($file."NEW",$file);
} else {
// echo "datei XX $file local: ".md5_file($file."NEW")." remote: ".$md5sum."\n";
}
} else { }
}
}
}
//pruefe, update, lege verzeichnis an, lege datei an, loesche datei????
// download all files with UPD_ prefix
// get md5 liste von server
// pruefe ob alle dateien passen, wenn ja dann alle updaten am schluss
// wenn nein fehler abbrechen und ganzen prozess nochmal starten
//echo $md5sums;
}
function CheckUpdateModules()
{
$parameter['version']=@$this->conf['version'];
$result = $this->Request("md5listmodules",$parameter);
if($result=="ERROR") { echo "Modules: ERROR FROM SERVER (Perhaps a wrong license?)\n"; return;}
$rows = explode(";",$result);
if(count($rows)>0)
{
foreach($rows as $value)
{
unset($single_row);
$single_row = explode(":",$value);
if(count($single_row)>=2 && strlen($single_row[0])>3 && strlen($single_row[1])>3)
{
$filename = $single_row[0];
$file = dirname(__FILE__)."/".$single_row[0];
$md5sum = $single_row[1];
$parameter['file']=$filename;
$parameter['md5sum']=$md5sum;
if($file=="./upgradesystemclient.php")
{
}
else if(is_file($file))
{
// pruefe md5sum
if(md5_file($file)!=$md5sum)
{
// wenn update dann UPD_
echo "update (M) <- $file\n";
$result = $this->Request("getfilemodules",$parameter);
$output = (base64_decode($result));
//$output = preg_replace('/[^(\x22-\x7F)\x0A]*/','', $output);
file_put_contents($file."UPD", $output);
/*
$fp = fopen($file."UPD","wb+");
fwrite($fp,base64_decode($result));
fclose($fp);
*/
// pruefsuemme neu berechnen wenn passt umbenennen und ins archiv
echo md5_file($file."UPD");
echo "-".$md5sum."\n";
if(md5_file($file."UPD")==$md5sum)
{
echo "update (M) ok $file\n";
rename($file."UPD",$file);
}
}
} else if($file!="") {
echo "datei (M) <- $file\n";
// pruefe ob es verzeichnis gibt
$verzeichnis = dirname($file);
if(!is_dir($verzeichnis))
{
echo "verzeichnis (M) <- $verzeichnis\n";
mkdir($verzeichnis,0777,true);
}
$result = $this->Request("getfilemodules",$parameter);
$output = base64_decode($result);
//$output = iconv("UTF-8","ISO-8859-1//IGNORE",$output);
//$output = iconv("ISO-8859-1","UTF-8",$output);
//$output = preg_replace('/[^(\x20-\x7F)\x0A]*/','', $output);
file_put_contents($file."NEW", $output);
/*$fp = fopen($file."NEW","wb+");
fwrite($fp,base64_decode($result));
fclose($fp);
*/
if(md5_file($file."NEW")==$md5sum)
{
echo "datei (M) ok $file\n";
rename($file."NEW",$file);
} else {
// echo "datei XX $file local: ".md5_file($file."NEW")." remote: ".$md5sum."\n";
}
} else { }
}
}
}
//pruefe, update, lege verzeichnis an, lege datei an, loesche datei????
// download all files with UPD_ prefix
// get md5 liste von server
// pruefe ob alle dateien passen, wenn ja dann alle updaten am schluss
// wenn nein fehler abbrechen und ganzen prozess nochmal starten
//echo $md5sums;
}
function CheckUpdateCustom()
{
$parameter['version']=@$this->conf['version'];
$result = $this->Request("md5listcustom",$parameter);
if($result=="ERROR") { echo "Custom: ERROR FROM SERVER (Perhaps a wrong license?)\n"; return;}
$rows = explode(";",$result);
if(count($rows)>0)
{
foreach($rows as $value)
{
unset($single_row);
$single_row = explode(":",$value);
if(count($single_row)>=2 && strlen($single_row[0])>3 && strlen($single_row[1])>3)
{
$filename = $single_row[0];
$file = __DIR__."/".$single_row[0];
$md5sum = $single_row[1];
$parameter['file']=$filename;
$parameter['md5sum']=$md5sum;
if($file=="./upgradesystemclient.php")
{
}
else if(is_file($file))
{
// pruefe md5sum
if(md5_file($file)!=$md5sum)
{
// wenn update dann UPD_
echo "update (C) <- $file\n";
$result = $this->Request("getfilecustom",$parameter);
$output = (base64_decode($result));
//$output = preg_replace('/[^(\x22-\x7F)\x0A]*/','', $output);
file_put_contents($file."UPD", $output);
/*
$fp = fopen($file."UPD","wb+");
fwrite($fp,base64_decode($result));
fclose($fp);
*/
// pruefsuemme neu berechnen wenn passt umbenennen und ins archiv
echo md5_file($file."UPD");
echo "-".$md5sum."\n";
if(md5_file($file."UPD")==$md5sum)
{
echo "update (C) ok $file\n";
rename($file."UPD",$file);
}
}
} else if($file!="") {
echo "datei (C) <- $file\n";
// pruefe ob es verzeichnis gibt
$verzeichnis = dirname($file);
if(!is_dir($verzeichnis))
{
echo "verzeichnis (C) <- $verzeichnis\n";
mkdir($verzeichnis,0777,true);
}
$result = $this->Request("getfilecustom",$parameter);
$output = base64_decode($result);
//$output = iconv("UTF-8","ISO-8859-1//IGNORE",$output);
//$output = iconv("ISO-8859-1","UTF-8",$output);
//$output = preg_replace('/[^(\x20-\x7F)\x0A]*/','', $output);
file_put_contents($file."NEW", $output);
/*$fp = fopen($file."NEW","wb+");
fwrite($fp,base64_decode($result));
fclose($fp);
*/
if(md5_file($file."NEW")==$md5sum)
{
echo "datei (C) ok $file\n";
rename($file."NEW",$file);
} else {
// echo "datei XX $file local: ".md5_file($file."NEW")." remote: ".$md5sum."\n";
}
} else { }
}
}
}
//pruefe, update, lege verzeichnis an, lege datei an, loesche datei????
// download all files with UPD_ prefix
// get md5 liste von server
// pruefe ob alle dateien passen, wenn ja dann alle updaten am schluss
// wenn nein fehler abbrechen und ganzen prozess nochmal starten
//echo $md5sums;
}
function DownloadUpdate()
{
}
function CheckDownloadedUpdate()
{
}
function ExecuteUpdate()
{
}
function Request($command,$parameter)
{
global $erp;
$auth['serial']=$this->app->erp->Firmendaten("lizenz");//$this->conf['serial'];
$auth['authkey']=$this->app->erp->Firmendaten("schluessel");//$this->conf['authkey'];
$auth = base64_encode(json_encode($auth));
$parameter = base64_encode(json_encode($parameter));
$client = new HttpClientUpgrade($this->conf['host'],$this->conf['port']);
$client->post('/upgradesystem.php', array( "authjson" => $auth, "parameterjson"=>$parameter,"command"=>"$command" ));
$pageContents = $client->getContent();
return $pageContents;
}
function dir_rekursiv($verzeichnis)
{
$handle = opendir($verzeichnis);
while ($datei = readdir($handle))
{
if ($datei != "." && $datei != "..")
{
if (is_dir($verzeichnis.$datei)) // Wenn Verzeichniseintrag ein Verzeichnis ist
{
// Erneuter Funktionsaufruf, um das aktuelle Verzeichnis auszulesen
$this->dir_rekursiv($verzeichnis.$datei.'/');
}
else
{
// Wenn Verzeichnis-Eintrag eine Datei ist, diese ausgeben
$this->localmd5sums[$verzeichnis.$datei] = md5_file($verzeichnis.$datei);
}
}
}
closedir($handle);
}
}
/* Version 0.9, 6th April 2003 - Simon Willison ( http://simon.incutio.com/ )
Manual: http://scripts.incutio.com/httpclient/
*/
class HttpClientUpgrade {
// Request vars
var $host;
var $port;
var $path;
var $method;
var $postdata = '';
var $cookies = array();
var $referer;
var $accept = 'text/xml,application/xml,application/xhtml+xml,text/html,text/plain,image/png,image/jpeg,image/gif,*/*';
var $accept_encoding = 'gzip';
var $accept_language = 'en-us';
var $user_agent = 'Incutio HttpClientUpgrade v0.9';
// Options
var $timeout = 20;
var $use_gzip = true;
var $persist_cookies = true; // If true, received cookies are placed in the $this->cookies array ready for the next request
// Note: This currently ignores the cookie path (and time) completely. Time is not important,
// but path could possibly lead to security problems.
var $persist_referers = true; // For each request, sends path of last request as referer
var $debug = false;
var $handle_redirects = true; // Auaomtically redirect if Location or URI header is found
var $max_redirects = 5;
var $headers_only = false; // If true, stops receiving once headers have been read.
// Basic authorization variables
var $username;
var $password;
// Response vars
var $status;
var $headers = array();
var $content = '';
var $errormsg;
// Tracker variables
var $redirect_count = 0;
var $cookie_host = '';
function __construct($host, $port=80) {
$this->host = $host;
$this->port = $port;
}
function get($path, $data = false) {
$this->path = $path;
$this->method = 'GET';
if ($data) {
$this->path .= '?'.$this->buildQueryString($data);
}
return $this->doRequest();
}
function post($path, $data) {
$this->path = $path;
$this->method = 'POST';
$this->postdata = $this->buildQueryString($data);
return $this->doRequest();
}
function buildQueryString($data) {
$querystring = '';
if (is_array($data)) {
// Change data in to postable data
foreach ($data as $key => $val) {
if (is_array($val)) {
foreach ($val as $val2) {
$querystring .= urlencode($key).'='.urlencode($val2).'&';
}
} else {
$querystring .= urlencode($key).'='.urlencode($val).'&';
}
}
$querystring = substr($querystring, 0, -1); // Eliminate unnecessary &
} else {
$querystring = $data;
}
return $querystring;
}
function doRequest() {
// Performs the actual HTTP request, returning true or false depending on outcome
// check if port is available
if(!fsockopen("ssl://".$this->host, $this->port, $errno, $errstr, $this->timeout) && $this->port==443)
{
$this->port=80;
}
if($this->port==443)
$url = "ssl://".$this->host;
else
$url = $this->host;
if (!$fp = @fsockopen($url, $this->port, $errno, $errstr, $this->timeout)) {
// Set error message
switch($errno) {
case -3:
$this->errormsg = 'Socket creation failed (-3)';
case -4:
$this->errormsg = 'DNS lookup failure (-4)';
case -5:
$this->errormsg = 'Connection refused or timed out (-5)';
default:
$this->errormsg = 'Connection failed ('.$errno.')';
$this->errormsg .= ' '.$errstr;
$this->debug($this->errormsg);
}
return false;
}
stream_set_timeout($fp, $this->timeout);
$request = $this->buildRequest();
$this->debug('Request', $request);
fwrite($fp, $request);
// Reset all the variables that should not persist between requests
$this->headers = array();
$this->content = '';
$this->errormsg = '';
// Set a couple of flags
$inHeaders = true;
$atStart = true;
// Now start reading back the response
while (!feof($fp)) {
$line = fgets($fp, 4096);
if ($atStart) {
// Deal with first line of returned data
$atStart = false;
if (!preg_match('/HTTP\/(\\d\\.\\d)\\s*(\\d+)\\s*(.*)/', $line, $m)) {
$this->errormsg = "Status code line invalid: ".htmlentities($line);
$this->debug($this->errormsg);
//return false;
}
$http_version = $m[1]; // not used
$this->status = $m[2];
$status_string = $m[3]; // not used
$this->debug(trim($line));
continue;
}
if ($inHeaders) {
if (trim($line) == '') {
$inHeaders = false;
$this->debug('Received Headers', $this->headers);
if ($this->headers_only) {
break; // Skip the rest of the input
}
continue;
}
if (!preg_match('/([^:]+):\\s*(.*)/', $line, $m)) {
// Skip to the next header
continue;
}
$key = strtolower(trim($m[1]));
$val = trim($m[2]);
// Deal with the possibility of multiple headers of same name
if (isset($this->headers[$key])) {
if (is_array($this->headers[$key])) {
$this->headers[$key][] = $val;
} else {
$this->headers[$key] = array($this->headers[$key], $val);
}
} else {
$this->headers[$key] = $val;
}
continue;
}
// We're not in the headers, so append the line to the contents
$this->content .= $line;
}
fclose($fp);
// If data is compressed, uncompress it
if (isset($this->headers['content-encoding']) && $this->headers['content-encoding'] == 'gzip') {
$this->debug('Content is gzip encoded, unzipping it');
$this->content = substr($this->content, 10); // See http://www.php.net/manual/en/function.gzencode.php
$this->content = gzinflate($this->content);
}
// If $persist_cookies, deal with any cookies
if ($this->persist_cookies && isset($this->headers['set-cookie']) && $this->host == $this->cookie_host) {
$cookies = $this->headers['set-cookie'];
if (!is_array($cookies)) {
$cookies = array($cookies);
}
foreach ($cookies as $cookie) {
if (preg_match('/([^=]+)=([^;]+);/', $cookie, $m)) {
$this->cookies[$m[1]] = $m[2];
}
}
// Record domain of cookies for security reasons
$this->cookie_host = $this->host;
}
// If $persist_referers, set the referer ready for the next request
if ($this->persist_referers) {
$this->debug('Persisting referer: '.$this->getRequestURL());
$this->referer = $this->getRequestURL();
}
// Finally, if handle_redirects and a redirect is sent, do that
if ($this->handle_redirects) {
if (++$this->redirect_count >= $this->max_redirects) {
$this->errormsg = 'Number of redirects exceeded maximum ('.$this->max_redirects.')';
$this->debug($this->errormsg);
$this->redirect_count = 0;
return false;
}
$location = isset($this->headers['location']) ? $this->headers['location'] : '';
$uri = isset($this->headers['uri']) ? $this->headers['uri'] : '';
if ($location || $uri) {
$url = parse_url($location.$uri);
// This will FAIL if redirect is to a different site
return $this->get($url['path']);
}
}
return true;
}
function buildRequest() {
$headers = array();
$headers[] = "{$this->method} {$this->path} HTTP/1.0"; // Using 1.1 leads to all manner of problems, such as "chunked" encoding
$headers[] = "Host: {$this->host}";
$headers[] = "User-Agent: {$this->user_agent}";
$headers[] = "Accept: {$this->accept}";
if ($this->use_gzip) {
$headers[] = "Accept-encoding: {$this->accept_encoding}";
}
$headers[] = "Accept-language: {$this->accept_language}";
if ($this->referer) {
$headers[] = "Referer: {$this->referer}";
}
// Cookies
if ($this->cookies) {
$cookie = 'Cookie: ';
foreach ($this->cookies as $key => $value) {
$cookie .= "$key=$value; ";
}
$headers[] = $cookie;
}
// Basic authentication
if ($this->username && $this->password) {
$headers[] = 'Authorization: BASIC '.base64_encode($this->username.':'.$this->password);
}
// If this is a POST, set the content type and length
if ($this->postdata) {
$headers[] = 'Content-Type: application/x-www-form-urlencoded';
$headers[] = 'Content-Length: '.strlen($this->postdata);
}
$request = implode("\r\n", $headers)."\r\n\r\n".$this->postdata;
return $request;
}
function getStatus() {
return $this->status;
}
function getContent() {
return $this->content;
}
function getHeaders() {
return $this->headers;
}
function getHeader($header) {
$header = strtolower($header);
if (isset($this->headers[$header])) {
return $this->headers[$header];
} else {
return false;
}
}
function getError() {
return $this->errormsg;
}
function getCookies() {
return $this->cookies;
}
function getRequestURL() {
$url = 'http://'.$this->host;
if ($this->port != 80) {
$url .= ':'.$this->port;
}
$url .= $this->path;
return $url;
}
// Setter methods
function setUserAgent($string) {
$this->user_agent = $string;
}
function setAuthorization($username, $password) {
$this->username = $username;
$this->password = $password;
}
function setCookies($array) {
$this->cookies = $array;
}
// Option setting methods
function useGzip($boolean) {
$this->use_gzip = $boolean;
}
function setPersistCookies($boolean) {
$this->persist_cookies = $boolean;
}
function setPersistReferers($boolean) {
$this->persist_referers = $boolean;
}
function setHandleRedirects($boolean) {
$this->handle_redirects = $boolean;
}
function setMaxRedirects($num) {
$this->max_redirects = $num;
}
function setHeadersOnly($boolean) {
$this->headers_only = $boolean;
}
function setDebug($boolean) {
$this->debug = $boolean;
}
// "Quick" static methods
function quickGet($url) {
$bits = parse_url($url);
$host = $bits['host'];
$port = isset($bits['port']) ? $bits['port'] : 80;
$path = isset($bits['path']) ? $bits['path'] : '/';
if (isset($bits['query'])) {
$path .= '?'.$bits['query'];
}
$client = new HttpClientUpgrade($host, $port);
if (!$client->get($path)) {
return false;
} else {
return $client->getContent();
}
}
function quickPost($url, $data) {
$bits = parse_url($url);
$host = $bits['host'];
$port = isset($bits['port']) ? $bits['port'] : 80;
$path = isset($bits['path']) ? $bits['path'] : '/';
$client = new HttpClientUpgrade($host, $port);
if (!$client->post($path, $data)) {
return false;
} else {
return $client->getContent();
}
}
function debug($msg, $object = false) {
if ($this->debug) {
print '<div style="border: 1px solid red; padding: 0.5em; margin: 0.5em;"><strong>HttpClientUpgrade Debug:</strong> '.$msg;
if ($object) {
ob_start();
print_r($object);
$content = htmlentities(ob_get_contents());
ob_end_clean();
print '<pre>'.$content.'</pre>';
}
print '</div>';
}
}
}
-928
View File
@@ -1,928 +0,0 @@
<?php
require_once __DIR__ . '/xentral_autoloader.php';
if (class_exists(Config::class)){
$config = new Config();
$updateHost = $config->updateHost ?: 'removed.upgrade.host';
}else{
$updateHost = 'removed.upgrade.host';
}
define('XENTRAL_UPDATE_HOST', $updateHost);
$WAWISION['host']=XENTRAL_UPDATE_HOST;
$WAWISION['port']="443";
$myUpd = new UpgradeClient($WAWISION,$this->app);
$myUpd->Connect();
if(isset($sendStats)) {
}
elseif(isset($buy)) {
}
elseif(isset($getBuyList)) {
}
elseif(isset($getBuyInfo)) {
}
elseif(isset($setBeta)) {
}
elseif(isset($setDevelopmentVersion)) {
}
elseif(isset($buyFromDemo)) {
}
elseif(isset($resetXentral)) {
}
elseif(isset($fiskalyCommand)) {
}
elseif(isset($createFiskalyClientFromClientId) && isset($tseId) && isset($organizationId)) {
}
elseif(isset($sma) && isset($sendSmaErrorMessage)) {
}
else{
}
if(!class_exists('Md5Dateien'))
{
class Md5Dateien
{
var $Dateien;
function __construct($quellverzeichnis)
{
$this->getVerzeichnis($quellverzeichnis, '', 0, '');
}
function getVerzeichnis($quellverzeichnis, $zielverzeichnis, $lvl, $relativ){
//echo "Verzeichnis: ".$quellverzeichnis." ".$zielverzeichnis. "\r\n";
$quelllast = $quellverzeichnis;
if($quellverzeichnis[strlen($quellverzeichnis) - 1] == '/')$quelllast = substr($quellverzeichnis, 0, strlen($quellverzeichnis) - 1);
$path_parts = pathinfo($quelllast);
$quelllast = $path_parts['basename'];
if(file_exists($quellverzeichnis))
{
if($quelllast != 'importer' || $lvl != 1){
if ($handle = opendir($quellverzeichnis)) {
while (false !== ($entry = readdir($handle))) {
if($entry != '.' && $entry != '..' && $entry != '.git' && $entry != '.svn' && $entry != 'main.conf.php' && $entry != 'user.inc.php' && $entry != 'user_db_version.php' && $entry != 'pygen')
{
if(is_dir($quellverzeichnis.'/'.$entry))
{
if(!($lvl == 1 && $entry == 'vorlagen' && strpos($quellverzeichnis,'www')))
$this->getVerzeichnis($quellverzeichnis.(strrpos($quellverzeichnis,'/')!==strlen($quellverzeichnis)-1?'/':'').$entry,$zielverzeichnis .(strrpos($zielverzeichnis,'/')!==strlen($zielverzeichnis)-1?'/':'').$entry, $lvl + 1,$relativ.'/'.$entry);
} else {
if(!($lvl == 0 && ($entry == 'INSTALL' || $entry == 'LICENSE_LIST' || $entry == 'LICENSE' || $entry == 'README' || $entry == 'gitlog.txt')))
{
//$this->getFile($quellverzeichnis.(strrpos($quellverzeichnis,'/')!==strlen($quellverzeichnis)-1?'/':'').$entry,$zielverzeichnis .(strrpos($zielverzeichnis,'/')!==strlen($zielverzeichnis)-1?'/':'').$entry,$relativ.'/'.$entry);
if(strtolower(substr($entry,-4)) == '.php')$this->Dateien[$relativ.'/'.$entry] = md5_file($quellverzeichnis.(strrpos($quellverzeichnis,'/')!==strlen($quellverzeichnis)-1?'/':'').$entry);
}
}
}
}
@closedir($handle);
} else {
}
}
} else {
}
return true;
}
}
}
class UpgradeClient
{
var $localmd5sums;
/**
* UpgradeClient constructor.
*
* @param Config $conf
* @param ApplicationCore $app
*/
public function __construct($conf, $app)
{
$this->conf = $conf;
$this->app = $app;
}
function Connect()
{
// check connection then stop
}
function CheckCRT()
{
$updateHost = XENTRAL_UPDATE_HOST;
$cert = shell_exec("openssl s_client -connect {$updateHost}:443 < /dev/null 2>/dev/null | openssl x509 -in /dev/stdin");
if($cert==$this->conf['cert']."\n") return 1;
else {
echo "wrong\n";
exit;
}
}
function CheckUpdate()
{
//$this->dir_rekursiv("./");
//$parameter['md5sums'] = $this->localmd5sums;
//shell_exec('find ./ -exec md5sum "{}" \;');
$lines = null;
$funktions_ind = null;
$dateien = new Md5Dateien(__DIR__.'/');
if(!empty($dateien->Dateien) && is_array($dateien->Dateien)) {
foreach($dateien->Dateien as $k => $v) {
if(
strtolower(substr($k,-4)) === '.php'
&& strpos($k, '_custom') !== false
&& strpos($k,'/vendor/') === false
) {
$datei = __DIR__.$k;
if(!file_exists($datei)) {
continue;
}
$fh = fopen($datei, 'r');
if(!$fh) {
continue;
}
$f_ind = -1;
if(isset($lines)) {
unset($lines);
}
$i = -1;
while(($line = fgets($fh)) !== false) {
$i++;
$lines[$i] = $line;
if(isset($funktions_ind) && isset($funktions_ind[$k])) {
foreach($funktions_ind[$k] as $k2 => $v2) {
if($v2 + 5 >= $i) {
$funktions[$k][$k2][] = $line;
}
}
}
if(strpos($line, 'function') !== false) {
$f_ind++;
for($j = $i-5; $j <= $i; $j++) {
if($j > -1) {
$funktions[$k][$f_ind][] = $lines[$j];
}
}
$funktions_ind[$k][$f_ind] = $i;
}
}
fclose($fh);
}
}
}
$parameter['version'] = @$this->conf['version'];
if(isset($funktions)) {
$parameter['funktionen'] = $funktions;
$this->Request("versionen", $parameter);
}
if (is_file(__DIR__ . '/marketing_labels.txt')) {
$parameter['marketing_labels'] = explode(',', (string)@file_get_contents(__DIR__ . '/marketing_labels.txt'));
}
$result = $this->Request("md5list",$parameter);
if($result==="ERROR") {
echo "Updates: ERROR FROM SERVER (Perhaps a wrong license?)\n";
return;
}
$rows = explode(";",$result);
if(count($rows)>0)
{
foreach($rows as $value)
{
unset($single_row);
$single_row = explode(":",$value);
if(count($single_row)>=2 && strlen($single_row[0])>3 && strlen($single_row[1])>3)
{
$filename = $single_row[0];
$file = __DIR__."/".$single_row[0];
$md5sum = $single_row[1];
$parameter['file']=$filename;
$parameter['md5sum']=$md5sum;
if($file==="./upgradesystemclient.php")
{
}
else if(is_file($file))
{
// pruefe md5sum
if(md5_file($file)!=$md5sum)
{
// wenn update dann UPD_
echo "update <- $file\n";
$result = $this->Request("getfile",$parameter);
$output = (base64_decode($result));
//$output = preg_replace('/[^(\x22-\x7F)\x0A]*/','', $output);
file_put_contents($file."UPD", $output);
/*
$fp = fopen($file."UPD","wb+");
fwrite($fp,base64_decode($result));
fclose($fp);
*/
// pruefsuemme neu berechnen wenn passt umbenennen und ins archiv
echo md5_file($file."UPD");
echo "-".$md5sum."\n";
if(md5_file($file."UPD")==$md5sum)
{
echo "update ok $file\n";
rename($file."UPD",$file);
}
}
} else if($file!="") {
echo "datei <- $file\n";
// pruefe ob es verzeichnis gibt
$verzeichnis = dirname($file);
if(!is_dir($verzeichnis))
{
echo "verzeichnis <- $verzeichnis\n";
mkdir($verzeichnis,0777,true);
}
$result = $this->Request("getfile",$parameter);
$output = base64_decode($result);
//$output = iconv("UTF-8","ISO-8859-1//IGNORE",$output);
//$output = iconv("ISO-8859-1","UTF-8",$output);
//$output = preg_replace('/[^(\x20-\x7F)\x0A]*/','', $output);
file_put_contents($file."NEW", $output);
/*$fp = fopen($file."NEW","wb+");
fwrite($fp,base64_decode($result));
fclose($fp);
*/
if(md5_file($file."NEW")==$md5sum)
{
echo "datei ok $file\n";
rename($file."NEW",$file);
} else {
// echo "datei XX $file local: ".md5_file($file."NEW")." remote: ".$md5sum."\n";
}
} else { }
}
}
}
//pruefe, update, lege verzeichnis an, lege datei an, loesche datei????
// download all files with UPD_ prefix
// get md5 liste von server
// pruefe ob alle dateien passen, wenn ja dann alle updaten am schluss
// wenn nein fehler abbrechen und ganzen prozess nochmal starten
//echo $md5sums;
}
function CheckUpdateModules()
{
$parameter['version']=@$this->conf['version'];
$result = $this->Request("md5listmodules",$parameter);
if($result=="ERROR") { echo "Modules: ERROR FROM SERVER (Perhaps a wrong license?)\n"; return;}
$rows = explode(";",$result);
if(count($rows)>0)
{
foreach($rows as $value)
{
unset($single_row);
$single_row = explode(":",$value);
if(count($single_row)>=2 && strlen($single_row[0])>3 && strlen($single_row[1])>3)
{
$filename = $single_row[0];
$file = dirname(__FILE__)."/".$single_row[0];
$md5sum = $single_row[1];
$parameter['file']=$filename;
$parameter['md5sum']=$md5sum;
if($file=="./upgradesystemclient.php")
{
}
else if(is_file($file))
{
// pruefe md5sum
if(md5_file($file)!=$md5sum)
{
// wenn update dann UPD_
echo "update (M) <- $file\n";
$result = $this->Request("getfilemodules",$parameter);
$output = (base64_decode($result));
//$output = preg_replace('/[^(\x22-\x7F)\x0A]*/','', $output);
file_put_contents($file."UPD", $output);
/*
$fp = fopen($file."UPD","wb+");
fwrite($fp,base64_decode($result));
fclose($fp);
*/
// pruefsuemme neu berechnen wenn passt umbenennen und ins archiv
echo md5_file($file."UPD");
echo "-".$md5sum."\n";
if(md5_file($file."UPD")==$md5sum)
{
echo "update (M) ok $file\n";
rename($file."UPD",$file);
}
}
} else if($file!="") {
echo "datei (M) <- $file\n";
// pruefe ob es verzeichnis gibt
$verzeichnis = dirname($file);
if(!is_dir($verzeichnis))
{
echo "verzeichnis (M) <- $verzeichnis\n";
mkdir($verzeichnis,0777,true);
}
$result = $this->Request("getfilemodules",$parameter);
$output = base64_decode($result);
//$output = iconv("UTF-8","ISO-8859-1//IGNORE",$output);
//$output = iconv("ISO-8859-1","UTF-8",$output);
//$output = preg_replace('/[^(\x20-\x7F)\x0A]*/','', $output);
file_put_contents($file."NEW", $output);
/*$fp = fopen($file."NEW","wb+");
fwrite($fp,base64_decode($result));
fclose($fp);
*/
if(md5_file($file."NEW")==$md5sum)
{
echo "datei (M) ok $file\n";
rename($file."NEW",$file);
} else {
// echo "datei XX $file local: ".md5_file($file."NEW")." remote: ".$md5sum."\n";
}
} else { }
}
}
}
//pruefe, update, lege verzeichnis an, lege datei an, loesche datei????
// download all files with UPD_ prefix
// get md5 liste von server
// pruefe ob alle dateien passen, wenn ja dann alle updaten am schluss
// wenn nein fehler abbrechen und ganzen prozess nochmal starten
//echo $md5sums;
}
/**
* @param array $data
*
* @return string|null
*/
public function sendSetDevelopmentStatus($data)
{
$parameter['version'] = isset($this->conf['version']) ? $this->conf['version']: null;
$parameter['data'] = $data;
return $this->Request('setdevelopmentversion', $parameter);
}
/**
* @param array $data
*
* @return string|null
*/
public function sendSetBetaStatus($data)
{
$parameter['version'] = isset($this->conf['version']) ? $this->conf['version']: null;
$parameter['data'] = $data;
return $this->Request('setbeta', $parameter);
}
function CheckUpdateKey()
{
$parameter['SERVER_NAME'] = $_SERVER['SERVER_NAME'];
if(!empty($_SERVER['HTTP_HOST']) && (empty($parameter['SERVER_NAME']) || $parameter['SERVER_NAME'] === '_')) {
$parameter['SERVER_NAME'] = $_SERVER['HTTP_HOST'];
}
$parameter['phpversion'] = (String)phpversion();
$parameter['mysqlversion'] = $this->app->DB->GetVersion();
$parameter['version']=@$this->conf['version'];
$result = $this->Request('md5listcustom',$parameter);
if($result==='ERROR') {
return false;
}
$rows = explode(';',$result);
$return = false;
if(count($rows) <= 0) {
return false;
}
foreach($rows as $value) {
unset($single_row);
$single_row = explode(':',$value);
if(count($single_row)>=2 && strlen($single_row[0])>3 && strlen($single_row[1])>3) {
$filename = $single_row[0];
$file = __DIR__.'/'.$single_row[0];
$md5sum = $single_row[1];
$parameter['file']=$filename;
$parameter['md5sum']=$md5sum;
$fileOk = $filename === './key.php';
if(!$fileOk && strpos($md5sum, 'DEL') === false) {
if($filename === './www/themes/new/templates/loginslider.tpl') {
$fileOk = true;
}
elseif(strpos($filename ,'./www/themes/new/templates/') === 0
&& (substr($filename,-4) === '.jpg' || substr($filename,-5) === '.jpeg')
&& strpos($filename, '/', 28) === false) {
$fileOk = true;
}
}
if(!$fileOk) {
continue;
}
if(is_file($file)) {
// pruefe md5sum
if(md5_file($file)!=$md5sum) {
// wenn update dann UPD_
$result = $this->Request('getfilecustom',$parameter);
$output = (base64_decode($result));
file_put_contents($file.'UPD', $output);
if(md5_file($file.'UPD')==$md5sum && $result) {
$return = rename($file.'UPD',$file);
}
}
else {
$return = true;
}
continue;
}
// pruefe ob es verzeichnis gibt
$verzeichnis = dirname($file);
if(!is_dir($verzeichnis) && !mkdir($verzeichnis,0777,true) && !is_dir($verzeichnis)) {
}
$result = $this->Request('getfilecustom',$parameter);
$output = base64_decode($result);
file_put_contents($file.'NEW', $output);
if(md5_file($file.'NEW')==$md5sum) {
$return = rename($file.'NEW',$file);
}
}
}
return $return;
}
function DownloadUpdate()
{
}
function CheckDownloadedUpdate()
{
}
function ExecuteUpdate()
{
}
function Request($command,$parameter)
{
global $erp;
$auth['serial']=$this->app->erp->Firmendaten("lizenz");//$this->conf['serial'];
$auth['authkey']=$this->app->erp->Firmendaten("schluessel");//$this->conf['authkey'];
$auth['SERVER_NAME'] = (isset($_SERVER['SERVER_NAME']) && $_SERVER['SERVER_NAME'] != '')?$_SERVER['SERVER_NAME']:(isset($_SERVER['HTTP_HOST'])?$_SERVER['HTTP_HOST']:'');
$auth = base64_encode(json_encode($auth));
$parameter = base64_encode(json_encode($parameter));
$client = new HttpClientUpgrade($this->conf['host'],$this->conf['port']);
$client->post('/upgradesystem.php', array( "authjson" => $auth, "parameterjson"=>$parameter,"command"=>"$command" ));
$pageContents = $client->getContent();
return $pageContents;
}
function dir_rekursiv($verzeichnis)
{
$handle = opendir($verzeichnis);
while ($datei = readdir($handle))
{
if ($datei != "." && $datei != "..")
{
if (is_dir($verzeichnis.$datei)) // Wenn Verzeichniseintrag ein Verzeichnis ist
{
// Erneuter Funktionsaufruf, um das aktuelle Verzeichnis auszulesen
$this->dir_rekursiv($verzeichnis.$datei.'/');
}
else
{
// Wenn Verzeichnis-Eintrag eine Datei ist, diese ausgeben
$this->localmd5sums[$verzeichnis.$datei] = md5_file($verzeichnis.$datei);
}
}
}
closedir($handle);
}
}
/* Version 0.9, 6th April 2003 - Simon Willison ( http://simon.incutio.com/ )
Manual: http://scripts.incutio.com/httpclient/
*/
class HttpClientUpgrade {
// Request vars
var $host;
var $port;
var $path;
var $method;
var $postdata = '';
var $cookies = array();
var $referer;
var $accept = 'text/xml,application/xml,application/xhtml+xml,text/html,text/plain,image/png,image/jpeg,image/gif,*/*';
var $accept_encoding = 'gzip';
var $accept_language = 'en-us';
var $user_agent = 'Incutio HttpClientUpgrade v0.9';
// Options
var $timeout = 20;
var $use_gzip = true;
var $persist_cookies = true; // If true, received cookies are placed in the $this->cookies array ready for the next request
// Note: This currently ignores the cookie path (and time) completely. Time is not important,
// but path could possibly lead to security problems.
var $persist_referers = true; // For each request, sends path of last request as referer
var $debug = false;
var $handle_redirects = true; // Auaomtically redirect if Location or URI header is found
var $max_redirects = 5;
var $headers_only = false; // If true, stops receiving once headers have been read.
// Basic authorization variables
var $username;
var $password;
// Response vars
var $status;
var $headers = array();
var $content = '';
var $errormsg;
// Tracker variables
var $redirect_count = 0;
var $cookie_host = '';
function __construct($host, $port=80) {
$this->host = $host;
$this->port = $port;
}
function get($path, $data = false) {
$this->path = $path;
$this->method = 'GET';
if ($data) {
$this->path .= '?'.$this->buildQueryString($data);
}
return $this->doRequest();
}
function post($path, $data) {
$this->path = $path;
$this->method = 'POST';
$this->postdata = $this->buildQueryString($data);
return $this->doRequest();
}
function buildQueryString($data) {
$querystring = '';
if (is_array($data)) {
// Change data in to postable data
foreach ($data as $key => $val) {
if (is_array($val)) {
foreach ($val as $val2) {
$querystring .= urlencode($key).'='.urlencode($val2).'&';
}
} else {
$querystring .= urlencode($key).'='.urlencode($val).'&';
}
}
$querystring = substr($querystring, 0, -1); // Eliminate unnecessary &
} else {
$querystring = $data;
}
return $querystring;
}
function doRequest() {
// Performs the actual HTTP request, returning true or false depending on outcome
// check if port is available
if(!fsockopen("ssl://".$this->host, $this->port, $errno, $errstr, $this->timeout) && $this->port==443)
{
$this->port=80;
}
if($this->port==443)
$url = "ssl://".$this->host;
else
$url = $this->host;
if (!$fp = @fsockopen($url, $this->port, $errno, $errstr, $this->timeout)) {
// Set error message
switch($errno) {
case -3:
$this->errormsg = 'Socket creation failed (-3)';
case -4:
$this->errormsg = 'DNS lookup failure (-4)';
case -5:
$this->errormsg = 'Connection refused or timed out (-5)';
default:
$this->errormsg = 'Connection failed ('.$errno.')';
$this->errormsg .= ' '.$errstr;
$this->debug($this->errormsg);
}
return false;
}
socket_set_timeout($fp, $this->timeout);
$request = $this->buildRequest();
$this->debug('Request', $request);
fwrite($fp, $request);
// Reset all the variables that should not persist between requests
$this->headers = array();
$this->content = '';
$this->errormsg = '';
// Set a couple of flags
$inHeaders = true;
$atStart = true;
// Now start reading back the response
while (!feof($fp)) {
$line = fgets($fp, 4096);
if ($atStart) {
// Deal with first line of returned data
$atStart = false;
if (!preg_match('/HTTP\/(\\d\\.\\d)\\s*(\\d+)\\s*(.*)/', $line, $m)) {
$this->errormsg = "Status code line invalid: ".htmlentities($line);
$this->debug($this->errormsg);
//return false;
}
$http_version = $m[1]; // not used
$this->status = $m[2];
$status_string = $m[3]; // not used
$this->debug(trim($line));
continue;
}
if ($inHeaders) {
if (trim($line) == '') {
$inHeaders = false;
$this->debug('Received Headers', $this->headers);
if ($this->headers_only) {
break; // Skip the rest of the input
}
continue;
}
if (!preg_match('/([^:]+):\\s*(.*)/', $line, $m)) {
// Skip to the next header
continue;
}
$key = strtolower(trim($m[1]));
$val = trim($m[2]);
// Deal with the possibility of multiple headers of same name
if (isset($this->headers[$key])) {
if (is_array($this->headers[$key])) {
$this->headers[$key][] = $val;
} else {
$this->headers[$key] = array($this->headers[$key], $val);
}
} else {
$this->headers[$key] = $val;
}
continue;
}
// We're not in the headers, so append the line to the contents
$this->content .= $line;
}
fclose($fp);
// If data is compressed, uncompress it
if (isset($this->headers['content-encoding']) && $this->headers['content-encoding'] == 'gzip') {
$this->debug('Content is gzip encoded, unzipping it');
$this->content = substr($this->content, 10); // See http://www.php.net/manual/en/function.gzencode.php
$this->content = gzinflate($this->content);
}
// If $persist_cookies, deal with any cookies
if ($this->persist_cookies && isset($this->headers['set-cookie']) && $this->host == $this->cookie_host) {
$cookies = $this->headers['set-cookie'];
if (!is_array($cookies)) {
$cookies = array($cookies);
}
foreach ($cookies as $cookie) {
if (preg_match('/([^=]+)=([^;]+);/', $cookie, $m)) {
$this->cookies[$m[1]] = $m[2];
}
}
// Record domain of cookies for security reasons
$this->cookie_host = $this->host;
}
// If $persist_referers, set the referer ready for the next request
if ($this->persist_referers) {
$this->debug('Persisting referer: '.$this->getRequestURL());
$this->referer = $this->getRequestURL();
}
// Finally, if handle_redirects and a redirect is sent, do that
if ($this->handle_redirects) {
if (++$this->redirect_count >= $this->max_redirects) {
$this->errormsg = 'Number of redirects exceeded maximum ('.$this->max_redirects.')';
$this->debug($this->errormsg);
$this->redirect_count = 0;
return false;
}
$location = isset($this->headers['location']) ? $this->headers['location'] : '';
$uri = isset($this->headers['uri']) ? $this->headers['uri'] : '';
if ($location || $uri) {
$url = parse_url($location.$uri);
// This will FAIL if redirect is to a different site
return $this->get($url['path']);
}
}
return true;
}
function buildRequest() {
$headers = array();
$headers[] = "{$this->method} {$this->path} HTTP/1.0"; // Using 1.1 leads to all manner of problems, such as "chunked" encoding
$headers[] = "Host: {$this->host}";
$headers[] = "User-Agent: {$this->user_agent}";
$headers[] = "Accept: {$this->accept}";
if ($this->use_gzip) {
$headers[] = "Accept-encoding: {$this->accept_encoding}";
}
$headers[] = "Accept-language: {$this->accept_language}";
if ($this->referer) {
$headers[] = "Referer: {$this->referer}";
}
// Cookies
if ($this->cookies) {
$cookie = 'Cookie: ';
foreach ($this->cookies as $key => $value) {
$cookie .= "$key=$value; ";
}
$headers[] = $cookie;
}
// Basic authentication
if ($this->username && $this->password) {
$headers[] = 'Authorization: BASIC '.base64_encode($this->username.':'.$this->password);
}
// If this is a POST, set the content type and length
if ($this->postdata) {
$headers[] = 'Content-Type: application/x-www-form-urlencoded';
$headers[] = 'Content-Length: '.strlen($this->postdata);
}
$request = implode("\r\n", $headers)."\r\n\r\n".$this->postdata;
return $request;
}
function getStatus() {
return $this->status;
}
function getContent() {
return $this->content;
}
function getHeaders() {
return $this->headers;
}
function getHeader($header) {
$header = strtolower($header);
if (isset($this->headers[$header])) {
return $this->headers[$header];
} else {
return false;
}
}
function getError() {
return $this->errormsg;
}
function getCookies() {
return $this->cookies;
}
function getRequestURL() {
$url = 'http://'.$this->host;
if ($this->port != 80) {
$url .= ':'.$this->port;
}
$url .= $this->path;
return $url;
}
// Setter methods
function setUserAgent($string) {
$this->user_agent = $string;
}
function setAuthorization($username, $password) {
$this->username = $username;
$this->password = $password;
}
function setCookies($array) {
$this->cookies = $array;
}
// Option setting methods
function useGzip($boolean) {
$this->use_gzip = $boolean;
}
function setPersistCookies($boolean) {
$this->persist_cookies = $boolean;
}
function setPersistReferers($boolean) {
$this->persist_referers = $boolean;
}
function setHandleRedirects($boolean) {
$this->handle_redirects = $boolean;
}
function setMaxRedirects($num) {
$this->max_redirects = $num;
}
function setHeadersOnly($boolean) {
$this->headers_only = $boolean;
}
function setDebug($boolean) {
$this->debug = $boolean;
}
// "Quick" static methods
function quickGet($url) {
$bits = parse_url($url);
$host = $bits['host'];
$port = isset($bits['port']) ? $bits['port'] : 80;
$path = isset($bits['path']) ? $bits['path'] : '/';
if (isset($bits['query'])) {
$path .= '?'.$bits['query'];
}
$client = new HttpClientUpgrade($host, $port);
if (!$client->get($path)) {
return false;
} else {
return $client->getContent();
}
}
function quickPost($url, $data) {
$bits = parse_url($url);
$host = $bits['host'];
$port = isset($bits['port']) ? $bits['port'] : 80;
$path = isset($bits['path']) ? $bits['path'] : '/';
$client = new HttpClientUpgrade($host, $port);
if (!$client->post($path, $data)) {
return false;
} else {
return $client->getContent();
}
}
function debug($msg, $object = false) {
if ($this->debug) {
print '<div style="border: 1px solid red; padding: 0.5em; margin: 0.5em;"><strong>HttpClientUpgrade Debug:</strong> '.$msg;
if ($object) {
ob_start();
print_r($object);
$content = htmlentities(ob_get_contents());
ob_end_clean();
print '<pre>'.$content.'</pre>';
}
print '</div>';
}
}
}
+747
View File
@@ -0,0 +1,747 @@
<?php
/*
MUSTAL Mysql Upgrade Schema Tool by Alex Ledis
Helper to compare database structures from JSON files vs. database and upgrade database
Copyright (c) 2022 Alex Ledis
Licensed under AGPL v3
Version 1.0
function mustal_load_tables_from_db(string $host, string $schema, string $user, string $passwd, $replacers) : array
Load structure from db connection to an array.
function mustal_save_tables_to_json(array $db_def, string $path, string $tables_file_name, bool $force) : int
Save structure from array to a JSON file.
function mustal_load_tables_from_json(string $path, string $tables_file_name) : array
Load structure from JSON file into array.
function mustal_compare_table_array(array $nominal, string $nominal_name, array $actual, string $actual_name, bool $check_column_definitions) : array
Compare two database structures
Returns a structured array containing information on all the differences.
function mustal_calculate_db_upgrade(array $compare_def, array $db_def, array &$upgrade_sql) : int
Generate the SQL needed to upgrade the database to match the definition, based on a comparison.
Data structure in Array and JSON
{
"host": "hostname",
"database": "schemaname",
"user": "username",
"tables": [
{
"name": "",
"type": "",
"columns": [
{
"Field": "",
"Type": "",
"Collation": "",
"Null": "",
"Key": "",
"Default": "",
"Extra": "",
"Privileges": "",
"Comment": ""
}
],
"keys": [
{
"Key_name": "",
"columns": [
"",
""
]
}
]
}
]
}
*/
// These default values will not be in quotes, converted to lowercase and be replaced by the second entry
$mustal_replacers = [
['current_timestamp','current_timestamp()'],
['on update current_timestamp','on update current_timestamp()']
];
// Load all db_def from a DB connection into a db_def array
function mustal_load_tables_from_db(string $host, string $schema, string $user, string $passwd, $replacers) : array {
// First get the contents of the database table structure
$mysqli = mysqli_connect($host, $user, $passwd, $schema);
/* Check if the connection succeeded */
if (!$mysqli) {
return(array());
}
// Get db_def and views
$sql = "SHOW FULL tables WHERE Table_type = 'BASE TABLE'";
$query_result = mysqli_query($mysqli, $sql);
if (!$query_result) {
return(array());
}
while ($row = mysqli_fetch_assoc($query_result)) {
$table = array();
$table['name'] = $row['Tables_in_'.$schema];
$table['type'] = $row['Table_type'];
$tables[] = $table; // Add table to list of tables
}
// Get and add columns of the table
foreach ($tables as &$table) {
$sql = "SHOW FULL COLUMNS FROM ".$table['name'];
$query_result = mysqli_query($mysqli, $sql);
if (!$query_result) {
return(array());
}
$columns = array();
while ($column = mysqli_fetch_assoc($query_result)) {
// Do some harmonization
if ($column['Default'] !== NULL) {
mustal_sql_replace_reserved_functions($column,$replacers);
$column['Default'] = mustal_mysql_put_text_type_in_quotes($column['Type'],$column['Default']);
}
$columns[] = $column; // Add column to list of columns
}
$table['columns'] = $columns;
$sql = "SHOW KEYS FROM ".$table['name'];
$query_result = mysqli_query($mysqli, $sql);
if (!$query_result) {
return(array());
}
$keys = array();
while ($key = mysqli_fetch_assoc($query_result)) {
$keys[] = $key; // Add key to list of keys
}
// Compose comparable format for keys
$composed_keys = array();
foreach ($keys as $key) {
// Check if this key exists already
$key_pos = array_search($key['Key_name'],array_column($composed_keys,'Key_name'));
if ($key_pos == false) {
// New key
$composed_key = array();
$composed_key['Key_name'] = $key['Key_name'];
$composed_key['Index_type'] = $key['Index_type'];
$composed_key['columns'][] = $key['Column_name'];
$composed_keys[] = $composed_key;
} else {
// Given key, add column
$composed_keys[$key_pos]['columns'][] .= $key['Column_name'];
}
}
unset($key);
$table['keys'] = $composed_keys;
unset($composed_keys);
}
unset($table);
$sql = "SHOW FULL tables WHERE Table_type = 'VIEW'";
$query_result = mysqli_query($mysqli, $sql);
if (!$query_result) {
return(array());
}
while ($row = mysqli_fetch_assoc($query_result)) {
$view = array();
$view['name'] = $row['Tables_in_'.$schema];
$view['type'] = $row['Table_type'];
$views[] = $view; // Add view to list of views
}
foreach ($views as &$view) {
$sql = "SHOW CREATE VIEW ".$view['name'];
$query_result = mysqli_query($mysqli, $sql);
if (!$query_result) {
return(array());
}
$viewdef = mysqli_fetch_assoc($query_result);
$view['Create'] = $viewdef['Create View'];
}
$result = array();
$result['host'] = $host;
$result['database'] = $schema;
$result['user'] = $user;
$result['tables'] = $tables;
$result['views'] = $views;
return($result);
}
function mustal_save_tables_to_json(array $db_def, string $path, string $tables_file_name, bool $force) : int {
// Prepare db_def file
if (!is_dir($path)) {
mkdir($path);
}
if (!$force && file_exists($path."/".$tables_file_name)) {
return(2);
}
$tables_file = fopen($path."/".$tables_file_name, "w");
if (empty($tables_file)) {
return(2);
}
fwrite($tables_file, json_encode($db_def,JSON_PRETTY_PRINT));
fclose($tables_file);
return(0);
}
// Load all db_def from JSON file
function mustal_load_tables_from_json(string $path, string $tables_file_name) : array {
$db_def = array();
$contents = file_get_contents($path."/".$tables_file_name);
if (!$contents) {
return(array());
}
$db_def = json_decode($contents, true);
if (!$db_def) {
return(array());
}
return($db_def);
}
// Compare two definitions
// Report based on the first array
// Return Array
function mustal_compare_table_array(array $nominal, string $nominal_name, array $actual, string $actual_name, bool $check_column_definitions, bool $utf8fix) : array {
$compare_differences = array();
if($utf8fix) {
$column_collation_aliases = array(
['utf8mb3_general_ci','utf8_general_ci'],
['utf8mb3_unicode_ci','utf8_unicode_ci'],
['utf8mb3_bin','utf8_bin']
);
} else {
$column_collation_aliases = array();
}
foreach ($nominal['tables'] as $database_table) {
$found_table = array();
foreach ($actual['tables'] as $compare_table) {
if ($database_table['name'] == $compare_table['name']) {
$found_table = $compare_table;
break;
}
}
unset($compare_table);
if ($found_table) {
// Check type table vs view
if ($database_table['type'] != $found_table['type']) {
$compare_difference = array();
$compare_difference['type'] = "Table type";
$compare_difference['table'] = $database_table['name'];
$compare_difference[$nominal_name] = $database_table['type'];
$compare_difference[$actual_name] = $found_table['type'];
$compare_differences[] = $compare_difference;
}
// Only BASE TABLE supported now
if ($found_table['type'] != 'BASE TABLE') {
continue;
}
// Check columns
$compare_table_columns = array_column($found_table['columns'],'Field');
foreach ($database_table['columns'] as $column) {
$column_name_to_find = $column['Field'];
$column_key = array_search($column_name_to_find,$compare_table_columns,true);
if ($column_key !== false) {
// Compare the properties of the columns
if ($check_column_definitions) {
$found_column = $found_table['columns'][$column_key];
foreach ($column as $key => $value) {
// Apply aliases
if (!empty($column_collation_aliases)) {
foreach($column_collation_aliases as $column_collation_alias) {
if ($value == $column_collation_alias[0]) {
$value = $column_collation_alias[1];
}
if ($found_column[$key] == $column_collation_alias[0]) {
$found_column[$key] = $column_collation_alias[1];
}
}
}
if ($found_column[$key] != $value) {
if ($key != 'Key') { // Keys will be handled separately
$compare_difference = array();
$compare_difference['type'] = "Column definition";
$compare_difference['table'] = $database_table['name'];
$compare_difference['column'] = $column['Field'];
$compare_difference['property'] = $key;
$compare_difference[$nominal_name] = $value;
$compare_difference[$actual_name] = $found_column[$key];
$compare_differences[] = $compare_difference;
}
}
}
unset($value);
} // $check_column_definitions
} else {
$compare_difference = array();
$compare_difference['type'] = "Column existence";
$compare_difference['table'] = $database_table['name'];
$compare_difference[$nominal_name] = $column['Field'];
$compare_differences[] = $compare_difference;
}
}
unset($column);
// Check keys
$compare_table_sql_indexs = array_column($found_table['keys'],'Key_name');
foreach ($database_table['keys'] as $sql_index) {
$sql_index_name_to_find = $sql_index['Key_name'];
$sql_index_key = array_search($sql_index_name_to_find,$compare_table_sql_indexs,true);
if ($sql_index_key !== false) {
// Compare the properties of the sql_indexs
if ($check_column_definitions) {
$found_sql_index = $found_table['keys'][$sql_index_key];
foreach ($sql_index as $key => $value) {
if ($found_sql_index[$key] != $value) {
// if ($key != 'permissions') {
$compare_difference = array();
$compare_difference['type'] = "Key definition";
$compare_difference['table'] = $database_table['name'];
$compare_difference['key'] = $sql_index['Key_name'];
$compare_difference['property'] = $key;
$compare_difference[$nominal_name] = implode(',',$value);
$compare_difference[$actual_name] = implode(',',$found_sql_index[$key]);
$compare_differences[] = $compare_difference;
// }
}
}
unset($value);
} // $check_sql_index_definitions
} else {
$compare_difference = array();
$compare_difference['type'] = "Key existence";
$compare_difference['table'] = $database_table['name'];
$compare_difference[$nominal_name] = $sql_index['Key_name'];
$compare_differences[] = $compare_difference;
}
}
unset($sql_index);
} else {
$compare_difference = array();
$compare_difference['type'] = "Table existence";
$compare_difference[$nominal_name] = $database_table['name'];
$compare_differences[] = $compare_difference;
}
}
unset($database_table);
foreach ($nominal['views'] as $database_view) {
$found_view = array();
foreach ($actual['views'] as $compare_view) {
if ($database_view['name'] == $compare_view['name']) {
$found_view = $compare_view;
break;
}
}
unset($compare_view);
if ($found_view) {
if (trim($database_view['Create']) != trim($found_view['Create'])) {
$compare_difference = array();
$compare_difference['type'] = "View definition";
$compare_difference[$nominal_name] = $database_view['name'];
$compare_differences[] = $compare_difference;
}
} else {
$compare_difference = array();
$compare_difference['type'] = "View existence";
$compare_difference[$nominal_name] = $database_view['name'];
$compare_differences[] = $compare_difference;
}
}
return($compare_differences);
}
// Generate SQL to create or modify column
function mustal_column_sql_definition(string $table_name, array $column, array $reserved_words_without_quote) : string {
foreach($column as $key => &$value) {
$value = (string) $value;
$value = mustal_column_sql_create_property_definition($key,$value,$reserved_words_without_quote);
}
// Default handling here
if ($column['Default'] == " DEFAULT ''") {
$column['Default'] = "";
}
$sql =
$column['Type'].
$column['Null'].
$column['Default'].
$column['Extra'].
$column['Collation'];
return($sql);
}
// Generate SQL to modify a single column property
function mustal_column_sql_create_property_definition(string $property, string $property_value, array $reserved_words_without_quote) : string {
switch ($property) {
case 'Type':
break;
case 'Null':
if ($property_value == "NO") {
$property_value = " NOT NULL"; // Idiotic...
}
if ($property_value == "YES") {
$property_value = " NULL"; // Also Idiotic...
}
break;
case 'Default':
// Check for MYSQL function mustal_call as default
if (in_array(strtolower($property_value),$reserved_words_without_quote)) {
$quote = "";
} else {
// Remove quotes if there are
$property_value = trim($property_value,"'");
$quote = "'";
}
$property_value = " DEFAULT $quote".$property_value."$quote";
break;
case 'Extra':
if ($property_value != '') {
$property_value = " ".$property_value;
}
break;
case 'Collation':
if ($property_value != '') {
$property_value = " COLLATE ".$property_value;
}
break;
default:
$property_value = "";
break;
}
return($property_value);
}
// Replaces different variants of the same function mustal_to allow comparison
function mustal_sql_replace_reserved_functions(array &$column, array $replacers) {
$result = strtolower($column['Default']);
foreach ($replacers as $replace) {
if ($result == $replace[0]) {
$result = $replace[1];
}
}
$column['Default'] = $result;
$result = strtolower($column['Extra']);
foreach ($replacers as $replace) {
if ($result == $replace[0]) {
$result = $replace[1];
}
}
$column['Extra'] = $result;
}
// Is it a text type? -> Use quotes then
function mustal_mysql_put_text_type_in_quotes(string $checktype, string $value) : string {
$types = array('char','varchar','tinytext','text','mediumtext','longtext');
foreach($types as $type) {
if (stripos($checktype, $type) !== false) {
return("'".$value."'");
}
}
return($value);
}
function mustal_implode_with_quote(string $quote, string $delimiter, array $array_to_implode) : string {
return($quote.implode($quote.$delimiter.$quote, $array_to_implode).$quote);
}
// Calculate the sql neccessary to update the database
// returns array(code,text)
// Error codes:
// 0 ok
// 1 Upgrade type of table not supported
// 2 Error on table upgrade
// 3 Error on column existence upgrade
// 4 Error on column existence upgrade
// 5 Error on column definition upgrade
// 6 Error on column definition upgrade
// 7 Error on key existence upgrade
// 8 Error on key existence upgrade
// 9 Error on key definition upgrade
// 10 Error on key definition upgrade
// 11 Table type upgrade not supported
// 12 Upgrade type not supported
function mustal_calculate_db_upgrade(array $compare_def, array $db_def, array &$upgrade_sql, array $replacers) : array {
$result = array();
$upgrade_sql = array();
$compare_differences = mustal_compare_table_array($compare_def,"in JSON",$db_def,"in DB",true,true);
foreach ($compare_differences as $compare_difference) {
$drop_view = false;
switch ($compare_difference['type']) {
case 'Table existence':
// Get table definition from JSON
$table_name = $compare_difference['in JSON'];
$table_key = array_search($table_name,array_column($compare_def['tables'],'name'));
if ($table_key !== false) {
$table = $compare_def['tables'][$table_key];
switch ($table['type']) {
case 'BASE TABLE':
// Create table in DB
$sql = "";
$sql = "CREATE TABLE `".$table['name']."` (";
$comma = "";
foreach ($table['columns'] as $column) {
$sql .= $comma."`".$column['Field']."` ".mustal_column_sql_definition($table_name, $column,array_column($replacers,1));
$comma = ", ";
}
// Add keys
$comma = ", ";
foreach ($table['keys'] as $key) {
if ($key['Key_name'] == 'PRIMARY') {
$keystring = "PRIMARY KEY ";
} else {
if(array_key_exists('Index_type', $key)) {
$index_type = $key['Index_type'];
} else {
$index_type = "";
}
$keystring = $index_type." KEY `".$key['Key_name']."` ";
}
$sql .= $comma.$keystring."(`".implode("`,`",$key['columns'])."`) ";
}
$sql .= ")";
$upgrade_sql[] = $sql;
break;
default:
$result[] = array(1,"Upgrade type '".$table['type']."' on table '".$table['name']."' not supported.");
break;
}
} else {
$result[] = array(2,"Error table_key while creating upgrade for table existence `$table_name`.");
}
break;
case 'Column existence':
$table_name = $compare_difference['table'];
$column_name = $compare_difference['in JSON'];
$table_key = array_search($table_name,array_column($compare_def['tables'],'name'));
if ($table_key !== false) {
$table = $compare_def['tables'][$table_key];
$columns = $table['columns'];
$column_key = array_search($column_name,array_column($columns,'Field'));
if ($column_key !== false) {
$column = $table['columns'][$column_key];
$sql = "ALTER TABLE `$table_name` ADD COLUMN `".$column_name."` ";
$sql .= mustal_column_sql_definition($table_name, $column, array_column($replacers,1));
$sql .= ";";
$upgrade_sql[] = $sql;
}
else {
$result[] = array(3,"Error column_key while creating column '$column_name' in table '".$table['name']."'.");
}
}
else {
$result[] = array(4,"Error table_key while creating upgrade for column existence '$column_name' in table '$table_name'.");
}
// Add Column in DB
break;
case 'Column definition':
$table_name = $compare_difference['table'];
$column_name = $compare_difference['column'];
$table_key = array_search($table_name,array_column($compare_def['tables'],'name'));
if ($table_key !== false) {
$table = $compare_def['tables'][$table_key];
$columns = $table['columns'];
$column_names = array_column($columns,'Field');
$column_key = array_search($column_name,$column_names);
if ($column_key !== false) {
$column = $table['columns'][$column_key];
$sql = "ALTER TABLE `$table_name` MODIFY COLUMN `".$column_name."` ";
$sql .= mustal_column_sql_definition($table_name, $column,array_column($replacers,1));
$sql .= ";";
$upgrade_sql[] = $sql;
}
else {
$result[] = array(5,"Error column_key while modifying column '$column_name' in table '".$table['name']."'.");
}
}
else {
$result[] = array(6,"Error table_key while modifying column '$column_name' in table '$table_name'.");
return(6);
}
// Modify Column in DB
break;
case 'Key existence':
$table_name = $compare_difference['table'];
$key_name = $compare_difference['in JSON'];
$table_key = array_search($table_name,array_column($compare_def['tables'],'name'));
if ($table_key !== false) {
$table = $compare_def['tables'][$table_key];
$keys = $table['keys'];
$key_names = array_column($keys,'Key_name');
$key_key = array_search($key_name,$key_names);
if ($key_key !== false) {
$key = $table['keys'][$key_key];
$sql = "ALTER TABLE `$table_name` ADD KEY `".$key_name."` ";
$sql .= "(`".implode("`,`",$key['columns'])."`)";
$sql .= ";";
$upgrade_sql[] = $sql;
}
else {
$result[] = array(7,"Error key_key while adding key '$key_name' in table '".$table['name']."'.");
}
}
else {
$result[] = array(8,"Error table_key while adding key '$key_name' in table '$table_name'.");
}
break;
case "Key definition":
$table_name = $compare_difference['table'];
$key_name = $compare_difference['key'];
$table_key = array_search($table_name,array_column($compare_def['tables'],'name'));
if ($table_key !== false) {
$table = $compare_def['tables'][$table_key];
$keys = $table['keys'];
$key_names = array_column($keys,'Key_name');
$key_key = array_search($key_name,$key_names);
if ($key_key !== false) {
$key = $table['keys'][$key_key];
$sql = "ALTER TABLE `$table_name` DROP KEY `".$key_name."`;";
$upgrade_sql[] = $sql;
$sql = "ALTER TABLE `$table_name` ADD KEY `".$key_name."` ";
$sql .= "(`".implode("`,`",$key['columns'])."`)";
$sql .= ";";
$upgrade_sql[] = $sql;
}
else {
$result[] = array(9, "Error key_key while changing key '$key_name' in table '".$table['name']."'.");
}
}
else {
$result[] = array(10,"Error table_key while changing key '$key_name' in table '$table_name'.");
}
break;
case 'Table count':
// Nothing to do
break;
case 'Table type':
$result[] = array(11,"Upgrade type '".$compare_difference['type']."' on table '".$compare_difference['table']."' not supported.");
break;
case 'View definition':
$drop_view = true;
// intentionally omitted break;
case 'View existence':
$view_name = $compare_difference['in JSON'];
$view_key = array_search($view_name,array_column($compare_def['views'],'name'));
if ($view_key !== false) {
$view = $compare_def['views'][$view_key];
switch ($view['type']) {
case 'VIEW':
if ($drop_view === true) {
$sql = "DROP VIEW ".$view['name'];
$upgrade_sql[] = $sql;
}
// Create view in DB
$upgrade_sql[] = $view['Create'];
break;
default:
$result[] = array(1,"Upgrade type '".$view['type']."' on view '".$view['name']."' not supported.");
break;
}
} else {
$result[] = array(2,"Error view_key while creating upgrade for view existence `$view_name`.");
}
break;
default:
$result[] = array(12,"Upgrade type '".$compare_difference['type']."' not supported.");
break;
}
}
$upgrade_sql = array_unique($upgrade_sql);
if (count($upgrade_sql) > 0) {
array_unshift($upgrade_sql,"SET SQL_MODE='ALLOW_INVALID_DATES';","SET SESSION innodb_strict_mode=OFF;");
}
return($result);
}
+1 -1
View File
@@ -1,7 +1,7 @@
<?php <?php
$version="OSS"; $version="OSS";
$version_revision="1.0"; $version_revision="1.6";
$githash = file_get_contents("../githash.txt"); $githash = file_get_contents("../githash.txt");
if (!empty($githash)) { if (!empty($githash)) {
$version_revision .= " (".substr($githash,0,8).")"; $version_revision .= " (".substr($githash,0,8).")";
+16
View File
@@ -0,0 +1,16 @@
# Generated file from class.acl.php
# Disable directory browsing
Options -Indexes
# Deny access to all *.php
Order deny,allow
Allow from all
<FilesMatch "\.(css|jpg|jpeg|gif|png|svg|js)$">
Order Allow,Deny
Allow from all
</FilesMatch>
# Allow access to index.php
<Files index.php>
Order Allow,Deny
Allow from all
</Files>
# end
+9 -7
View File
@@ -443,10 +443,10 @@ class erpooSystem extends Application
// Creates user specific items // Creates user specific items
$possibleUserItems = [ $possibleUserItems = [
/* 'Inbox' => [ 'Tickets' => [
'link' => 'index.php?module=ticket&action=offene', 'link' => 'index.php?module=ticket&action=list',
'counter' => $this->erp->AnzahlOffeneTickets() 'counter' => $this->erp->AnzahlOffeneTickets()
],*/ ],
'Aufgaben' => [ 'Aufgaben' => [
'link' => 'index.php?module=aufgaben&action=list', 'link' => 'index.php?module=aufgaben&action=list',
'counter' => $this->erp->AnzahlOffeneAufgaben() 'counter' => $this->erp->AnzahlOffeneAufgaben()
@@ -586,7 +586,7 @@ class erpooSystem extends Application
$version = ''; $version = '';
if(isset($version_revision) && $version_revision != '') { if(isset($version_revision) && $version_revision != '') {
$version .= '<div class="sidebar-software-version">Xenomporio V.'. $version_revision .'</div>'; $version .= '<div class="sidebar-software-version">OpenXE V.'. $version_revision .'</div>';
} }
if($userId = $this->User->GetID()){ if($userId = $this->User->GetID()){
@@ -618,7 +618,9 @@ class erpooSystem extends Application
); );
} }
else{ else{
$this->Tpl->Add('SIDEBARLOGO', @file_get_contents(__DIR__ . '/themes/new/templates/sidebar_logo.svg')); // $this->Tpl->Add('SIDEBARLOGO', @file_get_contents(__DIR__ . '/themes/new/templates/sidebar_logo.svg'));
$this->Tpl->Add('SIDEBARLOGO','<div class="sidebar_logo">'.@file_get_contents(__DIR__ . '/themes/new/templates/sidebar_logo.svg').'</div>');
$this->Tpl->Add('SIDEBARLOGO','<div class="sidebar_icon_logo">'.@file_get_contents(__DIR__ . '/themes/new/templates/sidebar_icon_logo.svg').'</div>');
} }
$this->Tpl->Parse('SIDEBAR', 'sidebar.tpl'); $this->Tpl->Parse('SIDEBAR', 'sidebar.tpl');
@@ -1128,7 +1130,7 @@ if (typeof document.hidden !== \"undefined\") { // Opera 12.10 and Firefox 18 an
$this->Tpl->SetText('MODUL',ucfirst($module)); $this->Tpl->SetText('MODUL',ucfirst($module));
$this->Tpl->Set('HTMLTITLE','{|[MODUL]|} | Xenomporio '); $this->Tpl->Set('HTMLTITLE','{|[MODUL]|} | OpenXE ');
switch($module) switch($module)
@@ -1280,7 +1282,7 @@ if (typeof document.hidden !== \"undefined\") { // Opera 12.10 and Firefox 18 an
$this->Tpl->Set('TPLLOGOFIRMA', './themes/new/images/logo_cache.png'); $this->Tpl->Set('TPLLOGOFIRMA', './themes/new/images/logo_cache.png');
}elseif($this->erp->Firmendaten('firmenlogoaktiv')!='1') }elseif($this->erp->Firmendaten('firmenlogoaktiv')!='1')
{ {
$this->Tpl->Set('TPLLOGOFIRMA', './themes/new/images/xentral_logo.svg'); $this->Tpl->Set('TPLLOGOFIRMA', './themes/new/images/openxe_logo.svg');
}else{ }else{
$this->Tpl->Set('TPLLOGOFIRMA', './index.php?module=welcome&action=logo'); $this->Tpl->Set('TPLLOGOFIRMA', './index.php?module=welcome&action=logo');
} }
+225 -5495
View File
File diff suppressed because it is too large Load Diff
+173 -166
View File
@@ -54,6 +54,11 @@ class Briefpapier extends SuperFPDF {
/** @var array **/ /** @var array **/
private $styleData; private $styleData;
// Typed variables to get rid of the typos, $border omitted intenionally
function Cell_typed(int $w, int $h = 0, string $txt = '', $border = 0, int $ln = 0, string $align = '', bool $fill = false, string $link = '') {
return($this->Cell($w,$h,$txt,$border,$ln,$align,$fill,$link));
}
/** /**
* Briefpapier constructor. * Briefpapier constructor.
* *
@@ -1006,9 +1011,9 @@ class Briefpapier extends SuperFPDF {
$this->cMargin=-3; $this->cMargin=-3;
if($this->getStyleElement("seite_belegnr")) if($this->getStyleElement("seite_belegnr"))
$this->Cell(0,8,$this->app->erp->Beschriftung("dokument_seite").' '.$this->PageNo().' '.$this->app->erp->Beschriftung("dokument_seitevon").' {nb} '.$this->zusatzfooter,0,0,$this->seite_von_ausrichtung); $this->Cell_typed(0,8,$this->app->erp->Beschriftung("dokument_seite").' '.$this->PageNo().' '.$this->app->erp->Beschriftung("dokument_seitevon").' {nb} '.$this->zusatzfooter,0,0,$this->seite_von_ausrichtung);
else else
$this->Cell(0,8,$this->app->erp->Beschriftung("dokument_seite").' '.$this->PageNo().' '.$this->app->erp->Beschriftung("dokument_seitevon").' {nb}',0,0,$this->seite_von_ausrichtung); $this->Cell_typed(0,8,$this->app->erp->Beschriftung("dokument_seite").' '.$this->PageNo().' '.$this->app->erp->Beschriftung("dokument_seitevon").' {nb}',0,0,$this->seite_von_ausrichtung);
$this->cMargin = $tmpc; $this->cMargin = $tmpc;
@@ -1836,8 +1841,10 @@ class Briefpapier extends SuperFPDF {
//$this->setStationery("/home/eproo/eproo-master/app/main/www/lib/dokumente/demo.pdf"); //$this->setStationery("/home/eproo/eproo-master/app/main/www/lib/dokumente/demo.pdf");
$this->SetDisplayMode("real","single"); $this->SetDisplayMode("real","single");
/*
if($this->getStyleElement("abstand_seitenrandrechts")=="") if($this->getStyleElement("abstand_seitenrandrechts")=="")
$this->getStyleElementSet("abstand_seitenrandrechts",$this->getStyleElement("abstand_seitenrandlinks")); $this->getStyleElementSet("abstand_seitenrandrechts",$this->getStyleElement("abstand_seitenrandlinks"));
*/
$this->SetMargins($this->getStyleElement("abstand_seitenrandlinks"),50,$this->getStyleElement("abstand_seitenrandrechts")); $this->SetMargins($this->getStyleElement("abstand_seitenrandlinks"),50,$this->getStyleElement("abstand_seitenrandrechts"));
$this->SetAutoPageBreak(true,$this->getStyleElement("abstand_umbruchunten")); $this->SetAutoPageBreak(true,$this->getStyleElement("abstand_umbruchunten"));
@@ -1886,7 +1893,7 @@ class Briefpapier extends SuperFPDF {
$this->SetTextColor(0,0,0); $this->SetTextColor(0,0,0);
if($this->doctype!="lieferschein" && $this->doctype!="preisanfrage" && !$this->nichtsichtbar_summe) { if($this->doctype!="lieferschein" && $this->doctype!="preisanfrage" && !$this->nichtsichtbar_summe) {
$this->renderTotals(); $this->renderTotals();
} else $this->Cell(1,5,'',0); } else $this->Cell_typed(1,5,'',0);
} }
$this->renderFooter(); $this->renderFooter();
$this->logofile = ""; $this->logofile = "";
@@ -1928,7 +1935,7 @@ class Briefpapier extends SuperFPDF {
if($this->recipient['anrede']!="" && $this->getStyleElement('typimdokument')) if($this->recipient['anrede']!="" && $this->getStyleElement('typimdokument'))
{ {
$this->SetX($this->getStyleElement("abstand_adresszeilelinks")); $this->SetX($this->getStyleElement("abstand_adresszeilelinks"));
$this->Cell(80,5,$this->recipient['anrede'],0,1); $this->Cell_typed(80,5,$this->recipient['anrede'],0,1);
} }
$this->SetMargins($this->getStyleElement("abstand_adresszeilelinks"),50); $this->SetMargins($this->getStyleElement("abstand_adresszeilelinks"),50);
@@ -1940,10 +1947,10 @@ class Briefpapier extends SuperFPDF {
$array = explode( "\n", wordwrap($this->recipient['enterprise'], $charlimit)); $array = explode( "\n", wordwrap($this->recipient['enterprise'], $charlimit));
foreach($array as $row) foreach($array as $row)
{ {
$this->Cell(80,5,$this->app->erp->ReadyForPDF($row),0,1); $this->Cell_typed(80,5,$this->app->erp->ReadyForPDF($row),0,1);
} }
} else { } else {
$this->Cell(80,5,$this->app->erp->ReadyForPDF($this->recipient['enterprise']),0,1); $this->Cell_typed(80,5,$this->app->erp->ReadyForPDF($this->recipient['enterprise']),0,1);
} }
} }
@@ -1952,30 +1959,30 @@ class Briefpapier extends SuperFPDF {
if($this->recipient['firstname']!="") if($this->recipient['firstname']!="")
{ {
$this->SetX($this->getStyleElement("abstand_adresszeilelinks")); $this->SetX($this->getStyleElement("abstand_adresszeilelinks"));
$this->Cell(80,5,$this->recipient['firstname'],0,1); $this->Cell_typed(80,5,$this->recipient['firstname'],0,1);
} }
if($this->recipient['address2']!="") { if($this->recipient['address2']!="") {
$this->SetX($this->getStyleElement("abstand_adresszeilelinks")); $this->SetX($this->getStyleElement("abstand_adresszeilelinks"));
$this->Cell(80,5,$this->recipient['address2'],0,1); $this->Cell_typed(80,5,$this->recipient['address2'],0,1);
} }
if($this->recipient['address3']!="") if($this->recipient['address3']!="")
{ {
$this->SetX($this->getStyleElement("abstand_adresszeilelinks")); $this->SetX($this->getStyleElement("abstand_adresszeilelinks"));
$this->Cell(80,5,$this->recipient['address3'],0,1); $this->Cell_typed(80,5,$this->recipient['address3'],0,1);
} }
if($this->recipient['address4']!="") if($this->recipient['address4']!="")
{ {
$this->SetX($this->getStyleElement("abstand_adresszeilelinks")); $this->SetX($this->getStyleElement("abstand_adresszeilelinks"));
$this->Cell(80,5,$this->recipient['address4'],0,1); $this->Cell_typed(80,5,$this->recipient['address4'],0,1);
} }
//$this->Cell(80,5,$this->recipient['firstname']." ".$this->recipient['familyname'],0,1); //$this->Cell_typed(80,5,$this->recipient['firstname']." ".$this->recipient['familyname'],0,1);
$this->SetX($this->getStyleElement("abstand_adresszeilelinks")); $this->SetX($this->getStyleElement("abstand_adresszeilelinks"));
$this->Cell(80,5,$this->recipient['address1'],0,1); $this->Cell_typed(80,5,$this->recipient['address1'],0,1);
$this->SetFont($this->GetFont(),'',10); $this->SetFont($this->GetFont(),'',10);
@@ -1987,22 +1994,22 @@ class Briefpapier extends SuperFPDF {
$inland = $this->getStyleElement("land"); $inland = $this->getStyleElement("land");
if($this->recipient['country']!=$inland) if($this->recipient['country']!=$inland)
{ {
//$this->Cell(80,5,$this->recipient['country']."-".$this->recipient['areacode']." ".$this->recipient['city'],0,1); //$this->Cell_typed(80,5,$this->recipient['country']."-".$this->recipient['areacode']." ".$this->recipient['city'],0,1);
if(function_exists('mb_strtoupper')) if(function_exists('mb_strtoupper'))
$this->Cell(80,5,mb_strtoupper($this->recipient['areacode']." ".$this->recipient['city'],"UTF-8"),0,1); $this->Cell_typed(80,5,mb_strtoupper($this->recipient['areacode']." ".$this->recipient['city'],"UTF-8"),0,1);
else else
$this->Cell(80,5,strtoupper($this->recipient['areacode']." ".$this->recipient['city']),0,1); $this->Cell_typed(80,5,strtoupper($this->recipient['areacode']." ".$this->recipient['city']),0,1);
$this->SetX($this->getStyleElement("abstand_adresszeilelinks")); $this->SetX($this->getStyleElement("abstand_adresszeilelinks"));
$this->Cell(80,5,strtoupper($this->app->erp->UmlauteEntfernen($this->app->GetLandLang($this->recipient['country'],$this->sprache))),0,1); $this->Cell_typed(80,5,strtoupper($this->app->erp->UmlauteEntfernen($this->app->GetLandLang($this->recipient['country'],$this->sprache))),0,1);
} }
else { else {
$this->Cell(80,5,$this->recipient['areacode']." ".$this->recipient['city'],0,1); $this->Cell_typed(80,5,$this->recipient['areacode']." ".$this->recipient['city'],0,1);
} }
//$this->SetFont($this->GetFont(),'',9); //$this->SetFont($this->GetFont(),'',9);
//if(isset($this->recipient['country'])) $this->Cell(80,5,$this->recipient['country'],0,1); //if(isset($this->recipient['country'])) $this->Cell_typed(80,5,$this->recipient['country'],0,1);
//FREITEXT1 //FREITEXT1
@@ -2074,9 +2081,9 @@ class Briefpapier extends SuperFPDF {
$this->SetX($this->getStyleElement("abstand_adresszeilelinks")); $this->SetX($this->getStyleElement("abstand_adresszeilelinks"));
if($this->getStyleElement("absenderunterstrichen")=="1") if($this->getStyleElement("absenderunterstrichen")=="1")
$this->Cell($this->GetStringWidth($cellStr)+2,5,$cellStr,'B'); $this->Cell_typed($this->GetStringWidth($cellStr)+2,5,$cellStr,'B');
else else
$this->Cell($this->GetStringWidth($cellStr)+2,5,$cellStr,''); $this->Cell_typed($this->GetStringWidth($cellStr)+2,5,$cellStr,'');
} }
if($this->nichtsichtbar_rechtsoben!=true) if($this->nichtsichtbar_rechtsoben!=true)
@@ -2088,70 +2095,70 @@ class Briefpapier extends SuperFPDF {
$this->SetXY($xOffset,10); $this->SetXY($xOffset,10);
$this->SetFont($this->GetFont(),'',9); $this->SetFont($this->GetFont(),'',9);
$this->Cell(30,$lineHeight,"Name der Gesellschaft: ",0,0,'R'); $this->Cell_typed(30,$lineHeight,"Name der Gesellschaft: ",0,0,'R');
$this->SetFont($this->GetFont(),'B',9); $this->SetFont($this->GetFont(),'B',9);
$this->Cell(60,$lineHeight,$this->sender['enterprise'],0,2); $this->Cell_typed(60,$lineHeight,$this->sender['enterprise'],0,2);
if(isset($this->sender['enterprise2'])) if(isset($this->sender['enterprise2']))
$this->Cell(60,$lineHeight,$this->sender['enterprise2'],0,2); $this->Cell_typed(60,$lineHeight,$this->sender['enterprise2'],0,2);
$this->SetXY($xOffset,$this->GetY()); $this->SetXY($xOffset,$this->GetY());
$this->SetFont($this->GetFont(),'',9); $this->SetFont($this->GetFont(),'',9);
$this->Cell(30,$lineHeight,"Sitz der Gesellschaft: ",0,0,'R'); $this->Cell_typed(30,$lineHeight,"Sitz der Gesellschaft: ",0,0,'R');
$this->SetFont($this->GetFont(),'B',9); $this->SetFont($this->GetFont(),'B',9);
$this->Cell(60,$lineHeight,$this->sender['address1'],0,2); $this->Cell_typed(60,$lineHeight,$this->sender['address1'],0,2);
if(isset($this->sender['address2'])) if(isset($this->sender['address2']))
$this->Cell(60,$lineHeight,$this->sender['address2'],0,2); $this->Cell_typed(60,$lineHeight,$this->sender['address2'],0,2);
$this->Cell(60,$lineHeight,$this->sender['areacode']." ".$this->sender['city'],0,2); $this->Cell_typed(60,$lineHeight,$this->sender['areacode']." ".$this->sender['city'],0,2);
$this->SetXY($xOffset,$this->GetY()+$absatz); //abstand $this->SetXY($xOffset,$this->GetY()+$absatz); //abstand
$this->SetFont($this->GetFont(),'',9); $this->SetFont($this->GetFont(),'',9);
if(isset($this->sender['phone1'])) { if(isset($this->sender['phone1'])) {
$this->Cell(30,$lineHeight,"Fon: ",0,0,'R'); $this->Cell_typed(30,$lineHeight,"Fon: ",0,0,'R');
$this->Cell(60,$lineHeight,$this->sender['phone1'],0,2); $this->Cell_typed(60,$lineHeight,$this->sender['phone1'],0,2);
} }
if(isset($this->sender['fax'])) { if(isset($this->sender['fax'])) {
$this->SetXY($xOffset,$this->GetY()); $this->SetXY($xOffset,$this->GetY());
$this->Cell(30,$lineHeight,"Fax: ",0,0,'R'); $this->Cell_typed(30,$lineHeight,"Fax: ",0,0,'R');
$this->Cell(60,$lineHeight,$this->sender['fax'],0,2); $this->Cell_typed(60,$lineHeight,$this->sender['fax'],0,2);
} }
$this->SetXY($xOffset, $this->GetY()+$absatz); //abstand $this->SetXY($xOffset, $this->GetY()+$absatz); //abstand
if(isset($this->sender['email'])) { if(isset($this->sender['email'])) {
$this->Cell(30,$lineHeight,"Mail: ",0,0,'R'); $this->Cell_typed(30,$lineHeight,"Mail: ",0,0,'R');
$this->Cell(60,$lineHeight,$this->sender['email'],0,2); $this->Cell_typed(60,$lineHeight,$this->sender['email'],0,2);
} }
if(isset($this->sender['web'])) { if(isset($this->sender['web'])) {
$this->SetXY($xOffset,$this->GetY()); $this->SetXY($xOffset,$this->GetY());
$this->Cell(30,$lineHeight,"Web: ",0,0,'R'); $this->Cell_typed(30,$lineHeight,"Web: ",0,0,'R');
$this->Cell(60,$lineHeight,$this->sender['web'],0,2); $this->Cell_typed(60,$lineHeight,$this->sender['web'],0,2);
} }
$this->SetXY($xOffset, $this->GetY()+$absatz); //abstand $this->SetXY($xOffset, $this->GetY()+$absatz); //abstand
if(isset($this->sender['ustid'])) { if(isset($this->sender['ustid'])) {
$this->Cell(30,$lineHeight,"UST-ID: ",0,0,'R'); $this->Cell_typed(30,$lineHeight,"UST-ID: ",0,0,'R');
$this->Cell(60,$lineHeight,$this->sender['ustid'],0,2); $this->Cell_typed(60,$lineHeight,$this->sender['ustid'],0,2);
} }
if(isset($this->sender['taxnr'])) { if(isset($this->sender['taxnr'])) {
$this->SetXY($xOffset,$this->GetY()); $this->SetXY($xOffset,$this->GetY());
$this->Cell(30,$lineHeight,"Steuer-Nr.: ",0,0,'R'); $this->Cell_typed(30,$lineHeight,"Steuer-Nr.: ",0,0,'R');
$this->Cell(60,$lineHeight,$this->sender['taxnr'],0,2); $this->Cell_typed(60,$lineHeight,$this->sender['taxnr'],0,2);
} }
if(isset($this->sender['hreg'])) { if(isset($this->sender['hreg'])) {
$this->SetXY($xOffset,$this->GetY()); $this->SetXY($xOffset,$this->GetY());
$this->Cell(30,$lineHeight,"Handelsregister: ",0,0,'R'); $this->Cell_typed(30,$lineHeight,"Handelsregister: ",0,0,'R');
$this->Cell(60,$lineHeight,$this->sender['hreg'],0,2); $this->Cell_typed(60,$lineHeight,$this->sender['hreg'],0,2);
} }
$this->SetXY($xOffset,$this->GetY()); $this->SetXY($xOffset,$this->GetY());
$this->Cell(30,$lineHeight,utf8_encode("Geschftsfhrung: "),0,0,'R'); $this->Cell_typed(30,$lineHeight,utf8_encode("Geschftsfhrung: "),0,0,'R');
$this->Cell(60,$lineHeight,$this->sender['firstname'].' '.$this->sender['familyname'],0,2); $this->Cell_typed(60,$lineHeight,$this->sender['firstname'].' '.$this->sender['familyname'],0,2);
//$this->SetXY($xOffset, $this->GetY()+$absatz+2); //abstand //$this->SetXY($xOffset, $this->GetY()+$absatz+2); //abstand
//$this->Cell(30,$lineHeight,"Datum: ",0,0,'R'); //$this->Cell_typed(30,$lineHeight,"Datum: ",0,0,'R');
//$this->Cell(60,$lineHeight,utf8_encode($date),0,2); //$this->Cell_typed(60,$lineHeight,utf8_encode($date),0,2);
} }
} }
@@ -2270,7 +2277,7 @@ class Briefpapier extends SuperFPDF {
$this->SetFont($this->GetFont(),'B',$betreffszeile); $this->SetFont($this->GetFont(),'B',$betreffszeile);
$this->SetY($this->GetY()+$this->abstand_betreffzeileoben); $this->SetY($this->GetY()+$this->abstand_betreffzeileoben);
//$this->Cell(85,6,$this->doctypeOrig); //$this->Cell_typed(85,6,$this->doctypeOrig);
$this->MultiCell(210-83+$this->abstand_boxrechtsoben_lr-$this->getStyleElement("abstand_seitenrandlinks")-5,6,html_entity_decode($this->doctypeOrig,ENT_QUOTES),0,'L'); $this->MultiCell(210-83+$this->abstand_boxrechtsoben_lr-$this->getStyleElement("abstand_seitenrandlinks")-5,6,html_entity_decode($this->doctypeOrig,ENT_QUOTES),0,'L');
$this->SetY($this->GetY()-$this->abstand_betreffzeileoben); $this->SetY($this->GetY()-$this->abstand_betreffzeileoben);
@@ -2593,76 +2600,76 @@ class Briefpapier extends SuperFPDF {
$this->SetX($this->getStyleElement('abstand_seitenrandlinks')+1); // eventuell einstellbar per GUI $this->SetX($this->getStyleElement('abstand_seitenrandlinks')+1); // eventuell einstellbar per GUI
$this->SetFont($this->GetFont(),'B',$tabellenbeschriftung); $this->SetFont($this->GetFont(),'B',$tabellenbeschriftung);
$this->Cell($posWidth,6,$this->app->erp->ReadyForPDF($this->app->erp->Beschriftung('dokument_position'),0,0,'C')); $this->Cell_typed($posWidth,6,$this->app->erp->ReadyForPDF($this->app->erp->Beschriftung('dokument_position'),0,0,'C'));
if($this->doctype!='arbeitsnachweis') if($this->doctype!='arbeitsnachweis')
{ {
if($this->doctype=='zahlungsavis') if($this->doctype=='zahlungsavis')
{ {
$this->Cell($itemNoWidth,6,'Nummer'); $this->Cell_typed($itemNoWidth,6,'Nummer');
$this->Cell($descWidth-$einheitWidth+$taxWidth+$priceWidth+$rabattWidth,6,'Beleg'); $this->Cell_typed($descWidth-$einheitWidth+$taxWidth+$priceWidth+$rabattWidth,6,'Beleg');
$this->Cell($amWidth,6,'',0,0,'R'); $this->Cell_typed($amWidth,6,'',0,0,'R');
} }
else { else {
$this->Cell($itemNoWidth,6,$this->app->erp->ReadyForPDF($this->app->erp->Beschriftung('dokument_artikelnummer'))); $this->Cell_typed($itemNoWidth,6,$this->app->erp->ReadyForPDF($this->app->erp->Beschriftung('dokument_artikelnummer')));
if($this->getStyleElement('artikeleinheit')=='1'){ if($this->getStyleElement('artikeleinheit')=='1'){
$this->Cell($descWidth - $einheitWidth, 6, $this->app->erp->ReadyForPDF($this->app->erp->Beschriftung('dokument_artikel'))); $this->Cell_typed($descWidth - $einheitWidth, 6, $this->app->erp->ReadyForPDF($this->app->erp->Beschriftung('dokument_artikel')));
} }
else{ else{
$this->Cell($descWidth, 6, $this->app->erp->ReadyForPDF($this->app->erp->Beschriftung('dokument_artikel'))); $this->Cell_typed($descWidth, 6, $this->app->erp->ReadyForPDF($this->app->erp->Beschriftung('dokument_artikel')));
} }
$this->Cell($amWidth,6,$this->app->erp->ReadyForPDF($this->app->erp->Beschriftung('dokument_menge')),0,0,'R'); $this->Cell_typed($amWidth,6,$this->app->erp->ReadyForPDF($this->app->erp->Beschriftung('dokument_menge')),0,0,'R');
} }
} else { } else {
$this->Cell($taxWidth,6,'Mitarbeiter'); $this->Cell_typed($taxWidth,6,'Mitarbeiter');
$this->Cell($itemNoWidth,6,'Ort'); $this->Cell_typed($itemNoWidth,6,'Ort');
$this->Cell($descWidth,6,'Tätigkeit'); $this->Cell_typed($descWidth,6,'Tätigkeit');
$this->Cell($amWidth,6,'Stunden',0,0,'R'); $this->Cell_typed($amWidth,6,'Stunden',0,0,'R');
} }
if($this->doctype!='lieferschein' && $this->doctype!='arbeitsnachweis' && $this->doctype!='produktion' && $this->doctype!='zahlungsavis' && $this->doctype!='preisanfrage'){ if($this->doctype!='lieferschein' && $this->doctype!='arbeitsnachweis' && $this->doctype!='produktion' && $this->doctype!='zahlungsavis' && $this->doctype!='preisanfrage'){
if($this->getStyleElement('artikeleinheit')=='1'){ if($this->getStyleElement('artikeleinheit')=='1'){
$this->Cell($einheitWidth, 6, $this->app->erp->ReadyForPDF($this->app->erp->Beschriftung('dokument_einheit')), 0, 0, 'R'); $this->Cell_typed($einheitWidth, 6, $this->app->erp->ReadyForPDF($this->app->erp->Beschriftung('dokument_einheit')), 0, 0, 'R');
} }
if($this->ust_spalteausblende){ if($this->ust_spalteausblende){
$this->Cell($taxWidth, 6, '', 0, 0, 'R'); $this->Cell_typed($taxWidth, 6, '', 0, 0, 'R');
} }
else{ else{
$this->Cell($taxWidth, 6, $this->app->erp->ReadyForPDF($this->app->erp->Beschriftung('dokument_mwst')), 0, 0, 'R'); $this->Cell_typed($taxWidth, 6, $this->app->erp->ReadyForPDF($this->app->erp->Beschriftung('dokument_mwst')), 0, 0, 'R');
} }
if($this->getStyleElement('artikeleinheit')=='1'){ if($this->getStyleElement('artikeleinheit')=='1'){
if(!$inventurohnepreis){ if(!$inventurohnepreis){
$this->Cell($priceWidth, 6, $this->app->erp->ReadyForPDF($this->app->erp->Beschriftung('dokument_einzel')), 0, 0, 'R'); $this->Cell_typed($priceWidth, 6, $this->app->erp->ReadyForPDF($this->app->erp->Beschriftung('dokument_einzel')), 0, 0, 'R');
} }
} }
else{ else{
if(!$inventurohnepreis){ if(!$inventurohnepreis){
$this->Cell($priceWidth, 6, $this->app->erp->ParseUserVars($this->doctype, $this->id,$this->app->erp->ReadyForPDF($this->app->erp->Beschriftung('dokument_stueck'))), 0, 0, 'R'); $this->Cell_typed($priceWidth, 6, $this->app->erp->ParseUserVars($this->doctype, $this->id,$this->app->erp->ReadyForPDF($this->app->erp->Beschriftung('dokument_stueck'))), 0, 0, 'R');
} }
} }
if($this->rabatt=='1') { if($this->rabatt=='1') {
if(!$inventurohnepreis){ if(!$inventurohnepreis){
$this->Cell($rabattWidth,6,$this->app->erp->Beschriftung('dokument_rabatt'),0,0,'R'); $this->Cell_typed($rabattWidth,6,$this->app->erp->Beschriftung('dokument_rabatt'),0,0,'R');
$this->Cell($sumWidth,6,$this->app->erp->ParseUserVars($this->doctype, $this->id,$this->app->erp->ReadyForPDF($this->app->erp->Beschriftung('dokument_gesamt'))),0,0,'R'); $this->Cell_typed($sumWidth,6,$this->app->erp->ParseUserVars($this->doctype, $this->id,$this->app->erp->ReadyForPDF($this->app->erp->Beschriftung('dokument_gesamt'))),0,0,'R');
} }
} else { } else {
if(!$inventurohnepreis){ if(!$inventurohnepreis){
$this->Cell($sumWidth,6,$this->app->erp->ParseUserVars($this->doctype, $this->id,$this->app->erp->ReadyForPDF($this->app->erp->Beschriftung('dokument_gesamt'))),0,0,'R'); $this->Cell_typed($sumWidth,6,$this->app->erp->ParseUserVars($this->doctype, $this->id,$this->app->erp->ReadyForPDF($this->app->erp->Beschriftung('dokument_gesamt'))),0,0,'R');
} }
} }
} }
else if ($this->doctype=='lieferschein' || $this->doctype=='preisanfrage') else if ($this->doctype=='lieferschein' || $this->doctype=='preisanfrage')
{ {
if($this->getStyleElement("artikeleinheit")=='1'){ if($this->getStyleElement("artikeleinheit")=='1'){
$this->Cell($einheitWidth, 6, $this->app->erp->ReadyForPDF($this->app->erp->Beschriftung('dokument_einheit')), 0, 0, 'R'); $this->Cell_typed($einheitWidth, 6, $this->app->erp->ReadyForPDF($this->app->erp->Beschriftung('dokument_einheit')), 0, 0, 'R');
} }
} }
else if ($this->doctype=='zahlungsavis') else if ($this->doctype=='zahlungsavis')
{ {
$this->Cell($sumWidth,6,$this->app->erp->ParseUserVars($this->doctype, $this->id,$this->app->erp->ReadyForPDF($this->app->erp->Beschriftung('dokument_gesamt'))),0,0,'R'); $this->Cell_typed($sumWidth,6,$this->app->erp->ParseUserVars($this->doctype, $this->id,$this->app->erp->ReadyForPDF($this->app->erp->Beschriftung('dokument_gesamt'))),0,0,'R');
} }
$this->Ln(); $this->Ln();
@@ -2748,7 +2755,7 @@ class Briefpapier extends SuperFPDF {
$posWidthold = $posWidth; $posWidthold = $posWidth;
if($belege_stuecklisteneinrueckenmm && $newlvl > 0) if($belege_stuecklisteneinrueckenmm && $newlvl > 0)
{ {
$this->Cell($belege_stuecklisteneinrueckenmm * $newlvl,$cellhoehe,''); $this->Cell_typed($belege_stuecklisteneinrueckenmm * $newlvl,$cellhoehe,'');
$posWidth -= $belege_stuecklisteneinrueckenmm * $newlvl; $posWidth -= $belege_stuecklisteneinrueckenmm * $newlvl;
if($posWidth < 2* strlen($posstr)) if($posWidth < 2* strlen($posstr))
{ {
@@ -2760,11 +2767,11 @@ class Briefpapier extends SuperFPDF {
if($belege_subpositionenstuecklisten)$posstr = $this->CalcPosString($posstr,$oldpostr, $hauptnummer, $oldlvl, $newlvl); if($belege_subpositionenstuecklisten)$posstr = $this->CalcPosString($posstr,$oldpostr, $hauptnummer, $oldlvl, $newlvl);
$oldpostr = $posstr; $oldpostr = $posstr;
$oldlvl = isset($item['lvl'])?(int)$item['lvl']:0; $oldlvl = isset($item['lvl'])?(int)$item['lvl']:0;
$this->Cell($posWidth,$cellhoehe,$posstr,0,0,$belege_stuecklisteneinrueckenmm?'':'C'); $this->Cell_typed($posWidth,$cellhoehe,$posstr,0,0,$belege_stuecklisteneinrueckenmm?'':'C');
//artikelnummer //artikelnummer
if($this->doctype==='arbeitsnachweis') if($this->doctype==='arbeitsnachweis')
{ {
$this->Cell($taxWidth,$cellhoehe,trim($item['person']),0); $this->Cell_typed($taxWidth,$cellhoehe,trim($item['person']),0);
$zeilenuntertext = $this->getStyleElement('zeilenuntertext'); $zeilenuntertext = $this->getStyleElement('zeilenuntertext');
$this->SetFont($this->GetFont(),'',$zeilenuntertext); $this->SetFont($this->GetFont(),'',$zeilenuntertext);
@@ -2785,10 +2792,10 @@ class Briefpapier extends SuperFPDF {
$this->SetFont($this->GetFont(), '', $tabelleninhalt); $this->SetFont($this->GetFont(), '', $tabelleninhalt);
} }
if(isset($item['itemno'])) { if(isset($item['itemno'])) {
$this->Cell($itemNoWidth,$cellhoehe,$item['itemno'],0); $this->Cell_typed($itemNoWidth,$cellhoehe,$item['itemno'],0);
} }
else { else {
$this->Cell($itemNoWidth); $this->Cell_typed($itemNoWidth);
} }
$this->SetFont($this->GetFont(),'',$tabelleninhalt); $this->SetFont($this->GetFont(),'',$tabelleninhalt);
} }
@@ -2837,10 +2844,10 @@ class Briefpapier extends SuperFPDF {
// Menge // Menge
if($this->doctype==='zahlungsavis'){ if($this->doctype==='zahlungsavis'){
$this->Cell($amWidth, $cellhoehe, '', 0, 0, 'R'); $this->Cell_typed($amWidth, $cellhoehe, '', 0, 0, 'R');
} }
else{ else{
$this->Cell($amWidth, $cellhoehe, $item['amount'], 0, 0, 'R'); $this->Cell_typed($amWidth, $cellhoehe, $item['amount'], 0, 0, 'R');
} }
if($this->doctype!=='lieferschein' && $this->doctype!=='arbeitsnachweis' && $this->doctype!=='produktion' && $this->doctype!=='preisanfrage') { if($this->doctype!=='lieferschein' && $this->doctype!=='arbeitsnachweis' && $this->doctype!=='produktion' && $this->doctype!=='preisanfrage') {
@@ -2877,7 +2884,7 @@ class Briefpapier extends SuperFPDF {
} }
} }
$this->Cell($einheitWidth,$cellhoehe,$this->app->erp->ReadyForPDF($einheit),0,0,'R'); $this->Cell_typed($einheitWidth,$cellhoehe,$this->app->erp->ReadyForPDF($einheit),0,0,'R');
} }
// if($item['tax']=="hidden") $item['tax']=="hidden"; // if($item['tax']=="hidden") $item['tax']=="hidden";
@@ -2905,21 +2912,21 @@ class Briefpapier extends SuperFPDF {
// standard anzeige mit steuer // standard anzeige mit steuer
if(!$this->ust_spalteausblende){ if(!$this->ust_spalteausblende){
if($item['tax']==='hidden'){ if($item['tax']==='hidden'){
$this->Cell($taxWidth,$cellhoehe,"",0,0,'R'); $this->Cell_typed($taxWidth,$cellhoehe,"",0,0,'R');
} else { } else {
$tax = $item['tax']; //= $tax; //="USTV"?0.19:0.07; $tax = $item['tax']; //= $tax; //="USTV"?0.19:0.07;
$tax *= 100; $tax = $tax.'%'; $tax *= 100; $tax = $tax.'%';
if($this->doctype==='zahlungsavis'){ if($this->doctype==='zahlungsavis'){
$this->Cell($taxWidth,$cellhoehe,"",0,0,'R'); $this->Cell_typed($taxWidth,$cellhoehe,"",0,0,'R');
} }
else{ else{
$this->Cell($taxWidth, $cellhoehe, $item['ohnepreis'] ? '' : $tax, 0, 0, 'R'); $this->Cell_typed($taxWidth, $cellhoehe, $item['ohnepreis'] ? '' : $tax, 0, 0, 'R');
} }
} }
} else { } else {
//kleinunternehmer //kleinunternehmer
$this->Cell($taxWidth,$cellhoehe,"",0,0,'R'); $this->Cell_typed($taxWidth,$cellhoehe,"",0,0,'R');
} }
if($this->doctype!=='lieferschein' && $this->doctype!=='produktion' && $this->doctype!=='preisanfrage') { if($this->doctype!=='lieferschein' && $this->doctype!=='produktion' && $this->doctype!=='preisanfrage') {
@@ -2933,29 +2940,29 @@ class Briefpapier extends SuperFPDF {
//if(($this->anrede=="firma" || $this->app->erp->AnzeigeBelegNetto($this->anrede,$projekt) || $this->doctype=="bestellung" || $this->getStyleElement("immernettorechnungen",$projekt)=="1") //if(($this->anrede=="firma" || $this->app->erp->AnzeigeBelegNetto($this->anrede,$projekt) || $this->doctype=="bestellung" || $this->getStyleElement("immernettorechnungen",$projekt)=="1")
//&& $this->getStyleElement("immerbruttorechnungen",$projekt)!="1") //&& $this->getStyleElement("immerbruttorechnungen",$projekt)!="1")
if(!$inventurohnepreis){ if(!$inventurohnepreis){
$this->Cell($priceWidth, $cellhoehe, $item['ohnepreis'] ? '' : $this->formatMoney((double)$item['price']), 0, 0, 'R'); $this->Cell_typed($priceWidth, $cellhoehe, $item['ohnepreis'] ? '' : $this->formatMoney((double)$item['price']), 0, 0, 'R');
} }
} }
else{ else{
if(!$inventurohnepreis){ if(!$inventurohnepreis){
$this->Cell($priceWidth, $cellhoehe, $item['ohnepreis'] ? '' : $this->formatMoney((double)$item['price'] * $item['tmptax']), 0, 0, 'R'); $this->Cell_typed($priceWidth, $cellhoehe, $item['ohnepreis'] ? '' : $this->formatMoney((double)$item['price'] * $item['tmptax']), 0, 0, 'R');
} }
} }
} else } else
{ {
if($item['ohnepreis']==2) { if($item['ohnepreis']==2) {
if(!$inventurohnepreis){ if(!$inventurohnepreis){
$this->Cell($priceWidth,$cellhoehe,$item['price'],0,0,'R'); $this->Cell_typed($priceWidth,$cellhoehe,$item['price'],0,0,'R');
} }
} // text alternativ zu preis } // text alternativ zu preis
else { else {
if(!$inventurohnepreis){ if(!$inventurohnepreis){
$this->Cell($priceWidth,$cellhoehe,$item['ohnepreis']?'':$this->formatMoney((double)$item['price']),0,0,'R'); $this->Cell_typed($priceWidth,$cellhoehe,$item['ohnepreis']?'':$this->formatMoney((double)$item['price']),0,0,'R');
} }
} }
} }
} else { } else {
$this->Cell($priceWidth,$cellhoehe,"",0,0,'R'); $this->Cell_typed($priceWidth,$cellhoehe,"",0,0,'R');
} }
// zentale rabatt spalte // zentale rabatt spalte
@@ -3023,7 +3030,7 @@ class Briefpapier extends SuperFPDF {
} else { } else {
if($item['rabatt']<>0){ if($item['rabatt']<>0){
// && $item['keinrabatterlaubt']!="1") // && $item['keinrabatterlaubt']!="1")
$this->Cell($rabattWidth, $cellhoehe, $item['ohnepreis'] ? '' : $item['rabatt'] . " %", 0, 0, 'R'); $this->Cell_typed($rabattWidth, $cellhoehe, $item['ohnepreis'] ? '' : $item['rabatt'] . " %", 0, 0, 'R');
} }
else else
{ {
@@ -3032,13 +3039,13 @@ class Briefpapier extends SuperFPDF {
$rabatt_or_porto = $this->app->DB->Select("SELECT id FROM artikel WHERE $rabatt_or_porto = $this->app->DB->Select("SELECT id FROM artikel WHERE
nummer='".$item['itemno']."' AND (porto='1' OR rabatt='1') LIMIT 1"); nummer='".$item['itemno']."' AND (porto='1' OR rabatt='1') LIMIT 1");
if($rabatt_or_porto){ if($rabatt_or_porto){
$this->Cell($rabattWidth, $cellhoehe, '', 0, 0, 'R'); $this->Cell_typed($rabattWidth, $cellhoehe, '', 0, 0, 'R');
} }
else{ else{
$this->Cell($rabattWidth, $cellhoehe, 'SNP', 0, 0, 'R'); $this->Cell_typed($rabattWidth, $cellhoehe, 'SNP', 0, 0, 'R');
} }
} else { } else {
$this->Cell($rabattWidth,$cellhoehe,"",0,0,'R'); $this->Cell_typed($rabattWidth,$cellhoehe,"",0,0,'R');
} }
} }
} }
@@ -3046,7 +3053,7 @@ class Briefpapier extends SuperFPDF {
else { else {
// anzeige ohne zentrale rabatt spalte // anzeige ohne zentrale rabatt spalte
if ($item['tax']==="hidden"){ if ($item['tax']==="hidden"){
$this->Cell($priceWidth,$cellhoehe,"",0,0,'R'); $this->Cell_typed($priceWidth,$cellhoehe,"",0,0,'R');
} }
else { else {
if($anzeigeBelegNettoAdrese) if($anzeigeBelegNettoAdrese)
@@ -3054,16 +3061,16 @@ class Briefpapier extends SuperFPDF {
// && $this->getStyleElement("immerbruttorechnungen",$projekt)!="1") // && $this->getStyleElement("immerbruttorechnungen",$projekt)!="1")
{ {
if(!$inventurohnepreis){ if(!$inventurohnepreis){
$this->Cell($priceWidth,$cellhoehe,$item['ohnepreis']?'':$this->formatMoney((double)$item['tprice']),0,0,'R'); $this->Cell_typed($priceWidth,$cellhoehe,$item['ohnepreis']?'':$this->formatMoney((double)$item['tprice']),0,0,'R');
} }
} }
else{ else{
if(!$inventurohnepreis){ if(!$inventurohnepreis){
$this->Cell($priceWidth, $cellhoehe, $item['ohnepreis'] ? '' : $this->formatMoney((double)$item['tprice'] * $item['tmptax']), 0, 0, 'R'); $this->Cell_typed($priceWidth, $cellhoehe, $item['ohnepreis'] ? '' : $this->formatMoney((double)$item['tprice'] * $item['tmptax']), 0, 0, 'R');
} }
} }
$this->Cell($rabattWidth,$cellhoehe,"",0,0,'R'); $this->Cell_typed($rabattWidth,$cellhoehe,"",0,0,'R');
} }
} }
} }
@@ -3072,20 +3079,20 @@ class Briefpapier extends SuperFPDF {
// if(($this->anrede=="firma" || $this->app->erp->AnzeigeBelegNetto($this->anrede,$projekt) || $this->doctype=="bestellung" || $this->getStyleElement("immernettorechnungen",$projekt)=="1") // if(($this->anrede=="firma" || $this->app->erp->AnzeigeBelegNetto($this->anrede,$projekt) || $this->doctype=="bestellung" || $this->getStyleElement("immernettorechnungen",$projekt)=="1")
// && $this->getStyleElement("immerbruttorechnungen",$projekt)!="1") // && $this->getStyleElement("immerbruttorechnungen",$projekt)!="1")
if(!$inventurohnepreis){ if(!$inventurohnepreis){
$this->Cell($priceWidth,$cellhoehe,$item['ohnepreis']?'':$this->formatMoney((double)$item['price']),0,0,'R'); $this->Cell_typed($priceWidth,$cellhoehe,$item['ohnepreis']?'':$this->formatMoney((double)$item['price']),0,0,'R');
} }
else{ else{
if(!$inventurohnepreis){ if(!$inventurohnepreis){
$this->Cell($priceWidth, $cellhoehe, $item['ohnepreis'] ? '' : $this->formatMoney((double)$item['price'] * $item['tmptax']), 0, 0, 'R'); $this->Cell_typed($priceWidth, $cellhoehe, $item['ohnepreis'] ? '' : $this->formatMoney((double)$item['price'] * $item['tmptax']), 0, 0, 'R');
} }
} }
} }
//$this->Cell($sumWidth,$cellhoehe,$this->formatMoney($item['tprice']).' '.$item['currency'],0,0,'R'); //$this->Cell_typed($sumWidth,$cellhoehe,$this->formatMoney($item['tprice']).' '.$item['currency'],0,0,'R');
if($this->rabatt=='1') if($this->rabatt=='1')
{ {
//gesamt preis //gesamt preis
if ($item['tax']==='hidden'){ if ($item['tax']==='hidden'){
$this->Cell($priceWidth,$cellhoehe,'',0,0,'R'); $this->Cell_typed($priceWidth,$cellhoehe,'',0,0,'R');
} }
else { else {
if($this->rabatt=='1'){ if($this->rabatt=='1'){
@@ -3093,12 +3100,12 @@ class Briefpapier extends SuperFPDF {
//if(($this->anrede=="firma" || $this->app->erp->AnzeigeBelegNetto($this->anrede,$projekt) || $this->doctype=="bestellung" || $this->getStyleElement("immernettorechnungen",$projekt)=="1") //if(($this->anrede=="firma" || $this->app->erp->AnzeigeBelegNetto($this->anrede,$projekt) || $this->doctype=="bestellung" || $this->getStyleElement("immernettorechnungen",$projekt)=="1")
// && $this->getStyleElement("immerbruttorechnungen",$projekt)!="1") // && $this->getStyleElement("immerbruttorechnungen",$projekt)!="1")
if(!$inventurohnepreis){ if(!$inventurohnepreis){
$this->Cell($sumWidth, $cellhoehe, $item['ohnepreis'] ? '' : $this->formatMoney((double)$item['tprice']), 0, 0, 'R'); $this->Cell_typed($sumWidth, $cellhoehe, $item['ohnepreis'] ? '' : $this->formatMoney((double)$item['tprice']), 0, 0, 'R');
} }
} }
else{ else{
if(!$inventurohnepreis){ if(!$inventurohnepreis){
$this->Cell($sumWidth, $cellhoehe, $item['ohnepreis'] ? '' : $this->formatMoney((double)$item['tprice'] * $item['tmptax']), 0, 0, 'R'); $this->Cell_typed($sumWidth, $cellhoehe, $item['ohnepreis'] ? '' : $this->formatMoney((double)$item['tprice'] * $item['tmptax']), 0, 0, 'R');
} }
} }
} }
@@ -3107,12 +3114,12 @@ class Briefpapier extends SuperFPDF {
// if(($this->anrede=="firma" || $this->app->erp->AnzeigeBelegNetto($this->anrede,$projekt) || $this->doctype=="bestellung" || $this->getStyleElement("immernettorechnungen",$projekt)=="1") // if(($this->anrede=="firma" || $this->app->erp->AnzeigeBelegNetto($this->anrede,$projekt) || $this->doctype=="bestellung" || $this->getStyleElement("immernettorechnungen",$projekt)=="1")
// && $this->getStyleElement("immerbruttorechnungen",$projekt)!="1") // && $this->getStyleElement("immerbruttorechnungen",$projekt)!="1")
if(!$inventurohnepreis){ if(!$inventurohnepreis){
$this->Cell($sumWidth, $cellhoehe, $item['ohnepreis'] ? '' : $this->formatMoney((double)$item['tprice']), 0, 0, 'R'); $this->Cell_typed($sumWidth, $cellhoehe, $item['ohnepreis'] ? '' : $this->formatMoney((double)$item['tprice']), 0, 0, 'R');
} }
} }
else{ else{
if(!$inventurohnepreis){ if(!$inventurohnepreis){
$this->Cell($sumWidth, $cellhoehe, $item['ohnepreis'] ? '' : $this->formatMoney((double)$item['tprice'] * $item['tmptax']), 0, 0, 'R'); $this->Cell_typed($sumWidth, $cellhoehe, $item['ohnepreis'] ? '' : $this->formatMoney((double)$item['tprice'] * $item['tmptax']), 0, 0, 'R');
} }
} }
} }
@@ -3148,7 +3155,7 @@ class Briefpapier extends SuperFPDF {
} }
} }
$this->Cell($einheitWidth,$cellhoehe,$this->app->erp->ReadyForPDF($einheit),0,0,'R'); $this->Cell_typed($einheitWidth,$cellhoehe,$this->app->erp->ReadyForPDF($einheit),0,0,'R');
} }
$this->Ln(); $this->Ln();
@@ -3298,12 +3305,12 @@ class Briefpapier extends SuperFPDF {
$yBeforeDescription = $this->GetY(); $yBeforeDescription = $this->GetY();
$this->SetFont($this->GetFont(),'',$zeilenuntertext); $this->SetFont($this->GetFont(),'',$zeilenuntertext);
if($belege_stuecklisteneinrueckenmm && $newlvl > 0){ if($belege_stuecklisteneinrueckenmm && $newlvl > 0){
$this->Cell($belege_stuecklisteneinrueckenmm * $newlvl, $cellhoehe, ''); $this->Cell_typed($belege_stuecklisteneinrueckenmm * $newlvl, $cellhoehe, '');
} }
$this->Cell($posWidth); $this->Cell_typed($posWidth);
$this->Cell($itemNoWidth); $this->Cell_typed($itemNoWidth);
if($this->doctype==='arbeitsnachweis') { if($this->doctype==='arbeitsnachweis') {
$this->Cell($taxWidth); $this->Cell_typed($taxWidth);
} }
if($this->doctype==='lieferschein' && $this->getStyleElement('modul_verband')=='1'){ if($this->doctype==='lieferschein' && $this->getStyleElement('modul_verband')=='1'){
@@ -3392,17 +3399,17 @@ class Briefpapier extends SuperFPDF {
} }
} }
$this->Cell($taxWidth); $this->Cell_typed($taxWidth);
$this->Cell($amWidth); $this->Cell_typed($amWidth);
$this->Ln(); $this->Ln();
$this->SetFont($this->GetFont(),'',$tabelleninhalt); $this->SetFont($this->GetFont(),'',$tabelleninhalt);
$zeilenuntertext = $this->getStyleElement('zeilenuntertext'); $zeilenuntertext = $this->getStyleElement('zeilenuntertext');
$this->SetFont($this->GetFont(),'',$zeilenuntertext); $this->SetFont($this->GetFont(),'',$zeilenuntertext);
$this->Cell($posWidth); $this->Cell_typed($posWidth);
$this->Cell($itemNoWidth); $this->Cell_typed($itemNoWidth);
if($this->doctype==='arbeitsnachweis') { if($this->doctype==='arbeitsnachweis') {
$this->Cell($taxWidth); $this->Cell_typed($taxWidth);
} }
if($this->getStyleElement('artikeleinheit')=='1'){ if($this->getStyleElement('artikeleinheit')=='1'){
$this->MultiCell($descWidth - $einheitWidth, 4, '', 0); // 4 = abstand zwischen Artikeln $this->MultiCell($descWidth - $einheitWidth, 4, '', 0); // 4 = abstand zwischen Artikeln
@@ -3410,8 +3417,8 @@ class Briefpapier extends SuperFPDF {
else{ else{
$this->MultiCell($descWidth, 4, '', 0); // 4 = abstand zwischen Artikeln $this->MultiCell($descWidth, 4, '', 0); // 4 = abstand zwischen Artikeln
} }
$this->Cell($taxWidth); $this->Cell_typed($taxWidth);
$this->Cell($amWidth); $this->Cell_typed($amWidth);
$this->Ln(); $this->Ln();
$this->SetFont($this->GetFont(),'',$tabelleninhalt); $this->SetFont($this->GetFont(),'',$tabelleninhalt);
$yAfterDescription = $this->GetY(); $yAfterDescription = $this->GetY();
@@ -3421,11 +3428,11 @@ class Briefpapier extends SuperFPDF {
$this->SetY($position_y_end_name); $this->SetY($position_y_end_name);
$yBeforeDescription = $this->GetY(); $yBeforeDescription = $this->GetY();
$this->SetFont($this->GetFont(),'',$zeilenuntertext); $this->SetFont($this->GetFont(),'',$zeilenuntertext);
$this->Cell($posWidth); $this->Cell_typed($posWidth);
$this->Cell($itemNoWidth); $this->Cell_typed($itemNoWidth);
if($this->doctype==='arbeitsnachweis') if($this->doctype==='arbeitsnachweis')
{ {
$this->Cell($taxWidth); $this->Cell_typed($taxWidth);
} }
if($this->getStyleElement('artikeleinheit')=='1') if($this->getStyleElement('artikeleinheit')=='1')
{ {
@@ -3450,8 +3457,8 @@ class Briefpapier extends SuperFPDF {
$this->MultiCell($posWidth+$itemNoWidth+$descWidth+$amWidth+$taxWidth+$sumWidth+$priceWidth,($zeilenuntertext/2),trim($staffelpreistext),0,'R'); $this->MultiCell($posWidth+$itemNoWidth+$descWidth+$amWidth+$taxWidth+$sumWidth+$priceWidth,($zeilenuntertext/2),trim($staffelpreistext),0,'R');
} }
$this->Cell($taxWidth); $this->Cell_typed($taxWidth);
$this->Cell($amWidth); $this->Cell_typed($amWidth);
$this->Ln(); $this->Ln();
$this->SetFont($this->GetFont(),'',$tabelleninhalt); $this->SetFont($this->GetFont(),'',$tabelleninhalt);
$yAfterDescription = $this->GetY(); $yAfterDescription = $this->GetY();
@@ -3805,7 +3812,7 @@ class Briefpapier extends SuperFPDF {
$this->Image($dateiname, $this->GetX(), $this->GetY(),$width / 10, $hoehe / 10, 'jpg'); $this->Image($dateiname, $this->GetX(), $this->GetY(),$width / 10, $hoehe / 10, 'jpg');
if($nochtext == '') if($nochtext == '')
{ {
$this->Cell($picwidth,6,'',0,0,'C'); $this->Cell_typed($picwidth,6,'',0,0,'C');
} }
$this->SetXY($this->GetX(), $y + $height / 10 + ($nochtext == ''?5:0)); $this->SetXY($this->GetX(), $y + $height / 10 + ($nochtext == ''?5:0));
} }
@@ -4016,7 +4023,7 @@ class Briefpapier extends SuperFPDF {
} }
$this->SetX($x+$abstand_links); $this->SetX($x+$abstand_links);
$this->Cell($descWidth,4,$this->WriteHTML($html)); $this->Cell_typed($descWidth,4,$this->WriteHTML($html));
$this->SetX($x+$abstand_links+$descWidth); $this->SetX($x+$abstand_links+$descWidth);
//$this->SetX($x); //$this->SetX($x);
@@ -4050,7 +4057,7 @@ class Briefpapier extends SuperFPDF {
{ {
$ausrichtung = $data['Text_Ausrichtung']; $ausrichtung = $data['Text_Ausrichtung'];
} }
$this->Cell($priceWidth+$amWidth+$taxWidth+$priceWidth,4,$summe,$rahmen,0,$ausrichtung); $this->Cell_typed($priceWidth+$amWidth+$taxWidth+$priceWidth,4,$summe,$rahmen,0,$ausrichtung);
if(!empty($data['Abstand_Unten'])) if(!empty($data['Abstand_Unten']))
{ {
$this->Ln((int)$data['Abstand_Unten']); $this->Ln((int)$data['Abstand_Unten']);
@@ -4098,19 +4105,19 @@ class Briefpapier extends SuperFPDF {
//$this->Line(110, $this->GetY(), 190, $this->GetY()); //$this->Line(110, $this->GetY(), 190, $this->GetY());
$this->Ln(1); $this->Ln(1);
$this->SetFont($this->GetFont(),'',$this->getStyleElement('schriftgroesse_gesamt')); $this->SetFont($this->GetFont(),'',$this->getStyleElement('schriftgroesse_gesamt'));
$this->Cell($differenz_wegen_abstand,2,'',0); $this->Cell_typed($differenz_wegen_abstand,2,'',0);
if($this->getStyleElement('kleinunternehmer')!='1' && $this->doctype!='zahlungsavis'){ if($this->getStyleElement('kleinunternehmer')!='1' && $this->doctype!='zahlungsavis'){
$nettoText = $this->app->erp->Beschriftung('dokument_gesamtnetto'); $nettoText = $this->app->erp->Beschriftung('dokument_gesamtnetto');
$nettoAmount = $this->formatMoney(round((double)$this->totals['totalArticles'], 2), 2).' '.$this->waehrung; $nettoAmount = $this->formatMoney(round((double)$this->totals['totalArticles'], 2), 2).' '.$this->waehrung;
$doctype = $this->doctype; $doctype = $this->doctype;
$doctypeid = !empty($this->doctypeid)?$this->doctypeid: $this->id; $doctypeid = !empty($this->doctypeid)?$this->doctypeid: $this->id;
$this->app->erp->RunHook('class_briefpapier_render_netto', 4, $doctype, $doctypeid, $nettoText, $nettoAmount); $this->app->erp->RunHook('class_briefpapier_render_netto', 4, $doctype, $doctypeid, $nettoText, $nettoAmount);
$this->Cell(30,5,$nettoText,0,0,'L'); $this->Cell_typed(30,5,$nettoText,0,0,'L');
$this->Cell(40,5,$nettoAmount,0,'L','R'); $this->Cell_typed(40,5,$nettoAmount,0,0,'R');
} else { } else {
//kleinunzernehmer //kleinunzernehmer
$this->Cell(30,5,'',0,0,'L'); $this->Cell_typed(30,5,'',0,0,'L');
$this->Cell(40,5,'',0,'L','R'); $this->Cell_typed(40,5,'',0,0,'R');
} }
$this->Ln(); $this->Ln();
@@ -4121,16 +4128,16 @@ class Briefpapier extends SuperFPDF {
$versand = 'Versandkosten: '; $versand = 'Versandkosten: ';
} }
if(isset($this->totals['priceOfDispatch'])) { if(isset($this->totals['priceOfDispatch'])) {
$this->Cell($differenz_wegen_abstand,2,'',0); $this->Cell_typed($differenz_wegen_abstand,2,'',0);
$this->Cell(30,5,$versand,0,'L','L'); $this->Cell_typed(30,5,$versand,0,'L','L');
$this->Cell(40,5,$this->formatMoney((double)$this->totals['priceOfDispatch'], 2).' '.$this->waehrung,0,'L','R'); $this->Cell_typed(40,5,$this->formatMoney((double)$this->totals['priceOfDispatch'], 2).' '.$this->waehrung,0,0,'R');
} }
//$this->Ln(); //$this->Ln();
if(isset($this->totals['priceOfPayment']) && $this->totals['priceOfPayment']!='0.00'){ if(isset($this->totals['priceOfPayment']) && $this->totals['priceOfPayment']!='0.00'){
$this->Cell($differenz_wegen_abstand,2,'',0); $this->Cell_typed($differenz_wegen_abstand,2,'',0);
$this->Cell(30,5,$this->totals['modeOfPayment'],0,'L','L'); $this->Cell_typed(30,5,$this->totals['modeOfPayment'],0,'L','L');
$this->Cell(40,5,$this->formatMoney((double)$this->totals['priceOfPayment'], 2).' '.$this->waehrung,0,'L','R'); $this->Cell_typed(40,5,$this->formatMoney((double)$this->totals['priceOfPayment'], 2).' '.$this->waehrung,0,0,'R');
$this->Ln(); $this->Ln();
} }
@@ -4139,7 +4146,7 @@ class Briefpapier extends SuperFPDF {
if(isset($this->totals['totalTaxV']) && $this->totals['totalTaxV']!="0.00"){ if(isset($this->totals['totalTaxV']) && $this->totals['totalTaxV']!="0.00"){
$this->Cell($differenz_wegen_abstand,1,'',0); $this->Cell_typed($differenz_wegen_abstand,1,'',0);
if($this->getStyleElement('kleinunternehmer')!='1'){ if($this->getStyleElement('kleinunternehmer')!='1'){
if(!empty($this->doctype) && !empty($this->id) && is_numeric($this->id)){ if(!empty($this->doctype) && !empty($this->id) && is_numeric($this->id)){
@@ -4154,23 +4161,23 @@ class Briefpapier extends SuperFPDF {
//if(($this->anrede=="firma" || $this->app->erp->AnzeigeBelegNetto($this->anrede,$projekt) || $this->doctype=="bestellung" || $this->getStyleElement("immernettorechnungen",$projekt)=="1") //if(($this->anrede=="firma" || $this->app->erp->AnzeigeBelegNetto($this->anrede,$projekt) || $this->doctype=="bestellung" || $this->getStyleElement("immernettorechnungen",$projekt)=="1")
// && $this->getStyleElement("immerbruttorechnungen",$projekt)!="1") // && $this->getStyleElement("immerbruttorechnungen",$projekt)!="1")
{ {
$this->Cell(30,3,$this->app->erp->Beschriftung('dokument_zzglmwst').' '.$this->app->erp->GetSteuersatzNormal(false,$this->id,$this->table).' %',0,'L','L'); //1 $this->Cell_typed(30,3,$this->app->erp->Beschriftung('dokument_zzglmwst').' '.$this->app->erp->GetSteuersatzNormal(false,$this->id,$this->table).' %',0,0,'L'); //1
} }
else { else {
$this->Cell(30,3,$this->app->erp->Beschriftung('dokument_inklmwst').' '.$this->app->erp->GetSteuersatzNormal(false,$this->id,$this->table).' %',0,'L','L'); $this->Cell_typed(30,3,$this->app->erp->Beschriftung('dokument_inklmwst').' '.$this->app->erp->GetSteuersatzNormal(false,$this->id,$this->table).' %',0,0,'L');
} }
$this->Cell(40,3,$this->formatMoney((double)$this->totals['totalTaxV'], 2).' '.$this->waehrung,0,'L','R'); $this->Cell_typed(40,3,$this->formatMoney((double)$this->totals['totalTaxV'], 2).' '.$this->waehrung,0,0,'R');
} else { } else {
//kleinunternehmer //kleinunternehmer
$this->Cell(30,3,'',0,'L','L'); $this->Cell_typed(30,3,'',0,0,'L');
$this->Cell(40,3,'',0,'L','R'); $this->Cell_typed(40,3,'',0,0,'R');
} }
$this->Ln(); $this->Ln();
} }
$projekt = $this->projekt; $projekt = $this->projekt;
$adresse = $this->app->DB->Select("SELECT adresse FROM ".($this->table?$this->table:$this->doctype)." WHERE id = '".$this->id."' LIMIT 1"); $adresse = $this->app->DB->Select("SELECT adresse FROM ".($this->table?$this->table:$this->doctype)." WHERE id = '".$this->id."' LIMIT 1");
if(!empty($this->totals['totalTaxR']) && $this->totals['totalTaxR']!='0.00'){ if(!empty($this->totals['totalTaxR']) && $this->totals['totalTaxR']!='0.00'){
$this->Cell($differenz_wegen_abstand,1,'',0); $this->Cell_typed($differenz_wegen_abstand,1,'',0);
if($this->getStyleElement('kleinunternehmer')!='1'){ if($this->getStyleElement('kleinunternehmer')!='1'){
@@ -4178,17 +4185,17 @@ class Briefpapier extends SuperFPDF {
//if(($this->anrede=="firma" || $this->app->erp->AnzeigeBelegNetto($this->anrede,$projekt) || $this->doctype=="bestellung" || $this->getStyleElement("immernettorechnungen",$projekt)=="1") //if(($this->anrede=="firma" || $this->app->erp->AnzeigeBelegNetto($this->anrede,$projekt) || $this->doctype=="bestellung" || $this->getStyleElement("immernettorechnungen",$projekt)=="1")
// && $this->getStyleElement("immerbruttorechnungen",$projekt)!="1") // && $this->getStyleElement("immerbruttorechnungen",$projekt)!="1")
{ {
$this->Cell(30,3,$this->app->erp->Beschriftung('dokument_zzglmwst').' '.$this->app->erp->GetSteuersatzErmaessigt(false,$this->id,$this->table).' %',0,'L','L'); //1 $this->Cell_typed(30,3,$this->app->erp->Beschriftung('dokument_zzglmwst').' '.$this->app->erp->GetSteuersatzErmaessigt(false,$this->id,$this->table).' %',0,0,'L'); //1
} }
else { else {
$this->Cell(30,3,$this->app->erp->Beschriftung('dokument_inklmwst').' '.$this->app->erp->GetSteuersatzErmaessigt(false,$this->id,$this->table).' %',0,'L','L'); $this->Cell_typed(30,3,$this->app->erp->Beschriftung('dokument_inklmwst').' '.$this->app->erp->GetSteuersatzErmaessigt(false,$this->id,$this->table).' %',0,0,'L');
} }
$this->Cell(40,3,$this->formatMoney(round((double)$this->totals['totalTaxR'],2), 2).' '.$this->waehrung,0,'L','R'); $this->Cell_typed(40,3,$this->formatMoney(round((double)$this->totals['totalTaxR'],2), 2).' '.$this->waehrung,0,0,'R');
} else { } else {
//kleinunternehmer //kleinunternehmer
$this->Cell(30,3,'',0,'L','L'); $this->Cell_typed(30,3,'',0,0,'L');
$this->Cell(40,3,"",0,'L','R'); $this->Cell_typed(40,3,"",0,0,'R');
} }
$this->Ln(); $this->Ln();
@@ -4203,24 +4210,24 @@ class Briefpapier extends SuperFPDF {
{ {
continue; continue;
} }
$this->Cell($differenz_wegen_abstand,1,'',0); $this->Cell_typed($differenz_wegen_abstand,1,'',0);
if($this->getStyleElement('kleinunternehmer')!='1'){ if($this->getStyleElement('kleinunternehmer')!='1'){
if($this->app->erp->AnzeigeBelegNettoAdresse($this->anrede, $this->doctype, $projekt, $adresse,$this->id)) if($this->app->erp->AnzeigeBelegNettoAdresse($this->anrede, $this->doctype, $projekt, $adresse,$this->id))
//if(($this->anrede=="firma" || $this->app->erp->AnzeigeBelegNetto($this->anrede,$projekt) || $this->doctype=="bestellung" || $this->getStyleElement("immernettorechnungen",$projekt)=="1") //if(($this->anrede=="firma" || $this->app->erp->AnzeigeBelegNetto($this->anrede,$projekt) || $this->doctype=="bestellung" || $this->getStyleElement("immernettorechnungen",$projekt)=="1")
// && $this->getStyleElement("immerbruttorechnungen",$projekt)!="1") // && $this->getStyleElement("immerbruttorechnungen",$projekt)!="1")
{ {
$this->Cell(30,3,$this->app->erp->Beschriftung('dokument_zzglmwst').' '.$k.' %',0,'L','L'); //1 $this->Cell_typed(30,3,$this->app->erp->Beschriftung('dokument_zzglmwst').' '.$k.' %',0,0,'L'); //1
}else { }else {
//$this->Cell(30,3,$this->app->erp->Beschriftung('dokument_inklmwst').' '.$k.' %',0,'L','L'); 09.12.2018 ab heute auskommentiert wegen 829087 //$this->Cell_typed(30,3,$this->app->erp->Beschriftung('dokument_inklmwst').' '.$k.' %',0,'L','L'); 09.12.2018 ab heute auskommentiert wegen 829087
$this->Cell(30,3,$this->app->erp->Beschriftung('dokument_zzglmwst').' '.$k.' %',0,'L','L'); $this->Cell_typed(30,3,$this->app->erp->Beschriftung('dokument_zzglmwst').' '.$k.' %',0,0,'L');
} }
$this->Cell(40,3,$this->formatMoney(round($value,2), 2).' '.$this->waehrung,0,'L','R'); $this->Cell_typed(40,3,$this->formatMoney(round($value,2), 2).' '.$this->waehrung,0,0,'R');
} else { } else {
//kleinunternehmer //kleinunternehmer
$this->Cell(30,3,'',0,'L','L'); $this->Cell_typed(30,3,'',0,0,'L');
$this->Cell(40,3,"",0,'L','R'); $this->Cell_typed(40,3,"",0,0,'R');
} }
$this->Ln(); $this->Ln();
@@ -4231,7 +4238,7 @@ class Briefpapier extends SuperFPDF {
if(!isset($this->totals['totalTaxR']) && !isset($this->totals['totalTaxV']) && !isset($this->totals['summen']) && $this->doctype!="zahlungsavis") if(!isset($this->totals['totalTaxR']) && !isset($this->totals['totalTaxV']) && !isset($this->totals['summen']) && $this->doctype!="zahlungsavis")
{ {
$this->Cell($differenz_wegen_abstand,3,'',0); $this->Cell_typed($differenz_wegen_abstand,3,'',0);
if($this->getStyleElement('kleinunternehmer')!='1') if($this->getStyleElement('kleinunternehmer')!='1')
{ {
@@ -4241,24 +4248,24 @@ class Briefpapier extends SuperFPDF {
{ {
if(!($this->ust_befreit==3 && $this->getStyleElement('steuerfrei_inland_ausblenden')=='1')) //steuerfrei inland if(!($this->ust_befreit==3 && $this->getStyleElement('steuerfrei_inland_ausblenden')=='1')) //steuerfrei inland
{ {
$this->Cell(30, 3, $this->app->erp->Beschriftung('dokument_zzglmwst') . ' 0.00 %', 0, 'L', 'L'); //1 $this->Cell_typed(30, 3, $this->app->erp->Beschriftung('dokument_zzglmwst') . ' 0.00 %', 0, 0, 'L'); //1
} }
} }
else { else {
if(!($this->ust_befreit==3 && $this->getStyleElement('steuerfrei_inland_ausblenden')=='1')) //steuerfrei inland if(!($this->ust_befreit==3 && $this->getStyleElement('steuerfrei_inland_ausblenden')=='1')) //steuerfrei inland
{ {
$this->Cell(30, 3, $this->app->erp->Beschriftung('dokument_inklmwst') . ' 0.00 %', 0, 'L', 'L'); $this->Cell_typed(30, 3, $this->app->erp->Beschriftung('dokument_inklmwst') . ' 0.00 %', 0, 0, 'L');
} }
} }
if(!($this->ust_befreit==3 && $this->getStyleElement('steuerfrei_inland_ausblenden')=='1')) //steuerfrei inland if(!($this->ust_befreit==3 && $this->getStyleElement('steuerfrei_inland_ausblenden')=='1')) //steuerfrei inland
{ {
$this->Cell(40, 3, '0,00 ' . $this->waehrung, 0, 'L', 'R'); $this->Cell_typed(40, 3, '0,00 ' . $this->waehrung, 0, 0, 'R');
} }
} else { } else {
//kleinunternehmer //kleinunternehmer
$this->Cell(30,3,'',0,'L','L'); $this->Cell_typed(30,3,'',0,0,'L');
$this->Cell(40,3,'',0,'L','R'); $this->Cell_typed(40,3,'',0,0,'R');
} }
$this->Ln(); $this->Ln();
} }
@@ -4267,32 +4274,32 @@ class Briefpapier extends SuperFPDF {
} }
$this->SetFont($this->GetFont(),'B',$this->getStyleElement('schriftgroesse_gesamt')); $this->SetFont($this->GetFont(),'B',$this->getStyleElement('schriftgroesse_gesamt'));
$this->Cell($differenz_wegen_abstand,5,'',0); $this->Cell_typed($differenz_wegen_abstand,5,'',0);
if($this->doctype=='offer'){ if($this->doctype=='offer'){
$this->Cell(30, 5, $this->app->erp->Beschriftung('dokument_gesamt_total'), 0, 'L', 'L'); $this->Cell_typed(30, 5, $this->app->erp->Beschriftung('dokument_gesamt_total'), 0, 0, 'L');
} }
elseif($this->doctype=='creditnote'){ elseif($this->doctype=='creditnote'){
$this->Cell(30, 5, $this->app->erp->Beschriftung('dokument_gesamt_total'), 0, 'L', 'L'); $this->Cell_typed(30, 5, $this->app->erp->Beschriftung('dokument_gesamt_total'), 0, 0, 'L');
} }
else if($this->doctype=='arbeitsnachweis'){ else if($this->doctype=='arbeitsnachweis'){
$this->Cell(30, 5, $this->app->erp->Beschriftung('dokument_gesamt_total'), 0, 'L', 'L'); $this->Cell_typed(30, 5, $this->app->erp->Beschriftung('dokument_gesamt_total'), 0, 0, 'L');
} }
else if($this->doctype=='zahlungsavis'){ else if($this->doctype=='zahlungsavis'){
$this->Cell(30, 5, $this->app->erp->Beschriftung('dokument_gesamt_total'), 0, 'L', 'L'); $this->Cell_typed(30, 5, $this->app->erp->Beschriftung('dokument_gesamt_total'), 0, 0, 'L');
} }
else{ else{
$this->Cell(30, 5, $this->app->erp->Beschriftung('dokument_gesamt_total'), 0, 'L', 'L'); $this->Cell_typed(30, 5, $this->app->erp->Beschriftung('dokument_gesamt_total'), 0, 0, 'L');
} }
if($this->doctype=='arbeitsnachweis'){ if($this->doctype=='arbeitsnachweis'){
$this->Cell(40, 5, $this->totals['total'] . ' ', 0, 'L', 'R'); $this->Cell_typed(40, 5, $this->totals['total'] . ' ', 0, 0, 'R');
} }
else { else {
if($this->getStyleElement('kleinunternehmer')!='1'){ if($this->getStyleElement('kleinunternehmer')!='1'){
$this->Cell(40, 5, $this->formatMoney(round((double)$this->totals['total'], 2), 2) . ' ' . $this->waehrung, 0, 'L', 'R'); $this->Cell_typed(40, 5, $this->formatMoney(round((double)$this->totals['total'], 2), 2) . ' ' . $this->waehrung, 0, 0, 'R');
} }
else{ else{
$this->Cell(40, 5, $this->formatMoney(round((double)$this->totals['totalArticles'], 2), 2) . ' ' . $this->waehrung, 0, 'L', 'R'); $this->Cell_typed(40, 5, $this->formatMoney(round((double)$this->totals['totalArticles'], 2), 2) . ' ' . $this->waehrung, 0, 0, 'R');
} }
} }
+7 -1
View File
@@ -353,11 +353,17 @@ class fpdi extends fpdf_tpl {
$this->_out("<<",false); $this->_out("<<",false);
reset ($value[1]); reset ($value[1]);
/*
while (list($k, $v) = each($value[1])) { while (list($k, $v) = each($value[1])) {
$this->_out($k . " ",false); $this->_out($k . " ",false);
$this->pdf_write_value($v); $this->pdf_write_value($v);
} }
*/
foreach($value[1] as $k => $v) {
$this->_out($k . " ",false);
$this->pdf_write_value($v);
}
$this->_out(">>"); $this->_out(">>");
break; break;
+60 -4
View File
@@ -659,8 +659,10 @@ class Adresse extends GenAdresse {
$this->AdresseBriefPreview('dokumente',$id,false); $this->AdresseBriefPreview('dokumente',$id,false);
break; break;
case '2': case '2':
$this->AdresseBriefPreview('dokumente_send',$id,false);
$this->AdresseBriefPreview('dokumente_send',$id,false); break;
case '4':
$this->AdresseBriefPreview('ticket_nachricht',$id,false);
break; break;
case '5': case '5':
@@ -3736,11 +3738,21 @@ function AdresseBriefErstellen() {
if (!empty($adresse['email'])) { if (!empty($adresse['email'])) {
$this->app->Tpl->Add('EMAIL_AN',str_replace('"','&#34;',$adresse['name']) . ' &lt;' . $adresse['email'] . '&gt;'); $this->app->Tpl->Add('EMAIL_AN',str_replace('"','&#34;',$adresse['name']) . ' &lt;' . $adresse['email'] . '&gt;');
} }
$anschreiben = $this->app->DB->Select("SELECT anschreiben FROM adresse WHERE id='".$ticket_from_db['adresse']."' LIMIT 1");
if($anschreiben=="")
{
$anschreiben = $this->app->erp->Beschriftung("dokument_anschreiben").",\n".$this->app->erp->Grussformel($projekt,$sprache);
}
$this->app->Tpl->Add('CONTENT',$anschreiben);
$projekt = $this->app->DB->Select("SELECT abkuerzung FROM projekt INNER JOIN adresse ON adresse.projekt = projekt.id WHERE adresse.id='".$id."' LIMIT 1");
$this->app->Tpl->Set('PROJEKT', $projekt);
$anhaenge = ''; $anhaenge = '';
$anhaenge .= '<tr><td nowrap>Datei:</td><td><input type="file" name="upload[]" id="file" /></td></tr>'; $anhaenge .= '<tr><td nowrap>Datei:</td><td><input type="file" name="upload[]" id="file" /></td></tr>';
// $anhaenge .= '<tr><td nowrap>Datei 2:</td><td><input type="file" name="upload[]" /></td></tr>'; // $anhaenge .= '<tr><td nowrap>Datei 2:</td><td><input type="file" name="upload[]" /></td></tr>';
// $anhaenge .= '<tr><td nowrap>Datei 3:</td><td><input type="file" name="upload[]" /></td></tr>'; // $anhaenge .= '<tr><td nowrap>Datei 3:</td><td><input type="file" name="upload[]" /></td></tr>';
$this->app->Tpl->Add('ANHAENGEHERAUFLADEN', $anhaenge); $this->app->Tpl->Add('ANHAENGEHERAUFLADEN', $anhaenge);
$anhaenge = '<tr><td colspan=3 align=center><i>Keine Anh&auml;nge vorhanden</i></td></tr>'; $anhaenge = '<tr><td colspan=3 align=center><i>Keine Anh&auml;nge vorhanden</i></td></tr>';
@@ -4073,6 +4085,19 @@ function AdresseBriefPreview($type = '', $id = '', $json = true) {
id = ' . $id . ' id = ' . $id . '
'; ';
break; break;
case 'ticket_nachricht':
$query .= '
SELECT
id,
DATE_FORMAT(zeit, "%d.%m.%Y") as datum,
betreff,
text as content
FROM
ticket_nachricht
WHERE
id = ' . $id . '
';
break;
case 'wiedervorlage': case 'wiedervorlage':
$query .= ' $query .= '
SELECT SELECT
@@ -4970,6 +4995,7 @@ function AdresseBrief() {
$count += $this->app->DB->Select('SELECT count(id) FROM dokumente_send WHERE adresse = ' . $id); $count += $this->app->DB->Select('SELECT count(id) FROM dokumente_send WHERE adresse = ' . $id);
$count += $this->app->DB->Select('SELECT count(id) FROM wiedervorlage WHERE adresse = ' . $id); $count += $this->app->DB->Select('SELECT count(id) FROM wiedervorlage WHERE adresse = ' . $id);
$count += $this->app->DB->Select('SELECT count(id) FROM kalender_event WHERE adresse = '.$id); $count += $this->app->DB->Select('SELECT count(id) FROM kalender_event WHERE adresse = '.$id);
$count += $this->app->DB->Select('SELECT count(tn.id) FROM ticket_nachricht tn INNER JOIN ticket t ON tn.ticket = t.schluessel WHERE t.adresse = '.$id);
if ($count > 0) { if ($count > 0) {
$this->app->YUI->TableSearch('TABELLE', 'adresse_brief'); $this->app->YUI->TableSearch('TABELLE', 'adresse_brief');
@@ -6358,6 +6384,8 @@ function AdresseVerein()
} }
/** /**
* Query for adresse minidetail
* CRM view inside adresse page is in adresse.php
* @param int $adresseId AdressID * @param int $adresseId AdressID
* @param int $maxResults SQL-Limit; Maximale Anzahl der Ergebnisse * @param int $maxResults SQL-Limit; Maximale Anzahl der Ergebnisse
* *
@@ -6489,7 +6517,8 @@ function AdresseVerein()
SELECT SELECT
w.id, w.id,
CONCAT(DATE_FORMAT(datum_erinnerung, "%Y-%m-%d"), " ", IF(zeit_erinnerung IS NULL OR DATE_FORMAT(zeit_erinnerung, "%H:%i")="00:00", "", DATE_FORMAT(zeit_erinnerung, "%H:%i")) ) as datum, CONCAT(DATE_FORMAT(datum_erinnerung, "%Y-%m-%d"), " ", IF(zeit_erinnerung IS NULL OR DATE_FORMAT(zeit_erinnerung, "%H:%i")="00:00", "", DATE_FORMAT(zeit_erinnerung, "%H:%i")) ) as datum,
w.bezeichnung COLLATE utf8_general_ci as title,\'\' as ansprechpartner, w.bezeichnung COLLATE utf8_general_ci as title,
\'\' as ansprechpartner,
p.abkuerzung COLLATE utf8_general_ci as abkuerzung, p.abkuerzung COLLATE utf8_general_ci as abkuerzung,
adr.name COLLATE utf8_general_ci as bearbeiter, adr.name COLLATE utf8_general_ci as bearbeiter,
CONCAT("Wiedervorlage") as art, CONCAT("Wiedervorlage") as art,
@@ -6506,6 +6535,32 @@ function AdresseVerein()
)'; )';
} }
} }
$sql .= 'UNION ALL
(
SELECT
t.id,
tn.zeit,
tn.betreff,
ifnull((SELECT name FROM ansprechpartner ap WHERE ap.adresse = a.id AND ap.email = tn.mail LIMIT 1),tn.mail) as ansprechpartner,
p.abkuerzung,
tn.verfasser,
\'Ticketnachricht\' as art,
CONCAT(IF(tn.versendet = 1, "JA", "NEIN"),"<a data-type=ticket_nachricht data-id=", t.id, "></a>") as gesendet,
\'\' as PDF,
concat("4","-",tn.id) as did,
CONCAT(tn.text,t.notiz) as suchtext,
\'\' as intern
FROM
ticket_nachricht tn
INNER JOIN ticket t ON
tn.ticket = t.schluessel
INNER JOIN adresse a ON t.adresse = a.id
LEFT JOIN projekt p ON t.projekt = p.id
WHERE t.adresse = '.$adresseId.' AND !(tn.versendet = 1 AND tn.zeitausgang IS NULL)
)
';
$sql .= ') AS a '; $sql .= ') AS a ';
$sql .= 'ORDER BY a.datum DESC '; $sql .= 'ORDER BY a.datum DESC ';
$sql .= 'LIMIT 0, ' . $maxResults; $sql .= 'LIMIT 0, ' . $maxResults;
@@ -6514,3 +6569,4 @@ function AdresseVerein()
} }
} }
+8 -1
View File
@@ -1287,7 +1287,14 @@ class Ajax {
for($i = 0; $i < $carr; $i++) { for($i = 0; $i < $carr; $i++) {
$newarr[] = "{$arr[$i]['name2']}"; $newarr[] = "{$arr[$i]['name2']}";
} }
break; break;
case 'warteschlangename':
$arr = $this->app->DB->SelectArr("SELECT CONCAT(label, ' ', warteschlange) as result from warteschlangen");
$carr = !empty($arr)?count($arr):0;
for($i = 0; $i < $carr; $i++) {
$newarr[] = "{$arr[$i]['result']}";
}
break;
/* /*
select a.kundennummer, (SELECT name FROM adresse a2 WHERE a2.kundennummer = a.kundennummer order by a2.projekt = 13 DESC, a2.projekt = 0 DESC, projekt LIMIT 1) as name FROM adresse a WHERE a.kundennummer like '10500' group by a.kundennummer select a.kundennummer, (SELECT name FROM adresse a2 WHERE a2.kundennummer = a.kundennummer order by a2.projekt = 13 DESC, a2.projekt = 0 DESC, projekt LIMIT 1) as name FROM adresse a WHERE a.kundennummer like '10500' group by a.kundennummer
+7004 -6816
View File
File diff suppressed because it is too large Load Diff
+6 -6
View File
@@ -228,12 +228,12 @@ input[type=button].anlegen_close {
var ersterEintrag = [TABELLEFLAG]; var ersterEintrag = [TABELLEFLAG];
function edit_Eintrag(elem) function edit_Eintrag(elem)
{ {
var entryData = $(elem).parent().parent().parent().parent().parent().parent().find('a').first(); var entryData = $(elem).parent().parent().parent().parent().parent().parent().find('a').first();
var entryDataDokument = entryData.attr('data-type'); var entryDataDokument = entryData.attr('data-type');
entryDataId = entryData.attr('data-id');
// entryData = entryData.split('||');
if (entryDataDokument != 'dokumente' && entryDataDokument != 'wiedervorlage' && entryDataDokument != 'kalender') { entryDataId = entryData.attr('data-id');
if (entryDataDokument != 'dokumente' && entryDataDokument != 'wiedervorlage' && entryDataDokument != 'kalender') {
if(entryDataDokument == 'dokumente_send') if(entryDataDokument == 'dokumente_send')
{ {
var artel = $(elem).parents('tr').first().parents('tr').first().find('span.editlink').first(); var artel = $(elem).parents('tr').first().parents('tr').first().find('span.editlink').first();
@@ -243,7 +243,7 @@ var ersterEintrag = [TABELLEFLAG];
} }
else if(entryDataDokument == 'ticket_nachricht') else if(entryDataDokument == 'ticket_nachricht')
{ {
window.open('index.php?module=ticket&action=assistent&id='+entryDataId,'_blank'); window.open('index.php?module=ticket&action=edit&id='+entryDataId,'_blank');
return; return;
} }
+14 -32
View File
@@ -1,16 +1,14 @@
<div id="tabs"> <div id="tabs">
<ul> <ul>
<li><a href="#tabs-2">[TABTEXT2]</a></li> <li><a href="#tabs-1">[TABTEXT1]</a></li>
[VORTABS3UEBERSCHRIFT]<li><a href="#tabs-3">[TABTEXT3]</a></li>[NACHTABS3UEBERSCHRIFT] [VORTABS2UEBERSCHRIFT]<li><a href="#tabs-2">[TABTEXT2]</a></li>[NACHTABS2UEBERSCHRIFT]
</ul> </ul>
<div id="tabs-1">
<div id="tabs-2"> [MESSAGE]
[AUTOVERSANDBERECHNEN] [AUTOVERSANDBERECHNEN]
<form action="#tabs-1" id="frmauto" name="frmauto" method="post">
<form action="#tabs-2" id="frmauto" name="frmauto" method="post">
<div class="filter-box filter-usersave"> <div class="filter-box filter-usersave">
<div class="filter-block filter-inline"> <div class="filter-block filter-inline">
<div class="filter-title">{|Filter|}</div> <div class="filter-title">{|Filter|}</div>
@@ -34,13 +32,12 @@
<input type="checkbox" id="auftrag_lieferdatum"> <input type="checkbox" id="auftrag_lieferdatum">
<span class="slider round"></span> <span class="slider round"></span>
</label> </label>
<label for="auftrag_lieferdatum">{|nur Auftr&auml;ge mit zukünftigem Lieferdatum|}</label> <label for="auftrag_lieferdatum">{|inkl. Auftr&auml;ge mit zukünftigem Lieferdatum|}</label>
</li> </li>
</ul> </ul>
</div> </div>
</div> </div>
[TAB1]
[TAB2]
<fieldset> <fieldset>
<legend>Stapelverarbeitung</legend> <legend>Stapelverarbeitung</legend>
<input type="checkbox" value="1" id="autoalle" checked="checked" />&nbsp;alle markieren&nbsp; <input type="checkbox" value="1" id="autoalle" checked="checked" />&nbsp;alle markieren&nbsp;
@@ -59,32 +56,17 @@
</fieldset> </fieldset>
</form> </form>
</div> </div>
<div id="tabs-3">
[VORTABS3UEBERSCHRIFT]
<form action="#tabs-3" method="post">
<div class="filter-box filter-usersave">
<div class="filter-block filter-inline">
<div class="filter-title">{|Filter|}</div>
<ul class="filter-list">
<li class="filter-item">
<label for="autoallewartend" class="switch">
<input type="checkbox" value="1" id="autoallewartend" checked="checked" />
<span class="slider round"></span>
</label>
<label for="autoallewartend">{|Alle|}</label>
</li>
</ul>
</div>
</div>
[TAB3] <div id="tabs-2">
<table width="100%"><tr><td><input type="submit" value="Auftr&auml;ge aus Liste entfernen" name="entfernen"></td> [VORTABS2UEBERSCHRIFT]
<form action="#tabs-2" method="post">
[TAB2]
<table width="100%"><tr><td><input type="submit" value="Gew&auml;hlte Auftr&auml;ge zurücksetzen" name="entfernen"></td>
</tr></table> </tr></table>
</form> </form>
[NACHTABS3UEBERSCHRIFT] [NACHTABS2UEBERSCHRIFT]
</div> </div>
</div> </div>
<script> <script>
+1 -5
View File
@@ -12,7 +12,7 @@ document.onkeydown = function(evt) {
<div id="tabs"> <div id="tabs">
<ul> <ul>
<li><a href="#tabs-1">{|Auftr&auml;ge|}</a></li> <li><a href="#tabs-1">{|Auftr&auml;ge|}</a></li>
<li><a href="#tabs-5">{|in Bearbeitung|}</a></li> <li><a href="#tabs-5">{|in Bearbeitung|}[TABTEXT5]</a></li>
</ul> </ul>
<div id="tabs-1"> <div id="tabs-1">
@@ -113,10 +113,6 @@ document.onkeydown = function(evt) {
<div id="tabs-5"> <div id="tabs-5">
[TAB5] [TAB5]
</div> </div>
</div> </div>
<div id="lagermehrpopup" style="display:none;"> <div id="lagermehrpopup" style="display:none;">
<div id="lagermehrpopupinhalt"> <div id="lagermehrpopupinhalt">
+19 -28
View File
@@ -1,44 +1,35 @@
<div id="tabs"> <div id="tabs">
<ul> <ul>
<li><a href="#tab1">&Uuml;bersicht</a></li> <li><a href="#tab1">&Uuml;bersicht</a></li>
<li><a href="#tab2">neue Version anlegen</a></li> <li><a href="#tab2">neue Version anlegen</a></li>
</ul> </ul>
<!-- ende gehort zu tabview --> <!-- ende gehort zu tabview -->
<!-- erstes tab --> <!-- erstes tab -->
<div id="tab1"> <div id="tab1">
<form action="" method="post" name="eprooform" enctype="multipart/form-data"> <form action="" method="post" name="eprooform" enctype="multipart/form-data">
<h2>Beschreibung</h2>
<table border="0" width="100%">
<h2>Beschreibung</h2>
<table border="0" width="100%">
<tr><td>Titel</td><td colspan="3"><input type="text" size="30" name="titel" value="[TITEL]"></td></tr> <tr><td>Titel</td><td colspan="3"><input type="text" size="30" name="titel" value="[TITEL]"></td></tr>
<tr><td>Beschreibung</td><td colspan="3"><textarea cols="35" rows="5" name="beschreibung">[BESCHREIBUNG]</textarea></td></tr> <tr><td>Beschreibung</td><td colspan="3"><textarea cols="35" rows="5" name="beschreibung">[BESCHREIBUNG]</textarea></td></tr>
</table>
<h2>Versionen</h2>
</table> [VERSIONEN]
<h2>Zuordnungen</h2>
<h2>Versionen</h2>[VERSIONEN] [STICHWOERTER]
<h2>Stichworte</h2>[STICHWORTE] <table border="0" width="100%">
<tr>
<td width="" valign="" height="" bgcolor="" align="right" bordercolor="" classname="orange2" class="orange2">
<table border="0" width="100%"> <input type="submit" name="speichern" value="Speichern" />
<tr valign="" height="" bgcolor="" align="" bordercolor="" class="klein" classname="klein"> </td>
<td width="" valign="" height="" bgcolor="" align="right" colspan="4" bordercolor="" classname="orange2" class="orange2"> </tr>
<input type="submit" name="speichern" <tr>
value="Speichern" /> <input type="button" value="Abbrechen" /></td> <td width="" valign="" height="" bgcolor="" align="right" bordercolor="" classname="orange2" class="orange2">
</tr> <input type="submit" value="Abbrechen" />
</td>
</table> </tr>
</table>
</form> </form>
</div> </div>
<div id="tab2"> <div id="tab2">
[NEUEVERSION] [NEUEVERSION]
+7 -7
View File
@@ -19,7 +19,7 @@
<tr valign="middle"><td>Stichwort:</td><td colspan="3"> <tr valign="middle"><td>Stichwort:</td><td colspan="3">
<table> <table>
<tr> <tr>
<td><select name="huhu" onchange="document.getElementById('subjekt').value=document.eprooform.huhu.options[document.eprooform.huhu.selectedIndex].value"> <td><select name="subjektselect" onchange="document.getElementById('subjekt').value=document.eprooform.subjektselect.options[document.eprooform.subjektselect.selectedIndex].value">
<option value=""></option> <option value=""></option>
<option value="Bild">Bild</option> <option value="Bild">Bild</option>
<option value="Schaltplan">Schaltplan</option> <option value="Schaltplan">Schaltplan</option>
@@ -32,17 +32,17 @@
<option value="Schaltplan">UST-Pr&uuml;fung</option> <option value="Schaltplan">UST-Pr&uuml;fung</option>
</select></td> </select></td>
<td>von</td> <td>von</td>
<td><select> <td><select name="objekt">
<option value="Projekt">Projekt %</option> <option value="Projekt">Projekt ID</option>
<option value="Kunde">Kunde %</option> <option value="Kunde">Kunde ID</option>
<option value="Artikel">Artikel %</option> <option value="Artikel">Artikel ID</option>
<option value="Auftrag">Auftrag %</option> <option value="Auftrag">Auftrag ID</option>
</select></td> </select></td>
</tr> </tr>
<tr> <tr>
<td><input type="text" size="15" name="subjekt" id="subjekt" value="[SUBJEKT]"></td> <td><input type="text" size="15" name="subjekt" id="subjekt" value="[SUBJEKT]"></td>
<td>&nbsp;</td> <td>&nbsp;</td>
<td><input type="text" size="15" name="objekt" value="[OBJEKT]"></td> <td><input type="text" size="15" name="nummer" value="[NUMMER]"></td>
</tr> </tr>
</table> </table>
</td></tr> </td></tr>
+5
View File
@@ -0,0 +1,5 @@
<div id="tabs-1">
[MESSAGE]
[TAB1]
[TAB1NEXT]
</div>
+10 -10
View File
@@ -24,7 +24,7 @@
</tr> </tr>
<tr align="center"> <tr align="center">
<td><a [TICKETVORLAGENLINK]>{|Ticket Vorlagen|}</a></td> <td><a [TICKETVORLAGENLINK]>{|Ticket Vorlagen|}</a></td>
<td><a [WARTESCHLANGENLINK]>{|Warteschlangen|}</a></td> <td><a [WARTESCHLANGENLINK]>{|Ticket Warteschlangen|}</a></td>
<!--<td><a href="index.php?module=generic&action=edit">Startseite</a></td>--> <!--<td><a href="index.php?module=generic&action=edit">Startseite</a></td>-->
<td><a [ARTIKELKATEGORIENLINK]>{|Artikel Kategorien|}</a></td> <td><a [ARTIKELKATEGORIENLINK]>{|Artikel Kategorien|}</a></td>
<td><a href="index.php?module=artikeleinheit&action=list">{|Artikel Einheiten|}</a></td> <td><a href="index.php?module=artikeleinheit&action=list">{|Artikel Einheiten|}</a></td>
@@ -106,47 +106,47 @@
<table width="800" border="0" align="center"> <table width="800" border="0" align="center">
<tr align="center"> <tr align="center">
<td width="25%"><a href="index.php?module=prozessstarter&action=list"><img src="./themes/[THEME]/images/einstellungen/Icons_dunkel_22.gif" border="0" width="30%"></a></td> <td width="25%"><a href="index.php?module=prozessstarter&action=list"><img src="./themes/[THEME]/images/einstellungen/Icons_dunkel_22.gif" border="0" width="30%"></a></td>
<td width="25%"><a href="index.php?module=protokoll&action=list"><img src="./themes/[THEME]/images/einstellungen/Icons_dunkel_22.gif" border="0" width="30%"></a></td>
<td width="25%"><a href="index.php?module=logfile&action=list"><img src="./themes/[THEME]/images/einstellungen/Icons_dunkel_22.gif" border="0" width="30%"></a></td> <td width="25%"><a href="index.php?module=logfile&action=list"><img src="./themes/[THEME]/images/einstellungen/Icons_dunkel_22.gif" border="0" width="30%"></a></td>
<td width="25%"><a href="index.php?module=welcome&action=info"><img src="./themes/[THEME]/images/einstellungen/Icons_dunkel_23.gif" border="0" width="30%"></a></td> <td width="25%"><a href="index.php?module=log&action=list"><img src="./themes/[THEME]/images/einstellungen/Icons_dunkel_22.gif" border="0" width="30%"></a></td>
<td width="25%"><a href="index.php?module=drucker&action=list"><img src="./themes/[THEME]/images/einstellungen/Icons_dunkel_24.gif" border="0" width="30%"></a></td>
</tr> </tr>
<tr align="center"> <tr align="center">
<td><a href="index.php?module=prozessstarter&action=list">{|Prozessstarter|}</a></td> <td><a href="index.php?module=prozessstarter&action=list">{|Prozessstarter|}</a></td>
<td><a href="index.php?module=prozessstarter&action=list">{|Errorlog|}</a></td> <td><a href="index.php?module=protokoll&action=list">{|Protokoll|}</a></td>
<td><a href="index.php?module=welcome&action=info">{|Lizenz|}</a></td> <td><a href="index.php?module=prozessstarter&action=list">{|Logfile|}</a></td>
<td><a href="index.php?module=drucker&action=list">{|Drucker|}</a></td> <td><a href="index.php?module=prozessstarter&action=list">{|Log|}</a></td>
</tr> </tr>
</table> </table>
<table width="800" border="0" align="center"> <table width="800" border="0" align="center">
<tr align="center"> <tr align="center">
<td width="25%"><a href="index.php?module=protokoll&action=list"><img src="./themes/[THEME]/images/einstellungen/Icons_dunkel_22.gif" border="0" width="30%"></a></td>
<td width="25%"><a href="index.php?module=etiketten&action=list"><img src="./themes/[THEME]/images/einstellungen/Icons_dunkel_14.gif" border="0" width="30%"></a></td> <td width="25%"><a href="index.php?module=etiketten&action=list"><img src="./themes/[THEME]/images/einstellungen/Icons_dunkel_14.gif" border="0" width="30%"></a></td>
<td width="25%" style="position:relative"><a [UEBERSETZUNGENLINK]><img src="./themes/[THEME]/images/einstellungen/Icons_dunkel_14.gif" border="0" width="30%"></a>[GREYUEBERSETZUNGEN]</td> <td width="25%" style="position:relative"><a [UEBERSETZUNGENLINK]><img src="./themes/[THEME]/images/einstellungen/Icons_dunkel_14.gif" border="0" width="30%"></a>[GREYUEBERSETZUNGEN]</td>
<td width="25%" style="position:relative"><a [ARBEITSFREIETAGELINK]><img src="./themes/[THEME]/images/einstellungen/Icons_dunkel_14.gif" border="0" width="30%"></a>[GREYARBEITSFREIETAGE]</td> <td width="25%" style="position:relative"><a [ARBEITSFREIETAGELINK]><img src="./themes/[THEME]/images/einstellungen/Icons_dunkel_14.gif" border="0" width="30%"></a>[GREYARBEITSFREIETAGE]</td>
<td width="25%"><a href="index.php?module=drucker&action=list"><img src="./themes/[THEME]/images/einstellungen/Icons_dunkel_24.gif" border="0" width="30%"></a></td>
</tr> </tr>
<tr align="center"> <tr align="center">
<td><a href="index.php?module=protokoll&action=list">{|Protokoll|}</a></td>
<td><a href="index.php?module=etiketten&action=list">{|Etiketten|}</a></td> <td><a href="index.php?module=etiketten&action=list">{|Etiketten|}</a></td>
<td><a [UEBERSETZUNGENLINK]>{|&Uuml;bersetzungen|}</a></td> <td><a [UEBERSETZUNGENLINK]>{|&Uuml;bersetzungen|}</a></td>
<td width="25%"><a [ARBEITSFREIETAGELINK]>{|Arbeitsfreie Tage|}</a></td> <td width="25%"><a [ARBEITSFREIETAGELINK]>{|Arbeitsfreie Tage|}</a></td>
<td><a href="index.php?module=drucker&action=list">{|Drucker|}</a></td>
</tr> </tr>
</table> </table>
<table width="800" border="0" align="center"> <table width="800" border="0" align="center">
<tr align="center"> <tr align="center">
<td width="25%"><a href="index.php?module=welcome&action=info"><img src="./themes/[THEME]/images/einstellungen/Icons_dunkel_23.gif" border="0" width="30%"></a></td>
<td width="25%"><a href="index.php?module=support&action=list"><img src="./themes/[THEME]/images/einstellungen/Icons_dunkel_23.gif" border="0" width="30%"></a></td> <td width="25%"><a href="index.php?module=support&action=list"><img src="./themes/[THEME]/images/einstellungen/Icons_dunkel_23.gif" border="0" width="30%"></a></td>
<td width="25%"><a href="index.php?module=api_account&action=list"><img src="./themes/[THEME]/images/einstellungen/Icons_dunkel_25.gif" border="0" width="30%"></td> <td width="25%"><a href="index.php?module=api_account&action=list"><img src="./themes/[THEME]/images/einstellungen/Icons_dunkel_25.gif" border="0" width="30%"></td>
<td width="25%"><a href="index.php?module=adapterbox&action=list"><img src="./themes/[THEME]/images/einstellungen/Icons_dunkel_25.gif" border="0" width="30%"></a></td> <td width="25%"><a href="index.php?module=adapterbox&action=list"><img src="./themes/[THEME]/images/einstellungen/Icons_dunkel_25.gif" border="0" width="30%"></a></td>
<td width="25%" style="position:relative"></td>
</tr> </tr>
<tr align="center"> <tr align="center">
<td><a href="index.php?module=welcome&action=info">{|Lizenz|}</a></td>
<td><a href="index.php?module=support&action=list">{|Support|}</a></td> <td><a href="index.php?module=support&action=list">{|Support|}</a></td>
<td><a href="index.php?module=api_account&action=list">{|API-Account|}</a></td> <td><a href="index.php?module=api_account&action=list">{|API-Account|}</a></td>
<td><a href="index.php?module=adapterbox&action=list">{|Adapterbox|}</a></td> <td><a href="index.php?module=adapterbox&action=list">{|Adapterbox|}</a></td>
<td width="25%"></td>
</tr> </tr>
</table> </table>
</fieldset> </fieldset>
+10 -1
View File
@@ -67,7 +67,10 @@
<tr><td>{|imap_sentfolder_aktiv|}:</td><td><input type="text" name="imap_sentfolder_aktiv" value="[IMAP_SENTFOLDER_AKTIV]" size="40"></td></tr> <tr><td>{|imap_sentfolder_aktiv|}:</td><td><input type="text" name="imap_sentfolder_aktiv" value="[IMAP_SENTFOLDER_AKTIV]" size="40"></td></tr>
<tr><td>{|imap_sentfolder|}:</td><td><input type="text" name="imap_sentfolder" value="[IMAP_SENTFOLDER]" size="40"></td></tr> <tr><td>{|imap_sentfolder|}:</td><td><input type="text" name="imap_sentfolder" value="[IMAP_SENTFOLDER]" size="40"></td></tr>
<tr><td>{|imap_port|}:</td><td><input type="text" name="imap_port" value="[IMAP_PORT]" size="40"></td></tr> <tr><td>{|imap_port|}:</td><td><input type="text" name="imap_port" value="[IMAP_PORT]" size="40"></td></tr>
<tr><td>{|imap_type|}:</td><td><input type="text" name="imap_type" value="[IMAP_TYPE]" size="40"><i>0 = standard, 1 = SSL</i></td></tr> <tr><td>{|imap_type|}:</td><td><input type="text" name="imap_type" value="[IMAP_TYPE]" size="40"><i>1 = standard, 3 = SSL, 5 = OAuth</i></td></tr>
<tr><td width="50">Testmail:</td><td>
<input type="submit" form="imap_test" value="IMAP testen" id="testimap-button">&nbsp;<i>Bitte erst speichern und dann testen!</i>
</td></tr>
</table> </table>
</fieldset> </fieldset>
</div> </div>
@@ -168,3 +171,9 @@
<input type="text" name="id" value="[ID]" style="display:none"> <input type="text" name="id" value="[ID]" style="display:none">
</form> </form>
<form id="imap_test" action = "index.php">
<input type="text" name="module" value="emailbackup" style="display:none">
<input type="text" name="action" value="test_imap" style="display:none">
<input type="text" name="id" value="[ID]" style="display:none">
</form>
+270
View File
@@ -0,0 +1,270 @@
<div id="tabs">
<ul>
<li><a href="#tabs-1">Allgemein</a></li>
<li><a href="#tabs-2">Produktion</a></li>
<li><a href="#tabs-3">Positionen</a></li>
<li><a href="#tabs-4">Protokoll</a></li>
</ul>
<div id="tabs-1">
[MESSAGE]
<form action="" method="post">
[FORMHANDLEREVENT]
<div class="row">
<div class="row-height">
<div class="col-xs-12 col-md-12 col-md-height">
<div class="inside inside-full-height">
<fieldset>
<legend>{|<b>Produktion <font color="blue">[BELEGNR]</font></b>|}</legend>
[STATUSICONS]
[TEILPRODUKTIONINFO]
</fieldset>
</div>
</div>
</div>
</div>
<div class="row">
<div class="row-height">
<div class="col-xs-14 col-md-6 col-md-height">
<div class="inside inside-full-height">
<fieldset>
<legend>{|Allgemein|}</legend>
<table width="100%" border="0" class="mkTableFormular">
<tr><td>{|Kunde|}:</td><td><input type="text" name="kundennummer" id="kundennummer" value="[KUNDENNUMMER]" size="20"></td></tr>
<tr><td>{|Projekt|}:</td><td><input type="text" name="projekt" id="projekt" value="[PROJEKT]" size="20"></td></tr>
<tr><td>{|Auftrag|}:</td><td><input type="text" name="auftragid" id="auftragid" value="[AUFTRAGID]" size="20"></td></tr>
<tr><td>{|Interne Bezeichnung|}:</td><td><input type="text" name="internebezeichnung" value="[INTERNEBEZEICHNUNG]" size="20"></td></tr>
</table>
</fieldset>
</div>
</div>
<div class="col-xs-14 col-md-6 col-md-height">
<div class="inside inside-full-height">
<fieldset>
<table width="100%" border="0" class="mkTableFormular">
<tr><td>{|Status|}:</td><td><input disabled type="text" name="status" value="[STATUS]" size="20"></td></tr>
<tr><td>{|Angelegt am|}:</td><td><input type="text" name="datum" id="datum" value="[DATUM]" size="10"></td></tr>
<tr><td>{|Materiallager|}:</td><td><input type="text" name="standardlager" id="standardlager" value="[STANDARDLAGER]" size="20"></td></tr>
</table>
</fieldset>
</div>
</div>
<div class="col-xs-14 col-md-2 col-md-height">
<div class="inside inside-full-height">
<fieldset>
<table width="100%" border="0" class="mkTableFormular">
<legend>{|Aktionen|}</legend>
<tr><td><button [AKTION_SPEICHERN_DISABLED] name="submit" value="speichern" class="ui-button-icon" style="width:100%;">Speichern</button></td></tr>
<tr [AKTION_FREIGEBEN_VISIBLE]><td><button name="submit" value="freigeben" class="ui-button-icon" style="width:100%;">Freigeben</button></td></tr>
</table>
</fieldset>
</div>
</div>
</div>
</div>
<div class="row">
<div class="row-height">
<div class="col-xs-14 col-md-6 col-md-height">
<div class="inside inside-full-height">
<fieldset>
<legend>{|Einstellungen|}</legend>
<table width="100%" border="0" class="mkTableFormular">
<tr><td>{|Reservierart|}:</td><td><input disabled type="text" name="reservierart" value="[RESERVIERART]" size="20"></td></tr>
<tr><td>{|Auslagerart|}:</td><td><input disabled type="text" name="auslagerart" value="[AUSLAGERART]" size="20"></td></tr>
<tr><td>{|Unterstücklisten aufl&ouml;sen|}:</td><td><input disabled type="checkbox" name="unterlistenexplodieren" value=1 [UNTERLISTENEXPLODIEREN] size="20"></td></tr>
<tr><td>{|Funktionstest|}:</td><td><input disabled type="checkbox" name="funktionstest" value=1 [FUNKTIONSTEST] size="20"></td></tr>
<tr><td>{|Beschreibungen von Arbeitsschritten anzeigen|}:</td><td><input disabled type="checkbox" name="arbeitsschrittetextanzeigen" value=1 [ARBEITSSCHRITTETEXTANZEIGEN] size="20"></td></tr>
<tr><td>{|Seriennummer erstellen|}:</td><td><input disabled type="checkbox" name="seriennummer_erstellen" value=1 [SERIENNUMMER_ERSTELLEN] size="20"></td></tr>
<tr><td>{|Unterseriennummer erfassen|}:</td><td><input disabled type="checkbox" name="unterseriennummer_erfassen" value=1 [UNTERSERIENNUMMER_ERFASSEN] size="20"></td></tr>
</table>
</fieldset>
</div>
</div>
<div class="col-xs-14 col-md-8 col-md-height">
<div class="inside inside-full-height">
<fieldset>
<table width="100%" border="0" class="mkTableFormular">
<tr><td>{|Auslieferung Lager|}:</td><td><input type="text" name="datumauslieferung" id="datumauslieferung" value="[DATUMAUSLIEFERUNG]" size="10"></td></tr>
<tr><td>{|Bereitstellung Start|}:</td><td><input type="text" name="datumbereitstellung" id="datumbereitstellung" value="[DATUMBEREITSTELLUNG]" size="10"></td></tr>
<tr><td>{|Produktion Start|}:</td><td><input type="text" name="datumproduktion" id="datumproduktion" value="[DATUMPRODUKTION]" size="10"></td></tr>
<tr><td>{|Produktion Ende|}:</td><td><input type="text" name="datumproduktionende" id="datumproduktionende" value="[DATUMPRODUKTIONENDE]" size="10"></td></tr>
</table>
</fieldset>
</div>
</div>
</div>
</div>
<div class="row">
<div class="row-height">
<div class="col-xs-12 col-md-12 col-md-height">
<div class="inside inside-full-height">
<fieldset>
<legend>{|Freitext|}</legend>
<textarea name="freitext" id="freitext" style="min-height: 180px;">[FREITEXT]</textarea>
</table>
</fieldset>
</div>
</div>
</div>
</div>
<div class="row">
<div class="row-height">
<div class="col-xs-12 col-md-12 col-md-height">
<div class="inside inside-full-height">
<fieldset>
<legend>{|Interne Bemerkung|}</legend>
<textarea name="internebemerkung" id="internebemerkung" style="min-height: 180px;">[INTERNEBEMERKUNG]</textarea>
</fieldset>
</div>
</div>
</div>
</div>
</form>
</div>
<div [POSITIONEN_TAB_VISIBLE]>
<div id="tabs-2">
[MESSAGE]
<form action="#tabs-2" method="post">
[FORMHANDLEREVENT]
<div class="row">
<div class="row-height">
<div class="col-xs-14 col-md-12 col-md-height">
<div class="inside inside-full-height">
<fieldset>
<legend>{|<b>Produktion <font color="blue">[BELEGNR]</font></b>|}</legend>
[STATUSICONS]
[TEILPRODUKTIONINFO]
</fieldset>
</div>
</div>
</div>
</div>
<div class="row">
<div class="row-height">
<div class="col-xs-14 col-md-5 col-md-height">
<div class="inside inside-full-height">
<fieldset>
<legend [AKTION_PLANEN_VISIBLE]>{|Zu produzierende Artikel|}</legend>
<legend [ARTIKEL_MENGE_VISIBLE]>{|Produktionsfortschritt|}</legend>
<table width="100%" border="0">
<tr [AKTION_PLANEN_VISIBLE]><td>{|Artikel|}:</td></tr>
<tr [AKTION_PLANEN_VISIBLE]><td><input type="text" name="artikel_planen" id="artikel_planen" value="[ARTIKEL_PLANEN]" size="20"></td></tr>
<tr [AKTION_PLANEN_VISIBLE]><td>{|Planmenge|}:</td></tr>
<tr [AKTION_PLANEN_VISIBLE]><td><input type="text" name="artikel_planen_menge" id="artikel_planen_menge" value="[ARTIKEL_PLANEN_MENGE]" size="20"></td></tr>
<tr [ARTIKEL_MENGE_VISIBLE]>
<td>{|Geplant|}:</td>
<td>[MENGE_GEPLANT]</td>
<td>{|Offen:|}</td>
<td>[MENGE_OFFEN]</td>
</tr>
<tr [ARTIKEL_MENGE_VISIBLE]>
<td>{|Produziert|}:</td>
<td>[MENGE_PRODUZIERT]</td>
<td>{|Reserviert:|}</td>
<td>[MENGE_RESERVIERT]</td>
</tr>
<tr [ARTIKEL_MENGE_VISIBLE]>
<td>{|Erfolgreich|}:</td>
<td>[MENGE_ERFOLGREICH]</td>
<td>{|Produzierbar:|}</td>
<td>[MENGE_PRODUZIERBAR]</td>
</tr>
</tr>
<tr [ARTIKEL_MENGE_VISIBLE]>
<td>{|Ausschuss|}:</td>
<td>[MENGE_AUSSCHUSS]</td>
</tr>
</table>
</fieldset>
</div>
</div>
<div class="col-xs-14 col-md-5 col-md-height">
<div class="inside inside-full-height">
<fieldset>
<legend [AKTION_PRODUZIEREN_VISIBLE]>{|Parameter|}</legend>
<table width="100%" border="0" class="mkTableFormular">
<tr [AKTION_PRODUZIEREN_VISIBLE]>
<td>{|Menge|}:</td>
<td><input type="number" min="0" name="menge_produzieren" id="menge_produzieren" value="[MENGE_PRODUZIEREN]" size="20""></td>
</tr>
<tr [AKTION_PRODUZIEREN_VISIBLE]>
<td>{|Ausschuss|}:</td>
<td><input type="number" min="0" name="menge_ausschuss_produzieren" id="menge_ausschuss_produzieren" value="[MENGE_AUSSCHUSS_PRODUZIEREN]" size="20"></td>
</tr>
<tr [AKTION_PRODUZIEREN_VISIBLE]>
<td>{|Ziellager|}:</td>
<td><input type="text" name="ziellager" id="ziellager" value="[ZIELLAGER]" size="20"></td>
</tr>
</table>
</fieldset>
</div>
</div>
<div class="col-xs-14 col-md-2 col-md-height">
<div class="inside inside-full-height">
<fieldset>
<table width="100%" border="0" class="mkTableFormular">
<legend>{|Anpassen|}</legend>
<tr [AKTION_PLANEN_VISIBLE]><td><button name="submit" value="planen" class="ui-button-icon" style="width:100%;">Planen</button></td></tr>
<tr [AKTION_LEEREN_VISIBLE]><td><button name="submit" value="leeren" class="ui-button-icon" style="width:100%;">Leeren</button></td></tr>
<tr [AKTION_FREIGEBEN_VISIBLE]><td><button name="submit" value="freigeben" class="ui-button-icon" style="width:100%;">Freigeben</button></td></tr>
<tr [AKTION_PRODUZIEREN_VISIBLE]><td><button name="submit" value="teilen" class="ui-button-icon" style="width:100%;">Teilen</button></td></tr>
<tr [AKTION_PRODUZIEREN_VISIBLE]><td><button name="submit" value="anpassen" class="ui-button-icon" style="width:100%;">Anpassen</button></td></tr>
</table>
</fieldset>
</div>
</div>
<div class="col-xs-14 col-md-2 col-md-height">
<div class="inside inside-full-height">
<fieldset>
<table width="100%" border="0" class="mkTableFormular">
<legend>{|Produzieren|}</legend>
<tr [AKTION_RESERVIEREN_VISIBLE]><td><button name="submit" value="reservieren" class="ui-button-icon" style="width:100%;">Reservieren</button></td></tr>
<tr [AKTION_PRODUZIEREN_VISIBLE]><td><button name="submit" value="produzieren" class="ui-button-icon" style="width:100%;">Produzieren</button></td></tr>
<tr [AKTION_ABSCHLIESSEN_VISIBLE]><td><button name="submit" value="abschliessen" class="ui-button-icon" style="width:100%;">Abschliessen</button></td></tr>
</table>
</fieldset>
</div>
</div>
</div>
</div>
<div [ARTIKEL_MENGE_VISIBLE] class="row">
<div class="row-height">
<div class="col-xs-12 col-md-12 col-md-height">
<div class="inside inside-full-height">
<fieldset>
<legend>{|Materialbedarf|}</legend>
</fieldset>
[PRODUKTION_POSITION_SOURCE_TABELLE]
</div>
</div>
</div>
</div>
</form>
</div>
</div>
<div id="tabs-3">
[MESSAGE]
<form action="" method="post">
[FORMHANDLEREVENT]
<div class="row">
<div class="row-height">
<div class="col-xs-12 col-md-12 col-md-height">
<div class="inside inside-full-height">
<fieldset>
<legend>{|Positionen|}</legend>
[PRODUKTION_POSITION_SOURCE_POSITION_TABELLE]
</fieldset>
</div>
</div>
</div>
</div>
</form>
</div>
<div id="tabs-4">
[MESSAGE]
<form action="" method="post">
[MINIDETAILINEDIT]
</form>
</div>
</div>
+48
View File
@@ -0,0 +1,48 @@
<div id="tabs">
<ul>
<li><a href="#tabs-1">[TABTEXT1]</a></li>
</ul>
<div id="tabs-1">
[MESSAGE]
<form action="#tabs-1" id="frmauto" name="frmauto" method="post">
<div class="filter-box filter-usersave">
<div class="filter-block filter-inline">
<div class="filter-title">{|Filter|}</div>
<ul class="filter-list">
[STATUSFILTER]
<li class="filter-item">
<label for="angelegte" class="switch">
<input type="checkbox" id="angelegte">
<span class="slider round"></span>
</label>
<label for="angelegte">{|Angelegt|}</label>
</li>
<li class="filter-item">
<label for="offene" class="switch">
<input type="checkbox" id="offene">
<span class="slider round"></span>
</label>
<label for="offene">{|Offen|}</label>
</li>
<li class="filter-item">
<label for="geschlossene" class="switch">
<input type="checkbox" id="geschlossene">
<span class="slider round"></span>
</label>
<label for="geschlossene">{|Abgeschlossen|}</label>
</li>
<li class="filter-item">
<label for="stornierte" class="switch">
<input type="checkbox" id="stornierte">
<span class="slider round"></span>
</label>
<label for="stornierte">{|Papierkorb|}</label>
</li>
</ul>
</div>
</div>
</form>
[TAB1]
[TAB1NEXT]
</div>
</div>
+40 -275
View File
@@ -1,281 +1,46 @@
<style> <div class="row">
<div class="col-xs-12 col-md-6 col-md-height">
<div class="inside inside-full-height">
.auftraginfo_cell { <legend>{|Produktionsfortschritt|}</legend>
color: #636363;border: 1px solid #ccc;padding: 5px; <div class="inside inside-full-height">
} <table width="100%" border="0">
<tr [ARTIKEL_MENGE_VISIBLE]>
.auftrag_cell { <td>{|Geplant|}:</td>
color: #636363;border: 1px solid #fff;padding: 0px; margin:0px; <td>[MINI_MENGE_GEPLANT]</td>
} <td>{|Offen:|}</td>
<td>[MINI_MENGE_OFFEN]</td>
</style> </tr>
<tr [ARTIKEL_MENGE_VISIBLE]>
<td>{|Produziert|}:</td>
<table width="100%" border="0" cellpadding="10" cellspacing="5"> <td>[MINI_MENGE_PRODUZIERT]</td>
<tr valign="top"> <td>{|Reserviert:|}</td>
<td width=""> <td>[MINI_MENGE_RESERVIERT]</td>
</tr>
<br> <tr [ARTIKEL_MENGE_VISIBLE]>
<center>[MENU]</center> <td>{|Erfolgreich|}:</td>
<br> <td>[MINI_MENGEERFOLGREICH]</td>
<td>{|Produzierbar:|}</td>
<h2 class="greyh2">Artikel für Produktion</h2> <td>[MINI_MENGE_PRODUZIERBAR]</td>
<div style="padding:10px;">[ARTIKEL]</div> </tr>
[MINIDETAILNACHARTIKEL] </tr>
<h2 class="greyh2">Externe Produktionsschritte</h2> <td>{|Ausschuss|}:</td>
<div style="padding:10px;" id="[RAND]bestellungen">[BESTELLUNGEN]</div> <td>[MINI_MENGEAUSSCHUSS]</td>
</tr>
</table>
<h2 class="greyh2">Zeiterfassung</h2> </div>
<div style="padding:10px;">[ZEITERFASSUNG]</div>
<h2 class="greyh2">Arbeitsschritte</h2>
<div style="padding:10px;">[ARBEITSSCHRITTE]</div>
<h2 class="greyh2">Abschlussbemerkung</h2>
<div style="padding:10px;">[ABSCHLUSSBEMERKUNG]</div>
<div style="padding:10px;">
<table width="100%>">
<tr>
<td>Zeit Geplant in Stunden</td>
<td>Zeit Tatsächlich in Stunden</td>
<td>Arbeitsplatzgruppe Kosten Geplant in EUR</td>
<td>Arbeitsplatzgruppe Kosten Tatsächlich in EUR</td>
</tr>
<tr>
<td class="greybox" width="25%">[ZEITGEPLANT]</td>
<td class="greybox" width="25%">[ZEITGEBUCHT]</td>
<td class="greybox" width="25%">[KOSTENGEPLANT]</td>
<td class="greybox" width="25%">[KOSTENGEBUCHT]</td>
</tr>
</table>
</div>
</td>
<td width="450">
<div style="overflow:auto; min-width:450px; max-height:550px;">
<div style="background-color:white">
<h2 class="greyh2">Produktionszentrum</h2>
<div style="padding:10px;">
<center>
[BUTTONS]
</center>
</div>
<div style="background-color:white">
<h2 class="greyh2">Protokoll</h2>
<div style="padding:10px;">
[PROTOKOLL]
</div>
</div>
<!--
<h2 class="greyh2">Datei Anhang</h2>
<div style="padding:10px;">[DATEIANHANGLISTE]</div>
-->
<!--
<h2 class="greyh2">Arbeitsschritte</h2>
<div style="padding:10px">
<table width="100%>">
<tr><td>Fertigstellung in %</td><td>Anzahl Schritte</td></tr>
<tr>
<td class="greybox" width="25%">[DECKUNGSBEITRAG]</td>
<td class="greybox" width="25%">[DBPROZENT]</td>
</tr>
</table>
</div>
-->
<h2 class="greyh2">Abschluss Bericht</h2>
<div style="padding:10px;">
<table width="100%>">
<tr>
<td>Menge Geplant</td>
<td>Menge Ausschuss</td>
</tr>
<tr>
<td class="greybox" width="25%">[MENGEGEPLANT]</td>
<td class="greybox" width="25%">[MENGEAUSSCHUSS]</td>
</tr>
</table>
</div>
<h2 class="greyh2">Deckungsbeitrag</h2>
<div style="padding:10px">
<table width="100%>">
<tr>
<td>Deckungsbeitrag in EUR</td>
<td>DB in %</td>
</tr>
<tr>
<td class="greybox" width="25%">[DECKUNGSBEITRAG]</td>
<td class="greybox" width="25%">[DBPROZENT]</td>
</tr>
</table>
<br>
<br>
</div>
</div> </div>
</div>
<div class="col-xs-12 col-md-6 col-md-height">
<div class="inside inside-full-height">
<legend>{|Protokoll|}</legend>
<div class="inside inside-full-height">
[PROTOKOLL]
</div>
</div>
</div>
</div>
</td>
</tr>
</table>
<div id="[RAND]createdocdialog">
<form id="[RAND]createdocfrom">
<fieldset><legend>{|Artikel|}</legend>
<div id="[RAND]createdocdialoginfo"></div>
<input type="hidden" name="[RAND]createdocsid" id="[RAND]createdocsid" />
<table class="mkTable" width="100%" id="[RAND]createdocdialogtable">
</table>
</fieldset>
<fieldset><legend>{|Bestellung bei externen Produzent|}</legend>
<table>
<tr>
<td nowrap>
<input type="radio" id="[RAND]createdoctypecreatebestellung" name="[RAND]createdoctypebestellungtyp" value="createbestellung" checked="checked" />
<label for="[RAND]createdoctypecreatebestellung">{|neue Bestellung anlegen|}</label>
<label for="[RAND]createdocadresse">{|bei Lieferant|}:</label>
</td><td nowrap>
<input type="text" id="[RAND]createdocadresse" name="[RAND]createdocadresse" size="30" />
</td>
</tr>
<tr class="[RAND]createdoctypetrlieferant"><td></td></tr>
<tr>
<td>
<input type="radio" id="[RAND]createdoctypeaddtobestellung" name="[RAND]createdoctypebestellungtyp" value="addtobestellung" /> <label for="[RAND]createdoctypeaddtobestellung">{|zu bestehender Bestellung anlegen|}:</label>
</td><td>
<input id="[RAND]createdocbestellung" name="[RAND]createdocbestellung" type="text" size="30"/>
</td>
</tr>
<tr id="[RAND]createdoctrbestellungnoprice">
<td colspan="2">
<input type="checkbox" id="[RAND]createdoctypebestellungnoprice" name="[RAND]createdoctypebestellungnoprice" value="1" [NEWSUPPLIERSORDERHASPRICE]/>
<label for="[RAND]createdoctypebestellungnoprice">{|Preis für Hauptprodukt nicht setzen|}</label>
</td>
</tr>
</table>
</fieldset>
<fieldset><legend>{|Beistellen des Materials|}</legend>
<table>
<tr id="[RAND]createdoctrtypebestellung">
<td colspan="2">
<input type="radio" id="[RAND]createdoctypebestellung" name="[RAND]createdoctype" value="bestellung" checked="checked" />
<label for="[RAND]createdoctypebestellung">{|Artikel sofort auslagern (basierend auf Bestellung)|}</label>
</td>
</tr>
<tr id="[RAND]createdoctrtypeauftrag">
<td colspan="2">
<input type="radio" id="[RAND]createdoctypeauftrag" name="[RAND]createdoctype" value="auftrag" />
<label for="[RAND]createdoctypeauftrag">{|Auftrag für Beistellung anlegen|}</label>
</td>
</tr>
</table>
</fieldset>
<fieldset><legend>{|Produktion|}</legend>
<table>
<tr id="[RAND]createdoctrprodstarten">
<td colspan="2">
<input type="checkbox" id="[RAND]createdocstartprod" name="[RAND]createdocstartprod" value="1" />
<label for="[RAND]createdocstartprod">{|Produktion starten|}</label>
</td>
</tr>
</table>
</fieldset>
</form>
</div>
<script type="application/javascript">
[AUTOCOMPLETE]
$(document).ready(function() {
$('#[RAND]createdocdialog').dialog(
{
modal: true,
autoOpen: false,
minWidth: 940,
title: 'Auftrag/Bestellung anlegen',
buttons: {
'OK': function () {
var $addr = $('#[RAND]createdocadresse');
var $best = $('#[RAND]createdocbestellung');
var allempty = ($($addr).val()+'' === '') &&
($($best).length === 0 || $($best).val()+'' === '');
if(allempty) {
alert('Bitte eine Adresse oder Bestellung auswählen');
} else {
if($('#[RAND]createdoctypebestellung').prop('checked') || $('#[RAND]createdoctypeauftrag').prop('checked')) {
$.ajax({
url: 'index.php?module=produktion&action=edit&cmd=createdocument&id=[ID]&frame=[FRAMEPARAM]',
type: 'POST',
dataType: 'json',
data: $('#[RAND]createdocfrom').serialize(),
success: function (data) {
//$('#[RAND]createdocdialog').dialog('close');
$('#[RAND]createdocdialoginfo').html(typeof data.html != 'undefined'? data.html:'');
if(data.html != '') {
$('input.[RAND]createdoc').remove();
}
$('#[RAND]createdocdialog').dialog('close');
if(typeof data.deliverynoteinfo != 'undefined') {
$('#[RAND]bestellungen').html(data.deliverynoteinfo);
bindButton[RAND]();
}
},
beforeSend: function () {
}
});
}
}
},
'ABBRECHEN': function () {
$(this).dialog('close');
}
},
close: function (event, ui) {
}
});
bindButton[RAND]();
});
function bindButton[RAND](){
$('input.[RAND]createdoc').on('click', function () {
$('#[RAND]createdocsid').val($(this).data('sid'));
$.ajax({
url: 'index.php?module=produktion&action=edit&cmd=gettableforcreatedocument&id=[ID]',
type: 'POST',
dataType: 'json',
data: {sid: $(this).data('sid'),rand:'[RAND]'},
success: function (data) {
$('#[RAND]createdocdialoginfo').html(typeof data.info != 'undefined'? data.info:'');
$('#[RAND]createdocdialogtable').html(data.html);
$('#[RAND]createdocadresse').val(data.adresse);
$('#[RAND]createdocbestellung').html(data.bestellung);
$('#[RAND]createdocauftrag').html(data.auftrag);
$('#[RAND]createdocdialog').dialog('open');
if(data.displayprodstart) {
$('#[RAND]createdoctrprodstarten').show();
} else {
$('#[RAND]createdoctrprodstarten').hide();
}
addClicklupe();
lupeclickevent();
// AutoComplete-Ergebnisboxen an Dialog-Fenster anhängen.
// Ansonsten wird AutoComplete-Ergebnis evtl. nicht sichtbar unterhalb des Dialog-Fensters angezeigt.
var $uiDialog = $('#[RAND]createdocdialog').first();
$($uiDialog).find('input.ui-autocomplete-input').autocomplete('option', 'appendTo', $uiDialog);
},
beforeSend: function () {
}
});
});
}
</script>
@@ -0,0 +1,33 @@
<div id="tabs">
<ul>
<li><a href="#tabs-1"></a></li>
</ul>
<!-- Example for multiple tabs
<ul hidden">
<li><a href="#tabs-1">First Tab</a></li>
<li><a href="#tabs-2">Second Tab</a></li>
</ul>
-->
<div id="tabs-1">
[MESSAGE]
<form action="" method="post">
[FORMHANDLEREVENT]
<div class="row">
<div class="row-height">
<div class="col-xs-12 col-md-12 col-md-height">
<div class="inside inside-full-height">
<fieldset>
<legend>{|<a href="index.php?module=produktion&action=edit&id=[PRODUKTIONID]#tabs-3">PRODUKTION [PRODUKTIONBELEGNR]<a>|}</legend>
<table width="100%" border="0" class="mkTableFormular">
<tr><td>{|Artikel|}:</td><td><input type="text" id="artikel" name="artikel" value="[ARTIKEL]" size="40"></td></tr>
<tr><td>{|Menge|}:</td><td><input type="text" name="menge" value="[MENGE]" size="40"></td></tr>
</table>
</fieldset>
</div>
</div>
</div>
</div>
<input type="submit" name="submit" value="Speichern" style="float:right"/>
</form>
</div>
</div>
@@ -1,25 +0,0 @@
<table border="0" width="100%">
<tr><td><table width="100%"><tr><td>
<form action="" method="post" name="eprooform">
<table class="tableborderred" border="0" cellpadding="3" cellspacing="0" width="100%">
<tbody>
<tr classname="red1" class="red1" bordercolor="" align="" bgcolor="" height="" valign="">
<td colspan="4" bordercolor="" class="" align="" bgcolor="" height="" valign="">[SUBSUBHEADING]<br></td>
</tr>
<tr valign="top" colspan="3">
<td>
[INHALT]
</td>
</tr>
<tr valign="" height="" bgcolor="" align="" bordercolor="" class="klein" classname="klein">
<td width="" valign="" height="" bgcolor="" align="right" colspan="4" bordercolor="" classname="red2" class="red2">[EXTEND]</td>
</tr>
</tbody>
</table>
</form>
</td></tr></table></td></tr>
</table>
+51 -139
View File
@@ -1,141 +1,53 @@
<script type="text/javascript" src="./js/einfuegen.js" ></script> <div id="tabs">
<form method="POST" id="eprooform" enctype="multipart/form-data"> <ul>
<li><a href="#tabs-1"></a></li>
<table width=100%"><tr valign="top"><td> </ul>
<fieldset><legend>{|Nachricht|}</legend> <div id="tabs-1">
<table> [MESSAGE]
<tr><td width="200">Von:</td><td><select name="quelle" id="quelle"/>[QUELLE]</select></td></tr> <form action="" method="post">
<tr><td>Kunde:</td><td><input type="text" name="adresse" onchange="changeemail()" id="adresse" size="80" /></td></tr> [FORMHANDLEREVENT]
<tr><td>E-Mail:</td><td><input type="text" name="email" id="email" size="80" /></td></tr> <div class="row">
<tr><td>E-Mail CC:</td><td><input type="text" name="emailcc" id="emailcc" size="80" /></td></tr> <div class="row-height">
<tr><td>Betreff:</td><td><input type="text" name="betreff" id="betreff" size="80" /></td></tr> <div class="col-xs-13 col-md-6 col-md-height">
<tr><td>Nachricht:</td><td><textarea id="eingabetext" name="eingabetext" cols="90" style="min-height:200px;">[TEXT]</textarea></td></tr> <div class="inside inside-full-height">
<tr><td>Anhang 1:</td><td><input type="file" name="datei[]" /></td></tr> <fieldset>
<tr><td>Anhang 2:</td><td><input type="file" name="datei[]" /></td></tr> <table width="100%" border="0" class="mkTableFormular">
<tr><td>Anhang 3:</td><td><input type="file" name="datei[]" /></td></tr> <tr><td>{|Betreff|}:</td><td><input type="text" name="betreff" id="betreff" value="" size="20"></td></tr>
<tr><td>Anhang 4:</td><td><input type="file" name="datei[]" /></td></tr> <tr><td>{|Projekt|}:</td><td><input type="text" name="projekt" id="projekt" value="[PROJEKT]" size="20"></td></tr>
<tr><td>Anhang 5:</td><td><input type="file" name="datei[]" /></td></tr> <tr><td>{|Adresse|}:</td><td><input type="text" name="adresse" id="adresse" value="[ADRESSE]" size="20"></td></tr>
<tr><td></td><td><input type="submit" name="speichern" id="speichern" value="Speichern" />&nbsp;<input type="submit" name="senden" id="senden" value="Speichern und Senden" /></td></tr> <tr><td>{|Tags|}:</td><td><input type="text" name="tags" value="[TAGS]" size="20"></td></tr>
</table> </table>
</fieldset> </fieldset>
</td><td width="30%"> </div>
</div>
Textvorlagen:<br> <div class="col-xs-13 col-md-6 col-md-height">
<select name="vorlage" id="vorlage" onchange="changevorlage(this)"><option value=""> - </option>[VORLAGE]</select> <div class="inside inside-full-height">
<fieldset>
<table width="100%" border="0" class="mkTableFormular">
<tr><td>{|Status|}:</td><td><select name="status">[STATUS]</select></td></tr>
<tr><td>{|Verantwortlich|}:</td><td><input type="text" name="warteschlange" id="warteschlange" value="[WARTESCHLANGE]" size="20"></td></tr>
<tr><td>{|Prio|}:</td><td><input type="text" name="prio" value="[PRIO]" size="20"></td></tr>
<tr><td>{|Notiz|}:</td><td><textarea name="notiz" id="notiz" rows="6" style="width:100%;">[NOTIZ]</textarea></td></tr>
</table>
</fieldset>
</div>
</div>
<div class="col-xs-13 col-md-1 col-md-height">
<div class="inside inside-full-height">
<fieldset>
<table width="100%" border="0" class="mkTableFormular">
<legend>{|Aktionen|}</legend>
<td><button name="submit" value="speichern" class="ui-button-icon" style="width:100%;">Speichern</button></td></tr>
</table>
</fieldset>
</div>
</div>
</div>
</div>
[NEW_MESSAGE]
</form>
[MESSAGES]
</div>
</div>
</td></tr>
</table>
</form>
<script>
var vorlage = [];
[VORLAGEARRAY]
var kundennummer = '';
function changeemail()
{
if($('#adresse').val() != kundennummer)
{
kundennummer = $('#adresse').val();
var kunde = kundennummer.split(' ');
var kundenid = kunde[0];
kunde[kunde.length - 1].replace(')', '');
if(kunde[kunde.length - 1].replace(')', '') != '') {
$.ajax({
url: "index.php?module=ajax&action=filter&filtername=emailadresse&limit=1&kd_id="+kundenid,
type: 'GET',
dataType: 'json',
success: function (data) {
$("input#email").val(data[0]);
},
errror: function (data) {
$("input#email").val('');
},
});
}
$( "input#email" ).autocomplete({
source: "index.php?module=ajax&action=filter&filtername=emailadresse&kd_id="+kundenid,
});
}
}
function changevorlage(id)
{
if(typeof id == "undefined")id = $('#vorlage');
$.ajax({
url: 'index.php',
type: 'GET',
dataType: 'json',
data: 'module=ticket&action=create&getvorlagen=1&kunde='+$('#adresse').val(),
success: function(data) {
if(typeof data.v != "undefined")
{
$.each(data.v, function (k,va)
{
vorlage[k] = va;
}
);
id = $(id).val();
if(typeof (vorlage[id]) !== "undefined" )
{
einfuegenticket(vorlage[id]);
}
}
}
});
}
$(document).ready(function() {
/*
setInterval(function(){
if($('#adresse').val() != kundennummer)
{
kundennummer = $('#adresse').val();
var kunde = kundennummer.split(' ');
var kundenid = kunde[0];
kunde[kunde.length - 1].replace(')', '');
if(kunde[kunde.length - 1].replace(')', '') != '') {
$.ajax({
url: "index.php?module=ajax&action=filter&filtername=emailadresse&limit=1&kd_id="+kundenid,
type: 'GET',
dataType: 'json',
success: function (data) {
$("input#email").val(data[0]);
}
});
}
$( "input#email" ).autocomplete({
source: "index.php?module=ajax&action=filter&filtername=emailadresse&kd_id="+kundenid,
});
changevorlage();
}
},100);
*/
$('#eprooform').submit(function(){
var fehler = '';
if(!$('#adresse').val())fehler = fehler + ' Kein Kunde ausgewählt!';
if(!$('#betreff').val())fehler = fehler + ' Kein Betreff eingegeben!';
if(!$('#email').val())fehler = fehler + ' Keine E-Mail-Adresse ausgewählt!';
if(!$('#eingabetext').val())fehler = fehler + ' Kein Text eingegben!';
if(fehler == '')
{
return true;
}
else
{
alert(fehler);
return false;
}
});
});
</script>
+64
View File
@@ -0,0 +1,64 @@
<div id="tabs">
<ul>
<li><a href="#tabs-1"></a></li>
</ul>
<!-- Example for multiple tabs
<ul hidden">
<li><a href="#tabs-1">First Tab</a></li>
<li><a href="#tabs-2">Second Tab</a></li>
</ul>
-->
<div id="tabs-1">
[MESSAGE]
<form action="" enctype="multipart/form-data" method="POST">
[FORMHANDLEREVENT]
<div class="row">
<div class="row-height">
<div class="col-xs-14 col-md-6 col-md-height">
<div class="inside inside-full-height">
<fieldset>
<table width="100%" border="0" class="mkTableFormular">
<legend>{|[STATUSICON]<b>Ticket <font color="blue">#[SCHLUESSEL]</font></b>|}</legend>
<tr><td>{|Betreff|}:</td><td><input type="text" name="betreff" id="betreff" value="[BETREFF]" size="20"></td></tr>
<tr><td>{|Letzte Aktion|}:</td><td>[ZEIT]</td></tr>
<tr><td>{|Von|}:</td><td>[MAILADRESSE] ([KUNDE])</td></tr>
<tr><td>{|Projekt|}:</td><td><input type="text" name="projekt" id="projekt" value="[PROJEKT]" size="20"></td></tr>
<tr><td>{|Adresse|}:</td><td><input type="text" name="adresse" id="adresse" value="[ADRESSE]" size="20"><a href="index.php?module=adresse&action=edit&id=[ADRESSE_ID]"><img src="./themes/new/images/forward.svg" border="0" style="top:6px; position:relative"></a></td></tr>
<tr><td>{|Tags|}:</td><td><input type="text" name="tags" id="tags" value="[TAGS]" size="20"></td></tr>
</table>
</fieldset>
</div>
</div>
<div class="col-xs-14 col-md-6 col-md-height">
<div class="inside inside-full-height">
<fieldset>
<table width="100%" border="0" class="mkTableFormular">
<tr><td>{|Status|}:</td><td><select name="status">[STATUS]</select></td></tr>
<tr><td>{|Verantwortlich|}:</td><td><input type="text" name="warteschlange" id="warteschlange" value="[WARTESCHLANGE]" size="20"></td></tr>
<tr><td>{|Prio|}:</td><td><input type="checkbox" name="prio" id="prio" value="1" [PRIO] size="20"></td></tr>
<tr><td>{|Neue Notiz|}:</td><td><textarea name="neue_notiz" id="neue_notiz" rows="1" style="width:100%;"></textarea></td></tr>
<tr><td>{|Notizen|}:</td><td><textarea name="notiz" id="notiz" rows="6" style="width:100%;">[NOTIZ]</textarea></td></tr>
</table>
</fieldset>
</div>
</div>
<div class="col-xs-14 col-md-2 col-md-height">
<div class="inside inside-full-height">
<fieldset>
<table width="100%" border="0" class="mkTableFormular">
<legend>{|Aktionen|}</legend>
<td><button name="submit" value="speichern" class="ui-button-icon" style="width:100%;">Speichern</button></td></tr>
<td><button name="submit" value="neue_email" class="ui-button-icon" style="width:100%;">Neue E-Mail</button></td></tr>
</table>
</fieldset>
</div>
</div>
</div>
</div>
[NEW_MESSAGE]
</form>
[MESSAGES]
</div>
</div>
+119
View File
@@ -0,0 +1,119 @@
<div id="tabs">
<ul>
<li><a href="#tabs-1"></a></li>
</ul>
<!-- Example for multiple tabs
<ul hidden">
<li><a href="#tabs-1">First Tab</a></li>
<li><a href="#tabs-2">Second Tab</a></li>
</ul>
-->
<div id="tabs-1">
[MESSAGE]
<form action="" method="post">
[FORMHANDLEREVENT]
<div class="row">
<div class="row-height">
<div class="col-xs-12 col-md-12 col-md-height">
<div class="inside inside-full-height">
<fieldset>
<legend>{|<!--Legend for this form area goes here>-->ticket|}</legend><i>Info like this.</i>
<table width="100%" border="0" class="mkTableFormular">
<tr><td>{|Schluessel|}:</td><td><input type="text" name="schluessel" value="[SCHLUESSEL]" size="40"></td></tr>
<tr><td>{|Zeit|}:</td><td><input type="text" name="zeit" value="[ZEIT]" size="40"></td></tr>
<tr><td>{|Projekt|}:</td><td><input type="text" name="projekt" value="[PROJEKT]" size="40"></td></tr>
<tr><td>{|Bearbeiter|}:</td><td><input type="text" name="bearbeiter" value="[BEARBEITER]" size="40"></td></tr>
<tr><td>{|Quelle|}:</td><td><input type="text" name="quelle" value="[QUELLE]" size="40"></td></tr>
<tr><td>{|Status|}:</td><td><input type="text" name="status" value="[STATUS]" size="40"></td></tr>
<tr><td>{|Adresse|}:</td><td><input type="text" name="adresse" value="[ADRESSE]" size="40"></td></tr>
<tr><td>{|Kunde|}:</td><td><input type="text" name="kunde" value="[KUNDE]" size="40"></td></tr>
<tr><td>{|Warteschlange|}:</td><td><input type="text" name="warteschlange" value="[WARTESCHLANGE]" size="40"></td></tr>
<tr><td>{|Mailadresse|}:</td><td><input type="text" name="mailadresse" value="[MAILADRESSE]" size="40"></td></tr>
<tr><td>{|Prio|}:</td><td><input type="text" name="prio" value="[PRIO]" size="40"></td></tr>
<tr><td>{|Betreff|}:</td><td><input type="text" name="betreff" value="[BETREFF]" size="40"></td></tr>
<tr><td>{|Zugewiesen|}:</td><td><input type="text" name="zugewiesen" value="[ZUGEWIESEN]" size="40"></td></tr>
<tr><td>{|Inbearbeitung|}:</td><td><input type="text" name="inbearbeitung" value="[INBEARBEITUNG]" size="40"></td></tr>
<tr><td>{|Inbearbeitung_user|}:</td><td><input type="text" name="inbearbeitung_user" value="[INBEARBEITUNG_USER]" size="40"></td></tr>
<tr><td>{|Firma|}:</td><td><input type="text" name="firma" value="[FIRMA]" size="40"></td></tr>
<tr><td>{|Notiz|}:</td><td><input type="text" name="notiz" value="[NOTIZ]" size="40"></td></tr>
<tr><td>{|Bitteantworten|}:</td><td><input type="text" name="bitteantworten" value="[BITTEANTWORTEN]" size="40"></td></tr>
<tr><td>{|Service|}:</td><td><input type="text" name="service" value="[SERVICE]" size="40"></td></tr>
<tr><td>{|Kommentar|}:</td><td><input type="text" name="kommentar" value="[KOMMENTAR]" size="40"></td></tr>
<tr><td>{|Privat|}:</td><td><input type="text" name="privat" value="[PRIVAT]" size="40"></td></tr>
<tr><td>{|Dsgvo|}:</td><td><input type="text" name="dsgvo" value="[DSGVO]" size="40"></td></tr>
<tr><td>{|Tags|}:</td><td><input type="text" name="tags" value="[TAGS]" size="40"></td></tr>
<tr><td>{|Nachrichten_anz|}:</td><td><input type="text" name="nachrichten_anz" value="[NACHRICHTEN_ANZ]" size="40"></td></tr>
</table>
</fieldset>
</div>
</div>
</div>
</div>
<!-- Example for 2nd row
<div class="row">
<div class="row-height">
<div class="col-xs-12 col-md-12 col-md-height">
<div class="inside inside-full-height">
<fieldset>
<legend>{|Another legend|}</legend>
<table width="100%" border="0" class="mkTableFormular">
<tr><td>{|Schluessel|}:</td><td><input type="text" name="schluessel" value="[SCHLUESSEL]" size="40"></td></tr>
<tr><td>{|Zeit|}:</td><td><input type="text" name="zeit" value="[ZEIT]" size="40"></td></tr>
<tr><td>{|Projekt|}:</td><td><input type="text" name="projekt" value="[PROJEKT]" size="40"></td></tr>
<tr><td>{|Bearbeiter|}:</td><td><input type="text" name="bearbeiter" value="[BEARBEITER]" size="40"></td></tr>
<tr><td>{|Quelle|}:</td><td><input type="text" name="quelle" value="[QUELLE]" size="40"></td></tr>
<tr><td>{|Status|}:</td><td><input type="text" name="status" value="[STATUS]" size="40"></td></tr>
<tr><td>{|Adresse|}:</td><td><input type="text" name="adresse" value="[ADRESSE]" size="40"></td></tr>
<tr><td>{|Kunde|}:</td><td><input type="text" name="kunde" value="[KUNDE]" size="40"></td></tr>
<tr><td>{|Warteschlange|}:</td><td><input type="text" name="warteschlange" value="[WARTESCHLANGE]" size="40"></td></tr>
<tr><td>{|Mailadresse|}:</td><td><input type="text" name="mailadresse" value="[MAILADRESSE]" size="40"></td></tr>
<tr><td>{|Prio|}:</td><td><input type="text" name="prio" value="[PRIO]" size="40"></td></tr>
<tr><td>{|Betreff|}:</td><td><input type="text" name="betreff" value="[BETREFF]" size="40"></td></tr>
<tr><td>{|Zugewiesen|}:</td><td><input type="text" name="zugewiesen" value="[ZUGEWIESEN]" size="40"></td></tr>
<tr><td>{|Inbearbeitung|}:</td><td><input type="text" name="inbearbeitung" value="[INBEARBEITUNG]" size="40"></td></tr>
<tr><td>{|Inbearbeitung_user|}:</td><td><input type="text" name="inbearbeitung_user" value="[INBEARBEITUNG_USER]" size="40"></td></tr>
<tr><td>{|Firma|}:</td><td><input type="text" name="firma" value="[FIRMA]" size="40"></td></tr>
<tr><td>{|Notiz|}:</td><td><input type="text" name="notiz" value="[NOTIZ]" size="40"></td></tr>
<tr><td>{|Bitteantworten|}:</td><td><input type="text" name="bitteantworten" value="[BITTEANTWORTEN]" size="40"></td></tr>
<tr><td>{|Service|}:</td><td><input type="text" name="service" value="[SERVICE]" size="40"></td></tr>
<tr><td>{|Kommentar|}:</td><td><input type="text" name="kommentar" value="[KOMMENTAR]" size="40"></td></tr>
<tr><td>{|Privat|}:</td><td><input type="text" name="privat" value="[PRIVAT]" size="40"></td></tr>
<tr><td>{|Dsgvo|}:</td><td><input type="text" name="dsgvo" value="[DSGVO]" size="40"></td></tr>
<tr><td>{|Tags|}:</td><td><input type="text" name="tags" value="[TAGS]" size="40"></td></tr>
<tr><td>{|Nachrichten_anz|}:</td><td><input type="text" name="nachrichten_anz" value="[NACHRICHTEN_ANZ]" size="40"></td></tr>
</table>
</fieldset>
</div>
</div>
</div>
</div> -->
<input type="submit" name="submit" value="Speichern" style="float:right"/>
</form>
</div>
<!-- Example for 2nd tab
<div id="tabs-2">
[MESSAGE]
<form action="" method="post">
[FORMHANDLEREVENT]
<div class="row">
<div class="row-height">
<div class="col-xs-12 col-md-12 col-md-height">
<div class="inside inside-full-height">
<fieldset>
<legend>{|...|}</legend>
<table width="100%" border="0" class="mkTableFormular">
...
</table>
</fieldset>
</div>
</div>
</div>
</div>
<input type="submit" name="submit" value="Speichern" style="float:right"/>
</form>
</div>
-->
</div>
+70
View File
@@ -0,0 +1,70 @@
<div id="tabs">
<ul>
<li><a href="#tabs-1">[TABTEXT1]</a></li>
[VORTABS2UEBERSCHRIFT]<li><a href="#tabs-2">[TABTEXT2]</a></li>[NACHTABS2UEBERSCHRIFT]
</ul>
<div id="tabs-1">
[MESSAGE]
<form action="#tabs-1" id="frmauto" name="frmauto" method="post">
<div class="filter-box filter-usersave">
<div class="filter-block filter-inline">
<div class="filter-title">{|Filter|}</div>
<ul class="filter-list">
[STATUSFILTER]
<li class="filter-item">
<label for="meinetickets" class="switch">
<input type="checkbox" id="meinetickets">
<span class="slider round"></span>
</label>
<label for="meinetickets">{|Meine|}</label>
</li>
<li class="filter-item">
<label for="prio" class="switch">
<input type="checkbox" id="prio">
<span class="slider round"></span>
</label>
<label for="prio">{|Prio|}</label>
</li>
<li class="filter-item">
<label for="geschlossene" class="switch">
<input type="checkbox" id="geschlossene">
<span class="slider round"></span>
</label>
<label for="geschlossene">{|Zzgl. abgeschlossen|}</label>
</li>
<li class="filter-item">
<label for="spam" class="switch">
<input type="checkbox" id="spam">
<span class="slider round"></span>
</label>
<label for="spam">{|Zzgl. Papierkorb|}</label>
</li>
</ul>
</div>
</div>
[TAB1]
<fieldset>
<table>
<legend>Stapelverarbeitung</legend>
<tr><td>{|Status|}:</td><td><select name="status">[STATUS]</select></td></tr>
<tr><td>{|Verantwortlich|}:</td><td><input type="text" name="warteschlange" id="warteschlange" value="[WARTESCHLANGE]" size="20"></td></tr>
<tr>
<td><input type="checkbox" value="1" id="autoalle" />&nbsp;alle markieren&nbsp;</td><td><input type="submit" class="btnBlue" name="ausfuehren" value="{|Zuordnen|}" /></td>
</tr>
</table>
</fieldset>
</form>
[TAB1NEXT]
</div>
</div>
<script>
$('#autoalle').on('change',function(){
var wert = $(this).prop('checked');
$('#ticket_list').find('input[type="checkbox"]').prop('checked',wert);
$('#ticket_list').find('input[type="checkbox"]').first().trigger('change');
});
</script>
+2
View File
@@ -0,0 +1,2 @@
[INFO]
[MESSAGES]
+21
View File
@@ -0,0 +1,21 @@
<div class="row">
<div class="row-height">
<div class="col-xs-12 col-md-10 col-md-height" style="float:[NACHRICHT_FLOAT];">
<div class="inside inside-full-height" style= "border:1px solid black;">
<fieldset>
<legend>{|<b>[NACHRICHT_BETREFF]</b>|}</legend>
<table width="100%" border="0" class="mkTableFormular">
<tr><td>{|Zeit|}:</td><td>[NACHRICHT_ZEIT]</td></tr>
<tr><td>{|Von|}:</td><td>[NACHRICHT_SENDER]</td></tr>
<tr><td>{|An|}:</td><td>[NACHRICHT_RECIPIENTS]</td></tr>
<tr><td>{|CC|}:</td><td>[NACHRICHT_CC_RECIPIENTS]</td></tr>
<tr><td colspan=2><hr style="border-style:solid; border-width:1px"></td></tr>
<tr><td colspan=2><div id="body" class="ticket_text_div">[NACHRICHT_TEXT]</div></td></tr>
<tr><td colspan=2><div id="body" class="ticket_attachments">[NACHRICHT_ANHANG]</div></td></tr>
</table>
</fieldset>
</div>
</div>
</div>
</div>
+91
View File
@@ -0,0 +1,91 @@
<div class="row">
<div class="row-height">
<div class="col-xs-14 col-md-12 col-md-height">
<div class="inside inside-full-height">
<fieldset>
<legend>{|Neue E-Mail|}</legend>
<input type="hidden" name="type" value="email">
<input type="hidden" name="eintragId" value="[EINTRAGID]">
<div style="position: absolute; margin-top:27em; margin-left:30%; min-width: 90px; background: url(./themes/new/images/loading.gif) no-repeat; background-position: 50% 0px; background-size: 150px; padding-top: 90px; display:none; " id="mailworking">
</div>
<table width="100%" border="0" class="mkTableFormular">
<tr>
<td>An:</td>
<td><input type="text" name="email_an" id="email_an" value="[EMAIL_AN]" id="an" style="width: 500px;"></td>
<td align="right" valign="bottom">
</tr>
<tr>
<td>CC:</td>
<td><input type="text" id="email_cc" name="email_cc" value="[EMAIL_CC]" id="cc" style="width: 500px;"></td>
</tr>
<tr>
<td colspan="3"><br></td>
</tr>
<tr>
<td>Betreff:</td>
<td><input type="text" name="email_betreff" value="[EMAIL_BETREFF]" style="width: 500px;"></td>
</tr>
<tr>
<td>Text:</td>
<td colspan=2><textarea name="email_text" id="email_text" style="min-height: 180px;">[EMAIL_TEXT]</textarea><br><i>(Signatur für E-Mail wird automatisch angehängt)</i></td>
</tr>
[ANHAENGEHERAUFLADEN]
<tr>
<td colspan="3"><br></td>
</tr>
<tr valign="top">
<td>Anh&auml;nge:</td>
<td>
[ANHAENGE]
</td>
</tr>
<tr>
<td>&nbsp;</td>
<td><input type="file" name="upload[]" id="file" multiple/></td>
</tr>
<tr>
<td align="left" valign="bottom">
<button name="submit" value="addfile" id="addfile" class="ui-button-icon" style="display:none">Hinzufügen</button>
</td>
<script type="text/javascript">
document.getElementById("file").onchange = function(e) {
document.getElementById("addfile").click();
}
</script>
</tr>
</table>
</fieldset>
</div>
</div>
<div class="col-xs-14 col-md-2 col-md-height">
<div class="inside inside-full-height">
<fieldset>
<legend>{|Neue E-Mail|}</legend>
<input type="hidden" name="type" value="email">
<input type="hidden" name="eintragId" value="[EINTRAGID]">
<div style="position: absolute; margin-top:27em; margin-left:30%; min-width: 90px; background: url(./themes/new/images/loading.gif) no-repeat; background-position: 50% 0px; background-size: 150px; padding-top: 90px; display:none; " id="mailworking">
</div>
<table width="100%" border="0" class="mkTableFormular">
<tr>
<td align="right" valign="bottom">
<button name="submit" value="entwurfloeschen" id="entwurfloeschen" class="ui-button-icon" style="width:100%;">Entwurf l&ouml;schen</button>
[DATEIENBUTTON]
</td>
</tr>
<tr>
<td align="right" ><button name="submit" value="zitat" id="zitat" class="ui-button-icon" style="width:100%;">Original-Nachricht einf&uuml;gen</button></td>
</tr>
<tr>
<td colspan="3"><br></td>
</tr>
<tr>
<td align="right" valign="bottom">
<button name="submit" value="absenden" id="absenden" class="ui-button-icon" style="width:100%;">Absenden</button>
</td>
</tr>
</table>
</fieldset>
</div>
</div>
</div>
</div>
-266
View File
@@ -1,266 +0,0 @@
<!-- gehort zu tabview -->
<div id="tabs">
<ul>
<li><a href="#tabs-1">[TABTEXT]</a></li>
</ul>
<!-- ende gehort zu tabview -->
<!-- erstes tab -->
<div id="tabs-1">
[MESSAGE]
<div class="row">
<div class="row-height">
<div class="col-xs-12 col-md-10 col-md-height">
<div class="inside-white inside-full-height">
<div class="filter-box filter-usersave">
<div class="filter-block filter-inline">
<div class="filter-title">{|Filter|}</div>
<ul class="filter-list">
<li class="filter-item">
<label for="nuraktive" class="switch">
<input type="checkbox" id="nuraktive">
<span class="slider round"></span>
</label>
<label for="nuraktive">&nbsp;{|nur aktive Regeln|}</label>
</li>
</ul>
</div>
</div>
[TAB1]
</div>
</div>
<div class="col-xs-12 col-md-2 col-md-height">
<div class="inside inside-full-height">
<fieldset>
<legend>{|Aktionen|}</legend>
<input type="button" class="btnGreenNew" name="neuereintrag" value="&#10010; Neuer Eintrag" onclick="RegelnEdit(0);">
</fieldset>
</div>
</div>
</div>
</div>
[TAB1NEXT]
</div>
<!-- tab view schließen -->
</div>
<div id="editRegeln" style="display:none;" title="Bearbeiten">
<form method="post">
<input type="hidden" id="e_id">
<fieldset>
<legend>{|Regeln Eintrag|}</legend>
<table>
<tr>
<td width="180">{|Empf&auml;nger E-Mail Adresse|}:</td>
<td><input type="text" name="e_empf_email_adresse" id="e_empf_email_adresse" size="40"></td>
</tr>
<tr>
<td>{|Sender E-Mail Adresse|}:</td>
<td><input type="text" name="e_email_adresse" id="e_email_adresse" size="40"></td>
</tr>
<tr>
<td>{|Name|}:</td>
<td><input type="text" name="e_name" id="e_name" size="40"></td>
</tr>
<tr>
<td>{|Betreff|}:</td>
<td><input type="text" name="e_betreff" id="e_betreff" size="40"></td>
</tr>
<tr>
<td>{|Aktiv|}:</td>
<td><input type="checkbox" name="e_aktiv" id="e_aktiv" value="1"></td>
</tr>
</table>
</fieldset>
<fieldset>
<legend>{|Aktion|}</legend>
<table>
<tr>
<td width="180">{|als SPAM markieren|}:</td>
<td><input type="checkbox" name="e_spam" id="e_spam" value="1"></td>
</tr>
<tr>
<td>{|als persönlich markieren|}:</td>
<td><input type="checkbox" name="e_persoenlich" id="e_persoenlich" value="1"></td>
</tr>
<tr>
<td>{|PRIO Markierung|}:</td>
<td><input type="checkbox" name="e_prio" id="e_prio" value="1"></td>
</tr>
<tr>
<td>{|DSGVO Markierung|}:</td>
<td><input type="checkbox" name="e_dsgvo" id="e_dsgvo" value="1"></td>
</tr>
<tr>
<td>{|Warteschlange zuordnen|}:</td>
<td>
<input type="text" id="ticketqueue" class="" tabindex="" name="ticketqueue" value="[WARTESCHLANGE]" size="50" placeholder="" maxlength="">
</td>
</tr>
</table>
</fieldset>
</div>
</form>
<script type="text/javascript">
$(document).ready(function() {
$('#e_email_adresse').focus();
$("#editRegeln").dialog({
modal: true,
bgiframe: true,
closeOnEscape:false,
minWidth:650,
maxHeight:700,
autoOpen: false,
buttons: {
ABBRECHEN: function() {
RegelnReset();
$(this).dialog('close');
},
SPEICHERN: function() {
RegelnEditSave();
}
}
});
$("#editRegeln").dialog({
close: function( event, ui ) { RegelnReset();}
});
});
function RegelnReset()
{
$('#editRegeln').find('#e_id').val('');
$('#editRegeln').find('#e_empf_email_adresse').val('');
$('#editRegeln').find('#e_email_adresse').val('');
$('#editRegeln').find('#e_name').val('');
$('#editRegeln').find('#e_betreff').val('');
$('#editRegeln').find('#e_spam').prop("checked", false);
$('#editRegeln').find('#e_persoenlich').prop("checked", false);
$('#editRegeln').find('#e_prio').prop("checked", false);
$('#editRegeln').find('#e_dsgvo').prop("checked", false);
$('#editRegeln').find('#ticketqueue').val('');
$('#editRegeln').find('#e_aktiv').prop("checked", true);
}
function RegelnEditSave() {
$.ajax({
url: 'index.php?module=ticket&action=regelnsave',
data: {
//Alle Felder die fürs editieren vorhanden sind
id: $('#e_id').val(),
empfaenger_email: $('#e_empf_email_adresse').val(),
sender_email: $('#e_email_adresse').val(),
name: $('#e_name').val(),
betreff: $('#e_betreff').val(),
spam: $('#e_spam').prop("checked")?1:0,
persoenlich: $('#e_persoenlich').prop("checked")?1:0,
prio: $('#e_prio').prop("checked")?1:0,
dsgvo: $('#e_dsgvo').prop("checked")?1:0,
warteschlange: $('#ticketqueue').val(),
aktiv: $('#e_aktiv').prop("checked")?1:0
},
method: 'post',
dataType: 'json',
beforeSend: function() {
App.loading.open();
},
success: function(data) {
App.loading.close();
if (data.status == 1) {
RegelnReset();
updateLiveTable();
$("#editRegeln").dialog('close');
} else {
alert(data.statusText);
}
}
});
}
function RegelnEdit(id) {
if(id > 0)
{
$.ajax({
url: 'index.php?module=ticket&action=regelnedit&cmd=get',
data: {
id: id
},
method: 'post',
dataType: 'json',
beforeSend: function() {
App.loading.open();
},
success: function(data) {
$('#editRegeln').find('#e_id').val(data.id);
$('#editRegeln').find('#e_empf_email_adresse').val(data.empfaenger_email)
$('#editRegeln').find('#e_email_adresse').val(data.sender_email);
$('#editRegeln').find('#e_name').val(data.name);
$('#editRegeln').find('#e_betreff').val(data.betreff);
$('#editRegeln').find('#e_spam').prop("checked",data.spam==1?true:false);
$('#editRegeln').find('#e_persoenlich').prop("checked",data.persoenlich==1?true:false);
$('#editRegeln').find('#e_prio').prop("checked",data.prio==1?true:false);
$('#editRegeln').find('#e_dsgvo').prop("checked",data.dsgvo==1?true:false);
$('#editRegeln').find('#ticketqueue').prop("value",data.warteschlange);
$('#editRegeln').find('#e_aktiv').prop("checked",data.aktiv==1?true:false);
App.loading.close();
$("#editRegeln").dialog('open');
}
});
} else {
RegelnReset();
$("#editRegeln").dialog('open');
}
}
function updateLiveTable(i) {
var oTableL = $('#ticketregeln').dataTable();
var tmp = $('.dataTables_filter input[type=search]').val();
oTableL.fnFilter('%');
//oTableL.fnFilter('');
oTableL.fnFilter(tmp);
}
function RegelnDelete(id) {
var conf = confirm('Wirklich löschen?');
if (conf) {
$.ajax({
url: 'index.php?module=ticket&action=regelndelete',
data: {
id: id
},
method: 'post',
dataType: 'json',
beforeSend: function() {
App.loading.open();
},
success: function(data) {
if (data.status == 1) {
updateLiveTable();
} else {
alert(data.statusText);
}
App.loading.close();
}
});
}
return false;
}
</script>
+1
View File
@@ -0,0 +1 @@
[TEXT]
+91
View File
@@ -0,0 +1,91 @@
<div id="tabs">
<ul>
<li><a href="#tabs-1"></a></li>
</ul>
<!-- Example for multiple tabs
<ul hidden">
<li><a href="#tabs-1">First Tab</a></li>
<li><a href="#tabs-2">Second Tab</a></li>
</ul>
-->
<div id="tabs-1">
[MESSAGE]
<form action="" method="post">
[FORMHANDLEREVENT]
<div class="row">
<div class="row-height">
<div class="col-xs-12 col-md-12 col-md-height">
<div class="inside inside-full-height">
<fieldset>
<legend>{|Ticketregeln|}</legend><i>Ticketregeln f&uuml; die Verarbeitung bei Ticketeingang. Platzhalter werden mit % angegeben.</i>
<table width="100%" border="0" class="mkTableFormular">
<tr><td>{|E-Mail Empf&auml;nger|}:</td><td><input type="text" name="empfaenger_email" value="[EMPFAENGER_EMAIL]" size="40"></td></tr>
<tr><td>{|E-Mail Verfasser|}:</td><td><input type="text" name="sender_email" value="[SENDER_EMAIL]" size="40"></td></tr>
<tr><td>{|Verfasser Name|}:</td><td><input type="text" name="name" value="[NAME]" size="40"></td></tr>
<tr><td>{|Betreff|}:</td><td><input type="text" name="betreff" value="[BETREFF]" size="40"></td></tr>
<tr><td>{|Papierkorb|}:</td><td><input type="text" name="spam" value="[SPAM]" size="40"></td></tr>
<tr><td>{|Pers&ouml;nlich|}:</td><td><input type="text" name="persoenlich" value="[PERSOENLICH]" size="40"></td></tr>
<tr><td>{|Prio|}:</td><td><input type="text" name="prio" value="[PRIO]" size="40"></td></tr>
<tr><td>{|DSGVO|}:</td><td><input type="text" name="dsgvo" value="[DSGVO]" size="40"></td></tr>
<tr><td>{|Verantwortliche Warteschlange|}:</td><td><input type="text" name="warteschlange" id="warteschlange" value="[WARTESCHLANGE]" size="40"></td></tr>
<tr><td>{|Aktiv|}:</td><td><input type="text" name="aktiv" value="[AKTIV]" size="40"></td></tr>
</table>
</fieldset>
</div>
</div>
</div>
</div>
<!-- Example for 2nd row
<div class="row">
<div class="row-height">
<div class="col-xs-12 col-md-12 col-md-height">
<div class="inside inside-full-height">
<fieldset>
<legend>{|Another legend|}</legend>
<table width="100%" border="0" class="mkTableFormular">
<tr><td>{|Empfaenger_email|}:</td><td><input type="text" name="empfaenger_email" value="[EMPFAENGER_EMAIL]" size="40"></td></tr>
<tr><td>{|Sender_email|}:</td><td><input type="text" name="sender_email" value="[SENDER_EMAIL]" size="40"></td></tr>
<tr><td>{|Name|}:</td><td><input type="text" name="name" value="[NAME]" size="40"></td></tr>
<tr><td>{|Betreff|}:</td><td><input type="text" name="betreff" value="[BETREFF]" size="40"></td></tr>
<tr><td>{|Spam|}:</td><td><input type="text" name="spam" value="[SPAM]" size="40"></td></tr>
<tr><td>{|Persoenlich|}:</td><td><input type="text" name="persoenlich" value="[PERSOENLICH]" size="40"></td></tr>
<tr><td>{|Prio|}:</td><td><input type="text" name="prio" value="[PRIO]" size="40"></td></tr>
<tr><td>{|Dsgvo|}:</td><td><input type="text" name="dsgvo" value="[DSGVO]" size="40"></td></tr>
<tr><td>{|Warteschlange|}:</td><td><input type="text" name="warteschlange" value="[WARTESCHLANGE]" size="40"></td></tr>
<tr><td>{|Aktiv|}:</td><td><input type="text" name="aktiv" value="[AKTIV]" size="40"></td></tr>
</table>
</fieldset>
</div>
</div>
</div>
</div> -->
<input type="submit" name="submit" value="Speichern" style="float:right"/>
</form>
</div>
<!-- Example for 2nd tab
<div id="tabs-2">
[MESSAGE]
<form action="" method="post">
[FORMHANDLEREVENT]
<div class="row">
<div class="row-height">
<div class="col-xs-12 col-md-12 col-md-height">
<div class="inside inside-full-height">
<fieldset>
<legend>{|...|}</legend>
<table width="100%" border="0" class="mkTableFormular">
...
</table>
</fieldset>
</div>
</div>
</div>
</div>
<input type="submit" name="submit" value="Speichern" style="float:right"/>
</form>
</div>
-->
</div>
+5
View File
@@ -0,0 +1,5 @@
<div id="tabs-1">
[MESSAGE]
[TAB1]
[TAB1NEXT]
</div>
+94
View File
@@ -0,0 +1,94 @@
<div id="tabs">
<ul>
<li><a href="#tabs-1"></a></li>
</ul>
<!-- Example for multiple tabs
<ul hidden">
<li><a href="#tabs-1">First Tab</a></li>
<li><a href="#tabs-2">Second Tab</a></li>
</ul>
-->
<div id="tabs-1">
[MESSAGE]
<form action="" method="post">
[FORMHANDLEREVENT]
<div class="row">
<div class="row-height">
<div class="col-xs-14 col-md-12 col-md-height">
<div class="inside inside-full-height">
<div class="row">
<div class="row-height">
<div class="col-xs-14 col-md-12 col-md-height">
<div class="inside inside-full-height">
<fieldset>
<legend>{|Aktuelle Version|}</legend>
<table width="100%" border="0" class="mkTableFormular">
<b>OpenXE [CURRENT]</b>
</table>
</fieldset>
</div>
</div>
</div>
</div>
<div class="row">
<div class="row-height">
<div class="col-xs-14 col-md-12 col-md-height">
<div class="inside inside-full-height">
<fieldset>
<legend>{|Ausgabe|}</legend>
<table width="100%" border="0" class="mkTableFormular">
[OUTPUT_FROM_CLI]
</table>
</fieldset>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="col-xs-14 col-md-2 col-md-height">
<div class="inside inside-full-height">
<fieldset>
<legend>{|Aktionen|}</legend>
<table width="100%" border="0" class="mkTableFormular">
<tr><td colspan=2><button name="submit" value="refresh" class="ui-button-icon" style="width:100%;">Anzeige auffrischen</button></td></tr>
<tr><td colspan=2><button name="submit" value="check_upgrade" class="ui-button-icon" style="width:100%;">Upgrades pr&uuml;fen</button></td></tr>
<tr><td style="width:100%;">{|Upgrade-Details anzeigen|}:</td><td><input type="checkbox" name="details_anzeigen" value=1 size="20"></td></tr>
<tr [UPGRADE_VISIBLE]><td colspan=2><button name="submit" value="do_upgrade" class="ui-button-icon" style="width:100%;">UPGRADE</button></td></tr>
<tr [UPGRADE_VISIBLE]><td style="width:100%;">{|Erzwingen (-f)|}:</td><td><input type="checkbox" name="erzwingen" value=1 size="20"></td></tr>
<tr><td colspan=2><button name="submit" value="check_db" class="ui-button-icon" style="width:100%;">Datenbank pr&uuml;fen</button></td></tr>
<tr><td style="width:100%;">{|Datenbank-Details anzeigen|}:</td><td><input type="checkbox" name="db_details_anzeigen" value=1 size="20"></td></tr>
<tr [UPGRADE_DB_VISIBLE]><td colspan=2><button name="submit" value="do_db_upgrade" class="ui-button-icon" style="width:100%;">Datenbank UPGRADE</button></td></tr>
</table>
</fieldset>
</div>
</div>
</div>
</div>
</form>
</div>
<!-- Example for 2nd tab
<div id="tabs-2">
[MESSAGE]
<form action="" method="post">
[FORMHANDLEREVENT]
<div class="row">
<div class="row-height">
<div class="col-xs-12 col-md-12 col-md-height">
<div class="inside inside-full-height">
<fieldset>
<legend>{|...|}</legend>
<table width="100%" border="0" class="mkTableFormular">
...
</table>
</fieldset>
</div>
</div>
</div>
</div>
<input type="submit" name="submit" value="Speichern" style="float:right"/>
</form>
</div>
-->
</div>
@@ -15,7 +15,7 @@
<tr valign="top"><td><b>{|Nummer|}:</b></td><td>[NUMMER]</td></tr> <tr valign="top"><td><b>{|Nummer|}:</b></td><td>[NUMMER]</td></tr>
[BILDERFASSENSTART] [BILDERFASSENSTART]
<tr valign="top"><td><br></td><td align="center"></td></tr> <tr valign="top"><td><br></td><td align="center"></td></tr>
<tr valign="top"><td><b>{|Bild erfassen|}:</b></td><td> <input name="wareneingangartikelbild" type="file" /></td></tr> <tr valign="top"><td><b>{|Bild für Artikelstammdaten erfassen|}:</b></td><td> <input name="wareneingangartikelbild" type="file" /></td></tr>
<tr valign="top"><td><b>{|Bildtyp|}:</b></td><td><select name="bildtyp">[BILDTYPEN]</select></td></tr> <tr valign="top"><td><b>{|Bildtyp|}:</b></td><td><select name="bildtyp">[BILDTYPEN]</select></td></tr>
[BILDERFASSENENDE] [BILDERFASSENENDE]
<tr valign="top"><td><br></td><td align="center"></td></tr> <tr valign="top"><td><br></td><td align="center"></td></tr>
+5
View File
@@ -0,0 +1,5 @@
<div id="tabs-1">
[MESSAGE]
[TAB1]
[TAB1NEXT]
</div>
@@ -5,7 +5,7 @@
<tr valign="top" colspan="3"> <tr valign="top" colspan="3">
<td> <td>
<div class="info">Der Artikel ist f&uuml;r einen Mitarbeiter.</div> <div class="info">Dies ist kein Lagerartikel.</div>
[MESSAGE] [MESSAGE]
<br><br> <br><br>
<table width="60%" style="background-color: #fff; border: solid 1px #000;" align="center"> <table width="60%" style="background-color: #fff; border: solid 1px #000;" align="center">
@@ -15,12 +15,12 @@
<table height="200" border="0" width="450"> <table height="200" border="0" width="450">
<tr valign="top"><td><b>Artikel:</b></td><td><u>[NAME]</u></td></tr> <tr valign="top"><td><b>Artikel:</b></td><td><u>[NAME]</u></td></tr>
<tr valign="top"><td>Lieferant:</td><td>[LIEFERANT]</td></tr> <!--<tr valign="top"><td>Lieferant:</td><td>[LIEFERANT]</td></tr> -->
<tr valign="top"><td><br></td><td align="center"></td></tr> <tr valign="top"><td><br></td><td align="center"></td></tr>
<tr valign="top"><td><b>Bemerkung:</b></td><td><textarea cols="35" rows="2" name="bemerkung">[BEMERKUNG]</textarea> <tr valign="top"><td><b>Bemerkung:</b></td><td><textarea cols="35" rows="2" name="bemerkung">[BEMERKUNG]</textarea>
</td></tr> </td></tr>
<tr valign="top"><td><br></td><td align="center"></td></tr> <tr valign="top"><td><br></td><td align="center"></td></tr>
<tr valign="top"><td nowrap><b>1. Schritt:</b></td><td>Artikel zu Mitarbeiter [MITARBEITER] bringen <tr valign="top"><td nowrap><b>Anmerkung:</b></td><td>Artikel zu Mitarbeiter [MITARBEITER] bringen
[DISPLAY_WARENEINGANG_RMA_HOOK1] [DISPLAY_WARENEINGANG_RMA_HOOK1]
<tr valign="top"><td><br></td><td align="center"><input type="submit" name="submit" value="Speichern" />&nbsp;<input type="button" onclick="window.location.href='index.php?module=wareneingang&action=distriinhalt&id=[ID]'" value="Abbrechen" /></td></tr> <tr valign="top"><td><br></td><td align="center"><input type="submit" name="submit" value="Speichern" />&nbsp;<input type="button" onclick="window.location.href='index.php?module=wareneingang&action=distriinhalt&id=[ID]'" value="Abbrechen" /></td></tr>
</td></tr> </td></tr>
@@ -15,34 +15,60 @@
[TAB1START] [TAB1START]
[MESSAGE1] [MESSAGE1]
<div class="row"> <form action="" method="post">
<div class="row-height"> <div class="row">
<div class="col-xs-12 col-md-10 col-md-height"> <div class="row-height">
<div class="inside-white inside-full-height"> <div class="col-xs-12 col-md-10 col-md-height">
[TAB1] <div class="inside inside-full-height">
<fieldset>
<legend>{|[LEGENDE]|}</legend>
<table>
<tr><td>{|Lieferschein-Nr.|}:</td><td><input type=text size="40" name="lsnr" value=[LSNR]></td></tr>
<tr><td>{|Rechnung-Nr.|}:</td><td><input type=text size="40" name="renr" value=[RENR]></td></tr>
<tr><td>{|Bemerkung|}:</td><td><textarea rows="5" cols="40" name="bemerkung">[BEMERKUNG]</textarea></td></tr>
<tr><td><input type="submit" name="speichern" class="btnGreenNew" value="Speichern"></td>
</table>
</fieldset>
</div>
</div> </div>
</div> <div class="col-xs-12 col-md-2 col-md-height">
<div class="col-xs-12 col-md-2 col-md-height"> <div class="inside inside-full-height">
<div class="inside inside-full-height"> <fieldset>
<fieldset> <legend>{|Aktionen|}</legend>
<legend>{|Aktionen|}</legend> [BUTTONS]
[BUTTONS] [BEFOREFRM]
[BEFOREFRM] [AFTERFRM]
<form action="" method="post"> [DISTRIINHALTBUTTONS]
[AFTERFRM] <input type="submit" name="abschliessen" id="btnabschliessen" class="btnGreenNew" value="Paketinhalt ist erfasst">
[DISTRIINHALTBUTTONS] [BEFOREMANUELLERFASSEN]
<input type="submit" name="abschliessen" id="btnabschliessen" class="btnGreenNew" value="Paketinhalt ist erfasst"> <input type="submit" name="manuellerfassen" class="btnBlueNew" value="Artikel manuell erfassen">
[BEFOREMANUELLERFASSEN] [AFTERMANUELLERFASSEN]
<input type="submit" name="manuellerfassen" class="btnBlueNew" value="Artikel manuell erfassen"> [BEFOREFRM]
[AFTERMANUELLERFASSEN] [AFTERFRM]
[BEFOREFRM] </fieldset>
</form> </div>
[AFTERFRM]
</fieldset>
</div> </div>
</div> </div>
</div> </div>
</div> <div class="row">
<div class="row-height">
<div class="col-xs-12 col-md-10 col-md-height">
<div class="inside-white inside-full-height">
[TAB1]
</div>
</div>
</div>
</div>
<div class="row">
<div class="row-height">
<div class="col-xs-12 col-md-10 col-md-height">
<div class="inside-white inside-full-height">
[TAB1_SECOND]
</div>
</div>
</div>
</div>
</form>
[TAB1ENDE] [TAB1ENDE]
</div> </div>
[AFTERTAB1] [AFTERTAB1]
@@ -108,4 +134,4 @@
}); });
} }
}); });
</script> </script>
+78
View File
@@ -0,0 +1,78 @@
<div id="tabs">
<ul>
<li><a href="#tabs-1"></a></li>
</ul>
<!-- Example for multiple tabs
<ul hidden">
<li><a href="#tabs-1">First Tab</a></li>
<li><a href="#tabs-2">Second Tab</a></li>
</ul>
-->
<div id="tabs-1">
[MESSAGE]
<form action="" method="post">
[FORMHANDLEREVENT]
<div class="row">
<div class="row-height">
<div class="col-xs-12 col-md-12 col-md-height">
<div class="inside inside-full-height">
<fieldset>
<legend>{|<!--Legend for this form area goes here>-->warteschlangen|}</legend>
<table width="100%" border="0" class="mkTableFormular">
<tr><td>{|Warteschlange|}:</td><td><input type="text" name="warteschlange" value="[WARTESCHLANGE]" size="40"></td></tr>
<tr><td>{|Kennung|}:</td><td><input type="text" name="label" value="[LABEL]" size="40"><i>Nur Buchstaben, keine Leerzeichen, keine Sonderzeichen und jede Kennung darf es nur einmal geben.</i></td></tr>
<tr valign="top"><td width="200">{|Verantwortlicher|}:</td><td width="">[ADRESSEAUTOSTART]<input type="text" name="adresse" id="adresse" value="[ADRESSE]" size="40">[ADRESSEAUTOEND]</td></tr>
</table>
</fieldset>
</div>
</div>
</div>
</div>
<!-- Example for 2nd row
<div class="row">
<div class="row-height">
<div class="col-xs-12 col-md-12 col-md-height">
<div class="inside inside-full-height">
<fieldset>
<legend>{|Another legend|}</legend>
<table width="100%" border="0" class="mkTableFormular">
<tr><td>{|Warteschlange|}:</td><td><input type="text" name="warteschlange" value="[WARTESCHLANGE]" size="40"></td></tr>
<tr><td>{|Label|}:</td><td><input type="text" name="label" value="[LABEL]" size="40"></td></tr>
<tr><td>{|Wiedervorlage|}:</td><td><input type="text" name="wiedervorlage" value="[WIEDERVORLAGE]" size="40"></td></tr>
<tr><td>{|Adresse|}:</td><td><input type="text" name="adresse" value="[ADRESSE]" size="40"></td></tr>
</table>
</fieldset>
</div>
</div>
</div>
</div> -->
<input type="submit" name="submit" value="Speichern" style="float:right"/>
</form>
</div>
<!-- Example for 2nd tab
<div id="tabs-2">
[MESSAGE]
<form action="" method="post">
[FORMHANDLEREVENT]
<div class="row">
<div class="row-height">
<div class="col-xs-12 col-md-12 col-md-height">
<div class="inside inside-full-height">
<fieldset>
<legend>{|...|}</legend>
<table width="100%" border="0" class="mkTableFormular">
...
</table>
</fieldset>
</div>
</div>
</div>
</div>
<input type="submit" name="submit" value="Speichern" style="float:right"/>
</form>
</div>
-->
</div>
@@ -0,0 +1,5 @@
<div id="tabs-1">
[MESSAGE]
[TAB1]
[TAB1NEXT]
</div>
+46 -48
View File
@@ -39,7 +39,6 @@ class Dateien {
// alle artikel die ein Kunde kaufen kann mit preisen netto brutto // alle artikel die ein Kunde kaufen kann mit preisen netto brutto
$cmd = $app->Secure->GetGET("smodule"); $cmd = $app->Secure->GetGET("smodule");
$cmd = strtolower($_objekt); $cmd = strtolower($_objekt);
$adresse = $app->DB->Select("SELECT adresse FROM {$cmd} WHERE id='$id' LIMIT 1");
// headings // headings
$heading = array('','','','Titel', 'Stichwort', 'Version','Gr&ouml;&szlig;e', 'Ersteller','Version','Datum','Men&uuml;'); $heading = array('','','','Titel', 'Stichwort', 'Version','Gr&ouml;&szlig;e', 'Ersteller','Version','Datum','Men&uuml;');
@@ -89,6 +88,31 @@ class Dateien {
LEFT JOIN datei_version v ON v.datei=d.id WHERE $where"; LEFT JOIN datei_version v ON v.datei=d.id WHERE $where";
} }
switch ($name) {
case "dateien_list":
$allowed['dateien_list'] = array('list');
$heading = array('ID','Titel', 'Beschreibung', 'Verkn&uuml;pfung', 'Geloescht', 'Logdatei', 'Men&uuml;');
$width = array('10%'); // Fill out manually later
$findcols = array('d.id','d.titel', 'd.beschreibung', 'ds.objekt', 'd.geloescht', 'd.logdatei');
$searchsql = array('d.titel', 'd.beschreibung', 'd.nummer', 'd.geloescht', 'd.logdatei','ds.objekt');
$defaultorder = 1;
$defaultorderdesc = 0;
$menu = "<table cellpadding=0 cellspacing=0><tr><td nowrap>" . "<a href=\"index.php?module=dateien&action=edit&id=%value%\"><img src=\"./themes/{$app->Conf->WFconf['defaulttheme']}/images/edit.svg\" border=\"0\"></a></td></tr></table>";
$sql = "SELECT SQL_CALC_FOUND_ROWS d.id, d.id, d.titel, d.beschreibung, GROUP_CONCAT(ds.objekt SEPARATOR ', ') as verknuepfung, d.geloescht, d.logdatei, d.id FROM datei d LEFT join datei_stichwoerter ds ON ds.datei = d.id";
$where = "1";
$count = "SELECT count(DISTINCT id) FROM datei WHERE $where";
$groupby = " GROUP BY d.id ";
break;
}
$erg = []; $erg = [];
foreach($erlaubtevars as $k => $v) foreach($erlaubtevars as $k => $v)
@@ -113,7 +137,7 @@ class Dateien {
$this->app->ActionHandler("create","DateienCreate"); $this->app->ActionHandler("create","DateienCreate");
$this->app->ActionHandler("edit","DateienEdit"); $this->app->ActionHandler("edit","DateienEdit");
$this->app->ActionHandler("list","DateienList"); $this->app->ActionHandler("list","datei_list");
$this->app->ActionHandler("archiv","DateienArchiv"); $this->app->ActionHandler("archiv","DateienArchiv");
$this->app->ActionHandler("artikel","DateienArtikel"); $this->app->ActionHandler("artikel","DateienArtikel");
$this->app->ActionHandler("send","DateienSend"); $this->app->ActionHandler("send","DateienSend");
@@ -172,23 +196,16 @@ class Dateien {
$this->app->erp->Headlines('Dateien'); $this->app->erp->Headlines('Dateien');
} }
function datei_list() {
$this->app->erp->MenuEintrag("index.php?module=dateien&action=list", "&Uuml;bersicht");
$this->app->erp->MenuEintrag("index.php?module=dateien&action=create", "Neu anlegen");
function DateienList() $this->app->erp->MenuEintrag("index.php", "Zur&uuml;ck");
{
$this->DateienHauptMenu(); $this->app->YUI->TableSearch('TAB1', 'dateien_list', "show", "", "", basename(__FILE__), __CLASS__);
$this->app->Tpl->Parse('PAGE', "dateien_list.tpl");
/* Dateiene zur Nachbesserung */ }
$this->app->Tpl->Set('HEADING','Dateien');
$this->app->Tpl->Set('SUBHEADING','Neuste Dateien');
//Jeder der in Nachbesserung war egal ob auto oder manuell wandert anschliessend in Manuelle-Freigabe");
$table = new EasyTable($this->app);
$table->Query("SELECT d.titel, s.subjekt, v.version, v.ersteller, v.bemerkung, d.id FROM datei d LEFT JOIN datei_stichwoerter s ON d.id=s.datei LEFT JOIN datei_version v ON v.datei=d.id ORDER by d.id DESC LIMIT 10",0,"");
$table->Display('INHALT');
$this->app->Tpl->Parse('PAGE',"rahmen.tpl");
$this->app->Tpl->Set('INHALT','');
}
function DateienDownload() function DateienDownload()
{ {
$typ = $this->app->Secure->GetGET('typ'); $typ = $this->app->Secure->GetGET('typ');
@@ -274,7 +291,7 @@ class Dateien {
$fileid = $this->app->erp->CreateDatei($_FILES['upload']['name'],$titel,$beschreibung,$nummer,$_FILES['upload']['tmp_name'],$this->app->User->GetName()); $fileid = $this->app->erp->CreateDatei($_FILES['upload']['name'],$titel,$beschreibung,$nummer,$_FILES['upload']['tmp_name'],$this->app->User->GetName());
// stichwoerter hinzufuegen // stichwoerter hinzufuegen
$this->app->erp->AddDateiStichwort($fileid,$subjekt,$objekt); $this->app->erp->AddDateiStichwort($fileid,$subjekt,$objekt,$nummer);
$this->app->Location->execute('index.php?module=dateien&action=edit&id='.$fileid); $this->app->Location->execute('index.php?module=dateien&action=edit&id='.$fileid);
//loeschen von /tmp //loeschen von /tmp
} }
@@ -305,7 +322,6 @@ class Dateien {
$beschreibung = $this->app->DB->Select("SELECT beschreibung FROM datei WHERE id='$id' LIMIT 1"); $beschreibung = $this->app->DB->Select("SELECT beschreibung FROM datei WHERE id='$id' LIMIT 1");
$nummer= $this->app->DB->Select("SELECT nummer FROM datei WHERE id='$id' LIMIT 1"); $nummer= $this->app->DB->Select("SELECT nummer FROM datei WHERE id='$id' LIMIT 1");
$this->app->Tpl->Set('TITEL',$titel); $this->app->Tpl->Set('TITEL',$titel);
$this->app->Tpl->Set('KURZUEBERSCHRIFT2',$titel); $this->app->Tpl->Set('KURZUEBERSCHRIFT2',$titel);
$this->app->Tpl->Set('BESCHREIBUNG',$beschreibung); $this->app->Tpl->Set('BESCHREIBUNG',$beschreibung);
@@ -313,17 +329,22 @@ class Dateien {
$table = new EasyTable($this->app); $table = new EasyTable($this->app);
$table->Query("SELECT version,dateiname,datum,ersteller,bemerkung,id FROM datei_version WHERE datei='$id'",0,""); $table->Query("SELECT version,dateiname,datum,ersteller,bemerkung,id FROM datei_version WHERE datei='$id'",0,"");
$table->DisplayNew('VERSIONEN'," /* $table->DisplayNew('VERSIONEN',"
<!--<a href=\"index.php?module=adresse&action=dateiversion&id=$id&lid=%value%\">edit</a>--> <!--<a href=\"index.php?module=adresse&action=dateiversion&id=$id&lid=%value%\">edit</a>-->
<a href=\"#\"onclick=\"if(!confirm('Wirklich löschen?')) return false; else window.location.href='index.php?module=dateien&action=delete&fid=%value%&version=true&id=$id';\" ><img src=\"./themes/new/images/delete.svg\" border=\"0\"></a> <a href=\"#\"onclick=\"if(!confirm('Wirklich löschen?')) return false; else window.location.href='index.php?module=dateien&action=delete&fid=%value%&version=true&id=$id';\" ><img src=\"./themes/new/images/delete.svg\" border=\"0\"></a>
<a href=\"index.php?module=dateien&action=send&fid=%value%&id=$id\"><img src=\"./themes/new/images/download.svg\" border=\"0\"></a> <a href=\"index.php?module=dateien&action=send&fid=%value%&id=$id\"><img src=\"./themes/new/images/download.svg\" border=\"0\"></a>
", ",
"<!--<a href=\"index.php?module=adresse&action=lieferadresseneu&id=$id\">Neue Version anlegen</a>-->"); "<!--<a href=\"index.php?module=adresse&action=lieferadresseneu&id=$id\">Neue Version anlegen</a>-->");*/
$table->DisplayNew('VERSIONEN',"
<a href=\"index.php?module=dateien&action=send&fid=%value%&id=$id\"><img src=\"./themes/new/images/download.svg\" border=\"0\"></a>
");
$table = new EasyTable($this->app); $table = new EasyTable($this->app);
$table->Query("SELECT subjekt,objekt,parameter FROM datei_stichwoerter WHERE datei='$id'",0,""); $table->Query("SELECT subjekt,objekt,parameter FROM datei_stichwoerter WHERE datei='$id'",0,"");
$table->DisplayNew('STICHWORTE',"Parameter","noAction"); $table->DisplayNew('STICHWOERTER',"Parameter","noAction");
$this->app->YUI->AutoComplete("auftrag_zuordnen","auftrag");
$this->app->YUI->AutoComplete("verbindlichkeit_zuordnen","verbindlichkeit");
$this->app->Tpl->Set('HEADING',"Datei (Bearbeiten)"); $this->app->Tpl->Set('HEADING',"Datei (Bearbeiten)");
$this->app->Tpl->Parse('PAGE',"datei.tpl"); $this->app->Tpl->Parse('PAGE',"datei.tpl");
@@ -346,32 +367,9 @@ class Dateien {
$this->app->erp->RunHook('LayouttemplateAttachmentItemsDelete', 2, $id, $cmd); $this->app->erp->RunHook('LayouttemplateAttachmentItemsDelete', 2, $id, $cmd);
$version = $this->app->Secure->GetGET("version"); // Deletion of files removed, they only get marketd
if($version!='')
{
if(is_numeric($fid)){
$this->app->DB->Delete("DELETE FROM datei_version WHERE id='$fid' AND datei='$id' LIMIT 1");
}
// TODO Datei aus dem Dateisystem entfernen
$this->app->Location->execute("index.php?module=dateien&action=edit&id=$id");
}
// stichweoeter loeschen
if(is_numeric($id)){
if($cmd!="") $this->app->DB->Update("UPDATE datei SET geloescht=1 WHERE id='$id'");
{
$this->app->DB->Delete("DELETE FROM datei_stichwoerter WHERE datei='$id' AND objekt LIKE '$cmd' LIMIT 1");
} else {
$this->app->DB->Delete("DELETE FROM datei_stichwoerter WHERE datei='$id'");
}
$check = $this->app->DB->Select("SELECT COUNT(id) FROM datei_stichwoerter WHERE datei='$id'");
if($check <=0)
{
$this->app->DB->Delete("DELETE FROM datei_version WHERE datei='$id'");
$this->app->DB->Update("UPDATE datei SET geloescht=1 WHERE id='$id'");
}
}
$refer = $_SERVER['HTTP_REFERER']; $refer = $_SERVER['HTTP_REFERER'];
$this->app->Location->execute($refer); $this->app->Location->execute($refer);
} }
File diff suppressed because it is too large Load Diff
+88 -7
View File
@@ -1,10 +1,11 @@
<?php <?php
/* /*
* Copyright (c) 2022 Xenomporio project * Copyright (c) 2022 OpenXE project
*/ */
use Xentral\Components\Database\Exception\QueryFailureException; use Xentral\Components\Database\Exception\QueryFailureException;
use Xentral\Components\Logger\Logger;
class Emailbackup { class Emailbackup {
@@ -19,6 +20,7 @@ class Emailbackup {
$this->app->ActionHandler("edit", "emailbackup_edit"); $this->app->ActionHandler("edit", "emailbackup_edit");
$this->app->ActionHandler("delete", "emailbackup_delete"); $this->app->ActionHandler("delete", "emailbackup_delete");
$this->app->ActionHandler("test_smtp",'emailbackup_test_smtp'); $this->app->ActionHandler("test_smtp",'emailbackup_test_smtp');
$this->app->ActionHandler("test_imap",'emailbackup_test_imap');
$this->app->DefaultActionHandler("list"); $this->app->DefaultActionHandler("list");
$this->app->ActionHandlerListen($app); $this->app->ActionHandlerListen($app);
@@ -42,10 +44,10 @@ $width = array('10%'); // Fill out manually later
$defaultorder = 1; $defaultorder = 1;
$defaultorderdesc = 0; $defaultorderdesc = 0;
$menu = "<table cellpadding=0 cellspacing=0><tr><td nowrap>" . "<a href=\"index.php?module=emailbackup&action=edit&id=%value%\"><img src=\"./themes/{$app->Conf->WFconf['defaulttheme']}/images/edit.png\" border=\"0\"></a>&nbsp;<a href=\"#\" onclick=DeleteDialog(\"index.php?module=emailbackup&action=delete&id=%value%\");>" . "<img src=\"themes/{$app->Conf->WFconf['defaulttheme']}/images/delete.svg\" border=\"0\"></a>" . "</td></tr></table>"; $menu = "<table cellpadding=0 cellspacing=0><tr><td nowrap>" . "<a href=\"index.php?module=emailbackup&action=edit&id=%value%\"><img src=\"./themes/{$app->Conf->WFconf['defaulttheme']}/images/edit.svg\" border=\"0\"></a>&nbsp;<a href=\"#\" onclick=DeleteDialog(\"index.php?module=emailbackup&action=delete&id=%value%\");>" . "<img src=\"themes/{$app->Conf->WFconf['defaulttheme']}/images/delete.svg\" border=\"0\"></a>" . "</td></tr></table>";
// $sql = "SELECT id, angezeigtername, internebeschreibung, benutzername, passwort, server, smtp, ticket, imap_sentfolder_aktiv, imap_sentfolder, imap_port, imap_type, autoresponder, geschaeftsbriefvorlage, autoresponderbetreff, autorespondertext, projekt, emailbackup, adresse, firma, loeschtage, geloescht, ticketloeschen, ticketabgeschlossen, ticketqueue, ticketprojekt, ticketemaileingehend, smtp_extra, smtp_ssl, smtp_port, smtp_frommail, smtp_fromname, client_alias, smtp_authtype, smtp_authparam, smtp_loglevel, autosresponder_blacklist, eigenesignatur, signatur, mutex, abdatum, email, id FROM emailbackup"; // $sql = "SELECT id, angezeigtername, internebeschreibung, benutzername, passwort, server, smtp, ticket, imap_sentfolder_aktiv, imap_sentfolder, imap_port, imap_type, autoresponder, geschaeftsbriefvorlage, autoresponderbetreff, autorespondertext, projekt, emailbackup, adresse, firma, loeschtage, geloescht, ticketloeschen, ticketabgeschlossen, ticketqueue, ticketprojekt, ticketemaileingehend, smtp_extra, smtp_ssl, smtp_port, smtp_frommail, smtp_fromname, client_alias, smtp_authtype, smtp_authparam, smtp_loglevel, autosresponder_blacklist, eigenesignatur, signatur, mutex, abdatum, email, id FROM emailbackup";
$sql = "SELECT id, email, angezeigtername, internebeschreibung, benutzername, server, smtp, ticket, emailbackup, id FROM emailbackup"; $sql = "SELECT SQL_CALC_FOUND_ROWS id, email, angezeigtername, internebeschreibung, benutzername, server, smtp, ticket, emailbackup, id FROM emailbackup";
$where = "1"; $where = "1";
$count = "SELECT count(DISTINCT id) FROM emailbackup WHERE $where"; $count = "SELECT count(DISTINCT id) FROM emailbackup WHERE $where";
@@ -282,9 +284,9 @@ $width = array('10%'); // Fill out manually later
$result[0]['angezeigtername'], $result[0]['angezeigtername'],
$result[0]['email'], $result[0]['email'],
$result[0]['angezeigtername'], $result[0]['angezeigtername'],
'Xenomporio ERP: Testmail', 'OpenXE ERP: Testmail',
'Dies ist eine Testmail', 'Dies ist eine Testmail für Account "'.$result[0]['email'].'".',
'',0,true,'','', '',0,false,'','',
true true
) )
) { ) {
@@ -294,11 +296,90 @@ $width = array('10%'); // Fill out manually later
} }
else { else {
$msg = $this->app->erp->base64_url_encode( $msg = $this->app->erp->base64_url_encode(
'<div class="error">Die Testmail wurde nicht versendet: '.$this->app->erp->mail_error.'</div>' '<div class="error">Fehler beim Versenden der Testmail: '.$this->app->erp->mail_error.'</div>'
); );
} }
$this->app->Location->execute("index.php?module=emailbackup&id=$id&action=edit&msg=$msg"); $this->app->Location->execute("index.php?module=emailbackup&id=$id&action=edit&msg=$msg");
} }
function emailbackup_test_imap() {
$id = $this->app->Secure->GetGET('id');
// get email Account
/** @var EmailAccountGateway $accountGateway */
$accountGateway = $this->app->Container->get('EmailAccountGateway');
$account = $accountGateway->getEmailAccountById($id);
if(!empty($account)) {
/** @var Ticket $ticketModule */
$ticketModule = $this->app->erp->LoadModul('ticket');
/** @var MailClientFactory $factory */
$factory = $this->app->Container->get('MailClientFactory');
/** @var MailClientConfigProvider $configProvider */
$configProvider = $this->app->Container->get('MailClientConfigProvider');
/** @var TicketFormatter $formatHelper */
$formatHelper = $this->app->Container->get('TicketFormatter');
/** @var TicketImportHelperFactory $importHelperFactory */
$importHelperFactory = $this->app->Container->get('TicketImportHelperFactory');
/** @var Logger $logger */
$logger = $this->app->Container->get('Logger');
$logger->debug(
'Start imap test {email}',
['email' => $account->getEmailAddress(), 'account' => $account]
);
// create mail client
try {
$mailConfig = $configProvider->createImapConfigFromAccount($account);
$mailClient = $factory->createImapClient($mailConfig);
} catch (Exception $e) {
$logger->error('Failed to create email client', ['error' => (string)$e, 'account' => $account]);
$msg = $this->app->erp->base64_url_encode(
'<div class="error">Fehler IMAP Test: '.$this->app->erp->mail_error.'</div>');
$error = true;
}
// connect mail client
try {
$mailClient->connect();
} catch (Exception $e) {
$logger->error('Error during imap connection', ['error' => (string)$e, 'account' => $account]);
$msg = $this->app->erp->base64_url_encode(
'<div class="error">Fehler IMAP Test: '.$this->app->erp->mail_error.'</div>');
$error = true;
}
// connet to INBOX folder
try {
$mailClient->selectFolder('INBOX');
} catch (Exception $e) {
$logger->error('Failed to select INBOX folder', ['error' => (string)$e, 'account' => $account]);
$msg = $this->app->erp->base64_url_encode(
'<div class="error">Fehler IMAP Test: '.$this->app->erp->mail_error.'</div>');
$error = true;
}
$mailClient->expunge();
$mailClient->disconnect();
if (!$error) {
$msg = $this->app->erp->base64_url_encode(
'<div class="info">IMAP Verbindung erfolgreich!</div>');
$logger->debug(
'IMAP test ok {email}',
['email' => $account->getEmailAddress(), 'account' => $account]
);
}
} else
{
$msg = $this->app->erp->base64_url_encode(
'<div class="error">Kein Account gefunden!</div>');
}
$this->app->Location->execute("index.php?module=emailbackup&id=$id&action=edit&msg=$msg");
}
} }
+2 -2
View File
@@ -468,7 +468,7 @@ class Firmendaten {
$this->app->erp->Firmendaten('absendername'), $this->app->erp->Firmendaten('absendername'),
$this->app->erp->Firmendaten('testmailempfaenger'), $this->app->erp->Firmendaten('testmailempfaenger'),
$this->app->erp->Firmendaten('testmailempfaenger'), $this->app->erp->Firmendaten('testmailempfaenger'),
'Xenomporio ERP: Testmail', 'OpenXE ERP: Testmail',
'Dies ist eine Testmail', 'Dies ist eine Testmail',
'',0,true,'','', '',0,true,'','',
true true
@@ -480,7 +480,7 @@ class Firmendaten {
} }
else { else {
$msg = $this->app->erp->base64_url_encode( $msg = $this->app->erp->base64_url_encode(
'<div class="error">Die Testmail wurde nicht versendet: '.$this->app->erp->mail_error.'</div>' '<div class="error">Fehler beim Versenden der Testmail: '.$this->app->erp->mail_error.'</div>'
); );
} }
$this->app->Location->execute("index.php?module=firmendaten&action=edit&msg=$msg#tabs-4"); $this->app->Location->execute("index.php?module=firmendaten&action=edit&msg=$msg#tabs-4");
+4 -4
View File
@@ -1353,7 +1353,7 @@ class Kalender {
$ical = "BEGIN:VCALENDAR\r\n"; $ical = "BEGIN:VCALENDAR\r\n";
$ical .= "VERSION:2.0\r\n"; $ical .= "VERSION:2.0\r\n";
$ical .= "PRODID:-//Xenomporio//Termin//DE\r\n"; $ical .= "PRODID:-//OpenXE//Termin//DE\r\n";
$ical .= "METHOD:REQUEST\r\n"; $ical .= "METHOD:REQUEST\r\n";
$ical .= "BEGIN:VEVENT\r\n"; $ical .= "BEGIN:VEVENT\r\n";
@@ -1376,7 +1376,7 @@ class Kalender {
} }
} }
$ical .= "UID:".strtoupper(md5($event_id))."-xenomporio\r\n"; $ical .= "UID:".strtoupper(md5($event_id))."-openxe\r\n";
$ical .= "SEQUENCE:".$sequence."\r\n"; $ical .= "SEQUENCE:".$sequence."\r\n";
$ical .= "STATUS:".$status."\r\n"; $ical .= "STATUS:".$status."\r\n";
$ical .= "DTSTAMPTZID=Europe/Berlin:".date('Ymd').'T'.date('His')."\r\n"; $ical .= "DTSTAMPTZID=Europe/Berlin:".date('Ymd').'T'.date('His')."\r\n";
@@ -1513,12 +1513,12 @@ class Kalender {
$ical = "BEGIN:VCALENDAR\r\n"; $ical = "BEGIN:VCALENDAR\r\n";
$ical .= "VERSION:2.0\r\n"; $ical .= "VERSION:2.0\r\n";
$ical .= "PRODID:-//Xenomporio//Termin//DE\r\n"; $ical .= "PRODID:-//OpenXE//Termin//DE\r\n";
$ical .= "METHOD:REQUEST\r\n"; $ical .= "METHOD:REQUEST\r\n";
$ical .= "BEGIN:VEVENT\r\n"; $ical .= "BEGIN:VEVENT\r\n";
$ical .= "ORGANIZER;SENT-BY=\"MAILTO:$initiator_to\"\r\n"; $ical .= "ORGANIZER;SENT-BY=\"MAILTO:$initiator_to\"\r\n";
$ical .= "ATTENDEE;CN=$to;ROLE=REQ-PARTICIPANT;PARTSTAT=ACCEPTED;RSVP=TRUE:mailto:$initiator_to\r\n"; $ical .= "ATTENDEE;CN=$to;ROLE=REQ-PARTICIPANT;PARTSTAT=ACCEPTED;RSVP=TRUE:mailto:$initiator_to\r\n";
$ical .= "UID:".strtoupper(md5($event_id))."-xenomporio\r\n"; $ical .= "UID:".strtoupper(md5($event_id))."-openxe\r\n";
$ical .= "SEQUENCE:".$sequence."\r\n"; $ical .= "SEQUENCE:".$sequence."\r\n";
$ical .= "STATUS:".$status."\r\n"; $ical .= "STATUS:".$status."\r\n";
$ical .= "DTSTAMPTZID=Europe/Berlin:".date('Ymd').'T'.date('His')."\r\n"; $ical .= "DTSTAMPTZID=Europe/Berlin:".date('Ymd').'T'.date('His')."\r\n";
+14 -13
View File
@@ -1346,17 +1346,17 @@ class Lager extends GenLager {
case "lager_reservierungen": case "lager_reservierungen":
$allowed['lager'] = array('reservierungen'); $allowed['lager'] = array('reservierungen');
$heading = array('Kunde','Belegart','Belegnr','Status','Artikel','Menge','Projekt','Grund','Men&uuml;'); $heading = array('Kunde','Belegart','Belegnr','Status','Artikelnummer','Artikel','Menge','Projekt','Grund','Men&uuml;');
$width = array('20%','20%','5%','10%','20%','1%'); $width = array('20%', '10%', '5%', '5%', '5%', '20%', '1%', '10%', '20%');
$findcols = array('t.kunde', 't.typ', 't.belegnr', 't.status', 't.Artikel', 't.menge', 't.projekt', 't.grund', 't.rid'); $findcols = array('t.kunde', 't.typ', 't.belegnr', 't.status','t.Artikelnummer', 't.Artikel', 't.menge', 't.projekt', 't.grund', 't.rid');
$searchsql = array('t.kunde', 't.typ', 't.belegnr', 't.status', 't.Artikel', $app->erp->FormatMenge('t.menge'), 't.projekt', 't.grund'); $searchsql = array('t.kunde', 't.typ', 't.belegnr', 't.status','t.Artikelnummer', 't.Artikel', $app->erp->FormatMenge('t.menge'), 't.projekt', 't.grund');
$defaultorder = 1; //Optional wenn andere Reihenfolge gewuenscht $defaultorder = 1; //Optional wenn andere Reihenfolge gewuenscht
$defaultorderdesc = 1; $defaultorderdesc = 1;
//$sumcol = 9; //$sumcol = 9;
$menu = "<table cellpadding=0 cellspacing=0><tr><td nowrap><a href=\"#\" onclick=DeleteDialog(\"index.php?module=lager&action=artikelentfernenreserviert&reservierung=%value%\"); ><img src=\"themes/{$app->Conf->WFconf['defaulttheme']}/images/delete.svg\" border=\"0\"></a></td></tr></table>"; $menu = "<table cellpadding=0 cellspacing=0><tr><td nowrap><a href=\"#\" onclick=DeleteDialog(\"index.php?module=lager&action=artikelentfernenreserviert&reservierung=%value%\"); ><img src=\"themes/{$app->Conf->WFconf['defaulttheme']}/images/delete.svg\" border=\"0\"></a></td></tr></table>";
$alignright = array(6); $alignright = array(7);
$numbercols = array(5); $numbercols = array(6);
$menucol = 5; $menucol = 5;
//$moreinfo = true; //$moreinfo = true;
$sql = " $sql = "
@@ -1366,6 +1366,7 @@ class Lager extends GenLager {
t.typ, t.typ,
t.belegnr, t.belegnr,
t.status, t.status,
t.Artikelnummer,
t.Artikel, t.Artikel,
".$app->erp->FormatMenge('t.menge').", ".$app->erp->FormatMenge('t.menge').",
t.projekt, t.projekt,
@@ -1375,43 +1376,43 @@ class Lager extends GenLager {
FROM FROM
( (
( (
SELECT r.id as rid, adr.name as kunde,'Auftrag' as typ,if(auf.belegnr = '','ENTWURF',auf.belegnr) as belegnr ,if(auf.status = '','angelegt',auf.status) as status, a.name_de as Artikel,r.menge,p.abkuerzung as projekt,r.grund, r.id FROM lager_reserviert r LEFT JOIN artikel a ON a.id=r.artikel LEFT JOIN projekt p ON SELECT r.id as rid, adr.name as kunde,'Auftrag' as typ,if(auf.belegnr = '','ENTWURF',auf.belegnr) as belegnr ,if(auf.status = '','angelegt',auf.status) as status, a.nummer as Artikelnummer, a.name_de as Artikel,r.menge,p.abkuerzung as projekt,r.grund, r.id FROM lager_reserviert r LEFT JOIN artikel a ON a.id=r.artikel LEFT JOIN projekt p ON
p.id=r.projekt LEFT JOIN adresse adr ON r.adresse=adr.id p.id=r.projekt LEFT JOIN adresse adr ON r.adresse=adr.id
INNER JOIN auftrag auf ON auf.id = r.parameter AND r.objekt = 'auftrag' INNER JOIN auftrag auf ON auf.id = r.parameter AND r.objekt = 'auftrag'
) )
UNION ALL UNION ALL
( (
SELECT r.id as rid, adr.name as kunde,'Lieferschein' as typ,if(l.belegnr = '','ENTWURF',l.belegnr) as belegnr ,if(l.status = '','angelegt',l.status) as status, a.name_de as Artikel,r.menge,p.abkuerzung as projekt,r.grund, r.id FROM lager_reserviert r LEFT JOIN artikel a ON a.id=r.artikel LEFT JOIN projekt p ON SELECT r.id as rid, adr.name as kunde,'Lieferschein' as typ,if(l.belegnr = '','ENTWURF',l.belegnr) as belegnr ,if(l.status = '','angelegt',l.status) as status, a.nummer as Artikelnummer, a.name_de as Artikel,r.menge,p.abkuerzung as projekt,r.grund, r.id FROM lager_reserviert r LEFT JOIN artikel a ON a.id=r.artikel LEFT JOIN projekt p ON
p.id=r.projekt LEFT JOIN adresse adr ON r.adresse=adr.id p.id=r.projekt LEFT JOIN adresse adr ON r.adresse=adr.id
INNER JOIN lieferschein l ON l.id = r.parameter AND r.objekt = 'lieferschein' INNER JOIN lieferschein l ON l.id = r.parameter AND r.objekt = 'lieferschein'
) )
UNION ALL UNION ALL
( (
SELECT r.id as rid, adr.name as kunde,'Produktion' as typ,if(l.belegnr = '','ENTWURF',l.belegnr) as belegnr ,if(l.status = '','angelegt',l.status) as status, a.name_de as Artikel,r.menge,p.abkuerzung as projekt,r.grund, r.id FROM lager_reserviert r LEFT JOIN artikel a ON a.id=r.artikel LEFT JOIN projekt p ON SELECT r.id as rid, adr.name as kunde,'Produktion' as typ,if(l.belegnr = '','ENTWURF',l.belegnr) as belegnr ,if(l.status = '','angelegt',l.status) as status, a.nummer as Artikelnummer, a.name_de as Artikel,r.menge,p.abkuerzung as projekt,r.grund, r.id FROM lager_reserviert r LEFT JOIN artikel a ON a.id=r.artikel LEFT JOIN projekt p ON
p.id=r.projekt LEFT JOIN adresse adr ON r.adresse=adr.id p.id=r.projekt LEFT JOIN adresse adr ON r.adresse=adr.id
INNER JOIN produktion l ON l.id = r.parameter AND r.objekt = 'produktion' INNER JOIN produktion l ON l.id = r.parameter AND r.objekt = 'produktion'
) )
UNION ALL UNION ALL
( (
SELECT r.id as rid, adr.name as kunde,'Auftrag' as typ,'GEL&Ouml;SCHT' as belegnr ,'GEL&Ouml;SCHT' as status, a.name_de as Artikel,r.menge,p.abkuerzung as projekt,r.grund, r.id FROM lager_reserviert r LEFT JOIN artikel a ON a.id=r.artikel LEFT JOIN projekt p ON SELECT r.id as rid, adr.name as kunde,'Auftrag' as typ,'GEL&Ouml;SCHT' as belegnr ,'GEL&Ouml;SCHT' as status, a.nummer as Artikelnummer, a.name_de as Artikel,r.menge,p.abkuerzung as projekt,r.grund, r.id FROM lager_reserviert r LEFT JOIN artikel a ON a.id=r.artikel LEFT JOIN projekt p ON
p.id=r.projekt LEFT JOIN adresse adr ON r.adresse=adr.id p.id=r.projekt LEFT JOIN adresse adr ON r.adresse=adr.id
LEFT JOIN auftrag auf ON auf.id = r.parameter AND r.objekt = 'auftrag' WHERE isnull(auf.id) AND r.objekt = 'auftrag' LEFT JOIN auftrag auf ON auf.id = r.parameter AND r.objekt = 'auftrag' WHERE isnull(auf.id) AND r.objekt = 'auftrag'
) )
UNION ALL UNION ALL
( (
SELECT r.id as rid, adr.name as kunde,'Lieferschein' as typ,'GEL&Ouml;SCHT' as belegnr ,'GEL&Ouml;SCHT' as status, a.name_de as Artikel,r.menge,p.abkuerzung as projekt,r.grund, r.id FROM lager_reserviert r LEFT JOIN artikel a ON a.id=r.artikel LEFT JOIN projekt p ON SELECT r.id as rid, adr.name as kunde,'Lieferschein' as typ,'GEL&Ouml;SCHT' as belegnr ,'GEL&Ouml;SCHT' as status, a.nummer as Artikelnummer, a.name_de as Artikel,r.menge,p.abkuerzung as projekt,r.grund, r.id FROM lager_reserviert r LEFT JOIN artikel a ON a.id=r.artikel LEFT JOIN projekt p ON
p.id=r.projekt LEFT JOIN adresse adr ON r.adresse=adr.id p.id=r.projekt LEFT JOIN adresse adr ON r.adresse=adr.id
LEFT JOIN lieferschein l ON l.id = r.parameter AND r.objekt = 'lieferschein' WHERE isnull(l.id) AND r.objekt = 'lieferschein' LEFT JOIN lieferschein l ON l.id = r.parameter AND r.objekt = 'lieferschein' WHERE isnull(l.id) AND r.objekt = 'lieferschein'
) )
UNION ALL UNION ALL
( (
SELECT r.id as rid, adr.name as kunde,'Produktion' as typ,'GEL&Ouml;SCHT' as belegnr ,'GEL&Ouml;SCHT' as status, a.name_de as Artikel,r.menge,p.abkuerzung as projekt,r.grund, r.id FROM lager_reserviert r LEFT JOIN artikel a ON a.id=r.artikel LEFT JOIN projekt p ON SELECT r.id as rid, adr.name as kunde,'Produktion' as typ,'GEL&Ouml;SCHT' as belegnr ,'GEL&Ouml;SCHT' as status, a.nummer as Artikelnummer, a.name_de as Artikel,r.menge,p.abkuerzung as projekt,r.grund, r.id FROM lager_reserviert r LEFT JOIN artikel a ON a.id=r.artikel LEFT JOIN projekt p ON
p.id=r.projekt LEFT JOIN adresse adr ON r.adresse=adr.id p.id=r.projekt LEFT JOIN adresse adr ON r.adresse=adr.id
LEFT JOIN produktion l ON l.id = r.parameter AND r.objekt = 'produktion' WHERE isnull(l.id) AND r.objekt = 'produktion' LEFT JOIN produktion l ON l.id = r.parameter AND r.objekt = 'produktion' WHERE isnull(l.id) AND r.objekt = 'produktion'
) )
UNION ALL UNION ALL
( (
SELECT r.id as rid, adr.name as kunde,r.objekt as typ,'' as belegnr , '' as status, a.name_de as Artikel,r.menge,p.abkuerzung as projekt,r.grund, r.id FROM lager_reserviert r LEFT JOIN artikel a ON a.id=r.artikel LEFT JOIN projekt p ON SELECT r.id as rid, adr.name as kunde,r.objekt as typ,'' as belegnr , '' as status, a.nummer as Artikelnummer, a.name_de as Artikel, r.menge,p.abkuerzung as projekt,r.grund, r.id FROM lager_reserviert r LEFT JOIN artikel a ON a.id=r.artikel LEFT JOIN projekt p ON
p.id=r.projekt LEFT JOIN adresse adr ON r.adresse=adr.id WHERE r.objekt <> 'auftrag' AND r.objekt <> 'lieferschein' AND r.objekt <> 'produktion' p.id=r.projekt LEFT JOIN adresse adr ON r.adresse=adr.id WHERE r.objekt <> 'auftrag' AND r.objekt <> 'lieferschein' AND r.objekt <> 'produktion'
) )
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
+249
View File
@@ -0,0 +1,249 @@
<?php
/*
* Copyright (c) 2022 OpenXE project
*/
use Xentral\Components\Database\Exception\QueryFailureException;
class Produktion_position {
function __construct($app, $intern = false) {
$this->app = $app;
if ($intern)
return;
$this->app->ActionHandlerInit($this);
$this->app->ActionHandler("list", "produktion_position_list");
$this->app->ActionHandler("create", "produktion_position_edit"); // This automatically adds a "New" button
$this->app->ActionHandler("edit", "produktion_position_edit");
$this->app->ActionHandler("delete", "produktion_position_delete");
$this->app->DefaultActionHandler("list");
$this->app->ActionHandlerListen($app);
}
public function Install() {
/* Fill out manually later */
}
static function TableSearch(&$app, $name, $erlaubtevars) {
switch ($name) {
case "produktion_position_list":
$allowed['produktion_position_list'] = array('list');
$heading = array('','','produktion', 'artikel', 'projekt', 'bezeichnung', 'beschreibung', 'internerkommentar', 'nummer', 'menge', 'preis', 'waehrung', 'lieferdatum', 'vpe', 'sort', 'status', 'umsatzsteuer', 'bemerkung', 'geliefert', 'geliefert_menge', 'explodiert', 'explodiert_parent', 'logdatei', 'nachbestelltexternereinkauf', 'beistellung', 'externeproduktion', 'einheit', 'steuersatz', 'steuertext', 'erloese', 'erloesefestschreiben', 'freifeld1', 'freifeld2', 'freifeld3', 'freifeld4', 'freifeld5', 'freifeld6', 'freifeld7', 'freifeld8', 'freifeld9', 'freifeld10', 'freifeld11', 'freifeld12', 'freifeld13', 'freifeld14', 'freifeld15', 'freifeld16', 'freifeld17', 'freifeld18', 'freifeld19', 'freifeld20', 'freifeld21', 'freifeld22', 'freifeld23', 'freifeld24', 'freifeld25', 'freifeld26', 'freifeld27', 'freifeld28', 'freifeld29', 'freifeld30', 'freifeld31', 'freifeld32', 'freifeld33', 'freifeld34', 'freifeld35', 'freifeld36', 'freifeld37', 'freifeld38', 'freifeld39', 'freifeld40', 'stuecklistestufe', 'teilprojekt', 'Men&uuml;');
$width = array('1%','1%','10%'); // Fill out manually later
$findcols = array('p.produktion', 'p.artikel', 'p.projekt', 'p.bezeichnung', 'p.beschreibung', 'p.internerkommentar', 'p.nummer', 'p.menge', 'p.preis', 'p.waehrung', 'p.lieferdatum', 'p.vpe', 'p.sort', 'p.status', 'p.umsatzsteuer', 'p.bemerkung', 'p.geliefert', 'p.geliefert_menge', 'p.explodiert', 'p.explodiert_parent', 'p.logdatei', 'p.nachbestelltexternereinkauf', 'p.beistellung', 'p.externeproduktion', 'p.einheit', 'p.steuersatz', 'p.steuertext', 'p.erloese', 'p.erloesefestschreiben', 'p.freifeld1', 'p.freifeld2', 'p.freifeld3', 'p.freifeld4', 'p.freifeld5', 'p.freifeld6', 'p.freifeld7', 'p.freifeld8', 'p.freifeld9', 'p.freifeld10', 'p.freifeld11', 'p.freifeld12', 'p.freifeld13', 'p.freifeld14', 'p.freifeld15', 'p.freifeld16', 'p.freifeld17', 'p.freifeld18', 'p.freifeld19', 'p.freifeld20', 'p.freifeld21', 'p.freifeld22', 'p.freifeld23', 'p.freifeld24', 'p.freifeld25', 'p.freifeld26', 'p.freifeld27', 'p.freifeld28', 'p.freifeld29', 'p.freifeld30', 'p.freifeld31', 'p.freifeld32', 'p.freifeld33', 'p.freifeld34', 'p.freifeld35', 'p.freifeld36', 'p.freifeld37', 'p.freifeld38', 'p.freifeld39', 'p.freifeld40', 'p.stuecklistestufe', 'p.teilprojekt');
$searchsql = array('p.produktion', 'p.artikel', 'p.projekt', 'p.bezeichnung', 'p.beschreibung', 'p.internerkommentar', 'p.nummer', 'p.menge', 'p.preis', 'p.waehrung', 'p.lieferdatum', 'p.vpe', 'p.sort', 'p.status', 'p.umsatzsteuer', 'p.bemerkung', 'p.geliefert', 'p.geliefert_menge', 'p.explodiert', 'p.explodiert_parent', 'p.logdatei', 'p.nachbestelltexternereinkauf', 'p.beistellung', 'p.externeproduktion', 'p.einheit', 'p.steuersatz', 'p.steuertext', 'p.erloese', 'p.erloesefestschreiben', 'p.freifeld1', 'p.freifeld2', 'p.freifeld3', 'p.freifeld4', 'p.freifeld5', 'p.freifeld6', 'p.freifeld7', 'p.freifeld8', 'p.freifeld9', 'p.freifeld10', 'p.freifeld11', 'p.freifeld12', 'p.freifeld13', 'p.freifeld14', 'p.freifeld15', 'p.freifeld16', 'p.freifeld17', 'p.freifeld18', 'p.freifeld19', 'p.freifeld20', 'p.freifeld21', 'p.freifeld22', 'p.freifeld23', 'p.freifeld24', 'p.freifeld25', 'p.freifeld26', 'p.freifeld27', 'p.freifeld28', 'p.freifeld29', 'p.freifeld30', 'p.freifeld31', 'p.freifeld32', 'p.freifeld33', 'p.freifeld34', 'p.freifeld35', 'p.freifeld36', 'p.freifeld37', 'p.freifeld38', 'p.freifeld39', 'p.freifeld40', 'p.stuecklistestufe', 'p.teilprojekt');
$defaultorder = 1;
$defaultorderdesc = 0;
$dropnbox = "'<img src=./themes/new/images/details_open.png class=details>' AS `open`, CONCAT('<input type=\"checkbox\" name=\"auswahl[]\" value=\"',p.id,'\" />') AS `auswahl`";
$menu = "<table cellpadding=0 cellspacing=0><tr><td nowrap>" . "<a href=\"index.php?module=produktion_position&action=edit&id=%value%\"><img src=\"./themes/{$app->Conf->WFconf['defaulttheme']}/images/edit.svg\" border=\"0\"></a>&nbsp;<a href=\"#\" onclick=DeleteDialog(\"index.php?module=produktion_position&action=delete&id=%value%\");>" . "<img src=\"themes/{$app->Conf->WFconf['defaulttheme']}/images/delete.svg\" border=\"0\"></a>" . "</td></tr></table>";
$sql = "SELECT SQL_CALC_FOUND_ROWS p.id, $dropnbox, p.produktion, p.artikel, p.projekt, p.bezeichnung, p.beschreibung, p.internerkommentar, p.nummer, p.menge, p.preis, p.waehrung, p.lieferdatum, p.vpe, p.sort, p.status, p.umsatzsteuer, p.bemerkung, p.geliefert, p.geliefert_menge, p.explodiert, p.explodiert_parent, p.logdatei, p.nachbestelltexternereinkauf, p.beistellung, p.externeproduktion, p.einheit, p.steuersatz, p.steuertext, p.erloese, p.erloesefestschreiben, p.freifeld1, p.freifeld2, p.freifeld3, p.freifeld4, p.freifeld5, p.freifeld6, p.freifeld7, p.freifeld8, p.freifeld9, p.freifeld10, p.freifeld11, p.freifeld12, p.freifeld13, p.freifeld14, p.freifeld15, p.freifeld16, p.freifeld17, p.freifeld18, p.freifeld19, p.freifeld20, p.freifeld21, p.freifeld22, p.freifeld23, p.freifeld24, p.freifeld25, p.freifeld26, p.freifeld27, p.freifeld28, p.freifeld29, p.freifeld30, p.freifeld31, p.freifeld32, p.freifeld33, p.freifeld34, p.freifeld35, p.freifeld36, p.freifeld37, p.freifeld38, p.freifeld39, p.freifeld40, p.stuecklistestufe, p.teilprojekt, p.id FROM produktion_position p";
$where = "1";
$count = "SELECT count(DISTINCT id) FROM produktion_position WHERE $where";
// $groupby = "";
break;
}
$erg = false;
foreach ($erlaubtevars as $k => $v) {
if (isset($$v)) {
$erg[$v] = $$v;
}
}
return $erg;
}
function produktion_position_list() {
/* $this->app->erp->MenuEintrag("index.php?module=produktion_position&action=list", "&Uuml;bersicht");
$this->app->erp->MenuEintrag("index.php?module=produktion_position&action=create", "Neu anlegen");
$this->app->erp->MenuEintrag("index.php", "Zur&uuml;ck");
$this->app->YUI->TableSearch('TAB1', 'produktion_position_list', "show", "", "", basename(__FILE__), __CLASS__);
$this->app->Tpl->Parse('PAGE', "produktion_position_list.tpl");*/
header("Location: index.php?module=produktion&action=list");
}
// End edit process and return to previous page
// Give pid in case of delete because position.id is already gone
function produktion_position_edit_end(string $msg, bool $error, bool $go_to_production, int $pid = 0) {
if ($error) {
$msg = $this->app->erp->base64_url_encode("<div class=\"error\">".$msg."</div>");
} else {
$msg = $this->app->erp->base64_url_encode("<div class=\"info\">".$msg."</div>");
}
if ($go_to_production) {
if ($pid == 0) {
$id = (int) $this->app->Secure->GetGET('id');
$sql = "SELECT p.status, p.id from produktion p INNER JOIN produktion_position pp ON pp.produktion = p.id WHERE pp.id = $id";
$result = $this->app->DB->SelectArr($sql)[0];
$pid = $result['id'];
}
header("Location: index.php?module=produktion&action=edit&id=$pid&msg=$msg#tabs-3");
} else {
header("Location: index.php?module=produktion_position&action=list&msg=$msg");
}
exit();
}
public function produktion_position_delete() {
$id = (int) $this->app->Secure->GetGET('id');
$sql = "SELECT p.status, p.id from produktion p INNER JOIN produktion_position pp ON pp.produktion = p.id WHERE pp.id = $id";
$result = $this->app->DB->SelectArr($sql)[0];
$status = $result['status'];
$pid = $result['id'];
if (!in_array($status,array('angelegt','freigegeben'))) {
$this->produktion_position_edit_end("Bearbeiten nicht möglich, Produktionsstatus ist '$status'",true, true);
}
$this->app->DB->Delete("DELETE FROM `produktion_position` WHERE `id` = '{$id}'");
// Remove reserved items
$this->produktion_position_edit_end("Der Eintrag wurde gel&ouml;scht.", true, true, $pid);
}
/*
* Edit produktion_position item
* If id is empty, create a new one
*/
function produktion_position_edit() {
$id = $this->app->Secure->GetGET('id');
$this->app->Tpl->Set('ID', $id);
$this->app->erp->MenuEintrag("index.php?module=produktion_position&action=edit&id=$id", "Details");
$this->app->erp->MenuEintrag("index.php?module=produktion&action=edit%id=$pid", "Zur&uuml;ck zur &Uuml;bersicht");
$id = $this->app->Secure->GetGET('id');
$input = $this->GetInput();
$submit = $this->app->Secure->GetPOST('submit');
if (empty($id)) {
// New item
$id = 'NULL';
}
$sql = "SELECT p.status, p.id from produktion p INNER JOIN produktion_position pp ON pp.produktion = p.id WHERE pp.id = $id";
$result = $this->app->DB->SelectArr($sql)[0];
$status = $result['status'];
$produktion_id = $result['id'];
$sql = "SELECT FORMAT(menge,0) as menge FROM produktion_position WHERE produktion = $produktion_id AND stuecklistestufe = 1";
$result = $this->app->DB->SelectArr($sql)[0];
$planmenge = $result['menge'];
if ($submit != '')
{
// Write to database
// Add checks here
$input['artikel'] = $this->app->erp->ReplaceArtikel(true, $input['artikel'],true); // Convert from form to db
// Only allowed when produktion is 'freigegeben or angelegt'
if (!in_array($status,array('angelegt','freigegeben'))) {
$this->produktion_position_edit_end("Bearbeiten nicht möglich, Produktionsstatus ist '$status'",true, true);
}
if ($input['menge'] < 0) {
$this->produktion_position_edit_end("Ung&uuml;ltige Menge.",true, true);
}
// Only allow quantities that are a multiple of the target quantity
if ($input['menge'] % $planmenge != 0) {
$this->produktion_position_edit_end("Positionsmenge muss Vielfaches von $planmenge sein.",true, true);
}
$columns = "id, ";
$values = "$id, ";
$update = "";
$fix = "";
foreach ($input as $key => $value) {
$columns = $columns.$fix.$key;
$values = $values.$fix."'".$value."'";
$update = $update.$fix.$key." = '$value'";
$fix = ", ";
}
// echo($columns."<br>");
// echo($values."<br>");
// echo($update."<br>");
$sql = "INSERT INTO produktion_position (".$columns.") VALUES (".$values.") ON DUPLICATE KEY UPDATE ".$update;
// echo($sql);
$this->app->DB->Update($sql);
if ($id == 'NULL') {
$msg = "Das Element wurde erfolgreich angelegt.";
} else {
$msg = "Die Einstellungen wurden erfolgreich &uuml;bernommen.";
}
$this->produktion_position_edit_end($msg,false,true);
}
// Load values again from database
$result = $this->app->DB->SelectArr("SELECT SQL_CALC_FOUND_ROWS pp.id, pp.produktion, p.belegnr, pp.artikel, FORMAT(pp.menge,0) as menge, pp.id FROM produktion_position pp INNER JOIN produktion p ON pp.produktion = p.id "." WHERE pp.id=$id");
foreach ($result[0] as $key => $value) {
$this->app->Tpl->Set(strtoupper($key), $value);
}
/*
* Add displayed items later
*
$this->app->Tpl->Add('KURZUEBERSCHRIFT2', $email);
$this->app->Tpl->Add('EMAIL', $email);
$this->app->Tpl->Add('ANGEZEIGTERNAME', $angezeigtername);
*/
//$this->app->YUI->AutoComplete("artikel", "artikelnummer");
$this->app->YUI->AutoComplete("artikel", "lagerartikelnummer");
$this->app->Tpl->Set('ARTIKEL',$this->app->erp->ReplaceArtikel(false, $result[0]['artikel'], false)); // Convert from form to db
$this->app->Tpl->Set('PRODUKTIONID',$result[0]['produktion']);
$this->app->Tpl->Set('PRODUKTIONBELEGNR',$result[0]['belegnr']);
$this->app->Tpl->Add('MESSAGE',"<div class=\"info\">Positionsmenge muss Vielfaches von $planmenge sein.</div>");
$this->app->Tpl->Parse('PAGE', "produktion_position_edit.tpl");
}
/**
* Get all paramters from html form and save into $input
*/
public function GetInput(): array {
$input = array();
$input['artikel'] = $this->app->Secure->GetPOST('artikel');
$input['menge'] = $this->app->Secure->GetPOST('menge');
return($input);
}
}
File diff suppressed because it is too large Load Diff
+939
View File
@@ -0,0 +1,939 @@
<?php
/*
* Copyright (c) 2022 OpenXE project
*/
use Xentral\Components\Database\Exception\QueryFailureException;
use Xentral\Modules\Ticket\Task;
class Ticket {
function __construct($app, $intern = false) {
$this->app = $app;
if ($intern)
return;
$this->app->ActionHandlerInit($this);
$this->app->ActionHandler("list", "ticket_list");
$this->app->ActionHandler("create", "ticket_create"); // This automatically adds a "New" button
$this->app->ActionHandler("edit", "ticket_edit");
$this->app->ActionHandler("minidetail", "ticket_minidetail");
$this->app->ActionHandler("text", "ticket_text"); // Output text for iframe display
$this->app->ActionHandler("text_ausgang", "ticket_text_ausgang"); // Output text for iframe display
$this->app->ActionHandler("statusfix", "ticket_statusfix"); // Xentral 20 compatibility set all ticket status to latest ticket_nachricht status
$this->app->ActionHandler("datefix", "ticket_datefix"); // Xentral 20 compatibility set all ticket dates to latest ticket_nachricht date
$this->app->DefaultActionHandler("list");
$this->app->ActionHandlerListen($app);
}
public function Install() {
/* Fill out manually later */
}
function ticket_status_icon(string $status) {
return('<img src="./themes/new/images/status_'.$status.'.png" style="margin-right:1px" title="'.$status.'" border="0">');
}
public function TableSearch(&$app, $name, $erlaubtevars) {
function ticket_iconssql() {
return "CONCAT('<img src=\"./themes/new/images/status_',`t`.`status`,'.png\" style=\"margin-right:1px\" title=\"',`t`.`status`,'\" border=\"0\">')";
}
switch ($name) {
case "ticket_list":
$allowed['ticket_list'] = array('list');
$heading = array('','','Ticket #', 'Letzte Aktion', 'Adresse', 'Betreff', 'Tags', 'Verant.', 'Nachr.', 'Status', 'Alter', 'Projekt', 'Men&uuml;');
$width = array('1%','1%','5%', '5%', '5%', '30%', '1%', '5%', '1%', '1%', '1%', '1%', '1%');
$findcols = array('t.id','t.zeit','t.schluessel', 't.zeit', 'a.name', 't.betreff', 't.tags', 'w.warteschlange', 'nachrichten_anz', 't.status','t.zeit', 't.projekt');
$searchsql = array( 't.schluessel', 't.zeit', 'a.name', 't.betreff','t.notiz', 't.tags', 'w.warteschlange', 't.status', 't.projekt');
$defaultorder = 1;
$defaultorderdesc = 0;
$menu = "<table cellpadding=0 cellspacing=0><tr><td nowrap>" . "<a href=\"index.php?module=ticket&action=edit&id=%value%\"><img src=\"./themes/{$app->Conf->WFconf['defaulttheme']}/images/edit.svg\" border=\"0\"></a>" . "</td></tr></table>";
$timedifference = "if (
TIMESTAMPDIFF(hour, t.zeit, NOW()) < 24,
CONCAT(TIMESTAMPDIFF(hour, t.zeit, NOW()),'h'),
CONCAT(TIMESTAMPDIFF(day, t.zeit, NOW()), 'd ',MOD(TIMESTAMPDIFF(hour, t.zeit, NOW()),24),'h'))";
$dropnbox = "'<img src=./themes/new/images/details_open.png class=details>' AS `open`, CONCAT('<input type=\"checkbox\" name=\"auswahl[]\" value=\"',t.id,'\" />') AS `auswahl`";
$priobetreff = "if(t.prio!=1,t.betreff,CONCAT('<b><font color=red>',t.betreff,'</font></b>'))";
$anzahlnachrichten = "(SELECT COUNT(n.id) FROM ticket_nachricht n WHERE n.ticket = t.schluessel)";
$tagstart = "<li class=\"tag-editor-tag\">";
$tagend = "</li>";
$sql = "SELECT SQL_CALC_FOUND_ROWS
t.id,
".$dropnbox.",
CONCAT('<a href=\"index.php?module=ticket&action=edit&id=',t.id,'\">',t.schluessel,'</a>'),
t.zeit,
a.name,
CONCAT('<b>',".$priobetreff.",'</b><br/><i>',replace(substring(ifnull(t.notiz,''),1,500),'\n','<br/>'),'</i>'),
CONCAT('<div class=\"ticketoffene\"><ul class=\"tag-editor\">'\n,'".$tagstart."',replace(t.tags,',','".$tagend."<div class=\"tag-editor-spacer\">&nbsp;</div>".$tagstart."'),'".$tagend."','</ul></div>'),
w.warteschlange,
".$anzahlnachrichten." as nachrichten_anz,
".ticket_iconssql().",
".$timedifference.",
p.abkuerzung,
t.id
FROM ticket t
LEFT JOIN adresse a ON t.adresse = a.id
LEFT JOIN warteschlangen w ON t.warteschlange = w.label
LEFT JOIN projekt p on t.projekt = p.id";
$where = "1";
// Toggle filters
$this->app->Tpl->Add('JQUERYREADY', "$('#meinetickets').click( function() { fnFilterColumn1( 0 ); } );");
$this->app->Tpl->Add('JQUERYREADY', "$('#prio').click( function() { fnFilterColumn2( 0 ); } );");
$this->app->Tpl->Add('JQUERYREADY', "$('#geschlossene').click( function() { fnFilterColumn3( 0 ); } );");
$this->app->Tpl->Add('JQUERYREADY', "$('#spam').click( function() { fnFilterColumn4( 0 ); } );");
for ($r = 1;$r <= 4;$r++) {
$this->app->Tpl->Add('JAVASCRIPT', '
function fnFilterColumn' . $r . ' ( i )
{
if(oMoreData' . $r . $name . '==1)
oMoreData' . $r . $name . ' = 0;
else
oMoreData' . $r . $name . ' = 1;
$(\'#' . $name . '\').dataTable().fnFilter(
\'\',
i,
0,0
);
}
');
}
$more_data1 = $this->app->Secure->GetGET("more_data1");
if ($more_data1 == 1) {
$where .= " AND t.warteschlange IN (SELECT w.label FROM warteschlangen w WHERE adresse=".$this->app->User->GetAdresse().")"; // Queues of user
} else {
}
$more_data2 = $this->app->Secure->GetGET("more_data2");
if ($more_data2 == 1) {
$where .= " AND t.prio = '1'";
}
else {
}
$more_data3 = $this->app->Secure->GetGET("more_data3");
if ($more_data3 == 1) {
}
else {
$where .= " AND (t.status <> 'abgeschlossen')"; // Exclude and geschlossen
}
$more_data4 = $this->app->Secure->GetGET("more_data4");
if ($more_data4 == 1) {
}
else {
$where .= " AND (t.status <> 'spam')";
}
// END Toggle filters
$moreinfo = true; // Allow drop down details
$menucol = 12; // For moredata
$count = "SELECT count(DISTINCT id) FROM ticket t WHERE $where";
// echo(htmlentities($sql." ".$where));
// $groupby = "";
break;
}
$erg = false;
foreach ($erlaubtevars as $k => $v) {
if (isset($$v)) {
$erg[$v] = $$v;
}
}
return $erg;
}
function ticket_list() {
// Process multi action
$auswahl = $this->app->Secure->GetPOST('auswahl');
$selectedIds = [];
if(!empty($auswahl)) {
foreach($auswahl as $selectedId) {
$selectedId = (int)$selectedId;
if($selectedId > 0) {
$selectedIds[] = $selectedId;
}
}
$status = $this->app->Secure->GetPOST('status');
$warteschlange = $this->app->Secure->GetPOST('warteschlange');
$sql = "UPDATE ticket SET status = '".$status."', zeit = NOW()";
if ($warteschlange != '') {
$sql .= ", warteschlange = '".explode(" ",$warteschlange)[0]."'";
}
$sql .= " WHERE id IN (".implode(",",$selectedIds).")";
$this->app->DB->Update($sql);
}
// List
$this->app->YUI->TagEditor('taglist', array('width'=>370));
$this->app->Tpl->Add('SCRIPTJAVASCRIPT','<link rel="stylesheet" type="text/css" href="./css/jquery.tag-editor.css">');
$this->app->erp->MenuEintrag("index.php?module=ticket&action=list", "&Uuml;bersicht");
$this->app->erp->MenuEintrag("index.php?module=ticket&action=create", "Neu anlegen");
$this->app->erp->MenuEintrag("index.php", "Zur&uuml;ck");
$this->app->Tpl->Set('STATUS', $this->app->erp->GetStatusTicketSelect('neu'));
$this->app->YUI->AutoComplete("warteschlange","warteschlangename");
$this->app->YUI->TableSearch('TAB1', 'ticket_list', "show", "", "", basename(__FILE__), __CLASS__);
$this->app->Tpl->Parse('PAGE', "ticket_list.tpl");
}
function get_messages_of_ticket($ticket_id, $where, $limit) {
if ($limit) {
$limitsql = " LIMIT ".((int) $limit);
} else {
$limitsql = "";
}
if (empty($ticket_id)) {
$ticket_where = "";
} else {
$ticket_where = " AND t.id = ".$ticket_id;
}
if (empty($where)) {
$where = "1";
}
// $sql = "SELECT n.id, n.betreff, n.verfasser, n.mail, n.mail_cc, n.zeit, n.zeitausgang, n.versendet, n.text, n.verfasser_replyto, mail_replyto, (SELECT GROUP_CONCAT(value SEPARATOR ', ' FROM ticket_header th WHERE th.ticket_nachricht = n.id AND th.type = 'cc') value from) as cc FROM ticket_nachricht n INNER JOIN ticket t ON t.schluessel = n.ticket WHERE (".$where.") AND t.id = ".$ticket_id." ORDER BY n.zeit DESC ".$limitsql;
$sql = "SELECT n.id,
n.betreff,
n.bearbeiter,
n.verfasser,
n.mail,
t.quelle,
n.zeit,
n.zeitausgang,
n.versendet,
n.text,
n.textausgang,
n.verfasser_replyto,
n.mail_replyto,
n.mail_cc,
(SELECT GROUP_CONCAT(value SEPARATOR ', ') FROM ticket_header th WHERE th.ticket_nachricht = n.id AND th.type = 'cc') as mail_cc_recipients,
(SELECT GROUP_CONCAT(value SEPARATOR ', ') FROM ticket_header th WHERE th.ticket_nachricht = n.id AND th.type = 'to') as mail_recipients
FROM ticket_nachricht n INNER JOIN ticket t ON t.schluessel = n.ticket
WHERE (".$where.") ".$ticket_where." ORDER BY n.zeit DESC ".$limitsql;
return $this->app->DB->SelectArr($sql);
}
function add_attachments_html($ticket_id, $message_id,$templatepos,$showdelete) {
$file_attachments = $this->app->erp->GetDateiSubjektObjekt('Anhang','Ticket',$message_id);
if (!empty($file_attachments)) {
$this->app->Tpl->Add('NACHRICHT_ANHANG',"<hr style=\"border-style:solid; border-width:1px\">");
foreach ($file_attachments as $file_attachment) {
if ($showdelete) {
$deletetext = '<a href=index.php?module=ticket&action=edit&id='.$ticket_id.'&cmd=deleteattachment'.'&fileid='.$file_attachment.'>'.
'<img src="./themes/' . $this->app->Conf->WFconf['defaulttheme'] . '/images/delete.svg" /></a>';
} else {
$deletetext = "";
}
$attachtext = "";
/* Not implemented -> Attachment of ticket_nachricht to business object is the better option -> implement later
$attachtext = '<a href=index.php?module=dateien&action=edit&id='.$file_attachment.'>'.
'<img src="./themes/' . $this->app->Conf->WFconf['defaulttheme'] . '/images/copy.svg" /></a>'; */
$this->app->Tpl->Add($templatepos,
"<a href=\"index.php?module=dateien&action=send&id=".$file_attachment.
"\">".
htmlentities($this->app->erp->GetDateiName($file_attachment)).
" (".
$this->app->erp->GetDateiSize($file_attachment).
")".
"</a>".
$deletetext.
$attachtext.
"<br>");
}
}
}
function add_messages_tpl($messages, $showdrafts) {
// Add Messages now
foreach ($messages as $message) {
// Clear this first
$this->app->Tpl->Set('NACHRICHT_ANHANG',"");
// Xentral 20 compatibility
if ($message['textausgang'] != '') {
// Sent message
$this->app->Tpl->Set("NACHRICHT_BETREFF",'<a href="index.php?module=ticket&action=text_ausgang&mid='.$message['id'].'" target="_blank">'.htmlentities($message['betreff']).'</a>');
$this->app->Tpl->Set("NACHRICHT_ZEIT",$message['zeitausgang']);
$this->app->Tpl->Set("NACHRICHT_FLOAT","right");
$this->app->Tpl->Set("NACHRICHT_TEXT",$message['textausgang']);
$this->app->Tpl->Set("NACHRICHT_SENDER",htmlentities($message['bearbeiter']));
$this->app->Tpl->Set("NACHRICHT_RECIPIENTS",htmlentities($message['verfasser']." <".$message['mail'].">"));
// $this->app->Tpl->Set("NACHRICHT_TEXT",$message['textausgang']);
$this->app->Tpl->Set("NACHRICHT_TEXT",'<iframe class="ticket_text" src="index.php?module=ticket&action=text_ausgang&mid='.$message['id'].'"></iframe>');
$this->app->Tpl->Parse('MESSAGES', "ticket_nachricht.tpl");
}
if ($message['versendet'] == '1' && empty($message['textausgang'])) { // textausgang is always empty, except for old Xentral 20 tickets
// Sent message
if (is_null($message['zeitausgang'])) {
if (!$showdrafts) {
continue;
}
$this->app->Tpl->Set("NACHRICHT_BETREFF",htmlentities($message['betreff']." (Entwurf)"));
} else {
$this->app->Tpl->Set("NACHRICHT_BETREFF",htmlentities($message['betreff']));
}
$this->app->Tpl->Set("NACHRICHT_SENDER",htmlentities($message['verfasser']." <".$message['mail_replyto'].">"));
$this->app->Tpl->Set("NACHRICHT_RECIPIENTS",htmlentities($message['mail']));
$this->app->Tpl->Set("NACHRICHT_CC_RECIPIENTS",htmlentities($message['mail_cc']));
$this->app->Tpl->Set("NACHRICHT_FLOAT","right");
$this->app->Tpl->Set("NACHRICHT_ZEIT",$message['zeitausgang']);
$this->app->Tpl->Set("NACHRICHT_NAME",htmlentities($message['verfasser']));
} else {
// Received message
$this->app->Tpl->Set("NACHRICHT_SENDER",htmlentities($message['verfasser']." <".$message['mail'].">"));
if ($message['mail_recipients'] != '') {
$this->app->Tpl->Set("NACHRICHT_RECIPIENTS",htmlentities($message['mail_recipients']));
}
else {
// Xentral 20 compatibility
$this->app->Tpl->Set("NACHRICHT_RECIPIENTS",htmlentities($message['quelle']));
}
$this->app->Tpl->Set("NACHRICHT_CC_RECIPIENTS",htmlentities($message['mail_cc_recipients']));
$this->app->Tpl->Set("NACHRICHT_BETREFF",'<a href="index.php?module=ticket&action=text&mid='.$message['id'].'" target="_blank">'.htmlentities($message['betreff']).'</a>');
$this->app->Tpl->Set("NACHRICHT_FLOAT","left");
$this->app->Tpl->Set("NACHRICHT_ZEIT",$message['zeit']);
}
// $this->app->Tpl->Set("NACHRICHT_TEXT",$message['text']);
$this->app->Tpl->Set("NACHRICHT_TEXT",'<iframe class="ticket_text" src="index.php?module=ticket&action=text&mid='.$message['id'].'"></iframe>');
$this->add_attachments_html($id,$message['id'],'NACHRICHT_ANHANG',false);
$this->app->Tpl->Parse('MESSAGES', "ticket_nachricht.tpl");
}
}
function ticket_text() {
$mid = $this->app->Secure->GetGET('mid');
if (empty($mid)) {
return;
}
$messages = $this->get_messages_of_ticket("", "n.id = ".$mid, NULL);
if (empty($messages)) {
}
$this->app->Tpl->Set("TEXT",$messages[0]['text']);
$this->app->Tpl->Output('ticket_text.tpl');
$this->app->ExitXentral();
}
function ticket_text_ausgang() {
$mid = $this->app->Secure->GetGET('mid');
if (empty($mid)) {
return;
}
$messages = $this->get_messages_of_ticket("", "n.id = ".$mid, NULL);
if (empty($messages)) {
}
$this->app->Tpl->Set("TEXT",$messages[0]['textausgang']);
$this->app->Tpl->Output('ticket_text.tpl');
$this->app->ExitXentral();
}
/**
* @throws NumberGeneratorException
*
* @return string
*/
private function generateRandomTicketNumber(): string
{
$random = rand(300,700);
$loopCounter = 0;
while(true) {
$candidate = sprintf('%s%04d', date('Ymd'), $random++);
if (!$this->app->DB->Select('SELECT id FROM ticket WHERE schluessel = '.$candidate)) {
return($candidate);
}
if ($loopCounter > 99) {
throw new NumberGeneratorException('ticket number generation failed');
}
$loopCounter++;
}
}
function ticket_save_to_db($id, $input) {
// Write to database
// Add checks here
if (empty($id)) {
// New item
$id = 'NULL';
}
if ($input['betreff'] == '') {
$input['betreff'] = "...";
}
$input['projekt'] = $this->app->erp->ReplaceProjekt(true,$input['projekt'],true); // Parameters: Target db?, value, from form?
$input['adresse'] = $this->app->erp->ReplaceAdresse(true,$input['adresse'],true); // Parameters: Target db?, value, from form?
$input['warteschlange'] = explode(" ",$input['warteschlange'])[0]; // Just the label
$input['zeit'] = date('Y-m-d H:i:s', time());
$columns = "id, ";
$values = "$id, ";
$update = "";
$fix = "";
foreach ($input as $key => $value) {
if ($this->app->DB->ColumnExists('ticket',$key)) {
$columns = $columns.$fix.$key;
$values = $values.$fix."'".$value."'";
$update = $update.$fix.$key." = '$value'";
$fix = ", ";
}
}
$sql = "INSERT INTO ticket (".$columns.") VALUES (".$values.") ON DUPLICATE KEY UPDATE ".$update;
$this->app->DB->Update($sql);
$id = $this->app->DB->GetInsertID();
return($id);
}
function save_draft($id, $input) {
$columns = "id, ";
$values = "$id, ";
$update = "";
$fix = "";
// Translate form to table
$input['betreff'] = $input['email_betreff'];
$input['mail'] = $input['email_an'];
$input['mail_cc'] = $input['email_cc'];
$input['text'] = $input['email_text'];
foreach ($input as $key => $value) {
if ($this->app->DB->ColumnExists('ticket_nachricht',$key)) {
$columns = $columns.$fix.$key;
$values = $values.$fix."'".$value."'";
$update = $update.$fix.$key." = '$value'";
$fix = ", ";
}
}
$sql = "INSERT INTO ticket_nachricht (".$columns.") VALUES (".$values.") ON DUPLICATE KEY UPDATE ".$update;
$this->app->DB->Update($sql);
}
function ticket_create() {
$submit = $this->app->Secure->GetPOST('submit');
$input = $this->GetInput();
$projekt_id = $this->app->User->DefaultProjekt();
$projekt = $this->app->DB->Select("SELECT abkuerzung FROM projekt WHERE id = ".$projekt_id);
if ($submit != '') {
$input['schluessel'] = $this->generateRandomTicketNumber();
$input['kunde'] = $this->app->User->GetName();
$id = $this->ticket_save_to_db($id, $input);
header("Location: index.php?module=ticket&action=edit&id=$id");
exit();
}
$this->app->Tpl->Set('PROJEKT', $projekt);
$this->app->Tpl->Set('STATUSICON', $this->ticket_status_icon('neu')."&nbsp;");
$this->app->YUI->AutoComplete("adresse","adresse");
$this->app->YUI->AutoComplete("projekt","projektname",1);
$this->app->YUI->AutoComplete("status","ticketstatus",1);
$this->app->Tpl->Set('STATUS', $this->app->erp->GetStatusTicketSelect('neu'));
$this->app->YUI->AutoComplete("warteschlange","warteschlangename");
$this->app->Tpl->Parse('PAGE', "ticket_create.tpl");
}
function ticket_edit() {
$id = $this->app->Secure->GetGET('id');
if (empty($id)) {
return;
}
$this->app->Tpl->Set('ID', $id);
$this->app->erp->MenuEintrag("index.php?module=ticket&action=edit&id=$id", "Details");
$this->app->erp->MenuEintrag("index.php?module=ticket&action=list", "Zur&uuml;ck zur &Uuml;bersicht");
$id = $this->app->Secure->GetGET('id');
$cmd = $this->app->Secure->GetGET('cmd');
$input = $this->GetInput();
$submit = $this->app->Secure->GetPOST('submit');
$msg = $this->app->erp->base64_url_decode($this->app->Secure->GetGET('msg'));
if ($input['neue_notiz'] != '') {
$input['notiz'] = $this->app->User->GetName()." ".date("d.m.Y H:i").": ".$input['neue_notiz']."\r\n".$input['notiz'];
}
// Always save
if ($submit != '')
{
$this->ticket_save_to_db($id, $input);
$msg = "<div class=\"success\">Die Einstellungen wurden erfolgreich &uuml;bernommen.</div>";
}
// Load values again from database
$ticket_from_db = $this->app->DB->SelectArr("SELECT t.id, t.schluessel, t.zeit, p.abkuerzung as projekt, t.bearbeiter, t.quelle, t.status, t.prio, t.adresse, t.kunde, CONCAT(w.label,' ',w.warteschlange) as warteschlange, t.mailadresse, t.betreff, t.zugewiesen, t.inbearbeitung, t.inbearbeitung_user, t.firma, t.notiz, t.bitteantworten, t.service, t.kommentar, t.privat, t.dsgvo, t.tags, t.nachrichten_anz, t.id FROM ticket t LEFT JOIN adresse a ON t.adresse = a.id LEFT JOIN projekt p on t.projekt = p.id LEFT JOIN warteschlangen w on t.warteschlange = w.label WHERE t.id=$id")[0];
foreach ($ticket_from_db as $key => $value) {
$this->app->Tpl->Set(strtoupper($key), $value);
}
$this->app->Tpl->Set('PRIO', $ticket_from_db['prio']==1?"checked":"");
$this->app->Tpl->Set('STATUSICON', $this->ticket_status_icon($ticket_from_db['status'])."&nbsp;");
$this->app->YUI->AutoComplete("adresse","adresse");
$this->app->Tpl->Set('ADRESSE', $this->app->erp->ReplaceAdresse(false,$ticket_from_db['adresse'],false)); // Convert ID to form display
$this->app->Tpl->Set('ADRESSE_ID',$ticket_from_db['adresse']);
$this->app->YUI->AutoComplete("projekt","projektname",1);
$this->app->YUI->AutoComplete("status","ticketstatus",1);
$this->app->YUI->TagEditor('tags', array('width'=>370));
$this->app->Tpl->Set('STATUS', $this->app->erp->GetStatusTicketSelect($ticket_from_db['status']));
$input['projekt'] = $this->app->erp->ReplaceProjekt(false,$input['projekt'],false); // Parameters: Target db?, value, from form?
$this->app->YUI->AutoComplete("warteschlange","warteschlangename");
// END Header
// Check for draft
$drafted_messages = $this->get_messages_of_ticket($id, "zeitausgang IS NULL AND versendet = '1'",NULL);
if (!empty($drafted_messages)) {
// Draft from form?
if ($submit != '') {
$this->save_draft($drafted_messages[0]['id'],$input);
// Reload
$drafted_messages = $this->get_messages_of_ticket($id, "zeitausgang IS NULL AND versendet = '1'",NULL);
}
// Load the draft for editing
$this->app->Tpl->Set('EMAIL_AN', htmlentities($drafted_messages[0]['mail']));
$this->app->Tpl->Set('EMAIL_CC', htmlentities($drafted_messages[0]['mail_cc']));
$this->app->Tpl->Set('EMAIL_BCC', htmlentities($drafted_messages[0]['mail_bcc']));
$this->app->Tpl->Set('EMAIL_BETREFF', htmlentities($drafted_messages[0]['betreff']));
$this->app->Tpl->Set('EMAIL_TEXT',htmlentities($drafted_messages[0]['text']));
// Show new message dialog
$this->app->Tpl->Set('EMAIL_SENDER', $this->app->erp->GetSelectEmailMitName($dokument['von']));
$this->app->YUI->AutoComplete("email_an","emailname");
$this->app->YUI->AutoComplete("email_cc","emailname");
$this->app->YUI->AutoComplete("email_bcc","emailname");
$this->app->YUI->CkEditor("email_text","internal", null, 'JQUERY');
// Delete attachment from draft
if ($cmd=='deleteattachment') {
$fileid = $this->app->Secure->GetGET('fileid');
// Check if this file is only attached to this draft and nowhere else
$check = $this->app->erp->GetDateiStichwoerter($fileid);
$save_to_delete = true;
foreach ($check as $stichwort) {
if ($stichwort['subjekt'] != 'anhang' || $stichwort['objekt'] != 'Ticket' || $stichwort['parameter'] != $drafted_messages[0]['id']) {
$save_to_delete = false;
break;
}
}
if ($save_to_delete) {
$this->app->erp->DeleteDatei($fileid);
} else {
$msg .= "<div class=\"success\">Fehler beim Löschen der Datei: In Verwendung.</div>";
}
}
// Upload of attachments
if(isset($_FILES['upload']) && is_array($_FILES['upload']))
{
foreach($_FILES['upload']['tmp_name'] as $key => $file)
{
if($file != "")
{
$fileid = $this->app->erp->CreateDatei($_FILES['upload']['name'][$key], $_FILES['upload']['name'][$key], "", "", $_FILES['upload']['tmp_name'][$key], $this->app->User->GetName());
// stichwoerter hinzufuegen
$this->app->erp->AddDateiStichwort($fileid, "anhang", "Ticket", $drafted_messages[0]['id']);
}
}
}
$this->add_attachments_html($id,$drafted_messages[0]['id'],'ANHAENGE',true);
$this->app->Tpl->Parse('NEW_MESSAGE', "ticket_new_message.tpl");
}
// END Draft
// Get all messsages
$messages = $this->get_messages_of_ticket($id, 1, NULL);
$recv_messages = $this->get_messages_of_ticket($id,"n.versendet != 1",NULL);
switch ($submit) {
case 'neue_email':
if (empty($drafted_messages)) {
// Create new message and save it for editing
$this->app->Tpl->Set('EMAIL_AN', htmlentities($recv_messages[0]['mail']));
$senderName = $this->app->User->GetName()." (".$this->app->erp->GetFirmaAbsender().")";
$senderAddress = $this->app->erp->GetFirmaMail();
$to = "";
$cc = "";
if (!empty($recv_messages)) {
if (!str_starts_with(strtoupper($recv_messages[0]['betreff']),"RE:")) {
$betreff = "RE: ".$recv_messages[0]['betreff'];
}
else {
$betreff = $recv_messages[0]['betreff'];
}
$sql = "SELECT GROUP_CONCAT(DISTINCT `value` ORDER BY `value` SEPARATOR ', ') FROM ticket_header th WHERE th.ticket_nachricht = ".$recv_messages[0]['id']." AND `value` <> '".$senderAddress."' AND type='to'";
$to = $recv_messages[0]['mail'];
$to_additional = $this->app->DB->Select($sql);
if (!empty($to_additional)) {
$to .= ", ".$to_additional;
}
$sql = "SELECT GROUP_CONCAT(DISTINCT `value` ORDER BY `value` SEPARATOR ', ') FROM ticket_header th WHERE th.ticket_nachricht = ".$recv_messages[0]['id']." AND `value` <> '".$senderAddress."' AND type='cc'";
$cc = $this->app->DB->Select($sql);
}
else {
$betreff = $ticket_from_db['betreff'];
$sql = "SELECT email FROM adresse WHERE id =".$ticket_from_db['adresse'];
$to = $this->app->DB->Select($sql);
}
$anschreiben = $this->app->DB->Select("SELECT anschreiben FROM adresse WHERE id='".$ticket_from_db['adresse']."' LIMIT 1");
if($anschreiben=="")
{
$anschreiben = $this->app->erp->Beschriftung("dokument_anschreiben").",\n".$this->app->erp->Grussformel($projekt,$sprache);
}
$sql = "INSERT INTO `ticket_nachricht` (
`ticket`, `zeit`, `text`, `betreff`, `medium`, `versendet`,
`verfasser`, `mail`,`status`, `verfasser_replyto`, `mail_replyto`,`mail_cc`
) VALUES ('".$ticket_from_db['schluessel']."',NOW(),'".$anschreiben."','".$betreff."','email','1','".$senderName."','".$to."','neu','".$senderName."','".$senderAddress."','".$cc."');";
$this->app->DB->Insert($sql);
// Show new message dialog
header("Location: index.php?module=ticket&action=edit&id=$id");
$this->app->ExitXentral();
}
break;
case 'entwurfloeschen':
if (!empty($drafted_messages)) {
$sql = "UPDATE ticket_nachricht SET ticket = '' WHERE id=".$drafted_messages[0]['id'];
$this->app->DB->Update($sql);
$msg = $this->app->erp->base64_url_encode("<div class=\"success\">Der Entwurf wurde gel&ouml;scht.</div>");
header("Location: index.php?module=ticket&action=edit&msg=$msg&id=$id");
$this->app->ExitXentral();
}
break;
case 'zitat':
if (!empty($drafted_messages) && !empty($recv_messages)) {
$nl = "<br />";
$citation_info =$recv_messages[0]['zeit']." ".$recv_messages[0]['verfasser']." &lt;".$recv_messages[0]['mail']."&gt;";
$text = $drafted_messages[0]['text'].$nl.$nl.$citation_info.":".$nl."<blockquote type=\"cite\">".$recv_messages[0]['text']."</blockquote>";
$sql = "UPDATE ticket_nachricht SET text='".$text."' WHERE id=".$drafted_messages[0]['id'];
$this->app->DB->Update($sql);
header("Location: index.php?module=ticket&action=edit&id=$id");
$this->app->ExitXentral();
}
break;
case 'absenden':
if (empty($drafted_messages)) {
break;
}
$msg = "";
// Enforce Ticket #
if (!preg_match("/Ticket #[0-9]{12}/i", $drafted_messages[0]['betreff'])) {
$drafted_messages[0]['betreff'].= " Ticket #".$ticket_from_db['schluessel'];
}
// Attachments
$files = $this->app->erp->GetDateiSubjektObjektDateiname('Anhang','Ticket',$drafted_messages[0]['id'],"");
$pattern = '/[a-z0-9_\-\+\.]+@[a-z0-9\-]+\.([a-z]{2,4})(?:\.[a-z]{2})?/i';
preg_match_all($pattern, $drafted_messages[0]['mail'], $matches);
$to = $matches[0];
if ($drafted_messages[0]['mail_cc'] != '') {
$pattern = '/[a-z0-9_\-\+\.]+@[a-z0-9\-]+\.([a-z]{2,4})(?:\.[a-z]{2})?/i';
preg_match_all($pattern, $drafted_messages[0]['mail_cc'], $matches);
$cc = $matches[0];
} else {
$cc = null;
}
// function MailSend($from,$from_name,$to,$to_name,$betreff,$text,$files="",$projekt="",$signature=true,$cc="",$bcc="", $system = false)
if (
$this->app->erp->MailSend(
$drafted_messages[0]['mail_replyto'],
$drafted_messages[0]['verfasser_replyto'],
$to,
$to,
htmlentities($drafted_messages[0]['betreff']),
htmlentities($drafted_messages[0]['text']),
$files,
0,
true,
$cc,
'',
true
) != 0
) {
// Update message in ticket_nachricht
$sql = "UPDATE `ticket_nachricht` SET `zeitausgang` = NOW(), `betreff` = '".$drafted_messages[0]['betreff']."' WHERE id = ".$drafted_messages[0]['id'];
$this->app->DB->Insert($sql);
$msg .= '<div class="info">Die E-Mail wurde erfolgreich versendet an '.$input['email_an'].'.';
if ($drafted_messages[0]['mail_cc'] != '') {
$msg .= ' (CC: '.$drafted_messages[0]['mail_cc'].')</div>';
}
else {
$msg .= '</div>';
}
header("Location: index.php?module=ticket&action=edit&id=".$id."&msg=".$this->app->erp->base64_url_encode($msg));
}
else {
$msg = '<div class="error">Fehler beim Versenden der E-Mail: '.$this->app->erp->mail_error.'</div>';
}
// Get messsages again
$messages = $this->get_messages_of_ticket($id,1,NULL);
break;
}
$this->add_messages_tpl($messages, false);
$this->app->Tpl->Set('MESSAGE', $msg);
$this->app->Tpl->Parse('PAGE', "ticket_edit.tpl");
}
/**
* Get all paramters from html form and save into $input
*/
public function GetInput(): array {
$input = array();
//$input['EMAIL'] = $this->app->Secure->GetPOST('email');
$input['projekt'] = $this->app->Secure->GetPOST('projekt');
$input['status'] = $this->app->Secure->GetPOST('status');
$input['adresse'] = $this->app->Secure->GetPOST('adresse');
$input['warteschlange'] = $this->app->Secure->GetPOST('warteschlange');
$input['prio'] = !empty($this->app->Secure->GetPOST('prio'))?"1":"0";
$input['neue_notiz'] = $this->app->Secure->GetPOST('neue_notiz');
$input['notiz'] = $this->app->Secure->GetPOST('notiz');
$input['tags'] = $this->app->Secure->GetPOST('tags');
$input['betreff'] = $this->app->Secure->GetPOST('betreff');
$input['email_sender'] = $this->app->Secure->GetPOST('email_sender');
$input['email_an'] = $this->app->Secure->GetPOST('email_an');
$input['email_cc'] = $this->app->Secure->GetPOST('email_cc');
$input['email_bcc'] = $this->app->Secure->GetPOST('email_bcc');
$input['email_betreff'] = $this->app->Secure->GetPOST('email_betreff');
$input['email_text'] = $this->app->Secure->GetPOST('email_text');
return $input;
}
public function ticket_minidetail($parsetarget='',$menu=true) {
$id = $this->app->Secure->GetGET('id');
// Get last 3 messages
$messages = $this->get_messages_of_ticket($id, "1", 3);
if(!empty($messages)) {
$this->add_messages_tpl($messages, true); // With drafts
$render = true;
} else {
}
if($parsetarget=='')
{
if ($render) {
$this->app->Tpl->Output('ticket_minidetail.tpl');
}
$this->app->ExitXentral();
}
if ($render) {
$this->app->Tpl->Parse($parsetarget,'ticket_minidetail.tpl');
}
}
/*
* After import of Xentral 20 ticket system
* Set all ticket status to the status of the latest ticket_nachricht
*/
function ticket_statusfix() {
$confirmed = $this->app->Secure->GetGET('confirmed');
if ($confirmed == "yes") {
$sql = "UPDATE
ticket
SET
STATUS
=ifnull((
SELECT
tn.status
FROM
ticket_nachricht tn
INNER JOIN(
SELECT
ticket,
MAX(zeit) AS lastzeit
FROM
ticket_nachricht
GROUP BY
ticket
) l
ON
tn.ticket = l.ticket AND tn.zeit = l.lastzeit
WHERE
ticket.schluessel = tn.ticket
LIMIT 1
),'abgeschlossen')
WHERE ticket.status = 'neu'";
$this->app->DB->Update($sql);
$this->app->Tpl->Set('TEXT', "Status fix abgeschlossen.");
$this->app->Tpl->Parse('PAGE','ticket_text.tpl');
}
else {
// $this->app->Tpl->Set('TEXT', "This will replace all ticket status with the status of the latest ticket_nachricht. To confirm, press here: ");
$this->app->Tpl->Set('TEXT', "Dieser Assistent ersetzt den Status aller offenen Tickets (Weder abgeschlossen noch Spam) mit dem Status der letzten Nachricht im Ticket. Hier starten: ");
$this->app->Tpl->Add('TEXT', '<a href="index.php?module=ticket&action=statusfix&confirmed=yes"><button>OK</button></a>');
$this->app->Tpl->Parse('PAGE','ticket_text.tpl');
}
}
/*
* After import of Xentral 20 ticket system
* Set all ticket dates to the date of the latest ticket_nachricht
*/
function ticket_datefix() {
$confirmed = $this->app->Secure->GetGET('confirmed');
if ($confirmed == "yes") {
$sql = "UPDATE ticket set zeit =
(SELECT
MAX(zeit) AS lastzeit
FROM
ticket_nachricht
WHERE ticket.schluessel = ticket_nachricht.ticket AND ticket.schluessel
LIMIT 1
)
WHERE ticket.status <> 'abgeschlossen' AND ticket.status <> 'spam'";
$this->app->DB->Update($sql);
$this->app->Tpl->Set('TEXT', "Datum fix abgeschlossen.");
$this->app->Tpl->Parse('PAGE','ticket_text.tpl');
}
else {
// $this->app->Tpl->Set('TEXT', "This will replace all open ticket dates with the date of the latest ticket_nachricht. To confirm, press here: ");
$this->app->Tpl->Set('TEXT', "Dieser Assistent ersetzt das Datum aller offenen Tickets (Weder abgeschlossen noch Spam) mit dem Datum der letzten Nachricht im Ticket. Hier starten: ");
$this->app->Tpl->Add('TEXT', '<a href="index.php?module=ticket&action=datefix&confirmed=yes"><button>OK</button></a>');
$this->app->Tpl->Parse('PAGE','ticket_text.tpl');
}
}
}

Some files were not shown because too many files have changed in this diff Show More