Compare commits

...

296 Commits

Author SHA1 Message Date
Martin Edenhofer
cd5e64f7db Updated gems regarding CVE-2018-8048 and CVE-2018-3741. 2018-03-28 23:46:31 +02:00
Martin Edenhofer
1a9af7dbe6 Updated for 2.2.2. 2018-03-28 23:36:30 +02:00
Martin Edenhofer
de51dedcbd Updated nokogiri to verion 1.8.2. 2018-02-13 17:21:20 +01:00
Martin Edenhofer
f99f30e61e Fixed issue #1829 - The column widths of a table are shifted after manual change and use of pagination. 2018-02-13 17:20:55 +01:00
Thorsten Eckel
428136120f Fixed bug: OTRS import - User queue/group permissions are not transfered. 2018-02-12 08:54:00 +01:00
Thorsten Eckel
4ceeffcc4c Fixed bug: OTRS import fails for Roles without users assigned. 2018-02-12 08:53:54 +01:00
Muhammad Nuzaihan
fe3a739a58 #1674 make sure login data is downcased. included tests to check as well 2018-02-12 08:53:42 +01:00
Martin Edenhofer
5c983f69e8 Version 2.2.1. 2018-01-30 00:50:23 +01:00
Muhammad Nuzaihan
dfa8f805cb fixes #1756 with security issue of content injection in excel generated data 2018-01-22 23:18:13 +08:00
Muhammad Nuzaihan
db19f30961 Fixes issue #1752 #1742 with object manager 2018-01-17 22:45:21 +08:00
Thorsten Eckel
80341b90f9 Fixed issue #1753 - Ticket search fails for limit exceeding 100 with internal server error. 2018-01-16 17:14:20 +01:00
Martin Edenhofer
5604e5fe8c Added support to ignore system id for follow up checks. 2018-01-16 07:42:05 +01:00
Martin Edenhofer
fc499909ce Fixed issue #1749 - Unable to send auto reply if from contains 2 or more senders with invalid email address. 2018-01-15 16:33:36 +01:00
Thorsten Eckel
1c2ff2a514 Removed debugging file. 2018-01-15 15:24:49 +01:00
Thorsten Eckel
0e8203fff4 Follow up: Fixed issue #1741 - Do not show merged issues in reports. 2018-01-15 15:24:16 +01:00
Muhammad Nuzaihan
d2d6945a8f Fixed issue #1741 - Do not show merged issues in reports. 2018-01-15 14:12:40 +01:00
Martin Edenhofer
dbad0f53cb Improved error handling of email processing with invalid email addresses. 2017-12-20 17:15:53 +01:00
Martin Edenhofer
b7e9b97a13 Fixed issue #1723 - Wrong ticket number count in preview. 2017-12-20 10:56:09 +01:00
Felix Niklas
c44ebc166a Chat: fix open/close icon and status alignment 2017-12-17 10:35:53 +01:00
Martin Edenhofer
47a1bb76a6 Fixed issue #1711 - Zammad Api for idoit.object_ids broken. 2017-12-14 08:37:29 +01:00
Martin Edenhofer
db6eadce9f Fixed issue #1710 - Unable to login with Office365. 2017-12-13 19:45:42 +01:00
Martin Edenhofer
535ce06efd Improved max. agent limit check. 2017-12-13 12:18:21 +01:00
Martin Edenhofer
8d79744bc5 Fixed usage to twitter initials setting. 2017-12-12 10:16:09 +01:00
André Bauer
7884d86480 added database & elasticsearch fields to github issue template 2017-12-09 11:05:20 +01:00
André Bauer
2036235d55 Merge branch 'stable' of git.znuny.com:zammad/zammad into stable 2017-12-07 17:58:59 +01:00
André Bauer
8200862127 added executable bit to travis bash script 2017-12-07 17:58:53 +01:00
Martin Edenhofer
0736061008 Fixed issue #1699 - No user preference for out-of-office available. 2017-12-07 16:43:49 +01:00
André Bauer
626911e52c added univention docker image build trigger for travis-ci 2017-12-07 16:21:22 +01:00
Martin Edenhofer
0bac6f5e5f Improved config input validation for issue #1698 - SipgateController - undefined method `each' for nil:NilClass (NoMethodError). 2017-12-07 15:35:40 +01:00
Martin Edenhofer
cc5a34df97 Improved wording. 2017-12-07 09:50:11 +01:00
Martin Edenhofer
7209b85c16 Updated CHANGES, 2017-12-06 17:08:41 +01:00
Martin Edenhofer
66c0975877 Merge branch 'develop' 2017-12-06 16:51:16 +01:00
Martin Edenhofer
76efb008a8 Merge branch 'develop' 2017-12-06 15:39:41 +01:00
Martin Edenhofer
abc0541244 Merge branch 'develop' 2017-12-06 09:56:14 +01:00
Martin Edenhofer
c9f8022f83 Merge branch 'develop' 2017-11-30 11:33:56 +01:00
Martin Edenhofer
dfc757968e Merge branch 'develop' 2017-11-30 09:32:27 +01:00
Martin Edenhofer
52bc45c0f8 Merge branch 'develop' 2017-11-20 12:03:21 +01:00
Martin Edenhofer
cbc8ba5467 Merge branch 'develop' 2017-11-14 23:03:43 +01:00
Martin Edenhofer
5f071e7d7f Merge branch 'develop' 2017-11-07 08:19:41 +01:00
Martin Edenhofer
1dcd6a243c Merge branch 'develop' 2017-11-06 03:03:07 +01:00
Martin Edenhofer
679deb1cf3 Merge branch 'develop' 2017-11-03 08:14:33 +01:00
Martin Edenhofer
6f6ac44978 Merge branch 'develop' 2017-10-30 13:35:44 +01:00
Martin Edenhofer
0bb341cb7e Merge branch 'develop' 2017-10-25 14:05:59 +02:00
Martin Edenhofer
6c122e046b Merge branch 'develop' 2017-10-25 10:15:04 +02:00
Martin Edenhofer
57c2dad0a3 Merge branch 'develop' 2017-10-23 03:19:56 +02:00
Martin Edenhofer
faefd529b4 Merge branch 'develop' 2017-10-09 02:27:20 +02:00
Martin Edenhofer
1481a12035 Merge branch 'develop' 2017-10-09 01:37:42 +02:00
Martin Edenhofer
2bf0635e0d Merge branch 'develop' 2017-09-27 11:02:30 +02:00
Martin Edenhofer
2211274bc5 Merge branch 'develop' 2017-09-12 16:39:39 +02:00
Martin Edenhofer
c229c42838 Merge branch 'develop' 2017-09-11 06:45:49 +02:00
Martin Edenhofer
a3c71f6558 Merge branch 'develop' 2017-09-10 19:43:13 +02:00
Thorsten Eckel
db8b85f767 Merge branch 'develop' 2017-09-06 15:01:15 +02:00
Martin Edenhofer
f1664c3841 Merge branch 'develop' 2017-09-05 21:54:52 +02:00
Martin Edenhofer
151c298056 Merge branch 'develop' 2017-08-31 09:05:09 +02:00
Martin Edenhofer
38f51ce6b2 Merge branch 'develop' 2017-08-28 11:44:51 +02:00
Martin Edenhofer
434f3e963e Merge branch 'develop' 2017-08-25 05:38:22 +02:00
Martin Edenhofer
b853dd1597 Merge branch 'develop' 2017-08-24 01:00:34 +02:00
Martin Edenhofer
3b5b6f612f Merge branch 'develop' 2017-08-23 17:16:20 +02:00
Martin Edenhofer
962043c520 Merge branch 'develop' 2017-08-22 14:58:32 +02:00
Martin Edenhofer
8394be87ed Merge branch 'develop' 2017-08-14 11:32:42 +02:00
Martin Edenhofer
5b547ceb3c Merge branch 'develop' 2017-08-13 11:55:41 +02:00
Martin Edenhofer
789ee08485 Merge branch 'develop' 2017-08-11 12:08:58 +02:00
Martin Edenhofer
490937859a Merge branch 'develop' 2017-07-29 13:03:58 +02:00
Martin Edenhofer
dfc306a2ac Merge branch 'develop' 2017-07-28 13:57:37 +02:00
Martin Edenhofer
dea06015a1 Merge branch 'develop' 2017-07-28 11:48:50 +02:00
Martin Edenhofer
2711e3392d Merge branch 'develop' 2017-07-27 06:38:29 +02:00
Martin Edenhofer
f5e1fe0c2f Merge branch 'develop' 2017-07-24 15:26:00 +02:00
Martin Edenhofer
dbbb4ac7a1 Merge branch 'develop' 2017-07-21 15:09:34 +02:00
Martin Edenhofer
8ec2ffdde1 Merge branch 'develop' 2017-07-20 17:22:54 +02:00
Martin Edenhofer
b76664e7ae Merge branch 'develop' 2017-07-20 15:58:47 +02:00
Martin Edenhofer
704c537749 Merge branch 'develop' 2017-07-20 15:00:37 +02:00
Martin Edenhofer
633c99bb72 Merge branch 'develop' 2017-07-19 11:07:56 +02:00
Martin Edenhofer
44051d8023 Merge branch 'develop' 2017-07-16 18:15:24 +02:00
Martin Edenhofer
50dc143c1b Merge branch 'develop' 2017-07-14 15:58:16 +02:00
Martin Edenhofer
6d44275869 Merge branch 'develop' 2017-07-13 20:53:59 +02:00
Martin Edenhofer
b1b3bf6d3c Merge branch 'develop' 2017-07-12 13:30:01 +02:00
Martin Edenhofer
77081ecd4d Merge branch 'develop' 2017-07-04 16:05:04 +02:00
Martin Edenhofer
b823b960d8 Merge branch 'develop' 2017-06-30 08:32:40 +02:00
Martin Edenhofer
e08f634125 Merge branch 'develop' 2017-06-21 09:10:41 +02:00
Martin Edenhofer
ab5e8d9338 Merge branch 'develop' 2017-06-19 20:01:15 +02:00
Martin Edenhofer
9a29ea8f14 Merge branch 'develop' 2017-06-13 02:40:32 +02:00
Martin Edenhofer
cf87e00b21 Merge branch 'develop' 2017-06-13 01:57:29 +02:00
Martin Edenhofer
6233b0a9ec Merge branch 'develop' 2017-06-01 18:32:42 +02:00
Martin Edenhofer
04b1bc638c Merge branch 'develop' 2017-05-29 06:57:52 +02:00
Martin Edenhofer
a78938f7c2 Merge branch 'develop' 2017-05-23 11:05:51 +02:00
Martin Edenhofer
1d23308454 Merge branch 'develop' 2017-05-23 10:30:03 +02:00
Martin Edenhofer
6bc9c00ab8 Merge branch 'develop' 2017-05-16 15:41:06 +02:00
Martin Edenhofer
bc131742be Merge branch 'develop' 2017-05-16 14:22:22 +02:00
Martin Edenhofer
5a12aa0167 Merge branch 'develop' 2017-05-16 01:47:49 +02:00
Martin Edenhofer
b3ab9d0055 Merge branch 'develop' 2017-05-16 00:57:14 +02:00
Martin Edenhofer
1bde8f91bc Merge branch 'develop' 2017-05-15 15:31:15 +02:00
Martin Edenhofer
47ef1b7e5d Merge branch 'develop' 2017-05-11 23:54:32 +02:00
Martin Edenhofer
88c7816f5c Merge branch 'develop' 2017-05-08 17:09:55 +02:00
Martin Edenhofer
82339c6c18 Merge branch 'develop' 2017-05-08 16:56:10 +02:00
Martin Edenhofer
04a609c3a8 Merge branch 'develop' 2017-05-05 15:23:04 +02:00
Martin Edenhofer
60430139aa Merge branch 'develop' 2017-05-02 10:45:06 +02:00
Martin Edenhofer
7d1c655ee3 Merge branch 'develop' 2017-04-28 16:50:31 +02:00
Martin Edenhofer
e34c1c9b79 Merge branch 'develop' 2017-04-28 12:48:40 +02:00
Thorsten Eckel
3c430b35ef Fixed issue #906 - Doorkeeper tokens should be refreshable but aren't. 2017-04-24 13:58:03 +02:00
Rolf Schmidt
7ad3c70311 Fixed issue #975 - Exception in OTRS Import. 2017-04-24 11:58:07 +02:00
Martin Edenhofer
c270bc1e67 Merge branch 'develop' 2017-04-21 14:36:50 +02:00
Thorsten Eckel
3d19bfdcf7 Fixed issue #912 - Long Twitter direct messages are shown as link after 140 chars. 2017-04-21 13:58:33 +02:00
Martin Edenhofer
dc4a55cc5c Merge branch 'develop' 2017-04-21 12:38:25 +02:00
Martin Edenhofer
6e8886277d Merge branch 'develop' 2017-04-21 06:17:09 +02:00
Martin Edenhofer
74e96e92b2 Merge branch 'develop' 2017-04-20 00:22:13 +02:00
Martin Edenhofer
287b1f0d01 Merge branch 'develop' 2017-04-18 09:57:19 +02:00
Martin Edenhofer
feee46e29b Merge branch 'develop' 2017-04-08 08:32:45 +02:00
Martin Edenhofer
991efe36e4 Merge branch 'develop' 2017-04-05 22:23:05 +02:00
Martin Edenhofer
a2aacb20fa Merge branch 'develop' 2017-03-31 16:20:21 +02:00
Martin Edenhofer
592e978062 Merge branch 'develop' 2017-03-31 14:01:20 +02:00
Martin Edenhofer
a4769c8bc7 Merge branch 'develop' 2017-03-27 14:49:54 +02:00
Martin Edenhofer
d1378d53f1 Merge branch 'develop' 2017-03-25 14:44:10 +01:00
Martin Edenhofer
f0b91d3269 Merge branch 'develop' 2017-03-23 21:10:03 +01:00
Martin Edenhofer
48c77dd688 Merge branch 'develop' 2017-03-21 16:06:51 +01:00
Martin Edenhofer
d86d904395 Merge branch 'develop' 2017-03-21 10:05:58 +01:00
Martin Edenhofer
5efc455f0c Merge branch 'develop' 2017-03-18 23:16:57 +01:00
Martin Edenhofer
be3bbeba20 Merged develop into master. 2017-03-18 13:45:42 +01:00
Martin Edenhofer
31ab1b614c Merge branch 'develop' 2017-03-17 08:09:20 +01:00
Martin Edenhofer
4bc5fa4693 Merge branch 'develop' 2017-03-14 19:24:36 +01:00
Martin Edenhofer
418a64f401 Merge branch 'develop' 2017-03-14 13:33:37 +01:00
Martin Edenhofer
abe46270a6 Merge branch 'develop' 2017-03-03 10:54:22 +01:00
Martin Edenhofer
1249a77150 Merge branch 'develop' 2017-03-03 09:46:01 +01:00
Martin Edenhofer
cfa6b9ed16 Merge branch 'develop' 2017-02-24 23:19:06 +01:00
Rolf Schmidt
aa2303f999 Merge branch 'develop' 2017-02-24 09:27:43 +01:00
Martin Edenhofer
d5616684f8 Merge branch 'develop' 2017-02-22 07:12:36 +01:00
Martin Edenhofer
0f75ba57bd Merge branch 'develop' 2017-02-15 17:42:20 +01:00
Martin Edenhofer
c83675bbba Merge branch 'develop' 2017-02-15 13:39:29 +01:00
Martin Edenhofer
17d16d405c Merge branch 'develop' 2017-02-06 11:48:59 +01:00
Martin Edenhofer
76795ca302 Merge branch 'develop' 2017-02-06 00:16:24 +01:00
Martin Edenhofer
5d145bd09f Merge branch 'develop' 2017-02-05 19:26:16 +01:00
Martin Edenhofer
82471552a8 Merge branch 'develop' 2017-02-01 23:24:18 +01:00
Rolf Schmidt
dc60574129 Merge branch 'develop' 2017-01-23 15:05:52 +01:00
Martin Edenhofer
d33a96dee2 Merge branch 'develop' 2017-01-19 06:18:19 +01:00
Martin Edenhofer
0098d4ab82 Merge branch 'develop' 2017-01-17 15:57:42 +01:00
Martin Edenhofer
bb03b5eab8 Merge branch 'develop' 2017-01-17 12:41:03 +01:00
Martin Edenhofer
17eb0f84ec Merge branch 'develop' 2017-01-17 08:56:18 +01:00
Martin Edenhofer
56d0523c1f Merge branch 'develop' 2017-01-04 15:21:24 +01:00
Martin Edenhofer
9fa18758bc Merge branch 'develop' 2016-12-21 14:12:06 +01:00
Martin Edenhofer
d2f2c55b06 Merge branch 'develop' 2016-12-21 08:50:52 +01:00
Martin Edenhofer
f4a409bd6e Merge branch 'develop' 2016-12-21 00:13:59 +01:00
Martin Edenhofer
971b724d4c Merge branch 'develop' 2016-12-18 12:45:13 +01:00
Martin Edenhofer
3263c6f2ba Merge branch 'develop' 2016-12-16 15:49:33 +01:00
Martin Edenhofer
359b026535 Merge branch 'develop' 2016-12-15 17:16:38 +01:00
Martin Edenhofer
c63518fd3e Merge branch 'develop' 2016-12-14 16:06:09 +01:00
Martin Edenhofer
24ba3cff44 Merge branch 'develop' 2016-12-06 13:29:23 +01:00
Martin Edenhofer
f7066e1995 Merge branch 'develop' 2016-12-06 12:23:13 +01:00
Martin Edenhofer
6844499309 Merge branch 'develop' 2016-11-25 16:59:16 +01:00
Martin Edenhofer
afa3e47eab Merge branch 'develop' 2016-11-25 14:22:00 +01:00
Martin Edenhofer
5f3e9298f1 Merge branch 'develop' 2016-11-24 16:03:45 +01:00
Martin Edenhofer
e4dd303357 Merge branch 'develop' 2016-11-21 17:07:30 +01:00
Martin Edenhofer
2fa06eee3d Merge branch 'develop' 2016-11-21 08:58:54 +01:00
Martin Edenhofer
dc0ac03334 Merge branch 'develop' 2016-11-19 16:42:10 +01:00
Martin Edenhofer
c5a1d69ec5 Merge branch 'develop' 2016-11-19 16:35:07 +01:00
Martin Edenhofer
9891981f92 Merge branch 'develop' 2016-11-17 15:12:22 +01:00
Martin Edenhofer
2c721f71e7 Merge branch 'develop' 2016-11-17 10:03:34 +01:00
Martin Edenhofer
0b4a4be0b7 Merge branch 'develop' 2016-11-16 23:21:05 +01:00
Martin Edenhofer
b13bb2fcaf Added change log. 2016-11-14 08:37:51 +01:00
Martin Edenhofer
d9ba369fcf Merge branch 'develop' 2016-11-14 08:36:58 +01:00
Martin Edenhofer
3adece0db5 Merge branch 'develop' 2016-11-14 00:03:57 +01:00
Martin Edenhofer
7101ffc277 Merge branch 'develop' 2016-11-12 16:44:43 +01:00
Martin Edenhofer
19a7a439b8 Merge branch 'develop' 2016-11-11 19:29:56 +01:00
Martin Edenhofer
e728320241 Merge branch 'develop' 2016-10-30 07:08:08 +01:00
Martin Edenhofer
1bc17afc53 Merge branch 'master' of git.znuny.com:zammad/zammad 2016-10-30 07:07:39 +01:00
Thorsten Eckel
ee5c58f53a Fixed bug: Zip archive doesn't contain sub folder content. 2016-10-19 08:25:51 +02:00
Martin Edenhofer
9bdf6d7b81 Merge branch 'develop' 2016-10-19 07:50:08 +02:00
Thorsten Eckel
5754fdccdd Working on CI tag/branch pushing, syncing, deployment issue. 2016-10-19 07:32:05 +02:00
Thorsten Eckel
4901050d57 Working on issue not syncing to github correctly. 2016-10-19 07:25:18 +02:00
Martin Edenhofer
7980c8cb93 Merge branch 'develop' 2016-10-19 07:21:10 +02:00
Martin Edenhofer
7e7088388d Merge branch 'develop' 2016-10-17 16:43:54 +02:00
Martin Edenhofer
2f6e52d63d Merge branch 'develop' 2016-09-28 16:08:28 +02:00
Martin Edenhofer
bde8babb43 Merge branch 'develop' 2016-09-28 08:53:02 +02:00
Martin Edenhofer
d6d68fb363 Merge branch 'develop' 2016-09-19 07:47:06 +02:00
Martin Edenhofer
814ffed0f0 Merge branch 'develop' 2016-09-15 22:11:57 +02:00
Thorsten Eckel
b013fb8cbc Merge branch 'private-otrs_import_df' 2016-09-13 12:06:56 +02:00
Martin Edenhofer
fbd8e63592 Merge branch 'develop' 2016-09-13 08:55:38 +02:00
Martin Edenhofer
e8ad3965d7 Removed build badged. 2016-09-10 16:47:33 +02:00
Martin Edenhofer
e00981ee23 Merge branch 'master' of git.znuny.com:zammad/zammad 2016-09-10 00:05:18 +02:00
Martin Edenhofer
4e74c6beda Merge branch 'develop' 2016-09-10 00:04:28 +02:00
Thorsten Eckel
2d09e556d7 Added deployment of archives. 2016-09-07 15:31:28 +02:00
Martin Edenhofer
8cd39398d6 Merge branch 'develop' 2016-09-06 16:07:33 +02:00
Martin Edenhofer
94c616ffe3 Merge branch 'develop' 2016-08-25 10:00:36 +02:00
Martin Edenhofer
57649bb888 Merge branch 'develop' 2016-08-23 09:49:40 +02:00
Martin Edenhofer
7e9442ec4a Merge branch 'develop' 2016-08-21 21:38:00 +02:00
Martin Edenhofer
521e6265fd Merge branch 'develop' 2016-08-19 13:58:26 +02:00
Martin Edenhofer
a42a9689fc Merge branch 'develop' 2016-08-19 13:48:46 +02:00
Martin Edenhofer
d9ffb8001d Merge branch 'develop' 2016-07-28 13:39:08 +02:00
Martin Edenhofer
ec86d26ae6 Merge branch 'develop' 2016-07-24 23:52:04 +02:00
Martin Edenhofer
e00efc821a Merge branch 'develop' 2016-07-18 19:35:51 +02:00
Martin Edenhofer
f04be8ca93 Merge branch 'develop' 2016-07-12 20:50:32 +02:00
Martin Edenhofer
c7ff6a323a Merge branch 'develop' 2016-07-08 11:28:43 +02:00
Martin Edenhofer
34833416bc Merge branch 'develop' 2016-06-30 09:50:09 +02:00
Martin Edenhofer
d7a6e28d81 Merge branch 'develop' 2016-06-29 00:18:44 +02:00
Martin Edenhofer
c13531d720 Merge branch 'develop' 2016-06-27 11:28:22 +02:00
Martin Edenhofer
4a40cced7d Merge branch 'develop' 2016-06-26 08:07:04 +02:00
Martin Edenhofer
450de10cc7 Merge branch 'develop' 2016-06-23 08:24:56 +02:00
Martin Edenhofer
5e587a455c Merge branch 'develop' 2016-06-22 08:54:24 +02:00
Martin Edenhofer
04aef9b258 Merge branch 'develop' 2016-06-20 15:52:43 +02:00
Martin Edenhofer
9b72557d13 Merge branch 'develop' 2016-06-15 06:58:36 +02:00
Martin Edenhofer
a5e0bc30c1 Merge branch 'develop' 2016-06-09 13:40:27 +02:00
Martin Edenhofer
458c166e9f Merge branch 'develop' 2016-06-08 16:43:29 +02:00
Martin Edenhofer
3373e5d141 Merge branch 'develop' 2016-06-08 10:48:12 +02:00
Martin Edenhofer
8f6b8de617 Merge branch 'develop' 2016-06-08 07:42:19 +02:00
Martin Edenhofer
22b21a82e7 Merge branch 'develop' 2016-06-07 07:02:25 +02:00
Martin Edenhofer
b4151b299f Merge branch 'develop' 2016-06-04 02:23:14 +02:00
Martin Edenhofer
e969fca8c4 Merge branch 'develop' 2016-06-03 07:08:59 +02:00
Martin Edenhofer
e59993a5d6 Merge branch 'develop' 2016-05-31 08:31:56 +02:00
Martin Edenhofer
3adc9d4cf1 Merge branch 'develop' 2016-05-30 13:21:46 +02:00
Martin Edenhofer
c1153250cb Merge branch 'develop' 2016-05-30 00:00:52 +02:00
Martin Edenhofer
7718dc28d3 Merge branch 'develop'
# Conflicts:
#	README.md
2016-05-27 17:30:22 +02:00
Martin Edenhofer
1894580ae6 Updated badge url. 2016-05-27 17:28:26 +02:00
Martin Edenhofer
11df714bbf Merge branch 'develop' 2016-05-20 15:18:36 +02:00
Martin Edenhofer
72adee37a8 Merge branch 'develop' 2016-05-20 06:10:19 +02:00
Martin Edenhofer
0e8f460d73 Merge branch 'develop' 2016-05-06 16:25:09 +02:00
Martin Edenhofer
4e62d5d0d2 Merge branch 'develop' 2016-05-06 09:40:16 +02:00
Martin Edenhofer
004e5ba457 Merge branch 'develop' 2016-05-04 12:13:34 +02:00
Martin Edenhofer
f1a8a8da6f Merge branch 'develop' 2016-05-03 16:01:03 +02:00
Martin Edenhofer
bfb44d1189 Merge branch 'develop' 2016-05-01 14:18:26 +02:00
Martin Edenhofer
d64afd8d97 Merge branch 'develop' 2016-04-14 17:47:03 +02:00
Martin Edenhofer
97cfdb9c4c Merge branch 'develop' 2016-04-12 08:25:06 +02:00
Martin Edenhofer
bb336f63f1 Merge branch 'develop' 2016-03-25 18:23:12 +01:00
Martin Edenhofer
80da08f447 Merge branch 'develop' 2016-03-23 09:31:02 +01:00
Martin Edenhofer
a6db2b7c90 Merge branch 'develop' 2016-03-17 17:45:04 +01:00
Martin Edenhofer
e1c3f83324 Merge branch 'develop' 2016-03-17 10:41:20 +01:00
Martin Edenhofer
8545a44ad1 Merge branch 'develop' 2016-03-16 11:17:22 +01:00
Martin Edenhofer
cfbe7510a2 Merge branch 'develop' 2016-03-16 09:10:05 +01:00
Martin Edenhofer
1479c32edb Merge branch 'develop' 2016-03-15 00:34:36 +01:00
Martin Edenhofer
a9d428bf5a Merge branch 'develop' 2016-03-11 10:38:15 +01:00
Martin Edenhofer
3a62eb11da Merge branch 'develop' 2016-03-04 07:07:55 +01:00
Martin Edenhofer
2df5f81029 Merge branch 'develop' 2016-03-03 03:42:27 +01:00
Martin Edenhofer
b88c23bc92 Merge branch 'develop' 2016-02-28 00:16:49 +01:00
Martin Edenhofer
4144fbaf5b Merge branch 'develop' 2016-02-25 23:46:10 +01:00
Martin Edenhofer
86ddc93f52 Merge branch 'develop' 2016-02-23 14:29:01 +01:00
Martin Edenhofer
8a1b583535 Merge branch 'develop' 2016-02-23 01:38:39 +01:00
Martin Edenhofer
7623628b86 Merge branch 'develop' 2016-02-12 08:53:57 +01:00
Martin Edenhofer
f753bc203f Merge branch 'develop' 2016-02-11 13:25:39 +01:00
Martin Edenhofer
ff9ba10705 Merge branch 'develop' 2016-02-11 02:11:06 +01:00
Martin Edenhofer
fdc25bdc26 Merge branch 'develop' 2016-02-09 01:36:03 +01:00
Martin Edenhofer
d154a587ad Merge branch 'develop' 2016-02-04 12:55:30 +01:00
Martin Edenhofer
a9cc4f037b Merge branch 'develop' 2016-02-04 10:41:41 +01:00
Martin Edenhofer
50d6679189 Merge branch 'develop' 2016-02-03 13:19:51 +01:00
Martin Edenhofer
b82cf4e1d6 Merge branch 'develop' 2016-01-29 15:19:23 +01:00
Martin Edenhofer
fa6eaa6710 Merge branch 'develop'
# Conflicts:
#	README.md
2016-01-26 19:59:34 +01:00
Martin Edenhofer
2ca17ac1bd Updated build status url. 2016-01-26 13:57:24 +01:00
Martin Edenhofer
862ecd7d36 Merge branch 'develop' 2016-01-22 14:47:53 +01:00
Martin Edenhofer
e38b72593b Merge branch 'develop' 2016-01-12 11:14:24 +01:00
Martin Edenhofer
81883cae8f Revert "update terminal start script"
This reverts commit 63770c9cbf.
2016-01-12 11:13:40 +01:00
Felix Niklas
63770c9cbf update terminal start script 2016-01-12 10:58:46 +01:00
Martin Edenhofer
aaf5da55a0 Merge branch 'develop' 2015-12-28 11:33:58 +01:00
Martin Edenhofer
8455d9ae17 Merge branch 'develop' 2015-12-21 16:03:31 +01:00
Martin Edenhofer
839a8e8eb4 Merge branch 'develop' 2015-12-13 15:26:35 +01:00
Martin Edenhofer
7aa3f6eaee Updated build url. 2015-12-10 09:44:16 +01:00
Martin Edenhofer
219abc69a3 Merge branch 'develop' 2015-12-10 09:21:59 +01:00
Martin Edenhofer
595822c928 Merge branch 'develop' 2015-12-02 02:27:40 +01:00
Martin Edenhofer
32112937b1 Merge branch 'develop' 2015-12-02 01:41:10 +01:00
Martin Edenhofer
a0889c5b99 Merge branch 'develop' 2015-12-01 22:03:52 +01:00
Martin Edenhofer
4bc281bfb0 Merge branch 'develop' 2015-12-01 20:04:51 +01:00
Martin Edenhofer
e12ec607d7 Merge branch 'develop' 2015-11-30 15:11:25 +01:00
Martin Edenhofer
545f393293 Merge branch 'develop' 2015-11-30 01:24:11 +01:00
Martin Edenhofer
4efa152e93 Merge branch 'master' of github.com:martini/zammad 2015-11-24 03:39:17 +01:00
Martin Edenhofer
0ebda4f32a Merge branch 'develop'
Conflicts:
	README.md
	script/websocket-server.rb
