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.
- checksums.yaml +7 -0
- data/.gitignore +18 -0
- data/Gemfile +6 -0
- data/Guardfile +13 -0
- data/LICENSE.txt +674 -0
- data/README.md +88 -0
- data/Rakefile +58 -0
- data/config/database.yml +9 -0
- data/db/migrate/20120110142845_create_skr_sequential_ids.rb +35 -0
- data/db/migrate/20140202185309_create_skr_gl_accounts.rb +15 -0
- data/db/migrate/20140202193316_create_skr_gl_periods.rb +16 -0
- data/db/migrate/20140202193318_create_skr_gl_transactions.rb +14 -0
- data/db/migrate/20140202193319_create_skr_gl_postings.rb +16 -0
- data/db/migrate/20140202193700_create_skr_gl_manual_entries.rb +13 -0
- data/db/migrate/20140213040608_create_skr_payment_terms.rb +16 -0
- data/db/migrate/20140220031700_create_skr_addresses.rb +19 -0
- data/db/migrate/20140220031800_create_skr_locations.rb +19 -0
- data/db/migrate/20140220190836_create_skr_vendors.rb +22 -0
- data/db/migrate/20140220203029_create_skr_customers.rb +22 -0
- data/db/migrate/20140224034759_create_skr_skus.rb +22 -0
- data/db/migrate/20140225032853_create_skr_sku_locs.rb +21 -0
- data/db/migrate/20140320030501_create_skr_uoms.rb +19 -0
- data/db/migrate/20140321031604_create_skr_sku_vendors.rb +18 -0
- data/db/migrate/20140322012143_create_skr_ia_reasons.rb +14 -0
- data/db/migrate/20140322014401_create_skr_inventory_adjustments.rb +16 -0
- data/db/migrate/20140322023453_create_skr_ia_lines.rb +18 -0
- data/db/migrate/20140322035024_create_skr_sku_trans.rb +21 -0
- data/db/migrate/20140322223912_create_skr_sales_orders.rb +27 -0
- data/db/migrate/20140322223920_create_skr_so_lines.rb +25 -0
- data/db/migrate/20140323001446_create_so_details_view.rb +81 -0
- data/db/migrate/20140327202102_create_skr_purchase_orders.rb +20 -0
- data/db/migrate/20140327202107_create_skr_po_lines.rb +25 -0
- data/db/migrate/20140327202207_create_skr_pick_tickets.rb +16 -0
- data/db/migrate/20140327202209_create_skr_pt_lines.rb +23 -0
- data/db/migrate/20140327224000_create_skr_invoices.rb +25 -0
- data/db/migrate/20140327224002_create_skr_inv_lines.rb +23 -0
- data/db/migrate/20140330232808_create_skr_sku_loc_details_view.rb +31 -0
- data/db/migrate/20140330232810_create_skr_sku_qty_details_view.rb +48 -0
- data/db/migrate/20140400164729_create_skr_vouchers.rb +22 -0
- data/db/migrate/20140400164733_create_skr_vo_lines.rb +21 -0
- data/db/migrate/20140401164729_create_skr_po_receipt.rb +16 -0
- data/db/migrate/20140401164740_create_skr_por_line.rb +21 -0
- data/db/migrate/20140422024010_create_skr_inv_details_view.rb +42 -0
- data/lib/generators/stockor/migrations/install_generator.rb +42 -0
- data/lib/skr/address.rb +97 -0
- data/lib/skr/business_entity.rb +25 -0
- data/lib/skr/concerns/acts_as_uom.rb +47 -0
- data/lib/skr/concerns/all.rb +30 -0
- data/lib/skr/concerns/association_extensions.rb +85 -0
- data/lib/skr/concerns/attr_accessor_with_default.rb +54 -0
- data/lib/skr/concerns/code_identifier.rb +43 -0
- data/lib/skr/concerns/export_associations.rb +52 -0
- data/lib/skr/concerns/export_join_tables.rb +39 -0
- data/lib/skr/concerns/export_methods.rb +104 -0
- data/lib/skr/concerns/export_scope.rb +66 -0
- data/lib/skr/concerns/exported_limit_evaluator.rb +17 -0
- data/lib/skr/concerns/gl_tran_extensions.rb +18 -0
- data/lib/skr/concerns/has_gl_transaction.rb +67 -0
- data/lib/skr/concerns/has_sku_loc_lines.rb +47 -0
- data/lib/skr/concerns/immutable_model.rb +32 -0
- data/lib/skr/concerns/inv_extensions.rb +24 -0
- data/lib/skr/concerns/is_order_like.rb +47 -0
- data/lib/skr/concerns/is_sku_loc_line.rb +65 -0
- data/lib/skr/concerns/json_attribute_access.rb +55 -0
- data/lib/skr/concerns/locked_fields.rb +84 -0
- data/lib/skr/concerns/pt_extensions.rb +22 -0
- data/lib/skr/concerns/pub_sub.rb +105 -0
- data/lib/skr/concerns/queries.rb +20 -0
- data/lib/skr/concerns/random_hash_code.rb +40 -0
- data/lib/skr/concerns/sanitize_json.rb +49 -0
- data/lib/skr/concerns/sku_extensions.rb +52 -0
- data/lib/skr/concerns/so_extensions.rb +30 -0
- data/lib/skr/concerns/state_machine.rb +62 -0
- data/lib/skr/concerns/track_modifications.rb +48 -0
- data/lib/skr/concerns/visible_id_identifier.rb +53 -0
- data/lib/skr/core.rb +30 -0
- data/lib/skr/core/configuration.rb +87 -0
- data/lib/skr/core/db.rb +82 -0
- data/lib/skr/core/db/migration_helpers.rb +178 -0
- data/lib/skr/core/db/migrations.rb +15 -0
- data/lib/skr/core/db/seed.rb +46 -0
- data/lib/skr/core/db/seed/chart_of_accounts.yml +168 -0
- data/lib/skr/core/db/seed/payment_terms.yml +60 -0
- data/lib/skr/core/logger.rb +36 -0
- data/lib/skr/core/numbers.rb +71 -0
- data/lib/skr/core/rails_engine.rb +5 -0
- data/lib/skr/core/standard_pricing_provider.rb +15 -0
- data/lib/skr/core/strings.rb +57 -0
- data/lib/skr/core/testing.rb +11 -0
- data/lib/skr/core/testing/assertions.rb +44 -0
- data/lib/skr/core/testing/fixtures.rb +25 -0
- data/lib/skr/core/testing/fixtures/skr/addresses.yml +53 -0
- data/lib/skr/core/testing/fixtures/skr/customers.yml +43 -0
- data/lib/skr/core/testing/fixtures/skr/gl_accounts.yml +86 -0
- data/lib/skr/core/testing/fixtures/skr/gl_manual_entries.yml +4 -0
- data/lib/skr/core/testing/fixtures/skr/gl_periods.yml +26 -0
- data/lib/skr/core/testing/fixtures/skr/gl_postings.yml +88 -0
- data/lib/skr/core/testing/fixtures/skr/gl_transactions.yml +35 -0
- data/lib/skr/core/testing/fixtures/skr/ia_lines.yml +7 -0
- data/lib/skr/core/testing/fixtures/skr/ia_reasons.yml +15 -0
- data/lib/skr/core/testing/fixtures/skr/inv_lines.yml +22 -0
- data/lib/skr/core/testing/fixtures/skr/inventory_adjustments.yml +6 -0
- data/lib/skr/core/testing/fixtures/skr/invoices.yml +10 -0
- data/lib/skr/core/testing/fixtures/skr/locations.yml +24 -0
- data/lib/skr/core/testing/fixtures/skr/payment_terms.yml +42 -0
- data/lib/skr/core/testing/fixtures/skr/pick_tickets.yml +4 -0
- data/lib/skr/core/testing/fixtures/skr/po_lines.yml +44 -0
- data/lib/skr/core/testing/fixtures/skr/po_receipts.yml +5 -0
- data/lib/skr/core/testing/fixtures/skr/por_lines.yml +13 -0
- data/lib/skr/core/testing/fixtures/skr/pt_lines.yml +12 -0
- data/lib/skr/core/testing/fixtures/skr/purchase_orders.yml +16 -0
- data/lib/skr/core/testing/fixtures/skr/sales_orders.yml +32 -0
- data/lib/skr/core/testing/fixtures/skr/sku_locs.yml +78 -0
- data/lib/skr/core/testing/fixtures/skr/sku_trans.yml +9 -0
- data/lib/skr/core/testing/fixtures/skr/sku_vendors.yml +35 -0
- data/lib/skr/core/testing/fixtures/skr/skus.yml +50 -0
- data/lib/skr/core/testing/fixtures/skr/so_lines.yml +71 -0
- data/lib/skr/core/testing/fixtures/skr/uoms.yml +61 -0
- data/lib/skr/core/testing/fixtures/skr/vendors.yml +48 -0
- data/lib/skr/core/testing/fixtures/skr/vo_lines.yml +12 -0
- data/lib/skr/core/testing/fixtures/skr/vouchers.yml +8 -0
- data/lib/skr/core/testing/helper.rb +18 -0
- data/lib/skr/core/testing/test_case.rb +17 -0
- data/lib/skr/core/version.rb +5 -0
- data/lib/skr/customer.rb +34 -0
- data/lib/skr/gl_account.rb +56 -0
- data/lib/skr/gl_manual_entry.rb +31 -0
- data/lib/skr/gl_period.rb +13 -0
- data/lib/skr/gl_posting.rb +54 -0
- data/lib/skr/gl_transaction.rb +174 -0
- data/lib/skr/ia_line.rb +129 -0
- data/lib/skr/ia_reason.rb +16 -0
- data/lib/skr/inv_line.rb +90 -0
- data/lib/skr/inventory_adjustment.rb +60 -0
- data/lib/skr/invoice.rb +159 -0
- data/lib/skr/location.rb +31 -0
- data/lib/skr/model.rb +37 -0
- data/lib/skr/null_user.rb +30 -0
- data/lib/skr/payment_term.rb +30 -0
- data/lib/skr/pick_ticket.rb +71 -0
- data/lib/skr/po_line.rb +69 -0
- data/lib/skr/po_receipt.rb +51 -0
- data/lib/skr/por_line.rb +80 -0
- data/lib/skr/pt_line.rb +74 -0
- data/lib/skr/purchase_order.rb +112 -0
- data/lib/skr/sales_order.rb +159 -0
- data/lib/skr/sequential_id.rb +23 -0
- data/lib/skr/sku.rb +99 -0
- data/lib/skr/sku_loc.rb +94 -0
- data/lib/skr/sku_tran.rb +111 -0
- data/lib/skr/sku_vendor.rb +26 -0
- data/lib/skr/so_line.rb +159 -0
- data/lib/skr/uom.rb +63 -0
- data/lib/skr/user_proxy.rb +60 -0
- data/lib/skr/validators/all.rb +2 -0
- data/lib/skr/validators/email.rb +17 -0
- data/lib/skr/validators/set.rb +18 -0
- data/lib/skr/vendor.rb +33 -0
- data/lib/skr/vo_line.rb +35 -0
- data/lib/skr/voucher.rb +119 -0
- data/lib/stockor/core.rb +9 -0
- data/stockor-core.gemspec +37 -0
- data/tasks/migrations.rake +23 -0
- data/tasks/publish.rake +8 -0
- data/test/address_test.rb +57 -0
- data/test/concerns/attr_with_default_test.rb +45 -0
- data/test/concerns/code_identifier_test.rb +46 -0
- data/test/concerns/export_associations_test.rb +7 -0
- data/test/concerns/export_methods_test.rb +31 -0
- data/test/concerns/export_scope_test.rb +16 -0
- data/test/concerns/exported_limits_test.rb +47 -0
- data/test/concerns/json_attribute_access_test.rb +27 -0
- data/test/concerns/pub_sub_test.rb +83 -0
- data/test/concerns/sanitize_json_test.rb +47 -0
- data/test/core/configuration_test.rb +24 -0
- data/test/core/numbers_test.rb +26 -0
- data/test/core/strings_test.rb +41 -0
- data/test/customer_test.rb +34 -0
- data/test/gl_account_test.rb +23 -0
- data/test/gl_manual_entry_test.rb +17 -0
- data/test/gl_period_test.rb +12 -0
- data/test/gl_posting_test.rb +39 -0
- data/test/gl_transaction_test.rb +58 -0
- data/test/ia_line_test.rb +68 -0
- data/test/ia_reason_test.rb +11 -0
- data/test/inv_line_test.rb +58 -0
- data/test/inventory_adjustment_test.rb +72 -0
- data/test/invoice_test.rb +63 -0
- data/test/location_test.rb +10 -0
- data/test/payment_term_test.rb +25 -0
- data/test/pick_ticket_test.rb +27 -0
- data/test/po_line_test.rb +36 -0
- data/test/po_receipt_test.rb +93 -0
- data/test/por_line_test.rb +79 -0
- data/test/pt_line_test.rb +29 -0
- data/test/purchase_order_test.rb +44 -0
- data/test/sales_order_test.rb +74 -0
- data/test/sku_loc_test.rb +50 -0
- data/test/sku_test.rb +45 -0
- data/test/sku_tran_test.rb +21 -0
- data/test/sku_vendor_test.rb +13 -0
- data/test/so_line_test.rb +89 -0
- data/test/test_helper.rb +1 -0
- data/test/uom_test.rb +14 -0
- data/test/vendor_test.rb +35 -0
- data/test/vo_line_test.rb +20 -0
- data/test/voucher_test.rb +35 -0
- data/yard_ext/all.rb +9 -0
- data/yard_ext/code_identifier_handler.rb +33 -0
- data/yard_ext/concern_meta_methods.rb +60 -0
- data/yard_ext/config_options.rb +27 -0
- data/yard_ext/exported_scope.rb +4 -0
- data/yard_ext/immutable_handler.rb +17 -0
- data/yard_ext/json_attr_accessor.rb +22 -0
- data/yard_ext/locked_fields_handler.rb +21 -0
- data/yard_ext/templates/default/layout/html/layout.erb +20 -0
- data/yard_ext/templates/default/method_details/html/github_link.erb +1 -0
- data/yard_ext/templates/default/method_details/setup.rb +3 -0
- data/yard_ext/validators.rb +1 -0
- data/yard_ext/visible_id_handler.rb +38 -0
- metadata +448 -0
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
module Skr
|
|
2
|
+
module Concerns
|
|
3
|
+
|
|
4
|
+
# A collection of handly utility methods to generate queries
|
|
5
|
+
module Queries
|
|
6
|
+
|
|
7
|
+
extend ActiveSupport::Concern
|
|
8
|
+
|
|
9
|
+
module ClassMethods
|
|
10
|
+
|
|
11
|
+
def compose_query_using_detail_view( view: view, join_to: join_to )
|
|
12
|
+
view = Skr::Core.config.table_prefix + view.to_s
|
|
13
|
+
joins("join #{view} as details on details.#{join_to} = #{table_name}.#{primary_key}")
|
|
14
|
+
.select("#{table_name}.*, details.*")
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
end
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
module Skr
|
|
2
|
+
module Concerns
|
|
3
|
+
|
|
4
|
+
# @see ClassMethods
|
|
5
|
+
module RandomHashCode
|
|
6
|
+
|
|
7
|
+
extend ActiveSupport::Concern
|
|
8
|
+
|
|
9
|
+
# ### Random Hash Code Concern
|
|
10
|
+
# This adds the {#has_random_hash_code} class method
|
|
11
|
+
module ClassMethods
|
|
12
|
+
|
|
13
|
+
# A random string that identifies an entity, such as a Customer, or Vendor
|
|
14
|
+
# The code is generated by {Skr::Core::Strings.random} for new records
|
|
15
|
+
# It's useful for generating *magic* links for access to an entity that cannot be guessed.
|
|
16
|
+
# @param field_name [Symbol] which field should the hash_code be stored in
|
|
17
|
+
# @param length [Integer] how long the hash_code should be
|
|
18
|
+
|
|
19
|
+
def has_random_hash_code( field_name: :hash_code, length: 12 )
|
|
20
|
+
|
|
21
|
+
validates field_name, :presence=>{
|
|
22
|
+
:message=>"hash code is not set (should be automatically chosen)"
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
scope :with_hash_code, lambda{ | code |
|
|
26
|
+
where({ :hash_code=>code })
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
before_validation(:on=>:create) do
|
|
30
|
+
self[ field_name ] = Skr::Core::Strings.random( length ) if self[ field_name ].blank?
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
end
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
module Skr
|
|
2
|
+
module Concerns
|
|
3
|
+
|
|
4
|
+
module SanitizeJson
|
|
5
|
+
extend ActiveSupport::Concern
|
|
6
|
+
|
|
7
|
+
# SanitizeJson is where all the exports_XXX concerns come together. It's responsible for only allowing
|
|
8
|
+
# associations and other data to be saved that have been marked as safe.
|
|
9
|
+
module ClassMethods
|
|
10
|
+
|
|
11
|
+
# Takes in a hash containing attribute name/value pairs, as well as sub hashes/arrays.
|
|
12
|
+
# It returns only the attributes that have been marked as exportable
|
|
13
|
+
# @param json [Hash]
|
|
14
|
+
# @param user [UserProxy,User] who is performing request
|
|
15
|
+
def sanitize_json(json, user = Skr::UserProxy.current)
|
|
16
|
+
return {} unless user.can_write?(self)
|
|
17
|
+
json.each_with_object(Hash.new) do | kv, result |
|
|
18
|
+
( key, value ) = kv
|
|
19
|
+
|
|
20
|
+
if json_attribute_is_allowed?( key.to_sym, user )
|
|
21
|
+
result[ key ] = value
|
|
22
|
+
else
|
|
23
|
+
# allow nested params to be specified using Rails _attributes
|
|
24
|
+
name = key.to_s.gsub(/_attributes$/,'')
|
|
25
|
+
|
|
26
|
+
next unless has_exported_nested_attribute?( name, user )
|
|
27
|
+
|
|
28
|
+
klass_name = self.reflections[ name.to_sym ].class_name
|
|
29
|
+
klass = klass_name.safe_constantize || "Skr::#{klass_name}".constantize
|
|
30
|
+
|
|
31
|
+
# only Hash, Array & nil is valid for nesting attributes
|
|
32
|
+
cleaned = case value
|
|
33
|
+
when Hash then klass.sanitize_json( value, user )
|
|
34
|
+
when Array then value.map{ | nested | klass.sanitize_json( nested, user ) }
|
|
35
|
+
else
|
|
36
|
+
nil
|
|
37
|
+
end
|
|
38
|
+
result[ (name + '_attributes').to_sym ] = cleaned unless cleaned.blank?
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
end
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
module Skr
|
|
2
|
+
module Concerns
|
|
3
|
+
|
|
4
|
+
module Sku
|
|
5
|
+
|
|
6
|
+
module Locations
|
|
7
|
+
# Attempt to find a {SkuLoc} record and create it if not found
|
|
8
|
+
def find_or_create_for( location )
|
|
9
|
+
location_id = location.is_a?(Numeric) ? location : location.id
|
|
10
|
+
for_location(location) || create!({ :location_id=>location_id })
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def for_location( location )
|
|
14
|
+
location_id = location.is_a?(Numeric) ? location : location.id
|
|
15
|
+
detect{ |l| l.location_id==location_id }
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def default
|
|
19
|
+
loc_id = Location.default.id
|
|
20
|
+
detect{ |sl| sl.location_id == loc_id }
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
module Vendors
|
|
25
|
+
def default
|
|
26
|
+
vendid = self.proxy_association.owner.default_vendor_id
|
|
27
|
+
detect{ |sv| sv.vendor_id == vendid }
|
|
28
|
+
end
|
|
29
|
+
def for_vendor( vendor )
|
|
30
|
+
vendor_id = vendor.is_a?(Numeric) ? vendor : vendor.id
|
|
31
|
+
detect{ |v| v.vendor_id==vendor_id }
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
module Uoms
|
|
36
|
+
def default
|
|
37
|
+
code = self.proxy_association.owner.default_uom_code
|
|
38
|
+
with_code( code )
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
# Return the uom with code. Since the UOM's are probably already loaded
|
|
42
|
+
# for the SKU, it makes sense to search over the in-memory collection
|
|
43
|
+
# vs hitting the DB again.
|
|
44
|
+
def with_code( code )
|
|
45
|
+
detect{|uom| uom.code == code }
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
end
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
end
|
|
52
|
+
end
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
module Skr
|
|
2
|
+
module Concerns
|
|
3
|
+
|
|
4
|
+
module SO
|
|
5
|
+
|
|
6
|
+
module Lines
|
|
7
|
+
|
|
8
|
+
def set_ship_qty
|
|
9
|
+
each{|l| l.qty_to_ship = l.qty }
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
def eq_qty
|
|
13
|
+
if proxy_association.loaded?
|
|
14
|
+
inject(0){ | sum, sol | sum + (sol.eq_qty*uom_size) }
|
|
15
|
+
else
|
|
16
|
+
sum('qty*uom_size')
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
def eq_qty_allocated
|
|
21
|
+
if proxy_association.loaded?
|
|
22
|
+
inject(0){ | sum, sol | sum + (sol.qty_allocated * uom_size) }
|
|
23
|
+
else
|
|
24
|
+
sum('qty_allocated*uom_size')
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
end
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
require 'aasm' # Acts As State Machine
|
|
2
|
+
|
|
3
|
+
module Skr
|
|
4
|
+
module Concerns
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
# Models that use the {https://github.com/aasm/aasm}
|
|
8
|
+
# gem to track object state
|
|
9
|
+
module StateMachine
|
|
10
|
+
|
|
11
|
+
extend ActiveSupport::Concern
|
|
12
|
+
|
|
13
|
+
module ClassMethods
|
|
14
|
+
|
|
15
|
+
# Mark class as a StateMachine {https://github.com/aasm/aasm}
|
|
16
|
+
#
|
|
17
|
+
# Specifically it:
|
|
18
|
+
#
|
|
19
|
+
# * Adds the methods in {InstanceMethods} to the class
|
|
20
|
+
# * Blacklists the "state" field so it cannot be set via the API
|
|
21
|
+
# * Allows access to the "state_event" pseudo field from the API
|
|
22
|
+
# * Sets up the aasm library with the contents of &block
|
|
23
|
+
def state_machine( options={}, &block )
|
|
24
|
+
include InstanceMethods
|
|
25
|
+
include AASM
|
|
26
|
+
aasm( options.merge( column: 'state' ), &block )
|
|
27
|
+
|
|
28
|
+
json_attr_accessor :state_event
|
|
29
|
+
|
|
30
|
+
export_methods :valid_state_events, :optional=>false
|
|
31
|
+
blacklist_json_attributes :state
|
|
32
|
+
whitelist_json_attributes :state_event
|
|
33
|
+
|
|
34
|
+
before_save :fire_state_machine_event_on_save
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
module InstanceMethods
|
|
40
|
+
|
|
41
|
+
def fire_state_machine_event_on_save
|
|
42
|
+
return unless state_event.present?
|
|
43
|
+
event_name = state_event.to_sym
|
|
44
|
+
if valid_state_events.include?( event_name )
|
|
45
|
+
self.send( :aasm_fire_event, event_name, {:persist=>false} )
|
|
46
|
+
else
|
|
47
|
+
errors.add(:state_event, "is not valid")
|
|
48
|
+
false
|
|
49
|
+
end
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
# @return [Array of symbols] the available state_transistions
|
|
53
|
+
def valid_state_events
|
|
54
|
+
aasm.events
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
end
|
|
62
|
+
end
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
module Skr::Concerns
|
|
2
|
+
|
|
3
|
+
# Extends Rails updated_by and created_by timestamps to also track who created and updated the model.
|
|
4
|
+
# It reads the current user from UserProxy.current_id when saving and updating the record
|
|
5
|
+
# The class_name for the created_by and updated_by is set to {Skr::Core::Configuration#user_model}
|
|
6
|
+
module TrackModifications
|
|
7
|
+
extend ActiveSupport::Concern
|
|
8
|
+
|
|
9
|
+
included do
|
|
10
|
+
class_attribute :record_modifications, :instance_writer=>false
|
|
11
|
+
self.record_modifications = true
|
|
12
|
+
|
|
13
|
+
belongs_to :created_by, :class_name=>Skr::Core.config.user_model
|
|
14
|
+
belongs_to :updated_by, :class_name=>Skr::Core.config.user_model
|
|
15
|
+
|
|
16
|
+
self.blacklist_json_attributes :created_at, :updated_at, :created_by_id, :updated_by_id
|
|
17
|
+
before_update :record_update_modifications
|
|
18
|
+
before_create :record_create_modifications
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
private
|
|
22
|
+
|
|
23
|
+
def _record_user_to_column( column )
|
|
24
|
+
user_id = Skr::UserProxy.current_id ? Skr::UserProxy.current_id : 0
|
|
25
|
+
write_attribute( column, user_id ) if self.class.column_names.include?( column )
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
def record_create_modifications
|
|
29
|
+
if self.record_modifications
|
|
30
|
+
_record_user_to_column('updated_by_id')
|
|
31
|
+
_record_user_to_column('created_by_id')
|
|
32
|
+
end
|
|
33
|
+
true
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
def record_update_modifications
|
|
37
|
+
if self.record_modifications && should_record_timestamps?
|
|
38
|
+
_record_user_to_column('updated_by_id')
|
|
39
|
+
end
|
|
40
|
+
true
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
def change_tracking_fields
|
|
44
|
+
%w{updated_by_id created_by_id updated_at created_at}
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
end
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
module Skr
|
|
2
|
+
module Concerns
|
|
3
|
+
|
|
4
|
+
# @see ClassMethods
|
|
5
|
+
module VisibleIdIdentifier
|
|
6
|
+
|
|
7
|
+
extend ActiveSupport::Concern
|
|
8
|
+
|
|
9
|
+
module InstanceMethods
|
|
10
|
+
|
|
11
|
+
# setup the visible id to the next available #{Skr::SequentialId}
|
|
12
|
+
# @return [Integer] the assigned ID
|
|
13
|
+
def assign_visible_id!
|
|
14
|
+
self.visible_id = Skr::SequentialId.next_for( self.class )
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
# ### Visible ID Identifier Concern
|
|
20
|
+
# This adds the {#has_visible_id} class methods
|
|
21
|
+
module ClassMethods
|
|
22
|
+
|
|
23
|
+
# An auto-incrementing number that's user-visible.
|
|
24
|
+
# The visible_id is stored as an integer, but a string index is generated for
|
|
25
|
+
# querying by the sql like operator. The **with_visible_id** scope is available for this purpose
|
|
26
|
+
#
|
|
27
|
+
# The next number an also be adjusted by the end-user by setting {Skr::SequentialId}
|
|
28
|
+
# so they can set the numbers to start at
|
|
29
|
+
# a specific point, which is useful for getting Invoice and other
|
|
30
|
+
# numbers to match up to a legacy system
|
|
31
|
+
def has_visible_id
|
|
32
|
+
include InstanceMethods
|
|
33
|
+
validates :visible_id, :presence=>{
|
|
34
|
+
:message=>"ID was not set (should be automatically chosen)"
|
|
35
|
+
}
|
|
36
|
+
alias_attribute :record_identifier, :visible_id
|
|
37
|
+
before_validation :assign_visible_id!, :on=>:create
|
|
38
|
+
|
|
39
|
+
export_scope :with_visible_id, lambda{ | visid |
|
|
40
|
+
if visid.to_s =~/%/
|
|
41
|
+
where( 'cast(visible_id as varchar) like ?', visid.to_s )
|
|
42
|
+
else
|
|
43
|
+
where( 'cast(visible_id as varchar) = ?', visid.to_s )
|
|
44
|
+
end
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
end
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
end
|
|
53
|
+
end
|
data/lib/skr/core.rb
ADDED
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
require 'active_record'
|
|
2
|
+
|
|
3
|
+
module Skr
|
|
4
|
+
module Core
|
|
5
|
+
end
|
|
6
|
+
module Concerns
|
|
7
|
+
end
|
|
8
|
+
module Validators
|
|
9
|
+
end
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
require_relative "core/version"
|
|
13
|
+
require_relative "core/logger"
|
|
14
|
+
require_relative "core/testing"
|
|
15
|
+
require_relative "core/standard_pricing_provider"
|
|
16
|
+
require_relative "core/configuration"
|
|
17
|
+
if defined?(::Rails)
|
|
18
|
+
require_relative "core/rails_engine"
|
|
19
|
+
end
|
|
20
|
+
require_relative "core/db"
|
|
21
|
+
require_relative "core/strings"
|
|
22
|
+
require_relative "core/numbers"
|
|
23
|
+
require_relative "concerns/all"
|
|
24
|
+
require_relative "validators/all"
|
|
25
|
+
require_relative "model"
|
|
26
|
+
require_relative "user_proxy"
|
|
27
|
+
require_relative "sequential_id"
|
|
28
|
+
|
|
29
|
+
require 'require_all'
|
|
30
|
+
require_rel '*.rb'
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
require_relative "../concerns/attr_accessor_with_default"
|
|
2
|
+
require_relative "standard_pricing_provider"
|
|
3
|
+
|
|
4
|
+
module Skr
|
|
5
|
+
module Core
|
|
6
|
+
|
|
7
|
+
class Configuration
|
|
8
|
+
include Skr::Concerns::AttrAccessorWithDefault
|
|
9
|
+
# Since changing a config value inadvertently
|
|
10
|
+
# can have pretty drastic consequences that might not be
|
|
11
|
+
# discovered immediately, we log each time a value is changed
|
|
12
|
+
def self.config_option( name, default )
|
|
13
|
+
define_method( "#{name}=" ) do | value |
|
|
14
|
+
old_value = self.send( name )
|
|
15
|
+
if old_value.is_a?(String) && Skr::Core.logger
|
|
16
|
+
Skr::Core.logger.info "Config option #{name} changed from #{old_value} to #{value}"
|
|
17
|
+
end
|
|
18
|
+
instance_variable_set( "@#{name}", value )
|
|
19
|
+
end
|
|
20
|
+
attr_reader_with_default( name, default )
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
class DefaultConfiguration < Configuration
|
|
25
|
+
|
|
26
|
+
# Since the Configuration class is essentially a singleton,
|
|
27
|
+
# we don't care about AttrReaderWithDefault sharing values between instances
|
|
28
|
+
# Therefore all the values are given directly and not enclosed in Procs/lambdas.
|
|
29
|
+
|
|
30
|
+
# Database tables will have this prefix applied to them
|
|
31
|
+
config_option :table_prefix, 'skr_'
|
|
32
|
+
|
|
33
|
+
# The GL branch code to use for default newly created locations
|
|
34
|
+
config_option :default_branch_code, '01'
|
|
35
|
+
|
|
36
|
+
# The string value of the UserModel. Will be set on model's updated_by and created_by
|
|
37
|
+
config_option :user_model, 'UserProxy'
|
|
38
|
+
|
|
39
|
+
# Transactions that do not specify a location will use the one that's identified by this code
|
|
40
|
+
config_option :default_location_code, 'DEFAULT'
|
|
41
|
+
|
|
42
|
+
# Do freshly created SKUs default to being backorderable?
|
|
43
|
+
config_option :skus_backorder_default, true
|
|
44
|
+
|
|
45
|
+
# The code for a Sku that represents tax
|
|
46
|
+
config_option :tax_sku_code, 'TAX'
|
|
47
|
+
|
|
48
|
+
# Code for a Sku that represents shipping charges
|
|
49
|
+
config_option :ship_sku_code, 'SHIP'
|
|
50
|
+
|
|
51
|
+
# Code for a PaymentTerm that will be used as the default for new Customers
|
|
52
|
+
config_option :customer_terms_code, 'CASH'
|
|
53
|
+
|
|
54
|
+
# Code for a PaymentTerm that will be used as the default for new Vendors
|
|
55
|
+
config_option :vendor_terms_code, 'CASH'
|
|
56
|
+
|
|
57
|
+
config_option :default_gl_accounts, {
|
|
58
|
+
# The Accounts Receivable (AR) GL account number to use for freshly created Customers
|
|
59
|
+
ar: '1200',
|
|
60
|
+
# The Accounts Payable (AP) GL account number to use for freshly created Vendors
|
|
61
|
+
ap: '2200',
|
|
62
|
+
# The Freight GL account number to use for freshly created Vendors
|
|
63
|
+
freight: '6420',
|
|
64
|
+
# The Asset GL account number to use for freshly created SKUs
|
|
65
|
+
asset: '1100',
|
|
66
|
+
# Clearing account for inventory that's been
|
|
67
|
+
inventory_receipts_clearing: '2600',
|
|
68
|
+
# Holding account for funds that are awaiting deposit
|
|
69
|
+
deposit_holding: '1010'
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
config_option :pricing_provider, Skr::Core::StandardPricingProvider
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
class << self
|
|
76
|
+
@@config = DefaultConfiguration.new
|
|
77
|
+
def config
|
|
78
|
+
@@config
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
def configure
|
|
82
|
+
yield(@@config)
|
|
83
|
+
end
|
|
84
|
+
end
|
|
85
|
+
|
|
86
|
+
end
|
|
87
|
+
end
|