Commit dba8a0e7d8a08ba47cda0a134e65c58f556749c8
Exists in
master
and in
28 other branches
Merge commit 'refs/merge-requests/40' of git://gitorious.org/noosfero/noosfero
Showing
16 changed files
with
1022 additions
and
3 deletions
Show diff stats
plugins/shopping_cart/controllers/shopping_cart_plugin_myprofile_controller.rb
| 1 | +include ShoppingCartPlugin::CartHelper | ||
| 2 | + | ||
| 1 | class ShoppingCartPluginMyprofileController < MyProfileController | 3 | class ShoppingCartPluginMyprofileController < MyProfileController |
| 2 | append_view_path File.join(File.dirname(__FILE__) + '/../views') | 4 | append_view_path File.join(File.dirname(__FILE__) + '/../views') |
| 3 | 5 | ||
| @@ -13,4 +15,35 @@ class ShoppingCartPluginMyprofileController < MyProfileController | @@ -13,4 +15,35 @@ class ShoppingCartPluginMyprofileController < MyProfileController | ||
| 13 | end | 15 | end |
| 14 | end | 16 | end |
| 15 | 17 | ||
| 18 | + def reports | ||
| 19 | + utc_string = ' 00:00:00 UTC' | ||
| 20 | + @from = params[:from] ? Time.parse(params[:from] + utc_string) : Time.now.utc.at_beginning_of_month | ||
| 21 | + @to = params[:to] ? Time.parse(params[:to] + utc_string) : Time.now.utc | ||
| 22 | + @status = !params[:filter_status].blank? ? params[:filter_status].to_i : nil | ||
| 23 | + | ||
| 24 | + condition = 'created_at >= ? AND created_at <= ?' | ||
| 25 | + condition_parameters = [@from, @to+1.day] | ||
| 26 | + if @status | ||
| 27 | + condition += ' AND status == ?' | ||
| 28 | + condition_parameters << @status | ||
| 29 | + end | ||
| 30 | + | ||
| 31 | + conditions = [condition] + condition_parameters | ||
| 32 | + @orders = profile.orders.find(:all, :conditions => conditions) | ||
| 33 | + | ||
| 34 | + @products = {} | ||
| 35 | + @orders.each do |order| | ||
| 36 | + order.products_list.each do |id, qp| | ||
| 37 | + @products[id] ||= 0 | ||
| 38 | + @products[id] += qp[:quantity] | ||
| 39 | + end | ||
| 40 | + end | ||
| 41 | + end | ||
| 42 | + | ||
| 43 | + def update_order_status | ||
| 44 | + order = ShoppingCartPlugin::PurchaseOrder.find(params[:order_id].to_i) | ||
| 45 | + order.status = params[:order_status].to_i | ||
| 46 | + order.save! | ||
| 47 | + redirect_to :action => 'reports', :from => params[:context_from], :to => params[:context_to], :filter_status => params[:context_status] | ||
| 48 | + end | ||
| 16 | end | 49 | end |
plugins/shopping_cart/controllers/shopping_cart_plugin_profile_controller.rb
| @@ -89,6 +89,7 @@ class ShoppingCartPluginProfileController < ProfileController | @@ -89,6 +89,7 @@ class ShoppingCartPluginProfileController < ProfileController | ||
| 89 | end | 89 | end |
| 90 | 90 | ||
| 91 | def send_request | 91 | def send_request |
| 92 | + register_order(params[:customer], session[:cart][:items]) | ||
| 92 | begin | 93 | begin |
| 93 | ShoppingCartPlugin::Mailer.deliver_customer_notification(params[:customer], profile, session[:cart][:items]) | 94 | ShoppingCartPlugin::Mailer.deliver_customer_notification(params[:customer], profile, session[:cart][:items]) |
| 94 | ShoppingCartPlugin::Mailer.deliver_supplier_notification(params[:customer], profile, session[:cart][:items]) | 95 | ShoppingCartPlugin::Mailer.deliver_supplier_notification(params[:customer], profile, session[:cart][:items]) |
| @@ -223,4 +224,23 @@ class ShoppingCartPluginProfileController < ProfileController | @@ -223,4 +224,23 @@ class ShoppingCartPluginProfileController < ProfileController | ||
| 223 | end | 224 | end |
| 224 | true | 225 | true |
| 225 | end | 226 | end |
| 227 | + | ||
| 228 | + def register_order(custumer, items) | ||
| 229 | + new_items = {} | ||
| 230 | + items.each do |id, quantity| | ||
| 231 | + new_items[id] = {:quantity => quantity, :price => Product.find(id).price} | ||
| 232 | + end | ||
| 233 | + ShoppingCartPlugin::PurchaseOrder.create!( | ||
| 234 | + :seller => profile, | ||
| 235 | + :customer => user, | ||
| 236 | + :status => ShoppingCartPlugin::PurchaseOrder::Status::OPENED, | ||
| 237 | + :products_list => new_items, | ||
| 238 | + :customer_name => params[:customer][:name], | ||
| 239 | + :customer_email => params[:customer][:email], | ||
| 240 | + :customer_contact_phone => params[:customer][:contact_phone], | ||
| 241 | + :customer_address => params[:customer][:address], | ||
| 242 | + :customer_city => params[:customer][:city], | ||
| 243 | + :customer_zip_code => params[:customer][:zip_code] | ||
| 244 | + ) | ||
| 245 | + end | ||
| 226 | end | 246 | end |
plugins/shopping_cart/db/migrate/20110825173657_create_purchase_order.rb
0 → 100644
| @@ -0,0 +1,15 @@ | @@ -0,0 +1,15 @@ | ||
| 1 | +class CreatePurchaseOrder < ActiveRecord::Migration | ||
| 2 | + def self.up | ||
| 3 | + create_table :shopping_cart_plugin_purchase_orders do |t| | ||
| 4 | + t.references :customer | ||
| 5 | + t.references :seller | ||
| 6 | + t.text :data | ||
| 7 | + t.integer :status | ||
| 8 | + t.timestamps | ||
| 9 | + end | ||
| 10 | + end | ||
| 11 | + | ||
| 12 | + def self.down | ||
| 13 | + drop_table :shopping_cart_plugin_purchase_order | ||
| 14 | + end | ||
| 15 | +end |
plugins/shopping_cart/lib/shopping_cart_plugin.rb
| 1 | +require_dependency 'ext/enterprise' | ||
| 2 | +require_dependency 'ext/person' | ||
| 3 | + | ||
| 1 | class ShoppingCartPlugin < Noosfero::Plugin | 4 | class ShoppingCartPlugin < Noosfero::Plugin |
| 2 | 5 | ||
| 3 | def self.plugin_name | 6 | def self.plugin_name |
| @@ -42,8 +45,14 @@ class ShoppingCartPlugin < Noosfero::Plugin | @@ -42,8 +45,14 @@ class ShoppingCartPlugin < Noosfero::Plugin | ||
| 42 | end | 45 | end |
| 43 | 46 | ||
| 44 | def control_panel_buttons | 47 | def control_panel_buttons |
| 48 | + buttons = [] | ||
| 45 | if context.profile.enterprise? | 49 | if context.profile.enterprise? |
| 46 | - { :title => 'Shopping cart', :icon => 'shopping_cart_icon', :url => {:controller => 'shopping_cart_plugin_myprofile', :action => 'edit'} } | 50 | + buttons << { :title => 'Shopping cart', :icon => 'shopping_cart_icon', :url => {:controller => 'shopping_cart_plugin_myprofile', :action => 'edit'} } |
| 51 | + end | ||
| 52 | + if context.profile.enterprise? && context.profile.shopping_cart | ||
| 53 | + buttons << { :title => 'Purchase reports', :icon => 'shopping-cart-purchase-report', :url => {:controller => 'shopping_cart_plugin_myprofile', :action => 'reports'} } | ||
| 47 | end | 54 | end |
| 55 | + | ||
| 56 | + buttons | ||
| 48 | end | 57 | end |
| 49 | end | 58 | end |
plugins/shopping_cart/lib/shopping_cart_plugin/cart_helper.rb
| @@ -54,8 +54,6 @@ module ShoppingCartPlugin::CartHelper | @@ -54,8 +54,6 @@ module ShoppingCartPlugin::CartHelper | ||
| 54 | '</table>' | 54 | '</table>' |
| 55 | end | 55 | end |
| 56 | 56 | ||
| 57 | - private | ||
| 58 | - | ||
| 59 | def float_to_currency_cart(value, environment) | 57 | def float_to_currency_cart(value, environment) |
| 60 | number_to_currency(value, :unit => environment.currency_unit, :separator => environment.currency_separator, :delimiter => environment.currency_delimiter, :format => "%u %n") | 58 | number_to_currency(value, :unit => environment.currency_unit, :separator => environment.currency_separator, :delimiter => environment.currency_delimiter, :format => "%u %n") |
| 61 | end | 59 | end |
plugins/shopping_cart/lib/shopping_cart_plugin/purchase_order.rb
0 → 100644
| @@ -0,0 +1,37 @@ | @@ -0,0 +1,37 @@ | ||
| 1 | +class ShoppingCartPlugin::PurchaseOrder < Noosfero::Plugin::ActiveRecord | ||
| 2 | + | ||
| 3 | + belongs_to :customer, :class_name => "Profile" | ||
| 4 | + belongs_to :seller, :class_name => "Profile" | ||
| 5 | + | ||
| 6 | + validates_presence_of :status, :seller | ||
| 7 | + | ||
| 8 | + acts_as_having_settings :field => :data | ||
| 9 | + | ||
| 10 | + settings_items :products_list, :type => Array, :default => {} | ||
| 11 | + settings_items :customer_name, :type => String | ||
| 12 | + settings_items :customer_email, :type => String | ||
| 13 | + settings_items :customer_contact_phone, :type => String | ||
| 14 | + settings_items :customer_address, :type => String | ||
| 15 | + settings_items :customer_city, :type => String | ||
| 16 | + settings_items :customer_zip_code, :type => String | ||
| 17 | + | ||
| 18 | + before_create do |order| | ||
| 19 | + order.created_at = Time.now.utc | ||
| 20 | + order.updated_at = Time.now.utc | ||
| 21 | + end | ||
| 22 | + | ||
| 23 | + before_update do |order| | ||
| 24 | + order.updated_at = Time.now.utc | ||
| 25 | + end | ||
| 26 | + | ||
| 27 | + module Status | ||
| 28 | + OPENED = 0 | ||
| 29 | + CANCELED = 1 | ||
| 30 | + CONFIRMED = 2 | ||
| 31 | + SHIPPED = 3 | ||
| 32 | + | ||
| 33 | + def self.name | ||
| 34 | + [_('Opened'), _('Canceled'), _('Confirmed'), _('Shipped')] | ||
| 35 | + end | ||
| 36 | + end | ||
| 37 | +end |
2.44 KB
plugins/shopping_cart/public/images/control-panel/purchase-report.svg
0 → 100644
| @@ -0,0 +1,648 @@ | @@ -0,0 +1,648 @@ | ||
| 1 | +<?xml version="1.0" encoding="UTF-8" standalone="no"?> | ||
| 2 | +<!-- Created with Inkscape (http://www.inkscape.org/) --> | ||
| 3 | + | ||
| 4 | +<svg | ||
| 5 | + xmlns:dc="http://purl.org/dc/elements/1.1/" | ||
| 6 | + xmlns:cc="http://creativecommons.org/ns#" | ||
| 7 | + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" | ||
| 8 | + xmlns:svg="http://www.w3.org/2000/svg" | ||
| 9 | + xmlns="http://www.w3.org/2000/svg" | ||
| 10 | + xmlns:xlink="http://www.w3.org/1999/xlink" | ||
| 11 | + xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" | ||
| 12 | + xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" | ||
| 13 | + width="48" | ||
| 14 | + height="48" | ||
| 15 | + id="svg2" | ||
| 16 | + version="1.1" | ||
| 17 | + inkscape:version="0.47 r22583" | ||
| 18 | + sodipodi:docname="purchase-report.svg" | ||
| 19 | + inkscape:export-filename="/home/aurium/purchase-report.png" | ||
| 20 | + inkscape:export-xdpi="90" | ||
| 21 | + inkscape:export-ydpi="90"> | ||
| 22 | + <defs | ||
| 23 | + id="defs4"> | ||
| 24 | + <linearGradient | ||
| 25 | + inkscape:collect="always" | ||
| 26 | + id="linearGradient4980"> | ||
| 27 | + <stop | ||
| 28 | + style="stop-color:#2e3436;stop-opacity:1;" | ||
| 29 | + offset="0" | ||
| 30 | + id="stop4982" /> | ||
| 31 | + <stop | ||
| 32 | + style="stop-color:#babdb6;stop-opacity:0" | ||
| 33 | + offset="1" | ||
| 34 | + id="stop4984" /> | ||
| 35 | + </linearGradient> | ||
| 36 | + <linearGradient | ||
| 37 | + id="linearGradient4962" | ||
| 38 | + inkscape:collect="always"> | ||
| 39 | + <stop | ||
| 40 | + id="stop4964" | ||
| 41 | + offset="0" | ||
| 42 | + style="stop-color:#ffffff;stop-opacity:0" /> | ||
| 43 | + <stop | ||
| 44 | + id="stop4966" | ||
| 45 | + offset="1" | ||
| 46 | + style="stop-color:#ffffff;stop-opacity:1" /> | ||
| 47 | + </linearGradient> | ||
| 48 | + <linearGradient | ||
| 49 | + inkscape:collect="always" | ||
| 50 | + id="linearGradient4952"> | ||
| 51 | + <stop | ||
| 52 | + style="stop-color:#555753;stop-opacity:1;" | ||
| 53 | + offset="0" | ||
| 54 | + id="stop4954" /> | ||
| 55 | + <stop | ||
| 56 | + style="stop-color:#888a85;stop-opacity:1" | ||
| 57 | + offset="1" | ||
| 58 | + id="stop4956" /> | ||
| 59 | + </linearGradient> | ||
| 60 | + <linearGradient | ||
| 61 | + inkscape:collect="always" | ||
| 62 | + id="linearGradient4944"> | ||
| 63 | + <stop | ||
| 64 | + style="stop-color:#888a85;stop-opacity:1;" | ||
| 65 | + offset="0" | ||
| 66 | + id="stop4946" /> | ||
| 67 | + <stop | ||
| 68 | + style="stop-color:#555753;stop-opacity:1" | ||
| 69 | + offset="1" | ||
| 70 | + id="stop4948" /> | ||
| 71 | + </linearGradient> | ||
| 72 | + <linearGradient | ||
| 73 | + inkscape:collect="always" | ||
| 74 | + id="linearGradient4914"> | ||
| 75 | + <stop | ||
| 76 | + style="stop-color:#cccccc;stop-opacity:1" | ||
| 77 | + offset="0" | ||
| 78 | + id="stop4916" /> | ||
| 79 | + <stop | ||
| 80 | + style="stop-color:#4d4d4d;stop-opacity:1" | ||
| 81 | + offset="1" | ||
| 82 | + id="stop4918" /> | ||
| 83 | + </linearGradient> | ||
| 84 | + <linearGradient | ||
| 85 | + inkscape:collect="always" | ||
| 86 | + id="linearGradient4853"> | ||
| 87 | + <stop | ||
| 88 | + style="stop-color:#000000;stop-opacity:1;" | ||
| 89 | + offset="0" | ||
| 90 | + id="stop4855" /> | ||
| 91 | + <stop | ||
| 92 | + style="stop-color:#000000;stop-opacity:0;" | ||
| 93 | + offset="1" | ||
| 94 | + id="stop4857" /> | ||
| 95 | + </linearGradient> | ||
| 96 | + <inkscape:perspective | ||
| 97 | + sodipodi:type="inkscape:persp3d" | ||
| 98 | + inkscape:vp_x="0 : 526.18109 : 1" | ||
| 99 | + inkscape:vp_y="0 : 1000 : 0" | ||
| 100 | + inkscape:vp_z="744.09448 : 526.18109 : 1" | ||
| 101 | + inkscape:persp3d-origin="372.04724 : 350.78739 : 1" | ||
| 102 | + id="perspective10" /> | ||
| 103 | + <inkscape:perspective | ||
| 104 | + id="perspective3634" | ||
| 105 | + inkscape:persp3d-origin="0.5 : 0.33333333 : 1" | ||
| 106 | + inkscape:vp_z="1 : 0.5 : 1" | ||
| 107 | + inkscape:vp_y="0 : 1000 : 0" | ||
| 108 | + inkscape:vp_x="0 : 0.5 : 1" | ||
| 109 | + sodipodi:type="inkscape:persp3d" /> | ||
| 110 | + <inkscape:perspective | ||
| 111 | + id="perspective3659" | ||
| 112 | + inkscape:persp3d-origin="0.5 : 0.33333333 : 1" | ||
| 113 | + inkscape:vp_z="1 : 0.5 : 1" | ||
| 114 | + inkscape:vp_y="0 : 1000 : 0" | ||
| 115 | + inkscape:vp_x="0 : 0.5 : 1" | ||
| 116 | + sodipodi:type="inkscape:persp3d" /> | ||
| 117 | + <inkscape:perspective | ||
| 118 | + id="perspective4618" | ||
| 119 | + inkscape:persp3d-origin="0.5 : 0.33333333 : 1" | ||
| 120 | + inkscape:vp_z="1 : 0.5 : 1" | ||
| 121 | + inkscape:vp_y="0 : 1000 : 0" | ||
| 122 | + inkscape:vp_x="0 : 0.5 : 1" | ||
| 123 | + sodipodi:type="inkscape:persp3d" /> | ||
| 124 | + <linearGradient | ||
| 125 | + id="linearGradient2251"> | ||
| 126 | + <stop | ||
| 127 | + style="stop-color:#ffffff;stop-opacity:1;" | ||
| 128 | + offset="0" | ||
| 129 | + id="stop2253" /> | ||
| 130 | + <stop | ||
| 131 | + style="stop-color:#ffffff;stop-opacity:0;" | ||
| 132 | + offset="1" | ||
| 133 | + id="stop2255" /> | ||
| 134 | + </linearGradient> | ||
| 135 | + <linearGradient | ||
| 136 | + inkscape:collect="always" | ||
| 137 | + xlink:href="#linearGradient2224" | ||
| 138 | + id="linearGradient4602" | ||
| 139 | + gradientUnits="userSpaceOnUse" | ||
| 140 | + gradientTransform="translate(3.2628514,1006.5776)" | ||
| 141 | + x1="36.237148" | ||
| 142 | + y1="41.284599" | ||
| 143 | + x2="33.664921" | ||
| 144 | + y2="37.770721" /> | ||
| 145 | + <linearGradient | ||
| 146 | + id="linearGradient2224"> | ||
| 147 | + <stop | ||
| 148 | + style="stop-color:#7c7c7c;stop-opacity:1;" | ||
| 149 | + offset="0" | ||
| 150 | + id="stop2226" /> | ||
| 151 | + <stop | ||
| 152 | + style="stop-color:#b8b8b8;stop-opacity:1;" | ||
| 153 | + offset="1" | ||
| 154 | + id="stop2228" /> | ||
| 155 | + </linearGradient> | ||
| 156 | + <linearGradient | ||
| 157 | + inkscape:collect="always" | ||
| 158 | + xlink:href="#linearGradient2259" | ||
| 159 | + id="linearGradient4605" | ||
| 160 | + gradientUnits="userSpaceOnUse" | ||
| 161 | + gradientTransform="matrix(0.999421,0,0,1,-5.0089689,998.39565)" | ||
| 162 | + x1="26.076092" | ||
| 163 | + y1="26.696676" | ||
| 164 | + x2="30.811172" | ||
| 165 | + y2="42.007351" /> | ||
| 166 | + <linearGradient | ||
| 167 | + inkscape:collect="always" | ||
| 168 | + id="linearGradient2259"> | ||
| 169 | + <stop | ||
| 170 | + style="stop-color:#ffffff;stop-opacity:1;" | ||
| 171 | + offset="0" | ||
| 172 | + id="stop2261" /> | ||
| 173 | + <stop | ||
| 174 | + style="stop-color:#ffffff;stop-opacity:0;" | ||
| 175 | + offset="1" | ||
| 176 | + id="stop2263" /> | ||
| 177 | + </linearGradient> | ||
| 178 | + <linearGradient | ||
| 179 | + inkscape:collect="always" | ||
| 180 | + xlink:href="#linearGradient15218" | ||
| 181 | + id="linearGradient4608" | ||
| 182 | + gradientUnits="userSpaceOnUse" | ||
| 183 | + gradientTransform="matrix(1.067236,0,0,0.989276,4.391684,4.035227)" | ||
| 184 | + x1="22.308331" | ||
| 185 | + y1="18.99214" | ||
| 186 | + x2="35.785294" | ||
| 187 | + y2="39.498238" /> | ||
| 188 | + <linearGradient | ||
| 189 | + id="linearGradient15218"> | ||
| 190 | + <stop | ||
| 191 | + style="stop-color:#f0f0ef;stop-opacity:1.0000000;" | ||
| 192 | + offset="0.0000000" | ||
| 193 | + id="stop15220" /> | ||
| 194 | + <stop | ||
| 195 | + id="stop2269" | ||
| 196 | + offset="0.59928656" | ||
| 197 | + style="stop-color:#e8e8e8;stop-opacity:1;" /> | ||
| 198 | + <stop | ||
| 199 | + id="stop2267" | ||
| 200 | + offset="0.82758623" | ||
| 201 | + style="stop-color:#ffffff;stop-opacity:1;" /> | ||
| 202 | + <stop | ||
| 203 | + style="stop-color:#d8d8d3;stop-opacity:1.0000000;" | ||
| 204 | + offset="1.0000000" | ||
| 205 | + id="stop15222" /> | ||
| 206 | + </linearGradient> | ||
| 207 | + <inkscape:perspective | ||
| 208 | + id="perspective4722" | ||
| 209 | + inkscape:persp3d-origin="0.5 : 0.33333333 : 1" | ||
| 210 | + inkscape:vp_z="1 : 0.5 : 1" | ||
| 211 | + inkscape:vp_y="0 : 1000 : 0" | ||
| 212 | + inkscape:vp_x="0 : 0.5 : 1" | ||
| 213 | + sodipodi:type="inkscape:persp3d" /> | ||
| 214 | + <linearGradient | ||
| 215 | + y2="-968.28137" | ||
| 216 | + x2="46.01725" | ||
| 217 | + y1="-987.48724" | ||
| 218 | + x1="31.962252" | ||
| 219 | + gradientTransform="matrix(1.067236,0,0,0.989276,-9.611267,2002.7597)" | ||
| 220 | + gradientUnits="userSpaceOnUse" | ||
| 221 | + id="linearGradient4644-0" | ||
| 222 | + xlink:href="#linearGradient15218-5" | ||
| 223 | + inkscape:collect="always" /> | ||
| 224 | + <linearGradient | ||
| 225 | + id="linearGradient15218-5"> | ||
| 226 | + <stop | ||
| 227 | + style="stop-color:#f0f0ef;stop-opacity:1.0000000;" | ||
| 228 | + offset="0.0000000" | ||
| 229 | + id="stop15220-1" /> | ||
| 230 | + <stop | ||
| 231 | + id="stop2269-8" | ||
| 232 | + offset="0.59928656" | ||
| 233 | + style="stop-color:#e8e8e8;stop-opacity:1;" /> | ||
| 234 | + <stop | ||
| 235 | + id="stop2267-9" | ||
| 236 | + offset="0.82758623" | ||
| 237 | + style="stop-color:#ffffff;stop-opacity:1;" /> | ||
| 238 | + <stop | ||
| 239 | + style="stop-color:#d8d8d3;stop-opacity:1.0000000;" | ||
| 240 | + offset="1.0000000" | ||
| 241 | + id="stop15222-1" /> | ||
| 242 | + </linearGradient> | ||
| 243 | + <linearGradient | ||
| 244 | + y2="39.498238" | ||
| 245 | + x2="35.785294" | ||
| 246 | + y1="18.99214" | ||
| 247 | + x1="22.308331" | ||
| 248 | + gradientTransform="matrix(1.067236,0,0,0.989276,-11.611266,-5.9647499)" | ||
| 249 | + gradientUnits="userSpaceOnUse" | ||
| 250 | + id="linearGradient4733" | ||
| 251 | + xlink:href="#linearGradient15218-5" | ||
| 252 | + inkscape:collect="always" /> | ||
| 253 | + <linearGradient | ||
| 254 | + inkscape:collect="always" | ||
| 255 | + xlink:href="#linearGradient4853" | ||
| 256 | + id="linearGradient4870" | ||
| 257 | + gradientUnits="userSpaceOnUse" | ||
| 258 | + x1="32.5" | ||
| 259 | + y1="1026.8622" | ||
| 260 | + x2="36.5" | ||
| 261 | + y2="1026.8622" | ||
| 262 | + gradientTransform="translate(0,15)" /> | ||
| 263 | + <linearGradient | ||
| 264 | + inkscape:collect="always" | ||
| 265 | + xlink:href="#linearGradient4914" | ||
| 266 | + id="linearGradient4926" | ||
| 267 | + gradientUnits="userSpaceOnUse" | ||
| 268 | + x1="21.5" | ||
| 269 | + y1="16.5" | ||
| 270 | + x2="32.5" | ||
| 271 | + y2="38.5" | ||
| 272 | + gradientTransform="translate(0,1004.3622)" /> | ||
| 273 | + <mask | ||
| 274 | + maskUnits="userSpaceOnUse" | ||
| 275 | + id="mask4922"> | ||
| 276 | + <rect | ||
| 277 | + style="color:#000000;fill:url(#linearGradient4926);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" | ||
| 278 | + id="rect4924" | ||
| 279 | + width="34" | ||
| 280 | + height="41" | ||
| 281 | + x="7.5" | ||
| 282 | + y="1006.8622" /> | ||
| 283 | + </mask> | ||
| 284 | + <filter | ||
| 285 | + inkscape:collect="always" | ||
| 286 | + id="filter4938" | ||
| 287 | + x="-0.063571429" | ||
| 288 | + width="1.1271429" | ||
| 289 | + y="-1.0679999" | ||
| 290 | + height="3.1359998"> | ||
| 291 | + <feGaussianBlur | ||
| 292 | + inkscape:collect="always" | ||
| 293 | + stdDeviation="1.1124999" | ||
| 294 | + id="feGaussianBlur4940" /> | ||
| 295 | + </filter> | ||
| 296 | + <linearGradient | ||
| 297 | + inkscape:collect="always" | ||
| 298 | + xlink:href="#linearGradient4944" | ||
| 299 | + id="linearGradient4950" | ||
| 300 | + x1="5.5" | ||
| 301 | + y1="1015.8622" | ||
| 302 | + x2="11.5" | ||
| 303 | + y2="1049.8622" | ||
| 304 | + gradientUnits="userSpaceOnUse" /> | ||
| 305 | + <linearGradient | ||
| 306 | + inkscape:collect="always" | ||
| 307 | + xlink:href="#linearGradient4962" | ||
| 308 | + id="linearGradient4958" | ||
| 309 | + x1="36.5" | ||
| 310 | + y1="1047.8622" | ||
| 311 | + x2="31.5" | ||
| 312 | + y2="1038.8622" | ||
| 313 | + gradientUnits="userSpaceOnUse" /> | ||
| 314 | + <linearGradient | ||
| 315 | + inkscape:collect="always" | ||
| 316 | + xlink:href="#linearGradient4952" | ||
| 317 | + id="linearGradient4960" | ||
| 318 | + gradientUnits="userSpaceOnUse" | ||
| 319 | + x1="34.5" | ||
| 320 | + y1="1046.8622" | ||
| 321 | + x2="29.5" | ||
| 322 | + y2="1039.8622" /> | ||
| 323 | + <linearGradient | ||
| 324 | + inkscape:collect="always" | ||
| 325 | + xlink:href="#linearGradient4962" | ||
| 326 | + id="linearGradient4968" | ||
| 327 | + gradientUnits="userSpaceOnUse" | ||
| 328 | + x1="37.420265" | ||
| 329 | + y1="1044.8622" | ||
| 330 | + x2="36.5" | ||
| 331 | + y2="1043.8622" /> | ||
| 332 | + <linearGradient | ||
| 333 | + inkscape:collect="always" | ||
| 334 | + xlink:href="#linearGradient4980" | ||
| 335 | + id="linearGradient4986" | ||
| 336 | + x1="38.5" | ||
| 337 | + y1="41.5" | ||
| 338 | + x2="41.5" | ||
| 339 | + y2="44.5" | ||
| 340 | + gradientUnits="userSpaceOnUse" /> | ||
| 341 | + </defs> | ||
| 342 | + <sodipodi:namedview | ||
| 343 | + id="base" | ||
| 344 | + pagecolor="#ffffff" | ||
| 345 | + bordercolor="#666666" | ||
| 346 | + borderopacity="1.0" | ||
| 347 | + inkscape:pageopacity="0.0" | ||
| 348 | + inkscape:pageshadow="2" | ||
| 349 | + inkscape:zoom="12.541667" | ||
| 350 | + inkscape:cx="24" | ||
| 351 | + inkscape:cy="24" | ||
| 352 | + inkscape:document-units="px" | ||
| 353 | + inkscape:current-layer="layer1" | ||
| 354 | + showgrid="true" | ||
| 355 | + inkscape:window-width="1440" | ||
| 356 | + inkscape:window-height="827" | ||
| 357 | + inkscape:window-x="0" | ||
| 358 | + inkscape:window-y="25" | ||
| 359 | + inkscape:window-maximized="1"> | ||
| 360 | + <inkscape:grid | ||
| 361 | + type="xygrid" | ||
| 362 | + id="grid2816" | ||
| 363 | + empspacing="5" | ||
| 364 | + visible="true" | ||
| 365 | + enabled="true" | ||
| 366 | + snapvisiblegridlinesonly="true" | ||
| 367 | + spacingx="1px" | ||
| 368 | + originx="0.5px" | ||
| 369 | + originy="0.5px" /> | ||
| 370 | + </sodipodi:namedview> | ||
| 371 | + <metadata | ||
| 372 | + id="metadata7"> | ||
| 373 | + <rdf:RDF> | ||
| 374 | + <cc:Work | ||
| 375 | + rdf:about=""> | ||
| 376 | + <dc:format>image/svg+xml</dc:format> | ||
| 377 | + <dc:type | ||
| 378 | + rdf:resource="http://purl.org/dc/dcmitype/StillImage" /> | ||
| 379 | + <dc:title></dc:title> | ||
| 380 | + </cc:Work> | ||
| 381 | + </rdf:RDF> | ||
| 382 | + </metadata> | ||
| 383 | + <g | ||
| 384 | + inkscape:label="Camada 1" | ||
| 385 | + inkscape:groupmode="layer" | ||
| 386 | + id="layer1" | ||
| 387 | + transform="translate(0,-1004.3622)"> | ||
| 388 | + <rect | ||
| 389 | + style="color:#000000;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate;filter:url(#filter4938);opacity:0.7" | ||
| 390 | + id="rect4928" | ||
| 391 | + width="41.999996" | ||
| 392 | + height="2.5" | ||
| 393 | + x="3.5" | ||
| 394 | + y="43.5" | ||
| 395 | + transform="translate(0,1004.3622)" | ||
| 396 | + ry="1" /> | ||
| 397 | + <rect | ||
| 398 | + style="color:#000000;fill:url(#linearGradient4644-0);fill-opacity:1;fill-rule:evenodd;stroke:url(#linearGradient4950);stroke-width:1.00000024000000010;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" | ||
| 399 | + id="rect4699" | ||
| 400 | + width="38" | ||
| 401 | + height="45" | ||
| 402 | + x="5.5" | ||
| 403 | + y="1004.8622" | ||
| 404 | + ry="1" /> | ||
| 405 | + <path | ||
| 406 | + style="fill:url(#linearGradient4986);stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;fill-opacity:1;opacity:0.59999999999999998" | ||
| 407 | + d="M 33.5,45 43,36.5 43,45 33.5,45 z" | ||
| 408 | + id="path4970" | ||
| 409 | + transform="translate(0,1004.3622)" | ||
| 410 | + sodipodi:nodetypes="cccc" /> | ||
| 411 | + <rect | ||
| 412 | + style="fill:none;stroke:url(#linearGradient4605);stroke-width:1.00000083;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0" | ||
| 413 | + id="rect15244" | ||
| 414 | + width="35.997337" | ||
| 415 | + height="43.000019" | ||
| 416 | + x="6.5026627" | ||
| 417 | + y="1005.8622" | ||
| 418 | + rx="0" | ||
| 419 | + ry="0" /> | ||
| 420 | + <g | ||
| 421 | + id="g4873" | ||
| 422 | + mask="url(#mask4922)"> | ||
| 423 | + <g | ||
| 424 | + transform="translate(6,1)" | ||
| 425 | + id="g4757"> | ||
| 426 | + <path | ||
| 427 | + style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1" | ||
| 428 | + d="m 2.5,2.5 2,0 0,8 12,0 0,-6" | ||
| 429 | + id="path2839" | ||
| 430 | + transform="translate(0,1004.3622)" | ||
| 431 | + sodipodi:nodetypes="ccccc" /> | ||
| 432 | + <path | ||
| 433 | + sodipodi:nodetypes="cccccc" | ||
| 434 | + id="path3619" | ||
| 435 | + style="fill:none;stroke:#000000;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:1, 1;stroke-dashoffset:0" | ||
| 436 | + d="m 15,1012.8622 -9.5,0 m 9.5,-2 -9.5,0 m 9.5,-2 -9.5,0" /> | ||
| 437 | + <path | ||
| 438 | + transform="translate(7.5,1000.8622)" | ||
| 439 | + d="m 8.5,16 c 0,0.828427 -0.6715729,1.5 -1.5,1.5 -0.8284271,0 -1.5,-0.671573 -1.5,-1.5 0,-0.828427 0.6715729,-1.5 1.5,-1.5 0.8284271,0 1.5,0.671573 1.5,1.5 z" | ||
| 440 | + sodipodi:ry="1.5" | ||
| 441 | + sodipodi:rx="1.5" | ||
| 442 | + sodipodi:cy="16" | ||
| 443 | + sodipodi:cx="7" | ||
| 444 | + id="path3647" | ||
| 445 | + style="color:#000000;fill:#000000;stroke:none;stroke-width:1px;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" | ||
| 446 | + sodipodi:type="arc" /> | ||
| 447 | + <path | ||
| 448 | + sodipodi:type="arc" | ||
| 449 | + style="color:#000000;fill:#000000;stroke:none;stroke-width:1px;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" | ||
| 450 | + id="path4776" | ||
| 451 | + sodipodi:cx="7" | ||
| 452 | + sodipodi:cy="16" | ||
| 453 | + sodipodi:rx="1.5" | ||
| 454 | + sodipodi:ry="1.5" | ||
| 455 | + d="m 8.5,16 c 0,0.828427 -0.6715729,1.5 -1.5,1.5 -0.8284271,0 -1.5,-0.671573 -1.5,-1.5 0,-0.828427 0.6715729,-1.5 1.5,-1.5 0.8284271,0 1.5,0.671573 1.5,1.5 z" | ||
| 456 | + transform="translate(-1,1000.8622)" /> | ||
| 457 | + </g> | ||
| 458 | + <g | ||
| 459 | + id="g4778" | ||
| 460 | + transform="translate(6,15)"> | ||
| 461 | + <path | ||
| 462 | + sodipodi:nodetypes="ccccc" | ||
| 463 | + transform="translate(0,1004.3622)" | ||
| 464 | + id="path4780" | ||
| 465 | + d="m 2.5,2.5 2,0 0,8 12,0 0,-6" | ||
| 466 | + style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1" /> | ||
| 467 | + <path | ||
| 468 | + d="m 15,1012.8622 -9.5,0 m 9.5,-2 -9.5,0 m 9.5,-2 -9.5,0" | ||
| 469 | + style="fill:none;stroke:#000000;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:1, 1;stroke-dashoffset:0" | ||
| 470 | + id="path4782" | ||
| 471 | + sodipodi:nodetypes="cccccc" /> | ||
| 472 | + <path | ||
| 473 | + sodipodi:type="arc" | ||
| 474 | + style="color:#000000;fill:#000000;stroke:none;stroke-width:1px;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" | ||
| 475 | + id="path4784" | ||
| 476 | + sodipodi:cx="7" | ||
| 477 | + sodipodi:cy="16" | ||
| 478 | + sodipodi:rx="1.5" | ||
| 479 | + sodipodi:ry="1.5" | ||
| 480 | + d="m 8.5,16 c 0,0.828427 -0.6715729,1.5 -1.5,1.5 -0.8284271,0 -1.5,-0.671573 -1.5,-1.5 0,-0.828427 0.6715729,-1.5 1.5,-1.5 0.8284271,0 1.5,0.671573 1.5,1.5 z" | ||
| 481 | + transform="translate(7.5,1000.8622)" /> | ||
| 482 | + <path | ||
| 483 | + transform="translate(-1,1000.8622)" | ||
| 484 | + d="m 8.5,16 c 0,0.828427 -0.6715729,1.5 -1.5,1.5 -0.8284271,0 -1.5,-0.671573 -1.5,-1.5 0,-0.828427 0.6715729,-1.5 1.5,-1.5 0.8284271,0 1.5,0.671573 1.5,1.5 z" | ||
| 485 | + sodipodi:ry="1.5" | ||
| 486 | + sodipodi:rx="1.5" | ||
| 487 | + sodipodi:cy="16" | ||
| 488 | + sodipodi:cx="7" | ||
| 489 | + id="path4786" | ||
| 490 | + style="color:#000000;fill:#000000;stroke:none;stroke-width:1px;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" | ||
| 491 | + sodipodi:type="arc" /> | ||
| 492 | + </g> | ||
| 493 | + <g | ||
| 494 | + transform="translate(6,29)" | ||
| 495 | + id="g4788"> | ||
| 496 | + <path | ||
| 497 | + style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1" | ||
| 498 | + d="m 2.5,2.5 2,0 0,8 12,0 0,-6" | ||
| 499 | + id="path4790" | ||
| 500 | + transform="translate(0,1004.3622)" | ||
| 501 | + sodipodi:nodetypes="ccccc" /> | ||
| 502 | + <path | ||
| 503 | + sodipodi:nodetypes="cccccc" | ||
| 504 | + id="path4792" | ||
| 505 | + style="fill:none;stroke:#000000;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:1, 1;stroke-dashoffset:0" | ||
| 506 | + d="m 15,1012.8622 -9.5,0 m 9.5,-2 -9.5,0 m 9.5,-2 -9.5,0" /> | ||
| 507 | + <path | ||
| 508 | + transform="translate(7.5,1000.8622)" | ||
| 509 | + d="m 8.5,16 c 0,0.828427 -0.6715729,1.5 -1.5,1.5 -0.8284271,0 -1.5,-0.671573 -1.5,-1.5 0,-0.828427 0.6715729,-1.5 1.5,-1.5 0.8284271,0 1.5,0.671573 1.5,1.5 z" | ||
| 510 | + sodipodi:ry="1.5" | ||
| 511 | + sodipodi:rx="1.5" | ||
| 512 | + sodipodi:cy="16" | ||
| 513 | + sodipodi:cx="7" | ||
| 514 | + id="path4794" | ||
| 515 | + style="color:#000000;fill:#000000;stroke:none;stroke-width:1px;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" | ||
| 516 | + sodipodi:type="arc" /> | ||
| 517 | + <path | ||
| 518 | + sodipodi:type="arc" | ||
| 519 | + style="color:#000000;fill:#000000;stroke:none;stroke-width:1px;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" | ||
| 520 | + id="path4796" | ||
| 521 | + sodipodi:cx="7" | ||
| 522 | + sodipodi:cy="16" | ||
| 523 | + sodipodi:rx="1.5" | ||
| 524 | + sodipodi:ry="1.5" | ||
| 525 | + d="m 8.5,16 c 0,0.828427 -0.6715729,1.5 -1.5,1.5 -0.8284271,0 -1.5,-0.671573 -1.5,-1.5 0,-0.828427 0.6715729,-1.5 1.5,-1.5 0.8284271,0 1.5,0.671573 1.5,1.5 z" | ||
| 526 | + transform="translate(-1,1000.8622)" /> | ||
| 527 | + </g> | ||
| 528 | + <path | ||
| 529 | + sodipodi:nodetypes="cccccc" | ||
| 530 | + d="m 29.5,1015.8622 11,0 m -11,-3 11,0 m -11,-3 11,0" | ||
| 531 | + style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1" | ||
| 532 | + id="path4802" /> | ||
| 533 | + <path | ||
| 534 | + transform="translate(0,1004.3622)" | ||
| 535 | + d="m 27.5,5.5 a 1,1 0 1 1 -2,0 1,1 0 1 1 2,0 z" | ||
| 536 | + sodipodi:ry="1" | ||
| 537 | + sodipodi:rx="1" | ||
| 538 | + sodipodi:cy="5.5" | ||
| 539 | + sodipodi:cx="26.5" | ||
| 540 | + id="path4804" | ||
| 541 | + style="color:#000000;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" | ||
| 542 | + sodipodi:type="arc" /> | ||
| 543 | + <path | ||
| 544 | + sodipodi:type="arc" | ||
| 545 | + style="color:#000000;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" | ||
| 546 | + id="path4806" | ||
| 547 | + sodipodi:cx="26.5" | ||
| 548 | + sodipodi:cy="5.5" | ||
| 549 | + sodipodi:rx="1" | ||
| 550 | + sodipodi:ry="1" | ||
| 551 | + d="m 27.5,5.5 a 1,1 0 1 1 -2,0 1,1 0 1 1 2,0 z" | ||
| 552 | + transform="translate(0,1007.3622)" /> | ||
| 553 | + <path | ||
| 554 | + transform="translate(0,1010.3622)" | ||
| 555 | + d="m 27.5,5.5 a 1,1 0 1 1 -2,0 1,1 0 1 1 2,0 z" | ||
| 556 | + sodipodi:ry="1" | ||
| 557 | + sodipodi:rx="1" | ||
| 558 | + sodipodi:cy="5.5" | ||
| 559 | + sodipodi:cx="26.5" | ||
| 560 | + id="path4808" | ||
| 561 | + style="color:#000000;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" | ||
| 562 | + sodipodi:type="arc" /> | ||
| 563 | + <path | ||
| 564 | + id="path4811" | ||
| 565 | + style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1" | ||
| 566 | + d="m 29.5,1029.8622 11,0 m -11,-3 11,0 m -11,-3 11,0" | ||
| 567 | + sodipodi:nodetypes="cccccc" /> | ||
| 568 | + <path | ||
| 569 | + sodipodi:type="arc" | ||
| 570 | + style="color:#000000;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" | ||
| 571 | + id="path4813" | ||
| 572 | + sodipodi:cx="26.5" | ||
| 573 | + sodipodi:cy="5.5" | ||
| 574 | + sodipodi:rx="1" | ||
| 575 | + sodipodi:ry="1" | ||
| 576 | + d="m 27.5,5.5 a 1,1 0 1 1 -2,0 1,1 0 1 1 2,0 z" | ||
| 577 | + transform="translate(0,1018.3622)" /> | ||
| 578 | + <path | ||
| 579 | + transform="translate(0,1021.3622)" | ||
| 580 | + d="m 27.5,5.5 a 1,1 0 1 1 -2,0 1,1 0 1 1 2,0 z" | ||
| 581 | + sodipodi:ry="1" | ||
| 582 | + sodipodi:rx="1" | ||
| 583 | + sodipodi:cy="5.5" | ||
| 584 | + sodipodi:cx="26.5" | ||
| 585 | + id="path4815" | ||
| 586 | + style="color:#000000;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" | ||
| 587 | + sodipodi:type="arc" /> | ||
| 588 | + <path | ||
| 589 | + sodipodi:type="arc" | ||
| 590 | + style="color:#000000;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" | ||
| 591 | + id="path4817" | ||
| 592 | + sodipodi:cx="26.5" | ||
| 593 | + sodipodi:cy="5.5" | ||
| 594 | + sodipodi:rx="1" | ||
| 595 | + sodipodi:ry="1" | ||
| 596 | + d="m 27.5,5.5 a 1,1 0 1 1 -2,0 1,1 0 1 1 2,0 z" | ||
| 597 | + transform="translate(0,1024.3622)" /> | ||
| 598 | + <path | ||
| 599 | + id="path4827" | ||
| 600 | + style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1" | ||
| 601 | + d="m 29.5,1038.8622 11,0 m -11,3 11,0 m -11,3 9,0" /> | ||
| 602 | + <path | ||
| 603 | + transform="translate(0,1033.3622)" | ||
| 604 | + d="m 27.5,5.5 a 1,1 0 1 1 -2,0 1,1 0 1 1 2,0 z" | ||
| 605 | + sodipodi:ry="1" | ||
| 606 | + sodipodi:rx="1" | ||
| 607 | + sodipodi:cy="5.5" | ||
| 608 | + sodipodi:cx="26.5" | ||
| 609 | + id="path4829" | ||
| 610 | + style="color:#000000;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" | ||
| 611 | + sodipodi:type="arc" /> | ||
| 612 | + <path | ||
| 613 | + sodipodi:type="arc" | ||
| 614 | + style="color:#000000;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" | ||
| 615 | + id="path4831" | ||
| 616 | + sodipodi:cx="26.5" | ||
| 617 | + sodipodi:cy="5.5" | ||
| 618 | + sodipodi:rx="1" | ||
| 619 | + sodipodi:ry="1" | ||
| 620 | + d="m 27.5,5.5 a 1,1 0 1 1 -2,0 1,1 0 1 1 2,0 z" | ||
| 621 | + transform="translate(0,1036.3622)" /> | ||
| 622 | + <path | ||
| 623 | + transform="translate(0,1039.3622)" | ||
| 624 | + d="m 27.5,5.5 a 1,1 0 1 1 -2,0 1,1 0 1 1 2,0 z" | ||
| 625 | + sodipodi:ry="1" | ||
| 626 | + sodipodi:rx="1" | ||
| 627 | + sodipodi:cy="5.5" | ||
| 628 | + sodipodi:cx="26.5" | ||
| 629 | + id="path4833" | ||
| 630 | + style="color:#000000;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" | ||
| 631 | + sodipodi:type="arc" /> | ||
| 632 | + </g> | ||
| 633 | + <g | ||
| 634 | + id="g4835" | ||
| 635 | + style="stroke:url(#linearGradient4958)"> | ||
| 636 | + <path | ||
| 637 | + sodipodi:nodetypes="csccc" | ||
| 638 | + id="path2210" | ||
| 639 | + d="m 30.5,1049.8622 c 3,0 4.031657,-1.3115 7,-4 2.357963,-2.1356 6,-4 6,-8 0,5 -5,4 -10,4 0,4 1,8 -3,8 z" | ||
| 640 | + style="color:#000000;fill:url(#linearGradient4602);fill-opacity:1;fill-rule:evenodd;stroke:url(#linearGradient4960);stroke-width:1.00000024000000010;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible" /> | ||
| 641 | + <path | ||
| 642 | + style="opacity:0.50000000000000000;color:#000000;fill:none;stroke:url(#linearGradient4968);stroke-width:1;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible" | ||
| 643 | + d="m 39.5,1042.8622 -5,0 0,4" | ||
| 644 | + id="path2247" | ||
| 645 | + sodipodi:nodetypes="ccc" /> | ||
| 646 | + </g> | ||
| 647 | + </g> | ||
| 648 | +</svg> |
plugins/shopping_cart/public/style.css
| @@ -168,3 +168,47 @@ label.error { | @@ -168,3 +168,47 @@ label.error { | ||
| 168 | padding-left: .5em; | 168 | padding-left: .5em; |
| 169 | vertical-align: top; | 169 | vertical-align: top; |
| 170 | } | 170 | } |
| 171 | + | ||
| 172 | +.controller-profile_editor a.control-panel-shopping-cart-purchase-report {background-image: url(images/control-panel/purchase-report.png)} | ||
| 173 | +.controller-profile_editor .msie6 a.control-panel-shopping-cart-purchase-report {background-image: url(images/control-panel/purchase-report.gif)} | ||
| 174 | +.controller-profile_editor a.control-panel-shopping-cart {background-image: url(/images/control-panel/shopping-cart.png)} | ||
| 175 | +.controller-profile_editor .msie6 a.control-panel-shopping-cart {background-image: url(/images/control-panel/shopping-cart.gif)} | ||
| 176 | + | ||
| 177 | +.action-shopping_cart_plugin_myprofile-reports td.order-info { | ||
| 178 | + padding: 0px; | ||
| 179 | + height: auto; | ||
| 180 | +} | ||
| 181 | + | ||
| 182 | +.action-shopping_cart_plugin_myprofile-reports .customer-details, | ||
| 183 | +.action-shopping_cart_plugin_myprofile-reports .order-products { | ||
| 184 | + list-style-position: inside; | ||
| 185 | + float: left; | ||
| 186 | + width: 49%; | ||
| 187 | + margin: 0px; | ||
| 188 | + padding: 10px 0px; | ||
| 189 | +} | ||
| 190 | + | ||
| 191 | +.action-shopping_cart_plugin_myprofile-reports .order-products { | ||
| 192 | + float: right; | ||
| 193 | +} | ||
| 194 | + | ||
| 195 | +.action-shopping_cart_plugin_myprofile-reports .customer-details li, | ||
| 196 | +.action-shopping_cart_plugin_myprofile-reports .order-products li { | ||
| 197 | + padding-left: 5px; | ||
| 198 | +} | ||
| 199 | + | ||
| 200 | +#order-filter { | ||
| 201 | + background-color: #ccc; | ||
| 202 | + border: 1px solid #aaa; | ||
| 203 | + border-radius: 5px; | ||
| 204 | + padding: 3px 8px; | ||
| 205 | + margin-bottom: 10px; | ||
| 206 | +} | ||
| 207 | + | ||
| 208 | +th { | ||
| 209 | + text-align: center; | ||
| 210 | +} | ||
| 211 | + | ||
| 212 | +td { | ||
| 213 | + text-align: left; | ||
| 214 | +} |
plugins/shopping_cart/test/functional/shopping_cart_plugin_myprofile_controller_test.rb
| @@ -6,6 +6,8 @@ class ShoppingCartPluginMyprofileController; def rescue_action(e) raise e end; e | @@ -6,6 +6,8 @@ class ShoppingCartPluginMyprofileController; def rescue_action(e) raise e end; e | ||
| 6 | 6 | ||
| 7 | class ShoppingCartPluginMyprofileControllerTest < Test::Unit::TestCase | 7 | class ShoppingCartPluginMyprofileControllerTest < Test::Unit::TestCase |
| 8 | 8 | ||
| 9 | + TIME_FORMAT = '%Y-%m-%d' | ||
| 10 | + | ||
| 9 | def setup | 11 | def setup |
| 10 | @controller = ShoppingCartPluginMyprofileController.new | 12 | @controller = ShoppingCartPluginMyprofileController.new |
| 11 | @request = ActionController::TestRequest.new | 13 | @request = ActionController::TestRequest.new |
| @@ -59,4 +61,56 @@ class ShoppingCartPluginMyprofileControllerTest < Test::Unit::TestCase | @@ -59,4 +61,56 @@ class ShoppingCartPluginMyprofileControllerTest < Test::Unit::TestCase | ||
| 59 | enterprise.reload | 61 | enterprise.reload |
| 60 | assert enterprise.shopping_cart_delivery_price == price | 62 | assert enterprise.shopping_cart_delivery_price == price |
| 61 | end | 63 | end |
| 64 | + | ||
| 65 | + should 'filter the reports correctly' do | ||
| 66 | + another_enterprise = fast_create(Enterprise) | ||
| 67 | + po1 = ShoppingCartPlugin::PurchaseOrder.create!(:seller => enterprise, :status => ShoppingCartPlugin::PurchaseOrder::Status::OPENED) | ||
| 68 | + po2 = ShoppingCartPlugin::PurchaseOrder.create!(:seller => enterprise, :status => ShoppingCartPlugin::PurchaseOrder::Status::SHIPPED) | ||
| 69 | + po3 = ShoppingCartPlugin::PurchaseOrder.create!(:seller => enterprise, :status => ShoppingCartPlugin::PurchaseOrder::Status::OPENED) | ||
| 70 | + po3.created_at = 1.year.ago | ||
| 71 | + po3.save! | ||
| 72 | + po4 = ShoppingCartPlugin::PurchaseOrder.create!(:seller => another_enterprise, :status => ShoppingCartPlugin::PurchaseOrder::Status::OPENED) | ||
| 73 | + | ||
| 74 | + post :reports, | ||
| 75 | + :profile => enterprise.identifier, | ||
| 76 | + :from => (Time.now - 1.day).strftime(TIME_FORMAT), | ||
| 77 | + :to => (Time.now + 1.day).strftime(TIME_FORMAT), | ||
| 78 | + :filter_status => ShoppingCartPlugin::PurchaseOrder::Status::OPENED | ||
| 79 | + | ||
| 80 | + assert_includes assigns(:orders), po1 | ||
| 81 | + assert_not_includes assigns(:orders), po2 | ||
| 82 | + assert_not_includes assigns(:orders), po3 | ||
| 83 | + assert_not_includes assigns(:orders), po4 | ||
| 84 | + end | ||
| 85 | + | ||
| 86 | + should 'group filtered orders products and quantities' do | ||
| 87 | + p1 = fast_create(Product, :enterprise_id => enterprise.id, :price => 1) | ||
| 88 | + p2 = fast_create(Product, :enterprise_id => enterprise.id, :price => 2) | ||
| 89 | + p3 = fast_create(Product, :enterprise_id => enterprise.id, :price => 3) | ||
| 90 | + po1_products = {p1.id => {:quantity => 1, :price => p1.price}, p2.id => {:quantity => 2, :price => p2.price }} | ||
| 91 | + po2_products = {p2.id => {:quantity => 1, :price => p2.price}, p3.id => {:quantity => 2, :price => p3.price }} | ||
| 92 | + po1 = ShoppingCartPlugin::PurchaseOrder.create!(:seller => enterprise, :products_list => po1_products, :status => ShoppingCartPlugin::PurchaseOrder::Status::OPENED) | ||
| 93 | + po2 = ShoppingCartPlugin::PurchaseOrder.create!(:seller => enterprise, :products_list => po2_products, :status => ShoppingCartPlugin::PurchaseOrder::Status::OPENED) | ||
| 94 | + | ||
| 95 | + post :reports, | ||
| 96 | + :profile => enterprise.identifier, | ||
| 97 | + :from => (Time.now - 1.day).strftime(TIME_FORMAT), | ||
| 98 | + :to => (Time.now + 1.day).strftime(TIME_FORMAT), | ||
| 99 | + :filter_status => ShoppingCartPlugin::PurchaseOrder::Status::OPENED | ||
| 100 | + | ||
| 101 | + hash = {p1.id => 1, p2.id => 3, p3.id => 2} | ||
| 102 | + | ||
| 103 | + assert_equal hash, assigns(:products) | ||
| 104 | + end | ||
| 105 | + | ||
| 106 | + should 'be able to update the order status' do | ||
| 107 | + po = ShoppingCartPlugin::PurchaseOrder.create!(:seller => enterprise, :status => ShoppingCartPlugin::PurchaseOrder::Status::OPENED) | ||
| 108 | + | ||
| 109 | + post :update_order_status, | ||
| 110 | + :profile => enterprise.identifier, | ||
| 111 | + :order_id => po.id, | ||
| 112 | + :order_status => ShoppingCartPlugin::PurchaseOrder::Status::CONFIRMED | ||
| 113 | + po.reload | ||
| 114 | + assert_equal ShoppingCartPlugin::PurchaseOrder::Status::CONFIRMED, po.status | ||
| 115 | + end | ||
| 62 | end | 116 | end |
plugins/shopping_cart/test/functional/shopping_cart_plugin_profile_controller_test.rb
| @@ -144,6 +144,25 @@ class ShoppingCartPluginProfileControllerTest < Test::Unit::TestCase | @@ -144,6 +144,25 @@ class ShoppingCartPluginProfileControllerTest < Test::Unit::TestCase | ||
| 144 | assert_nothing_raised { get :clean, :profile => enterprise.identifier } | 144 | assert_nothing_raised { get :clean, :profile => enterprise.identifier } |
| 145 | end | 145 | end |
| 146 | 146 | ||
| 147 | + should 'register order on send request' do | ||
| 148 | + product1 = fast_create(Product, :enterprise_id => enterprise.id, :price => 1.99) | ||
| 149 | + product2 = fast_create(Product, :enterprise_id => enterprise.id, :price => 2.23) | ||
| 150 | + @controller.stubs(:session).returns({:cart => {:items => {product1.id => 1, product2.id => 2}}}) | ||
| 151 | + assert_difference ShoppingCartPlugin::PurchaseOrder, :count, 1 do | ||
| 152 | + post :send_request, | ||
| 153 | + :customer => {:name => "Manuel", :email => "manuel@ceu.com"}, | ||
| 154 | + :profile => enterprise.identifier | ||
| 155 | + end | ||
| 156 | + | ||
| 157 | + order = ShoppingCartPlugin::PurchaseOrder.last | ||
| 158 | + | ||
| 159 | + assert_equal 1.99, order.products_list[product1.id][:price] | ||
| 160 | + assert_equal 1, order.products_list[product1.id][:quantity] | ||
| 161 | + assert_equal 2.23, order.products_list[product2.id][:price] | ||
| 162 | + assert_equal 2, order.products_list[product2.id][:quantity] | ||
| 163 | + assert_equal ShoppingCartPlugin::PurchaseOrder::Status::OPENED, order.status | ||
| 164 | + end | ||
| 165 | + | ||
| 147 | private | 166 | private |
| 148 | 167 | ||
| 149 | def json_response | 168 | def json_response |
plugins/shopping_cart/views/shopping_cart_plugin_myprofile/_orders_list.html.erb
0 → 100644
| @@ -0,0 +1,59 @@ | @@ -0,0 +1,59 @@ | ||
| 1 | +<% if @orders.empty? %> | ||
| 2 | + <p><i><%= _("No results.") %></i></p> | ||
| 3 | +<% else %> | ||
| 4 | + <table> | ||
| 5 | + <tr> | ||
| 6 | + <th><%= _('Date') %></th> | ||
| 7 | + <th><%= _('Customer') %></th> | ||
| 8 | + <th><%= _('Purchase value') %></th> | ||
| 9 | + <th><%= _('Status')%></th> | ||
| 10 | + <th> </th> | ||
| 11 | + </tr> | ||
| 12 | + <% status_collection.delete_at(0) %> | ||
| 13 | + <% @orders.each do |order|%> | ||
| 14 | + <tr> | ||
| 15 | + <td><%= order.created_at.strftime("%Y-%m-%d")%></td> | ||
| 16 | + <td><%= order.customer_name %></td> | ||
| 17 | + <td style="text-align: right"><%= float_to_currency_cart(order.products_list.sum {|id, qp| qp[:price]*qp[:quantity]}, environment) %></td> | ||
| 18 | + <td> | ||
| 19 | + <% form_tag :action => 'update_order_status' do %> | ||
| 20 | + <%= hidden_field_tag(:order_id, order.id) + | ||
| 21 | + hidden_field_tag(:context_from, @from) + | ||
| 22 | + hidden_field_tag(:context_to, @to) + | ||
| 23 | + hidden_field_tag(:context_status, @status) + | ||
| 24 | + select_tag( :order_status, options_from_collection_for_select(status_collection, :first, :last, order.status), | ||
| 25 | + :onchange => "this.form.submit()" ) | ||
| 26 | + %> | ||
| 27 | + <% end %> | ||
| 28 | + </td> | ||
| 29 | + <td><button class="view-order-details" data-order="<%=order.id%>"><%=_('View details')%></button></td> | ||
| 30 | + </tr> | ||
| 31 | + <tr id="order-details-<%=order.id%>" style="display:none"> | ||
| 32 | + <td class="order-info" colspan="5"> | ||
| 33 | + <div style="display:none"> | ||
| 34 | + <ul class="customer-details"> | ||
| 35 | + <% { 'name' =>_('Name'), 'email' => _('E-mail'), 'contact_phone' => _('Contact phone'), 'address' => _('Address'), 'city' => _('City'), 'zip_code' => _('Zip code')}.each do |attribute, name| %> | ||
| 36 | + <%= content_tag('li', content_tag('strong', name+': ') + order.send('customer_'+attribute)) if !order.send('customer_'+attribute).blank? %> | ||
| 37 | + <% end %> | ||
| 38 | + </ul> | ||
| 39 | + <ul class="order-products"> | ||
| 40 | + <% order.products_list.each do |id, qp| %> | ||
| 41 | + <% | ||
| 42 | + begin | ||
| 43 | + product = Product.find(id) | ||
| 44 | + rescue | ||
| 45 | + product = nil | ||
| 46 | + end | ||
| 47 | + %> | ||
| 48 | + <li><%= product ? link_to(product.name, product.url) : _("Pruduct unavailable")%> | ||
| 49 | + × <%= qp[:quantity] %> = <%= float_to_currency_cart( qp[:quantity] * qp[:price], environment ) %></li> | ||
| 50 | + <% end %> | ||
| 51 | + </ul> | ||
| 52 | + <br style="clear:both"/> | ||
| 53 | + </div> | ||
| 54 | + </td> | ||
| 55 | + </tr> | ||
| 56 | + <% end %> | ||
| 57 | + </table> | ||
| 58 | +<% end %> | ||
| 59 | + |
plugins/shopping_cart/views/shopping_cart_plugin_myprofile/_products_list.html.erb
0 → 100644
| @@ -0,0 +1,17 @@ | @@ -0,0 +1,17 @@ | ||
| 1 | +<% if @products.empty? %> | ||
| 2 | + <p><i><%= _("No results.") %></i></p> | ||
| 3 | +<% else %> | ||
| 4 | + <table> | ||
| 5 | + <tr> | ||
| 6 | + <th><%= _('Product') %></th> | ||
| 7 | + <th><%= _('Quantity') %></th> | ||
| 8 | + </tr> | ||
| 9 | + <% @products.each do |id, quantity|%> | ||
| 10 | + <tr> | ||
| 11 | + <td><%= link_to(Product.find(id).name, Product.find(id).url) %></td> | ||
| 12 | + <td style="text-align: center"><%= quantity %></td> | ||
| 13 | + </tr> | ||
| 14 | + <% end %> | ||
| 15 | + </table> | ||
| 16 | +<% end %> | ||
| 17 | + |
plugins/shopping_cart/views/shopping_cart_plugin_myprofile/reports.html.erb
0 → 100644
| @@ -0,0 +1,56 @@ | @@ -0,0 +1,56 @@ | ||
| 1 | +<h1> <%= _('Purchase Reports') %> </h1> | ||
| 2 | + | ||
| 3 | +<% extend ProfileHelper %> | ||
| 4 | + | ||
| 5 | +<% status = ShoppingCartPlugin::PurchaseOrder::Status.name; pos=-1 %> | ||
| 6 | +<% status_collection = [[nil, _('All')]] %> | ||
| 7 | +<% status_collection += status.map{|s| [pos+=1, s] } %> | ||
| 8 | + | ||
| 9 | +<% form_tag({}, {:id => 'order-filter'}) do %> | ||
| 10 | + <%= labelled_text_field(_('From')+' ', :from, @from.strftime("%Y-%m-%d"), :id => 'from', :size => 9) %> | ||
| 11 | + <%= labelled_text_field(_('to')+' ', :to, @to.strftime("%Y-%m-%d"), :id => 'to', :size => 9) %> | ||
| 12 | + <span style="white-space:nowrap"><%= labelled_select(_('Status')+' ', :filter_status, :first, :last, @status, status_collection)%></span> | ||
| 13 | + | ||
| 14 | + <%= submit_button('save', _('Filter')) %> | ||
| 15 | +<% end %> | ||
| 16 | + | ||
| 17 | +<% tabs = [] %> | ||
| 18 | +<% tabs << {:title => _('Products list'), :id => 'products_list', :content => (render :partial => 'products_list')} %> | ||
| 19 | +<% tabs << {:title => _('Orders list'), :id => 'orders_list', :content => (render :partial => 'orders_list', :locals => {:status_collection => status_collection})} %> | ||
| 20 | +<%= render_tabs(tabs) %> | ||
| 21 | + | ||
| 22 | +<script> | ||
| 23 | + var dates = jQuery( "#from, #to" ).datepicker({ | ||
| 24 | + defaultDate: "+1w", | ||
| 25 | + changeMonth: true, | ||
| 26 | + dateFormat: 'yy-mm-dd', | ||
| 27 | + onSelect: function( selectedDate ) { | ||
| 28 | + var option = this.id == "from" ? "minDate" : "maxDate", | ||
| 29 | + instance = jQuery( this ).data( "datepicker" ), | ||
| 30 | + date = jQuery.datepicker.parseDate( | ||
| 31 | + instance.settings.dateFormat || | ||
| 32 | + jQuery.datepicker._defaults.dateFormat, | ||
| 33 | + selectedDate, instance.settings ); | ||
| 34 | + dates.not( this ).datepicker( "option", option, date ); | ||
| 35 | + } | ||
| 36 | + }); | ||
| 37 | + jQuery(".view-order-details").each(function(index, bt){ | ||
| 38 | + jQuery(bt).button({ | ||
| 39 | + icons: { | ||
| 40 | + primary: "ui-icon-info" | ||
| 41 | + }, | ||
| 42 | + text: false | ||
| 43 | + }); | ||
| 44 | + bt.onclick = function(){ | ||
| 45 | + var orderId = this.getAttribute("data-order"); | ||
| 46 | + var tr = jQuery("#order-details-"+orderId); | ||
| 47 | + var div = jQuery("#order-details-"+orderId+" div"); | ||
| 48 | + if ( tr[0].style.display == "none" ) { | ||
| 49 | + tr.show(); | ||
| 50 | + div.slideDown('fast'); | ||
| 51 | + } else { | ||
| 52 | + div.slideUp("fast", function(){tr.hide()}); | ||
| 53 | + } | ||
| 54 | + } | ||
| 55 | + }); | ||
| 56 | +</script> |