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
@@ -0,0 +1,22 @@
1
+ require 'skr/core/db/migration_helpers'
2
+
3
+ class CreateSkrVouchers < ActiveRecord::Migration
4
+ def change
5
+
6
+ create_skr_table "vouchers" do |t|
7
+ t.skr_visible_id
8
+
9
+ t.skr_reference :vendor, single: true, null: false
10
+ t.skr_reference :purchase_order, single: true, null: true
11
+
12
+ t.skr_reference :terms, to_table: 'payment_terms'
13
+
14
+ t.string "state", null: false
15
+ t.string "refno"
16
+
17
+ t.date "confirmation_date", null: true # starts out as non-confirmed
18
+ t.skr_track_modifications
19
+ end
20
+
21
+ end
22
+ end
@@ -0,0 +1,21 @@
1
+ require 'skr/core/db/migration_helpers'
2
+
3
+ class CreateSkrVoLines < ActiveRecord::Migration
4
+ def change
5
+ create_skr_table "vo_lines" do |t|
6
+ t.skr_reference :voucher, null: false, single: true
7
+ t.skr_reference :sku_vendor, null: false, single: true
8
+ t.skr_reference :po_line, null: true, single: true
9
+ t.string "sku_code", null: false
10
+ t.string "part_code", null: false
11
+ t.string "description", null: false
12
+ t.string "uom_code", null: false
13
+ t.integer "uom_size", null: false, limit: 2
14
+ t.integer "position", null: false, limit: 2
15
+ t.integer "qty", null: false, default: 0
16
+ t.skr_currency "price", null: false
17
+ t.skr_track_modifications
18
+ end
19
+
20
+ end
21
+ end
@@ -0,0 +1,16 @@
1
+ require 'skr/core/db/migration_helpers'
2
+
3
+ class CreateSkrPoReceipt < ActiveRecord::Migration
4
+ def change
5
+ create_skr_table "po_receipts" do |t|
6
+ t.skr_visible_id
7
+ t.skr_reference :location, single: true
8
+ t.skr_currency :freight, null: false, default: 0.0
9
+ t.skr_reference :purchase_order, single: true, null: false
10
+ t.skr_reference :vendor, single: true, null: false
11
+ t.skr_reference :voucher, single: true, null: true
12
+ t.string :refno
13
+ t.skr_track_modifications create_only: true
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,21 @@
1
+ require 'skr/core/db/migration_helpers'
2
+
3
+ class CreateSkrPorLine < ActiveRecord::Migration
4
+ def change
5
+ create_skr_table "por_lines" do |t|
6
+ t.skr_reference :po_receipt, null: false, to_table: 'po_receipts'
7
+ t.skr_reference :po_line, null: true, single: true
8
+ t.skr_reference :sku_loc, null: false, single: true
9
+ t.skr_reference :sku_vendor, null: true, single: true
10
+ t.string "sku_code", null: false
11
+ t.string "part_code", null: false
12
+ t.string "description", null: false
13
+ t.string "uom_code", null: false
14
+ t.integer "uom_size", null: false, limit: 2
15
+ t.integer "position", null: false, limit: 2
16
+ t.integer "qty", null: false, default: 0
17
+ t.skr_currency "price", null: false
18
+ t.skr_track_modifications create_only: true
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,42 @@
1
+ require 'skr/core/db/migration_helpers'
2
+
3
+ class CreateSkrInvDetailsView < ActiveRecord::Migration
4
+
5
+ def up
6
+ execute <<-EOS.squish
7
+ create view #{skr_prefix}inv_details as
8
+ select
9
+ inv.id as invoice_id,
10
+ so.visible_id as sales_order_visible_id,
11
+ pt.id as pick_ticket_id,
12
+ to_char(so.created_at,'YYYY-MM-DD') as string_order_date,
13
+ to_char(inv.created_at,'YYYY-MM-DD') as string_invoice_date,
14
+ cust.code as customer_code, cust.name as customer_name,
15
+ ba.name as bill_addr_name,
16
+ coalesce( ttls.total,0.0 ) as total,
17
+ coalesce( ttls.num_lines, 0 ) as num_lines,
18
+ coalesce( ttls.other_charge_total, 0 ) as total_other_charge_amount,
19
+ coalesce( ttls.total,0.0 ) - coalesce( ttls.other_charge_total, 0.0 ) as subtotal_amount
20
+ from #{skr_prefix}invoices inv
21
+ join #{skr_prefix}customers cust on cust.id = inv.customer_id
22
+ left join #{skr_prefix}addresses ba on ba.id = inv.billing_address_id
23
+ left join #{skr_prefix}sales_orders so on so.id = inv.sales_order_id
24
+ left join #{skr_prefix}pick_tickets pt on pt.id = inv.pick_ticket_id
25
+ left join (
26
+ select
27
+ invoice_id,
28
+ sum(ivl.qty*ivl.price) as total,
29
+ sum( case when s.is_other_charge then ivl.qty*ivl.price else 0 end ) as other_charge_total,
30
+ count(ivl.*) as num_lines
31
+ from #{skr_prefix}inv_lines ivl
32
+ join #{skr_prefix}sku_locs sl on sl.id = ivl.sku_loc_id
33
+ join #{skr_prefix}skus s on s.id = sl.sku_id
34
+ group by invoice_id
35
+ ) ttls on ttls.invoice_id = inv.id
36
+ EOS
37
+ end
38
+
39
+ def down
40
+ execute "drop view #{skr_prefix}inv_details"
41
+ end
42
+ end
@@ -0,0 +1,42 @@
1
+ require 'skr/core/db/migrations'
2
+
3
+ module Stockor
4
+
5
+ module Migrations
6
+
7
+ class InstallGenerator < Rails::Generators::Base
8
+ include Rails::Generators::Migration
9
+
10
+ source_root Skr::Core::DB::Migrations.paths.first
11
+
12
+ Skr::Core::DB::Migrations.paths.slice(1..-1).each do | source_path |
13
+ source_paths << source_path
14
+ end
15
+
16
+ desc "Install Stockor migrations"
17
+ def self.next_migration_number(path)
18
+ unless @prev_migration_nr
19
+ @prev_migration_nr = Time.now.utc.strftime("%Y%m%d%H%M%S").to_i
20
+ else
21
+ @prev_migration_nr += 1
22
+ end
23
+ @prev_migration_nr.to_s
24
+ end
25
+
26
+ def copy_migrations
27
+ Skr::Core::DB::Migrations.paths.each do | source_path |
28
+
29
+ Pathname.glob( source_path.join('*') ).each do | migration |
30
+ from = File.basename( migration )
31
+ dest = from.gsub(/^\d+_(.*).rb$/,'\\1.rb')
32
+ if self.class.migration_exists?("db/migrate", "#{dest}")
33
+ say_status("skipped", "Migration #{dest} already exists")
34
+ else
35
+ migration_template( from, "db/migrate/#{dest}" )
36
+ end
37
+ end
38
+ end
39
+ end
40
+ end
41
+ end
42
+ end
@@ -0,0 +1,97 @@
1
+ module Skr
2
+
3
+ # A postal address with optional email and phone number
4
+ # By default all fields may be left blank.
5
+ #
6
+ # Validations may be selectively enabled by using the #enable_validations method
7
+ class Address < Skr::Model
8
+
9
+ # @!attribute email
10
+ # The email address to use
11
+
12
+ # @!attribute ensure_not_blank
13
+ # Must the Address be filled out? The {#blank?} method must return false
14
+ # @return [Boolean]
15
+ # @!attribute validate_email
16
+ # Will the email be validated to meet the {EmailValidator} requirements?
17
+ # @return [Boolean]
18
+ # @!attribute validate_phone
19
+ # Should the phone field be validated to be not blank?
20
+ # @return [Boolean]
21
+ attr_accessor :ensure_not_blank, :validate_email, :validate_phone
22
+
23
+ validates :name, :line1, :city, :state, :postal_code, :presence=>true, :if=>:ensure_not_blank
24
+ validates :email, :presence=>true, :email=>true, :if=>:validate_email
25
+ validates :phone, :presence=>true, :if=>:validate_phone
26
+
27
+ # @return [Address] a blank copy of an address
28
+ def self.blank
29
+ Address.new({ name: '', line1: '', city: '', state: '', postal_code: '' })
30
+ end
31
+
32
+ # @return [String] the name and email formatted for inclusion in an email
33
+ def email_with_name
34
+ "#{name} <#{email}>"
35
+ end
36
+
37
+ # fill in missing fields from postal_code using the ZipCode lookup table
38
+ def fill_missing_from_zip
39
+ if ( self.postal_code.present? &&
40
+ ( self.city.blank? || self.state.blank? ) &&
41
+ zc = ZipCode.find_by_code( self.postal_code )
42
+ )
43
+ self.city ||= zc.city
44
+ self.state ||= zc.state
45
+ end
46
+ end
47
+
48
+ # @return [Boolean] is any of (name line1 city state postal_code) blank?
49
+ def blank?
50
+ return !! %w{ name line1 city state postal_code }.detect{ |field| self[field].blank? }
51
+ end
52
+
53
+ # split the name on space
54
+ # @return [Hash]
55
+ # * :first [String] Portion of name before first space
56
+ # * :last [String] Portion of name after last space
57
+ def seperated_name
58
+ {:first=>name.to_s.split(' ').first, :last=> name.to_s.split(' ').last }
59
+ end
60
+
61
+ # enable selected validations
62
+ # @option options [Boolean] :include_email should the email be validated
63
+ # @option options [Boolean] :include_phone should the phone number be validated
64
+ def enable_validations( options = {} )
65
+ self.ensure_not_blank = true
66
+ self.validate_email = options[:include_email]
67
+ self.validate_phone = options[:include_phone]
68
+ end
69
+
70
+ # @param include [Array] list of extra fields to include in the address
71
+ # @return [String] Address converted to string, formatted with line breaks in the typical US style of display
72
+ # @example
73
+ # address = Address.new( name: 'Bob\s Uncle',phone: '877-555-5555', line1: 'PO Box 87',
74
+ # city: 'Nowhereville', state: 'Urgandishly' postal_code: 'ASCN 1ZZ' )
75
+ # address.to_s( :include => :phone ) #=>
76
+ # Bob's Uncle
77
+ # PO Box 87
78
+ # Nowhereville, Urgandishly ASCN 1ZZ
79
+ # 877-5550-5555
80
+ def to_s( include: [] )
81
+ ret = ""
82
+ %w{ name line1 line2 }.each{ |a| ret << self[a] + "\n" unless self[a].blank? }
83
+ ret << city.to_s
84
+ ret << ' ' + state unless state.blank?
85
+ ret << ', ' + postal_code.to_s unless postal_code.blank?
86
+ include = [ *include ]
87
+ if include.any?
88
+ ret << "\n" + include.map{ | field | self[ field ] }.join(' ')
89
+ end
90
+ ret
91
+ end
92
+
93
+
94
+ end
95
+
96
+
97
+ end # end Skr module
@@ -0,0 +1,25 @@
1
+ module Skr
2
+
3
+ module BusinessEntity
4
+
5
+ extend ActiveSupport::Concern
6
+
7
+ included do
8
+ has_random_hash_code
9
+ has_code_identifier from: 'name'
10
+
11
+ belongs_to :billing_address, class_name: 'Skr::Address', export: { writable: true }
12
+ belongs_to :shipping_address, class_name: 'Skr::Address', export: { writable: true }
13
+ belongs_to :terms, class_name: 'Skr::PaymentTerm', export: { writable: true }
14
+
15
+ delegate_and_export :terms_code, :terms_description
16
+
17
+ validates :name, presence: true
18
+ validates :terms, :billing_address, :shipping_address, set: true
19
+
20
+ before_validation :set_defaults, :on=>:create
21
+ end
22
+
23
+ end
24
+
25
+ end
@@ -0,0 +1,47 @@
1
+ module Skr
2
+ module Concerns
3
+
4
+ # @see ClassMethods
5
+ module ActsAsUOM
6
+
7
+ extend ActiveSupport::Concern
8
+
9
+ module ClassMethods
10
+ def acts_as_uom( opts = {})
11
+ include InstanceMethods
12
+
13
+ export_methods :ea_qty, :combined_uom, :optional=>false
14
+ end
15
+ end
16
+
17
+ module InstanceMethods
18
+ def combined_uom
19
+ if self.uom_size.nil? || self.uom_code.nil?
20
+ ''
21
+ elsif 1 == self.uom_size
22
+ self.uom_code
23
+ else
24
+ "#{self.uom_code}/#{self.uom_size}"
25
+ end
26
+ end
27
+
28
+ def ea_qty
29
+ self.uom_size * self.qty
30
+ end
31
+
32
+ def uom=(uom)
33
+ self.uom_size = uom.size
34
+ self.uom_code = uom.code
35
+ end
36
+
37
+ def uom
38
+ Uom.new({ size: self.uom_size, code: self.uom_code })
39
+ end
40
+
41
+ end
42
+
43
+ end
44
+
45
+ end
46
+
47
+ end
@@ -0,0 +1,30 @@
1
+ require_relative "queries"
2
+ require_relative "attr_accessor_with_default"
3
+ require_relative "json_attribute_access"
4
+ require_relative "track_modifications"
5
+ require_relative "code_identifier"
6
+ require_relative "random_hash_code"
7
+
8
+ require_relative "visible_id_identifier"
9
+ require_relative "immutable_model"
10
+ require_relative "export_scope"
11
+ require_relative "export_associations"
12
+ require_relative "export_join_tables"
13
+ require_relative "export_methods"
14
+
15
+ require_relative "locked_fields"
16
+ require_relative "json_attribute_access"
17
+ require_relative "sanitize_json"
18
+ require_relative "pub_sub"
19
+ require_relative "association_extensions"
20
+ require_relative "acts_as_uom"
21
+ require_relative "state_machine"
22
+ require_relative "has_sku_loc_lines"
23
+ require_relative "has_gl_transaction"
24
+ require_relative "is_order_like"
25
+ require_relative "is_sku_loc_line"
26
+ require_relative "sku_extensions"
27
+ require_relative "gl_tran_extensions"
28
+ require_relative "so_extensions"
29
+ require_relative "pt_extensions"
30
+ require_relative "inv_extensions"
@@ -0,0 +1,85 @@
1
+ module Skr::Concerns
2
+
3
+
4
+ # Custom implentation of has_many and belongs_to
5
+ #
6
+ module AssociationExtensions
7
+
8
+ extend ActiveSupport::Concern
9
+
10
+ module ClassMethods
11
+
12
+ def has_one(name, scope = nil, options = {})
13
+ opts = extract_private_options( scope, options )
14
+ associations = super
15
+ handle_private_options( name, opts ) unless opts.empty?
16
+ associations
17
+ end
18
+
19
+ def belongs_to(name, scope = nil, options = {} )
20
+ opts = extract_private_options( scope, options )
21
+ associations = super
22
+ handle_private_options( name, opts ) unless opts.empty?
23
+ associations
24
+ end
25
+
26
+ def has_many(name, scope=nil,options={}, &extension )
27
+ opts = extract_private_options( scope, options )
28
+ associations = super
29
+ handle_private_options( name, opts ) unless opts.empty?
30
+ associations
31
+ end
32
+
33
+ private
34
+
35
+ def handle_private_options( name, opts )
36
+ association = reflect_on_association( name.to_sym )
37
+ setup_listeners( association, opts[:listen] ) if opts[:listen]
38
+ setup_association_export( association, opts[:export] ) if opts[:export]
39
+ end
40
+
41
+ def extract_private_options( scope, options )
42
+ if scope.is_a?(Hash)
43
+ scope.extract!( :export, :listen )
44
+ else
45
+ options.extract!( :export, :listen )
46
+ end
47
+ end
48
+
49
+ # This gets complex; We
50
+ # First setup proc's for each listener,
51
+ # then attempt to load the associations's class
52
+ # If that succeds, we're done, otherwise we add it
53
+ # to PubSub's pending queue
54
+ def setup_listeners( association, listeners )
55
+ targets = {}
56
+ if listeners.any? && association.options[:inverse_of].nil?
57
+ raise RuntimeError.new "Setting listener on #{name}##{association.name} " +
58
+ "but the association does not have " +
59
+ "an inverse_of specified."
60
+ end
61
+ listeners.each do | name, target |
62
+ targets[ name ] = Proc.new{ | record, *args |
63
+ record = record.send( association.inverse_of.name )
64
+ record.send( target, *( [record] + args ) ) if record
65
+ }
66
+ end
67
+ begin
68
+ klass = association.klass # This will throw if the class hasn't been loaded yet
69
+ targets.each{ | name, proc | klass._add_event_listener( name, proc ) }
70
+ rescue NameError
71
+ pending = PendingEventListeners.all[association.class_name.demodulize]
72
+ targets.each do | name, proc |
73
+ pending[name] << proc
74
+ end
75
+ end
76
+ end
77
+
78
+ def setup_association_export( association, options )
79
+ export_associations( association.name, options == true ? {} : options )
80
+ end
81
+ end
82
+
83
+ end
84
+
85
+ end