vyapari 0.1.4 → 0.1.5dev

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (164) hide show
  1. checksums.yaml +4 -4
  2. data/app/assets/images/vyapari/sample_stock_bundle.csv +1 -0
  3. data/app/controllers/vyapari/admin/base_controller.rb +10 -0
  4. data/app/controllers/vyapari/admin/brands_controller.rb +99 -0
  5. data/app/controllers/vyapari/admin/categories_controller.rb +115 -0
  6. data/app/controllers/vyapari/admin/countries_controller.rb +2 -2
  7. data/app/controllers/vyapari/admin/dashboard_controller.rb +3 -1
  8. data/app/controllers/vyapari/admin/exchange_rates_controller.rb +2 -2
  9. data/app/controllers/vyapari/admin/products_controller.rb +79 -0
  10. data/app/controllers/vyapari/admin/regions_controller.rb +1 -1
  11. data/app/controllers/vyapari/admin/resource_controller.rb +1 -0
  12. data/app/controllers/vyapari/admin/stores_controller.rb +67 -0
  13. data/app/controllers/vyapari/admin/suppliers_controller.rb +67 -0
  14. data/app/controllers/vyapari/admin/terminals_controller.rb +150 -0
  15. data/app/controllers/vyapari/application_controller.rb +12 -0
  16. data/app/controllers/vyapari/store_manager/base_controller.rb +28 -0
  17. data/app/controllers/vyapari/store_manager/dashboard_controller.rb +30 -0
  18. data/app/controllers/vyapari/store_manager/resource_controller.rb +17 -0
  19. data/app/controllers/vyapari/store_manager/stock_bundles_controller.rb +206 -0
  20. data/app/controllers/vyapari/store_manager/stock_entries_controller.rb +161 -0
  21. data/app/controllers/vyapari/terminal_staff/base_controller.rb +29 -0
  22. data/app/controllers/vyapari/terminal_staff/dashboard_controller.rb +29 -0
  23. data/app/controllers/vyapari/terminal_staff/invoices_controller.rb +138 -0
  24. data/app/controllers/vyapari/terminal_staff/line_items_controller.rb +123 -0
  25. data/app/controllers/vyapari/terminal_staff/resource_controller.rb +17 -0
  26. data/app/controllers/vyapari/user_dashboard_controller.rb +31 -0
  27. data/app/models/brand.rb +63 -10
  28. data/app/models/category.rb +60 -16
  29. data/app/models/country.rb +27 -5
  30. data/app/models/exchange_rate.rb +31 -6
  31. data/app/models/image/brand_image.rb +3 -0
  32. data/app/models/image/category_image.rb +3 -0
  33. data/app/models/image/product_image.rb +3 -0
  34. data/app/models/invoice.rb +223 -0
  35. data/app/models/line_item.rb +206 -0
  36. data/app/models/product.rb +67 -13
  37. data/app/models/region.rb +26 -3
  38. data/app/models/stock_bundle.rb +249 -0
  39. data/app/models/stock_entry.rb +271 -0
  40. data/app/models/store.rb +216 -0
  41. data/app/models/supplier.rb +85 -0
  42. data/app/models/terminal.rb +158 -0
  43. data/app/models/vyapari/application_record.rb +4 -0
  44. data/app/uploaders/brand_image_uploader.rb +14 -0
  45. data/app/uploaders/category_image_uploader.rb +14 -0
  46. data/app/uploaders/product_image_uploader.rb +14 -0
  47. data/app/uploaders/stock_bundle_uploader.rb +10 -0
  48. data/app/views/layouts/kuppayam/_footer.html.erb +1 -1
  49. data/app/views/layouts/kuppayam/_sidebar.html.erb +45 -44
  50. data/app/views/layouts/vyapari/_store_manager_menu.html.erb +107 -0
  51. data/app/views/layouts/vyapari/_terminal_staff_menu.html.erb +103 -0
  52. data/app/views/layouts/vyapari/store_manager.html.erb +112 -0
  53. data/app/views/layouts/vyapari/terminal_staff.html.erb +116 -0
  54. data/app/views/vyapari/admin/brands/_form.html.erb +23 -0
  55. data/app/views/vyapari/admin/brands/_index.html.erb +89 -0
  56. data/app/views/vyapari/admin/brands/_row.html.erb +63 -0
  57. data/app/views/vyapari/admin/brands/_show.html.erb +104 -0
  58. data/app/views/vyapari/admin/brands/index.html.erb +48 -0
  59. data/app/views/vyapari/admin/categories/_form.html.erb +28 -0
  60. data/app/views/vyapari/admin/categories/_index.html.erb +101 -0
  61. data/app/views/vyapari/admin/categories/_row.html.erb +69 -0
  62. data/app/views/vyapari/admin/categories/_show.html.erb +115 -0
  63. data/app/views/vyapari/admin/{users → categories}/index.html.erb +8 -24
  64. data/app/views/vyapari/admin/countries/_index.html.erb +1 -1
  65. data/app/views/vyapari/admin/countries/index.html.erb +19 -3
  66. data/app/views/vyapari/admin/exchange_rates/_form.html.erb +3 -4
  67. data/app/views/vyapari/admin/exchange_rates/_index.html.erb +7 -7
  68. data/app/views/vyapari/admin/exchange_rates/_row.html.erb +3 -3
  69. data/app/views/vyapari/admin/exchange_rates/_show.html.erb +1 -0
  70. data/app/views/vyapari/admin/exchange_rates/index.html.erb +19 -3
  71. data/app/views/vyapari/admin/products/_form.html.erb +32 -0
  72. data/app/views/vyapari/admin/products/_index.html.erb +58 -0
  73. data/app/views/vyapari/admin/products/_row.html.erb +30 -0
  74. data/app/views/vyapari/admin/products/_show.html.erb +81 -0
  75. data/app/views/vyapari/admin/products/index.html.erb +48 -0
  76. data/app/views/vyapari/admin/regions/_index.html.erb +1 -1
  77. data/app/views/vyapari/admin/regions/index.html.erb +19 -3
  78. data/app/views/vyapari/admin/stores/_form.html.erb +37 -0
  79. data/app/views/vyapari/admin/stores/_index.html.erb +84 -0
  80. data/app/views/vyapari/admin/stores/_row.html.erb +55 -0
  81. data/app/views/vyapari/admin/stores/_show.html.erb +110 -0
  82. data/app/views/vyapari/admin/stores/index.html.erb +48 -0
  83. data/app/views/vyapari/admin/suppliers/_form.html.erb +32 -0
  84. data/app/views/vyapari/admin/suppliers/_index.html.erb +58 -0
  85. data/app/views/vyapari/admin/suppliers/_row.html.erb +30 -0
  86. data/app/views/vyapari/admin/suppliers/_show.html.erb +81 -0
  87. data/app/views/vyapari/admin/suppliers/index.html.erb +48 -0
  88. data/app/views/vyapari/admin/terminals/_form.html.erb +24 -0
  89. data/app/views/vyapari/admin/terminals/_index.html.erb +75 -0
  90. data/app/views/vyapari/admin/terminals/_row.html.erb +49 -0
  91. data/app/views/vyapari/admin/terminals/_show.html.erb +74 -0
  92. data/app/views/vyapari/store_manager/dashboard/index.html.erb +93 -0
  93. data/app/views/vyapari/store_manager/stock_bundles/_form.html.erb +99 -0
  94. data/app/views/vyapari/store_manager/stock_bundles/_index.html.erb +74 -0
  95. data/app/views/vyapari/store_manager/stock_bundles/_row.html.erb +44 -0
  96. data/app/views/vyapari/store_manager/stock_bundles/_show.html.erb +110 -0
  97. data/app/views/vyapari/store_manager/stock_bundles/create.html.erb +57 -0
  98. data/app/views/vyapari/store_manager/stock_bundles/index.html.erb +36 -0
  99. data/app/views/vyapari/store_manager/stock_bundles/update.html.erb +57 -0
  100. data/app/views/vyapari/store_manager/stock_entries/_form.html.erb +50 -0
  101. data/app/views/vyapari/store_manager/stock_entries/_index.html.erb +80 -0
  102. data/app/views/vyapari/store_manager/stock_entries/_row.html.erb +33 -0
  103. data/app/views/vyapari/store_manager/stock_entries/_show.html.erb +110 -0
  104. data/app/views/vyapari/store_manager/stock_entries/_stock_bundle.html.erb +61 -0
  105. data/app/views/vyapari/store_manager/stock_entries/index.html.erb +45 -0
  106. data/app/views/vyapari/terminal_staff/dashboard/_counts.html.erb +88 -0
  107. data/app/views/vyapari/terminal_staff/dashboard/_invoices.html.erb +37 -0
  108. data/app/views/vyapari/terminal_staff/dashboard/index.html.erb +36 -0
  109. data/app/views/vyapari/terminal_staff/invoices/_draft.html.erb +62 -0
  110. data/app/views/vyapari/terminal_staff/invoices/_form.html.erb +120 -0
  111. data/app/views/vyapari/terminal_staff/invoices/_index.html.erb +64 -0
  112. data/app/views/vyapari/terminal_staff/invoices/_row.html.erb +33 -0
  113. data/app/views/vyapari/terminal_staff/invoices/_show.html.erb +171 -0
  114. data/app/views/vyapari/terminal_staff/invoices/index.html.erb +37 -0
  115. data/app/views/vyapari/terminal_staff/invoices/new.js.erb +13 -0
  116. data/app/views/vyapari/terminal_staff/invoices/show.html.erb +1 -0
  117. data/app/views/vyapari/terminal_staff/line_items/_form.html.erb +40 -0
  118. data/app/views/vyapari/terminal_staff/line_items/_index.html.erb +94 -0
  119. data/app/views/vyapari/terminal_staff/line_items/create.js.erb +34 -0
  120. data/app/views/vyapari/terminal_staff/line_items/destroy.js.erb +25 -0
  121. data/app/views/vyapari/terminal_staff/stores/index.html.erb +24 -0
  122. data/app/views/vyapari/user_dashboard/index.html.erb +51 -0
  123. data/config/routes.rb +62 -5
  124. data/db/import_data/brands.csv +7 -0
  125. data/db/import_data/categories.csv +12 -0
  126. data/db/import_data/countries.csv +1 -0
  127. data/db/import_data/dummy/brands.csv +7 -0
  128. data/db/import_data/dummy/categories.csv +12 -0
  129. data/db/import_data/dummy/countries.csv +1 -0
  130. data/db/import_data/dummy/exchange_rates.csv +5 -0
  131. data/db/import_data/dummy/products-copy.csv +1 -0
  132. data/db/import_data/dummy/products.csv +1 -0
  133. data/db/import_data/dummy/products.xlsx +0 -0
  134. data/db/import_data/dummy/regions.csv +13 -0
  135. data/db/import_data/dummy/stores.csv +10 -0
  136. data/db/import_data/dummy/suppliers.csv +14 -0
  137. data/db/import_data/dummy/terminals.csv +11 -0
  138. data/db/import_data/exchange_rates.csv +5 -0
  139. data/db/import_data/regions.csv +13 -0
  140. data/db/import_data/stores.csv +3 -0
  141. data/db/import_data/suppliers.csv +14 -0
  142. data/db/import_data/terminals.csv +3 -0
  143. data/db/migrate/20170000000200_create_exchange_rates.rb +3 -2
  144. data/db/migrate/20170000000203_create_contacts.rb +22 -0
  145. data/db/migrate/20170000000204_create_bank_accounts.rb +21 -0
  146. data/db/migrate/20170000000205_create_suppliers.rb +18 -0
  147. data/db/migrate/20170000000206_create_stores.rb +21 -0
  148. data/db/migrate/20170000000207_create_terminals.rb +18 -0
  149. data/db/migrate/20170000000210_create_brands.rb +14 -0
  150. data/db/migrate/20170000000211_create_categories.rb +22 -0
  151. data/db/migrate/20170000000212_create_products.rb +29 -0
  152. data/db/migrate/20170000000213_create_invoices.rb +58 -0
  153. data/db/migrate/20170000000215_create_stock_bundles.rb +17 -0
  154. data/db/migrate/20170000000216_create_stock_entries.rb +20 -0
  155. data/db/sample_reports/products.xlsx +0 -0
  156. data/lib/tasks/vyapari/all.rake +73 -0
  157. data/lib/vyapari/version.rb +1 -1
  158. metadata +150 -15
  159. data/app/controllers/vyapari/admin/users_controller.rb +0 -130
  160. data/app/views/vyapari/admin/users/_form.html.erb +0 -39
  161. data/app/views/vyapari/admin/users/_index.html.erb +0 -101
  162. data/app/views/vyapari/admin/users/_row.html.erb +0 -72
  163. data/app/views/vyapari/admin/users/_show.html.erb +0 -199
  164. data/lib/tasks/vyapari_tasks.rake +0 -4
