rawbotz 0.1.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +12 -0
- data/CODE_OF_CONDUCT.md +49 -0
- data/Gemfile +9 -0
- data/README.md +185 -0
- data/Rakefile +29 -0
- data/bin/console +14 -0
- data/bin/setup +8 -0
- data/config.ru +9 -0
- data/exe/debug/test_mail +15 -0
- data/exe/rawbotz +39 -0
- data/exe/rawbotz_import_links +74 -0
- data/exe/rawbotz_maintenance.sh +57 -0
- data/exe/rawbotz_process_order +86 -0
- data/exe/rawbotz_process_order_queue +80 -0
- data/exe/rawbotz_stock_update +84 -0
- data/exe/rawbotz_update_local_products +48 -0
- data/exe/rawbotz_update_remote_products +160 -0
- data/lib/rawbotz/app.rb +84 -0
- data/lib/rawbotz/cli/order_result_table.rb +57 -0
- data/lib/rawbotz/datapolate.rb +42 -0
- data/lib/rawbotz/helpers/flash_helper.rb +13 -0
- data/lib/rawbotz/helpers/icon_helper.rb +40 -0
- data/lib/rawbotz/helpers/resource_link_helper.rb +45 -0
- data/lib/rawbotz/local_shop.rb +12 -0
- data/lib/rawbotz/mail_template.rb +29 -0
- data/lib/rawbotz/option_parser.rb +37 -0
- data/lib/rawbotz/order_processor.rb +92 -0
- data/lib/rawbotz/product_updater.rb +89 -0
- data/lib/rawbotz/public/Chart.min.js +14 -0
- data/lib/rawbotz/public/font-awesome-4.5.0/HELP-US-OUT.txt +7 -0
- data/lib/rawbotz/public/font-awesome-4.5.0/css/font-awesome.css +2086 -0
- data/lib/rawbotz/public/font-awesome-4.5.0/css/font-awesome.min.css +4 -0
- data/lib/rawbotz/public/font-awesome-4.5.0/fonts/FontAwesome.otf +0 -0
- data/lib/rawbotz/public/font-awesome-4.5.0/fonts/fontawesome-webfont.eot +0 -0
- data/lib/rawbotz/public/font-awesome-4.5.0/fonts/fontawesome-webfont.svg +655 -0
- data/lib/rawbotz/public/font-awesome-4.5.0/fonts/fontawesome-webfont.ttf +0 -0
- data/lib/rawbotz/public/font-awesome-4.5.0/fonts/fontawesome-webfont.woff +0 -0
- data/lib/rawbotz/public/font-awesome-4.5.0/fonts/fontawesome-webfont.woff2 +0 -0
- data/lib/rawbotz/public/font-awesome-4.5.0/less/animated.less +34 -0
- data/lib/rawbotz/public/font-awesome-4.5.0/less/bordered-pulled.less +25 -0
- data/lib/rawbotz/public/font-awesome-4.5.0/less/core.less +12 -0
- data/lib/rawbotz/public/font-awesome-4.5.0/less/fixed-width.less +6 -0
- data/lib/rawbotz/public/font-awesome-4.5.0/less/font-awesome.less +17 -0
- data/lib/rawbotz/public/font-awesome-4.5.0/less/icons.less +697 -0
- data/lib/rawbotz/public/font-awesome-4.5.0/less/larger.less +13 -0
- data/lib/rawbotz/public/font-awesome-4.5.0/less/list.less +19 -0
- data/lib/rawbotz/public/font-awesome-4.5.0/less/mixins.less +26 -0
- data/lib/rawbotz/public/font-awesome-4.5.0/less/path.less +15 -0
- data/lib/rawbotz/public/font-awesome-4.5.0/less/rotated-flipped.less +20 -0
- data/lib/rawbotz/public/font-awesome-4.5.0/less/stacked.less +20 -0
- data/lib/rawbotz/public/font-awesome-4.5.0/less/variables.less +708 -0
- data/lib/rawbotz/public/font-awesome-4.5.0/scss/_animated.scss +34 -0
- data/lib/rawbotz/public/font-awesome-4.5.0/scss/_bordered-pulled.scss +25 -0
- data/lib/rawbotz/public/font-awesome-4.5.0/scss/_core.scss +12 -0
- data/lib/rawbotz/public/font-awesome-4.5.0/scss/_fixed-width.scss +6 -0
- data/lib/rawbotz/public/font-awesome-4.5.0/scss/_icons.scss +697 -0
- data/lib/rawbotz/public/font-awesome-4.5.0/scss/_larger.scss +13 -0
- data/lib/rawbotz/public/font-awesome-4.5.0/scss/_list.scss +19 -0
- data/lib/rawbotz/public/font-awesome-4.5.0/scss/_mixins.scss +26 -0
- data/lib/rawbotz/public/font-awesome-4.5.0/scss/_path.scss +15 -0
- data/lib/rawbotz/public/font-awesome-4.5.0/scss/_rotated-flipped.scss +20 -0
- data/lib/rawbotz/public/font-awesome-4.5.0/scss/_stacked.scss +20 -0
- data/lib/rawbotz/public/font-awesome-4.5.0/scss/_variables.scss +708 -0
- data/lib/rawbotz/public/font-awesome-4.5.0/scss/font-awesome.scss +17 -0
- data/lib/rawbotz/public/jquery-2.2.0.min.js +4 -0
- data/lib/rawbotz/public/jui/external/jquery/jquery.js +9789 -0
- data/lib/rawbotz/public/jui/images/ui-icons_444444_256x240.png +0 -0
- data/lib/rawbotz/public/jui/images/ui-icons_555555_256x240.png +0 -0
- data/lib/rawbotz/public/jui/images/ui-icons_777620_256x240.png +0 -0
- data/lib/rawbotz/public/jui/images/ui-icons_777777_256x240.png +0 -0
- data/lib/rawbotz/public/jui/images/ui-icons_cc0000_256x240.png +0 -0
- data/lib/rawbotz/public/jui/images/ui-icons_ffffff_256x240.png +0 -0
- data/lib/rawbotz/public/jui/index.html +513 -0
- data/lib/rawbotz/public/jui/jquery-ui.css +1225 -0
- data/lib/rawbotz/public/jui/jquery-ui.js +16617 -0
- data/lib/rawbotz/public/jui/jquery-ui.min.css +7 -0
- data/lib/rawbotz/public/jui/jquery-ui.min.js +13 -0
- data/lib/rawbotz/public/jui/jquery-ui.structure.css +833 -0
- data/lib/rawbotz/public/jui/jquery-ui.structure.min.css +5 -0
- data/lib/rawbotz/public/jui/jquery-ui.theme.css +410 -0
- data/lib/rawbotz/public/jui/jquery-ui.theme.min.css +5 -0
- data/lib/rawbotz/public/pure-min.css +11 -0
- data/lib/rawbotz/public/rawbotz.css +60 -0
- data/lib/rawbotz/public/rawbotz.js +96 -0
- data/lib/rawbotz/public/rawbotz_ajax_product_link.js +64 -0
- data/lib/rawbotz/remote_shop.rb +21 -0
- data/lib/rawbotz/routes/non_remote_orders.rb +45 -0
- data/lib/rawbotz/routes/orders.rb +76 -0
- data/lib/rawbotz/routes/product_links.rb +68 -0
- data/lib/rawbotz/routes/products.rb +104 -0
- data/lib/rawbotz/routes/remote_shop.rb +37 -0
- data/lib/rawbotz/routes/suppliers.rb +36 -0
- data/lib/rawbotz/routes.rb +9 -0
- data/lib/rawbotz/version.rb +3 -0
- data/lib/rawbotz/views/_hide_unhide_button.haml +11 -0
- data/lib/rawbotz/views/_menu.haml +20 -0
- data/lib/rawbotz/views/index.haml +1 -0
- data/lib/rawbotz/views/layout.haml +55 -0
- data/lib/rawbotz/views/maintenance/menu.haml +25 -0
- data/lib/rawbotz/views/maintenance.haml +150 -0
- data/lib/rawbotz/views/order/_head.haml +24 -0
- data/lib/rawbotz/views/order/_item_table.haml +44 -0
- data/lib/rawbotz/views/order/new.haml +22 -0
- data/lib/rawbotz/views/order/non_remote.haml +42 -0
- data/lib/rawbotz/views/order/packlist.haml +14 -0
- data/lib/rawbotz/views/order/view.haml +79 -0
- data/lib/rawbotz/views/orders/index.haml +40 -0
- data/lib/rawbotz/views/orders/menu.haml +24 -0
- data/lib/rawbotz/views/orders/non_remotes.haml +8 -0
- data/lib/rawbotz/views/product/_stock_sales_plot.haml +60 -0
- data/lib/rawbotz/views/product/link_to.haml +29 -0
- data/lib/rawbotz/views/product/view.haml +64 -0
- data/lib/rawbotz/views/products/_link_table.haml +38 -0
- data/lib/rawbotz/views/products/index.haml +36 -0
- data/lib/rawbotz/views/products/link_wizard.haml +48 -0
- data/lib/rawbotz/views/products/links.haml +65 -0
- data/lib/rawbotz/views/products/menu.haml +27 -0
- data/lib/rawbotz/views/products/table.haml +20 -0
- data/lib/rawbotz/views/products/table_with_linking.haml +30 -0
- data/lib/rawbotz/views/remote_cart/index.haml +30 -0
- data/lib/rawbotz/views/remote_order/view.haml +35 -0
- data/lib/rawbotz/views/remote_orders/index.haml +20 -0
- data/lib/rawbotz/views/remote_product/view.haml +90 -0
- data/lib/rawbotz/views/remote_products/_table.haml +15 -0
- data/lib/rawbotz/views/remote_products/index.haml +30 -0
- data/lib/rawbotz/views/supplier/view.haml +63 -0
- data/lib/rawbotz/views/suppliers/index.haml +13 -0
- data/lib/rawbotz/views/thin_layout.haml +32 -0
- data/lib/rawbotz/views/widgets/_ajax_link.haml +5 -0
- data/lib/rawbotz/views/widgets/_link.haml +6 -0
- data/lib/rawbotz/views/widgets/_link_line.haml +15 -0
- data/lib/rawbotz.rb +77 -0
- data/rawbotz.gemspec +33 -0
- metadata +327 -0
@@ -0,0 +1,36 @@
|
|
1
|
+
= haml "products/menu".to_sym
|
2
|
+
|
3
|
+
%h1 Products by Supplier
|
4
|
+
|
5
|
+
:javascript
|
6
|
+
$(function() {
|
7
|
+
$( "#tabs" ).tabs();
|
8
|
+
});
|
9
|
+
|
10
|
+
#tabs
|
11
|
+
%ul
|
12
|
+
%li
|
13
|
+
%a(href="#tab_all_products") All
|
14
|
+
- @suppliers.each_with_index do |supplier, idx|
|
15
|
+
%li
|
16
|
+
%a(href="#tab_#{idx}")="#{supplier.name} (#{@products.supplied_by(supplier).count})"
|
17
|
+
%li
|
18
|
+
%a(href="#tab_no_supplier") [no supplier] (#{@products.where(supplier_id: nil).count})
|
19
|
+
%li
|
20
|
+
%a(href="#tab_hidden_products") Hidden (#{@products.all_hidden.count})
|
21
|
+
#tab_all_products
|
22
|
+
%h2 All Products
|
23
|
+
= haml "products/table".to_sym, locals: {products: @products.all}
|
24
|
+
- @suppliers.each_with_index do |supplier, idx|
|
25
|
+
%div{id:"tab_#{idx}"}
|
26
|
+
%h2 Products of #{supplier.name || "Unknown Supplier"}
|
27
|
+
- if supplier == settings.supplier
|
28
|
+
= haml "products/table_with_linking".to_sym, locals: {products: @products.supplied_by(supplier)}
|
29
|
+
- else
|
30
|
+
= haml "products/table".to_sym, locals: {products: @products.supplied_by(supplier)}
|
31
|
+
#tab_no_supplier
|
32
|
+
%h2 Products without supplier
|
33
|
+
= haml "products/table".to_sym, locals: {products: @products.where(supplier_id: nil)}
|
34
|
+
#tab_hidden_products
|
35
|
+
%h2 Hidden Products
|
36
|
+
= haml "products/table".to_sym, locals: {products: @products.all_hidden}
|
@@ -0,0 +1,48 @@
|
|
1
|
+
= haml "products/menu".to_sym
|
2
|
+
|
3
|
+
%h1 Link Wizard
|
4
|
+
|
5
|
+
- if @unlinked_count == 0
|
6
|
+
%h2
|
7
|
+
Nothing to do! Congratulations!
|
8
|
+
%i.fa.fa-birthday-cake
|
9
|
+
-else
|
10
|
+
#{@unlinked_count}/#{settings.supplier.local_products.count} unlinked local products from #{settings.supplier.name}
|
11
|
+
|
12
|
+
%h2
|
13
|
+
= product_link @local_product
|
14
|
+
|
15
|
+
%center
|
16
|
+
%table.pure-table
|
17
|
+
%tr
|
18
|
+
%td
|
19
|
+
= haml "widgets/_link".to_sym, locals: {local_product: @local_product, redirect_to: "link_wizard"}
|
20
|
+
-#%form.pure-form(action="/product/#{@local_product.id}/link" method="POST")
|
21
|
+
-# %input(type="hidden" name="remote_product_id" id="remote_product_id")
|
22
|
+
-# %input(type="hidden" name="redirect_to" value="link_wizard")
|
23
|
+
-# %input#search-remote(placeholder="search ...")
|
24
|
+
-# %button.pure-button
|
25
|
+
-# Link!
|
26
|
+
%td
|
27
|
+
- if @local_product.link_suggestions.count > 0
|
28
|
+
Suggenstions:
|
29
|
+
%br
|
30
|
+
- @local_product.link_suggestions.each do |suggested_product|
|
31
|
+
%form.pure-form(action="/product/#{@local_product.id}/link" method="POST")
|
32
|
+
%input(type="hidden" name="remote_product_id" id="remote_product_id" value="#{suggested_product.id}")
|
33
|
+
%input(type="hidden" name="redirect_to" value="link_wizard")
|
34
|
+
%button.pure-button
|
35
|
+
= suggested_product.name
|
36
|
+
%br
|
37
|
+
- else
|
38
|
+
(no suggestions)
|
39
|
+
%td
|
40
|
+
%a.pure-button(href="/products/link_wizard/#{params[:idx].to_i + 1}")
|
41
|
+
Skip
|
42
|
+
%br
|
43
|
+
%br
|
44
|
+
= haml :"_hide_unhide_button", locals: {product: @local_product}
|
45
|
+
%br
|
46
|
+
%p#message
|
47
|
+
%br
|
48
|
+
|
@@ -0,0 +1,65 @@
|
|
1
|
+
= haml "products/menu".to_sym
|
2
|
+
|
3
|
+
%h1 Product Linking
|
4
|
+
|
5
|
+
:javascript
|
6
|
+
$(function() {
|
7
|
+
$( "#tabs" ).tabs();
|
8
|
+
});
|
9
|
+
|
10
|
+
#tabs
|
11
|
+
%ul
|
12
|
+
%li
|
13
|
+
%a(href="#local_unlinked")Local unlinked (#{settings.supplier.name}) (#{@local_products.unlinked.count})
|
14
|
+
%li
|
15
|
+
%a(href="#local_linked")Local linked (#{settings.supplier.name}) (#{@local_products.linked.count})
|
16
|
+
%li
|
17
|
+
%a(href="#remote_linked")Remote linked (#{settings.supplier.remote_products.linked.count})
|
18
|
+
%li
|
19
|
+
%a(href="#remote_unlinked")Remote unlinked (#{settings.supplier.remote_products.unlinked.count})
|
20
|
+
#local_linked
|
21
|
+
%table.pure-table.pure-table-striped
|
22
|
+
%thead
|
23
|
+
%tr
|
24
|
+
%th Local Product
|
25
|
+
%th Remote Product
|
26
|
+
%th Action
|
27
|
+
%tbody
|
28
|
+
- @local_products.linked.each do |local_product|
|
29
|
+
%tr
|
30
|
+
%td=local_product_link(local_product)
|
31
|
+
%td=remote_product_link(local_product.remote_product)
|
32
|
+
%td
|
33
|
+
%a.pure-button(href="/product/#{local_product.id}/link")
|
34
|
+
= link_icon
|
35
|
+
Change Link
|
36
|
+
#local_unlinked
|
37
|
+
%table.pure-table.pure-table-striped
|
38
|
+
%thead
|
39
|
+
%tr
|
40
|
+
%th Local Product
|
41
|
+
%th Suggested Remote Products
|
42
|
+
%th Action
|
43
|
+
%tbody
|
44
|
+
- @local_products.unlinked.each do |local_product|
|
45
|
+
%tr
|
46
|
+
%td=local_product_link(local_product)
|
47
|
+
%td
|
48
|
+
-local_product.link_suggestions.each do |suggested_product|
|
49
|
+
%form.pure-form.pure-form-aligned(action="/product/#{local_product.id}/link" method="post")
|
50
|
+
%input(type="hidden" name="remote_product_id" value="#{suggested_product.id}")
|
51
|
+
%input(type="hidden" name="redirect_to" value="links")
|
52
|
+
%button.pure-button.pure-button-primary(type="submit")
|
53
|
+
%small
|
54
|
+
%small
|
55
|
+
Link to
|
56
|
+
= suggested_product.name
|
57
|
+
%br
|
58
|
+
%td
|
59
|
+
%a.pure-button.pure-button-primary(href="/product/#{local_product.id}/link")
|
60
|
+
= link_icon
|
61
|
+
Link
|
62
|
+
#remote_linked
|
63
|
+
= haml "remote_products/_table".to_sym, locals: {products: @remote_products.supplied_by(settings.supplier).linked}
|
64
|
+
#remote_unlinked
|
65
|
+
= haml "remote_products/_table".to_sym, locals: {products: @remote_products.supplied_by(settings.supplier).unlinked}
|
@@ -0,0 +1,27 @@
|
|
1
|
+
.icon#headicon
|
2
|
+
= products_icon
|
3
|
+
|
4
|
+
.pure-u-1
|
5
|
+
.pure-menu.pure-menu-horizontal#submenu
|
6
|
+
%small
|
7
|
+
%center
|
8
|
+
%ul.pure-menu-list
|
9
|
+
%li.pure-menu-item
|
10
|
+
%a.pure-menu-link(href="/products")
|
11
|
+
= index_icon
|
12
|
+
Local Products
|
13
|
+
%ul.pure-menu-list
|
14
|
+
%li.pure-menu-item
|
15
|
+
%a.pure-menu-link(href="/remote_products")
|
16
|
+
%i(class="fa fa-globe")
|
17
|
+
Remote Products
|
18
|
+
%ul.pure-menu-list
|
19
|
+
%li.pure-menu-item
|
20
|
+
%a.pure-menu-link(href="/products/links")
|
21
|
+
%i(class="fa fa-link")
|
22
|
+
Product Linking
|
23
|
+
%ul.pure-menu-list
|
24
|
+
%li.pure-menu-item
|
25
|
+
%a.pure-menu-link(href="/products/link_wizard")
|
26
|
+
%i(class="fa fa-magic")
|
27
|
+
Product Link Wizard
|
@@ -0,0 +1,20 @@
|
|
1
|
+
%table.pure-table
|
2
|
+
%thead
|
3
|
+
%tr
|
4
|
+
%th
|
5
|
+
Product name
|
6
|
+
%th
|
7
|
+
Product ID
|
8
|
+
%th
|
9
|
+
Supplier
|
10
|
+
-#%th
|
11
|
+
-# Last Stock
|
12
|
+
%tbody
|
13
|
+
- products.each do |product|
|
14
|
+
%tr
|
15
|
+
%td
|
16
|
+
= product_link product
|
17
|
+
%td= product.product_id
|
18
|
+
%td= product.supplier.try(:name)
|
19
|
+
-#%td
|
20
|
+
-# %a(href="") Show modal
|
@@ -0,0 +1,30 @@
|
|
1
|
+
%table.pure-table
|
2
|
+
%thead
|
3
|
+
%tr
|
4
|
+
%th
|
5
|
+
Product name
|
6
|
+
%th
|
7
|
+
Product ID
|
8
|
+
%th
|
9
|
+
Remote Name
|
10
|
+
%th
|
11
|
+
Supplier
|
12
|
+
%th
|
13
|
+
Last Stock
|
14
|
+
%tbody
|
15
|
+
- products.each do |product|
|
16
|
+
%tr
|
17
|
+
%input.local_product_id(type="hidden" value="#{product.id}")
|
18
|
+
%td
|
19
|
+
%a(href="/product/#{product.id}")= product.name
|
20
|
+
%td= product.product_id
|
21
|
+
%td
|
22
|
+
- if product.remote_product.nil?
|
23
|
+
%a(href="/product/#{product.id}/link") Linking view
|
24
|
+
= haml "widgets/_ajax_link".to_sym, locals: {local_product: product, redirect_to: 'products'}
|
25
|
+
- else
|
26
|
+
= product.remote_product.name
|
27
|
+
%td= product.supplier.try(:name)
|
28
|
+
%td
|
29
|
+
%a(href="") Show modal
|
30
|
+
|
@@ -0,0 +1,30 @@
|
|
1
|
+
%h1 Remote Cart
|
2
|
+
|
3
|
+
%center
|
4
|
+
Currently #{@cart_content.size} items in cart.
|
5
|
+
%br
|
6
|
+
%br
|
7
|
+
%table.pure-table
|
8
|
+
%thead
|
9
|
+
%tr
|
10
|
+
%th
|
11
|
+
Product
|
12
|
+
%th
|
13
|
+
Local Name
|
14
|
+
%th
|
15
|
+
Quantity
|
16
|
+
%tbody
|
17
|
+
- @cart_products.each do |product, qty|
|
18
|
+
- if product.nil?
|
19
|
+
%tr
|
20
|
+
%td unknown product
|
21
|
+
%td unknown product
|
22
|
+
%td unknown product
|
23
|
+
- else
|
24
|
+
%tr
|
25
|
+
%td
|
26
|
+
= remote_product_link product
|
27
|
+
%td
|
28
|
+
= local_product_link(product.local_product) rescue "unlinked"
|
29
|
+
%td
|
30
|
+
= qty
|
@@ -0,0 +1,35 @@
|
|
1
|
+
= haml "orders/menu".to_sym
|
2
|
+
|
3
|
+
%h1 Remote Order
|
4
|
+
|
5
|
+
|
6
|
+
ID #{@remote_order_id}
|
7
|
+
%br
|
8
|
+
|
9
|
+
%table.pure-table.pure-table-striped
|
10
|
+
%thead
|
11
|
+
%tr
|
12
|
+
%th Remote Name
|
13
|
+
%th Local Name
|
14
|
+
%th Qty
|
15
|
+
%th Refund
|
16
|
+
%th Shelve
|
17
|
+
%tbody
|
18
|
+
- @remote_products_qty.sort_by{|p,_| p.name}.each do |p, q|
|
19
|
+
%tr
|
20
|
+
%td
|
21
|
+
= remote_product_link p
|
22
|
+
%td
|
23
|
+
-if p.local_product
|
24
|
+
%a(href="/product/#{p.local_product.id}")
|
25
|
+
= p.local_product.name
|
26
|
+
-elsif p.is_a? RemoteProduct
|
27
|
+
%a(href="/remote_product/#{p.id}/link")
|
28
|
+
Link (broken)
|
29
|
+
-else
|
30
|
+
not in database
|
31
|
+
%td=q
|
32
|
+
%td
|
33
|
+
%td
|
34
|
+
-if shelve = p.local_product.try(:shelve_nr)
|
35
|
+
= shelve
|
@@ -0,0 +1,20 @@
|
|
1
|
+
= haml "orders/menu".to_sym
|
2
|
+
|
3
|
+
%h1 Remote Orders
|
4
|
+
|
5
|
+
%center
|
6
|
+
%table.pure-table.pure-table-striped
|
7
|
+
%tr
|
8
|
+
%th Date
|
9
|
+
%th Volume
|
10
|
+
%th Action
|
11
|
+
- @last_orders.each do |p|
|
12
|
+
%tr
|
13
|
+
%td=p[0]
|
14
|
+
%td=p[1]
|
15
|
+
%td
|
16
|
+
%a(href="#{p[2]}")
|
17
|
+
Visit remote shop
|
18
|
+
%br
|
19
|
+
%a(href="/remote_order/#{p[2][/\d+/]}")
|
20
|
+
View
|
@@ -0,0 +1,90 @@
|
|
1
|
+
= haml "products/menu".to_sym
|
2
|
+
|
3
|
+
%h1= @product.name
|
4
|
+
|
5
|
+
%form.pure-form.pure-form-aligned(action="" method="post")
|
6
|
+
%input(type="hidden" name="_method" value="put")
|
7
|
+
%fieldset
|
8
|
+
.pure-control-group
|
9
|
+
%label(for="product_id") Product ID
|
10
|
+
%input#product_id(type="text" readonly value="#{@product.product_id}")
|
11
|
+
.pure-control-group
|
12
|
+
%label(for="product_page") Product Page
|
13
|
+
%a(href="#{Rawbotz::RemoteShop.product_page_url(@product, settings.conf)}" target="blank")
|
14
|
+
=Rawbotz::RemoteShop.product_page_url(@product, settings.conf)
|
15
|
+
.pure-control-group
|
16
|
+
%label(for="supplier") Supplier
|
17
|
+
= @product.supplier.try(:name)
|
18
|
+
.pure-control-group
|
19
|
+
%label(for="supplier") Local Product
|
20
|
+
- if @product.local_product.nil?
|
21
|
+
create link
|
22
|
+
- else
|
23
|
+
= local_product_link @product.local_product
|
24
|
+
- if packsize = @product.local_product.try(:packsize)
|
25
|
+
.pure-control-group
|
26
|
+
%label(for="packsize") Pack size
|
27
|
+
= packsize
|
28
|
+
- if shelve = @product.local_product.try(:shelve_nr)
|
29
|
+
.pure-control-group
|
30
|
+
%label(for="shelve") Shelve
|
31
|
+
= shelve
|
32
|
+
-# if supplier == settings.supplier ... show a link to product page (in shop catalog/product/view/id/ ...
|
33
|
+
|
34
|
+
-#- if @product.stock_items.present?
|
35
|
+
-# %h2 Stock Values
|
36
|
+
-# %table.pure-table
|
37
|
+
-# %thead
|
38
|
+
-# %tr
|
39
|
+
-# %th Date
|
40
|
+
-# %th Qty
|
41
|
+
-# %tbody
|
42
|
+
-# - @product.stock_items.each do |s|
|
43
|
+
-# %tr
|
44
|
+
-# %td= s.date
|
45
|
+
-# %td= s.qty
|
46
|
+
|
47
|
+
-#%div(style="width:60%")
|
48
|
+
-# %div
|
49
|
+
-# %div
|
50
|
+
-# %canvas(id="canvas" height="450" width="800")
|
51
|
+
-#
|
52
|
+
-#:javascript
|
53
|
+
-# // animate true?
|
54
|
+
-# var randomScalingFactor = function(){ return Math.round(Math.random()*100)}; // ??
|
55
|
+
-# Chart.defaults.global.multiTooltipTemplate = "<%= value %>";
|
56
|
+
-# var lineChartData = {
|
57
|
+
-# labels : [#{@sales.uniq.map{|s| "\"#{s[0]}\""}.reverse.join(',')}],
|
58
|
+
-# datasets : [
|
59
|
+
-# {
|
60
|
+
-# label: "Product sales",
|
61
|
+
-# fillColor : "rgba(220,220,220,0.2)",
|
62
|
+
-# strokeColor : "rgba(220,220,220,1)",
|
63
|
+
-# pointColor : "rgba(220,220,220,1)",
|
64
|
+
-# pointStrokeColor : "#fff",
|
65
|
+
-# pointHighlightFill : "#fff",
|
66
|
+
-# pointHighlightStroke : "rgba(220,220,220,1)",
|
67
|
+
-# data : [#{@sales.uniq.map{|s| "\"#{s[1]}\""}.reverse.join(',')}]
|
68
|
+
-# },
|
69
|
+
-# {
|
70
|
+
-# label: "Product",
|
71
|
+
-# fillColor : "rgba(220,220,220,0.2)",
|
72
|
+
-# strokeColor : "rgba(220,220,220,1)",
|
73
|
+
-# pointColor : "rgba(120,120,220,1)",
|
74
|
+
-# pointStrokeColor : "#fff",
|
75
|
+
-# pointHighlightFill : "#fff",
|
76
|
+
-# pointHighlightStroke : "rgba(220,220,220,1)",
|
77
|
+
-# data : [#{(@product.stock_items.map(&:qty) * @sales.uniq.length).join(',')}]
|
78
|
+
-# }
|
79
|
+
-# ]
|
80
|
+
-# }
|
81
|
+
-#
|
82
|
+
-# window.onload = function(){
|
83
|
+
-# var ctx = document.getElementById("canvas").getContext("2d");
|
84
|
+
-# window.myLine = new Chart(ctx).Line(lineChartData, {
|
85
|
+
-# responsive: true
|
86
|
+
-# });
|
87
|
+
-# }
|
88
|
+
-#
|
89
|
+
-#%h2 Orders
|
90
|
+
|
@@ -0,0 +1,15 @@
|
|
1
|
+
%table.pure-table.pure-table-horizontal
|
2
|
+
%thead
|
3
|
+
%tr
|
4
|
+
%th Remote Product
|
5
|
+
%th Local Product
|
6
|
+
%tbody
|
7
|
+
- products.each do |product|
|
8
|
+
%tr
|
9
|
+
%td=remote_product_link(product)
|
10
|
+
%td
|
11
|
+
- if product.local_product.present?
|
12
|
+
= local_product_link product.local_product
|
13
|
+
- else
|
14
|
+
= haml "widgets/_link_line".to_sym, locals: {direction: :remote_local, product_id: product.id}
|
15
|
+
|
@@ -0,0 +1,30 @@
|
|
1
|
+
= haml "products/menu".to_sym
|
2
|
+
|
3
|
+
%h1 Remote Products
|
4
|
+
|
5
|
+
%h2 of supplier #{settings.supplier.name} (#{@products.count})
|
6
|
+
|
7
|
+
%table.pure-table
|
8
|
+
%thead
|
9
|
+
%tr
|
10
|
+
%th
|
11
|
+
Product Name
|
12
|
+
%th
|
13
|
+
Product ID
|
14
|
+
%th
|
15
|
+
Local Name
|
16
|
+
%th
|
17
|
+
Supplier
|
18
|
+
%tbody
|
19
|
+
- @products.find_each do |product|
|
20
|
+
%tr
|
21
|
+
%td
|
22
|
+
%a(href="/remote_product/#{product.id}")= product.name
|
23
|
+
%td= product.product_id
|
24
|
+
%td
|
25
|
+
- if product.local_product.nil?
|
26
|
+
-#%a(href="/product/#{product.id}/link") Link to ...
|
27
|
+
Not linked
|
28
|
+
- else
|
29
|
+
= local_product_link product.local_product
|
30
|
+
%td= product.supplier.try(:name)
|
@@ -0,0 +1,63 @@
|
|
1
|
+
.icon#headicon
|
2
|
+
= settings_icon
|
3
|
+
|
4
|
+
= haml "maintenance/menu".to_sym
|
5
|
+
|
6
|
+
%h2 Supplier #{@supplier.name}
|
7
|
+
|
8
|
+
%form.pure-form.pure-form-aligned(action="" method="post")
|
9
|
+
%input(type="hidden" name="_method" value="put")
|
10
|
+
%fieldset
|
11
|
+
.pure-control-group
|
12
|
+
%label(for="email") E-Mail address
|
13
|
+
%input#email(name="email" type="email" value="#{@supplier.email}")
|
14
|
+
|
15
|
+
.pure-control-group
|
16
|
+
%label(for="order_template") Order Template
|
17
|
+
%textarea#order_template(name="order_template" value="#{@supplier.order_template}" rows="10" cols="80")~ @supplier.order_template
|
18
|
+
|
19
|
+
.pure-control-group
|
20
|
+
%button.pure-button.pure-button-primary
|
21
|
+
%i.fa.fa-save
|
22
|
+
Save
|
23
|
+
%h3 Help
|
24
|
+
.pure-control-group
|
25
|
+
%em
|
26
|
+
How to fill out templates:
|
27
|
+
.pure-control-group
|
28
|
+
See the example template in the following textarea. The line starting with a star (*) will be repeated. A list of supported symbols can be found below.
|
29
|
+
%br
|
30
|
+
%textarea#example_order_template(name="example_order_template" readonly rows="10" cols="80")
|
31
|
+
:preserve
|
32
|
+
SUBJECT=Order NAME
|
33
|
+
|
34
|
+
Dear NAME,
|
35
|
+
|
36
|
+
We will order
|
37
|
+
|
38
|
+
* PRODUCTCODE QTY (QTY_PACKS of PACKSIZE) PRODUCTNAME
|
39
|
+
|
40
|
+
Thank you,
|
41
|
+
|
42
|
+
us.
|
43
|
+
%br
|
44
|
+
Following symbols are supported:
|
45
|
+
%br
|
46
|
+
%dl
|
47
|
+
%dt SUBJECT=
|
48
|
+
%dd will be subject of the mail (and NOT included in mail itself)
|
49
|
+
%dt NAME
|
50
|
+
%dd will be replaced by this suppliers name
|
51
|
+
%dt *
|
52
|
+
%dd the line starting with a star will be iterated over with every product
|
53
|
+
%dt PRODUCTCODE
|
54
|
+
%dd the product code as stored in magento
|
55
|
+
%dt QTY
|
56
|
+
%dd quantity ordered
|
57
|
+
%dt QTY_PACKS
|
58
|
+
%dd quantity ordered (in packs of PACKSIZE)
|
59
|
+
%dt PACKSIZE
|
60
|
+
%dd packsize as stored in magento
|
61
|
+
%dt PRODUCTNAME
|
62
|
+
%dd the products name
|
63
|
+
%br
|
@@ -0,0 +1,32 @@
|
|
1
|
+
!!! 5
|
2
|
+
%html
|
3
|
+
%head
|
4
|
+
%title Rawbotz
|
5
|
+
%meta(name="viewport" content="width=device-width, initial-scale=1")
|
6
|
+
%meta(charset="utf-8")
|
7
|
+
%link(rel="stylesheet" txpe="text/css" href="/pure-min.css")
|
8
|
+
%link(rel="stylesheet" txpe="text/css" href="/font-awesome-4.5.0/css/font-awesome.min.css")
|
9
|
+
%link(rel="stylesheet" txpe="text/css" href="/rawbotz.css")
|
10
|
+
%script{:type => 'text/javascript', :src => "/Chart.min.js"}
|
11
|
+
%script{:type => 'text/javascript', :src => "/jquery-2.2.0.min.js"}
|
12
|
+
%script{:type => 'text/javascript', :src => "/jui/jquery-ui.min.js"}
|
13
|
+
%link(rel="stylesheet" type='text/css' href="/jui/jquery-ui.min.css")
|
14
|
+
%script{:type => 'text/javascript', :src => "/rawbotz.js"}
|
15
|
+
%body
|
16
|
+
.pure-g
|
17
|
+
.pure-u-1#main
|
18
|
+
- if flash
|
19
|
+
- if msg = flash.delete(:error)
|
20
|
+
#flash.ui-state-error
|
21
|
+
= msg.join(" | ")
|
22
|
+
- if msg = flash.delete(:success)
|
23
|
+
#flash.ui-state-highlight
|
24
|
+
= msg.join(" | ")
|
25
|
+
- if msg = flash.delete(:failure)
|
26
|
+
#flash.ui-state-highlight
|
27
|
+
= msg.join(" | ")
|
28
|
+
- if msg = flash.delete(:info)
|
29
|
+
#flash.ui-state-highlight
|
30
|
+
= msg.join(" | ")
|
31
|
+
|
32
|
+
=yield
|
@@ -0,0 +1,6 @@
|
|
1
|
+
%form.pure-form(action="/product/#{local_product.id}/link" method="POST")
|
2
|
+
%input(type="hidden" name="remote_product_id" id="remote_product_id")
|
3
|
+
%input(type="hidden" name="redirect_to" value="#{redirect_to}")
|
4
|
+
%input#search-remote(placeholder="search ...")
|
5
|
+
%button.pure-button
|
6
|
+
Link!
|
@@ -0,0 +1,15 @@
|
|
1
|
+
- if locals[:direction] == :remote_local
|
2
|
+
.link_line
|
3
|
+
.result(style="display:none;")
|
4
|
+
.ajax_link_area.pure-form
|
5
|
+
%input.search-local-ajax(placeholder="search ...")
|
6
|
+
%input.local_product_id(type="hidden")
|
7
|
+
%input.remote_product_id(type="hidden" value="#{product_id}")
|
8
|
+
%a.product_link_action.pure-button(href="")
|
9
|
+
Link
|
10
|
+
- else
|
11
|
+
.ajax_link_area.pure-form
|
12
|
+
%input.search-remote-ajax(placeholder="search ...")
|
13
|
+
%input.remote_product_id(type="hidden")
|
14
|
+
%a.ajax_product_link(href="")
|
15
|
+
Link! LR
|
data/lib/rawbotz.rb
ADDED
@@ -0,0 +1,77 @@
|
|
1
|
+
require "rawbotz/version"
|
2
|
+
require "rawbotz/remote_shop"
|
3
|
+
require "rawbotz/local_shop"
|
4
|
+
require "rawbotz/order_processor"
|
5
|
+
require "rawbotz/datapolate"
|
6
|
+
require "rawbotz/product_updater"
|
7
|
+
require "rawbotz/routes"
|
8
|
+
require "rawbotz/mail_template"
|
9
|
+
|
10
|
+
require 'rawgento_models'
|
11
|
+
require 'rawgento_db'
|
12
|
+
|
13
|
+
require 'ostruct'
|
14
|
+
require 'yaml'
|
15
|
+
require 'pony'
|
16
|
+
|
17
|
+
module Rawbotz
|
18
|
+
@@conf_file_path = nil
|
19
|
+
def self.conf_file_path=(conf_file_path)
|
20
|
+
@@conf_file_path = conf_file_path
|
21
|
+
end
|
22
|
+
def self.conf_file_path
|
23
|
+
@@conf_file_path
|
24
|
+
end
|
25
|
+
|
26
|
+
# Configure components (from config file path), exit 1 if fails.
|
27
|
+
# 'logs' to STDERR (TODO)
|
28
|
+
def self.configure!
|
29
|
+
begin
|
30
|
+
RawgentoModels.establish_connection @@conf_file_path
|
31
|
+
rescue
|
32
|
+
STDERR.puts "Could not establish rawbotz-database connection (read config from: #{@@conf_file_path})"
|
33
|
+
exit 1
|
34
|
+
end
|
35
|
+
begin
|
36
|
+
RawgentoDB.settings @@conf_file_path
|
37
|
+
rescue
|
38
|
+
STDERR.puts "Could not establish magento-database connection (read config from: #{@@conf_file_path})"
|
39
|
+
exit 1
|
40
|
+
end
|
41
|
+
# As a bonus, set mechs config (TODO)
|
42
|
+
end
|
43
|
+
|
44
|
+
def self.logger
|
45
|
+
@logger ||= Logger.new(STDOUT)
|
46
|
+
end
|
47
|
+
def self.logger= logger
|
48
|
+
@logger = logger
|
49
|
+
end
|
50
|
+
def self.configure_logger options
|
51
|
+
logger.level = options[:verbose] ? Logger::DEBUG : Logger::INFO
|
52
|
+
end
|
53
|
+
|
54
|
+
def self.new_mech
|
55
|
+
config_values = YAML::load_file(@@conf_file_path)["remote_shop"]
|
56
|
+
MagentoMech.from_config OpenStruct.new(config_values)
|
57
|
+
end
|
58
|
+
|
59
|
+
def self.mail subject, body
|
60
|
+
# From config, this should be memoized
|
61
|
+
settings = YAML::load_file(Rawbotz::conf_file_path)["mail"]
|
62
|
+
pony_via_options = { address: settings["host"],
|
63
|
+
user_name: settings["user"],
|
64
|
+
port: settings["port"].to_i,
|
65
|
+
authentication: :login,
|
66
|
+
password: settings["pass"]}
|
67
|
+
|
68
|
+
Pony.mail({
|
69
|
+
to: settings["to"],
|
70
|
+
from: settings["from"],
|
71
|
+
subject: subject,
|
72
|
+
body: body,
|
73
|
+
via: :smtp,
|
74
|
+
via_options: pony_via_options
|
75
|
+
})
|
76
|
+
end
|
77
|
+
end
|