254 Commits

Author SHA1 Message Date
Senad Uka
d97516e24e thrown out ringeraja banner 2016-06-09 12:42:22 +02:00
Senad Uka
9820f6a363 another trello card formatting fix 2016-05-07 09:26:02 +02:00
Senad Uka
6b4bc6aa20 fixed trello formating again 2016-05-07 09:21:34 +02:00
Senad Uka
98e64830e1 fixed trello formating 2016-05-07 09:17:30 +02:00
Senad Uka
5c899ca6ed added paypal notice 2016-05-07 09:14:06 +02:00
Senad Uka
138c5de68e added coupon code to label on remark 2016-05-07 08:49:11 +02:00
Senad Uka
edb1325c07 fixed search on enter 2016-05-07 06:41:12 +02:00
Senad Uka
6b97c2342c fixed trello 2016-05-07 06:10:04 +02:00
Senad Uka
70ee58e989 slugify fixed 2016-03-16 12:13:47 +01:00
Senad Uka
7e62881d16 SOlved conflict 2016-03-16 12:12:26 +01:00
adam.harbas@a-net.ba
fdc3362719 Remove cart from state 2016-02-16 14:37:18 +01:00
adam.harbas@a-net.ba
2534ee71e1 Fix for cartLoad 2016-02-16 14:34:29 +01:00
adam.harbas@a-net.ba
a2bc1e192c Fix for cartLoad 2016-02-16 14:31:51 +01:00
Senad Uka
d111406f03 fixed bugs with trello 2016-02-16 12:34:21 +01:00
adam.harbas@a-net.ba
006829bc77 Create trello card before purchasing 2016-02-16 12:28:49 +01:00
Senad Uka
1368a71f26 Merge branch 'develop'
paypal, pikpay and gift support
2016-02-07 19:54:08 +01:00
Senad Uka
92f45c378e disable pikpay for now 2016-02-07 19:53:48 +01:00
Adam
44f5b22c82 Fix for validate logger 2016-02-02 17:09:06 +01:00
Adam
97f6b34518 Fix for reindex console output too large 2016-02-02 17:06:22 +01:00
Adam
1b9f38a9c0 Fix for reindex logger error 2016-01-26 11:09:18 +01:00
Senad Uka
e0fda3e9ee add robots.txt - because of the SEO 2016-01-26 06:09:08 +01:00
Senad Uka
30e48cd1b6 put menu items into links - because of the SEO 2016-01-26 05:43:05 +01:00
Senad Uka
0e2e5b8fb9 put items into links - because of the SEO 2016-01-26 05:01:18 +01:00
Adam
338d4e7966 Paypal notify url fix 2016-01-24 23:40:26 +01:00
Adam
770138ba68 Removing migration 2016-01-22 16:27:19 +01:00
Adam
10b3109771 for pikpay send only integer num 2016-01-22 16:23:58 +01:00
Adam
63b2506872 Remove column - fixing error 2016-01-22 16:02:29 +01:00
Adam
13757d5a7f Schema updated 2016-01-22 15:55:40 +01:00
Adam
c6c04a1405 Root path for import log files added 2016-01-22 15:37:29 +01:00
Adam
185cdb2a14 Rails root poject path added to command 2016-01-22 15:30:13 +01:00
Adam
5fc1279c2a Reverting Gemfile state 2016-01-21 11:30:28 +01:00
Adam
973f39eec3 Fixing bundler error 2016-01-21 10:17:03 +01:00
Senad Uka
418eb028ae changed text of newsleetter sweepstake 2016-01-18 11:06:49 +01:00
Senad Uka
1c0c4fa78a changed date of newsleetter sweepstake 2016-01-18 10:28:28 +01:00
adam.harbas@a-net.ba
8675dc724f Mobile design fixed 2016-01-13 09:51:36 +01:00
adam.harbas@a-net.ba
9e200ca910 Adding Cart id for order number 2016-01-13 09:26:28 +01:00
adam.harbas@a-net.ba
2f673c9877 Fix hardcoded host 2016-01-13 08:51:05 +01:00
Adam
90d5e855db Sha1 added to package.json 2016-01-12 21:03:06 +01:00
adam.harbas@a-net.ba
828aac9a49 Gift info added to trello 2016-01-12 15:43:11 +01:00
adam.harbas@a-net.ba
54d7cdb04e Delivery cost depend on gift option 2016-01-12 15:18:27 +01:00
adam.harbas@a-net.ba
68c7a620ef Gift button added 2016-01-12 14:23:40 +01:00
adam.harbas@a-net.ba
7a053a60ba Delete unnecessary files 2016-01-12 13:27:40 +01:00
adam.harbas@a-net.ba
9142e0c4db Gift support changes 2016-01-12 13:26:43 +01:00
Adam
aca81d97ec Add Recipient destination model and functionality on front end 2016-01-12 09:05:32 +01:00
Adam
5ee38f6d9a Add Recipient destination model and functionality on front end 2016-01-12 09:01:46 +01:00
adam.harbas@a-net.ba
794cc2ec69 Gift interface added 2016-01-11 16:03:53 +01:00
adam.harbas@a-net.ba
391b912eb2 Text button changed 2016-01-11 10:54:49 +01:00
adam.harbas@a-net.ba
c345e9f016 Last used btn 2016-01-11 10:52:18 +01:00
adam.harbas@a-net.ba
76ad0606b4 Removing duplicate migration 2016-01-11 10:23:26 +01:00
adam.harbas@a-net.ba
fbcde51ef0 Button order 2016-01-11 10:21:11 +01:00
adam.harbas@a-net.ba
f4884c4985 Fixing errors 2016-01-11 10:07:51 +01:00
adam.harbas@a-net.ba
3faa487ecd Fixing 2016-01-11 09:51:59 +01:00
Adam
7b2552c31c Pikpay button 2016-01-11 08:53:03 +01:00
adam.harbas@a-net.ba
7624a438b6 Last used button added 2016-01-08 10:21:33 +01:00
adam.harbas@a-net.ba
05c8f6ce88 Adding payment method 2016-01-08 09:36:28 +01:00
adam.harbas@a-net.ba
2a0e326862 Last used payment added 2016-01-07 15:00:59 +01:00
adam.harbas@a-net.ba
080255f229 Merge branch 'develop' of https://github.com/senaduka/ribica into develop 2016-01-07 13:58:45 +01:00
Adam
4cd1470674 Fix misspelled 2016-01-07 13:28:57 +01:00
Adam
8dd163da91 Exclude method from json parse in before 2016-01-07 13:14:49 +01:00
adam.harbas@a-net.ba
41fc327874 Payment confirmation changing from get to post 2016-01-07 10:51:43 +01:00
adam.harbas@a-net.ba
ea1c760e85 Oayment confirmation added to cart contoroller 2016-01-07 10:49:50 +01:00
adam.harbas@a-net.ba
0efb73e385 Use PaypalId and ApiUrl from globals 2016-01-07 09:19:25 +01:00
adam.harbas@a-net.ba
d0f02df738 Price and shipping to euro 2016-01-07 09:08:20 +01:00
adam.harbas@a-net.ba
81140de4d7 Price and shipping to euro 2016-01-07 09:06:54 +01:00
adam.harbas@a-net.ba
3a3ba87066 Conversion rate and CoonvertToEuro added to globals 2016-01-07 09:05:18 +01:00
adam.harbas@a-net.ba
e49b6b93d6 Custom field with deliveryDestination object added to paypal button 2016-01-07 08:58:37 +01:00
adam.harbas@a-net.ba
f092719ac7 Cart configuration action removed 2016-01-07 08:39:11 +01:00
adam.harbas@a-net.ba
1b3478707b CartConfiguration removed 2016-01-07 08:38:05 +01:00
adam.harbas@a-net.ba
ecd4d79ff2 Get configuration from server 2016-01-06 08:40:27 +01:00
adam.harbas@a-net.ba
2b51dfcdec Fix for helper 2016-01-06 08:27:18 +01:00
adam.harbas@a-net.ba
f92d54b142 Paypal button added to page 2016-01-06 08:26:19 +01:00
adam.harbas@a-net.ba
abb44757a5 Fix for paypalButton component 2016-01-05 09:31:51 +01:00
adam.harbas@a-net.ba
c2cd011ffb Add price conversion 2016-01-04 11:14:16 +01:00
adam.harbas@a-net.ba
6b61afebc0 Check if task succeeded and execute reindex task 2016-01-04 09:56:40 +01:00
adam.harbas@a-net.ba
3fc4a9edea Handle CSV::MalformedCSVError 2015-12-31 15:12:37 +01:00
adam.harbas@a-net.ba
83022beb5b don't do anything if csv_content is empty 2015-12-31 15:01:15 +01:00
adam.harbas@a-net.ba
a1fbc18856 Handle undefined method for nil object 2015-12-31 14:55:47 +01:00
Adam
a6a3d5937c Requiring gems 2015-12-31 14:53:20 +01:00
Adam
a41e997931 Execute task and getting output from rake 2015-12-31 14:17:38 +01:00
Adam
ca91c3d16f Create csv from csv content 2015-12-31 00:07:43 +01:00
Adam
d73b8ca8d8 Post action for export/import added 2015-12-30 22:58:14 +01:00
Adam
1dcd8d404e Export/import elements added to the page 2015-12-30 22:52:51 +01:00
Adam
93a315bbe1 Export/import link, route, action and page added 2015-12-30 22:48:42 +01:00
adam.harbas@a-net.ba
4ccfdb002e Option delete items added to check_availability page 2015-12-29 13:36:02 +01:00
Senad Uka
53ef339f5f added ringeraja ba advertisement 2015-12-16 08:49:42 +01:00
Senad Uka
1fa1c1c18e in the middle of the work 2015-12-16 08:39:54 +01:00
Senad Uka
924a675fa1 main css conflict 2015-11-29 10:02:57 +01:00
Senad Uka
8d4146acee letters are smaller now 2015-11-28 09:01:04 +01:00
Senad Uka
f93b127c2f big header is here 2015-11-28 08:46:09 +01:00
Senad Uka
bbd492467f size of the iframe is now bigger 2015-11-28 08:40:14 +01:00
Senad Uka
7d01bfb393 changed slugs to be nicer 2015-11-28 08:35:42 +01:00
Senad Uka
e993904d78 added newsletter signup form 2015-11-28 08:28:17 +01:00
Senad Uka
8d5067a567 fixed limit for number of items in group 2015-11-26 10:57:25 +01:00
Senad Uka
247d1c72c7 fixed limit for number of items in group 2015-11-26 10:49:25 +01:00
Senad Uka
b93660b264 added decoration support 2015-11-24 10:29:46 +01:00
Senad Uka
31876c0c1a deleted duplicate places 2015-11-23 12:59:13 +01:00
Senad Uka
3d0eff1c15 paypal button 2015-11-23 12:58:14 +01:00
Senad Uka
34bce252c5 Merge branch 'master' into develop 2015-11-15 06:31:48 +01:00
Senad Uka
d283204e88 fixed url on form 2015-11-14 07:26:47 +01:00
Senad Uka
a50d8339dd fixed url on form 2015-11-14 07:24:35 +01:00
Senad Uka
88c1ad4e92 fixed link 2015-11-14 07:18:02 +01:00
Senad Uka
a341137939 created item availability checking tool 2015-11-14 07:07:08 +01:00
Senad Uka
3e47672fb3 Merge branch 'develop' of github.com:senaduka/ribica into develop 2015-11-14 04:39:20 +01:00
Senad Uka
82d0195530 payments 2015-11-14 04:39:05 +01:00
harleyribic
f8915dd2d6 testiram 2015-11-11 19:46:23 +01:00
Senad Uka
c5fd654f5f deleted bundle 2015-11-07 09:52:50 +01:00
Senad Uka
0aab42fa67 fixed problem with adding delivery costs 2015-11-07 09:11:02 +01:00
Senad Uka
481f1122a7 .gitignore 2015-11-07 09:09:28 +01:00
Senad Uka
4955480e86 fixed problem with adding delivery costs 2015-11-07 09:03:50 +01:00
Senad Uka
c4b64a8839 Merge branch 'master' into develop 2015-11-07 08:10:44 +01:00
Senad Uka
ba3ae18669 delivery costs on cart page shown only when address is saved 2015-11-07 07:57:06 +01:00
Senad Uka
11b3669270 multiple cities supported / delivery costs shown only when place is selected 2015-11-07 07:41:08 +01:00
Senad Uka
d34c0c280c parametrized access 2015-10-31 08:24:44 +01:00
Senad Uka
3c5be78146 search problem 2015-10-11 06:37:17 +02:00
Senad Uka
b432ca58d5 fixed mistake in about page 2015-10-11 05:40:57 +02:00
Senad Uka
06e482685f changed phone number on about us / added viber and whatsapp 2015-10-10 09:19:55 +02:00
Senad Uka
8ec08804aa phone changed 2015-10-09 12:29:12 +02:00
Senad Uka
205c8352a1 update prices fails if list price is smaller than input price 2015-10-06 12:03:22 +02:00
Senad Uka
2c19f97971 random is now really rendom 2015-10-01 16:10:41 +02:00
Senad Uka
c75b112027 changed about you, changed price settings 2015-10-01 15:48:32 +02:00
Senad Uka
4470e85344 fixed import 2015-09-29 15:32:50 +02:00
Senad Uka
bb4fb665e3 changed some minor aesthetic issues 2015-09-29 14:22:27 +02:00
Senad Uka
f8ecebbc3d price is not reset when importing descriptions 2015-09-28 13:47:02 +02:00
Senad Uka
ae5b52165d finished price updating 2015-09-27 19:59:39 +02:00
Senad Uka
014416ca51 trello integration finished 2015-09-26 11:58:01 +02:00
Senad Uka
ae8e9b0081 converted time to CEST 2015-09-21 12:27:51 +02:00
Senad Uka
980ea36fc2 only sarajevo is supported now 2015-09-21 09:04:55 +02:00
Senad Uka
56f9c7b72b suggested articles / email is now sent 2015-09-21 06:31:52 +02:00
Senad Uka
2a4800fdab urgent delivery is hidden 2015-09-19 07:15:04 +02:00
Senad Uka
95e746c87c notification is on top 2015-09-19 07:12:09 +02:00
Senad Uka
5b9abe8a1c production database password change 2015-09-13 07:51:36 +02:00
Senad Uka
2ff5ceabd2 added email notification when order arives 2015-08-09 10:58:14 +02:00
Senad Uka
8b6a62b7e7 added order report to back office 2015-08-09 10:17:52 +02:00
Senad Uka
69f6c86aee added instant delivery to gui / added RUC as abbr tag and details tag on mobile 2015-08-02 18:47:48 +02:00
Senad Uka
68b25bf491 added migrations for instant delivery 2015-07-26 19:10:16 +02:00
Senad Uka
af6864954a added google analytics 2015-07-25 14:08:02 +02:00
Senad Uka
246a587c92 address entry looks bearable on mobile now 2015-07-05 13:44:38 +02:00
Senad Uka
96a2fba535 fixed conflicts 2015-07-05 13:24:09 +02:00
Senad Uka
f5664dee88 delivery costs are now shown 2015-07-05 13:22:47 +02:00
Edin Dazdarevic
94be4b0fbd updated .gitignore 2015-06-21 17:25:44 +02:00
Edin Dazdarevic
18d54ffea3 configuring the production build 2015-06-21 15:01:49 +02:00
Senad Uka
52a03f3334 cart page bearable on mobile 2015-06-21 12:24:18 +02:00
Senad Uka
a158c76789 modified item details page to look not horrible on mobile 2015-06-21 10:40:58 +02:00
Senad Uka
080d3e4497 it works on ipad, safari etc. / splash screen has a progress wheel 2015-06-21 09:22:41 +02:00
Senad Uka
f05b307fc0 homepage mobile experience became bearable by using questionable css and js practices 2015-06-20 07:05:16 +02:00
Senad Uka
7d74a3cc27 shortened supported towns 2015-06-20 05:19:52 +02:00
Senad Uka
afe0325f00 fixed bugs on menuitem etags 2015-06-20 05:08:22 +02:00
Senad Uka
baf1617053 added etags on prepare_for_display items and menuitems 2015-06-20 05:06:32 +02:00
Senad Uka
71c504cb5f added nicer splash screen to trick user into
thinking web site is faster :)
W
2015-06-20 04:43:08 +02:00
Senad Uka
393ec79a40 fixed bug in commission calculation 2015-06-14 07:14:00 +02:00
Senad Uka
4dfc2ffbd1 our commission is now shown on cart page 2015-06-14 07:11:46 +02:00
Senad Uka
ce733c8cd8 address is now collapsable 2015-06-14 06:18:10 +02:00
Senad Uka
6c5a21789a removed two files 2015-06-14 05:30:33 +02:00
Senad Uka
db796d5f82 moved list of cities to store / fixed bug with grunt watch on fast computers 2015-06-14 05:28:42 +02:00
Senad Uka
ee32d6f7c9 cart icon is hidden when ordering (cart and delivery) 2015-06-14 04:30:21 +02:00
Senad Uka
fb12ea613a fixed bug with phone number not validating correctly 2015-06-14 03:41:21 +02:00
Senad Uka
032dfc6d64 fixed bug with more than 10 items in cart 2015-06-14 03:38:44 +02:00
Senad Uka
e5cc98f934 zavrsi narudzbu is now 'nastavi narudzbu' 2015-06-13 06:27:48 +02:00
Senad Uka
9c01fac72d empty cart now contains suggestions 2015-06-13 06:21:04 +02:00
Senad Uka
1e32562aff changed button labeling to be consistent 'ubaci u korpu' and 'ukloni iz korpe' 2015-06-13 06:09:59 +02:00
Senad Uka
d92624bfc7 added toast notification that item is added to the cart 2015-06-13 05:35:05 +02:00
Senad Uka
0c305d3c40 floating price on item list 2015-06-13 03:53:42 +02:00
Senad Uka
c27e08a682 price on item page is now with two decimals 2015-06-13 03:28:16 +02:00
Senad Uka
771a71b42f fiddled around with css / numbers on two decimals now on product list 2015-06-06 21:50:41 +02:00
Edin Dazdarevic
763bc329fc fix for delivery destination not validating 2015-06-04 13:37:33 +02:00
Edin Dazdarevic
99492f137f link banner centering 2015-06-02 13:41:58 +02:00
Edin Dazdarevic
1db13308ef reverted change in Gruntfile.js and fixed CSS issues in firefox 2015-06-02 12:30:48 +02:00
Edin Dazdarevic
055f9ab3fa removing unneeded function call 2015-06-02 11:40:15 +02:00
Edin Dazdarevic
e35489a16e fixed link to registration on thank you page 2015-06-01 13:40:05 +02:00
Edin Dazdarevic
328067e78b fixed 'Zavrsi narudzbu' button problems 2015-06-01 12:48:24 +02:00
Edin Dazdarevic
28e81c27ed removed 'login' and 'register' pages 2015-06-01 12:39:15 +02:00
Edin Dazdarevic
b5fdc6d173 cart now functional without bugs (at least the ones we know about)
fixed a small issue with ItemGroup REST call
2015-05-27 13:58:44 +02:00
Edin Dazdarevic
2ddfcf2141 cart page logic restructuring 2015-05-27 12:08:01 +02:00
Edin Dazdarevic
d358934a01 fixes for inconsistent cart state 2015-05-27 11:57:55 +02:00
Edin Dazdarevic
d5cef64cb6 updated 'reactify' version so that source maps work correctly 2015-05-27 11:31:03 +02:00
Edin Dazdarevic
a2ecdc5d63 margin-top fix 2015-05-26 21:35:06 +02:00
Edin Dazdarevic
ac41e8aef7 unknown bug fix 2015-05-26 18:24:49 +02:00
Edin Dazdarevic
12f48ab0e7 Merge branch 'master' of https://github.com/senaduka/ribica
Conflicts:
	front-ui/app/components/cart/cartPage.js
