stockor-core 0.2

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 (221) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +18 -0
  3. data/Gemfile +6 -0
  4. data/Guardfile +13 -0
  5. data/LICENSE.txt +674 -0
  6. data/README.md +88 -0
  7. data/Rakefile +58 -0
  8. data/config/database.yml +9 -0
  9. data/db/migrate/20120110142845_create_skr_sequential_ids.rb +35 -0
  10. data/db/migrate/20140202185309_create_skr_gl_accounts.rb +15 -0
  11. data/db/migrate/20140202193316_create_skr_gl_periods.rb +16 -0
  12. data/db/migrate/20140202193318_create_skr_gl_transactions.rb +14 -0
  13. data/db/migrate/20140202193319_create_skr_gl_postings.rb +16 -0
  14. data/db/migrate/20140202193700_create_skr_gl_manual_entries.rb +13 -0
  15. data/db/migrate/20140213040608_create_skr_payment_terms.rb +16 -0
  16. data/db/migrate/20140220031700_create_skr_addresses.rb +19 -0
  17. data/db/migrate/20140220031800_create_skr_locations.rb +19 -0
  18. data/db/migrate/20140220190836_create_skr_vendors.rb +22 -0
  19. data/db/migrate/20140220203029_create_skr_customers.rb +22 -0
  20. data/db/migrate/20140224034759_create_skr_skus.rb +22 -0
  21. data/db/migrate/20140225032853_create_skr_sku_locs.rb +21 -0
  22. data/db/migrate/20140320030501_create_skr_uoms.rb +19 -0
  23. data/db/migrate/20140321031604_create_skr_sku_vendors.rb +18 -0
  24. data/db/migrate/20140322012143_create_skr_ia_reasons.rb +14 -0
  25. data/db/migrate/20140322014401_create_skr_inventory_adjustments.rb +16 -0
  26. data/db/migrate/20140322023453_create_skr_ia_lines.rb +18 -0
  27. data/db/migrate/20140322035024_create_skr_sku_trans.rb +21 -0
  28. data/db/migrate/20140322223912_create_skr_sales_orders.rb +27 -0
  29. data/db/migrate/20140322223920_create_skr_so_lines.rb +25 -0
  30. data/db/migrate/20140323001446_create_so_details_view.rb +81 -0
  31. data/db/migrate/20140327202102_create_skr_purchase_orders.rb +20 -0
  32. data/db/migrate/20140327202107_create_skr_po_lines.rb +25 -0
  33. data/db/migrate/20140327202207_create_skr_pick_tickets.rb +16 -0
  34. data/db/migrate/20140327202209_create_skr_pt_lines.rb +23 -0
  35. data/db/migrate/20140327224000_create_skr_invoices.rb +25 -0
  36. data/db/migrate/20140327224002_create_skr_inv_lines.rb +23 -0
  37. data/db/migrate/20140330232808_create_skr_sku_loc_details_view.rb +31 -0
  38. data/db/migrate/20140330232810_create_skr_sku_qty_details_view.rb +48 -0
  39. data/db/migrate/20140400164729_create_skr_vouchers.rb +22 -0
  40. data/db/migrate/20140400164733_create_skr_vo_lines.rb +21 -0
  41. data/db/migrate/20140401164729_create_skr_po_receipt.rb +16 -0
  42. data/db/migrate/20140401164740_create_skr_por_line.rb +21 -0
  43. data/db/migrate/20140422024010_create_skr_inv_details_view.rb +42 -0
  44. data/lib/generators/stockor/migrations/install_generator.rb +42 -0
  45. data/lib/skr/address.rb +97 -0
  46. data/lib/skr/business_entity.rb +25 -0
  47. data/lib/skr/concerns/acts_as_uom.rb +47 -0
  48. data/lib/skr/concerns/all.rb +30 -0
  49. data/lib/skr/concerns/association_extensions.rb +85 -0
  50. data/lib/skr/concerns/attr_accessor_with_default.rb +54 -0
  51. data/lib/skr/concerns/code_identifier.rb +43 -0
  52. data/lib/skr/concerns/export_associations.rb +52 -0
  53. data/lib/skr/concerns/export_join_tables.rb +39 -0
  54. data/lib/skr/concerns/export_methods.rb +104 -0
  55. data/lib/skr/concerns/export_scope.rb +66 -0
  56. data/lib/skr/concerns/exported_limit_evaluator.rb +17 -0
  57. data/lib/skr/concerns/gl_tran_extensions.rb +18 -0
  58. data/lib/skr/concerns/has_gl_transaction.rb +67 -0
  59. data/lib/skr/concerns/has_sku_loc_lines.rb +47 -0
  60. data/lib/skr/concerns/immutable_model.rb +32 -0
  61. data/lib/skr/concerns/inv_extensions.rb +24 -0
  62. data/lib/skr/concerns/is_order_like.rb +47 -0
  63. data/lib/skr/concerns/is_sku_loc_line.rb +65 -0
  64. data/lib/skr/concerns/json_attribute_access.rb +55 -0
  65. data/lib/skr/concerns/locked_fields.rb +84 -0
  66. data/lib/skr/concerns/pt_extensions.rb +22 -0
  67. data/lib/skr/concerns/pub_sub.rb +105 -0
  68. data/lib/skr/concerns/queries.rb +20 -0
  69. data/lib/skr/concerns/random_hash_code.rb +40 -0
  70. data/lib/skr/concerns/sanitize_json.rb +49 -0
  71. data/lib/skr/concerns/sku_extensions.rb +52 -0
  72. data/lib/skr/concerns/so_extensions.rb +30 -0
  73. data/lib/skr/concerns/state_machine.rb +62 -0
  74. data/lib/skr/concerns/track_modifications.rb +48 -0
  75. data/lib/skr/concerns/visible_id_identifier.rb +53 -0
  76. data/lib/skr/core.rb +30 -0
  77. data/lib/skr/core/configuration.rb +87 -0
  78. data/lib/skr/core/db.rb +82 -0
  79. data/lib/skr/core/db/migration_helpers.rb +178 -0
  80. data/lib/skr/core/db/migrations.rb +15 -0
  81. data/lib/skr/core/db/seed.rb +46 -0
  82. data/lib/skr/core/db/seed/chart_of_accounts.yml +168 -0
  83. data/lib/skr/core/db/seed/payment_terms.yml +60 -0
  84. data/lib/skr/core/logger.rb +36 -0
  85. data/lib/skr/core/numbers.rb +71 -0
  86. data/lib/skr/core/rails_engine.rb +5 -0
  87. data/lib/skr/core/standard_pricing_provider.rb +15 -0
  88. data/lib/skr/core/strings.rb +57 -0
  89. data/lib/skr/core/testing.rb +11 -0
  90. data/lib/skr/core/testing/assertions.rb +44 -0
  91. data/lib/skr/core/testing/fixtures.rb +25 -0
  92. data/lib/skr/core/testing/fixtures/skr/addresses.yml +53 -0
  93. data/lib/skr/core/testing/fixtures/skr/customers.yml +43 -0
  94. data/lib/skr/core/testing/fixtures/skr/gl_accounts.yml +86 -0
  95. data/lib/skr/core/testing/fixtures/skr/gl_manual_entries.yml +4 -0
  96. data/lib/skr/core/testing/fixtures/skr/gl_periods.yml +26 -0
  97. data/lib/skr/core/testing/fixtures/skr/gl_postings.yml +88 -0
  98. data/lib/skr/core/testing/fixtures/skr/gl_transactions.yml +35 -0
  99. data/lib/skr/core/testing/fixtures/skr/ia_lines.yml +7 -0
  100. data/lib/skr/core/testing/fixtures/skr/ia_reasons.yml +15 -0
  101. data/lib/skr/core/testing/fixtures/skr/inv_lines.yml +22 -0
  102. data/lib/skr/core/testing/fixtures/skr/inventory_adjustments.yml +6 -0
  103. data/lib/skr/core/testing/fixtures/skr/invoices.yml +10 -0
  104. data/lib/skr/core/testing/fixtures/skr/locations.yml +24 -0
  105. data/lib/skr/core/testing/fixtures/skr/payment_terms.yml +42 -0
  106. data/lib/skr/core/testing/fixtures/skr/pick_tickets.yml +4 -0
  107. data/lib/skr/core/testing/fixtures/skr/po_lines.yml +44 -0
  108. data/lib/skr/core/testing/fixtures/skr/po_receipts.yml +5 -0
  109. data/lib/skr/core/testing/fixtures/skr/por_lines.yml +13 -0
  110. data/lib/skr/core/testing/fixtures/skr/pt_lines.yml +12 -0
  111. data/lib/skr/core/testing/fixtures/skr/purchase_orders.yml +16 -0
  112. data/lib/skr/core/testing/fixtures/skr/sales_orders.yml +32 -0
  113. data/lib/skr/core/testing/fixtures/skr/sku_locs.yml +78 -0
  114. data/lib/skr/core/testing/fixtures/skr/sku_trans.yml +9 -0
  115. data/lib/skr/core/testing/fixtures/skr/sku_vendors.yml +35 -0
  116. data/lib/skr/core/testing/fixtures/skr/skus.yml +50 -0
  117. data/lib/skr/core/testing/fixtures/skr/so_lines.yml +71 -0
  118. data/lib/skr/core/testing/fixtures/skr/uoms.yml +61 -0
  119. data/lib/skr/core/testing/fixtures/skr/vendors.yml +48 -0
  120. data/lib/skr/core/testing/fixtures/skr/vo_lines.yml +12 -0
  121. data/lib/skr/core/testing/fixtures/skr/vouchers.yml +8 -0
  122. data/lib/skr/core/testing/helper.rb +18 -0
  123. data/lib/skr/core/testing/test_case.rb +17 -0
  124. data/lib/skr/core/version.rb +5 -0
  125. data/lib/skr/customer.rb +34 -0
  126. data/lib/skr/gl_account.rb +56 -0
  127. data/lib/skr/gl_manual_entry.rb +31 -0
  128. data/lib/skr/gl_period.rb +13 -0
  129. data/lib/skr/gl_posting.rb +54 -0
  130. data/lib/skr/gl_transaction.rb +174 -0
  131. data/lib/skr/ia_line.rb +129 -0
  132. data/lib/skr/ia_reason.rb +16 -0
  133. data/lib/skr/inv_line.rb +90 -0
  134. data/lib/skr/inventory_adjustment.rb +60 -0
  135. data/lib/skr/invoice.rb +159 -0
  136. data/lib/skr/location.rb +31 -0
  137. data/lib/skr/model.rb +37 -0
  138. data/lib/skr/null_user.rb +30 -0
  139. data/lib/skr/payment_term.rb +30 -0
  140. data/lib/skr/pick_ticket.rb +71 -0
  141. data/lib/skr/po_line.rb +69 -0
  142. data/lib/skr/po_receipt.rb +51 -0
  143. data/lib/skr/por_line.rb +80 -0
  144. data/lib/skr/pt_line.rb +74 -0
  145. data/lib/skr/purchase_order.rb +112 -0
  146. data/lib/skr/sales_order.rb +159 -0
  147. data/lib/skr/sequential_id.rb +23 -0
  148. data/lib/skr/sku.rb +99 -0
  149. data/lib/skr/sku_loc.rb +94 -0
  150. data/lib/skr/sku_tran.rb +111 -0
  151. data/lib/skr/sku_vendor.rb +26 -0
  152. data/lib/skr/so_line.rb +159 -0
  153. data/lib/skr/uom.rb +63 -0
  154. data/lib/skr/user_proxy.rb +60 -0
  155. data/lib/skr/validators/all.rb +2 -0
  156. data/lib/skr/validators/email.rb +17 -0
  157. data/lib/skr/validators/set.rb +18 -0
  158. data/lib/skr/vendor.rb +33 -0
  159. data/lib/skr/vo_line.rb +35 -0
  160. data/lib/skr/voucher.rb +119 -0
  161. data/lib/stockor/core.rb +9 -0
  162. data/stockor-core.gemspec +37 -0
  163. data/tasks/migrations.rake +23 -0
  164. data/tasks/publish.rake +8 -0
  165. data/test/address_test.rb +57 -0
  166. data/test/concerns/attr_with_default_test.rb +45 -0
  167. data/test/concerns/code_identifier_test.rb +46 -0
  168. data/test/concerns/export_associations_test.rb +7 -0
  169. data/test/concerns/export_methods_test.rb +31 -0
  170. data/test/concerns/export_scope_test.rb +16 -0
  171. data/test/concerns/exported_limits_test.rb +47 -0
  172. data/test/concerns/json_attribute_access_test.rb +27 -0
  173. data/test/concerns/pub_sub_test.rb +83 -0
  174. data/test/concerns/sanitize_json_test.rb +47 -0
  175. data/test/core/configuration_test.rb +24 -0
  176. data/test/core/numbers_test.rb +26 -0
  177. data/test/core/strings_test.rb +41 -0
  178. data/test/customer_test.rb +34 -0
  179. data/test/gl_account_test.rb +23 -0
  180. data/test/gl_manual_entry_test.rb +17 -0
  181. data/test/gl_period_test.rb +12 -0
  182. data/test/gl_posting_test.rb +39 -0
  183. data/test/gl_transaction_test.rb +58 -0
  184. data/test/ia_line_test.rb +68 -0
  185. data/test/ia_reason_test.rb +11 -0
  186. data/test/inv_line_test.rb +58 -0
  187. data/test/inventory_adjustment_test.rb +72 -0
  188. data/test/invoice_test.rb +63 -0
  189. data/test/location_test.rb +10 -0
  190. data/test/payment_term_test.rb +25 -0
  191. data/test/pick_ticket_test.rb +27 -0
  192. data/test/po_line_test.rb +36 -0
  193. data/test/po_receipt_test.rb +93 -0
  194. data/test/por_line_test.rb +79 -0
  195. data/test/pt_line_test.rb +29 -0
  196. data/test/purchase_order_test.rb +44 -0
  197. data/test/sales_order_test.rb +74 -0
  198. data/test/sku_loc_test.rb +50 -0
  199. data/test/sku_test.rb +45 -0
  200. data/test/sku_tran_test.rb +21 -0
  201. data/test/sku_vendor_test.rb +13 -0
  202. data/test/so_line_test.rb +89 -0
  203. data/test/test_helper.rb +1 -0
  204. data/test/uom_test.rb +14 -0
  205. data/test/vendor_test.rb +35 -0
  206. data/test/vo_line_test.rb +20 -0
  207. data/test/voucher_test.rb +35 -0
  208. data/yard_ext/all.rb +9 -0
  209. data/yard_ext/code_identifier_handler.rb +33 -0
  210. data/yard_ext/concern_meta_methods.rb +60 -0
  211. data/yard_ext/config_options.rb +27 -0
  212. data/yard_ext/exported_scope.rb +4 -0
  213. data/yard_ext/immutable_handler.rb +17 -0
  214. data/yard_ext/json_attr_accessor.rb +22 -0
  215. data/yard_ext/locked_fields_handler.rb +21 -0
  216. data/yard_ext/templates/default/layout/html/layout.erb +20 -0
  217. data/yard_ext/templates/default/method_details/html/github_link.erb +1 -0
  218. data/yard_ext/templates/default/method_details/setup.rb +3 -0
  219. data/yard_ext/validators.rb +1 -0
  220. data/yard_ext/visible_id_handler.rb +38 -0
  221. metadata +448 -0