@@ -0,0 +1,123 @@
1
+ module Vyapari
2
+ module TerminalStaff
3
+ class LineItemsController < Vyapari::TerminalStaff::ResourceController
4
+
5
+ before_action :get_invoice
6
+
7
+ def create
8
+
9
+ ean_sku = permitted_params[:product_id]
10
+ product = Product.where("ean_sku = ?", permitted_params[:product_id]).first
11
+
12
+ product_in_stock = false
13
+
14
+ # Initialize the line item with quantity 0.0
15
+ @r_object = @line_item = @invoice.line_items.build(quantity: 0.0)
16
+
17
+ # Check if there exists a line item with the invoice.
18
+ @line_item = @invoice.line_items.where("product_id = ?", product.id).first if product
19
+
20
+ # Initialize the line item again if @line_item is nil
21
+ @line_item = @invoice.line_items.build(product: product, quantity: 0.0) unless @line_item
22
+
23
+ # Update the line item quantity and rate
24
+ @line_item.quantity = @line_item.quantity + permitted_params[:quantity].to_f if permitted_params[:quantity]
25
+ @line_item.rate = product.retail_price if product
26
+
27
+ # Check if line item is valid
28
+ @line_item.valid?
29
+
30
+ # check if product exists in store if product is there
31
+ # add error if out of stock
32
+ # Do this after .valid? method as .valid will clear errors
33
+ product_in_stock = @store.in_stock?(product) if product
34
+ @line_item.errors.add(:product_id, "This Product is Out of Stock") unless product_in_stock
35
+
36
+ if @line_item.errors.blank?
37
+ @line_item.save
38
+ # recalculate the total amount
39
+ @invoice.save
40
+ set_notification(true, @line_item.product.ean_sku, "Line Item '#{@line_item.product.name}' ADDED")
41
+ else
42
+ if product
43
+ if product_in_stock
44
+ error_message = @line_item.try(:product).try(:ean_sku) || I18n.t('status.error')
45
+ set_notification(false, error_message, @line_item.errors.full_messages.join(", "))
46
+ else
47
+ error_message = @line_item.try(:product).try(:ean_sku) || I18n.t('status.error')
48
+ set_notification(false, error_message, @line_item.errors[:product_id].first)
49
+ end
50
+ else
51
+ error_message = @line_item.try(:product).try(:ean_sku) || I18n.t('status.error')
52
+ set_notification(false, error_message, "Product doesn't exist")
53
+ end
54
+ end
55
+
56
+ end
57
+
58
+ def destroy
59
+ @line_item = @r_object = @resource_options[:class].find_by_id(params[:id])
60
+ if @r_object
61
+ if @r_object.can_be_deleted?
62
+ @r_object.destroy
63
+ get_collections
64
+ set_flash_message(I18n.t('success.deleted'), :success)
65
+ set_notification(false, I18n.t('status.success'), I18n.t('success.deleted', item: default_item_name.titleize))
66
+ @destroyed = true
67
+ else
68
+ message = I18n.t('errors.failed_to_delete', item: default_item_name.titleize)
69
+ set_flash_message(message, :failure)
70
+ set_notification(false, I18n.t('status.error'), message)
71
+ @destroyed = false
72
+ end
73
+ else
74
+ set_notification(false, I18n.t('status.error'), I18n.t('status.not_found', item: default_item_name.titleize))
75
+ end
76
+
77
+ # respond_to do |format|
78
+ # format.html {}
79
+ # format.js {
80
+ # js_view_path = @resource_options && @resource_options[:js_view_path] ? "#{@resource_options[:js_view_path]}/destroy" : :destroy
81
+ # render js_view_path
82
+ # }
83
+ # end
84
+
85
+ end
86
+
87
+ private
88
+
89
+ def get_invoice
90
+ @invoice = Invoice.find_by_id(params[:invoice_id])
91
+ end
92
+
93
+ def permitted_params
94
+ params.require(:line_item).permit(:product_id, :quantity)
95
+ end
96
+
97
+ def resource_controller_configuration
98
+ {
99
+ collection_name: :line_items,
100
+ item_name: :line_item,
101
+ class: LineItem,
102
+ page_title: "Line Item",
103
+ js_view_path: "/kuppayam/workflows/peacock",
104
+ view_path: "/vyapari/terminal_staff/line_items"
105
+ }
106
+ end
107
+
108
+ def breadcrumbs_configuration
109
+ {
110
+ heading: "LineItems",
111
+ description: "Listing the Line Items",
112
+ links: []
113
+ }
114
+ end
115
+
116
+ def set_navs
117
+ set_nav("terminal_staff/line_items")
118
+ end
119
+
120
+ end
121
+ end
122
+ end
123
+
@@ -0,0 +1,17 @@
1
+ module Vyapari
2
+ module TerminalStaff
3
+ class ResourceController < Vyapari::TerminalStaff::BaseController
4
+
5
+ include ResourceHelper
6
+
7
+ before_action :configure_resource_controller
8
+
9
+ private
10
+
11
+ def resource_url(obj)
12
+ url_for([:terminal, obj.stock, obj])
13
+ end
14
+
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,31 @@
1
+ module Vyapari
2
+ class UserDashboardController < Vyapari::ApplicationController
3
+
4
+ layout 'kuppayam/blank'
5
+
6
+ before_action :require_user
7
+
8
+ def index
9
+ end
10
+
11
+ private
12
+
13
+ def set_default_title
14
+ set_title("Dashboard")
15
+ end
16
+
17
+ def breadcrumbs_configuration
18
+ {
19
+ heading: current_user.display_name,
20
+ description: current_user.designation,
21
+ links: [{name: "Home", link: user_dashboard_path, icon: 'fa-dashboard'}]
22
+ }
23
+ end
24
+
25
+ def set_navs
26
+ set_nav("user/dashboard")
27
+ end
28
+
29
+ end
30
+ end
31
+
data/app/models/brand.rb CHANGED
@@ -12,11 +12,12 @@ class Brand < Vyapari::ApplicationRecord
12
12
  FEATURED_HASH_REVERSE = {true => "Featured", false => "Non Featured"}
