stockor 0.1.5
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 +4 -0
- data/Gemfile +11 -0
- data/Gemfile.lock +220 -0
- data/Guardfile +13 -0
- data/README.md +7 -0
- data/Rakefile +7 -0
- data/client/skr/Extension.coffee +12 -0
- data/client/skr/components/.gitkeep +0 -0
- data/client/skr/components/address/Address.coffee +21 -0
- data/client/skr/components/address/address.html +20 -0
- data/client/skr/index.js +21 -0
- data/client/skr/models/Address.coffee +17 -0
- data/client/skr/models/Base.coffee +8 -0
- data/client/skr/models/Customer.coffee +26 -0
- data/client/skr/models/GlAccount.coffee +10 -0
- data/client/skr/models/GlManualEntry.coffee +11 -0
- data/client/skr/models/GlPeriod.coffee +10 -0
- data/client/skr/models/GlPosting.coffee +15 -0
- data/client/skr/models/GlTransaction.coffee +16 -0
- data/client/skr/models/IaLine.coffee +19 -0
- data/client/skr/models/IaReason.coffee +12 -0
- data/client/skr/models/InvLine.coffee +27 -0
- data/client/skr/models/InventoryAdjustment.coffee +17 -0
- data/client/skr/models/Invoice.coffee +31 -0
- data/client/skr/models/Location.coffee +15 -0
- data/client/skr/models/PaymentTerm.coffee +11 -0
- data/client/skr/models/PickTicket.coffee +19 -0
- data/client/skr/models/PoLine.coffee +27 -0
- data/client/skr/models/PoReceipt.coffee +20 -0
- data/client/skr/models/PorLine.coffee +26 -0
- data/client/skr/models/PtLine.coffee +27 -0
- data/client/skr/models/PurchaseOrder.coffee +23 -0
- data/client/skr/models/SalesOrder.coffee +32 -0
- data/client/skr/models/Sku.coffee +21 -0
- data/client/skr/models/SkuLoc.coffee +21 -0
- data/client/skr/models/SkuTran.coffee +23 -0
- data/client/skr/models/SkuVendor.coffee +19 -0
- data/client/skr/models/SoLine.coffee +27 -0
- data/client/skr/models/Uom.coffee +17 -0
- data/client/skr/models/Vendor.coffee +28 -0
- data/client/skr/models/VoLine.coffee +23 -0
- data/client/skr/models/Voucher.coffee +22 -0
- data/client/skr/models/mixins/CodeField.coffee +5 -0
- data/client/skr/screens/.gitkeep +0 -0
- data/client/skr/screens/Base.coffee +3 -0
- data/client/skr/screens/base/index.js +5 -0
- data/client/skr/screens/base/index.scss +9 -0
- data/client/skr/screens/base/layout.html +3 -0
- data/client/skr/screens/customer-maint/CustomerMaint.coffee +49 -0
- data/client/skr/screens/customer-maint/index.js +5 -0
- data/client/skr/screens/customer-maint/index.scss +9 -0
- data/client/skr/screens/customer-maint/layout.html +32 -0
- data/client/skr/styles.scss +1 -0
- data/client/skr/views/.gitkeep +0 -0
- data/client/skr/views/Base.coffee +5 -0
- data/config/database.yml +9 -0
- data/config/lanes.rb +7 -0
- data/config/routes.rb +39 -0
- data/config/screens.rb +17 -0
- data/config.ru +5 -0
- data/db/.gitkeep +0 -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/db/schema.sql +2662 -0
- data/db/seed/chart_of_accounts.yml +168 -0
- data/db/seed/payment_terms.yml +60 -0
- data/db/seed.rb +29 -0
- data/lib/skr/access_roles.rb +28 -0
- data/lib/skr/concerns/acts_as_uom.rb +47 -0
- data/lib/skr/concerns/code_identifier.rb +43 -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/locked_fields.rb +84 -0
- data/lib/skr/concerns/pt_extensions.rb +22 -0
- data/lib/skr/concerns/random_hash_code.rb +40 -0
- data/lib/skr/concerns/so_extensions.rb +30 -0
- data/lib/skr/concerns/state_machine.rb +61 -0
- data/lib/skr/concerns/visible_id_identifier.rb +53 -0
- data/lib/skr/configuration.rb +68 -0
- data/lib/skr/db/migration_helpers.rb +178 -0
- data/lib/skr/extension.rb +23 -0
- data/lib/skr/model.rb +19 -0
- data/lib/skr/models/address.rb +97 -0
- data/lib/skr/models/business_entity.rb +29 -0
- data/lib/skr/models/customer.rb +35 -0
- data/lib/skr/models/gl_account.rb +56 -0
- data/lib/skr/models/gl_manual_entry.rb +31 -0
- data/lib/skr/models/gl_period.rb +13 -0
- data/lib/skr/models/gl_posting.rb +54 -0
- data/lib/skr/models/gl_transaction.rb +175 -0
- data/lib/skr/models/ia_line.rb +129 -0
- data/lib/skr/models/ia_reason.rb +16 -0
- data/lib/skr/models/inv_line.rb +90 -0
- data/lib/skr/models/inventory_adjustment.rb +60 -0
- data/lib/skr/models/invoice.rb +159 -0
- data/lib/skr/models/location.rb +31 -0
- data/lib/skr/models/payment_term.rb +30 -0
- data/lib/skr/models/pick_ticket.rb +71 -0
- data/lib/skr/models/po_line.rb +69 -0
- data/lib/skr/models/po_receipt.rb +51 -0
- data/lib/skr/models/por_line.rb +80 -0
- data/lib/skr/models/pt_line.rb +74 -0
- data/lib/skr/models/purchase_order.rb +112 -0
- data/lib/skr/models/sales_order.rb +159 -0
- data/lib/skr/models/sequential_id.rb +23 -0
- data/lib/skr/models/sku.rb +99 -0
- data/lib/skr/models/sku_loc.rb +94 -0
- data/lib/skr/models/sku_tran.rb +111 -0
- data/lib/skr/models/sku_vendor.rb +26 -0
- data/lib/skr/models/so_line.rb +159 -0
- data/lib/skr/models/uom.rb +63 -0
- data/lib/skr/models/user_proxy.rb +60 -0
- data/lib/skr/models/vendor.rb +33 -0
- data/lib/skr/models/vo_line.rb +35 -0
- data/lib/skr/models/voucher.rb +119 -0
- data/lib/skr/standard_pricing_provider.rb +14 -0
- data/lib/skr/version.rb +3 -0
- data/lib/skr.rb +18 -0
- data/lib/stockor.rb +4 -0
- data/lib/tasks/debug-activity.rake +58 -0
- data/log/test.log +0 -0
- data/spec/fixtures/skr/address.yml +2 -0
- data/spec/fixtures/skr/customer.yml +2 -0
- data/spec/fixtures/skr/gl_account.yml +2 -0
- data/spec/fixtures/skr/gl_manual_entry.yml +2 -0
- data/spec/fixtures/skr/gl_period.yml +2 -0
- data/spec/fixtures/skr/gl_posting.yml +2 -0
- data/spec/fixtures/skr/gl_transaction.yml +2 -0
- data/spec/fixtures/skr/ia_line.yml +2 -0
- data/spec/fixtures/skr/ia_reason.yml +2 -0
- data/spec/fixtures/skr/inv_line.yml +2 -0
- data/spec/fixtures/skr/inventory_adjustment.yml +2 -0
- data/spec/fixtures/skr/invoice.yml +2 -0
- data/spec/fixtures/skr/location.yml +2 -0
- data/spec/fixtures/skr/payment_term.yml +2 -0
- data/spec/fixtures/skr/pick_ticket.yml +2 -0
- data/spec/fixtures/skr/po_line.yml +2 -0
- data/spec/fixtures/skr/po_receipt.yml +2 -0
- data/spec/fixtures/skr/por_line.yml +2 -0
- data/spec/fixtures/skr/pt_line.yml +2 -0
- data/spec/fixtures/skr/purchase_order.yml +2 -0
- data/spec/fixtures/skr/sales_order.yml +2 -0
- data/spec/fixtures/skr/sku.yml +2 -0
- data/spec/fixtures/skr/sku_loc.yml +2 -0
- data/spec/fixtures/skr/sku_tran.yml +2 -0
- data/spec/fixtures/skr/sku_vendor.yml +2 -0
- data/spec/fixtures/skr/so_line.yml +2 -0
- data/spec/fixtures/skr/uom.yml +2 -0
- data/spec/fixtures/skr/vendor.yml +2 -0
- data/spec/fixtures/skr/vo_line.yml +2 -0
- data/spec/fixtures/skr/voucher.yml +2 -0
- data/spec/skr/address.rb +10 -0
- data/spec/skr/concerns/code_identifier_spec.rb +45 -0
- data/spec/skr/customer.rb +10 -0
- data/spec/skr/gl_account.rb +10 -0
- data/spec/skr/gl_manual_entry.rb +10 -0
- data/spec/skr/gl_period.rb +10 -0
- data/spec/skr/gl_posting.rb +10 -0
- data/spec/skr/gl_transaction.rb +10 -0
- data/spec/skr/ia_line.rb +10 -0
- data/spec/skr/ia_reason.rb +10 -0
- data/spec/skr/inv_line.rb +10 -0
- data/spec/skr/inventory_adjustment.rb +10 -0
- data/spec/skr/invoice.rb +10 -0
- data/spec/skr/location.rb +10 -0
- data/spec/skr/models/AddressSpec.coffee +5 -0
- data/spec/skr/models/CustomerSpec.coffee +5 -0
- data/spec/skr/models/GlAccountSpec.coffee +5 -0
- data/spec/skr/models/GlManualEntrySpec.coffee +5 -0
- data/spec/skr/models/GlPeriodSpec.coffee +5 -0
- data/spec/skr/models/GlPostingSpec.coffee +5 -0
- data/spec/skr/models/GlTransactionSpec.coffee +5 -0
- data/spec/skr/models/IaLineSpec.coffee +5 -0
- data/spec/skr/models/IaReasonSpec.coffee +5 -0
- data/spec/skr/models/InvLineSpec.coffee +5 -0
- data/spec/skr/models/InventoryAdjustmentSpec.coffee +5 -0
- data/spec/skr/models/InvoiceSpec.coffee +5 -0
- data/spec/skr/models/LocationSpec.coffee +5 -0
- data/spec/skr/models/PaymentTermSpec.coffee +5 -0
- data/spec/skr/models/PickTicketSpec.coffee +5 -0
- data/spec/skr/models/PoLineSpec.coffee +5 -0
- data/spec/skr/models/PoReceiptSpec.coffee +5 -0
- data/spec/skr/models/PorLineSpec.coffee +5 -0
- data/spec/skr/models/PtLineSpec.coffee +5 -0
- data/spec/skr/models/PurchaseOrderSpec.coffee +5 -0
- data/spec/skr/models/SalesOrderSpec.coffee +5 -0
- data/spec/skr/models/SkuLocSpec.coffee +5 -0
- data/spec/skr/models/SkuSpec.coffee +5 -0
- data/spec/skr/models/SkuTranSpec.coffee +5 -0
- data/spec/skr/models/SkuVendorSpec.coffee +5 -0
- data/spec/skr/models/SoLineSpec.coffee +5 -0
- data/spec/skr/models/UomSpec.coffee +5 -0
- data/spec/skr/models/VendorSpec.coffee +5 -0
- data/spec/skr/models/VoLineSpec.coffee +5 -0
- data/spec/skr/models/VoucherSpec.coffee +5 -0
- data/spec/skr/payment_term.rb +10 -0
- data/spec/skr/pick_ticket.rb +10 -0
- data/spec/skr/po_line.rb +10 -0
- data/spec/skr/po_receipt.rb +10 -0
- data/spec/skr/por_line.rb +10 -0
- data/spec/skr/pt_line.rb +10 -0
- data/spec/skr/purchase_order.rb +10 -0
- data/spec/skr/sales_order.rb +10 -0
- data/spec/skr/screens/Base.coffee +7 -0
- data/spec/skr/screens/CustomerMaint.coffee +7 -0
- data/spec/skr/screens/vendor-maint/VendorMaintSpec.coffee +5 -0
- data/spec/skr/sku.rb +10 -0
- data/spec/skr/sku_loc.rb +10 -0
- data/spec/skr/sku_tran.rb +10 -0
- data/spec/skr/sku_vendor.rb +10 -0
- data/spec/skr/so_line.rb +10 -0
- data/spec/skr/spec_helper.rb +26 -0
- data/spec/skr/uom.rb +10 -0
- data/spec/skr/vendor.rb +10 -0
- data/spec/skr/views/AddressSpec.coffee +5 -0
- data/spec/skr/vo_line.rb +10 -0
- data/spec/skr/voucher.rb +10 -0
- data/stockor.gemspec +38 -0
- data/tmp/.gitkeep +0 -0
- metadata +414 -0
|
@@ -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,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(Skr.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
|
+
validates :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,14 @@
|
|
|
1
|
+
module Skr
|
|
2
|
+
|
|
3
|
+
class StandardPricingProvider
|
|
4
|
+
|
|
5
|
+
# The default implementation returns the price for the given UOM
|
|
6
|
+
# Custom implementations will return from a pricing library
|
|
7
|
+
# @return [BigDecimal] the "standard" price for the SKU
|
|
8
|
+
def self.price( sku_loc: nil, customer: nil, uom: nil, qty: 1 )
|
|
9
|
+
sku_loc.sku.uoms.with_code( uom.code ).price
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
end
|
|
13
|
+
end
|
|
14
|
+
|
data/lib/skr/version.rb
ADDED
data/lib/skr.rb
ADDED
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
require "lanes"
|
|
2
|
+
require 'require_all'
|
|
3
|
+
require "lanes/access"
|
|
4
|
+
require_relative "skr/version"
|
|
5
|
+
require_relative "skr/extension"
|
|
6
|
+
require_rel "skr/configuration"
|
|
7
|
+
|
|
8
|
+
# The main namespace for Skr
|
|
9
|
+
module Skr
|
|
10
|
+
def self.table_name_prefix
|
|
11
|
+
"skr_"
|
|
12
|
+
end
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
require_rel "skr/concerns/*.rb"
|
|
16
|
+
require_rel "skr/model"
|
|
17
|
+
require_rel 'skr/models/*.rb'
|
|
18
|
+
require_relative "skr/access_roles"
|
data/lib/stockor.rb
ADDED
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
namespace :demo do
|
|
2
|
+
task :activity do
|
|
3
|
+
|
|
4
|
+
require 'faker'
|
|
5
|
+
require 'lanes/api/pub_sub'
|
|
6
|
+
|
|
7
|
+
Lanes::DB.establish_connection
|
|
8
|
+
Lanes::API::PubSub.initialize
|
|
9
|
+
|
|
10
|
+
attributes = {
|
|
11
|
+
Skr::Address => [:name,:email,:phone,:line1,:line2,:city,:state,:postal_code],
|
|
12
|
+
Skr::Vendor => [:name,:notes],
|
|
13
|
+
Skr::Customer => [:name,:notes]
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
attribute_values={
|
|
17
|
+
name: ->{ Faker::Name.name },
|
|
18
|
+
notes: ->{ Faker::Company.catch_phrase },
|
|
19
|
+
email: ->{ Faker::Internet.email },
|
|
20
|
+
phone: ->{ Faker::PhoneNumber.phone_number },
|
|
21
|
+
line1: ->{ Faker::Address.street_address },
|
|
22
|
+
line2: ->{ Faker::Address.secondary_address },
|
|
23
|
+
city: ->{ Faker::Address.city },
|
|
24
|
+
state: ->{ Faker::Address.state_abbr },
|
|
25
|
+
postal_code: ->{ Faker::Address.zip_code }
|
|
26
|
+
}
|
|
27
|
+
module Lanes::API::Updates
|
|
28
|
+
def self.user_info_for_change(model)
|
|
29
|
+
{ id: rand(4)+1, name: Faker::Name.name, email: Faker::Internet.email }
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
loop do
|
|
34
|
+
|
|
35
|
+
[ Skr::Customer ].each do | klass |
|
|
36
|
+
Thread.current[:demo_user_info] = {
|
|
37
|
+
name: Faker::Name.name, email: Faker::Internet.email
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
record = klass.order(:code).first
|
|
41
|
+
update = case rand(3)
|
|
42
|
+
when 0 then record
|
|
43
|
+
when 1 then record.billing_address
|
|
44
|
+
when 2 then record.shipping_address
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
attribute = attributes[update.class].sample
|
|
48
|
+
value = attribute_values[attribute].call
|
|
49
|
+
|
|
50
|
+
printf("%15s %15s(%3s) %13s => %-20s\n", klass, update.class, update.id, attribute, value )
|
|
51
|
+
|
|
52
|
+
update.update_attribute( attribute, value )
|
|
53
|
+
end
|
|
54
|
+
sleep 10
|
|
55
|
+
|
|
56
|
+
end
|
|
57
|
+
end
|
|
58
|
+
end
|
data/log/test.log
ADDED
|
File without changes
|
data/spec/skr/address.rb
ADDED
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
require "lanes/spec_helper"
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
class CodeIdentifierTest < Lanes::TestCase
|
|
5
|
+
|
|
6
|
+
class CodeIdentifierTestModel
|
|
7
|
+
class_attribute :blocks
|
|
8
|
+
attr_accessor :code
|
|
9
|
+
|
|
10
|
+
include Lanes::Concerns::CodeIdentifier
|
|
11
|
+
|
|
12
|
+
def self.before_validation( opts={}, &block )
|
|
13
|
+
self.blocks||=[]
|
|
14
|
+
self.blocks.push( block )
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def self.validates( *opts )
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
def run_validations
|
|
21
|
+
self.class.blocks.each{ |b| self.instance_eval(&b) }
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def [](name)
|
|
25
|
+
:name == name ? 'A Long String of Nonsense' : ''
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
has_code_identifier :from => :name
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
def test_that_it_uppercases
|
|
32
|
+
ci = CodeIdentifierTestModel.new
|
|
33
|
+
ci.code='test'
|
|
34
|
+
ci.run_validations
|
|
35
|
+
assert_equal 'TEST', ci.code
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
def test_that_it_generates
|
|
39
|
+
ci = CodeIdentifierTestModel.new
|
|
40
|
+
ci.run_validations
|
|
41
|
+
assert ci.code.present?, "Code wasn't auto-generated"
|
|
42
|
+
assert_equal 'ALOSTOFNON', ci.code
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
end
|