data/lib/skr/uom.rb ADDED
@@ -0,0 +1,63 @@
1
+ module Skr
2
+
3
+ class Uom < Skr::Model
4
+
5
+ belongs_to :sku, :inverse_of=>:uoms
6
+
7
+ validates :price, :numericality=>true, :allow_nil=>false
8
+ validates :sku, :presence=>true, :on=>:update
9
+ validates :code, :presence=>true
10
+ validates :size, :numericality => true, :length=>{:minimum=>1}
11
+ validates :weight, :height, :width, :depth, :numericality=>{:greater_than=>0.1}, :allow_nil=>true
12
+
13
+ export_methods :combined_uom, mandatory: true
14
+
15
+ def combined_uom
16
+ if self.size.nil? || self.code.nil?
17
+ ''
18
+ elsif 1 == self.size
19
+ self.code
20
+ else
21
+ "#{self.code}/#{self.size}"
22
+ end
23
+ end
24
+
25
+ def has_dimensions?
26
+ ! self.dimensions.include?(nil)
27
+ end
28
+
29
+ def dimensions
30
+ [ width, height, depth ]
31
+ end
32
+
33
+ def volume
34
+ if has_dimensions?
35
+ dimensions.inject(:*)
36
+ else
37
+ nil
38
+ end
39
+ end
40
+
41
+ def blank?
42
+ self.code.blank? || self.size.to_i == 0
43
+ end
44
+
45
+
46
+ def self.ea
47
+ Uom.new({ :code=>'EA',:size=>1, :price=>0.0 })
48
+ end
49
+
50
+ end
51
+
52
+
53
+ end # Skr module
54
+
55
+
56
+ __END__
57
+
58
+ def for_public(user=nil,options={})
59
+ as_json({
60
+ :only=>%w{ code size base_price },
61
+ :methods=>%w{ combined_uom dimensions volume }
62
+ })
63
+ end
@@ -0,0 +1,60 @@
1
+ module Skr
2
+
3
+ # The UserProxy is a stand-in for the real user
4
+ # model that will be implementation specific by the user of Stockor Core
5
+ class UserProxy
6
+
7
+ # The user who's currently interacting with Stockor.
8
+ # Defaults to 0, indicating anonymous or unknown
9
+ # @return [Object,FixNum] whatever was set using scoped_to, or 0 if nothing was set
10
+ def self.current
11
+ Thread.current[:skr_user_proxy]
12
+ end
13
+
14
+ # Retrieve the current id of the user we're proxying for.
15
+ # get's a bit complicated since we can proxy both for a user object
16
+ # or just the user's id
17
+ # @return [Fixnum] current user's ID. If the current user is not set, returns 0
18
+ def self.current_id
19
+ if self.current.nil?
20
+ 0
21
+ else
22
+ self.current.is_a?(Fixnum) ? self.current : self.current.id
23
+ end
24
+ end
25
+
26
+ # sets the user for the duration of the block
27
+ # @example Inside a Rails controller
28
+ #
29
+ # class DocumentsController < ApplicationController
30
+ # around_filter :set_skr_user
31
+ #
32
+ # # update's the Document's owner to current
33
+ # # But sets all the notes to be owned by admin
34
+ # def update_owner
35
+ # doc = Document.find(params[:id])
36
+ # doc.current_owner = Skr::UserProxy.current
37
+ # Skr::UserProxy.scoped_to( User.admin ) do
38
+ # doc.notes.each{ |note| note.set_owner_to_current! } # will set to Skr::UserProxy.current
39
+ # end
40
+ # end
41
+ #
42
+ # private
43
+ #
44
+ # def set_skr_user
45
+ # user = SuperUserModel.find( session[:user] )
46
+ # Skr::UserProxy.scoped_to( user ) do
47
+ # yield
48
+ # end
49
+ # end
50
+ # end
51
+ #
52
+ # @return [UserProxy] self
53
+ def self.scoped_to( user )
54
+ prev_user, Thread.current[:skr_user_proxy] = self.current, user
55
+ yield user
56
+ ensure
57
+ Thread.current[:skr_user_proxy] = prev_user
58
+ end
59
+ end
60
+ end
@@ -0,0 +1,2 @@
1
+ require_relative "set"
2
+ require_relative "email"
@@ -0,0 +1,17 @@
1
+ # A custom validator "email".
2
+ # Doesn't really validate an email completely
3
+ # It simply asserts that the email string has one (and only one)
4
+ # @ (at symbol). This is mainly
5
+ # to give user feedback and not to assert the e-mail validity.
6
+
7
+ class EmailValidator < ActiveModel::EachValidator
8
+
9
+ # Regex originated from the Devise gem
10
+ REGEX = /\A[^@]+@([^@\.]+\.)+[^@\.]+\z/
11
+
12
+ def validate_each( rec, attr, value)
13
+ unless value.present? && value.match( REGEX )
14
+ rec.errors.add attr, options[:message] || 'does not appear to be a valid email'
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,18 @@
1
+ # A custom validator "set". It's similar to :presence validator
2
+ # Unlike :presence, :set doesn't care whether the associated record is valid or not, just that it is present
3
+ # Also unlike :presence, it only works on belongs_to
4
+ class SetValidator < ActiveModel::EachValidator
5
+
6
+ def validate_each( record, attribute, value)
7
+ association = record.class.reflect_on_association( attribute )
8
+
9
+ if association.nil? || !association.belongs_to?
10
+ raise ArgumentError, "Cannot validate existence on #{record.class} #{attribute}, not a :belongs_to association"
11
+ end
12
+
13
+ if record.send( attribute ).nil?
14
+ record.errors.add( attribute, "is not set")
15
+ end
16
+
17
+ end
18
+ end
data/lib/skr/vendor.rb ADDED
@@ -0,0 +1,33 @@
1
+ module Skr
2
+
3
+ # Vendors is a companies you purchase goods and services from.
4
+ # They have both a billing and shipping address,
5
+ # a gl account that payables should be applied against, and a payment term.
6
+ class Vendor < Skr::Model
7
+
8
+ # Common code shared with {Customer}
9
+ include BusinessEntity
10
+
11
+ belongs_to :gl_payables_account, class_name: 'Skr::GlAccount', export: true
12
+ belongs_to :gl_freight_account, class_name: 'Skr::GlAccount', export: true
13
+
14
+ has_many :purchase_orders, inverse_of: :vendor
15
+ has_many :vouchers, inverse_of: :vendor
16
+ has_many :vendor_skus, class_name: 'Skr::SkuVendor', inverse_of: :vendor
17
+
18
+ delegate_and_export :gl_payables_account_number
19
+ validates :gl_payables_account, set: true
20
+
21
+ has_many :sku_vendors
22
+
23
+ private
24
+
25
+ def set_defaults
26
+ self.terms ||= PaymentTerm.find_by_code(Core.config.customer_terms_code)
27
+ self.gl_payables_account ||= GlAccount.default_for( :ap )
28
+ self.gl_freight_account ||= GlAccount.default_for( :freight )
29
+ end
30
+
31
+ end
32
+
33
+ end # Skr module
@@ -0,0 +1,35 @@
1
+ module Skr
2
+
3
+ class VoLine < Skr::Model
4
+
5
+ acts_as_uom
6
+
7
+ is_sku_loc_line parent: 'voucher'
8
+
9
+ belongs_to :voucher
10
+ belongs_to :sku_vendor
11
+ belongs_to :po_line
12
+ has_one :sku, :through => :sku_vendor, export: true
13
+
14
+ validates :sku_vendor, :voucher, set: true
15
+ validates :sku_code, :description, :presence => true
16
+
17
+ validate :qty, numericality: { gt: 0 }
18
+
19
+ before_validation :set_defaults, one: :create
20
+
21
+ private
22
+
23
+ def set_defaults
24
+ if po_line
25
+ self.sku_vendor = po_line.sku.sku_vendors.for_vendor( self.voucher.vendor )
26
+ %w{ price sku_code part_code description uom_code uom_size }.each do | attr |
27
+ self[ attr ] ||= po_line[ attr ]
28
+ end
29
+ end
30
+ true
31
+ end
32
+ end
33
+
34
+
35
+ end # Skr module
@@ -0,0 +1,119 @@
1
+ module Skr
2
+
3
+ # A voucher is a record of a {Vendor}'s demand for payment, or a record of
4
+ # It transistions through the following states
5
+ #
6
+ # * Saved; A {PurchaseOrder} has been recieved but an Invoice has not been received fromt the Vendor
7
+ # * It credit's each line's {Sku#gl_asset_account} and debit's the System default inventory_receipts_clearing
8
+ # * Confirmed; An Invoice has been received and verified as accurate.
9
+ # * Debit: {Vendor#gl_payables_account}, Credit: inventory_receipts_clearing
10
+ # * Paid; A payment has been made against the Voucher
11
+ # * Debit {Vendor#gl_payables_account}, Credit: Deposit clearing account
12
+ class Voucher < Skr::Model
13
+
14
+ has_visible_id
15
+
16
+ has_sku_loc_lines
17
+
18
+ belongs_to :vendor, export: true
19
+ belongs_to :customer, export: true
20
+
21
+ belongs_to :purchase_order
22
+ belongs_to :terms, :class_name=>'Skr::PaymentTerm', export: true
23
+ belongs_to :location
24
+
25
+ has_many :gl_transactions, :as=>:source
26
+ has_many :lines, :class_name=>'Skr::VoLine', export: { writable: true },
27
+ :inverse_of=>:voucher, :autosave=>true, validate: true
28
+
29
+ before_validation :set_defaults, :on=>:create
30
+
31
+ export_scope :with_details, lambda { | *args |
32
+ compose_query_using_detail_view( view: 'vo_details', join_to: 'voucher_id' )
33
+ }
34
+
35
+ export_scope :unpaid, lambda{ | unused=nil |
36
+ where(['vouchers.state <> ? and payment_lines.id is null', 'pending']).includes(:payment_line)
37
+ }
38
+
39
+ state_machine do
40
+ state :pending, initial: true
41
+ state :confirmed
42
+ state :paid
43
+
44
+ event :mark_confirmed do
45
+ transitions from: :pending, to: :confirmed
46
+ before :record_confirmation_in_gl
47
+ end
48
+
49
+ event :mark_paid do
50
+ transitions from: :confirmed, to: :paid, guards: :ensure_payment_line
51
+ before :record_payment_in_gl
52
+ end
53
+
54
+
55
+ end
56
+
57
+ def po_receipt=(por)
58
+ self.vendor = por.vendor
59
+ self.purchase_order = por.purchase_order
60
+ self.terms = self.purchase_order.terms
61
+ self.refno = por.refno
62
+ end
63
+
64
+ # def payment_line=(pl)
65
+ # pl.refno = self.refno
66
+ # pl.description = "Payment on PO #{self.visible_id}"
67
+ # super
68
+ # end
69
+
70
+ # def description_for_gl_transaction(gl_tran)
71
+ # end
72
+
73
+ # def does_create_own_gl_records?
74
+ # true
75
+ # end
76
+
77
+ private
78
+
79
+ def ensure_payment_line
80
+ payment_line.present?
81
+ end
82
+
83
+ def set_defaults
84
+ # self.freight ||= 0.0
85
+ if self.purchase_order
86
+ self.vendor = self.purchase_order.vendor
87
+ #self.location = self.purchase_order.location
88
+ self.terms ||= self.purchase_order.terms
89
+ end
90
+ end
91
+
92
+
93
+
94
+ def record_confirmation_in_gl
95
+ self.confirmation_date ||= Date.today
96
+ GlTransaction.push_or_save(
97
+ :owner => self, amount: total,
98
+ :debit => vendor.gl_payables_account,
99
+ :credit => GlAccount.default_for( :inventory_receipts_clearing ),
100
+ :options => { description: "Voucher #{self.visible_id}" }
101
+ )
102
+ true
103
+ end
104
+
105
+ def record_payment_in_gl
106
+ gl = self.gl_transactions.build({
107
+ :source =>self,
108
+ :location => self.purchase_order.location,
109
+ :amount =>self.total,
110
+ :description =>'Voucher Payment' })
111
+ gl.credit.account = self.vendor.gl_payables_account
112
+ gl.debit.account = self.payment_line.payment.bank_account.gl_account
113
+ gl.save!
114
+ end
115
+
116
+ end
117
+
118
+
119
+ end # Skr module
@@ -0,0 +1,9 @@
1
+ require_relative '../skr/core'
2
+
3
+ # This is a "sham" namespace that only exists so that
4
+ # Bundler will pull in the Skr::Core namespace
5
+ module Stockor
6
+ module Core
7
+ VERSION = Skr::Core::VERSION
8
+ end
9
+ end
@@ -0,0 +1,37 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'skr/core/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+
8
+ spec.name = "stockor-core"
9
+ spec.version = Skr::Core::VERSION
10
+ spec.authors = ["Nathan Stitt"]
11
+ spec.email = ["nathan@argosity.com"]
12
+
13
+ spec.summary = %q{Stockor Core contains the models for the Stockor ERP system}
14
+ spec.description = %q{Stockor Core contains the ActiveRecord models and business logic for the Stockor ERP system}
15
+
16
+ spec.homepage = "http://stockor.org/"
17
+ spec.license = "GPL-3.0"
18
+
19
+ spec.files = `git ls-files`.split($/)
20
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
21
+ spec.test_files = spec.files.grep(%r{^test/})
22
+ spec.require_paths = ["lib"]
23
+
24
+ spec.required_ruby_version = '>= 2.0'
25
+ spec.add_dependency 'activerecord', '~> 4.1'
26
+ spec.add_dependency 'pg', '~> 0.17'
27
+ spec.add_dependency 'aasm', '~>3.1'
28
+ spec.add_dependency "require_all", '~> 1.3'
29
+ spec.add_development_dependency "bundler", "~> 1.5"
30
+ spec.add_development_dependency "rake"
31
+ spec.add_development_dependency "guard"
32
+ spec.add_development_dependency "growl"
33
+ spec.add_development_dependency "pry-plus"
34
+ spec.add_development_dependency "guard-minitest"
35
+
36
+
37
+ end
@@ -0,0 +1,23 @@
1
+ require 'active_record'
2
+ require 'active_support/core_ext/string/strip'
3
+ require 'fileutils'
4
+ require 'skr/core'
5
+ ## quite a bit of this is cribbed from Sinatra ActiveRecord
6
+
7
+ load 'active_record/railties/databases.rake'
8
+ require 'rake'
9
+
10
+
11
+ namespace :db do
12
+
13
+ task :environment do
14
+ Skr::Core::DB.configure_rake_environment
15
+ end
16
+
17
+ desc "create an ActiveRecord migration"
18
+ task :create_migration,[ :name ] do | t, args |
19
+ Skr::Core::DB.create_migration( "create_skr_" + args[:name] )
20
+ end
21
+
22
+
23
+ end
@@ -0,0 +1,8 @@
1
+ namespace :publish do
2
+
3
+ desc "generate and publish docs to stockor.org"
4
+ task :docs => 'doc' do
5
+ system( "rsync", "doc/", "-avz", "--delete", "stockor@stockor.org:~/docs/core")
6
+ end
7
+
8
+ end
@@ -0,0 +1,57 @@
1
+ require_relative 'test_helper'
2
+
3
+ class AddressTest < Skr::TestCase
4
+
5
+ def test_creation
6
+ addr=Address.new( name:" a test", email:"test@test.com" )
7
+ assert_saves addr
8
+ end
9
+
10
+ def test_email_with_name
11
+ addr=Address.new( email: 'john@mcauthor.com', name: 'John D. McAuthor' )
12
+ assert_equal "John D. McAuthor <john@mcauthor.com>", addr.email_with_name
13
+ end
14
+
15
+ def test_blankness
16
+ addr = Address.blank
17
+ assert addr.blank?, "Blank address isn't blank?"
18
+ %w{ name line1 city state postal_code }.each do | attr |
19
+ assert addr.blank?
20
+ addr[ attr ] = "something"
21
+ end
22
+ refute addr.blank?
23
+ end
24
+
25
+ def test_separated_name
26
+ addr=Address.new( name: 'John D McAuthor' )
27
+ assert_equal 'John', addr.seperated_name[:first]
28
+ assert_equal 'McAuthor', addr.seperated_name[:last]
29
+ end
30
+
31
+ def test_selective_validations
32
+ addr=Address.blank
33
+ assert addr.save
34
+ addr.enable_validations
35
+ refute addr.save
36
+ %w{ name line1 city state postal_code }.each do | attr |
37
+ addr[ attr ] = "something"
38
+ end
39
+ assert addr.save
40
+ addr.enable_validations include_email: true
41
+ refute addr.save
42
+ addr.email = "test" # <- no '@'
43
+ refute addr.save
44
+ addr.email = "test@test.com" # <- no '@'
45
+ assert addr.save
46
+ addr.enable_validations include_phone: true
47
+ refute addr.save
48
+ addr.phone = "555-555-5555"
49
+ assert addr.save
50
+ end
51
+
52
+ def test_converting_to_string
53
+ addr = skr_addresses(:office)
54
+ assert_equal "Argosity Office\n619 E Capitol Ave\nJefferson City Missouri, 65101", addr.to_s
55
+ end
56
+
57
+ end