13
13
 
14
14
  # Validations
15
- validates :name, :presence=> true
15
+ validates :name, :presence=> true, uniqueness: true
16
16
  validates :status, :presence=> true, :inclusion => {:in => STATUS_HASH_REVERSE.keys, :presence_of => :status, :message => "%{value} is not a valid status" }
17
17
 
18
18
  # Associations
19
19
  has_one :brand_image, :as => :imageable, :dependent => :destroy, :class_name => "Image::BrandImage"
20
+ has_many :products
20
21
 
21
22
  # ------------------
22
23
  # Class Methods
@@ -41,6 +42,48 @@ class Brand < Vyapari::ApplicationRecord
41
42
 
42
43
  scope :this_month, lambda { where("created_at >= ? AND created_at <= ?", Time.zone.now.beginning_of_month, Time.zone.now.end_of_month) }
43
44
 
45
+ def self.save_row_data(row)
46
+
47
+ row.headers.each{ |cell| row[cell] = row[cell].to_s.strip }
48
+
49
+ return if row[:name].blank?
50
+
51
+ brand = Brand.find_by_name(row[:name]) || Brand.new
52
+
53
+ brand.name = row[:name]
54
+ brand.featured = row[:featured]
55
+ brand.status = row[:status]
56
+ brand.priority = row[:priority]
57
+
58
+ # Initializing error hash for displaying all errors altogether
59
+ error_object = Kuppayam::Importer::ErrorHash.new
60
+
61
+ if brand.valid?
62
+ brand.save!
63
+ else
64
+ summary = "Error while saving brand: #{brand.name}"
65
+ details = "Error! #{brand.errors.full_messages.to_sentence}"
66
+ error_object.errors << { summary: summary, details: details }
67
+ end
68
+ return error_object
69
+ end
70
+
71
+ # ------------------
72
+ # Instance Methods
73
+ # ------------------
74
+
75
+ def display_name
76
+ self.name
77
+ end
78
+
79
+ def slug
80
+ self.name.parameterize
81
+ end
82
+
83
+ def to_param
84
+ "#{id}-#{slug}"
85
+ end
86
+
44
87
  # * Return true if the brand is published, else false.