2015-05-26 18:12:26 +02:00
Senad Uka
db6dd6a1ab ahi fixed button that jumps around 2015-05-26 18:08:16 +02:00
Edin Dazdarevic
8bed4eb3f7 started with cart design
removing of items from cart now possible
2015-05-26 18:08:03 +02:00
Edin Dazdarevic
850e4a267c changed default number of items on a page to 24 2015-05-26 15:04:58 +02:00
Edin Dazdarevic
d23a4c0c0e added import.log to .gitignore 2015-05-25 23:27:43 +02:00
Edin Dazdarevic
458b67f185 search by brand name now works 2015-05-25 22:53:40 +02:00
Edin Dazdarevic
e1be044fd9 - removed our copy jquery & bootstrap. using cdn instead
- added search box to the header
- made reindex rake task
2015-05-25 20:49:52 +02:00
Senad Uka
c99bcbda7a fixed misleading name of an action 2015-05-17 03:20:26 +02:00
Senad Uka
16ff955c21 fixed css on product page - this is as far as my sabur goes :) 2015-05-16 04:10:21 +02:00
Senad Uka
8e3f071ef3 almost finished product page / need to fix some css stuff 2015-05-15 18:38:45 +02:00
Senad Uka
6453b1b241 fixed bug with amount not updating / solved double dispatch problem with cartAction.load / removed all console.log calls - it became too chatty / add them as needed 2015-05-14 06:21:49 +02:00
Senad Uka
49dd10acbc almost finished new design on product page / reproduced bug with amount not updating 2015-05-13 16:32:53 +02:00
Senad Uka
fe452d359f added orders to confirm report / phone allows more digits now / added reports to rails admin navigation 2015-05-11 11:35:24 +02:00
Edin Dazdarevic
0490800ab3 validate that item images start with https 2015-04-25 13:17:27 +02:00
Senad Uka
1f0e005723 Merge branch 'master' of github.com:senaduka/ribica 2015-04-21 06:39:44 +02:00
Senad Uka
c9949c444a item groups now have order - start page is now item group 1 (configurable in globals) 2015-04-21 06:39:30 +02:00
Edin Dazdarevic
e4536055df bug fix: menu does not work in firefox 2015-04-20 14:34:57 +02:00
Edin Dazdarevic
729393d88c page flickering solved 2015-04-20 14:12:42 +02:00
Senad Uka
ecbe58c626 money in upper right works now - zavrsi narudzbu is white 2015-04-20 05:49:23 +02:00
Edin Dazdarevic
a5836a428f implemented design for login page 2015-04-19 23:07:03 +02:00
Edin Dazdarevic
9eb7690d2d jsx reformat and added href to A tags 2015-04-19 18:42:34 +02:00
Edin Dazdarevic
0cdf57d4a9 sidebar design implemented on search by category and by section page 2015-04-19 15:58:08 +02:00
Edin Dazdarevic
2f809cfbcf registration page design added, some other minor changes 2015-04-19 15:00:06 +02:00
Edin Dazdarevic
79752fca47 small ui changes, fixed issue with items floating 2015-04-18 21:57:24 +02:00
Edin Dazdarevic
195bee516b added bootstrap.js file from the design 2015-04-18 16:20:53 +02:00
Edin Dazdarevic
aafda1d187 bug fix: menu not visible on small screens 2015-04-18 16:13:55 +02:00
Senad Uka
269ad19e4f it's not fluid anymore - and shadows are not that strong 2015-04-16 21:19:33 +02:00
Senad Uka
fc9f7496d2 number of items in cart is now properly aligned 2015-04-16 06:45:38 +02:00
Edin Dazdarevic
19cdca76b1 added menu sub sub items (horrible name i know) 2015-04-15 00:10:37 +02:00
Edin Dazdarevic
f71ab5ea47 hide menu when something (section, category, subcategory) is clicked 2015-04-14 23:34:46 +02:00
Edin Dazdarevic
452a2cd5f4 basic version of the menu 2015-04-13 23:16:33 +02:00
Edin Dazdarevic
96420fc547 Merge branch 'master' of https://github.com/senaduka/ribica 2015-04-13 01:05:40 +02:00
Edin Dazdarevic
9865cb5f0a trimming whitespace on import, fixed issue with units_in_pack column being too small 2015-04-13 01:05:22 +02:00
Senad Uka
ea2837bd00 items are now done and pictures resize on serverside automagically 2015-04-12 11:11:26 +02:00
Senad Uka
8197104040 design in progress - very ugly now 2015-04-12 09:21:00 +02:00
Edin Dazdarevic
82f40de96b when importing first do a lookup by code before creating a new item 2015-04-11 13:51:11 +02:00
Senad Uka
6da4e6c9fd created a very ugly report 2015-04-08 07:35:00 +02:00
Edin Dazdarevic
670f58fcff increased max number of pages on itemlist component 2015-04-08 00:11:44 +02:00
Edin Dazdarevic
5464ec5770 added ribica rake task (item import, copying sections to menu etc.) 2015-04-07 00:29:14 +02:00
Edin Dazdarevic
76d5fd7599 fixed paging on subcategory browsing page 2015-03-30 00:05:57 +02:00
Edin Dazdarevic
7c1eb2f4fd - browsing by subcategory 2015-03-29 23:23:21 +02:00
Edin Dazdarevic
8e3557cf2e minor refactoring of filters 2015-03-29 16:34:42 +02:00
Senad Uka
b3fc46633c Merge branch 'master' of github.com:senaduka/ribica 2015-03-29 12:47:08 +02:00
Senad Uka
7acf1a8d6c banners are show now ! 2015-03-29 12:46:51 +02:00
Edin Dazdarevic
71fbde93de added brands 2015-03-28 14:38:15 +01:00
Edin Dazdarevic
6c7a1b962f login & register form are now being submitted when pressing the 'enter' key 2015-03-28 14:10:56 +01:00
Edin Dazdarevic
1e256f728d finished menu items 2015-03-28 13:59:04 +01:00
Senad Uka
b90b4035aa fixed bug with address from a logged in user staying after logout 2015-03-28 06:05:16 +01:00
Senad Uka
d8668115ed fixed bugs with address in incognito and NaN in delivery costs and total 2015-03-25 06:12:38 +01:00
Edin Dazdarevic
5bc77597a4 menu -> submenu backend 2015-03-24 06:18:27 +01:00
Senad Uka
b534d15866 groups of articles now shown on ribica.ba/group/1/, background is in cloudinary 2015-03-23 07:21:53 +01:00
Edin Dazdarevic
0ff47313df minor search page fixes 2015-03-23 00:19:48 +01:00
Edin Dazdarevic
e23bfe0a7f Merge branch 'master' of https://github.com/senaduka/ribica 2015-03-22 16:17:05 +01:00
Edin Dazdarevic
9154d216a2 basic version of search implemented 2015-03-22 16:16:52 +01:00
Senad Uka
bbedb4a877 created item groups and link banners and their associations and fixed bugs with join tables 2015-03-22 06:17:05 +01:00
Senad Uka
38548e3e33 removed special offer id from items 2015-03-21 06:30:18 +01:00
Edin Dazdarevic
88c53a8512 added elasticsearch gem and index method 2015-03-21 00:00:36 +01:00
Edin Dazdarevic
fb080ed487 registration bug fix and login button style fix 2015-03-20 00:40:03 +01:00
Edin Dazdarevic
76379c4ae5 fixed 'registruj me' button a bit 2015-03-19 22:36:32 +01:00
Edin Dazdarevic
a7e40e579f bunch of fixes, need to refactoring to move state to the store in order to make it more fluxy 2015-03-19 22:29:16 +01:00
Edin Dazdarevic
bc10740780 Merge branch 'master' of https://github.com/senaduka/ribica 2015-03-19 14:27:27 +01:00
Edin Dazdarevic
69f5faffe4 added children to users 2015-03-19 14:27:04 +01:00
Senad Uka
4b019d6b9e logout and login cart state is working now - except a little bug with icon on login 2015-03-19 06:47:41 +01:00
Edin Dazdarevic
1d16951fcf reapplying the fix that was lost by conflict resolution 2015-03-19 01:13:11 +01:00
Edin Dazdarevic
70635ebd1e added 'order' fields to sections, categories and sub_categories. - moved backoffice migrations to front-api 2015-03-19 00:10:24 +01:00
Edin Dazdarevic
a1b9250865 subcategories should not show in the menu 2015-03-18 18:22:21 +01:00
Senad Uka
658fe4931d special offers backoffice is ready now 2015-03-18 06:25:40 +01:00
Senad Uka
3b95500635 cart logic now ties cart with user when cart is created with logged in user 2015-03-15 04:53:04 +01:00
Senad Uka
8815267a79 fixed problem with multiple carts and a whole load of problems with crazy delivery destination logic / if I didn't write it i would have thought it was written by a drug abuser during high 2015-03-14 08:17:06 +01:00
Senad Uka
e7793f0884 added suppliers, weight to item 2015-03-14 06:33:49 +01:00
Senad Uka
0bafbb4b2f fixed bug with not clearing cart notification number when confirming 2015-03-13 08:28:53 +01:00
Senad Uka
b2d4122940 item price is now saved when added to cart 2015-03-13 07:56:11 +01:00
Senad Uka
648dee4636 added delivery costs to total / added ribica logo just for fun / added validation check when confirming delivery 2015-03-13 07:04:44 +01:00
Senad Uka
e3abc09891 added validation for delivery destination 2015-03-11 07:32:05 +01:00
Senad Uka
549424b903 reshuffled towns in address selection - so bigger ones are at the top 2015-03-09 07:39:10 +01:00
Senad Uka
f4e258cb82 redesigned + and - to be clear 2015-03-09 07:38:34 +01:00
Senad Uka
e12c2b01d0 application no longer thanks people for ordering nothing 2015-03-09 07:09:34 +01:00
241 changed files with 16364 additions and 1473 deletions

BIN
.DS_Store vendored

Binary file not shown.

4
.gitignore vendored
View File