2015-11-24 03:38:55 +01:00
Martin Edenhofer
b94f54799f Merge branch 'develop' of http://ci.lab.zammad.com/core/zammad 2015-11-24 03:07:38 +01:00
Martin Edenhofer
99f0b4e2e2 Merge branch 'develop' 2015-11-19 14:27:39 +01:00
Martin Edenhofer
53cb906733 Merge branch 'develop' 2015-11-01 01:49:02 +01:00
Martin Edenhofer
2c31fe8a84 Merge branch 'develop' 2015-10-31 23:40:10 +01:00
Martin Edenhofer
6c5e673a2c Merge branch 'develop' 2015-10-02 15:31:54 +02:00
Martin Edenhofer
574b891a33 Merge branch 'develop' 2015-09-28 02:12:31 +02:00
Martin Edenhofer
9ef1d3f58b Merge branch 'develop'
Conflicts:
	extras/zammad.spec
2015-09-28 01:24:03 +02:00
Martin Edenhofer
8b3f432746 Merge branch 'develop' 2015-09-01 03:15:03 +02:00
Martin Edenhofer
14a9df261e Merge branch 'develop' 2015-08-31 15:11:27 +02:00
Martin Edenhofer
5620a2847b Merge branch 'develop' 2015-08-31 12:42:04 +02:00
Martin Edenhofer
13aaae3835 Merge branch 'develop' 2015-08-30 09:19:02 +02:00
Martin Edenhofer
2d4fcd3a4f Merge branch 'develop' 2015-08-30 08:22:27 +02:00
Martin Edenhofer
f4f70b0bc2 Merge branch 'develop' 2015-08-30 01:36:18 +02:00
Martin Edenhofer
1d279bb88f Merge branch 'develop' 2015-08-30 01:32:10 +02:00
Martin Edenhofer
fe4757cbf9 Merge branch 'develop' 2015-08-21 17:03:28 +02:00
me
1d476f163e Use also mysql on test. 2015-08-21 16:53:38 +02:00
Martin Edenhofer
513701b6d2 Merge branch 'develop'
Conflicts:
	README.md
	script/websocket-server.rb