45
88
  # == Examples
46
89
  # >>> brand.published?
@@ -92,23 +135,33 @@ class Brand < Vyapari::ApplicationRecord
92
135
  self.update_attributes(status: REMOVED, featured: false)
93
136
  end
94
137
 
138
+ def can_be_published?
139
+ unpublished? or removed?
140
+ end
141
+
142
+ def can_be_unpublished?
143
+ published? or removed?
144
+ end
145
+
146
+ def can_be_removed?
147
+ published? or unpublished?
148
+ end
149
+
95
150
  # TODO
151
+
152
+ def can_be_edited?
153
+ true
154
+ end
155
+
96
156
  def can_be_deleted?
157
+ removed? && self.products.blank?
97
158
  #if self.jobs.any?
98
159
  # self.errors.add(:base, DELETE_MESSAGE)
99
160
  # return false
100
161
  #else
101
162
  # return true
102
163
  #end
103
- return true
104
- end
105
-
106
- def display_name
107
- self.name
108
- end
109
-
110
- def default_image_url(size="medium")
111
- "/assets/defaults/brand-#{size}.png"
164
+ #return true
112
165
  end
113
166
 
114
167
  end
@@ -11,17 +11,15 @@ class Category < Vyapari::ApplicationRecord
11
11
  FEATURED_HASH = {"Featured" => true, "Non Featured" => false}