@@ -11,6 +11,7 @@
/back-office/log/*
!/back-office/log/.keep
/back-office/tmp
/back-office/import.log
*.gem
*.rbc
/front-api/.config
@@ -49,3 +50,6 @@
# everyone has its own configuration :)
config.rb
# bundle should be ignored
ribica.bundle.js

658
README.md
View File

@@ -1,3 +1,661 @@
# Ribica
One shop to rule them all!
## Unsuported towns
<option value="78255">Aleksandrovac</option>
<option value="89245">Avtovac</option>
<option value="76310">Balatun</option>
<option value="78000">Banja Luka</option>
<option value="75290">Banovici</option>
<option value="76312">Batkovic</option>
<option value="72233">Begov Han</option>
<option value="88363">Berkovici</option>
<option value="77000">Bihac</option>
<option value="76204">Bijela</option>
<option value="76300">Bijeljina</option>
<option value="73263">Bijelo Brdo</option>
<option value="89230">Bileca</option>
<option value="72248">Biljesevo</option>
<option value="88407">Bjelimici</option>
<option value="88201">Blagaj</option>
<option value="74275">Blatnica</option>
<option value="88263">Blatnica Kod Mostara</option>
<option value="71215">Blazuj</option>
<option value="76277">Bok</option>
<option value="74322">Boljanic</option>
<option value="77240">Bosanska Krupa</option>
<option value="77250">Bosanski Petrovac</option>
<option value="80270">Bosansko Grahovo</option>
<option value="88408">Bradina</option>
<option value="75420">Bratunac</option>
<option value="76000">Brcko</option>
<option value="76100">Brcko Distrikt</option>
<option value="77205">Brekovica</option>
<option value="74210">Brestovo</option>
<option value="71255">Brestovsko</option>
<option value="71370">Breza</option>
<option value="79208">Brezicani</option>
<option value="76109">Brezik</option>
<option value="76216">Brezovo Polje</option>
<option value="74206">Brijesnica</option>
<option value="74206">Brijesnica Kod Doboja</option>
<option value="74206">Brijesnica Mala</option>
<option value="74206">Brijesnica Velika</option>
<option value="76206">Brka</option>
<option value="72243">Brnjic</option>
<option value="88243">Brocanac</option>
<option value="88243">Brocanac</option>
<option value="73309">Brod Kod Foce</option>
<option value="76313">Brodac</option>
<option value="78204">Bronzani Majdan</option>
<option value="72290">Bucici</option>
<option value="70230">Bugojno</option>
<option value="75203">Bukinje</option>
<option value="74277">Buletic</option>
<option value="88202">Buna</option>
<option value="72260">Busovaca</option>
<option value="88409">Buturovicpolje</option>
<option value="77245">Buzim</option>
<option value="73280">Cajnice</option>
<option value="75405">Caparde</option>
<option value="88300">Capljina</option>
<option value="72224">Cardak</option>
<option value="71347">Careva Cuprija</option>
<option value="72246">Catici</option>
<option value="77220">Cazin</option>
<option value="74274">Cecava</option>
<option value="88404">Celebici</option>
<option value="80203">Celebici Lusnic</option>
<option value="73307">Celebici Kod Foce</option>
<option value="75246">Celic</option>
<option value="78240">Celinac</option>
<option value="89243">Cemerno</option>
<option value="88265">Cerin</option>
<option value="74211">Cerovica</option>
<option value="78403">Cerovljani</option>
<option value="88260">Citluk</option>
<option value="77226">Coralici</option>
<option value="76239">Crkvina</option>
<option value="88367">Crnici</option>
<option value="76328">Crnjelovo</option>
<option value="71221">Dejcici</option>
<option value="79243">Demirovac</option>
<option value="74400">Derventa</option>
<option value="75444">Derventa Kod Vlasenice</option>
<option value="89233">Divin</option>
<option value="74000">Doboj</option>
<option value="74206">Doboj Istok</option>
<option value="74203">Doboj Jug</option>
<option value="75328">Doborovci</option>
<option value="75308">Dobosnica</option>
<option value="77210">Dobretici</option>
<option value="71245">Dobrinja</option>
<option value="79223">Dobrljin</option>
<option value="77242">Dobro Selo</option>
<option value="73247">Dobrun</option>
<option value="75206">Dokanj</option>
<option value="72278">Dolac Na Lasvi</option>
<option value="76233">Domaljevac</option>
<option value="88305">Domanovici</option>
<option value="76274">Donja Mahala</option>
<option value="76257">Donja Medjidja</option>
<option value="76327">Donja Slatina</option>
<option value="71305">Donje Mostre</option>
<option value="79228">Donji Agici</option>
<option value="88343">Donji Memici</option>
<option value="70220">Donji Vakuf</option>
<option value="78432">Donji Vijacani</option>
<option value="79289">Donji Vrbljani</option>
<option value="76273">Donji Zabar</option>
<option value="76323">Dragaljevac</option>
<option value="74209">Dragalovci</option>
<option value="78215">Dragocaj</option>
<option value="88215">Dreznica</option>
<option value="75410">Drinjaca</option>
<option value="88344">Drinovci</option>
<option value="80260">Drvar</option>
<option value="75358">Duboki Potok</option>
<option value="75308">Dubostica</option>
<option value="78411">Dubrave</option>
<option value="75274">Dubrave Donje</option>
<option value="75273">Dubrave Gornje</option>
<option value="79227">Dubrovik</option>
<option value="74483">Dugo Polje</option>
<option value="75272">Djurdjevik</option>
<option value="75445">Dusanovo</option>
<option value="88342">Duzice</option>
<option value="76311">Dvorovi</option>
<option value="79264">Fajtovci</option>
<option value="73300">Foca</option>
<option value="71270">Fojnica</option>
<option value="89247">Fojnica Kod Gacka</option>
<option value="88306">Gabela Polje</option>
<option value="89240">Gacko</option>
<option value="80230">Glamoc</option>
<option value="76318">Glavicice</option>
<option value="72230">Globarica</option>
<option value="71275">Gojevici</option>
<option value="73000">Gorazde</option>
<option value="88340">Gorica</option>
<option value="77222">Gornja Koprivna</option>
<option value="76238">Gornja Slatina</option>
<option value="75208">Gornja Tuzla</option>
<option value="79266">Gornji Kamengrad</option>
<option value="78405">Gornji Podgradci</option>
<option value="76207">Gornji Rahic</option>
<option value="78439">Gornji Strpci</option>
<option value="74272">Gornji Teslic</option>
<option value="70240">Gornji Vakuf Uskoplje</option>
<option value="76207">Gornji Zovik</option>
<option value="89201">Grab</option>
<option value="78227">Grabovica</option>
<option value="75320">Gracanica</option>
<option value="70233">Gracanica Kod Bugojna</option>
<option value="75276">Gracanica Selo</option>
<option value="88392">Gradac</option>
<option value="76250">Gradacac</option>
<option value="78400">Gradiska</option>
<option value="88340">Grude</option>
<option value="80205">Guber</option>
<option value="80204">Listani</option>
<option value="72277">Guca Gora</option>
<option value="71240">Hadzici</option>
<option value="72225">Hajdarevici</option>
<option value="72245">Haljinici</option>
<option value="72281">Han Bila</option>
<option value="71360">Han Pijesak</option>
<option value="71212">Hrasnica</option>
<option value="88395">Hrasno</option>
<option value="71144">Hresa</option>
<option value="78436">Hrvacani</option>
<option value="75216">Husino</option>
<option value="88394">Hutovo</option>
<option value="71210">Ilidza</option>
<option value="71380">Ilijas</option>
<option value="73208">Ilovaca</option>
<option value="78234">Imljani</option>
<option value="77208">Izacic</option>
<option value="88420">Jablanica</option>
<option value="71423">Jahorina</option>
<option value="70101">Jajce</option>
<option value="76316">Janja</option>
<option value="72215">Janjici</option>
<option value="88224">Jare</option>
<option value="78233">Javorani</option>
<option value="74264">Jelah</option>
<option value="77241">Jezerski</option>
<option value="79244">Johova</option>
<option value="73319">Josanica</option>
<option value="78244">Josavka</option>
<option value="72264">Kacuni</option>
<option value="72240">Kakanj</option>
<option value="74413">Kalenderovci</option>
<option value="75260">Kalesija</option>
<option value="71230">Kalinovik</option>
<option value="77204">Kamenica</option>
<option value="72265">Kaonik</option>
<option value="71213">Kasindo</option>
<option value="80246">Kazaginac</option>
<option value="88283">Kifino Selo</option>
<option value="71250">Kiseljak</option>
<option value="75211">Kiseljak, Kod Tuzle</option>
<option value="75280">Kladanj</option>
<option value="74452">Klakar Donji</option>
<option value="79280">Kljuc</option>
<option value="88324">Klobuk</option>
<option value="74207">Klokotnica</option>
<option value="78230">Knezevo</option>
<option value="78230">Skender Vakuf</option>
<option value="79246">Knezica</option>
<option value="71356">Knezina</option>
<option value="78423">Kobas</option>
<option value="88226">Kocerin</option>
<option value="78409">Kocicevo</option>
<option value="78207">Kola</option>
<option value="80244">Kongora</option>
<option value="88400">Konjic</option>
<option value="77249">Konjoder</option>
<option value="74489">Koprivna</option>
<option value="75247">Koraj</option>
<option value="76236">Kornica</option>
<option value="74253">Kosova</option>
<option value="76276">Kostric</option>
<option value="78220">Kotor Varos</option>
<option value="74215">Kotorsko</option>
<option value="72226">Kovaci</option>
<option value="79002">Kozarac</option>
<option value="79240">Bosanska Dubica</option>
<option value="75413">Kozluk</option>
<option value="72244">Kraljeva Sutjeska</option>
<option value="71260">Kresevo</option>
<option value="78256">Kriskovci</option>
<option value="78206">Krupa Na Vrbasu</option>
<option value="88203">Krusevo</option>
<option value="78424">Kukulje</option>
<option value="71216">Kula</option>
<option value="78443">Kulasi</option>
<option value="77206">Kulen Vakuf</option>
<option value="80320">Kupres</option>
<option value="78250">Laktasi</option>
<option value="78407">Laminci Sredjani</option>
<option value="79204">Lamovita</option>
<option value="89208">Lastva</option>
<option value="72216">Lasva</option>
<option value="78222">Liplje</option>
<option value="75213">Lipnica</option>
<option value="78434">Lisnja</option>
<option value="80101">Livno</option>
<option value="75214">Ljubace</option>
<option value="79206">Ljubija</option>
<option value="88380">Ljubinje</option>
<option value="89209">Ljubomir</option>
<option value="88320">Ljubuski</option>
<option value="88223">Ljuti Dolac</option>
<option value="76278">Loncari</option>
<option value="75240">Lopare</option>
<option value="75300">Lukavac</option>
<option value="75301">Lukavac Mjesto</option>
<option value="75327">Lukavica</option>
<option value="79267">Lusci Palanka</option>
<option value="74250">Maglaj</option>
<option value="74216">Majevac</option>
<option value="77235">Mala Kladusa</option>
<option value="74418">Mala Socanica</option>
<option value="75320">Malesici</option>
<option value="76208">Maoca</option>
<option value="78410">Masici</option>
<option value="78223">Maslovare</option>
<option value="76271">Matici</option>
<option value="74203">Matuzici</option>
<option value="88266">Medjugorje</option>
<option value="79247">Medjuvodje</option>
<option value="72282">Mehurici</option>
<option value="80243">Mesihovina</option>
<option value="75446">Milici</option>
<option value="73283">Miljeno</option>
<option value="73313">Miljevina</option>
<option value="74485">Milosevac</option>
<option value="75329">Miricina</option>
<option value="74480">Modrica</option>
<option value="71428">Mokro</option>
<option value="89204">Mosko</option>
<option value="88000">Mostar</option>
<option value="88000">Mostar, Jug</option>
<option value="88000">Mostar, Jugozapad</option>
<option value="88000">Mostar, Sjever</option>
<option value="88000">Mostar, Zapad</option>
<option value="75212">Mramor</option>
<option value="73206">Mravinjac</option>
<option value="79544">Mrkodol</option>
<option value="70260">Mrkonjic Grad</option>
<option value="72212">Nemila</option>
<option value="88390">Neum</option>
<option value="88280">Nevesinje</option>
<option value="72276">Nova Bila</option>
<option value="78418">Nova Topola</option>
<option value="79220">Bosanski Novi</option>
<option value="74254">Novi Seher</option>
<option value="72290">Novi Travnik</option>
<option value="78428">Nozicko</option>
<option value="70225">Oborci</option>
<option value="76235">Obudovac</option>
<option value="76290">Odzak</option>
<option value="74470">Vukosavlje</option>
<option value="88285">Odzak Kod Nevesinja</option>
<option value="71340">Olovo</option>
<option value="79203">Omarska</option>
<option value="78406">Orahova</option>
<option value="75323">Orahovica Donja</option>
<option value="76270">Orasje</option>
<option value="74412">Osinja</option>
<option value="74225">Osjecani</option>
<option value="75406">Osmaci</option>
<option value="79263">Ostra Luka</option>
<option value="88423">Ostrozac</option>
<option value="77228">Ostrozac Kod Cazina</option>
<option value="77244">Otoka</option>
<option value="72238">Ozimica</option>
<option value="78437">Palackovci</option>
<option value="71420">Pale</option>
<option value="75435">Papraca</option>
<option value="71243">Pazaric</option>
<option value="77227">Pecigrad</option>
<option value="76256">Pelagicevo</option>
<option value="72112">Perin Han</option>
<option value="74317">Petrovo</option>
<option value="75412">Pilica</option>
<option value="78217">Piskavica</option>
<option value="88305">Pocitelj</option>
<option value="72252">Poculica</option>
<option value="71425">Podgrab</option>
<option value="80209">Podhum</option>
<option value="71387">Podlugovi</option>
<option value="74217">Podnovlje</option>
<option value="75355">Podorasje Kod Srebrenika</option>
<option value="77232">Podzvizd</option>
<option value="75303">Poljice</option>
<option value="75320">Popovi</option>
<option value="88240">Posusje</option>
<option value="78216">Potkozarje</option>
<option value="78435">Potocani</option>
<option value="88208">Potoci</option>
<option value="73290">Praca</option>
<option value="73245">Prelovo</option>
<option value="79287">Previja</option>
<option value="74276">Pribinic</option>
<option value="75249">Priboj Kod Lopara</option>
<option value="79101">Prijedor</option>
<option value="80202">Priluka</option>
<option value="80245">Prisoje</option>
<option value="78430">Prnjavor</option>
<option value="80206">Prolog</option>
<option value="88440">Prozor</option>
<option value="70223">Prusac</option>
<option value="71335">Przici</option>
<option value="72207">Puhovac</option>
<option value="75305">Puracic</option>
<option value="88325">Radisici</option>
<option value="75268">Rainci Gornji</option>
<option value="88245">Rakitno</option>
<option value="71217">Rakovica</option>
<option value="80247">Rasko Polje</option>
<option value="78429">Razboj Lijevce</option>
<option value="76218">Razljevo</option>
<option value="79288">Ribnik</option>
<option value="77215">Ripac</option>
<option value="73220">Rogatica</option>
<option value="79226">Rudice</option>
<option value="73260">Rudo</option>
<option value="88347">Ruzici</option>
<option value="76230">Bosanski Samac</option>
<option value="79285">Sanica Gornja</option>
<option value="79260">Sanski Most</option>
<option value="75411">Sapna</option>
<option value="78202">Saracica</option>
<option value="71000">Sarajevo</option>
<option value="71103">Sarajevo, Centar</option>
<option value="71160">Sarajevo, Novi Grad</option>
<option value="71120">Sarajevo, Novo Sarajevo</option>
<option value="71140">Sarajevo, Stari Grad</option>
<option value="76209">Satorovici</option>
<option value="73305">Sekovici</option>
<option value="75450">Sekovici</option>
<option value="71321">Semizovac</option>
<option value="76205">Seonjaci</option>
<option value="75275">Serici</option>
<option value="75245">Sibosnica</option>
<option value="78433">Sibovska</option>
<option value="75207">Simin Han</option>
<option value="78364">Sipovo</option>
<option value="78224">Siprage</option>
<option value="88220">Siroki Brijeg</option>
<option value="78422">Sitnesi</option>
<option value="79283">Sitnica</option>
<option value="75436">Skelani</option>
<option value="74261">Skugric</option>
<option value="75353">Sladna</option>
<option value="78253">Slatina Ilidza</option>
<option value="78438">Smrtici</option>
<option value="74279">Snjegotina Gornja</option>
<option value="74323">Sockovac</option>
<option value="71350">Sokolac</option>
<option value="71210">Sokolovici</option>
<option value="88345">Sovici</option>
<option value="75356">Spionica</option>
<option value="78420">Srbac</option>
<option value="75430">Srebrenica</option>
<option value="75350">Srebrenik</option>
<option value="71385">Srednje</option>
<option value="79249">Sreflije</option>
<option value="76258">Srnice</option>
<option value="79224">Bosanska Kostajnica</option>
<option value="74450">Bosanski Brod</option>
<option value="73110">Istocno Gorazde</option>
<option value="76278">Istocno Orasje</option>
<option value="71123">Istocno Sarajevo</option>
<option value="74208">Stanari</option>
<option value="78243">Stara Dubrava</option>
<option value="79268">Stari Majdan</option>
<option value="77224">Stijena</option>
<option value="73223">Stjenice</option>
<option value="75324">Stjepan Polje</option>
<option value="88360">Stolac</option>
<option value="72209">Stranjani</option>
<option value="78208">Stricici</option>
<option value="75305">Strpci</option>
<option value="88323">Studenci</option>
<option value="75283">Stupari</option>
<option value="77223">Sturlic</option>
<option value="75344">Suho Polje</option>
<option value="80249">Sujica</option>
<option value="79229">Svodna</option>
<option value="71244">Tarcin</option>
<option value="75414">Teocak</option>
<option value="74260">Tesanj</option>
<option value="74266">Tesanjka</option>
<option value="74270">Teslic</option>
<option value="88348">Tihaljina</option>
<option value="75357">Tinja</option>
<option value="75455">Tisca</option>
<option value="77233">Todorovo</option>
<option value="75265">Tojsici</option>
<option value="76272">Tolisa</option>
<option value="79265">Tomina</option>
<option value="80240">Tomislavgrad</option>
<option value="72213">Topcic Polje</option>
<option value="72270">Travnik</option>
<option value="88375">Trebinja</option>
<option value="89000">Trebinje</option>
<option value="78252">Trn</option>
<option value="76335">Trnava Donja</option>
<option value="76310">Trnjaci</option>
<option value="71220">Trnovo</option>
<option value="77225">Trzacka Rastela</option>
<option value="72283">Turbe</option>
<option value="75306">Turija</option>
<option value="78404">Turjak Kod Bosanske Gradiske</option>
<option value="75000">Tuzla</option>
<option value="76330">Ugljevik</option>
<option value="74278">Ugodnovici</option>
<option value="71233">Ulog</option>
<option value="74230">Usora</option>
<option value="73250">Ustikolina</option>
<option value="73265">Uvac</option>
<option value="73249">Vardiste</option>
<option value="71330">Vares</option>
<option value="77245">Varoska Rijeka</option>
<option value="74213">Velika Bukovica</option>
<option value="77207">Velika Gata</option>
<option value="77230">Velika Kladusa</option>
<option value="76329">Velika Obarska</option>
<option value="88208">Vidosi</option>
<option value="76275">Vidovice</option>
<option value="70202">Vinac</option>
<option value="88247">Vir Kod Posusja</option>
<option value="73240">Visegrad</option>
<option value="88307">Visici</option>
<option value="72250">Vitez</option>
<option value="88326">Vitina</option>
<option value="74265">Vitkovci Donji</option>
<option value="73205">Vitkovici</option>
<option value="75440">Vlasenica</option>
<option value="71320">Vogosca</option>
<option value="71123">Vojkovici</option>
<option value="70246">Voljevac</option>
<option value="72227">Vozuca</option>
<option value="74488">Vranjak</option>
<option value="88113">Vrapcici</option>
<option value="75248">Vrazici</option>
<option value="78211">Vrbanja Kod Banja Luke</option>
<option value="78225">Vrbanjci</option>
<option value="78408">Vrbaska</option>
<option value="77231">Vrnograc</option>
<option value="76325">Vrsani</option>
<option value="77203">Vrsta</option>
<option value="76254">Vuckovci</option>
<option value="74470">Vukosavlje</option>
<option value="76273">Zabar Donji</option>
<option value="73287">Zaborak</option>
<option value="72220">Zabrdje</option>
<option value="76333">Zabrdje</option>
<option value="78221">Zabrdje Kod Kotor Varosi</option>
<option value="78214">Zaluzani</option>
<option value="72220">Zavidovici</option>
<option value="74451">Zboriste</option>
<option value="76259">Zelinja</option>
<option value="72236">Zeljezno Polje</option>
<option value="72000">Zenica</option>
<option value="72230">Zepce</option>
<option value="88268">Zitomislici</option>
<option value="75270">Zivinice</option>
<option value="71370">Zupca</option>
<option value="75400">Zvornik</option>
deploy.sh
sudo pkill -f rails
sudo pkill -f puma
sudo git checkout -- front-api/db/schema.rb
sudo git pull
cd front-api
bundle install
rvmsudo rake db:migrate
rvmsudo bundle exec puma -e production -b unix:///var/www/ribica/ribica_app.sock -d
cd ..
cd back-office
bundle install
rvmsudo RAILS_ENV=production rails s -d
cd ..
cd front-ui
sudo npm install
sudo grunt build
cd ..
sudo service nginx restart
start_elastic_search.sh
sudo /opt/elasticsearch-1.4.4/bin/./elasticsearch -Xmx512m -Xms512m -d
ribica.conf
upstream ribica_app {
server unix:///var/www/ribica/ribica_app.sock;
}
server {
listen 443 ssl;
server_name ribica.ba www.ribica.ba;
location / {
root /var/www/ribica/front-ui/build;
try_files $uri $uri/ /index.html;
}
location /backoffice {
auth_basic "Restricted";
auth_basic_user_file /etc/nginx/.htpasswd;
proxy_pass http://localhost:3000;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
location /api {
proxy_pass http://ribica_app;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
#listen 443;
ssl on;
ssl_certificate /etc/certifikati/SSL.crt;
ssl_certificate_key /etc/certifikati/www.ribica.ba.key;
ssl_protocols SSLv3 TLSv1 TLSv1.1 TLSv1.2;
ssl_ciphers HIGH:!aNULL:!MD5;
}
default
# You may add here your
# server {
# ...
# }
# statements for each of your virtual hosts to this file
##
# You should look at the following URL's in order to grasp a solid understanding
# of Nginx configuration files in order to fully unleash the power of Nginx.
# http://wiki.nginx.org/Pitfalls
# http://wiki.nginx.org/QuickStart
# http://wiki.nginx.org/Configuration
#
# Generally, you will want to move this file somewhere, and start with a clean
# file but keep this around for reference. Or just disable in sites-enabled.
#
# Please see /usr/share/doc/nginx-doc/examples/ for more detailed examples.
##
server {
listen 80 default_server;
server_name ribica.ba www.ribica.ba;
return 301 https://$server_name$request_uri;
# Make site accessible from http://localhost/
}
default - dev server
upstream ribica_app {
server unix:///var/www/ribica/ribica_app.sock;
}
server {
listen 80 default_server;
listen [::]:80 default_server;
location / {
root /var/www/ribica/front-ui/build;
try_files $uri $uri/ /index.html;
}
location /backoffice {
auth_basic "Restricted";
auth_basic_user_file /etc/nginx/.htpasswd;
proxy_pass http://localhost:3000;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
location /api {
proxy_pass http://ribica_app;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
}
~
~

BIN
back-office/.DS_Store vendored

Binary file not shown.

View File

@@ -1,6 +1,5 @@
source 'https://rubygems.org'
gem 'rails_admin'
# Bundle edge Rails instead: gem 'rails', github: 'rails/rails'
gem 'rails', '4.2.0'
@@ -25,12 +24,17 @@ gem 'jbuilder', '~> 2.0'
# bundle exec rake doc:rails generates the API under doc/api.
gem 'sdoc', '~> 0.4.0', group: :doc
gem 'tzinfo-data'
gem "nokogiri", ">= 1.6.6"
# great server
gem 'puma'
gem 'puma', '~> 2.15.3'
# for uploading images
gem 'cloudinary'
gem 'tabulous'
# Use ActiveModel has_secure_password
# gem 'bcrypt', '~> 3.1.7'
@@ -54,3 +58,4 @@ group :development, :test do
gem 'spring'
end
gem 'elasticsearch'

View File

@@ -1,9 +1,9 @@
GIT
remote: git://github.com/activescaffold/active_scaffold.git
revision: 4693e8a3278702143b1668fb5f6317b1c4f90388
revision: 6f637d62c7b4eb7ae49a28f6b8c9b86997a326a3
branch: master
specs:
active_scaffold (3.4.14)
active_scaffold (3.4.17)
rails (>= 3.2.18, < 5)
GEM
@@ -63,11 +63,23 @@ GEM
coffee-script-source
execjs
coffee-script-source (1.8.0)
colored (1.2)
columnize (0.9.0)
debug_inspector (0.0.2)
debugger-linecache (1.2.0)
elasticsearch (1.0.9)
elasticsearch-api (= 1.0.9)
elasticsearch-transport (= 1.0.9)
elasticsearch-api (1.0.9)
multi_json
elasticsearch-transport (1.0.9)
faraday
multi_json
erubis (2.7.0)
execjs (2.2.2)
faraday (0.9.1)
multipart-post (>= 1.2, < 3)
ffi (1.9.10-x64-mingw32)
font-awesome-rails (4.3.0.0)
railties (>= 3.2, < 5.0)
globalid (0.3.0)
@@ -97,13 +109,16 @@ GEM
mini_portile (0.6.2)
minitest (5.5.1)
multi_json (1.10.1)
multipart-post (2.0.0)
nested_form (0.3.2)
netrc (0.10.2)
nokogiri (1.6.5)
nokogiri (1.6.6.2)
mini_portile (~> 0.6.0)
nokogiri (1.6.6.2-x64-mingw32)
mini_portile (~> 0.6.0)
pg (0.18.1)
puma (2.10.2)
rack (>= 1.1, < 2.0)
pg (0.18.1-x64-mingw32)
puma (2.15.3)
rack (1.6.0)
rack-pjax (0.8.0)
nokogiri (~> 1.5)
@@ -155,6 +170,10 @@ GEM
rest-client (1.7.2)
mime-types (>= 1.16, < 3.0)
netrc (~> 0.7)
rest-client (1.7.2-x64-mingw32)
ffi (~> 1.9)
mime-types (>= 1.16, < 3.0)
netrc (~> 0.7)
safe_yaml (1.0.4)
sass (3.4.9)
sass-rails (5.0.1)
@@ -177,6 +196,9 @@ GEM
actionpack (>= 3.0)
activesupport (>= 3.0)
sprockets (>= 2.8, < 4.0)
tabulous (2.1.3)
colored (~> 1.2.0)
rails (>= 3.0, < 5.0.0)
thor (0.19.1)
thread_safe (0.3.4)
tilt (1.4.1)
@@ -184,6 +206,8 @@ GEM
coffee-rails
tzinfo (1.2.2)
thread_safe (~> 0.1)
tzinfo-data (1.2015.7)
tzinfo (>= 1.0.0)
uglifier (2.7.0)
execjs (>= 0.3.0)
json (>= 1.8.0)
@@ -195,22 +219,30 @@ GEM
PLATFORMS
ruby
x64-mingw32
DEPENDENCIES
active_scaffold!
byebug
cloudinary
coffee-rails (~> 4.1.0)
elasticsearch
jbuilder (~> 2.0)
jquery-rails
jquery-ui-rails
nokogiri (>= 1.6.6)
pg
puma
puma (~> 2.15.3)
rails (= 4.2.0)
rails_admin
sass-rails (~> 5.0)
sdoc (~> 0.4.0)
spring
tabulous
turbolinks
tzinfo-data
uglifier (>= 1.3.0)
web-console (~> 2.0)
BUNDLED WITH
1.10.6

Binary file not shown.

View File

@@ -0,0 +1,5 @@
class CheckItemsConstraint
def self.matches?(request)
request.params[:commit] == 'Check'
end
end

View File

@@ -0,0 +1,5 @@
class DeleteItemsConstraint
def self.matches?(request)
request.params[:commit] == 'Delete Items'
end
end

View File

@@ -1,4 +1,5 @@
class CartsController < ApplicationController
active_scaffold :"cart" do |conf|
end
end

View File

@@ -0,0 +1,4 @@
class DeliveryTimeEstimationsController < ApplicationController
active_scaffold :"delivery_time_estimation" do |conf|
end
end

View File

@@ -0,0 +1,4 @@
class ItemGroupsController < ApplicationController
active_scaffold :"item_group" do |conf|
end
end

View File

@@ -0,0 +1,4 @@
class ItemInGroupsController < ApplicationController
active_scaffold :"item_in_group" do |conf|
end
end

View File

@@ -3,4 +3,92 @@ class ItemsController < ApplicationController
conf.columns[:unit].form_ui = :select
conf.columns[:sub_category].form_ui = :select
end
def check_availability
@suppliers = Supplier.order(:name).all
@selected_supplier = Supplier.find_by_id(params[:supplier_id])
@items = @selected_supplier.try(:items) || []
@codes_to_check = params[:codes] || ""
@codes_to_check_array = @codes_to_check.split("\n").reject { |code| code.strip.blank? }.map(&:strip)
items_to_check = @items.map { |i| i.code.strip }
@missing_from_database = (@codes_to_check_array - items_to_check) || []
@missing_from_codes = (items_to_check - @codes_to_check_array) || []
end
def delete_items
@suppliers = Supplier.order(:name).all
@selected_supplier = Supplier.find_by_id(params[:supplier_id])
@items = @selected_supplier.try(:items) || []
@codes_to_check = params[:codes] || ""
@codes_to_check_array = @codes_to_check.split("\n").reject { |code| code.strip.blank? }.map(&:strip)
items_to_check = @items.map { |i| i.code.strip }
@items_for_delete = items_to_check & @codes_to_check_array
Item.where(:code => @items_for_delete).destroy_all
@not_deleted_items = (@codes_to_check_array - @items_for_delete) || []
render :template => "items/check_availability"
end
def export_import
@tasks = [ ["Validate items", "validate_items"],
["Import items", "import_items"],
["Update prices", "update_prices"] ]
@task = "validate_items"
end
def export_import_post
@tasks = [ ["Validate items", "validate_items"],
["Import items", "import_items"],
["Update prices", "update_prices"] ]
@task = params[:task]
@csv_content = params[:csv_content]
@error_message = ""
@output = []
if params[:csv_content] == ""
@error_message = "Format of CSV is wrong (CSV content is empty)"
else
begin
csv_parsed = CSV.parse(params[:csv_content])
rescue CSV::MalformedCSVError => er
@error_message = "Format of CSV is wrong (#{er.message})"
end
unless csv_parsed.nil?
csv_file = ItemsHelper::create_csv(csv_parsed)
begin
ENV["INPUT"] = csv_file.path
case @task
when 'validate_items'
@output = ItemsHelper::execute_command("rake ribica:validate_items -f #{Rails.root}/Rakefile")
@output.collect{|x| x.sub! "\n", "" }
when 'import_items'
@output = ItemsHelper::execute_command("rake ribica:import_items -f #{Rails.root}/Rakefile")
@output.collect{|x| x.sub! "\n", "" }
%x(rake ribica:reindex -f #{Rails.root}/Rakefile) unless RakeTasksHelper::is_error_occurred @output
when 'update_prices'
@output = ItemsHelper::execute_command("rake ribica:update_prices -f #{Rails.root}/Rakefile")
%x(rake ribica:reindex -f #{Rails.root}/Rakefile) unless RakeTasksHelper::is_error_occurred @output
else
@error_message = "There is no such task"
end
ensure
csv_file.unlink
end
end
@output = @output.join("<br/>")
end
render :template => "items/export_import"
end
end

View File

@@ -0,0 +1,4 @@
class LinkBannersController < ApplicationController
active_scaffold :"link_banner" do |conf|
end
end

View File

@@ -0,0 +1,4 @@
class PlacesController < ApplicationController
active_scaffold :"place" do |conf|
end
end

View File

@@ -0,0 +1,11 @@
class ReportsController < ApplicationController
def items_to_order
@report = Item.items_to_order
end
def orders_to_confirm
@report = Item.orders_to_confirm
end
end

View File

@@ -0,0 +1,4 @@
class SuppliersController < ApplicationController
active_scaffold :"supplier" do |conf|
end
end

View File

@@ -1,2 +1,4 @@
module ApplicationHelper
end

View File

@@ -1,2 +1,6 @@
module CartsHelper
def money(amount)
sprintf('%.2f KM', amount.to_f)
end
end

View File

@@ -0,0 +1,2 @@
module DeliveryTimeEstimationsHelper
end

View File

@@ -0,0 +1,2 @@
module ItemGroupsHelper
end

View File

@@ -0,0 +1,2 @@
module ItemInGroupsHelper
end

View File

@@ -1,5 +1,27 @@
module ItemsHelper
def self.create_csv(data)
file = Tempfile.new([Rails.root.join('tmp/').to_s, ".csv"], "")
csv = CSV.new(file)
data.each do |row|
csv << row
end
file.rewind
file.close
file
end
def self.execute_command(command)
buffer = []
Open3.popen3(command) do |stdin, stdout, stderr|
begin
while line = stdout.readline
buffer << line
end
rescue
end
end
buffer
end
end

View File

@@ -0,0 +1,2 @@
module LinkBannersHelper
end

View File

@@ -0,0 +1,2 @@
module PlacesHelper
end

View File

@@ -0,0 +1,9 @@
module RakeTasksHelper
def self.task_error_message
"Rake task execution error"
end
def self.is_error_occurred(buffer)
buffer.include? self.task_error_message
end
end

View File

@@ -0,0 +1,2 @@
module SuppliersHelper
end

View File

@@ -0,0 +1,3 @@
class Brand < ActiveRecord::Base
has_many :items
end

View File

@@ -1,2 +1,26 @@
class Cart < ActiveRecord::Base
has_many :item_in_carts
belongs_to :user
belongs_to :delivery_destination
def delivery_cost
place = delivery_destination.gift ? Place.by_code_or_default(delivery_destination.recipient_place)
: Place.by_code_or_default(delivery_destination.place)
if delivery_destination.instant_delivery
place.instant_delivery_price
else
place.delivery_price
end
end
def total
sum = item_in_carts.inject (0) { |sum, iic| sum + (iic.price * iic.count) }
sum += delivery_cost
end
def confirmed_at
delivery_destination.updated_at.in_time_zone('Europe/Sarajevo')
end
end

View File

@@ -1,2 +1,14 @@
class DeliveryDestination < ActiveRecord::Base
def get_payment_string
case self.payment_method
when 'cash_on_delivery'
'Prilikom preuzimanja'
when 'paypal'
'Paypal'
when 'pikpay'
'Pikpay'
else
'Nepoznato'
end
end
end

View File

@@ -0,0 +1,2 @@
class DeliveryTimeEstimation < ActiveRecord::Base
end

View File

@@ -1,7 +1,138 @@
class Item < ActiveRecord::Base
CSV_COL = {
:code => 0,
:input_price => 1,
:list_price => 2,
:decoration => 3
}
belongs_to :unit
has_many :multi_media_descriptions
belongs_to :sub_category
belongs_to :supplier
belongs_to :brand
belongs_to :delivery_time_estimation
validates_presence_of :name, :description, :list_price, :current_input_price, :tags, :unit_id, :code, :sub_category_id, :weight, :supplier_id
validate :we_must_earn_money
def self.items_to_order
items_raw = Item.find_by_sql(%Q{
select s.id as supplier_id, i.code as code, i.name as name, sum(iic.count) amount, i.current_input_price
from carts c
left join item_in_carts iic on iic.cart_id = c.id
left join items i on i.id = iic.item_id
left join suppliers s on i.supplier_id = s.id
where c.confirmed and not (c.packed or c.delivered)
group by s.id, i.name, i.code, i.current_input_price
order by s.name, amount desc;
})
items_sorted = {}
suppliers_sorted = {}
items_raw.each do |item|
items_sorted[item.supplier_id] ||= []
suppliers_sorted[item.supplier_id] ||= item.supplier
items_sorted[item.supplier_id] << item
end
report_items = []
complete_sum = 0
suppliers_sorted.each_pair do |key, value|
rep_sec = OpenStruct.new # report section
rep_sec.supplier = value
rep_sec.items = items_sorted[key]
rep_sec.sum_amount = rep_sec.items.reduce(0) do |sum, item|
sum + (item.current_input_price * item.amount)
end
complete_sum += rep_sec.sum_amount
report_items << rep_sec
end
full_report = OpenStruct.new
full_report.sections = report_items
full_report.full_sum = complete_sum
return full_report
end
def self.orders_to_confirm
items_raw = Item.find_by_sql(%Q{
select dd.*, c.id as order_id,i.code as code, i.name as item, iic.count as amount , i.list_price, iic.count * i.list_price as sum_price
from carts c
left join delivery_destinations dd on c.delivery_destination_id = dd.id
left join item_in_carts iic on iic.cart_id = c.id
left join items i on i.id = iic.item_id
where c.ordered and not(c.canceled_on_check or c.canceled_on_delivery or c.confirmed or c.packed or c.delivered)
order by
c.created_at, iic.created_at;
})
items_sorted = {}
items_raw.each do |item|
items_sorted[item.phone] ||= []
items_sorted[item.phone] << item
end
sections = []
complete_sum = 0
items_sorted.each_pair do |key,values|
section = OpenStruct.new
section.delivery_destination = values.first
section.sum_amount = 0
section.items = []
values.each do |item|
section.sum_amount += item.sum_price
complete_sum += item.sum_price
section.items << item
end
sections << section
end
full_report = OpenStruct.new
full_report.sections = sections
full_report.full_sum = complete_sum
return full_report
end
def self.update_prices(path)
nonexistent_codes = []
Item.transaction do
CSV.foreach(path) do |row|
code = row[CSV_COL[:code]].strip
item = Item.find_by_code(code)
if item.nil?
nonexistent_codes << code
else
item.current_input_price = row[CSV_COL[:input_price]]
item.list_price = row[CSV_COL[:list_price]]
item.decoration = row[CSV_COL[:decoration]]
item.save!
end
end
end
puts "Nonexistent codes: "
puts "#{nonexistent_codes.join("\n")}"
end
def we_must_earn_money
if list_price.to_f <= current_input_price.to_f
errors[:list_price] << "#{code} Ulazna cijena veca od izlazne"
puts "#{code} Ulazna cijena veca od izlazne"
end
end
validates_presence_of :name, :description, :list_price, :current_input_price, :tags, :unit_id, :code, :sub_category_id
end

View File

@@ -0,0 +1,5 @@
class ItemGroup < ActiveRecord::Base
end

View File

@@ -5,4 +5,12 @@ class ItemInCart < ActiveRecord::Base
validates_uniqueness_of :item_id, scope: :cart_id
validates :item_id, presence: true
validates :cart_id, presence: true
def name
if item
item.name + " " + count.to_s + " " + price.to_s
else
" no item "
end
end
end

View File

@@ -0,0 +1,8 @@
class ItemInGroup < ActiveRecord::Base
belongs_to :item_group
belongs_to :item
validates_presence_of :item_group_id
validates_presence_of :item_id
validates_presence_of :position
end

View File

@@ -0,0 +1,15 @@
class LinkBanner < ActiveRecord::Base
belongs_to :category
belongs_to :section
belongs_to :sub_category
validates_presence_of :beginning, :ending, :image_url
validate :validate_beginning_before_ending
def validate_beginning_before_ending
if beginning && ending
errors.add(:ending, "End date must come after beginning date") if ending <= beginning
end
end
end

View File

@@ -0,0 +1,3 @@
class MenuItem < ActiveRecord::Base
has_many :menu_sub_items
end

View File

@@ -0,0 +1,4 @@
class MenuSubItem < ActiveRecord::Base
belongs_to :menu_item
has_many :menu_sub_sub_items
end

View File

@@ -0,0 +1,3 @@
class MenuSubSubItem < ActiveRecord::Base
belongs_to :menu_sub_item
end

View File

@@ -0,0 +1,533 @@
class Place < ActiveRecord::Base
def self.name_from_code(code)
places_bulk = %Q{Aleksandrovac 78255
Avtovac 89245
Balatun 76310
Banja Luka 78000
Banovici 75290
Batkovic 76312
Begov Han 72233
Berkovici 88363
Bihac 77000
Bijela 76204
Bijeljina 76300
Bijelo Brdo 73263
Bileca 89230
Biljesevo 72248
Bjelimici 88407
Blagaj 88201
Blatnica 74275
Blatnica Kod Mostara 88263
Blazuj 71215
Bok 76277
Boljanic 74322
Bosanska Krupa 77240
Bosanski Petrovac 77250
Bosansko Grahovo 80270
Bradina 88408
Bratunac 75420
Brcko 76000
Brcko Distrikt 76100
Brekovica 77205
Brestovo 74210
Brestovsko 71255
Breza 71370
Brezicani 79208
Brezik 76109
Brezovo Polje 76216
Brijesnica 74206
Brijesnica Kod Doboja 74206
Brijesnica Mala 74206
Brijesnica Velika 74206
Brka 76206
Brnjic 72243
Brocanac 88243
Brocanac 88243
Brod Kod Foce 73309
Brodac 76313
Bronzani Majdan 78204
Bucici 72290
Bugojno 70230
Bukinje 75203
Buletic 74277
Buna 88202
Busovaca 72260
Buturovicpolje 88409
Buzim 77245
Cajnice 73280
Caparde 75405
Capljina 88300
Cardak 72224
Careva Cuprija 71347
Catici 72246
Cazin 77220
Cecava 74274
Celebici 88404
Celebici Lusnic 80203
Celebici Kod Foce 73307
Celic 75246
Celinac 78240
Cemerno 89243
Cerin 88265
Cerovica 74211
Cerovljani 78403
Citluk 88260
Coralici 77226
Crkvina 76239
Crnici 88367
Crnjelovo 76328
Dejcici 71221
Demirovac 79243
Derventa 74400
Derventa Kod Vlasenice 75444
Divin 89233
Doboj 74000
Doboj Istok 74206
Doboj Jug 74203
Doborovci 75328
Dobosnica 75308
Dobretici 77210
Dobrinja 71245
Dobrljin 79223
Dobro Selo 77242
Dobrun 73247
Dokanj 75206
Dolac Na Lasvi 72278
Domaljevac 76233
Domanovici 88305
Donja Mahala 76274
Donja Medjidja 76257
Donja Slatina 76327
Donje Mostre 71305
Donji Agici 79228
Donji Memici 88343
Donji Vakuf 70220
Donji Vijacani 78432
Donji Vrbljani 79289
Donji Zabar 76273
Dragaljevac 76323
Dragalovci 74209
Dragocaj 78215
Dreznica 88215
Drinjaca 75410
Drinovci 88344
Drvar 80260
Duboki Potok 75358
Dubostica 75308
Dubrave 78411
Dubrave Donje 75274
Dubrave Gornje 75273
Dubrovik 79227
Dugo Polje 74483
Djurdjevik 75272
Dusanovo 75445
Duzice 88342
Dvorovi 76311
Fajtovci 79264
Foca 73300
Fojnica 71270
Fojnica Kod Gacka 89247
Gabela Polje 88306
Gacko 89240
Glamoc 80230
Glavicice 76318
Globarica 72230
Gojevici 71275
Gorazde 73000
Gorica 88340
Gornja Koprivna 77222
Gornja Slatina 76238
Gornja Tuzla 75208
Gornji Kamengrad 79266
Gornji Podgradci 78405
Gornji Rahic 76207
Gornji Strpci 78439
Gornji Teslic 74272
Gornji Vakuf Uskoplje 70240
Gornji Zovik 76207
Grab 89201
Grabovica 78227
Gracanica 75320
Gracanica Kod Bugojna 70233
Gracanica Selo 75276
Gradac 88392
Gradacac 76250
Gradiska 78400
Grude 88340
Guber 80205
Listani 80204
Guca Gora 72277
Hadzici 71240
Hajdarevici 72225
Haljinici 72245
Han Bila 72281
Han Pijesak 71360
Hrasnica 71212
Hrasno 88395
Hresa 71144
Hrvacani 78436
Husino 75216
Hutovo 88394
Ilidza 71210
Ilijas 71380
Ilovaca 73208
Imljani 78234
Izacic 77208
Jablanica 88420
Jahorina 71423
Jajce 70101
Janja 76316
Janjici 72215
Jare 88224
Javorani 78233
Jelah 74264
Jezerski 77241
Johova 79244
Josanica 73319
Josavka 78244
Kacuni 72264
Kakanj 72240
Kalenderovci 74413
Kalesija 75260
Kalinovik 71230
Kamenica 77204
Kaonik 72265
Kasindo 71213
Kazaginac 80246
Kifino Selo 88283
Kiseljak 71250
Kiseljak, Kod Tuzle 75211
Kladanj 75280
Klakar Donji 74452
Kljuc 79280
Klobuk 88324
Klokotnica 74207
Knezevo 78230
Skender Vakuf 78230
Knezica 79246
Knezina 71356
Kobas 78423
Kocerin 88226
Kocicevo 78409
Kola 78207
Kongora 80244
Konjic 88400
Konjoder 77249
Koprivna 74489
Koraj 75247
Kornica 76236
Kosova 74253
Kostric 76276
Kotor Varos 78220
Kotorsko 74215
Kovaci 72226
Kozarac 79002
Bosanska Dubica 79240
Kozluk 75413
Kraljeva Sutjeska 72244
Kresevo 71260
Kriskovci 78256
Krupa Na Vrbasu 78206
Krusevo 88203
Kukulje 78424
Kula 71216
Kulasi 78443
Kulen Vakuf 77206
Kupres 80320
Laktasi 78250
Laminci Sredjani 78407
Lamovita 79204
Lastva 89208
Lasva 72216
Liplje 78222
Lipnica 75213
Lisnja 78434
Livno 80101
Ljubace 75214
Ljubija 79206
Ljubinje 88380
Ljubomir 89209
Ljubuski 88320
Ljuti Dolac 88223
Loncari 76278
Lopare 75240
Lukavac 75300
Lukavac Mjesto 75301
Lukavica 75327
Lusci Palanka 79267
Maglaj 74250
Majevac 74216
Mala Kladusa 77235
Mala Socanica 74418
Malesici 75320
Maoca 76208
Masici 78410
Maslovare 78223
Matici 76271
Matuzici 74203
Medjugorje 88266
Medjuvodje 79247
Mehurici 72282
Mesihovina 80243
Milici 75446
Miljeno 73283
Miljevina 73313
Milosevac 74485
Miricina 75329
Modrica 74480
Mokro 71428
Mosko 89204
Mostar 88000
Mostar, Jug 88000
Mostar, Jugozapad 88000
Mostar, Sjever 88000
Mostar, Zapad 88000
Mramor 75212
Mravinjac 73206
Mrkodol 79544
Mrkonjic Grad 70260
Nemila 72212
Neum 88390
Nevesinje 88280
Nova Bila 72276
Nova Topola 78418
Bosanski Novi 79220
Novi Seher 74254
Novi Travnik 72290
Nozicko 78428
Oborci 70225
Obudovac 76235
Odzak 76290
Vukosavlje 74470
Odzak Kod Nevesinja 88285
Olovo 71340
Omarska 79203
Orahova 78406
Orahovica Donja 75323
Orasje 76270
Osinja 74412
Osjecani 74225
Osmaci 75406
Ostra Luka 79263
Ostrozac 88423
Ostrozac Kod Cazina 77228
Otoka 77244
Ozimica 72238
Palackovci 78437
Pale 71420
Papraca 75435
Pazaric 71243
Pecigrad 77227
Pelagicevo 76256
Perin Han 72112
Petrovo 74317
Pilica 75412
Piskavica 78217
Pocitelj 88305
Poculica 72252
Podgrab 71425
Podhum 80209
Podlugovi 71387
Podnovlje 74217
Podorasje Kod Srebrenika 75355
Podzvizd 77232
Poljice 75303
Popovi 75320
Posusje 88240
Potkozarje 78216
Potocani 78435
Potoci 88208
Praca 73290
Prelovo 73245
Previja 79287
Pribinic 74276
Priboj Kod Lopara 75249
Prijedor 79101
Priluka 80202
Prisoje 80245
Prnjavor 78430
Prolog 80206
Prozor 88440
Prusac 70223
Przici 71335
Puhovac 72207
Puracic 75305
Radisici 88325
Rainci Gornji 75268
Rakitno 88245
Rakovica 71217
Rasko Polje 80247
Razboj Lijevce 78429
Razljevo 76218
Ribnik 79288
Ripac 77215
Rogatica 73220
Rudice 79226
Rudo 73260
Ruzici 88347
Bosanski Samac 76230
Sanica Gornja 79285
Sanski Most 79260
Sapna 75411
Saracica 78202
Sarajevo 71000
Sarajevo, Centar 71103
Sarajevo, Novi Grad 71160
Sarajevo, Novo Sarajevo 71120
Sarajevo, Stari Grad 71140
Satorovici 76209
Sekovici 73305
Sekovici 75450
Semizovac 71321
Seonjaci 76205
Serici 75275
Sibosnica 75245
Sibovska 78433
Simin Han 75207
Sipovo 78364
Siprage 78224
Siroki Brijeg 88220
Sitnesi 78422
Sitnica 79283
Skelani 75436
Skugric 74261
Sladna 75353
Slatina Ilidza 78253
Smrtici 78438
Snjegotina Gornja 74279
Sockovac 74323
Sokolac 71350
Sokolovici 71210
Sovici 88345
Spionica 75356
Srbac 78420
Srebrenica 75430
Srebrenik 75350
Srednje 71385
Sreflije 79249
Srnice 76258
Bosanska Kostajnica 79224
Bosanski Brod 74450
Istocno Gorazde 73110
Istocno Orasje 76278
Istocno Sarajevo 71123
Stanari 74208
Stara Dubrava 78243
Stari Majdan 79268
Stijena 77224
Stjenice 73223
Stjepan Polje 75324
Stolac 88360
Stranjani 72209
Stricici 78208
Strpci 75305
Studenci 88323
Stupari 75283
Sturlic 77223
Suho Polje 75344
Sujica 80249
Svodna 79229
Tarcin 71244
Teocak 75414
Tesanj 74260
Tesanjka 74266
Teslic 74270
Tihaljina 88348
Tinja 75357
Tisca 75455
Todorovo 77233
Tojsici 75265
Tolisa 76272
Tomina 79265
Tomislavgrad 80240
Topcic Polje 72213
Travnik 72270
Trebinja 88375
Trebinje 89000
Trn 78252
Trnava Donja 76335
Trnjaci 76310
Trnovo 71220
Trzacka Rastela 77225
Turbe 72283
Turija 75306
Turjak Kod Bosanske Gradiske 78404
Tuzla 75000
Ugljevik 76330
Ugodnovici 74278
Ulog 71233
Usora 74230
Ustikolina 73250
Uvac 73265
Vardiste 73249
Vares 71330
Varoska Rijeka 77245
Velika Bukovica 74213
Velika Gata 77207
Velika Kladusa 77230
Velika Obarska 76329
Vidosi 88208
Vidovice 76275
Vinac 70202
Vir Kod Posusja 88247
Visegrad 73240
Visici 88307
Visoko 71300
Vitez 72250
Vitina 88326
Vitkovci Donji 74265
Vitkovici 73205
Vlasenica 75440
Vogosca 71320
Vojkovici 71123
Voljevac 70246
Vozuca 72227
Vranjak 74488
Vrapcici 88113
Vrazici 75248
Vrbanja Kod Banja Luke 78211
Vrbanjci 78225
Vrbaska 78408
Vrnograc 77231
Vrsani 76325
Vrsta 77203
Vuckovci 76254
Vukosavlje 74470
Zabar Donji 76273
Zaborak 73287
Zabrdje 72220
Zabrdje 76333
Zabrdje Kod Kotor Varosi 78221
Zaluzani 78214
Zavidovici 72220
Zboriste 74451
Zelinja 76259
Zeljezno Polje 72236
Zenica 72000
Zepce 72230
Zitomislici 88268
Zivinice 75270
Zupca 71370
Zvornik 75400}
separator = /(.*)\s(\d{5})/
places = places_bulk.split("\n")
places.each do |place|
matches = separator.match(place)
return matches[1].strip if matches and matches[2] === code
end
return "<nepoznato mjesto>";
end
def self.by_code_or_default(code)
# removes garbage and converts whitespace prefixed codes correctly - like " 71000" -> 71000
valid_code = code.to_i.to_s
place = Place.where(postal_code: valid_code).first
place ||= Place.where("postal_code is null or postal_code = ''").first
return place
end
end

View File

@@ -0,0 +1,6 @@
class Supplier < ActiveRecord::Base
has_many :items
validates_uniqueness_of :name
validates_presence_of :name
end

View File

@@ -0,0 +1,10 @@
class User < ActiveRecord::Base
has_many :carts
validates_presence_of :first_name, :last_name, :password, :email, :password_confirmation
validates :email, :uniqueness => {:case_sensitive => false, :message => "Email already exists!"},
format: { with: /\A([^@\s]+)@((?:[-a-z0-9]+\.)+[a-z]{2,})\z/i, message: "invalid email" }
validates :password, confirmation: true, length: { in:6..20, too_short: 'password needs to be at least 6 characters long' }
end

View File

@@ -0,0 +1,13 @@
Tabulous.setup do
tabs do
get_from_suppliers_tab do
text { 'From suppliers' }
link_path { '/' }
visible_when { true }
enabled_when { true }
active_when { in_action('any').of_controller('pictures') }
end
end
end

View File

@@ -0,0 +1,87 @@
<style type="text/css">
.tg { }
.tg td{ }
.tg th{ }
</style>
<%
dd = @record.delivery_destination
c = @record
%>
<p>
<p><strong>Ime:</strong> <%= dd.name %><br /><br /></p>
<p><strong>Adresa:</strong><br />
<%= dd.address %><br />
<%= dd.place.to_s.strip %> <%= Place.name_from_code(dd.place.to_s) %><br />
Bosna i Hercegovina<br /><br />
</p>
<p><strong>Email: </strong><%= dd.email %><br />
</p>
<p><strong>Telefon: </strong> +387 <%= dd.phone %><br /><br />
</p>
<p><strong>Plaćanje: </strong><%= dd.get_payment_string %></p><br />
<p><strong>Napomena: </strong><br />
<%= dd.note %><br /><br />
</p>
</p>
<% if dd.gift %>
<p><strong>Ovo je poklon</strong><br /><br />
<p><strong>Ime primaoca: </strong><%= dd.recipient_name %><br />
<p><strong>Adresa primaoca: </strong><%= dd.recipient_address %><br />
<p><strong>Postanski broj primaoca: </strong><%= dd.recipient_postal_code %><br />
<p><strong>Grad primaoca: </strong><%= dd.recipient_place %><br />
<p><strong>Email primaoca: </strong><%= dd.recipient_email %><br />
<p><strong>Telefon primaoca: </strong><%= dd.recipient_phone %><br /><br />
<% end %>
<p>
<strong>Naručeno:</strong> <%= c.confirmed_at.in_time_zone("Europe/Sarajevo").strftime("%A %d.%m.%Y. %H:%M") %>
<br />
<br />
</p>
<% if dd.instant_delivery %>
<p style="font-size: 120%;">
OVO JE NARUDŽBA ZA INSTANT DOSTAVU
</p>
<% end %>
<table class="tg">
<tr>
<th class="tg-031e">Code</th>
<th class="tg-031e">Item name</th>
<th style="text-align: right; ">Amount</th>
<th style="text-align: right; ">Price</th>
<th style="text-align: right; ">Total</th>
</tr>
<% @record.item_in_carts.each do |iic| %>
<tr>
<td class="tg-031e"><%= iic.item.code %></td>
<td class="tg-031e"><%= iic.item.name %></td>
<td style="text-align: right; "><%= iic.count %></td>
<td style="text-align: right; "><%= money(iic.price) %></td>
<td style="text-align: right; "><%= money(iic.count * iic.price) %></td>
</tr>
<% end %>
<tr>
<td class="tg-031e"></td>
<td class="tg-031e">Dostava</td>
<td style="text-align: right; ">1</td>
<td style="text-align: right; "><%= money(c.delivery_cost) %></td>
<td style="text-align: right; "><%= money(c.delivery_cost) %></td>
</tr>
<tr>
<td class="tg-031e"><strong>UKUPNO:</strong></td>
<td class="tg-031e"></td>
<td style="text-align: right; "></td>
<td style="text-align: right; "></td>
<td style="text-align: right; "><%= money(c.total) %></td>
</tr>
<tr><td><strong> </strong></td></tr>
</table>
<br /><br />

View File

@@ -0,0 +1,49 @@
<%= form_tag('./check_availability') do %>
<p><label for="supplier_id">Supplier: </label>
<%= select_tag "supplier_id", options_from_collection_for_select(@suppliers, "id", "name", @selected_supplier.try(:id)) %></p>
<p><label for="codes">
Codes to check:
</label><br />
<%= text_area_tag "codes", @codes_to_check, rows: 20, columns: 50 %></p>
<p><%= submit_tag "Check" %></p>
<p><%= submit_tag "Delete Items" %></p>
<% end %>
<% if controller.action_name == 'delete_items' %>
<h2> Delete successful </h2>
<% if @not_deleted_items.length > 0 %>
<p>Not deleted items</p>
<% @not_deleted_items.each do |code| %>
<%= code %><br />
<% end %>
<% end %>
<% else %>
<div>
<h2> In database: <%= @items.length %>, in file: <%= @codes_to_check_array.length %> </h2>
</div>
<div>
<h2>Not in database (<%= @missing_from_database.length %>): </h2>
<br />
<% @missing_from_database.each do |code| %>
<%= code %><br />
<% end %>
</div>
<div>
<h2>Not in file (<%= @missing_from_codes.length %>): </h2>
<br />
<% @missing_from_codes.each do |code| %>
<%= code %><br />
<% end %>
</div>
<% end %>

View File

@@ -0,0 +1,21 @@
<%= form_tag('./export_import') do %>
<p><label for="codes">
CSV content goes here:
</label><br />
<textarea id="csv_content" name="csv_content" rows=20 style="width: 100%"><%= @csv_content %></textarea></p>
<p><label for="task">Task: </label>
<%= select_tag "task", options_for_select(@tasks, @task) %></p>
<p><%= submit_tag "Run task" %></p>
<% if !@error_message.nil? && @error_message != "" %>
<div>Error message: <span style="color: red"><%= @error_message %></span></div>
<% end %>
<br />
<p><label for="output_area">Output area: </label>
<div id="output_area" style="width: 100%;height: 14em;outline: 1px solid #A9A9A9; overflow: scroll"><%= unless @output.nil?
@output.html_safe end %>
</div>
<% end %>

View File

@@ -0,0 +1,34 @@
<%= form_tag('./import') do %>
<p><label for="supplier_id">Supplier: </label>
<%= select_tag "supplier_id", options_from_collection_for_select(@suppliers, "id", "name", @selected_supplier.try(:id)) %></p>
<p><label for="codes">
Codes to check:
</label><br />
<%= text_area_tag "codes", @codes_to_check, rows: 20, columns: 50 %></p>
<p><%= submit_tag "Check" %></p>
<% end %>
<div>
<h2> In database: <%= @items.length %>, in file: <%= @codes_to_check_array.length %> </h2>
</div>
<div>
<h2>Not in database (<%= @missing_from_database.length %>): </h2>
<br />
<% @missing_from_database.each do |code| %>
<%= code %><br />
<% end %>
</div>
<div>
<h2>Not in file (<%= @missing_from_codes.length %>): </h2>
<br />
<% @missing_from_codes.each do |code| %>
<%= code %><br />
<% end %>
</div>

View File

@@ -0,0 +1,32 @@
<style type="text/css">
.tg {border-collapse:collapse;border-spacing:0;}
.tg td{font-family:Arial, sans-serif;font-size:14px;padding:10px 5px;border-style:solid;border-width:1px;overflow:hidden;word-break:normal;}
.tg th{font-family:Arial, sans-serif;font-size:14px;font-weight:normal;padding:10px 5px;border-style:solid;border-width:1px;overflow:hidden;word-break:normal;}
</style>
<div><%= "report is nil" if @report.nil? %></div>
<table class="tg">
<tr>
<th class="tg-031e">Code</th>
<th class="tg-031e">Item name</th>
<th class="tg-031e">Amount</th>
<th class="tg-031e">Price</th>
<th class="tg-031e">Total</th>
</tr>
<% unless @report.nil? %>
<% @report.sections.each do |section| %>
<tr><td><%= section.supplier.name %></td></tr>
<% section.items.each do |item| %>
<tr>
<td class="tg-031e"><%= item.code %></td>
<td class="tg-031e"><%= item.name %></td>
<td class="tg-031e"><%= item.amount %></td>
<td class="tg-031e"><%= item.current_input_price %></td>
<td class="tg-031e"><%= item.current_input_price * item.amount %></td>
</tr>
<% end %>
<tr><td>Sub-total: <%= section.sum_amount %></td></tr>
<% end %>
<tr><td><strong>Total: <%= @report.full_sum %></strong> </td></tr>
<% end %>
</table>

View File

@@ -0,0 +1,61 @@
<style type="text/css">
.tg {border-collapse:collapse;border-spacing:0;}
.tg td{font-family:Arial, sans-serif;font-size:14px;padding:10px 5px;border-style:solid;border-width:1px;overflow:hidden;word-break:normal;}
.tg th{font-family:Arial, sans-serif;font-size:14px;font-weight:normal;padding:10px 5px;border-style:solid;border-width:1px;overflow:hidden;word-break:normal;}
</style>
<div><%= "report is nil" if @report.nil? %></div>
<% unless @report.nil? %>
<% @report.sections.each do |section| %>
<div>
<hr>
<% unless section.delivery_destination.nil? %>
<div><%= section.delivery_destination.name %></div>
<div><%= section.delivery_destination.address %> </div>
<div><%= section.delivery_destination.place %> <%= Place.name_from_code(section.delivery_destination.place) %></div>
<div><%= section.delivery_destination.email %></div>
<div><strong><%= section.delivery_destinati on.phone %></strong></div>
<% end %>
<p>
<table class="tg">
<tr>
<th class="tg-031e">Code</th>
<th class="tg-031e">Item name</th>
<th class="tg-031e">Amount</th>
<th class="tg-031e">Price</th>
<th class="tg-031e">Total</th>
</tr>
<% section.items.each do |item| %>
<tr>
<td class="tg-031e"><%= item.code %></td>
<td class="tg-031e"><%= item.name %></td>
<td class="tg-031e"><%= item.amount %></td>
<td class="tg-031e"><%= item.list_price %></td>
<td class="tg-031e"><%= item.sum_price %></td>
</tr>
<% end %>
<tr><td><strong>Total for cart: <%= section.sum_amount %></strong></td></tr>
</table>
</p>
</div>
<div><a href="<%= rails_admin.edit_url(model_name: 'cart', id: section.delivery_destination.order_id.to_i)%>" >Update Order</a></div>
<% end %>
<strong>Total: <%= @report.full_sum %></strong>
<% end %>

View File

@@ -1,6 +1,8 @@
require File.expand_path('../boot', __FILE__)
require 'rails/all'
require 'rake'
require 'open3'
# Require the gems listed in Gemfile, including any gems
# you've limited to :test, :development, or :production.
@@ -22,5 +24,6 @@ module Ribicabackoffice
# Do not swallow errors in after_commit/after_rollback callbacks.
config.active_record.raise_in_transactional_callbacks = true
config.assets.precompile += %w(*.svg *.eot *.woff *.ttf *.gif *.png *.ico)
end
end

View File

@@ -81,6 +81,6 @@ test:
production:
<<: *default
database: ribica
username: postgres
password: testni_hamo2
username: ribicadatabase
password: super*kicma*plazma*sunce
host: localhost

View File

@@ -0,0 +1,86 @@
# PostgreSQL. Versions 8.2 and up are supported.
#
# Install the pg driver:
# gem install pg
# On OS X with Homebrew:
# gem install pg -- --with-pg-config=/usr/local/bin/pg_config
# On OS X with MacPorts:
# gem install pg -- --with-pg-config=/opt/local/lib/postgresql84/bin/pg_config
# On Windows:
# gem install pg
# Choose the win32 build.
# Install PostgreSQL and put its /bin directory on your path.
#
# Configure Using Gemfile
# gem 'pg'
#
default: &default
adapter: postgresql
encoding: unicode
# For details on connection pooling, see rails configuration guide
# http://guides.rubyonrails.org/configuring.html#database-pooling
pool: 5
development:
<<: *default
database: ribica
# The specified database role being used to connect to postgres.
# To create additional roles in postgres see `$ createuser --help`.
# When left blank, postgres will use the default role. This is
# the same name as the operating system user that initialized the database.
username: postgres
# The password associated with the postgres role (username).
password: testni_hamo2
# Connect on a TCP socket. Omitted by default since the client uses a
# domain socket that doesn't need configuration. Windows does not have
# domain sockets, so uncomment these lines.
host: localhost
# The TCP port the server listens on. Defaults to 5432.
# If your server runs on a different port number, change accordingly.
#port: 5432
# Schema search path. The server defaults to $user,public
#schema_search_path: myapp,sharedapp,public
# Minimum log levels, in increasing order:
# debug5, debug4, debug3, debug2, debug1,
# log, notice, warning, error, fatal, and panic
# Defaults to warning.
#min_messages: notice
# Warning: The database defined as "test" will be erased and
# re-generated from your development database when you run "rake".
# Do not set this db to the same as development or production.
test:
<<: *default
database: ribicabackoffice_test
# As with config/secrets.yml, you never want to store sensitive information,
# like your database password, in your source code. If your source code is
# ever seen by anyone, they now have access to your database.
#
# Instead, provide the password as a unix environment variable when you boot
# the app. Read http://guides.rubyonrails.org/configuring.html#configuring-a-database
# for a full rundown on how to provide these environment variables in a
# production deployment.
#
# On Heroku and other platform providers, you may have a full connection URL
# available as an environment variable. For example:
#
# DATABASE_URL="postgres://myuser:mypass@localhost/somedatabase"
#
# You can use this database configuration with:
#
# production:
# url: <%= ENV['DATABASE_URL'] %>
#
production:
<<: *default
database: ribica
username: postgres
password: testni_hamo2
host: localhost

View File

@@ -31,4 +31,11 @@ RailsAdmin.config do |config|
# history_index
# history_show
end
config.navigation_static_links = {
'Orders to Confirm' => './reports/orders_to_confirm',
'Items to Order' => './backreports/items_to_order',
'Check availability' => './items/check_availability',
'Export/import' => './items/export_import'
}
end

View File

@@ -1,5 +1,11 @@
Rails.application.routes.draw do
resources :item_in_groups do as_routes end
resources :item_groups do as_routes end
resources :link_banners do as_routes end
resources :delivery_time_estimations do as_routes end
resources :suppliers do as_routes end
resources :places do as_routes end
resources :delivery_destinations do as_routes end
mount RailsAdmin::Engine => '/admin', as: 'rails_admin'
resources :filter_criteria_values do as_routes end
@@ -9,10 +15,20 @@ Rails.application.routes.draw do
resources :multi_media_descriptions do as_routes end
resources :sections do as_routes end
resources :media_types do as_routes end
resources :items do as_routes end
resources :items do
collection do
get 'check_availability'
post 'check_availability' => 'items#check_availability', constraints: CheckItemsConstraint
post 'check_availability' => 'items#delete_items', constraints: DeleteItemsConstraint
get 'export_import'
post 'export_import' => 'items#export_import_post'
end
as_routes
end
resources :units do as_routes end
resources :sub_categories do as_routes end
resources :categories do as_routes end
get ':controller(/:action(/:id))'
# The priority is based upon order of creation: first created -> highest priority.
# See how all your routes lay out with "rake routes".

19
back-office/db/schema.rb Normal file
View File

@@ -0,0 +1,19 @@
# encoding: UTF-8
# This file is auto-generated from the current state of the database. Instead
# of editing this file, please use the migrations feature of Active Record to
# incrementally modify your database, and then regenerate this schema definition.
#
# Note that this schema.rb definition is the authoritative source for your
# database schema. If you need to create the application database on another
# system, you should be using db:schema:load, not running all the migrations
# from scratch. The latter is a flawed and unsustainable approach (the more migrations
# you'll amass, the slower it'll run and the greater likelihood for issues).
#
# It's strongly recommended that you check this file into your version control system.
ActiveRecord::Schema.define(version: 0) do
# These are extensions that must be enabled in order to support this database
enable_extension "plpgsql"
end

View File

@@ -0,0 +1,12 @@
# Logfile created on 2015-05-13 06:59:32 +0200 by logger.rb/47272
I, [2015-05-13T06:59:32.650998 #35530] INFO -- : Item import starting at 2015-05-13 06:59:32 +0200
I, [2015-05-13T06:59:32.651035 #35530] INFO -- : Will be importing items from /Users/senaduka/Downloads/items_for_import.csv
E, [2015-05-13T06:59:40.201578 #35530] ERROR -- : Could not import item on row number 608 (Dunjica), reason: Subcategory is missing!
I, [2015-05-13T06:59:45.758509 #35530] INFO -- : Rolling back because of errors
I, [2015-05-13T06:59:46.065723 #35530] INFO -- : Import done
I, [2015-05-13T07:00:24.402397 #35642] INFO -- : Item import starting at 2015-05-13 07:00:24 +0200
I, [2015-05-13T07:00:24.402456 #35642] INFO -- : Will be importing items from /Users/senaduka/Downloads/items_for_import.csv
I, [2015-05-13T07:00:37.829898 #35642] INFO -- : Import done
I, [2015-06-06T08:06:52.737647 #7908] INFO -- : Item import starting at 2015-06-06 08:06:52 +0200
I, [2015-06-06T08:06:52.738405 #7908] INFO -- : Will be importing items from /home/senadu/Downloads/items_for_import - item_2015-03-21_06h31m33.csv.csv
I, [2015-06-06T08:06:59.910247 #7908] INFO -- : Import done

View File

@@ -0,0 +1,388 @@
require 'csv'
def get_column_lookup
columns = [
:name,
:name_on_ribica,
:picture,
:brand,
:code,
:current_input_price,
:list_price,
:units_in_pack,
:description,
:stock,
:on_display,
:tags,
:traits,
:weight,
:delivery_time_estimation,
:name_unit,
:short_name_unit,
:description_suffix_unit,
:number_of_pieces_suffix_unit,
:name_sub_category,
:order_sub_category,
:name_supplier,
:address_supplier,
:postal_code_supplier,
:town_supplier,
:phone_supplier,
:contact_person_supplier,
:email_supplier,
:note_supplier
]
columns.map.with_index { |x, i| [x, i] }.to_h
end
def lookup_delivery_time_estimation(row, lookup)
dte = DeliveryTimeEstimation.where(
duration_in_days: row[lookup[:delivery_time_estimation]]
).take
if dte.nil?
dte = DeliveryTimeEstimation.new
dte.duration_in_days = row[lookup[:delivery_time_estimation]]
dte.save!
end
if dte.duration_in_days == 0
raise "Delivery time estimation input is missing or incorrect: #{dte.delivery_time_estimation}"
end
return dte
end
def lookup_unit(row, lookup)
unit = Unit.where(
name: row[lookup[:name_unit]],
short_name: row[lookup[:short_name_unit]],
description_suffix: row[lookup[:description_suffix_unit]],
number_of_pieces_suffix: row[lookup[:number_of_pieces_suffix_unit]]).take
if unit.nil?
new_unit = Unit.new
new_unit.name = row[lookup[:name_unit]]
new_unit.short_name = "kom" #row[lookup[:short_name_unit]]
new_unit.description_suffix = row[lookup[:description_suffix_unit]]
new_unit.number_of_pieces_suffix = row[lookup[:number_of_pieces_suffix_unit]]
new_unit.save!
new_unit
else
unit
end
end
def lookup_brand(row, lookup)
brand = Brand.find_by name: row[lookup[:brand]]
if brand.nil?
new_brand = Brand.new
new_brand.name = row[lookup[:brand]]
new_brand.save!
new_brand
else
brand
end
end
def lookup_supplier(row, lookup)
supplier = Supplier.find_by name: row[lookup[:name_supplier]]
if supplier.nil?
new_supplier = Supplier.new
new_supplier.name = row[lookup[:name_supplier]]
new_supplier.address = row[lookup[:address_supplier]]
new_supplier.postal_code = row[lookup[:postal_code_supplier]]
new_supplier.town = row[lookup[:town_supplier]]
new_supplier.phone = row[lookup[:phone_supplier]]
new_supplier.contact_person = row[lookup[:contact_person_supplier]]
new_supplier.email = row[lookup[:email_supplier]]
new_supplier.note = row[lookup[:note_supplier]]
new_supplier.save!
new_supplier
else
supplier
end
end
def resolve_subcategory(str)
raise "Subcategory is missing!" if str.nil?
parts = str.split(">").map{ |s| s.strip }
subcategory = parts[2]
category = parts[1]
section = parts[0]
if subcategory.to_s == '' || category.to_s == '' || section.to_s == ''
raise "Invalid subcategory : #{str}"
end
subcategory = subcategory.downcase
category = category.downcase
section = section.downcase
sc = SubCategory.eager_load(category: :section)
.where("lower(sub_categories.name) = '#{subcategory}' and lower(categories.name) = '#{category}' and lower(sections.name) = '#{section}'")
.take
return sc unless sc.nil?
section_in_db = Section.where("lower(name) = '#{section}'").take
if section_in_db.nil?
section_in_db = Section.new
section_in_db.name = section.capitalize
section_in_db.save!
end
cat_in_db =
Category
.eager_load(:section)
.where("lower(categories.name) = '#{category}' and lower(sections.name) = '#{section}'")
.take
if cat_in_db.nil?
cat_in_db = Category.new
cat_in_db.name = category.capitalize
cat_in_db.section_id = section_in_db.id
cat_in_db.save!
end
sub_cat_in_db =
SubCategory
.eager_load(:category)
.where("lower(sub_categories.name) = '#{subcategory}' and lower(categories.name) = '#{category}'")
.take
if sub_cat_in_db.nil?
sub_cat_in_db = SubCategory.new
sub_cat_in_db.name = subcategory.capitalize
sub_cat_in_db.category_id = cat_in_db.id
sub_cat_in_db.save!
end
sub_cat_in_db
#item.sub_category.order = row[lookup[:order_sub_category]]
end
def handle_multimedia(item, row, index, logger, lookup)
multimedia = row[lookup[:picture]]
return if multimedia.to_s == ""
parts = multimedia.split(";").map{ |s| s.strip }
parts.each do |part|
mmd = MultiMediaDescription.new
if part != "" and not part.start_with? "https://"
raise "Invalid url for the image: #{part}"
end
mmd.url = part
item.multi_media_descriptions.each(&:destroy)
item.multi_media_descriptions << mmd
end
end
def import_single_item(row, index, logger)
succes = true
begin
lookup = get_column_lookup
code = row[lookup[:code]]
item = (Item.find_by code: code) || Item.new
item.name = row[lookup[:name_on_ribica]]
item.code = code
if item.new_record?
item.current_input_price = 0 #row[lookup[:current_input_price]] || 11.00
item.list_price = 0 #row[lookup[:list_price]] || 12.00
end
item.units_in_pack = row[lookup[:units_in_pack]]
item.description = row[lookup[:description]]
item.description ||= item.name
item.stock = row[lookup[:stock]]
item.on_display = row[lookup[:on_display]]
item.tags = row[lookup[:tags]]
item.traits = row[lookup[:traits]]
item.weight = row[lookup[:weight]] || 1.0
item.delivery_time_estimation = lookup_delivery_time_estimation(row, lookup)
item.sub_category = resolve_subcategory(row[lookup[:name_sub_category]])
# todo multimedia, item groups
handle_multimedia(item, row, index, logger, lookup)
item.unit = lookup_unit(row, lookup)
item.supplier = lookup_supplier(row, lookup)
item.brand = lookup_brand(row, lookup)
item.save(validate: false)
# logger.info "Successfully imported item with on row position #{index}: #{row[lookup[:name_on_ribica]]}"
success = true
rescue Exception => e
logger.error "Could not import item on row number #{index} (#{row[lookup[:name_on_ribica]]}), reason: #{e}"
puts "Could not import item on row number #{index} (#{row[lookup[:name_on_ribica]]}), reason: #{e}"
success = false
end
success
end
def trim_whitespace(row)
row.map! do |value|
trimmed = value.strip if not value.nil? # value.to_s.strip
# puts "trimming '#{value}' to '#{trimmed}'"
trimmed
end
end
def do_import(validate_only)
begin
input_file = ENV['INPUT']
if input_file.to_s == ""
puts "Input file is missing! Please provide input file in form INPUT=somefile.csv"
puts RakeTasksHelper.task_error_message
return
end
lookup = get_column_lookup
path = Rails.root.join(input_file)
log_filename = Rails.root.join("import.log")
log_filename = Rails.root.join("import_validate.log") if validate_only
logger = Logger.new(log_filename)
logger.info "Item import starting at #{Time.now}"
logger.info "Will be importing items from #{path}"
i = 1
should_rollback = false
Item.transaction do
CSV.foreach(path) do |row|
if i != 1
trim_whitespace(row)
if import_single_item(row, i, logger) == false
should_rollback = true
end
end
i += 1
end
if validate_only || should_rollback
if should_rollback
puts "Import failed, please check the import log file for error details."
logger.info "Rolling back because of errors"
puts RakeTasksHelper.task_error_message
end
raise ActiveRecord::Rollback
end
end
rescue Exception => e
puts "Import failed, please check the import log file for error details."
puts "Error while importing: #{e}"
logger.error "Error while importing: #{e}"
puts RakeTasksHelper.task_error_message
end
puts "Import done"
logger.info "Import done"
end
namespace :ribica do
desc "Creates menu structure using the sections and subsections from items."
task copy_sections_to_menu: :environment do
Section.transaction do
Section.all.each do |section|
mi = MenuItem.new
mi.title = section.name
mi.url = "/sekcija/#{section.id}/#{section.name}"
mi.ordinal = section.order
section.categories.each do |category|
msi = MenuSubItem.new
msi.title = category.name
msi.url = "/sekcija/#{section.name}/kategorija/#{category.id}/#{category.name}"
msi.ordinal = section.order
mi.menu_sub_items << msi
category.sub_categories.each do |sub_category|
mssi = MenuSubSubItem.new
mssi.title = sub_category.name
mssi.url = "/podkategorija/#{sub_category.id}/#{sub_category.name}"
mssi.ordinal = sub_category.order
msi.menu_sub_sub_items << mssi
end
end
mi.save!
end
end
end
end
namespace :ribica do
desc "Clears database."
task clear_database: :environment do
conn = ActiveRecord::Base.connection
tables = conn.execute("SELECT table_name FROM information_schema.tables WHERE table_schema = 'public';").map { |r| r["table_name"] }
tables.delete "schema_migrations"
tables.each { |t| conn.execute("TRUNCATE TABLE #{t}") }
end
end
namespace :ribica do
desc "Checks for errors in csv file. "
task validate_items: :environment do
do_import true
end
end
namespace :ribica do
desc "Imports items from csv if everything is ok. "
task import_items: :environment do
do_import false
end
end
namespace :ribica do
desc "Updates prices from csv. "
task update_prices: :environment do
Item.update_prices(ENV['INPUT'])
end
end
namespace :ribica do
desc "Imports items from csv if everything is ok. "
task reindex: :environment do
es_client = Elasticsearch::Client.new log: true
# first delete the index
begin
es_client.indices.delete index: 'ribica'
rescue
Rails.logger.warn "Ribica index could not be deleted. Continuing with indexing operation..."
end
# now index items
all_items = Item.includes(sub_category: { category: :section }).all.to_a
all_items.each do |item|
es_client.index index: 'ribica', type: 'items', id: item.id, body: {
title: 'Test',
name: item.name,
code: item.code,
description: item.description,
sub_category: item.sub_category.name,
category: item.sub_category.category.name,
section: item.sub_category.category.section.name,
brand: item.brand.name
}
end
puts "ok!"
end
end

Binary file not shown.

View File

@@ -0,0 +1,49 @@
require 'test_helper'
class DeliveryTimeEstimationsControllerTest < ActionController::TestCase
setup do
@delivery_time_estimation = delivery_time_estimations(:one)
end
test "should get index" do
get :index
assert_response :success
assert_not_nil assigns(:delivery_time_estimations)
end
test "should get new" do
get :new
assert_response :success
end
test "should create delivery_time_estimation" do
assert_difference('DeliveryTimeEstimation.count') do
post :create, delivery_time_estimation: { duration_in_days: @delivery_time_estimation.duration_in_days, name: @delivery_time_estimation.name }
end
assert_redirected_to delivery_time_estimation_path(assigns(:delivery_time_estimation))
end
test "should show delivery_time_estimation" do
get :show, id: @delivery_time_estimation
assert_response :success
end
test "should get edit" do
get :edit, id: @delivery_time_estimation
assert_response :success
end
test "should update delivery_time_estimation" do
patch :update, id: @delivery_time_estimation, delivery_time_estimation: { duration_in_days: @delivery_time_estimation.duration_in_days, name: @delivery_time_estimation.name }
assert_redirected_to delivery_time_estimation_path(assigns(:delivery_time_estimation))
end
test "should destroy delivery_time_estimation" do
assert_difference('DeliveryTimeEstimation.count', -1) do
delete :destroy, id: @delivery_time_estimation
end
assert_redirected_to delivery_time_estimations_path
end
end

View File

@@ -0,0 +1,49 @@
require 'test_helper'
class ItemGroupsControllerTest < ActionController::TestCase
setup do
@item_group = item_groups(:one)
end
test "should get index" do
get :index
assert_response :success
assert_not_nil assigns(:item_groups)
end
test "should get new" do
get :new
assert_response :success
end
test "should create item_group" do
assert_difference('ItemGroup.count') do
post :create, item_group: { description: @item_group.description, name: @item_group.name, visible: @item_group.visible }
end
assert_redirected_to item_group_path(assigns(:item_group))
end
test "should show item_group" do
get :show, id: @item_group
assert_response :success
end
test "should get edit" do
get :edit, id: @item_group
assert_response :success
end
test "should update item_group" do
patch :update, id: @item_group, item_group: { description: @item_group.description, name: @item_group.name, visible: @item_group.visible }
assert_redirected_to item_group_path(assigns(:item_group))
end
test "should destroy item_group" do
assert_difference('ItemGroup.count', -1) do
delete :destroy, id: @item_group
end
assert_redirected_to item_groups_path
end
end

View File

@@ -0,0 +1,49 @@
require 'test_helper'
class ItemInGroupsControllerTest < ActionController::TestCase
setup do
@item_in_group = item_in_groups(:one)
end
test "should get index" do
get :index
assert_response :success
assert_not_nil assigns(:item_in_groups)
end
test "should get new" do
get :new
assert_response :success
end
test "should create item_in_group" do
assert_difference('ItemInGroup.count') do
post :create, item_in_group: { item_group_id: @item_in_group.item_group_id, item_id: @item_in_group.item_id, position: @item_in_group.position }
end
assert_redirected_to item_in_group_path(assigns(:item_in_group))
end
test "should show item_in_group" do
get :show, id: @item_in_group
assert_response :success
end
test "should get edit" do
get :edit, id: @item_in_group
assert_response :success
end
test "should update item_in_group" do
patch :update, id: @item_in_group, item_in_group: { item_group_id: @item_in_group.item_group_id, item_id: @item_in_group.item_id, position: @item_in_group.position }
assert_redirected_to item_in_group_path(assigns(:item_in_group))
end
test "should destroy item_in_group" do
assert_difference('ItemInGroup.count', -1) do
delete :destroy, id: @item_in_group
end
assert_redirected_to item_in_groups_path
end
end

View File

@@ -0,0 +1,49 @@
require 'test_helper'
class LinkBannersControllerTest < ActionController::TestCase
setup do
@link_banner = link_banners(:one)
end
test "should get index" do
get :index
assert_response :success
assert_not_nil assigns(:link_banners)
end
test "should get new" do
get :new
assert_response :success
end
test "should create link_banner" do
assert_difference('LinkBanner.count') do
post :create, link_banner: { beginning: @link_banner.beginning, category_id: @link_banner.category_id, checkout_page: @link_banner.checkout_page, ending: @link_banner.ending, footer: @link_banner.footer, header: @link_banner.header, image_url: @link_banner.image_url, item_id: @link_banner.item_id, link_url: @link_banner.link_url, search_result_page: @link_banner.search_result_page, section_id: @link_banner.section_id, start_page: @link_banner.start_page, sub_category_id: @link_banner.sub_category_id, thank_you_page: @link_banner.thank_you_page }
end
assert_redirected_to link_banner_path(assigns(:link_banner))
end
test "should show link_banner" do
get :show, id: @link_banner
assert_response :success
end
test "should get edit" do
get :edit, id: @link_banner
assert_response :success
end
test "should update link_banner" do
patch :update, id: @link_banner, link_banner: { beginning: @link_banner.beginning, category_id: @link_banner.category_id, checkout_page: @link_banner.checkout_page, ending: @link_banner.ending, footer: @link_banner.footer, header: @link_banner.header, image_url: @link_banner.image_url, item_id: @link_banner.item_id, link_url: @link_banner.link_url, search_result_page: @link_banner.search_result_page, section_id: @link_banner.section_id, start_page: @link_banner.start_page, sub_category_id: @link_banner.sub_category_id, thank_you_page: @link_banner.thank_you_page }
assert_redirected_to link_banner_path(assigns(:link_banner))
end
test "should destroy link_banner" do
assert_difference('LinkBanner.count', -1) do
delete :destroy, id: @link_banner
end
assert_redirected_to link_banners_path
end
end

View File

@@ -0,0 +1,49 @@
require 'test_helper'
class PlacesControllerTest < ActionController::TestCase
setup do
@place = places(:one)
end
test "should get index" do
get :index
assert_response :success
assert_not_nil assigns(:places)
end
test "should get new" do
get :new
assert_response :success
end
test "should create place" do
assert_difference('Place.count') do
post :create, place: { delivery_price: @place.delivery_price, name: @place.name, postal_code: @place.postal_code }
end
assert_redirected_to place_path(assigns(:place))
end
test "should show place" do
get :show, id: @place
assert_response :success
end
test "should get edit" do
get :edit, id: @place
assert_response :success
end
test "should update place" do
patch :update, id: @place, place: { delivery_price: @place.delivery_price, name: @place.name, postal_code: @place.postal_code }
assert_redirected_to place_path(assigns(:place))
end
test "should destroy place" do
assert_difference('Place.count', -1) do
delete :destroy, id: @place
end
assert_redirected_to places_path
end
end

View File

@@ -0,0 +1,49 @@
require 'test_helper'
class SuppliersControllerTest < ActionController::TestCase
setup do
@supplier = suppliers(:one)
end
test "should get index" do
get :index
assert_response :success
assert_not_nil assigns(:suppliers)
end
test "should get new" do
get :new
assert_response :success
end
test "should create supplier" do
assert_difference('Supplier.count') do
post :create, supplier: { address: @supplier.address, contact_person: @supplier.contact_person, email: @supplier.email, name: @supplier.name, note: @supplier.note, phone: @supplier.phone, postal_code: @supplier.postal_code, town: @supplier.town }
end
assert_redirected_to supplier_path(assigns(:supplier))
end
test "should show supplier" do
get :show, id: @supplier
assert_response :success
end
test "should get edit" do
get :edit, id: @supplier
assert_response :success
end
test "should update supplier" do
patch :update, id: @supplier, supplier: { address: @supplier.address, contact_person: @supplier.contact_person, email: @supplier.email, name: @supplier.name, note: @supplier.note, phone: @supplier.phone, postal_code: @supplier.postal_code, town: @supplier.town }
assert_redirected_to supplier_path(assigns(:supplier))
end
test "should destroy supplier" do
assert_difference('Supplier.count', -1) do
delete :destroy, id: @supplier
end
assert_redirected_to suppliers_path
end
end

View File

@@ -0,0 +1,9 @@
# Read about fixtures at http://api.rubyonrails.org/classes/ActiveRecord/FixtureSet.html
one:
name: MyString
duration_in_days: 1
two:
name: MyString
duration_in_days: 1

View File

@@ -0,0 +1,11 @@
# Read about fixtures at http://api.rubyonrails.org/classes/ActiveRecord/FixtureSet.html
one:
name: MyString
description: MyText
visible: false
two:
name: MyString
description: MyText
visible: false

View File

@@ -0,0 +1,11 @@
# Read about fixtures at http://api.rubyonrails.org/classes/ActiveRecord/FixtureSet.html
one:
item_id: 1
item_group_id: 1
position: 1
two:
item_id: 1
item_group_id: 1
position: 1

View File

@@ -0,0 +1,33 @@
# Read about fixtures at http://api.rubyonrails.org/classes/ActiveRecord/FixtureSet.html
one:
image_url: MyString
start_page: false
section_id: 1
category_id: 1
sub_category_id: 1
item_id: 1
thank_you_page: false
search_result_page: false
checkout_page: false
beginning: 2015-03-22
ending: 2015-03-22
footer: false
header: false
link_url: MyString
two:
image_url: MyString
start_page: false
section_id: 1
category_id: 1
sub_category_id: 1
item_id: 1
thank_you_page: false
search_result_page: false
checkout_page: false
beginning: 2015-03-22
ending: 2015-03-22
footer: false
header: false
link_url: MyString

11
back-office/test/fixtures/places.yml vendored Normal file
View File

@@ -0,0 +1,11 @@
# Read about fixtures at http://api.rubyonrails.org/classes/ActiveRecord/FixtureSet.html
one:
postal_code: MyString
delivery_price: 9.99
name: MyString
two:
postal_code: MyString
delivery_price: 9.99
name: MyString

21
back-office/test/fixtures/suppliers.yml vendored Normal file
View File

@@ -0,0 +1,21 @@
# Read about fixtures at http://api.rubyonrails.org/classes/ActiveRecord/FixtureSet.html
one:
name: MyString
address: MyString
postal_code: MyString
town: MyString
phone: MyString
contact_person: MyString
email: MyString
note: MyText
two:
name: MyString
address: MyString
postal_code: MyString
town: MyString
phone: MyString
contact_person: MyString
email: MyString
note: MyText

View File

@@ -0,0 +1,7 @@
require 'test_helper'
class DeliveryTimeEstimationTest < ActiveSupport::TestCase
# test "the truth" do
# assert true
# end
end

View File

@@ -0,0 +1,7 @@
require 'test_helper'
class ItemGroupTest < ActiveSupport::TestCase
# test "the truth" do
# assert true
# end
end

View File

@@ -0,0 +1,7 @@
require 'test_helper'
class ItemInGroupTest < ActiveSupport::TestCase
# test "the truth" do
# assert true
# end
end

View File

@@ -0,0 +1,7 @@
require 'test_helper'
class LinkBannerTest < ActiveSupport::TestCase
# test "the truth" do
# assert true
# end
end

View File

@@ -0,0 +1,7 @@
require 'test_helper'
class PlaceTest < ActiveSupport::TestCase
# test "the truth" do
# assert true
# end
end

View File

@@ -0,0 +1,7 @@
require 'test_helper'
class SupplierTest < ActiveSupport::TestCase
# test "the truth" do
# assert true
# end
end

BIN
front-api/.DS_Store vendored

Binary file not shown.

View File

@@ -14,9 +14,13 @@ platform :ruby do
gem "activerecord"
end
gem 'elasticsearch'
gem "sinatra"
gem "sinatra-activerecord"
gem "json"
gem 'puma'
gem "sinatra-contrib"
gem 'rerun'
gem 'xxhash', '~> 0.3.0'
gem 'sendgrid-ruby'
gem 'ruby-trello'

View File

@@ -1,78 +1,137 @@
GEM
remote: https://rubygems.org/
specs:
activemodel (4.2.0)
activesupport (= 4.2.0)
activemodel (4.2.4)
activesupport (= 4.2.4)
builder (~> 3.1)
activerecord (4.2.0)
activemodel (= 4.2.0)
activesupport (= 4.2.0)
activerecord (4.2.4)
activemodel (= 4.2.4)
activesupport (= 4.2.4)
arel (~> 6.0)
activerecord-jdbc-adapter (1.3.13)
activerecord-jdbc-adapter (1.3.18)
activerecord (>= 2.2)
activerecord-jdbcpostgresql-adapter (1.3.13)
activerecord-jdbc-adapter (~> 1.3.13)
activerecord-jdbcpostgresql-adapter (1.3.18)
activerecord-jdbc-adapter (~> 1.3.18)
jdbc-postgres (>= 9.1)
activesupport (4.2.0)
activesupport (4.2.4)
i18n (~> 0.7)
json (~> 1.7, >= 1.7.7)
minitest (~> 5.1)
thread_safe (~> 0.3, >= 0.3.4)
tzinfo (~> 1.1)
arel (6.0.0)
backports (3.6.4)
addressable (2.3.8)
arel (6.0.3)
backports (3.6.6)
bcrypt (3.1.10)
bcrypt (3.1.10-java)
bcrypt (3.1.10-x64-mingw32)
builder (3.2.2)
celluloid (0.16.0)
timers (~> 4.0.0)
elasticsearch (1.0.13)
elasticsearch-api (= 1.0.13)
elasticsearch-transport (= 1.0.13)
elasticsearch-api (1.0.13)
multi_json
elasticsearch-transport (1.0.13)
faraday
multi_json
faraday (0.9.1)
multipart-post (>= 1.2, < 3)
ffi (1.9.10)
ffi (1.9.10-java)
ffi (1.9.10-x64-mingw32)
hitimes (1.2.3)
hitimes (1.2.3-java)
i18n (0.7.0)
jdbc-postgres (9.3.1102)
jruby-openssl (0.9.6-java)
json (1.8.1)
json (1.8.1-java)
minitest (5.5.0)
multi_json (1.10.1)
pg (0.17.1)
puma (2.10.2)
rack (>= 1.1, < 2.0)
puma (2.10.2-java)
rack (>= 1.1, < 2.0)
rack (1.6.0)
jdbc-postgres (9.4.1200)
jruby-openssl (0.9.11-java)
json (1.8.3)
json (1.8.3-java)
listen (2.10.1)
celluloid (~> 0.16.0)
rb-fsevent (>= 0.9.3)
rb-inotify (>= 0.9)
mime-types (2.6.2)
minitest (5.8.0)
multi_json (1.11.2)
multipart-post (2.0.0)
netrc (0.10.3)
oauth (0.4.7)
pg (0.18.3)
puma (2.14.0)
puma (2.14.0-java)
rack (1.6.4)
rack-protection (1.5.3)
rack
rack-test (0.6.3)
rack (>= 1.0)
sinatra (1.4.5)
rb-fsevent (0.9.6)
rb-inotify (0.9.5)
ffi (>= 0.5.0)
rerun (0.10.0)
listen (~> 2.7, >= 2.7.3)
rest-client (1.7.3)
mime-types (>= 1.16, < 3.0)
netrc (~> 0.7)
rest-client (1.7.3-x64-mingw32)
ffi (~> 1.9)
mime-types (>= 1.16, < 3.0)
netrc (~> 0.7)
ruby-trello (1.2.1)
activemodel (>= 3.2.0)
addressable (~> 2.3)
json
oauth (~> 0.4.5)
rest-client (~> 1.7.2)
sendgrid-ruby (0.0.3)
rest-client
smtpapi
sinatra (1.4.6)
rack (~> 1.4)
rack-protection (~> 1.4)
tilt (~> 1.3, >= 1.3.4)
sinatra-activerecord (2.0.3)
tilt (>= 1.3, < 3)
sinatra-activerecord (2.0.8)
activerecord (>= 3.2)
sinatra (~> 1.0)
sinatra-contrib (1.4.2)
sinatra-contrib (1.4.6)
backports (>= 2.0)
multi_json
rack-protection
rack-test
sinatra (~> 1.4.0)
tilt (~> 1.3)
thread_safe (0.3.4)
thread_safe (0.3.4-java)
tilt (1.4.1)
tilt (>= 1.3, < 3)
smtpapi (0.1.0)
thread_safe (0.3.5)
thread_safe (0.3.5-java)
tilt (2.0.1)
timers (4.0.4)
hitimes
tzinfo (1.2.2)
thread_safe (~> 0.1)
xxhash (0.3.0)
PLATFORMS
java
ruby
x64-mingw32
DEPENDENCIES
activerecord
activerecord-jdbcpostgresql-adapter
bcrypt (~> 3.1.7)
elasticsearch
jruby-openssl
json
pg
puma
rerun
ruby-trello
sendgrid-ruby
sinatra
sinatra-activerecord
sinatra-contrib
xxhash (~> 0.3.0)
BUNDLED WITH
1.10.6

View File

@@ -1,8 +1,25 @@
require 'sinatra'
require 'sinatra/activerecord'
require './config'
require './helpers'
require 'json'
require 'sinatra/cookies'
require 'elasticsearch'
require 'xxhash'
require 'trello'
require 'sendgrid-ruby'
Trello.configure do |config|
# API key generated by visiting https://trello.com/1/appKey/generate
config.developer_public_key = RibicaConfig::TRELLO_DEVELOPER_PUBLIC_KEY
# Member token
# larry-price.com/blog/2014/03/18/connecting-to-the-trello-api/
config.member_token = RibicaConfig::TRELLO_MEMBER_TOKEN
end
Dir[File.dirname(__FILE__) + '/models/*.rb'].each {|file| require file }
@@ -13,15 +30,18 @@ before do
content_type :json
# TODO: before running to production change this so that only specific
# domain is allowed
headers 'Access-Control-Allow-Origin' => 'http://localhost:3001',
'Access-Control-Allow-Methods' => ['OPTIONS', 'GET', 'POST','PUT'],
'Access-Control-Allow-Methods' => ['OPTIONS', 'GET', 'POST','PUT'].join(','),
'Access-Control-Allow-Headers' => 'Origin, X-Requested-With, Content-Type, Accept',
'Access-Control-Expose-Headers' => 'X-Total-Count',
'Access-Control-Allow-Credentials' => 'true'
request.body.rewind
json_string = request.body.read
@json_params = JSON.parse json_string if json_string.length > 1
unless Helper::do_not_parse_as_json.include? env['PATH_INFO']
request.body.rewind
json_string = request.body.read
@json_params = JSON.parse json_string if json_string.length > 1
end
if request.request_method == 'OPTIONS'
halt 200
@@ -29,11 +49,14 @@ before do
end
helpers Sinatra::Cookies
def xxhash(text)
seed = 31337
XXhash.xxh32(text, seed)
end
Dir[File.dirname(__FILE__) + '/controllers/*.rb'].each {|file| require file }

View File

@@ -10,3 +10,23 @@ ActiveRecord::Base.establish_connection(
:database => db.path[1..-1],
:encoding => 'utf8'
)
module RibicaConfig
ROOT_ADDRESS = "https://ribica.ba"
SENDGRID_API_USER = "ribica"
SENDGRID_API_KEY = "(enter key here)"
BACKOFFICE_ORDER_EMAIL_TO = "narudzbe@ribica.ba"
BACKOFFICE_ORDER_EMAIL_FROM = "draga@ribica.ba"
BACKOFFICE_ORDER_EMAIL_FROM_NAME = "Prodavnica Ribica"
# API key generated by visiting https://trello.com/1/appKey/generate
TRELLO_DEVELOPER_PUBLIC_KEY = "f13dd6c2dcc65f48b9a56c6d420e32e7"
# Member token
# larry-price.com/blog/2014/03/18/connecting-to-the-trello-api/
TRELLO_MEMBER_TOKEN = "(enter token here)"
TRELLO_BOARD_NAME = "FqDO1eFL"
BAM_TO_EURO_CONVERSION_RATE = 0.51
end

View File

@@ -1,70 +1,158 @@
helpers do
def anonymous_id
auid = cookies[:anonymous_user_id]
if auid.nil?
auid = AnonymousUser.uid
response.set_cookie('anonymous_user_id', :path=> '/', :httponly => true, :value=>auid, :expires=> Time.now + 100.year)
end
return auid
end
end
get '/cart' do
create_the_cart = lambda do
# -1 is a placeholder for user id when we implement users
# auid will still be used in case user is not logged in
Cart.find_or_create(anonymous_id, -1).to_json
Cart.find_or_create(anonymous_id, logged_in_user_id).to_json
end
post '/cart', &create_the_cart
put '/cart', &create_the_cart
get '/cart' do
Cart.just_find(anonymous_id, logged_in_user_id).to_json
end
# gets number of items in cart for every item
get '/cart/item' do
Cart.find_or_create(anonymous_id, -1).item_in_carts.to_json
Cart.just_find(anonymous_id, logged_in_user_id).item_in_carts.to_json
end
update_cart_item = ->() {
cart_id = Cart.find_or_create(anonymous_id, -1).id
item_id = @json_params["item_id"].to_i
count = @json_params["count"].to_i
update_cart_item = lambda do
cart_id = Cart.just_find(anonymous_id, logged_in_user_id).id
item_id = @json_params['item_id'].to_i
count = @json_params['count'].to_i
ItemInCart.update_state(cart_id, item_id, count).to_json
}
end
put '/cart/item', &update_cart_item
post '/cart/item', &update_cart_item
# gets list of items in cart without count
get '/cart/item/display' do
cart = Cart.find_or_create(anonymous_id, -1)
item_ids = cart.item_in_carts.map do |x|
x.item_id
end
cart = Cart.just_find(anonymous_id, logged_in_user_id)
item_ids = cart.item_in_carts.map(&:item_id)
items = []
items = Item.find(item_ids) if cart.item_in_carts.length > 0
prepare_items_for_mass_display(items)
end
get '/cart/delivery_destination' do
cart = Cart.find_or_create(anonymous_id, -1)
cart.delivery_destination.to_json(:except => [:created_at, :email_verification_code, :phone_verification_code])
cart = Cart.just_find(anonymous_id, logged_in_user_id)
cart.delivery_destination.to_json(except: [:created_at, :email_verification_code, :phone_verification_code])
end
update_delivery_destination = lambda do
cart = Cart.just_find(anonymous_id, logged_in_user_id)
allowed_keys = %w(name address place postal_code phone email note payment_method gift
recipient_name recipient_address recipient_place recipient_postal_code recipient_phone recipient_email)
params = @json_params.reject { |key, _| !allowed_keys.include?(key) }
cart.delivery_destination.update_attributes(params)
cart.delivery_destination.save!
cart.delivery_destination.to_json(except: [:created_at, :email_verification_code, :phone_verification_code])
end
put '/cart/delivery_destination', &update_delivery_destination
post '/cart/delivery_destination', &update_delivery_destination
def report_to_trello(cart)
Thread.new do
@cart = cart
board = Trello::Board.find(RibicaConfig::TRELLO_BOARD_NAME)
list = board.lists.first
card = Trello::Card.new
card.list_id = list.id
card.name = cart.title
card.pos = 'bottom'
card.desc = erb(:cart_trello, layout: false)
card.save
end
end
update_delivery_destination = ->() {
cart = Cart.find_or_create(anonymous_id, -1)
allowed_keys = ["name", "address", "place", "postal_code", "phone", "email", "note"]
cart = Cart.just_find(anonymous_id, logged_in_user_id)
allowed_keys = ["name", "address", "place", "postal_code", "phone", "email", "note", "payment_method", "gift",
"recipient_name", "recipient_address", "recipient_place", "recipient_postal_code", "recipient_phone", "recipient_email"]
params = @json_params.reject { |key,_| !allowed_keys.include?(key) }
cart.delivery_destination.update_attributes(params)
cart.delivery_destination.save!
report_to_trello(cart)
cart.delivery_destination.to_json(:except => [:created_at, :email_verification_code, :phone_verification_code])
}
put '/cart/delivery_destination', &update_delivery_destination
post '/cart/delivery_destination', &update_delivery_destination
def send_order_email(cart)
Thread.new do
client = SendGrid::Client.new(
api_user: RibicaConfig::SENDGRID_API_USER,
api_key: RibicaConfig::SENDGRID_API_KEY
)
email = SendGrid::Mail.new do |m|
m.to = RibicaConfig::BACKOFFICE_ORDER_EMAIL_TO
m.from = RibicaConfig::BACKOFFICE_ORDER_EMAIL_FROM
m.from_name = 'Prodavnica Ribica'
m.subject = "Nova Narudžba: #{cart.id}"
m.html = "Mušterija naručila nešto. <br /> Pogledati #{RibicaConfig::ROOT_ADDRESS}/backoffice/carts/#{cart.id}"
end
client.send(email)
end
end
post '/cart/confirmation' do
cart = Cart.find_or_create(anonymous_id, -1)
anonymous = anonymous_id
cart = Cart.just_find(anonymous, logged_in_user_id)
if cart.item_in_carts.length > 0
cart.ordered = true
cart.save!
end
"OK".to_json
report_to_trello(cart)
send_order_email(cart)
# since there is no more ordered cart this needs to be done
# in order for next call of Cart#just_find to be ready
Cart.find_or_create(anonymous, logged_in_user_id)
'OK'.to_json
end
post '/payment/confirmation' do
data = JSON.parse params[:custom]
puts "Data #{data.inspect}"
anonymous = data['anonymous_id_string']
user = data['user_id']
user ||= -1
user = user.to_i
cart = Cart.just_find(anonymous, user)
if cart.item_in_carts.length > 0
cart.ordered = true
cart.save!
end
Cart.find_or_create(anonymous, user)
report_to_trello(cart)
send_order_email(cart)
'OK'.to_json
end
get '/pikpay/confirmation' do
anonymous = params['anonymous_id_string']
user = params['user_id']
user ||= -1
user = user.to_i
cart = Cart.just_find(anonymous, user)
if cart.item_in_carts.length > 0
cart.ordered = true
cart.save!
end
Cart.find_or_create(anonymous, user)
report_to_trello(cart)
send_order_email(cart)
redirect "#{RibicaConfig::ROOT_ADDRESS}/hvala"
end

View File

@@ -1,10 +1,10 @@
get '/category' do
Category.order(:name).all.to_json(:include => [:section, :sub_categories, :filter_criterias =>{:include => :filter_criteria_values} ])
Category.eager_load(:sub_categories).order('categories.order, sub_categories.order').all.to_json(:include => [:section, :sub_categories, :filter_criterias =>{:include => :filter_criteria_values} ])
end
get '/category/:id' do
id = params[:id].to_i
Category.find(id).to_json(:include => [:section, :sub_categories, :filter_criterias =>{:include => :filter_criteria_values}])
Category.eager_load(:sub_categories).order('sub_categories.order').find(id).to_json(:include => [:section, :sub_categories, :filter_criterias =>{:include => :filter_criteria_values}])
end

View File

@@ -1,15 +1,18 @@
def prepare_items_for_mass_display(items)
items.to_json(
items_json = items.to_json(
:except => [:created_at, :current_input_price, :stock, :on_display],
:include => [
:unit ,
:multi_media_descriptions ,
:sub_category
:sub_category,
:brand
])
etag xxhash(items_json)
items_json
end
def offset_and_limit_invalid?(offset, limit)
offset < 0 or limit <= 0 or limit > 100
offset < 0 or limit <= 0 or limit > 300
end
@@ -65,14 +68,22 @@ end
# gets items in sub category ( useful for page showing single sub_category )
get '/item/sub_category/:sub_category_id/offset/:offset/limit/:limit' do |sub_category_id_s, offset_s, limit_s|
sub_category_id, offset, limit = mass_to_i(sub_category_id_s, offset_s, limit_s)
input_invalid = offset_and_limit_invalid?(offset,limit) or sub_category_id <= 0
return [].to_json if input_invalid
all_in_sub_cat = filter_by_traits(Item.all_in_sub_category(sub_category_id))
items = Item.best_selling_in_sub_category(sub_category_id, offset, limit)
items = filter_by_traits(items)
add_total_count_header(all_in_sub_cat.count)
prepare_items_for_mass_display(items)
end
# gets list of items in cart without count
get '/cart/item_details' do
cart = Cart.find_or_create(anonymous_id, -1)
@@ -83,3 +94,15 @@ get '/cart/item_details' do
items = Item.find(item_ids) if cart.item_in_carts.length > 0
prepare_items_for_mass_display(items)
end
# gets items in sub category ( useful for page showing single sub_category )
get '/item/item_group/:item_group_id/offset/:offset/limit/:limit' do |item_group_id_s, offset_s, limit_s|
item_group_id, offset, limit = mass_to_i(item_group_id_s, offset_s, limit_s)
input_invalid = offset_and_limit_invalid?(offset,limit) or item_group_id <= 0
return [].to_json if input_invalid
items = ItemGroup.find_by_id(item_group_id)
return [].to_json if items.nil?
prepare_items_for_mass_display(items.all_items(offset, limit))
end

View File

@@ -0,0 +1,6 @@
get '/link_banner' do
LinkBanner.all.to_json
end

View File

@@ -0,0 +1,8 @@
get '/menuitem' do
# list all menu items
menu_items_json = MenuItem.eager_load(menu_sub_items: :menu_sub_sub_items)
.order("menu_items.ordinal, menu_sub_items.ordinal, menu_sub_sub_items.ordinal")
.to_json(:include => [:menu_sub_items => {:include => :menu_sub_sub_items}])
etag xxhash(menu_items_json)
menu_items_json
end

View File

@@ -0,0 +1,5 @@
get '/place/:postal_code' do
Place.by_code_or_default(params["postal_code"]).to_json
end

View File

@@ -0,0 +1,45 @@
get '/search' do
results = { }
begin
es_client = Elasticsearch::Client.new log: true
q = params[:q]
# for now we do the basic query
results = es_client.search index: 'ribica', type: 'items', body: { query: { match: { _all: q } } }
rescue Exception => error
puts error.inspect
results = { "hits" => {"hits" => [ {"_id" => Item.first.id, "_score" => 2 }, {"_id" => Item.last.id, "_score" => 1 } ]}}
end
ids = results["hits"]["hits"].map do |r|
r["_id"]
end
ids_with_score = {}
results["hits"]["hits"].each do |r|
ids_with_score[r["_id"].to_i] = {:score => r["_score"], :item => nil}
end
if ids.length > 0
res = Item.where(:id => ids).to_a
# make sure we have correct relevance order, since `where in` does not guarantee order
res.each do |ii|
ids_with_score[ii.id][:item] = ii
end
final = []
ids_with_score.each do |k,v|
final << v
end
final.sort_by! {|v| -v[:score]}
final = final.map do |f|
f[:item]
end
prepare_items_for_mass_display(final)
else
[].to_json
end
end

View File

@@ -1,9 +1,7 @@
get '/section' do
Section.order(:name).all.to_json(:include =>
[:categories => { :include => :sub_categories }])
Section.eager_load(:categories).order('sections.order, categories.order').to_json(:include => :categories)
end
get '/section/:id' do
Section.find(params[:id].to_i).to_json(:include => [
:categories => { :include => :sub_categories } ])
Section.eager_load(categories: :sub_categories).order('categories.order, sub_categories.order').find(params[:id].to_i).to_json(:include => [:categories => {:include => :sub_categories}])
end

View File

@@ -0,0 +1,18 @@
get '/subcategory' do
SubCategory
.eager_load(category: :section)
.order(:order)
.all
.to_json(:include => [filter_criterias: {include: :filter_criteria_values}, category: {include: :section} ])
end
get '/subcategory/:id' do
id = params[:id].to_i
SubCategory
.eager_load(category: :section)
.order(:order)
.find(id)
.to_json(:include => [filter_criterias: {include: :filter_criteria_values}, category: {include: :section} ])
end

View File

@@ -1,4 +1,22 @@
helpers do
def logged_in_user_id
auth = cookies['ribica_auth']
auth ||= -1
return auth.to_i
end
def anonymous_id
auid = cookies[:anonymous_user_id]
if auid.nil?
auid = AnonymousUser.uid
response.set_cookie('anonymous_user_id', :path=> '/', :httponly => true, :value=>auid, :expires=> Time.now + 100.year)
end
return auid
end
end
post '/user/logout' do
response.delete_cookie("ribica_auth", :path => "/")
end

View File

@@ -0,0 +1,11 @@
class CreatePlaces < ActiveRecord::Migration
def change
create_table :places do |t|
t.string :postal_code
t.decimal :delivery_price
t.string :name
t.timestamps null: false
end
end
end

View File

@@ -0,0 +1,5 @@
class AddPriceToItemInCart < ActiveRecord::Migration
def change
add_column :item_in_carts, :price, :decimal
end
end

View File

@@ -0,0 +1,16 @@
class CreateSuppliers < ActiveRecord::Migration
def change
create_table :suppliers do |t|
t.string :name
t.string :address
t.string :postal_code
t.string :town
t.string :phone
t.string :contact_person
t.string :email
t.text :note
t.timestamps null: false
end
end
end

View File

@@ -0,0 +1,5 @@
class AddSupplierToItem < ActiveRecord::Migration
def change
add_column :items, :supplier_id, :integer
end
end

View File

@@ -0,0 +1,5 @@
class AddWeigthToItem < ActiveRecord::Migration
def change
add_column :items, :weight, :decimal, precision: 5, scale: 3
end
end

View File

@@ -0,0 +1,10 @@
class AddFlagsToCart < ActiveRecord::Migration
def change
add_column :carts, :confirmed, :boolean, default: false
add_column :carts, :packed, :boolean, default: false
add_column :carts, :canceled_on_check, :boolean, default: false
add_column :carts, :canceled_on_delivery, :boolean, default: false
add_column :carts, :delivered, :boolean, default: false
add_column :carts, :internal_note, :text
end
end

View File

@@ -0,0 +1,19 @@
class CreateSpecialOffers < ActiveRecord::Migration
def change
create_table :special_offers do |t|
t.string :image_url
t.boolean :start_page
t.integer :section_id
t.integer :category_id
t.integer :sub_category_id
t.integer :item_id
t.boolean :thank_you_page
t.boolean :search_result_page
t.boolean :checkout_page
t.date :beginning
t.date :ending
t.timestamps null: false
end
end
end

View File

@@ -0,0 +1,5 @@
class AddSpecialOfferToItem < ActiveRecord::Migration
def change
add_column :items, :special_offer_id, :integer
end
end

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