2015-08-11 15:17:14 +02:00
Thorsten Eckel
1a1b661714 Fixed typo. 2015-07-16 09:50:18 +02:00
Roy Kaldung
6081a98279 Update README.md 2015-01-12 12:39:26 +01:00
Roy Kaldung
157991c33d Update README.md 2015-01-12 12:38:11 +01:00
Roy Kaldung
ef67be9170 We like to know if it's starting or stopping 2014-11-06 17:24:45 +01:00
Martin Edenhofer
39f3819303 Merge branch 'develop' 2014-11-06 16:13:39 +01:00
Martin Edenhofer
7a676bd563 Merge branch 'develop' into 'master', goto next level.
Conflicts:
	Gemfile
	README.md
	extras/zammad.spec
2014-10-05 20:42:39 +02:00
Roy Kaldung
80c54daa03 Delete httpd.spec 2014-05-02 12:47:51 +02:00
Roy Kaldung
99c88cde62 Delete apr.spec 2014-05-02 12:47:41 +02:00
Roy Kaldung
17d113ca20 removed old file 2014-05-02 12:47:18 +02:00
Martin Edenhofer
2fbf4324a7 Update Gemfile 2014-02-22 14:46:25 +01:00
Roy Kaldung
b46c390d30 minor change to test GitHub hook (automatic deploy) 2013-12-04 18:22:21 +01:00
Martin Edenhofer
3c3651bc52 Merge branch 'develop'
Conflicts:
	app/controllers/tickets_controller.rb
2013-09-20 13:52:53 +02:00
Roy Kaldung
abeeb5e66d Updated Build Status image URL 2013-08-23 21:00:55 +02:00
rkaldung
09d61ce4c8 added dependency 2013-08-14 20:38:09 +02:00
rkaldung
cc1c4495b2 Merge branch 'master' of github.com:martini/zammad 2013-08-14 20:27:15 +02:00
rkaldung
7b1ec4d17f modified install section 2013-08-14 20:26:25 +02:00
rkaldung
99b3201ccf added initial spec for rpm 2013-08-14 20:20:55 +02:00
Roy Kaldung
d4205d9ba6 removed Windows ;-) 2013-08-14 20:08:23 +02:00
Roy Kaldung
8d57633390 minor changes on comments 2013-08-05 19:18:52 +02:00
46 changed files with 2087 additions and 133 deletions

View File

@@ -25,24 +25,26 @@ Note: We always do our best. Unfortunately, sometimes there are too many request
### Infos:
* Used Zammad version:
* Used Zammad installation source: (source, package, ...)
* Operating system:
* Used Zammad version:
* Installation method (source, package, ..):
* Operating system:
* Database + version:
* Elasticsearch version:
* Browser + version:
### Expected behavior:
*
*
### Actual behavior:
*
*
### Steps to reproduce the behavior:
*
*
Yes I'm sure this is a bug and no feature request or a general question.
Yes I'm sure this is a bug and no feature request or a general question.

View File

@@ -62,3 +62,4 @@ script:
after_success:
- if [ "${DB}" = "mysql" ]; then contrib/travis-ci.org/trigger-docker-build.sh; fi
- if [ "${DB}" = "mysql" ]; then contrib/travis-ci.org/trigger-docker-compose-build.sh; fi
- if [ "${DB}" = "mysql" ]; then contrib/travis-ci.org/trigger-docker-univention-build.sh; fi

View File