12
12
  FEATURED_HASH_REVERSE = {true => "Featured", false => "Non Featured"}
13
13
 
14
- # Callbacks
15
- before_validation :update_permalink
16
-
17
- # Validations
18
- validates :name, presence: true
14
+ # Validations
15
+ validates :name, presence: true, uniqueness: true
19
16
  validates :one_liner, presence: false
20
17
  validates :status, :presence=> true, :inclusion => {:in => STATUS_HASH_REVERSE.keys, :presence_of => :status, :message => "%{value} is not a valid status" }
21
18
 
22
19
  # Associations
23
20
  has_many :products
24
21
  belongs_to :parent, :class_name => 'Category', optional: true
22
+ belongs_to :top_parent, :class_name => 'Category', optional: true
25
23
  has_many :sub_categories, :foreign_key => "parent_id", :class_name => "Category"
26
24
  has_one :category_image, :as => :imageable, :dependent => :destroy, :class_name => "Image::CategoryImage"
27
25
 
@@ -31,9 +29,7 @@ class Category < Vyapari::ApplicationRecord
31
29
  # >>> object.search(query)
32
30
  # => ActiveRecord::Relation object
33
31
  scope :search, lambda {|query| where("LOWER(name) LIKE LOWER('%#{query}%') OR\
34
- LOWER(permalink) LIKE LOWER('%#{query}%') OR\
35
- LOWER(one_liner) LIKE LOWER('%#{query}%') OR\
36
- LOWER(description) LIKE LOWER('%#{query}%')")
32
+ LOWER(one_liner) LIKE LOWER('%#{query}%')")
37
33
  }
38
34
 
39
35
  scope :status, lambda { |status| where("LOWER(status)='#{status}'") }
@@ -43,10 +39,52 @@ class Category < Vyapari::ApplicationRecord
43
39
  scope :unpublished, -> { where(status: UNPUBLISHED) }
44
40
  scope :removed, -> { where(status: REMOVED) }
45
41
 
42
+ def self.save_row_data(row)
43
+
44
+ row.headers.each{ |cell| row[cell] = row[cell].to_s.strip }
45
+
46
+ return if row[:name].blank?
47
+
48
+ category = Category.find_by_name(row[:name]) || Category.new
49
+
50
+ category.name = row[:name]
51
+ category.one_liner = row[:one_liner]
52
+ category.parent = Category.find_by_name(row[:parent])
53
+ category.top_parent = category.parent.top_parent if category.parent
54
+
55
+ category.featured = row[:featured]
56
+ category.status = row[:status]
57
+ category.priority = row[:priority]
58
+
59
+ # Initializing error hash for displaying all errors altogether
60
+ error_object = Kuppayam::Importer::ErrorHash.new
61
+
62
+ if category.valid?
63
+ category.save!
64
+ else
65
+ summary = "Error while saving category: #{category.name}"
66
+ details = "Error! #{category.errors.full_messages.to_sentence}"
67
+ error_object.errors << { summary: summary, details: details }
68
+ end
69
+ return error_object
70
+ end
71
+
46
72
  # ------------------
47
73
  # Instance variables
48
74
  # ------------------
49
75
 
76
+ def display_name
77
+ self.name
78
+ end
79
+
80
+ def slug
81
+ self.name.parameterize
82
+ end
83
+
84
+ def to_param
85
+ "#{id}-#{slug}"
86
+ end
87
+
50
88
  # * Return true if the category is published, else false.
51
89
  # == Examples
52
90
  # >>> category.published?
@@ -98,18 +136,24 @@ class Category < Vyapari::ApplicationRecord
98
136
  self.update_attribute(:status, REMOVED)
99
137
  end
100
138
 
101
- def default_image_url(size="medium")
102
- "/assets/defaults/category-#{size}.png"
139
+ def can_be_published?
140
+ unpublished? or removed?
103
141
  end
104
142
 
105
- def display_name
106
- self.name
143
+ def can_be_unpublished?
144
+ published? or removed?
107
145
  end
108
146
 
109
- protected
110
-
111
- def update_permalink
112
- self.permalink = "#{self.id}-#{name.parameterize}"
147
+ def can_be_removed?
148
+ published? or unpublished?
149
+ end
150
+
151
+ def can_be_edited?
152
+ true
153
+ end
154
+
155
+ def can_be_deleted?
156
+ true
113
157
  end
114
158
 
115
159
  end
@@ -1,14 +1,12 @@
1
1
  class Country < Vyapari::ApplicationRecord
2
2
 
3
- DELETE_MESSAGE = "Cannot delete the country. You should first remove all the cities and exchange rates associated with this country."
4
-
5
3
  # Validations
6
4
  validates :name, presence: true, length: {minimum: 2, maximum: 250}, allow_blank: false
7
5
  validates :code, presence: true, uniqueness: true, length: {minimum: 2, maximum: 32}, allow_blank: false
8
6
 
9
7
  # Associations
10
8
  has_many :regions
11
- has_many :exchange_rates
9
+ has_many :stores
12
10
 
13
11
  # ------------------
14
12
  # Class Methods
@@ -21,6 +19,30 @@ class Country < Vyapari::ApplicationRecord
21
19
  # => ActiveRecord::Relation object
22
20
  scope :search, lambda {|query| where("LOWER(countries.name) LIKE LOWER('%#{query}%')")}
23
21
 
22
+ def self.save_row_data(row)
23
+
24
+ row.headers.each{ |cell| row[cell] = row[cell].to_s.strip }
25
+
26
+ return if row[:name].blank?
27
+
28
+ country = Country.find_by_code(row[:code]) || Country.new
29
+ country.name = row[:name]
30
+ country.code = row[:code]
31
+
32
+ # Initializing error hash for displaying all errors altogether
33
+ error_object = Kuppayam::Importer::ErrorHash.new
34
+
35
+ if country.valid?
36
+ country.save!
37
+ else
38
+ summary = "Error while saving country: #{country.name}"
39
+ details = "Error! #{country.errors.full_messages.to_sentence}"
40
+ error_object.errors << { summary: summary, details: details }
41
+ end
42
+
43
+ return error_object
44
+ end
45
+
24
46
  # ------------------
25
47
  # Instance Methods
26
48
  # ------------------
@@ -34,8 +56,8 @@ class Country < Vyapari::ApplicationRecord
34
56
  end
35
57
 
36
58
  def can_be_deleted?
37
- if self.regions.any? || self.exchange_rates.any?
38
- self.errors.add(:base, DELETE_MESSAGE)
59
+ if self.regions.any?
60
+ #self.errors.add(:base, DELETE_MESSAGE)
39
61
  return false
40
62
  else
41
63
  return true
@@ -1,13 +1,11 @@
1
1
  class ExchangeRate < Vyapari::ApplicationRecord
2
2
 
3
3
  # Validations
4
- validates :currency_name, presence: true, length: {minimum: 2, maximum: 4}, allow_blank: false
4
+ validates :base_currency, presence: true, length: {minimum: 2, maximum: 6}, allow_blank: false
5
+ validates :counter_currency, presence: true, length: {minimum: 2, maximum: 6}, allow_blank: false
5
6
  validates :value, presence: true
6
7
  validates :effective_date, presence: true
7
8
 
8
- # Associations
9
- belongs_to :country
10
-
11
9
  # ------------------
12
10
  # Class Methods
13
11
  # ------------------
@@ -17,14 +15,41 @@ class ExchangeRate < Vyapari::ApplicationRecord
17
15
  # == Examples
18
16
  # >>> obj.search(query)
19
17
  # => ActiveRecord::Relation object
20
- scope :search, lambda {|query| joins(:country).where("LOWER(exchange_rates.currency_name) LIKE LOWER('%#{query}%') OR LOWER(countries.name) LIKE LOWER('%#{query}%')")}
18
+ scope :search, lambda {|query| where("LOWER(base_currency) LIKE LOWER('%#{query}%') OR LOWER(counter_currency) LIKE LOWER('%#{query}%')")}
19
+
20
+ def self.save_row_data(row)
21
+
22
+ row.headers.each{ |cell| row[cell] = row[cell].to_s.strip }
23
+
24
+ return if row[:base_currency].blank?
25
+
26
+ exchange_rate = ExchangeRate.where("base_currency = ? AND counter_currency = ?", row[:base_currency], row[:counter_currency]).first || ExchangeRate.new
27
+
28
+ exchange_rate.base_currency = row[:base_currency]
29
+ exchange_rate.counter_currency = row[:counter_currency]
30
+ exchange_rate.value = row[:value]
31
+ exchange_rate.effective_date = row[:effective_date]
32
+
33
+ # Initializing error hash for displaying all errors altogether
34
+ error_object = Kuppayam::Importer::ErrorHash.new
35
+
36
+ if exchange_rate.valid?
37
+ exchange_rate.save!
38
+ else
39
+ summary = "Error while saving exchange_rate: #{exchange_rate.name}"
40
+ details = "Error! #{exchange_rate.errors.full_messages.to_sentence}"
41
+ error_object.errors << { summary: summary, details: details }
42
+ end
43
+
44
+ return error_object
45
+ end
21
46
 
22
47
  # ------------------
23
48
  # Instance Methods
24
49
  # ------------------
25
50
 
26
51
  def display_name
27
- "#{self.currency_name_was}, #{self.country.try(:name)}"
52
+ "#{self.base_currency_was} to #{self.counter_currency_was}"
28
53
  end
29
54
 
30
55
  def can_be_edited?
@@ -0,0 +1,3 @@
1
+ class Image::BrandImage < Image::Base
2
+ mount_uploader :image, BrandImageUploader
3
+ end
@@ -0,0 +1,3 @@
1
+ class Image::CategoryImage < Image::Base
2
+ mount_uploader :image, CategoryImageUploader
3
+ end
@@ -0,0 +1,3 @@
1
+ class Image::ProductImage < Image::Base
2
+ mount_uploader :image, ProductImageUploader
3
+ end