@@ -1,16 +1,55 @@
# Change Log
## [2.2.0](https://github.com/zammad/zammad/tree/2.2.0) (2017-xx-xx)
## [2.2.2](https://github.com/zammad/zammad/tree/2.2.2) (2018-03-29)
[Full Changelog](https://github.com/zammad/zammad/compare/2.2.1...2.2.2)
**Fixed bugs:**
- The column widths of a table are shifted after manual change and use of pagination. [\#1829](https://github.com/zammad/zammad/issues/1829) [[bug](https://github.com/zammad/zammad/labels/bug)]
- XSS issue in ticket overview [\#1869](https://github.com/zammad/zammad/issues/1869) [[bug](https://github.com/zammad/zammad/labels/bug)]
## [2.2.1](https://github.com/zammad/zammad/tree/2.2.0) (2018-01-30)
[Full Changelog](https://github.com/zammad/zammad/compare/2.2.0...2.2.1)
**Fixed bugs:**
- Generated excel report fails to create for special strings in ticket titles \(also: CSV formula injection possible\) [\#1756](https://github.com/zammad/zammad/issues/1756) [[bug](https://github.com/zammad/zammad/labels/bug)] [[reporting](https://github.com/zammad/zammad/labels/reporting)]
- Need data\_option\[:null\] - Ticket Object Manager [\#1742](https://github.com/zammad/zammad/issues/1742) [[bug](https://github.com/zammad/zammad/labels/bug)]
- Ticket search fails for limit exceeding 100 with internal server error [\#1753](https://github.com/zammad/zammad/issues/1753) [[bug](https://github.com/zammad/zammad/labels/bug)]
- Unable to send auto reply if from contains 2 or more senders with invalid email address [\#1749](https://github.com/zammad/zammad/issues/1749) [[bug](https://github.com/zammad/zammad/labels/bug)]
- Report for Created tickets should not have "merged" tickets [\#1741](https://github.com/zammad/zammad/issues/1741) [[bug](https://github.com/zammad/zammad/labels/bug)] [[reporting](https://github.com/zammad/zammad/labels/reporting)]
- Wrong ticket number count in preview [\#1723](https://github.com/zammad/zammad/issues/1723) [[bug](https://github.com/zammad/zammad/labels/bug)]
- Zammad Api for idoit.object\_ids broken [\#1711](https://github.com/zammad/zammad/issues/1711) [[bug](https://github.com/zammad/zammad/labels/bug)]
- Unable to login with Office365 [\#1710](https://github.com/zammad/zammad/issues/1710) [[bug](https://github.com/zammad/zammad/labels/bug)]
- No user preference for out-of-office available [\#1699](https://github.com/zammad/zammad/issues/1699) [[bug](https://github.com/zammad/zammad/labels/bug)]
- SipgateController - undefined method `each' for nil:NilClass \(NoMethodError\) [\#1698](https://github.com/zammad/zammad/issues/1698) [[bug](https://github.com/zammad/zammad/labels/bug)]
## [2.2.0](https://github.com/zammad/zammad/tree/2.2.0) (2017-12-06)
[Full Changelog](https://github.com/zammad/zammad/compare/2.1.0...2.2.0)
**Implemented enhancements:**
- email forward of article \(like regular email client forward - e. g. forward customers message to third party contact\) [\#573](https://github.com/zammad/zammad/issues/573) [[enhancement](https://github.com/zammad/zammad/labels/enhancement)]
- Take over attachment on ticket split [\#195](https://github.com/zammad/zammad/issues/195) [[enhancement](https://github.com/zammad/zammad/labels/enhancement)]
- Enable state "merged" for admin overviews, triggers and jobs [\#1689](https://github.com/zammad/zammad/issues/1689) [[enhancement](https://github.com/zammad/zammad/labels/enhancement)]
- Elasticsearchs mapper-attachments plugin has been deprecated, use ingest-attachment now [\#599](https://github.com/zammad/zammad/issues/599) [[enhancement](https://github.com/zammad/zammad/labels/enhancement)]
- Improve i-doit filtering \(without type\) [\#1571](https://github.com/zammad/zammad/issues/1571) [[enhancement](https://github.com/zammad/zammad/labels/enhancement)]
- Reset customer selection in ticket create screen if input field cleared [\#1670](https://github.com/zammad/zammad/issues/1670) [[enhancement](https://github.com/zammad/zammad/labels/enhancement)]
- Add config option for intelligent customer selection of incoming emails of agents [\#1671](https://github.com/zammad/zammad/issues/1671) [[enhancement](https://github.com/zammad/zammad/labels/enhancement)]
- Twitter: Allow tweet articles to be 280 chars long [\#1628](https://github.com/zammad/zammad/issues/1628) [[enhancement](https://github.com/zammad/zammad/labels/enhancement)]
- Chat language setting or behaviour in dutch [\#1618](https://github.com/zammad/zammad/issues/1618) [[enhancement](https://github.com/zammad/zammad/labels/enhancement)]
- leading and tailing utf8 spaces are not removed for email addresses are not removed [\#1579](https://github.com/zammad/zammad/issues/1579) [[enhancement](https://github.com/zammad/zammad/labels/enhancement)]
- Import emails with same message\_id but target was different channels [\#1578](https://github.com/zammad/zammad/issues/1578) [[enhancement](https://github.com/zammad/zammad/labels/enhancement)]
**Fixed bugs:**
- Webform isn´t available | 401 Unauthorized [\#1604](https://github.com/zammad/zammad/issues/1604) [[bug](https://github.com/zammad/zammad/labels/bug)]
- TimeAccounting ticket condition prevents submit of Zoom [\#1513](https://github.com/zammad/zammad/issues/1513) [[bug](https://github.com/zammad/zammad/labels/bug)]
- Unable to re-order overviews in admin interface with over 100 overviews [\#1681](https://github.com/zammad/zammad/issues/1681) [[bug](https://github.com/zammad/zammad/labels/bug)]
- Unable to open trigger in admin interface [\#1666](https://github.com/zammad/zammad/issues/1666) [[bug](https://github.com/zammad/zammad/labels/bug)]
- Users mail\_delivery\_failed is not removed after changing the email address [\#1661](https://github.com/zammad/zammad/issues/1661) [[bug](https://github.com/zammad/zammad/labels/bug)]
- Tickets are deleted but database is still the same size [\#1649](https://github.com/zammad/zammad/issues/1649) [[bug](https://github.com/zammad/zammad/labels/bug)]
- Translation for form widget in Dutch [\#1623](https://github.com/zammad/zammad/issues/1623) [[enhancement](https://github.com/zammad/zammad/labels/enhancement)]
- Exchange Integration SSL Error with self-signed root certificate authority [\#1442](https://github.com/zammad/zammad/issues/1442) [[bug](https://github.com/zammad/zammad/labels/bug)]
- Unable to sort overview by priority [\#1595](https://github.com/zammad/zammad/issues/1595) [[bug](https://github.com/zammad/zammad/labels/bug)]
- LDAP Integration: Comprehensive configuration cause the import to fail [\#1457](https://github.com/zammad/zammad/issues/1457) [[bug](https://github.com/zammad/zammad/labels/bug)]
- {"error":"Role Customer conflicts with Admin"} [\#1509](https://github.com/zammad/zammad/issues/1509) [[bug](https://github.com/zammad/zammad/labels/bug)]
- prevent admin from locking out [\#1563](https://github.com/zammad/zammad/issues/1563) [[bug](https://github.com/zammad/zammad/labels/bug)]
\* *This Change Log was automatically generated by [github_changelog_generator](https://github.com/skywinder/Github-Changelog-Generator)*

View File

@@ -213,7 +213,7 @@ GEM
logging (2.2.2)
little-plugger (~> 1.1)
multi_json (~> 1.10)
loofah (2.1.1)
loofah (2.2.2)
crass (~> 1.0.2)
nokogiri (>= 1.5.9)
lumberjack (1.0.12)
@@ -235,7 +235,7 @@ GEM
net-ldap (0.16.1)
netrc (0.11.0)
nio4r (2.1.0)
nokogiri (1.8.1)
nokogiri (1.8.2)
mini_portile2 (~> 2.3.0)
nori (2.6.0)
notiffany (0.1.1)
@@ -318,8 +318,8 @@ GEM
rails-dom-testing (2.0.3)
activesupport (>= 4.2.0)
nokogiri (>= 1.6)
rails-html-sanitizer (1.0.3)
loofah (~> 2.0)
rails-html-sanitizer (1.0.4)
loofah (~> 2.2, >= 2.2.2)
rails-observers (0.1.5)
activemodel (>= 4.0)
railties (5.1.4)

View File

@@ -192,8 +192,8 @@ class App.ControllerTable extends App.Controller
el.filter('.js-pager').html('')
return
pager = App.view('generic/table_pager')(
page: @shownPage
pages: pages
page: @shownPage
pages: pages
)
if find
el.find('.js-pager').html(pager)
@@ -839,13 +839,21 @@ class App.ControllerTable extends App.Controller
# update store and runtime @headerWidth
@preferencesStore('headerWidth', leftColumnKey, leftWidth)
@headerWidth[leftColumnKey] = leftWidth
_.find(@headers, (column) -> column.name is leftColumnKey).displayWidth = leftWidth
# set header at runtime
for header in @headers
if header.name is leftColumnKey
header.displayWidth = @resizeTargetLeft.outerWidth()
# update store and runtime @headerWidth
if rightColumnKey
@preferencesStore('headerWidth', rightColumnKey, rightWidth)
@headerWidth[rightColumnKey] = rightWidth
_.find(@headers, (column) -> column.name is rightColumnKey).displayWidth = rightWidth
# set header at runtime
for header in @headers
if header.name is rightColumnKey
header.displayWidth = @resizeTargetRight.outerWidth()
sortByColumn: (event) =>
column = $(event.currentTarget).closest('[data-column-key]').attr('data-column-key')

View File

@@ -42,7 +42,7 @@ class App.SettingsAreaTicketNumber extends App.Controller
number = "#{App.Config.get('ticket_hook')}#{App.Config.get('system_id')}"
counter = '1'
if paramsItem.min_size
minSize = parseInt(paramsItem.min_size)
minSize = parseInt(paramsItem.min_size) - "#{App.Config.get('system_id')}".length
if paramsItem.checksum
minSize -= 1
if minSize > 1

View File

@@ -151,7 +151,7 @@ class App.TicketZoomArticleNew extends App.Controller
icon: 'twitter'
attributes: []
internal: false,
features: ['body:limit', 'body:initials']
features: attributes
maxTextLength: 280
warningTextLength: 30
}
@@ -164,7 +164,7 @@ class App.TicketZoomArticleNew extends App.Controller
icon: 'twitter'
attributes: ['to']
internal: false,
features: ['body:limit', 'body:initials']
features: attributes
maxTextLength: 10000
warningTextLength: 500
}

View File

@@ -1,11 +1,11 @@
<div class="signup fullscreen">
<div class="fullscreen-center">
<div class="hero-unit fullscreen-body">
<h1><%- @T( 'Join' ) %> <%= @C( 'product_name' ) %></h1>
<h1><%- @T('Join %s', @C('product_name')) %></h1>
<form>
<div class="form-controls">
<a class="btn btn--text btn--subtle js-cancel" href="#login"><%- @T( 'Cancel & Go Back' ) %></a>
<button class="btn btn--primary js-submit align-right"><%- @T( 'Create my account' ) %></button>
<a class="btn btn--text btn--subtle js-cancel" href="#login"><%- @T('Cancel & Go Back') %></a>
<button class="btn btn--primary js-submit align-right"><%- @T('Create my account') %></button>
</div>
</form>
</div>

View File

@@ -43,8 +43,13 @@ class Integration::SipgateController < ApplicationController
# set caller id of outbound call
def out
config_outbound = config_integration[:outbound][:routing_table]
default_caller_id = config_integration[:outbound][:default_caller_id]
config_outbound = config_integration[:outbound]
routing_table = nil
default_caller_id = nil
if config_outbound.present?
routing_table = config_outbound[:routing_table]
default_caller_id = config_outbound[:default_caller_id]
end
xml = Builder::XmlMarkup.new(indent: 2)
xml.instruct!
@@ -53,8 +58,8 @@ class Integration::SipgateController < ApplicationController
content = nil
to = params[:to]
from = nil
if to
config_outbound.each do |row|
if to && routing_table.present?
routing_table.each do |row|
dest = row[:dest].gsub(/\*/, '.+?')
next if to !~ /^#{dest}$/
from = row[:caller_id]
@@ -63,7 +68,7 @@ class Integration::SipgateController < ApplicationController
end
break
end
if !content && default_caller_id
if !content && default_caller_id.present?
from = default_caller_id
content = xml.Response(onHangup: url, onAnswer: url) do
xml.Dial(callerId: default_caller_id) { xml.Number(params[:to]) }
@@ -73,8 +78,8 @@ class Integration::SipgateController < ApplicationController
content = xml.Response(onHangup: url, onAnswer: url)
end
send_data content, type: 'application/xml; charset=UTF-8;'
if from
send_data(content, type: 'application/xml; charset=UTF-8;')
if from.present?
params['from'] = from
end
Cti::Log.process(params)
@@ -89,7 +94,7 @@ class Integration::SipgateController < ApplicationController
xml_error('Feature is disable, please contact your admin to enable it!')
return
end
if !config_integration || !config_integration[:inbound] || !config_integration[:outbound]
if config_integration.blank? || config_integration[:inbound].blank? || config_integration[:outbound].blank?
xml_error('Feature not configured, please contact your admin!')
return
end

View File

@@ -32,6 +32,7 @@ class ObjectManagerAttributesController < ApplicationController
raise Exceptions::UnprocessableEntity, 'already exists' if exists
local_params = params.permit!.to_h
local_params[:data_option][:null] = true # set data option which can be null
begin
object_manager_attribute = ObjectManager::Attribute.add(
object: local_params[:object],
@@ -110,12 +111,33 @@ class ObjectManagerAttributesController < ApplicationController
# rubocop:enable Lint/BooleanSymbol
end
end
if params[:data_option] && !params[:data_option].key?(:default)
params[:data_option][:default] = if params[:data_type].match?(/^(input|select|tree_select)$/)
''
end
if params[:data_option]
if !params[:data_option].key?(:default)
params[:data_option][:default] = if params[:data_type].match?(/^(input|select|tree_select)$/)
''
end
end
if params[:data_option][:null].nil?
params[:data_option][:null] = true
end
if params[:data_option][:options].nil?
params[:data_option][:options] = ''
end
if params[:data_option][:relation].nil?
params[:data_option][:relation] = ''
end
else
params[:data_option] = {
default: '',
options: '',
relation: '',
null: true
}
end
return if !params[:data_option][:null].nil?
params[:data_option][:null] = true
end
end

View File

@@ -234,7 +234,7 @@ curl http://localhost/api/v1/organization/{id} -v -u #{login}:#{password} -H "Co
end
if params[:limit] && params[:limit].to_i > 500
params[:limit].to_i = 500
params[:limit] = 500
end
query = params[:query]

View File

@@ -187,46 +187,50 @@ class ReportsController < ApplicationController
worksheet.set_row(0, 0, 6)
# Write a formatted and unformatted string, row and column notation.
worksheet.write(0, 0, "Tickets: #{profile.name} (#{title})", format)
worksheet.write_string(0, 0, "Tickets: #{profile.name} (#{title})", format)
format_header = workbook.add_format
format_header.set_italic
format_header.set_bg_color('gray')
format_header.set_color('white')
worksheet.write(2, 0, '#', format_header)
worksheet.write(2, 1, 'Title', format_header)
worksheet.write(2, 2, 'State', format_header)
worksheet.write(2, 3, 'Priority', format_header)
worksheet.write(2, 4, 'Group', format_header)
worksheet.write(2, 5, 'Owner', format_header)
worksheet.write(2, 6, 'Customer', format_header)
worksheet.write(2, 7, 'Organization', format_header)
worksheet.write(2, 8, 'Create Channel', format_header)
worksheet.write(2, 9, 'Sender', format_header)
worksheet.write(2, 10, 'Tags', format_header)
worksheet.write(2, 11, 'Created at', format_header)
worksheet.write(2, 12, 'Updated at', format_header)
worksheet.write(2, 13, 'Closed at', format_header)
worksheet.write_string(2, 0, '#', format_header)
worksheet.write_string(2, 1, 'Title', format_header)
worksheet.write_string(2, 2, 'State', format_header)
worksheet.write_string(2, 3, 'Priority', format_header)
worksheet.write_string(2, 4, 'Group', format_header)
worksheet.write_string(2, 5, 'Owner', format_header)
worksheet.write_string(2, 6, 'Customer', format_header)
worksheet.write_string(2, 7, 'Organization', format_header)
worksheet.write_string(2, 8, 'Create Channel', format_header)
worksheet.write_string(2, 9, 'Sender', format_header)
worksheet.write_string(2, 10, 'Tags', format_header)
worksheet.write_string(2, 11, 'Created at', format_header)
worksheet.write_string(2, 12, 'Updated at', format_header)
worksheet.write_string(2, 13, 'Closed at', format_header)
row = 2
result[:ticket_ids].each do |ticket_id|
ticket = Ticket.lookup(id: ticket_id)
row += 1
worksheet.write(row, 0, ticket.number)
worksheet.write(row, 1, ticket.title)
worksheet.write(row, 2, ticket.state.name)
worksheet.write(row, 3, ticket.priority.name)
worksheet.write(row, 4, ticket.group.name)
worksheet.write(row, 5, ticket.owner.fullname)
worksheet.write(row, 6, ticket.customer.fullname)
worksheet.write(row, 7, ticket.try(:organization).try(:name))
worksheet.write(row, 8, ticket.create_article_type.name)
worksheet.write(row, 9, ticket.create_article_sender.name)
worksheet.write(row, 10, ticket.tag_list.join(','))
worksheet.write(row, 11, ticket.created_at)
worksheet.write(row, 12, ticket.updated_at)
worksheet.write(row, 13, ticket.close_at)
begin
ticket = Ticket.lookup(id: ticket_id)
row += 1
worksheet.write_string(row, 0, ticket.number)
worksheet.write_string(row, 1, ticket.title)
worksheet.write_string(row, 2, ticket.state.name)
worksheet.write_string(row, 3, ticket.priority.name)
worksheet.write_string(row, 4, ticket.group.name)
worksheet.write_string(row, 5, ticket.owner.fullname)
worksheet.write_string(row, 6, ticket.customer.fullname)
worksheet.write_string(row, 7, ticket.try(:organization).try(:name))
worksheet.write_string(row, 8, ticket.create_article_type.name)
worksheet.write_string(row, 9, ticket.create_article_sender.name)
worksheet.write_string(row, 10, ticket.tag_list.join(','))
worksheet.write_date_time(row, 11, ticket.created_at.to_time.iso8601)
worksheet.write_date_time(row, 12, ticket.updated_at.to_time.iso8601)
worksheet.write_date_time(row, 13, ticket.close_at.to_time.iso8601)
rescue => e
Rails.logger.error "SKIP: #{e.message}"
end
end
workbook.close

View File

@@ -388,7 +388,7 @@ class TicketsController < ApplicationController
end
if params[:limit] && params[:limit].to_i > 100
params[:limit].to_i = 100
params[:limit] = 100
end
query = params[:query]

View File

@@ -382,7 +382,7 @@ class TimeAccountingsController < ApplicationController
worksheet.set_row(0, 0, header.count)
# Write a formatted and unformatted string, row and column notation.
worksheet.write(0, 0, title, format)
worksheet.write_string(0, 0, title, format)
format_header = workbook.add_format # Add a format
format_header.set_italic
@@ -393,7 +393,7 @@ class TimeAccountingsController < ApplicationController
if item[:width]
worksheet.set_column(count, count, item[:width])
end
worksheet.write(2, count, item[:name], format_header)
worksheet.write_string(2, count, item[:name], format_header)
count += 1
end
@@ -402,7 +402,11 @@ class TimeAccountingsController < ApplicationController
row_count += 1
row_item_count = 0
row.each do |item|
worksheet.write(row_count, row_item_count, item)
if item.acts_like?(:date)
worksheet.write_date_time(row_count, row_item_count, item.to_time.iso8601)
else
worksheet.write_string(row_count, row_item_count, item)
end
row_item_count += 1
end
end

View File

@@ -360,7 +360,7 @@ class UsersController < ApplicationController
end
if params[:limit] && params[:limit].to_i > 500
params[:limit].to_i = 500
params[:limit] = 500
end
query = params[:query]

View File

@@ -105,22 +105,41 @@ add avatar by url
# fetch image based on http url
if data[:url].present?
if data[:url].match?(/^http/)
if data[:url].class == Tempfile
logger.info "Reading image from tempfile '#{data[:url].inspect}'"
content = data[:url].read
filename = data[:url].path
mime_type = 'image'
if filename.match?(/\.png/i)
mime_type = 'image/png'
end
if filename.match?(/\.(jpg|jpeg)/i)
mime_type = 'image/jpeg'
end
data[:resize] ||= {}
data[:resize][:content] = content
data[:resize][:mime_type] = mime_type
data[:full] ||= {}
data[:full][:content] = content
data[:full][:mime_type] = mime_type
elsif data[:url].to_s.match?(/^http/)
url = data[:url].to_s
# check if source ist already updated within last 2 minutes
if avatar_already_exists&.source_url == data[:url]
if avatar_already_exists&.source_url == url
return if avatar_already_exists.updated_at > 2.minutes.ago
end
# twitter workaround to get bigger avatar images
# see also https://dev.twitter.com/overview/general/user-profile-images-and-banners
if data[:url].match?(%r{//pbs.twimg.com/}i)
data[:url].sub!(/normal\.(png|jpg|gif)$/, 'bigger.\1')
if url.match?(%r{//pbs.twimg.com/}i)
url.sub!(/normal\.(png|jpg|gif)$/, 'bigger.\1')
end
# fetch image
response = UserAgent.get(
data[:url],
url,
{},
{
open_timeout: 4,
@@ -129,20 +148,19 @@ add avatar by url
},
)
if !response.success?
logger.info "Can't fetch '#{data[:url]}' (maybe no avatar available), http code: #{response.code}"
logger.info "Can't fetch '#{url}' (maybe no avatar available), http code: #{response.code}"
return
end
logger.info "Fetchd image '#{data[:url]}', http code: #{response.code}"
logger.info "Fetchd image '#{url}', http code: #{response.code}"
mime_type = 'image'
if data[:url].match?(/\.png/i)
if url.match?(/\.png/i)
mime_type = 'image/png'
end
if data[:url].match?(/\.(jpg|jpeg)/i)
if url.match?(/\.(jpg|jpeg)/i)
mime_type = 'image/jpeg'
end
if !data[:resize]
data[:resize] = {}
end
data[:resize] ||= {}
data[:resize][:content] = response.body
data[:resize][:mime_type] = mime_type
data[:full] ||= {}
@@ -150,15 +168,16 @@ add avatar by url
data[:full][:mime_type] = mime_type
# try zammad backend to find image based on email
elsif data[:url].match?(/@/)
elsif data[:url].to_s.match?(/@/)
url = data[:url].to_s
# check if source ist already updated within last 3 minutes
if avatar_already_exists&.source_url == data[:url]
if avatar_already_exists&.source_url == url
return if avatar_already_exists.updated_at > 2.minutes.ago
end
# fetch image
image = Service::Image.user(data[:url])
image = Service::Image.user(url)
return if !image
data[:resize] ||= {}
data[:resize] = image
@@ -337,7 +356,7 @@ returns:
store_hash: hash,
)
return if !avatar
file = Store.find(avatar.store_resize_id)
Store.find(avatar.store_resize_id)
end
=begin

View File

@@ -95,16 +95,19 @@ module Channel::Filter::IdentifySender
max_count = 40
current_count = 0
['raw-to', 'raw-cc'].each do |item|
next if !mail[item.to_sym]
next if mail[item.to_sym].blank?
begin
next if !mail[item.to_sym].addrs
items = mail[item.to_sym].addrs
next if items.blank?
items.each do |address_data|
next if address_data.address.blank?
email_address = address_data.address
next if email_address.blank?
next if email_address !~ /@/
next if email_address.match?(/\s/)
user_create(
firstname: address_data.display_name,
lastname: '',
email: address_data.address,
email: email_address,
)
current_count += 1
return false if current_count == max_count
@@ -126,6 +129,8 @@ module Channel::Filter::IdentifySender
display_name = $1
end
next if address.blank?
next if address !~ /@/
next if address.match?(/\s/)
user_create(
firstname: display_name,
lastname: '',
@@ -176,7 +181,7 @@ module Channel::Filter::IdentifySender
data[:updated_by_id] = 1
data[:created_by_id] = 1
user = User.create(data)
user = User.create!(data)
user.update!(
updated_by_id: user.id,
created_by_id: user.id,

View File

@@ -22,6 +22,12 @@ class Report
dataDownload: true,
adapter: Report::TicketGenericTime,
params: { field: 'created_at' },
condition: {
'state' => {
'operator' => 'is not',
'value' => 'merged'
}
}
},
{
name: 'closed',
@@ -30,6 +36,12 @@ class Report
dataDownload: true,
adapter: Report::TicketGenericTime,
params: { field: 'close_at' },
condition: {
'state' => {
'operator' => 'is not',
'value' => 'merged'
}
}
},
{
name: 'backlog',
@@ -37,6 +49,12 @@ class Report
selected: true,
dataDownload: false,
adapter: Report::TicketBacklog,
condition: {
'state' => {
'operator' => 'is not',
'value' => 'merged'
}
}
},
{
name: 'first_solution',
@@ -44,6 +62,12 @@ class Report
selected: false,
dataDownload: true,
adapter: Report::TicketFirstSolution,
condition: {
'ticket_state.name' => {
'operator' => 'is not',
'value' => 'merged'
}
}
},
{
name: 'reopened',
@@ -51,6 +75,12 @@ class Report
selected: false,
dataDownload: true,
adapter: Report::TicketReopened,
condition: {
'ticket_state.name' => {
'operator' => 'is not',
'value' => 'merged'
}
}
},
{
name: 'movedin',
@@ -59,6 +89,12 @@ class Report
dataDownload: true,
adapter: Report::TicketMoved,
params: { type: 'in' },
condition: {
'ticket_state.name' => {
'operator' => 'is not',
'value' => 'merged'
}
}
},
{
name: 'movedout',
@@ -67,6 +103,12 @@ class Report
dataDownload: true,
adapter: Report::TicketMoved,
params: { type: 'out' },
condition: {
'ticket_state.name' => {
'operator' => 'is not',
'value' => 'merged'
}
}
},
]
config[:metric][:count][:backend] = backend

View File

@@ -185,7 +185,7 @@ returns
def last_admin_check_admin_count
admin_role_ids = Role.joins(:permissions).where(permissions: { name: ['admin', 'admin.user'], active: true }, roles: { active: true }).where.not(id: id).pluck(:id)
User.joins(:roles).where(roles: { id: admin_role_ids }, users: { active: true }).count
User.joins(:roles).where(roles: { id: admin_role_ids }, users: { active: true }).distinct().count
end
def validate_agent_limit_by_attributes
@@ -194,8 +194,8 @@ returns
return true if active != true
return true if !with_permission?('ticket.agent')
ticket_agent_role_ids = Role.joins(:permissions).where(permissions: { name: 'ticket.agent', active: true }, roles: { active: true }).pluck(:id)
currents = User.joins(:roles).where(roles: { id: ticket_agent_role_ids }, users: { active: true }).pluck(:id)
news = User.joins(:roles).where(roles: { id: id }, users: { active: true }).pluck(:id)
currents = User.joins(:roles).where(roles: { id: ticket_agent_role_ids }, users: { active: true }).distinct().pluck(:id)
news = User.joins(:roles).where(roles: { id: id }, users: { active: true }).distinct().pluck(:id)
count = currents.concat(news).uniq.count
raise Exceptions::UnprocessableEntity, 'Agent limit exceeded, please check your account settings.' if count > Setting.get('system_agent_limit')
true
@@ -208,7 +208,7 @@ returns
return true if permission.name != 'ticket.agent'
ticket_agent_role_ids = Role.joins(:permissions).where(permissions: { name: 'ticket.agent' }, roles: { active: true }).pluck(:id)
ticket_agent_role_ids.push(id)
count = User.joins(:roles).where(roles: { id: ticket_agent_role_ids }, users: { active: true }).count
count = User.joins(:roles).where(roles: { id: ticket_agent_role_ids }, users: { active: true }).distinct().count
raise Exceptions::UnprocessableEntity, 'Agent limit exceeded, please check your account settings.' if count > Setting.get('system_agent_limit')
true
end

View File

@@ -528,6 +528,9 @@ condition example
elsif selector[0] == 'article'
tables += ', ticket_articles articles'
query += 'tickets.id = articles.ticket_id'
elsif selector[0] == 'ticket_state'
tables += ', ticket_states'
query += 'tickets.state_id = ticket_states.id'
else
raise "invalid selector #{attribute.inspect}->#{selector.inspect}"
end
@@ -881,14 +884,25 @@ perform changes on ticket
next if skip_user
# send notifications only to email adresses
next if !recipient_email
next if recipient_email.blank?
next if recipient_email !~ /@/
# check if address is valid
begin
recipient_email = Mail::Address.new(recipient_email).address
Mail::AddressList.new(recipient_email).addresses.each do |address|
recipient_email = address.address
break if recipient_email.present? && recipient_email =~ /@/ && !recipient_email.match?(/\s/)
end
rescue
next # because unable to parse
if recipient_email.present?
if recipient_email !~ /^(.+?)<(.+?)@(.+?)>$/
next # no usable format found
end
recipient_email = "#{$2}@#{$3}"
end
next if recipient_email.blank?
next if recipient_email !~ /@/
next if recipient_email.match?(/\s/)
end
# do not sent notifications to this recipients

View File

@@ -81,6 +81,10 @@ module Ticket::Number::Date
ticket_hook_divider = Setting.get('ticket_hook_divider') || ''
ticket = nil
if Setting.get('ticket_number_ignore_system_id') == true
system_id = ''
end
# probe format
string.scan(/#{Regexp.quote(ticket_hook)}#{Regexp.quote(ticket_hook_divider)}(\d{4,10}#{system_id}\d{2,40})/i) do
ticket = Ticket.find_by(number: $1)

View File

@@ -78,6 +78,10 @@ module Ticket::Number::Increment
ticket_hook_divider = Setting.get('ticket_hook_divider') || ''
ticket = nil
if Setting.get('ticket_number_ignore_system_id') == true
system_id = ''
end
# probe format
string.scan(/#{Regexp.quote(ticket_hook)}#{Regexp.quote(ticket_hook_divider)}(#{system_id}\d{2,48})/i) do
ticket = Ticket.find_by(number: $1)

View File

@@ -99,7 +99,7 @@ returns
end
# try search index backend
if !condition && SearchIndexBackend.enabled?
if condition.blank? && SearchIndexBackend.enabled?
query_extention = {}
query_extention['bool'] = {}
query_extention['bool']['must'] = []

View File

@@ -1018,7 +1018,7 @@ raise 'Minimum one user need to have admin permissions'
def last_admin_check_admin_count
admin_role_ids = Role.joins(:permissions).where(permissions: { name: ['admin', 'admin.user'], active: true }, roles: { active: true }).pluck(:id)
User.joins(:roles).where(roles: { id: admin_role_ids }, users: { active: true }).count - 1
User.joins(:roles).where(roles: { id: admin_role_ids }, users: { active: true }).distinct().count - 1
end
def validate_agent_limit_by_attributes
@@ -1027,7 +1027,7 @@ raise 'Minimum one user need to have admin permissions'
return true if active != true
return true if !permissions?('ticket.agent')
ticket_agent_role_ids = Role.joins(:permissions).where(permissions: { name: 'ticket.agent', active: true }, roles: { active: true }).pluck(:id)
count = User.joins(:roles).where(roles: { id: ticket_agent_role_ids }, users: { active: true }).count + 1
count = User.joins(:roles).where(roles: { id: ticket_agent_role_ids }, users: { active: true }).distinct().count + 1
raise Exceptions::UnprocessableEntity, 'Agent limit exceeded, please check your account settings.' if count > Setting.get('system_agent_limit')
true
end
@@ -1038,7 +1038,7 @@ raise 'Minimum one user need to have admin permissions'
return true if role.active != true
return true if !role.with_permission?('ticket.agent')
ticket_agent_role_ids = Role.joins(:permissions).where(permissions: { name: 'ticket.agent', active: true }, roles: { active: true }).pluck(:id)
count = User.joins(:roles).where(roles: { id: ticket_agent_role_ids }, users: { active: true }).count
count = User.joins(:roles).where(roles: { id: ticket_agent_role_ids }, users: { active: true }).distinct().count
# if new added role is a ticket.agent role
if ticket_agent_role_ids.include?(role.id)

View File

@@ -0,0 +1,18 @@
#!/bin/bash
#
# trigger build of https://github.com/zammad/zammad-docker-univention on https://travis-ci.org/zammad/zammad-docker-univention and upload it to https://hub.docker.com/r/zammad/zammad-docker-univention
#
REPO_USER="zammad"
REPO="zammad-docker-univention"
BRANCH="master"
if [ "${TRAVIS_BRANCH}" == 'stable' ]; then
curl -X POST \
-H "Content-Type: application/json" \
-H "Travis-API-Version: 3" \
-H "Accept: application/json" \
-H "Authorization: token ${TRAVIS_API_TOKEN}" \
-d '{"request":{ "message": "'"${TRAVIS_COMMIT_MESSAGE}"'","branch":"'${BRANCH}'","config":{"env":{"ZAMMAD_VERSION":"'${ZAMMAD_VERSION}'"}}}}' \
"https://api.travis-ci.org/repo/${REPO_USER}%2F${REPO}/requests"
fi

View File

@@ -201,7 +201,7 @@ class CreateBase < ActiveRecord::Migration[4.2]
create_table :authorizations do |t|
t.string :provider, limit: 250, null: false
t.string :uid, limit: 250, null: false
t.string :token, limit: 250, null: true
t.string :token, limit: 2500, null: true
t.string :secret, limit: 250, null: true
t.string :username, limit: 250, null: true
t.references :user, null: false

View File

@@ -0,0 +1,18 @@
class PermissionUserPreferencesOutOfOffice < ActiveRecord::Migration[5.1]
def up
# return if it's a new setup
return if !Setting.find_by(name: 'system_init_done')
Permission.create_if_not_exists(
name: 'user_preferences.out_of_office',
note: 'Change %s',
preferences: {
translations: ['Out of Office'],
required: ['ticket.agent'],
},
)
end
end

View File

@@ -0,0 +1,10 @@
class ChangeAuthorizationTokenSize < ActiveRecord::Migration[5.1]
def up
# return if it's a new setup to avoid running the migration
return if !Setting.find_by(name: 'system_init_done')
change_column :authorizations, :token, :string, limit: 2500
end
end

View File

@@ -0,0 +1,37 @@
class SettingTicketNumberIgnoreSystemIdSupport < ActiveRecord::Migration[4.2]
def up
# return if it's a new setup
return if !Setting.find_by(name: 'system_init_done')
Setting.create_if_not_exists(
title: 'Ticket Number ignore system_id',
name: 'ticket_number_ignore_system_id',
area: 'Ticket::Core',
description: '-',
options: {
form: [
{
display: 'Ignore system_id',
null: true,
name: 'ticket_number_ignore_system_id',
tag: 'boolean',
options: {
true => 'yes',
false => 'no',
},
},
],
},
state: {
ticket_number_ignore_system_id: false
},
preferences: {
permission: ['admin.ticket'],
hidden: true,
},
frontend: false
)
end
end

View File

@@ -283,6 +283,14 @@ Permission.create_if_not_exists(
required: ['ticket.agent'],
},
)
Permission.create_if_not_exists(
name: 'user_preferences.out_of_office',
note: 'Change %s',
preferences: {
translations: ['Out of Office'],
required: ['ticket.agent'],
},
)
Permission.create_if_not_exists(
name: 'report',

View File

@@ -1672,6 +1672,34 @@ Setting.create_if_not_exists(
},
frontend: false
)
Setting.create_if_not_exists(
title: 'Ticket Number ignore system_id',
name: 'ticket_number_ignore_system_id',
area: 'Ticket::Core',
description: '-',
options: {
form: [
{
display: 'Ignore system_id',
null: true,
name: 'ticket_number_ignore_system_id',
tag: 'boolean',
options: {
true => 'yes',
false => 'no',
},
},
],
},
state: {
ticket_number_ignore_system_id: false
},
preferences: {
permission: ['admin.ticket'],
hidden: true,
},
frontend: false
)
Setting.create_if_not_exists(
title: 'Enable Ticket creation',

View File

@@ -68,6 +68,7 @@ module Import
mapped[:created_at] ||= DateTime.current
mapped[:updated_at] ||= DateTime.current
mapped[:email].downcase!
mapped[:login].downcase!
mapped
end

View File

@@ -68,6 +68,7 @@ module Import
def map(user)
mapped = map_default(user)
mapped[:email].downcase!
mapped[:login].downcase!
mapped
end
@@ -95,6 +96,7 @@ module Import
queues.each do |queue|
permissions = user['GroupIDs'][ queue['GroupID'] ]
permissions ||= user['GroupIDs'][ queue['GroupID'].to_s ]
next if !permissions
next if !permissions.include?('rw')
@@ -143,6 +145,7 @@ module Import
def groups_from_otrs_group(role_object, group)
result = []
return result if role_object.blank?
return result if role_object['GroupIDs'].blank?
permissions = role_object['GroupIDs'][ group['ID'] ]
@@ -164,7 +167,7 @@ module Import
roles = Import::OTRS::Requester.load('Role')
roles.each do |role|
next if !user['RoleIDs'].include?(role['ID'])
result += groups_from_otrs_groups(role['GroupIDs'])
result += groups_from_otrs_groups(role)
end
result
end

View File

@@ -461,7 +461,7 @@ get count of tickets and tickets which match on selector
elsif data['operator'] == 'contains not'
query_must_not.push t
else
raise "unknown operator '#{data['operator']}'"
raise "unknown operator '#{data['operator']}' for #{key}"
end
end
end

View File

@@ -71,8 +71,11 @@
height: 100%;
width: 3.4em;
text-align: center;
line-height: 3.5em;
line-height: 3.4em;
cursor: pointer; }
.zammad-chat-header-icon:before {
content: "";
display: inline-block; }
.zammad-chat-header-icon-open,
.zammad-chat-header-icon-close {
@@ -107,7 +110,7 @@
font-weight: bold; }
.zammad-chat-agent-status {
margin: 0 1em;
margin: 0.25em 1em;
display: inline-block;
line-height: 2em;
padding: 0 .7em;

View File

@@ -80,8 +80,13 @@
height: 100%;
width: 3.4em;
text-align: center;
line-height: 3.5em;
line-height: 3.4em;
cursor: pointer;
&:before { // force the icon to align to center
content: "";
display: inline-block;
}
}
.zammad-chat-header-icon-open,
@@ -125,7 +130,7 @@
}
.zammad-chat-agent-status {
margin: 0 1em;
margin: 0.25em 1em;
display: inline-block;
line-height: 2em;
padding: 0 .7em;

View File

@@ -0,0 +1,348 @@
{
"CustomerCompanyCity": "test712259",
"Config": {
"CustomerUserEmailUniqCheck": 1,
"CustomerUserSearchListLimit": 250,
"CustomerCompanySupport": 1,
"CustomerValid": "valid_id",
"CustomerUserSearchFields": [
"login",
"first_name",
"last_name",
"customer_id"
],
"CustomerUserSearchPrefix": "*",
"Params": {
"Table": "customer_user",
"CaseSensitive": 0
},
"CustomerUserListFields": [
"first_name",
"last_name",
"email"
],
"Map": [
[
"UserTitle",
"Title",
"title",
1,
0,
"var",
"",
0
],
[
"UserFirstname",
"Firstname",
"first_name",
1,
1,
"var",
"",
0
],
[
"UserLastname",
"Lastname",
"last_name",
1,
1,
"var",
"",
0
],
[
"UserLogin",
"Username",
"login",
1,
1,
"var",
"",
0
],
[
"UserPassword",
"Password",
"pw",
0,
0,
"var",
"",
0
],
[
"UserEmail",
"Email",
"email",
1,
1,
"var",
"",
0
],
[
"UserCustomerID",
"CustomerID",
"customer_id",
0,
1,
"var",
"",
0
],
[
"UserPhone",
"Phone",
"phone",
1,
0,
"var",
"",
0
],
[
"UserFax",
"Fax",
"fax",
1,
0,
"var",
"",
0
],
[
"UserMobile",
"Mobile",
"mobile",
1,
0,
"var",
"",
0
],
[
"UserStreet",
"Street",
"street",
1,
0,
"var",
"",
0
],
[
"UserZip",
"Zip",
"zip",
1,
0,
"var",
"",
0
],
[
"UserCity",
"City",
"city",
1,
0,
"var",
"",
0
],
[
"UserCountry",
"Country",
"country",
1,
0,
"var",
"",
0
],
[
"UserComment",
"Comment",
"comments",
1,
0,
"var",
"",
0
],
[
"ValidID",
"Valid",
"valid_id",
0,
1,
"int",
"",
0
]
],
"CustomerKey": "login",
"CustomerUserSearchSuffix": "*",
"Module": "Kernel::System::CustomerUser::DB",
"CacheTTL": 86400,
"Selections": {},
"CustomerID": "customer_id",
"Name": "Database Backend",
"CustomerUserPostMasterSearchFields": [
"email"
],
"CustomerUserNameFields": [
"title",
"first_name",
"last_name"
]
},
"UserCustomerID": "test712259",
"CustomerCompanyComment": "test712259",
"Source": "CustomerUser",
"UserTitle": "",
"CompanyConfig": {
"CustomerCompanySearchFields": [
"customer_id",
"name"
],
"CustomerCompanyListFields": [
"customer_id",
"name"
],
"Module": "Kernel::System::CustomerCompany::DB",
"CustomerCompanyKey": "customer_id",
"CustomerCompanySearchSuffix": "*",
"CacheTTL": 86400,
"CustomerCompanySearchListLimit": 250,
"CustomerCompanySearchPrefix": "",
"CustomerCompanyValid": "valid_id",
"Params": {
"Table": "customer_company",
"CaseSensitive": 0
},
"Map": [
[
"CustomerID",
"CustomerID",
"customer_id",
0,
1,
"var",
"",
0
],
[
"CustomerCompanyName",
"Customer",
"name",
1,
1,
"var",
"",
0
],
[
"CustomerCompanyStreet",
"Street",
"street",
1,
0,
"var",
"",
0
],
[
"CustomerCompanyZIP",
"Zip",
"zip",
1,
0,
"var",
"",
0
],
[
"CustomerCompanyCity",
"City",
"city",
1,
0,
"var",
"",
0
],
[
"CustomerCompanyCountry",
"Country",
"country",
1,
0,
"var",
"",
0
],
[
"CustomerCompanyURL",
"URL",
"url",
1,
0,
"var",
"[% Data.CustomerCompanyURL | html %]",
0
],
[
"CustomerCompanyComment",
"Comment",
"comments",
1,
0,
"var",
"",
0
],
[
"ValidID",
"Valid",
"valid_id",
0,
1,
"int",
"",
0
]
],
"Name": "Database Backend"
},
"UserZip": null,
"UserLastname": "test669673",
"ChangeBy": "1",
"CreateTime": "2014-06-07 02:31:31",
"UserLogin": "TeSt669673",
"UserPhone": null,
"CustomerID": "test712259",
"CustomerCompanyValidID": "1",
"CustomerCompanyZIP": "test712259",
"UserCountry": null,
"UserPassword": "f8be19af2f25837a31eff9131b0e47a5173290652c04a48b49b86474d48825ee",
"ValidID": "1",
"UserRefreshTime": "0",
"UserEmail": "QA100@t-Online.de",
"UserComment": "",
"UserID": "test669673",
"UserFirstname": "test669673",
"CustomerCompanyCountry": "test712259",
"UserFax": null,
"CreateBy": "1",
"ChangeTime": "2014-06-07 02:31:31",
"UserShowTickets": "25",
"UserStreet": null,
"CustomerCompanyURL": "test712259",
"CustomerCompanyName": "test712259",
"UserMobile": null,
"CustomerCompanyStreet": "test712259",
"UserCity": null
}

View File

@@ -0,0 +1,135 @@
{
"OutOfOffice": "1",
"OutOfOfficeStartMonth": "9",
"UserStoredFilterColumns-AgentTicketLockedView": "{}",
"UserTicketOverviewSmallPageShown": "35",
"UserCreateWorkOrderNextMask": "AgentITSMWorkOrderZoom",
"OutOfOfficeEndYear": "2014",
"UserDashboardTicketGenericFilter0110-TicketEscalation": "All",
"UserDashboardPref0120-TicketNew-Columns": "{\"Columns\":{\"Changed\":0,\"CustomerID\":0,\"CustomerName\":0,\"CustomerUserID\":0,\"DynamicField_CustomerLocation\":0,\"EscalationResponseTime\":0,\"EscalationSolutionTime\":0,\"EscalationTime\":0,\"EscalationUpdateTime\":0,\"Lock\":0,\"Owner\":0,\"PendingTime\":0,\"Priority\":0,\"Responsible\":0,\"SLA\":0,\"State\":0,\"Type\":0,\"Age\":1,\"Title\":1,\"Queue\":1,\"Service\":1,\"TicketNumber\":1},\"Order\":[\"Age\",\"Title\",\"Queue\",\"Service\",\"TicketNumber\"]}",
"UserLastUsedZoomViewType": "",
"OutOfOfficeStartDay": "10",
"UserStoredFilterColumns-AgentTicketStatusView": "{}",
"UserTitle": null,
"UserLastname": "OTRS",
"UserTicketOverviewMediumPageShown": "20",
"OutOfOfficeEndDay": "12",
"CreateTime": "2014-04-28 10:53:18",
"UserTicketOverviewPreviewPageShown": "15",
"UserLogin": "rOoT@LoCaLhOsT",
"UserFilterColumnsEnabled-AgentTicketEscalationView": "[\"TicketNumber\",\"Age\",\"EscalationTime\",\"EscalationResponseTime\",\"EscalationSolutionTime\",\"EscalationUpdateTime\",\"Title\",\"State\",\"Lock\",\"Queue\",\"Owner\",\"CustomerID\"]",
"UserLanguage": "de",
"UserDashboardPref0110-TicketEscalation-Columns": "{\"Columns\":{\"Changed\":0,\"CustomerID\":0,\"CustomerUserID\":0,\"EscalationResponseTime\":0,\"EscalationSolutionTime\":0,\"EscalationTime\":0,\"EscalationUpdateTime\":0,\"Lock\":0,\"Owner\":0,\"PendingTime\":0,\"Priority\":0,\"Queue\":0,\"Responsible\":0,\"SLA\":0,\"Service\":0,\"State\":0,\"Type\":0,\"Age\":1,\"Title\":1,\"CustomerName\":1,\"TicketNumber\":1},\"Order\":[\"Age\",\"Title\",\"CustomerName\",\"TicketNumber\"]}",
"OutOfOfficeStartYear": "2014",
"UserDashboardPref0120-TicketNew-Shown": "10",
"UserFullname": "Admin OTRS",
"UserLastLoginTimestamp": "2016-08-10 19:37:44",
"UserLastLogin": "1470850664",
"UserMarkTicketUnseenRedirectURL": "Action=AgentTicketZoom;TicketID=###TicketID####1",
"AdminDynamicFieldsOverviewPageShown": "35",
"UserChangeOverviewSmallPageShown": "25",
"RoleIDs": [],
"ValidID": "1",
"UserStoredFilterColumns-AgentTicketQueue": "{}",
"UserEmail": "ROOT@loCalhosT",
"UserRefreshTime": "0",
"UserDashboardPref0130-TicketOpen-Shown": "10",
"UserTicketOverviewAgentTicketQueue": "Small",
"UserID": "1",
"UserDashboardTicketGenericColumnFiltersRealKeys0120-TicketNew": "{\"QueueIDs\":[\"1\"]}",
"wpt22": "1",
"UserMarkTicketSeenRedirectURL": "Action=AgentTicketZoom;TicketID=###TicketID####1",
"UserStoredFilterColumns-AgentTicketEscalationView": "{}",
"UserDashboardTicketGenericFilter0120-TicketNew": "MyQueues",
"UserCreateNextMask": "",
"UserFirstname": "Admin",
"UserPw": "9faaba2ab242a99bbb6992e9424386375f6757c17e6484ae570f39d9cad9f28ea",
"UserDashboardPref0110-TicketEscalation-Shown": "10",
"UserFilterColumnsEnabled-AgentTicketQueue": "[\"TicketNumber\",\"Age\",\"Title\",\"State\",\"Lock\",\"DynamicField_CustomerLocation\",\"Queue\",\"Owner\",\"CustomerID\",\"DynamicField_Hostname\"]",
"OutOfOfficeEndMonth": "9",
"ChangeTime": "2014-04-28 10:53:18",
"UserDashboardPref0130-TicketOpen-Columns": "{\"Columns\":{\"Changed\":0,\"CustomerID\":0,\"CustomerUserID\":0,\"EscalationResponseTime\":0,\"EscalationTime\":0,\"EscalationUpdateTime\":0,\"Lock\":0,\"Owner\":0,\"PendingTime\":0,\"Priority\":0,\"Queue\":0,\"Responsible\":0,\"SLA\":0,\"Service\":0,\"State\":0,\"Type\":0,\"Age\":1,\"DynamicField_CustomerLocation\":1,\"Title\":1,\"CustomerName\":1,\"EscalationSolutionTime\":1,\"TicketNumber\":1},\"Order\":[\"Age\",\"DynamicField_CustomerLocation\",\"Title\",\"CustomerName\",\"EscalationSolutionTime\",\"TicketNumber\"]}",
"UserTicketOverviewAgentTicketSearch": "Small",
"UserTicketOverviewAgentCustomerSearch": "Small",
"UserDashboardTicketGenericColumnFilters0120-TicketNew": "{\"Queue\":\"1\"}",
"GroupIDs": {
"6": [
"ro",
"move_into",
"create",
"note",
"owner",
"priority",
"rw"
],
"3": [
"ro",
"move_into",
"create",
"note",
"owner",
"priority",
"rw"
],
"7": [
"ro",
"move_into",
"create",
"note",
"owner",
"priority",
"rw"
],
"2": [
"ro",
"move_into",
"create",
"note",
"owner",
"priority",
"rw"
],
"8": [
"ro",
"move_into",
"create",
"note",
"owner",
"priority",
"rw"
],
"1": [
"ro",
"move_into",
"create",
"note",
"owner",
"priority",
"rw"
],
"4": [
"ro",
"move_into",
"create",
"note",
"owner",
"priority",
"rw"
],
"5": [
"ro",
"move_into",
"create",
"note",
"owner",
"priority",
"rw"
]
},
"UserConfigItemOverviewSmallPageShown": "25",
"UserAuthBackend": "",
"UserTicketOverviewAgentTicketLockedView": "Small",
"UserTicketOverviewAgentTicketEscalationView": "Small",
"UserTicketOverviewAgentTicketStatusView": "Small",
"UserLoginFailed": "0"
}

View File

@@ -158,4 +158,42 @@ RSpec.describe Import::OTRS::CustomerUser do
updates_with(zammad_structure)
end
end
context 'regular user with camelcase login' do
let(:object_structure) { load_customer_json('camel_case_login') }
let(:zammad_structure) do
{
created_by_id: '1',
updated_by_id: '1',
active: true,
source: 'OTRS Import',
organization_id: 1337,
role_ids: [3],
updated_at: '2014-06-07 02:31:31',
created_at: '2014-06-07 02:31:31',
note: '',
email: 'qa100@t-online.de',
firstname: 'test669673',
lastname: 'test669673',
login: 'test669673',
password: 'f8be19af2f25837a31eff9131b0e47a5173290652c04a48b49b86474d48825ee',
phone: nil,
fax: nil,
mobile: nil,
street: nil,
zip: nil,
city: nil,
country: nil
}
end
it 'creates' do
creates_with(zammad_structure)
end
it 'updates' do
updates_with(zammad_structure)
end
end
end

View File

@@ -166,4 +166,38 @@ RSpec.describe Import::OTRS::User do
updates_with(zammad_structure)
end
end
context 'regular user with camel case login' do
let(:object_structure) { load_user_json('camel_case_login') }
let(:zammad_structure) do
{
created_by_id: 1,
updated_by_id: 1,
active: true,
source: 'OTRS Import',
role_ids: [2, 1],
group_ids: ['1'],
password: '{sha2}9faaba2ab242a99bbb6992e9424386375f6757c17e6484ae570f39d9cad9f28ea',
updated_at: '2014-04-28 10:53:18',
created_at: '2014-04-28 10:53:18',
id: '1',
email: 'root@localhost',
firstname: 'Admin',
lastname: 'OTRS',
login: 'root@localhost'
}
end
it 'creates' do
prepare_expectations
creates_with(zammad_structure)
end
it 'updates' do
prepare_expectations
updates_with(zammad_structure)
end
end
end

17
test/fixtures/mail65.box vendored Normal file
View File

@@ -0,0 +1,17 @@
From: =?iso-8859-1?Q?B=FCrling,=20Andreas?= <smith@example.com>
Content-Type: text/plain;
charset=iso-8859-1
Content-Transfer-Encoding: quoted-printable
Subject: =?iso-8859-1?Q?aa=E4=F6=FC=DFad_asd?=
X-Universally-Unique-Identifier: d12c15d2-e6d6-4ccd-86c7-abc2c3d0a2a2
Date: Fri, 4 May 2012 14:01:03 +0200
Message-Id: <BC182994-03FA-4DC5-8202-98CBFACA0887@example.com>
To: metest@znuny.com
Mime-Version: 1.0 (Apple Message framework v1257)
=E4=F6=FC=DF ad asd
-Martin
--
Old programmers never die. They just branch to a new address.

View File

@@ -136,8 +136,8 @@ class ReportTest < ActiveSupport::TestCase
state: Ticket::State.lookup(name: 'closed'),
priority: Ticket::Priority.lookup(name: '2 normal'),
close_at: '2015-10-28 11:30:00 UTC',
created_at: '2015-10-28 10:30:00 UTC',
updated_at: '2015-10-28 10:30:00 UTC',
created_at: '2015-10-28 10:30:01 UTC',
updated_at: '2015-10-28 10:30:01 UTC',
updated_by_id: 1,
created_by_id: 1,
)
@@ -151,8 +151,8 @@ class ReportTest < ActiveSupport::TestCase
internal: false,
sender: Ticket::Article::Sender.where(name: 'Customer').first,
type: Ticket::Article::Type.where(name: 'email').first,
created_at: '2015-10-28 10:30:00 UTC',
updated_at: '2015-10-28 10:30:00 UTC',
created_at: '2015-10-28 10:30:01 UTC',
updated_at: '2015-10-28 10:30:01 UTC',
updated_by_id: 1,
created_by_id: 1,
)
@@ -245,6 +245,34 @@ class ReportTest < ActiveSupport::TestCase
created_by_id: 1,
)
@ticket8 = Ticket.create!(
title: 'test 8',
group: group1,
customer_id: 2,
state: Ticket::State.lookup(name: 'merged'),
priority: Ticket::Priority.lookup(name: '2 normal'),
close_at: '2015-11-02 12:30:00 UTC',
created_at: '2015-11-02 12:30:00 UTC',
updated_at: '2015-11-02 12:30:00 UTC',
updated_by_id: 1,
created_by_id: 1,
)
Ticket::Article.create!(
ticket_id: @ticket8.id,
from: 'some_sender@example.com',
to: 'some_recipient@example.com',
subject: 'some subject',
message_id: 'some@id',
body: 'some message article_outbound',
internal: false,
sender: Ticket::Article::Sender.where(name: 'Agent').first,
type: Ticket::Article::Type.where(name: 'email').first,
created_at: '2015-11-02 12:30:00 UTC',
updated_at: '2015-11-02 12:30:00 UTC',
updated_by_id: 1,
created_by_id: 1,
)
# execute background jobs
Scheduler.worker(true)
@@ -276,7 +304,7 @@ class ReportTest < ActiveSupport::TestCase
assert_equal(0, result[7])
assert_equal(0, result[8])
assert_equal(2, result[9])
assert_equal(1, result[10])
assert_equal(2, result[10])
assert_equal(0, result[11])
assert_nil(result[12])
@@ -289,7 +317,8 @@ class ReportTest < ActiveSupport::TestCase
assert_equal(@ticket5.id, result[:ticket_ids][0])
assert_equal(@ticket6.id, result[:ticket_ids][1])
assert_equal(@ticket7.id, result[:ticket_ids][2])
assert_nil(result[:ticket_ids][3])
assert_equal(@ticket8.id, result[:ticket_ids][3])
assert_nil(result[:ticket_ids][4])
# month - with selector #1
result = Report::TicketFirstSolution.aggs(
@@ -332,6 +361,47 @@ class ReportTest < ActiveSupport::TestCase
assert_equal(@ticket5.id, result[:ticket_ids][0])
assert_nil(result[:ticket_ids][1])
# month - with merged tickets selector
result = Report::TicketFirstSolution.aggs(
range_start: '2015-01-01T00:00:00Z',
range_end: '2015-12-31T23:59:59Z',
interval: 'month', # year, quarter, month, week, day, hour, minute, second
selector: {
'ticket_state.name' => {
'operator' => 'is not',
'value' => 'merged',
}
}, # ticket selector to get only a collection of tickets
)
assert(result)
assert_equal(0, result[0])
assert_equal(0, result[1])
assert_equal(0, result[2])
assert_equal(0, result[3])
assert_equal(0, result[4])
assert_equal(0, result[5])
assert_equal(0, result[6])
assert_equal(0, result[7])
assert_equal(0, result[8])
assert_equal(2, result[9])
assert_equal(1, result[10])
assert_equal(0, result[11])
assert_nil(result[12])
result = Report::TicketFirstSolution.items(
range_start: '2015-01-01T00:00:00Z',
range_end: '2015-12-31T23:59:59Z',
selector: {
'ticket_state.name' => {
'operator' => 'is not',
'value' => 'merged',
}
}, # ticket selector to get only a collection of tickets
)
assert(result)
assert_equal(@ticket5.id, result[:ticket_ids][0])
assert_nil(result[:ticket_ids][3])
# month - with selector #2
result = Report::TicketFirstSolution.aggs(
range_start: '2015-01-01T00:00:00Z',
@@ -355,7 +425,7 @@ class ReportTest < ActiveSupport::TestCase
assert_equal(0, result[7])
assert_equal(0, result[8])
assert_equal(1, result[9])
assert_equal(1, result[10])
assert_equal(2, result[10])
assert_equal(0, result[11])
assert_nil(result[12])
@@ -372,7 +442,8 @@ class ReportTest < ActiveSupport::TestCase
assert(result)
assert_equal(@ticket6.id, result[:ticket_ids][0])
assert_equal(@ticket7.id, result[:ticket_ids][1])
assert_nil(result[:ticket_ids][2])
assert_equal(@ticket8.id, result[:ticket_ids][2])
assert_nil(result[:ticket_ids][3])
# week
result = Report::TicketFirstSolution.aggs(
@@ -611,6 +682,94 @@ class ReportTest < ActiveSupport::TestCase
assert(result)
assert_nil(result[:ticket_ids][0])
# month - reopened with merge selector
result = Report::TicketReopened.aggs(
range_start: '2015-01-01T00:00:00Z',
range_end: '2015-12-31T23:59:59Z',
interval: 'month', # year, quarter, month, week, day, hour, minute, second
selector: {
'ticket_state.name' => {
'operator' => 'is not',
'value' => 'merged',
}
}, # ticket selector to get only a collection of tickets
)
assert(result)
assert_equal(0, result[0])
assert_equal(0, result[1])
assert_equal(0, result[2])
assert_equal(0, result[3])
assert_equal(0, result[4])
assert_equal(0, result[5])
assert_equal(0, result[6])
assert_equal(0, result[7])
assert_equal(0, result[8])
assert_equal(1, result[9])
assert_equal(0, result[10])
assert_equal(0, result[11])
assert_nil(result[12])
result = Report::TicketReopened.items(
range_start: '2015-01-01T00:00:00Z',
range_end: '2015-12-31T23:59:59Z',
selector: {
'ticket_state.name' => {
'operator' => 'is not',
'value' => 'merged',
}
}, # ticket selector to get only a collection of tickets
)
assert(result)
assert_equal(@ticket5.id, result[:ticket_ids][0])
assert_nil(result[:ticket_ids][1])
# move in/out without merged status
result = Report::TicketMoved.aggs(
range_start: '2015-01-01T00:00:00Z',
range_end: '2015-12-31T23:59:59Z',
interval: 'month', # year, quarter, month, week, day, hour, minute, second
selector: {
'ticket_state.name' => {
'operator' => 'is not',
'value' => 'merged',
}
}, # ticket selector to get only a collection of tickets
params: {
type: 'in',
},
)
assert(result)
assert_equal(0, result[0])
assert_equal(0, result[1])
assert_equal(0, result[2])
assert_equal(0, result[3])
assert_equal(0, result[4])
assert_equal(0, result[5])
assert_equal(0, result[6])
assert_equal(0, result[7])
assert_equal(0, result[8])
assert_equal(0, result[9])
assert_equal(0, result[10])
assert_equal(0, result[11])
assert_nil(result[12])
result = Report::TicketMoved.items(
range_start: '2015-01-01T00:00:00Z',
range_end: '2015-12-31T23:59:59Z',
selector: {
'ticket.group_id' => {
'operator' => 'is',
'value' => [Group.lookup(name: 'Users').id],
}
}, # ticket selector to get only a collection of tickets
params: {
type: 'in',
},
)
assert(result)
assert_equal(@ticket1.id, result[:ticket_ids][0])
assert_nil(result[:ticket_ids][1])
# move in/out
result = Report::TicketMoved.aggs(
range_start: '2015-01-01T00:00:00Z',
@@ -658,6 +817,52 @@ class ReportTest < ActiveSupport::TestCase
assert_equal(@ticket1.id, result[:ticket_ids][0])
assert_nil(result[:ticket_ids][1])
# out without merged tickets
result = Report::TicketMoved.aggs(
range_start: '2015-01-01T00:00:00Z',
range_end: '2015-12-31T23:59:59Z',
interval: 'month', # year, quarter, month, week, day, hour, minute, second
selector: {
'ticket_state.name' => {
'operator' => 'is not',
'value' => 'merged',
}
}, # ticket selector to get only a collection of tickets
params: {
type: 'out',
},
)
assert(result)
assert_equal(0, result[0])
assert_equal(0, result[1])
assert_equal(0, result[2])
assert_equal(0, result[3])
assert_equal(0, result[4])
assert_equal(0, result[5])
assert_equal(0, result[6])
assert_equal(0, result[7])
assert_equal(0, result[8])
assert_equal(0, result[9])
assert_equal(0, result[10])
assert_equal(0, result[11])
assert_nil(result[12])
result = Report::TicketMoved.items(
range_start: '2015-01-01T00:00:00Z',
range_end: '2015-12-31T23:59:59Z',
selector: {
'ticket_state.name' => {
'operator' => 'is not',
'value' => 'merged',
}
}, # ticket selector to get only a collection of tickets
params: {
type: 'out',
},
)
assert(result)
assert_nil(result[:ticket_ids][0])
# out
result = Report::TicketMoved.aggs(
range_start: '2015-01-01T00:00:00Z',
@@ -724,7 +929,7 @@ class ReportTest < ActiveSupport::TestCase
assert_equal(0, result[7])
assert_equal(0, result[8])
assert_equal(6, result[9])
assert_equal(1, result[10])
assert_equal(2, result[10])
assert_equal(0, result[11])
assert_nil(result[12])
@@ -735,12 +940,62 @@ class ReportTest < ActiveSupport::TestCase
params: { field: 'created_at' },
)
assert(result)
assert_equal(@ticket8.id, result[:ticket_ids][0].to_i)
assert_equal(@ticket7.id, result[:ticket_ids][1].to_i)
assert_equal(@ticket6.id, result[:ticket_ids][2].to_i)
assert_equal(@ticket5.id, result[:ticket_ids][3].to_i)
assert_equal(@ticket4.id, result[:ticket_ids][4].to_i)
assert_equal(@ticket3.id, result[:ticket_ids][5].to_i)
assert_equal(@ticket2.id, result[:ticket_ids][6].to_i)
assert_equal(@ticket1.id, result[:ticket_ids][7].to_i)
assert_nil(result[:ticket_ids][8])
# create at - selector with merge
result = Report::TicketGenericTime.aggs(
range_start: '2015-01-01T00:00:00Z',
range_end: '2015-12-31T23:59:59Z',
interval: 'month', # year, quarter, month, week, day, hour, minute, second
selector: {
'state' => {
'operator' => 'is not',
'value' => 'merged'
}
}, # ticket selector to get only a collection of tickets
params: { field: 'created_at' },
)
assert(result)
assert_equal(0, result[0])
assert_equal(0, result[1])
assert_equal(0, result[2])
assert_equal(0, result[3])
assert_equal(0, result[4])
assert_equal(0, result[5])
assert_equal(0, result[6])
assert_equal(0, result[7])
assert_equal(0, result[8])
assert_equal(6, result[9])
assert_equal(1, result[10])
assert_equal(0, result[11])
assert_nil(result[12])
result = Report::TicketGenericTime.items(
range_start: '2015-01-01T00:00:00Z',
range_end: '2015-12-31T23:59:59Z',
selector: {
'state' => {
'operator' => 'is not',
'value' => 'merged'
}
}, # ticket selector to get only a collection of tickets
params: { field: 'created_at' },
)
assert(result)
assert_equal(@ticket7.id, result[:ticket_ids][0].to_i)
assert_equal(@ticket6.id, result[:ticket_ids][1].to_i)
assert_equal(@ticket5.id, result[:ticket_ids][2].to_i)
assert_equal(@ticket3.id, result[:ticket_ids][3].to_i)
assert_equal(@ticket4.id, result[:ticket_ids][4].to_i)
assert_equal(@ticket4.id, result[:ticket_ids][3].to_i)
assert_equal(@ticket3.id, result[:ticket_ids][4].to_i)
assert_equal(@ticket2.id, result[:ticket_ids][5].to_i)
assert_equal(@ticket1.id, result[:ticket_ids][6].to_i)
assert_nil(result[:ticket_ids][7])

View File

@@ -203,6 +203,74 @@ Some Text",
],
},
},
{
data: "From: sender@example.com
To: some_new_customer423@example.com
Cc: some recipient <some with invalid@example.com>, max <somebody_else@example.com>
Subject: abc some subject2
Some Text",
success: true,
result: {
0 => {
priority: '2 normal',
title: 'abc some subject2',
},
1 => {
body: 'Some Text',
sender: 'Customer',
type: 'email',
internal: false,
},
},
verify: {
users: [
{
firstname: 'max',
lastname: '',
fullname: 'max',
email: 'somebody_else@example.com',
},
{
firstname: '',
lastname: '',
fullname: 'some_new_customer423@example.com',
email: 'some_new_customer423@example.com',
},
],
},
},
{
data: "From: sender@example.com
To: some_new_customer424@example.com
Subject: abc some subject3
Reply-To: some user <no-reply-with invalid-spaces@example.com>
Some Text",
success: true,
result: {
0 => {
priority: '2 normal',
title: 'abc some subject3',
},
1 => {
body: 'Some Text',
sender: 'Customer',
type: 'email',
internal: false,
},
},
verify: {
users: [
{
firstname: '',
lastname: '',
fullname: 'some_new_customer424@example.com',
email: 'some_new_customer424@example.com',
},
],
},
},
{
data: "From: me@example.com
To: Alexander Ha <service-d1@example.com>,
@@ -2601,6 +2669,38 @@ Some Text',
],
},
},
{
data: IO.binread('test/fixtures/mail65.box'),
success: true,
result: {
0 => {
priority: '2 normal',
title: 'aaäöüßad asd',
},
1 => {
from: '=?iso-8859-1?Q?B=FCrling, =20Andreas?= <smith@example.com>',
sender: 'Customer',
type: 'email',
body: 'äöüß ad asd
-Martin
--
Old programmers never die. They just branch to a new address.
',
},
},
verify: {
users: [
{
firstname: '=20Andreas?=',
lastname: '',
fullname: '=20Andreas?=',
email: 'smith@example.com',
},
],
},
},
]
assert_process(files)
end
@@ -2812,9 +2912,9 @@ Some Text',
# verify if users are created
if file[:verify][:users]
file[:verify][:users].each { |user_result|
user = User.where(email: user_result[:email]).first
user = User.where(email: user_result[:email].downcase).first
if !user
assert(false, "No user '#{user_result[:email]}' found!")
assert(false, "No user '#{user_result[:email].downcase}' found!")
return
end
user_result.each { |key, value|

View File

@@ -73,9 +73,9 @@ class RoleValidateAgentLimit < ActiveSupport::TestCase
test 'role validate agent limit - 1 user 2 ticket.agent roles' do
agent_max = User.with_permissions('ticket.agent').count
current_agent_max = User.with_permissions('ticket.agent').count + 1
UserInfo.current_user_id = 1
Setting.set('system_agent_limit', agent_max + 1)
Setting.set('system_agent_limit', current_agent_max)
permission_ticket_agent = Permission.find_by(name: 'ticket.agent')
@@ -107,6 +107,8 @@ class RoleValidateAgentLimit < ActiveSupport::TestCase
user1.role_ids = [Role.find_by(name: 'Agent').id, role_agent_limit1.id]
user1.role_ids = [Role.find_by(name: 'Agent').id, role_agent_limit1.id, role_agent_limit2.id]
assert_raises(Exceptions::UnprocessableEntity) do
user2 = User.create!(
firstname: 'Firstname2',
@@ -118,6 +120,20 @@ class RoleValidateAgentLimit < ActiveSupport::TestCase
)
end
assert_equal(current_agent_max, User.with_permissions('ticket.agent').count)
current_agent_max = User.with_permissions('ticket.agent').count + 1
Setting.set('system_agent_limit', current_agent_max)
user3 = User.create!(
firstname: 'Firstname',
lastname: 'Lastname',
email: 'some-agentlimit-role-3@example.com',
login: 'some-agentlimit-role-3@example.com',
role_ids: [Role.find_by(name: 'Agent').id],
active: true,
)
role_agent_limit1.destroy!
role_agent_limit2.destroy!
Setting.set('system_agent_limit', nil)

View File

@@ -0,0 +1,162 @@
require 'test_helper'
class TicketNumberTest < ActiveSupport::TestCase
test 'number' do
Setting.set('ticket_number_increment', { checksum: false, min_size: 5 })
Setting.set('system_id', 1)
number = Ticket::Number.generate
assert_equal(number.to_s.length, 5)
Setting.set('ticket_number_increment', { checksum: false, min_size: 10 })
Setting.set('system_id', 1)
number = Ticket::Number.generate
assert_equal(number.to_s.length, 10)
Setting.set('ticket_number_increment', { checksum: true, min_size: 5 })
Setting.set('system_id', 1)
number = Ticket::Number.generate
assert_equal(number.to_s.length, 5)
Setting.set('ticket_number_increment', { checksum: true, min_size: 10 })
Setting.set('system_id', 1)
number = Ticket::Number.generate
assert_equal(number.to_s.length, 10)
Setting.set('ticket_number_increment', { checksum: false, min_size: 5 })
Setting.set('system_id', 88)
number = Ticket::Number.generate
assert_equal(number.to_s.length, 5)
Setting.set('ticket_number_increment', { checksum: false, min_size: 10 })
Setting.set('system_id', 88)
number = Ticket::Number.generate
assert_equal(number.to_s.length, 10)
Setting.set('ticket_number_increment', { checksum: true, min_size: 5 })
Setting.set('system_id', 88)
number = Ticket::Number.generate
assert_equal(number.to_s.length, 5)
Setting.set('ticket_number_increment', { checksum: true, min_size: 10 })
Setting.set('system_id', 88)
number = Ticket::Number.generate
assert_equal(number.to_s.length, 10)
150.times do
number = Ticket::Number.generate
assert_equal(number.to_s.length, 10)
end
end
test 'number check' do
Setting.set('ticket_number_increment', { checksum: false, min_size: 5 })
ticket = Ticket.create!(
title: 'test 1',
group: Group.lookup(name: 'Users'),
customer_id: 2,
state: Ticket::State.lookup(name: 'new'),
priority: Ticket::Priority.lookup(name: '2 normal'),
updated_by_id: 1,
created_by_id: 1,
)
subject = ticket.subject_build(ticket.title)
ticket_check = Ticket::Number.check(subject)
assert_equal(ticket.id, ticket_check.id)
Setting.set('system_id', 999)
ticket_check = Ticket::Number.check(subject)
assert_not(ticket_check)
Setting.set('ticket_number_ignore_system_id', true)
ticket_check = Ticket::Number.check(subject)
assert_equal(ticket.id, ticket_check.id)
end
test 'date' do
Setting.set('ticket_number', 'Ticket::Number::Date')
Setting.set('ticket_number_date', { checksum: false })
Setting.set('system_id', 1)
system_id = Setting.get('system_id')
number_prefix = "#{Time.zone.now.strftime('%Y%m%d')}#{system_id}"
number = Ticket::Number.generate
assert_equal(number.to_s.length, 13)
assert_match(/#{number_prefix}/, number.to_s)
Setting.set('ticket_number_date', { checksum: false })
Setting.set('system_id', 88)
number = Ticket::Number.generate
system_id = Setting.get('system_id')
number_prefix = "#{Time.zone.now.strftime('%Y%m%d')}#{system_id}"
assert_equal(number.to_s.length, 14)
assert_match(/#{number_prefix}/, number.to_s)
Setting.set('ticket_number_date', { checksum: true })
Setting.set('system_id', 1)
number = Ticket::Number.generate
system_id = Setting.get('system_id')
number_prefix = "#{Time.zone.now.strftime('%Y%m%d')}#{system_id}"
assert_equal(number.to_s.length, 14)
assert_match(/#{number_prefix}/, number.to_s)
Setting.set('ticket_number_date', { checksum: true })
Setting.set('system_id', 88)
number = Ticket::Number.generate
system_id = Setting.get('system_id')
number_prefix = "#{Time.zone.now.strftime('%Y%m%d')}#{system_id}"
assert_equal(number.to_s.length, 15)
assert_match(/#{number_prefix}/, number.to_s)
150.times do
number = Ticket::Number.generate
assert_equal(number.to_s.length, 15)
end
end
test 'date check' do
Setting.set('ticket_number', 'Ticket::Number::Date')
Setting.set('ticket_number_date', { checksum: false })
ticket = Ticket.create!(
title: 'test 1',
group: Group.lookup(name: 'Users'),
customer_id: 2,
state: Ticket::State.lookup(name: 'new'),
priority: Ticket::Priority.lookup(name: '2 normal'),
updated_by_id: 1,
created_by_id: 1,
)
subject = ticket.subject_build(ticket.title)
ticket_check = Ticket::Number.check(subject)
assert_equal(ticket.id, ticket_check.id)
Setting.set('system_id', 999)
ticket_check = Ticket::Number.check(subject)
assert_not(ticket_check)
Setting.set('ticket_number_ignore_system_id', true)
ticket_check = Ticket::Number.check(subject)
assert_equal(ticket.id, ticket_check.id)
end
end

View File

@@ -3480,4 +3480,549 @@ class TicketTriggerTest < ActiveSupport::TestCase
end
test '4 tag based auto response' do
trigger1 = Trigger.create_or_update(
name: '100 add tag if sender 1',
condition: {
'ticket.action' => {
'operator' => 'is',
'value' => 'create',
},
'article.from' => {
'operator' => 'contains',
'value' => 'sender1',
},
},
perform: {
'ticket.tags' => {
'operator' => 'add',
'value' => 'sender1',
},
},
disable_notification: true,
active: true,
created_by_id: 1,
updated_by_id: 1,
)
trigger2 = Trigger.create_or_update(
name: '200 add tag if sender 2',
condition: {
'ticket.action' => {
'operator' => 'is',
'value' => 'create',
},
'article.from' => {
'operator' => 'contains',
'value' => 'sender2',
},
},
perform: {
'ticket.tags' => {
'operator' => 'add',
'value' => 'sender2',
},
},
disable_notification: true,
active: true,
created_by_id: 1,
updated_by_id: 1,
)
trigger3 = Trigger.create_or_update(
name: '300 auto reply',
condition: {
'ticket.action' => {
'operator' => 'is',
'value' => 'create',
},
'ticket.state_id' => {
'operator' => 'is',
'value' => Ticket::State.lookup(name: 'new').id.to_s,
},
'ticket.tags' => {
#'operator' => 'contains one not',
'operator' => 'contains all not',
'value' => 'sender1, sender2',
},
},
perform: {
'notification.email' => {
'body' => 'some text<br>#{ticket.customer.lastname}<br>#{ticket.title}<br>#{article.body}',
'recipient' => 'ticket_customer',
'subject' => 'Thanks for your inquiry (#{ticket.title})!',
},
},
disable_notification: true,
active: true,
created_by_id: 1,
updated_by_id: 1,
)
ticket1 = Ticket.create!(
title: 'test 1',
group: Group.lookup(name: 'Users'),
customer: User.lookup(email: 'nicole.braun@zammad.org'),
updated_by_id: 1,
created_by_id: 1,
)
Ticket::Article.create!(
ticket_id: ticket1.id,
from: 'sender1@example.com',
to: 'some_recipient@example.com',
subject: 'some subject',
message_id: 'some@id',
body: "some message <b>note</b>\nnew line",
internal: false,
sender: Ticket::Article::Sender.find_by(name: 'Customer'),
type: Ticket::Article::Type.find_by(name: 'email'),
updated_by_id: 1,
created_by_id: 1,
)
ticket1.reload
assert_equal('test 1', ticket1.title, 'ticket1.title verify')
assert_equal('Users', ticket1.group.name, 'ticket1.group verify')
assert_equal('new', ticket1.state.name, 'ticket1.state verify')
assert_equal('2 normal', ticket1.priority.name, 'ticket1.priority verify')
assert_equal(1, ticket1.articles.count, 'ticket1.articles verify')
assert_equal([], ticket1.tag_list)
Observer::Transaction.commit
ticket1.reload
assert_equal('test 1', ticket1.title, 'ticket1.title verify')
assert_equal('Users', ticket1.group.name, 'ticket1.group verify')
assert_equal('new', ticket1.state.name, 'ticket1.state verify')
assert_equal('2 normal', ticket1.priority.name, 'ticket1.priority verify')
assert_equal(1, ticket1.articles.count, 'ticket1.articles verify')
assert_equal(%w[sender1], ticket1.tag_list)
ticket2 = Ticket.create!(
title: 'test 2',
group: Group.lookup(name: 'Users'),
customer: User.lookup(email: 'nicole.braun@zammad.org'),
updated_by_id: 1,
created_by_id: 1,
)
Ticket::Article.create!(
ticket_id: ticket2.id,
from: 'sender2@example.com',
to: 'some_recipient@example.com',
subject: 'some subject',
message_id: 'some@id',
body: "some message <b>note</b>\nnew line",
internal: false,
sender: Ticket::Article::Sender.find_by(name: 'Customer'),
type: Ticket::Article::Type.find_by(name: 'email'),
updated_by_id: 1,
created_by_id: 1,
)
ticket2.reload
assert_equal('test 2', ticket2.title, 'ticket2.title verify')
assert_equal('Users', ticket2.group.name, 'ticket2.group verify')
assert_equal('new', ticket2.state.name, 'ticket2.state verify')
assert_equal('2 normal', ticket2.priority.name, 'ticket2.priority verify')
assert_equal(1, ticket2.articles.count, 'ticket2.articles verify')
assert_equal([], ticket2.tag_list)
Observer::Transaction.commit
ticket2.reload
assert_equal('test 2', ticket2.title, 'ticket2.title verify')
assert_equal('Users', ticket2.group.name, 'ticket2.group verify')
assert_equal('new', ticket2.state.name, 'ticket2.state verify')
assert_equal('2 normal', ticket2.priority.name, 'ticket2.priority verify')
assert_equal(1, ticket2.articles.count, 'ticket2.articles verify')
assert_equal(%w[sender2], ticket2.tag_list)
ticket3 = Ticket.create!(
title: 'test 3',
group: Group.lookup(name: 'Users'),
customer: User.lookup(email: 'nicole.braun@zammad.org'),
updated_by_id: 1,
created_by_id: 1,
)
assert(ticket3, 'ticket3 created')
Ticket::Article.create!(
ticket_id: ticket3.id,
from: 'sender0@example.com',
to: 'some_recipient@example.com',
subject: 'some subject',
message_id: 'some@id',
body: "some message <b>note</b>\nnew line",
internal: false,
sender: Ticket::Article::Sender.find_by(name: 'Customer'),
type: Ticket::Article::Type.find_by(name: 'email'),
updated_by_id: 1,
created_by_id: 1,
)
ticket3.reload
assert_equal('test 3', ticket3.title, 'ticket3.title verify')
assert_equal('Users', ticket3.group.name, 'ticket3.group verify')
assert_equal('new', ticket3.state.name, 'ticket3.state verify')
assert_equal('2 normal', ticket3.priority.name, 'ticket3.priority verify')
assert_equal(1, ticket3.articles.count, 'ticket3.articles verify')
assert_equal([], ticket3.tag_list)
Observer::Transaction.commit
ticket3.reload
assert_equal('test 3', ticket3.title, 'ticket3.title verify')
assert_equal('Users', ticket3.group.name, 'ticket3.group verify')
assert_equal('new', ticket3.state.name, 'ticket3.state verify')
assert_equal('2 normal', ticket3.priority.name, 'ticket3.priority verify')
assert_equal(2, ticket3.articles.count, 'ticket3.articles verify')
assert_equal([], ticket3.tag_list)
article1 = ticket3.articles.last
end
test 'article.body' do
trigger1 = Trigger.create_or_update(
name: 'auto reply',
condition: {
'ticket.action' => {
'operator' => 'is',
'value' => 'create',
},
'ticket.state_id' => {
'operator' => 'is',
'value' => Ticket::State.lookup(name: 'new').id.to_s,
},
'article.body' => {
'operator' => 'contains',
'value' => 'hello',
},
},
perform: {
'notification.email' => {
'body' => 'some text<br>#{ticket.customer.lastname}<br>#{ticket.title}<br>#{article.body}',
'recipient' => 'ticket_customer',
'subject' => 'Thanks for your inquiry (#{ticket.title})!',
},
'ticket.tags' => {
'operator' => 'add',
'value' => 'aa, kk',
},
},
disable_notification: true,
active: true,
created_by_id: 1,
updated_by_id: 1,
)
ticket1 = Ticket.create!(
title: 'test 1',
group: Group.lookup(name: 'Users'),
customer: User.lookup(email: 'nicole.braun@zammad.org'),
updated_by_id: 1,
created_by_id: 1,
)
Ticket::Article.create!(
ticket_id: ticket1.id,
from: 'some_sender@example.com',
to: 'some_recipient@example.com',
subject: 'some subject',
message_id: 'some@id',
body: 'some message <b>note</b> hello ',
internal: false,
sender: Ticket::Article::Sender.find_by(name: 'Agent'),
type: Ticket::Article::Type.find_by(name: 'note'),
updated_by_id: 1,
created_by_id: 1,
)
ticket1.reload
assert_equal('test 1', ticket1.title, 'ticket1.title verify')
assert_equal('Users', ticket1.group.name, 'ticket1.group verify')
assert_equal('new', ticket1.state.name, 'ticket1.state verify')
assert_equal('2 normal', ticket1.priority.name, 'ticket1.priority verify')
assert_equal(1, ticket1.articles.count, 'ticket1.articles verify')
assert_equal([], ticket1.tag_list)
Observer::Transaction.commit
ticket1.reload
assert_equal('test 1', ticket1.title, 'ticket1.title verify')
assert_equal('Users', ticket1.group.name, 'ticket1.group verify')
assert_equal('new', ticket1.state.name, 'ticket1.state verify')
assert_equal(2, ticket1.articles.count, 'ticket1.articles verify')
assert_equal(%w[aa kk], ticket1.tag_list)
article1 = ticket1.articles.last
assert_match('Zammad <zammad@localhost>', article1.from)
assert_match('nicole.braun@zammad.org', article1.to)
assert_match('Thanks for your inquiry (test 1)!', article1.subject)
assert_match('some message', article1.body)
assert_match('&gt; some message &lt;b&gt;note&lt;/b&gt; hello', article1.body)
assert_equal('text/html', article1.content_type)
ticket2 = Ticket.create!(
title: 'test 1',
group: Group.lookup(name: 'Users'),
customer: User.lookup(email: 'nicole.braun@zammad.org'),
updated_by_id: 1,
created_by_id: 1,
)
Ticket::Article.create!(
ticket_id: ticket2.id,
from: 'some_sender@example.com',
to: 'some_recipient@example.com',
subject: 'some subject',
message_id: 'some@id',
body: 'some message <b>note</b>',
internal: false,
sender: Ticket::Article::Sender.find_by(name: 'Agent'),
type: Ticket::Article::Type.find_by(name: 'note'),
updated_by_id: 1,
created_by_id: 1,
)
ticket2.reload
assert_equal('test 1', ticket2.title, 'ticket2.title verify')
assert_equal('Users', ticket2.group.name, 'ticket2.group verify')
assert_equal('new', ticket2.state.name, 'ticket2.state verify')
assert_equal('2 normal', ticket2.priority.name, 'ticket2.priority verify')
assert_equal(1, ticket2.articles.count, 'ticket2.articles verify')
assert_equal([], ticket2.tag_list)
Observer::Transaction.commit
ticket2.reload
assert_equal('test 1', ticket2.title, 'ticket2.title verify')
assert_equal('Users', ticket2.group.name, 'ticket2.group verify')
assert_equal('new', ticket2.state.name, 'ticket2.state verify')
assert_equal(1, ticket2.articles.count, 'ticket2.articles verify')
assert_equal(%w[], ticket2.tag_list)
trigger1 = Trigger.create_or_update(
name: 'auto reply',
condition: {
'ticket.action' => {
'operator' => 'is',
'value' => 'create',
},
'ticket.state_id' => {
'operator' => 'is',
'value' => Ticket::State.lookup(name: 'new').id.to_s,
},
'article.body' => {
'operator' => 'contains not',
'value' => 'hello',
},
},
perform: {
'notification.email' => {
'body' => 'some text<br>#{ticket.customer.lastname}<br>#{ticket.title}<br>#{article.body}',
'recipient' => 'ticket_customer',
'subject' => 'Thanks for your inquiry (#{ticket.title})!',
},
'ticket.tags' => {
'operator' => 'add',
'value' => 'aa, kk',
},
},
disable_notification: true,
active: true,
created_by_id: 1,
updated_by_id: 1,
)
ticket3 = Ticket.create!(
title: 'test 1',
group: Group.lookup(name: 'Users'),
customer: User.lookup(email: 'nicole.braun@zammad.org'),
updated_by_id: 1,
created_by_id: 1,
)
Ticket::Article.create!(
ticket_id: ticket3.id,
from: 'some_sender@example.com',
to: 'some_recipient@example.com',
subject: 'some subject',
message_id: 'some@id',
body: 'some message <b>note</b> hello ',
internal: false,
sender: Ticket::Article::Sender.find_by(name: 'Agent'),
type: Ticket::Article::Type.find_by(name: 'note'),
updated_by_id: 1,
created_by_id: 1,
)
ticket3.reload
assert_equal('test 1', ticket3.title, 'ticket3.title verify')
assert_equal('Users', ticket3.group.name, 'ticket3.group verify')
assert_equal('new', ticket3.state.name, 'ticket3.state verify')
assert_equal('2 normal', ticket3.priority.name, 'ticket3.priority verify')
assert_equal(1, ticket3.articles.count, 'ticket3.articles verify')
assert_equal([], ticket3.tag_list)
Observer::Transaction.commit
ticket3.reload
assert_equal('test 1', ticket3.title, 'ticket3.title verify')
assert_equal('Users', ticket3.group.name, 'ticket3.group verify')
assert_equal('new', ticket3.state.name, 'ticket3.state verify')
assert_equal(1, ticket3.articles.count, 'ticket3.articles verify')
assert_equal(%w[], ticket3.tag_list)
ticket4 = Ticket.create!(
title: 'test 1',
group: Group.lookup(name: 'Users'),
customer: User.lookup(email: 'nicole.braun@zammad.org'),
updated_by_id: 1,
created_by_id: 1,
)
Ticket::Article.create!(
ticket_id: ticket4.id,
from: 'some_sender@example.com',
to: 'some_recipient@example.com',
subject: 'some subject',
message_id: 'some@id',
body: 'some message <b>note</b> 2',
internal: false,
sender: Ticket::Article::Sender.find_by(name: 'Agent'),
type: Ticket::Article::Type.find_by(name: 'note'),
updated_by_id: 1,
created_by_id: 1,
)
ticket4.reload
assert_equal('test 1', ticket4.title, 'ticket4.title verify')
assert_equal('Users', ticket4.group.name, 'ticket4.group verify')
assert_equal('new', ticket4.state.name, 'ticket4.state verify')
assert_equal('2 normal', ticket4.priority.name, 'ticket4.priority verify')
assert_equal(1, ticket4.articles.count, 'ticket4.articles verify')
assert_equal([], ticket4.tag_list)
Observer::Transaction.commit
ticket4.reload
assert_equal('test 1', ticket4.title, 'ticket4.title verify')
assert_equal('Users', ticket4.group.name, 'ticket4.group verify')
assert_equal('new', ticket4.state.name, 'ticket4.state verify')
assert_equal(2, ticket4.articles.count, 'ticket4.articles verify')
assert_equal(%w[aa kk], ticket4.tag_list)
article4 = ticket4.articles.last
assert_match('Zammad <zammad@localhost>', article4.from)
assert_match('nicole.braun@zammad.org', article4.to)
assert_match('Thanks for your inquiry (test 1)!', article4.subject)
assert_match('some message', article4.body)
assert_match('&gt; some message &lt;b&gt;note&lt;/b&gt; 2', article4.body)
assert_equal('text/html', article4.content_type)
end
test 'trigger auto reply with umlaut in form' do
trigger1 = Trigger.create_or_update(
name: 'auto reply',
condition: {
'ticket.action' => {
'operator' => 'is',
'value' => 'create',
},
'ticket.state_id' => {
'operator' => 'is',
'value' => Ticket::State.lookup(name: 'new').id.to_s,
},
},
perform: {
'notification.email' => {
'body' => 'some text<br>#{ticket.customer.lastname}<br>#{ticket.title}<br>#{article.body}',
'recipient' => 'article_last_sender',
'subject' => 'Thanks for your inquiry (#{ticket.title})!',
},
},
disable_notification: true,
active: true,
created_by_id: 1,
updated_by_id: 1,
)
ticket1 = Ticket.create!(
title: 'test 1',
group: Group.lookup(name: 'Users'),
customer: User.lookup(email: 'nicole.braun@zammad.org'),
updated_by_id: 1,
created_by_id: 1,
)
Ticket::Article.create!(
ticket_id: ticket1.id,
from: 'Sabine Schütz <some_sender@example.com>',
to: 'some_recipient@example.com',
subject: 'some subject',
message_id: 'some@id',
body: 'some message <b>note</b> hello ',
internal: false,
sender: Ticket::Article::Sender.find_by(name: 'Customer'),
type: Ticket::Article::Type.find_by(name: 'email'),
updated_by_id: 1,
created_by_id: 1,
)
ticket1.reload
assert_equal('test 1', ticket1.title, 'ticket1.title verify')
assert_equal('Users', ticket1.group.name, 'ticket1.group verify')
assert_equal('new', ticket1.state.name, 'ticket1.state verify')
assert_equal('2 normal', ticket1.priority.name, 'ticket1.priority verify')
assert_equal(1, ticket1.articles.count, 'ticket1.articles verify')
assert_equal('Sabine Schütz <some_sender@example.com>', ticket1.articles.first.from, 'ticket1.articles.first.from verify')
assert_equal([], ticket1.tag_list)
Observer::Transaction.commit
ticket1.reload
assert_equal('test 1', ticket1.title, 'ticket1.title verify')
assert_equal('Users', ticket1.group.name, 'ticket1.group verify')
assert_equal('new', ticket1.state.name, 'ticket1.state verify')
assert_equal(2, ticket1.articles.count, 'ticket1.articles verify')
article1 = ticket1.articles.last
assert_match('Zammad <zammad@localhost>', article1.from)
assert_match('some_sender@example.com', article1.to)
assert_match('Thanks for your inquiry (test 1)!', article1.subject)
assert_match('some message', article1.body)
assert_match('&gt; some message &lt;b&gt;note&lt;/b&gt; hello', article1.body)
assert_equal('text/html', article1.content_type)
end
test 'trigger auto reply with 2 sender addresses in form' do
trigger1 = Trigger.create_or_update(
name: 'auto reply',
condition: {
'ticket.action' => {
'operator' => 'is',
'value' => 'create',
},
'ticket.state_id' => {
'operator' => 'is',
'value' => Ticket::State.lookup(name: 'new').id.to_s,
},
},
perform: {
'notification.email' => {
'body' => 'some text<br>#{ticket.customer.lastname}<br>#{ticket.title}<br>#{article.body}',
'recipient' => 'article_last_sender',
'subject' => 'Thanks for your inquiry (#{ticket.title})!',
},
},
disable_notification: true,
active: true,
created_by_id: 1,
updated_by_id: 1,
)
ticket1, article1, user, mail = Channel::EmailParser.new.process({}, IO.binread('test/fixtures/mail65.box'))
assert_equal('aaäöüßad asd', ticket1.title, 'ticket1.title verify')
assert_equal('Users', ticket1.group.name, 'ticket1.group verify')
assert_equal('new', ticket1.state.name, 'ticket1.state verify')
assert_equal(2, ticket1.articles.count, 'ticket1.articles verify')
article1 = ticket1.articles.last
assert_match('Zammad <zammad@localhost>', article1.from)
assert_match('smith@example.com', article1.to)
assert_match('Thanks for your inquiry (aaäöüßad asd)!', article1.subject)
assert_match('some text<br><br>aaäöüßad asd', article1.body)
assert_equal('text/html', article1.content_type)
end
end