stockor 0.4.0 → 0.5.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (148) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile +2 -4
  3. data/Gemfile.lock +104 -87
  4. data/client/skr/api.js +3 -1
  5. data/client/skr/api/Components/AddressForm.cjsx +1 -1
  6. data/client/skr/api/Components/SingleItemCart.cjsx +1 -1
  7. data/client/skr/api/SingleItemCheckout.cjsx +3 -3
  8. data/client/skr/components/BankAccountFinder.cjsx +1 -1
  9. data/client/skr/components/CreditCardForm.cjsx +1 -1
  10. data/client/skr/components/Currency.cjsx +2 -1
  11. data/client/skr/components/CustomerFinder.cjsx +1 -1
  12. data/client/skr/components/CustomerProjectFinder.cjsx +1 -1
  13. data/client/skr/components/ExpenseCategoryFinder.cjsx +34 -0
  14. data/client/skr/components/GlAccountChooser.cjsx +2 -1
  15. data/client/skr/components/InvoiceFinder.cjsx +1 -1
  16. data/client/skr/components/LatexSnippets.cjsx +3 -0
  17. data/client/skr/components/LocationChooser.cjsx +3 -3
  18. data/client/skr/components/PaymentCategoryFinder.cjsx +1 -1
  19. data/client/skr/components/SalesOrderFinder.cjsx +1 -2
  20. data/client/skr/components/SkuFinder.cjsx +1 -1
  21. data/client/skr/components/SystemSettings.cjsx +4 -1
  22. data/client/skr/components/TermsChooser.cjsx +2 -2
  23. data/client/skr/components/ToolbarButton.cjsx +7 -3
  24. data/client/skr/components/TotalsLine.cjsx +5 -1
  25. data/client/skr/components/UserPreferences.cjsx +1 -1
  26. data/client/skr/components/VendorFinder.cjsx +1 -1
  27. data/client/skr/components/address/Address.cjsx +14 -1
  28. data/client/skr/components/styles.scss +6 -0
  29. data/client/skr/index.js +1 -0
  30. data/client/skr/lib/Remote.coffee +32 -0
  31. data/client/skr/lib/index.js +2 -0
  32. data/client/skr/lib/namespace.coffee +1 -0
  33. data/client/skr/models/CreditCardGateway.coffee +1 -1
  34. data/client/skr/models/ExpenseCategory.coffee +11 -0
  35. data/client/skr/models/ExpenseEntry.coffee +64 -0
  36. data/client/skr/models/ExpenseEntryCategory.coffee +11 -0
  37. data/client/skr/models/Invoice.coffee +4 -1
  38. data/client/skr/models/Payment.coffee +2 -2
  39. data/client/skr/models/SalesOrder.coffee +3 -2
  40. data/client/skr/models/SequentialId.coffee +1 -1
  41. data/client/skr/models/Vendor.coffee +1 -1
  42. data/client/skr/models/mixins/PrintSupport.coffee +1 -1
  43. data/client/skr/screens/bank-maint/BankMaint.cjsx +1 -1
  44. data/client/skr/screens/chart-of-accounts/ChartOfAccounts.cjsx +1 -1
  45. data/client/skr/screens/customer-maint/CustomerMaint.cjsx +1 -1
  46. data/client/skr/screens/customer-projects/CustomerProjects.cjsx +1 -1
  47. data/client/skr/screens/expense-categories/ExpenseCategories.cjsx +31 -0
  48. data/client/skr/screens/expense-categories/index.js +5 -0
  49. data/client/skr/screens/expense-categories/index.scss +9 -0
  50. data/client/skr/screens/expense-entry/ApprovalRequest.coffee +14 -0
  51. data/client/skr/screens/expense-entry/ApproveDialog.cjsx +30 -0
  52. data/client/skr/screens/expense-entry/Categories.cjsx +112 -0
  53. data/client/skr/screens/expense-entry/ExpenseEntry.cjsx +193 -0
  54. data/client/skr/screens/expense-entry/Form.cjsx +54 -0
  55. data/client/skr/screens/expense-entry/Grid.cjsx +51 -0
  56. data/client/skr/screens/expense-entry/ScreenState.coffee +1 -0
  57. data/client/skr/screens/expense-entry/index.js +1 -0
  58. data/client/skr/screens/expense-entry/index.scss +106 -0
  59. data/client/skr/screens/fresh-books-import/ApiInfo.cjsx +3 -3
  60. data/client/skr/screens/fresh-books-import/ChooseRecords.cjsx +6 -4
  61. data/client/skr/screens/fresh-books-import/FreshBooksImport.cjsx +1 -1
  62. data/client/skr/screens/fresh-books-import/ViewRecords.cjsx +2 -2
  63. data/client/skr/screens/fresh-books-import/index.scss +5 -4
  64. data/client/skr/screens/gl-accounts/GlAccounts.cjsx +1 -1
  65. data/client/skr/screens/gl-transactions/GlTransactions.cjsx +1 -1
  66. data/client/skr/screens/invoice/Invoice.cjsx +6 -2
  67. data/client/skr/screens/invoice/Payment.cjsx +1 -1
  68. data/client/skr/screens/invoice/TotalExtraInfo.cjsx +32 -0
  69. data/client/skr/screens/invoice/index.scss +4 -2
  70. data/client/skr/screens/locations/Locations.cjsx +1 -1
  71. data/client/skr/screens/payment-category/PaymentCategory.cjsx +1 -1
  72. data/client/skr/screens/payment-terms/PaymentTerms.cjsx +1 -1
  73. data/client/skr/screens/payments/Payments.cjsx +13 -6
  74. data/client/skr/screens/sale-report/SaleReport.cjsx +1 -1
  75. data/client/skr/screens/sales-order/SalesOrder.cjsx +2 -1
  76. data/client/skr/screens/sku-maint/SkuMaint.cjsx +1 -1
  77. data/client/skr/screens/sku-maint/SkuUomList.cjsx +2 -2
  78. data/client/skr/screens/time-invoicing/TimeInvoicing.cjsx +4 -4
  79. data/client/skr/screens/time-tracking/EditEntry.cjsx +2 -2
  80. data/client/skr/screens/time-tracking/Entries.coffee +6 -4
  81. data/client/skr/screens/time-tracking/Popover.cjsx +11 -6
  82. data/client/skr/screens/time-tracking/TimeTracking.cjsx +12 -5
  83. data/client/skr/screens/vendor-maint/VendorMaint.cjsx +2 -2
  84. data/config/database.yml +2 -0
  85. data/config/puma.rb +0 -4
  86. data/config/routes.rb +4 -0
  87. data/config/screens.rb +17 -0
  88. data/db/migrate/20140323001446_create_so_details_view.rb +2 -2
  89. data/db/migrate/20151121211323_create_customer_project_details_views.rb +1 -1
  90. data/db/migrate/20160216142845_create_gl_account_balances_view.rb +1 -1
  91. data/db/migrate/20160726004411_string_check_numbers.rb +5 -0
  92. data/db/migrate/20160805002717_create_expenses.rb +65 -0
  93. data/db/schema.sql +394 -229
  94. data/db/seed.rb +12 -12
  95. data/lib/skr/access_roles.rb +9 -4
  96. data/lib/skr/concerns/has_gl_transaction.rb +1 -1
  97. data/lib/skr/configuration.rb +3 -1
  98. data/lib/skr/db/migration_helpers.rb +2 -2
  99. data/lib/skr/handlers/approve_expense_entries.rb +16 -0
  100. data/lib/skr/handlers/invoice_from_time_entries.rb +1 -1
  101. data/lib/skr/handlers/sequential_ids.rb +2 -2
  102. data/lib/skr/jobs/fresh_books/import.rb +18 -17
  103. data/lib/skr/model.rb +3 -0
  104. data/lib/skr/models/bank_account.rb +9 -0
  105. data/lib/skr/models/expense_category.rb +27 -0
  106. data/lib/skr/models/expense_entry.rb +76 -0
  107. data/lib/skr/models/expense_entry_category.rb +15 -0
  108. data/lib/skr/models/gl_transaction.rb +2 -2
  109. data/lib/skr/models/inv_line.rb +3 -1
  110. data/lib/skr/models/invoice.rb +9 -5
  111. data/lib/skr/models/payment.rb +1 -1
  112. data/lib/skr/models/purchase_order.rb +4 -4
  113. data/lib/skr/models/uom.rb +2 -2
  114. data/lib/skr/models/voucher.rb +4 -4
  115. data/lib/skr/print/form.rb +17 -14
  116. data/lib/skr/version.rb +1 -1
  117. data/spec/fixtures/skr/expense_category.yml +17 -0
  118. data/spec/fixtures/skr/expense_entries.yml +20 -0
  119. data/spec/fixtures/skr/expense_entry_category.yml +19 -0
  120. data/spec/fixtures/skr/gl_account.yml +10 -0
  121. data/spec/server/handlers/invoice_from_time_entries_spec.rb +2 -2
  122. data/spec/server/handlers/sequential_ids_spec.rb +1 -1
  123. data/spec/server/models/expense_category_spec.rb +17 -0
  124. data/spec/server/models/expense_entry_spec.rb +44 -0
  125. data/spec/server/models/invoice_spec.rb +0 -1
  126. data/spec/server/models/spec_helper_spec.rb +5 -10
  127. data/spec/server/spec_helper.rb +12 -11
  128. data/spec/skr/components/SkuLinesSpec.coffee +11 -9
  129. data/spec/skr/models/CustomerSpec.coffee +1 -1
  130. data/spec/skr/models/ExpenseAccountSpec.coffee +5 -0
  131. data/spec/skr/screens/expense-categories/ExpenseCategoriesSpec.coffee +5 -0
  132. data/spec/skr/screens/expense-entry/ExpenseEntrySpec.coffee +5 -0
  133. data/spec/skr/screens/locations/LocationsSpec.coffee +4 -4
  134. data/spec/skr/screens/time-tracking/TimeTrackingSpec.coffee +4 -4
  135. data/stockor.gemspec +2 -3
  136. data/templates/print/partials/header.tex.erb +1 -1
  137. data/templates/print/partials/skus_table_invoice_footer.tex.erb +22 -19
  138. data/templates/print/partials/skus_table_invoice_info_line.tex.erb +5 -1
  139. data/templates/print/types/payment/default.tex.erb +10 -10
  140. metadata +40 -14
  141. data/client/skr/api/onReady.coffee +0 -23
  142. data/spec/skr/api/SingleItemCheckoutSpec.cjsx +0 -10
  143. data/spec/skr/screens/bank-maint/BankMaintSpec.coffee +0 -5
  144. data/spec/skr/screens/gl-accounts/GlAccountsSpec.coffee +0 -5
  145. data/spec/skr/screens/invoice/InvoiceSpec.coffee +0 -5
  146. data/spec/skr/screens/payment-category/PaymentCategorySpec.coffee +0 -5
  147. data/spec/skr/screens/payments/PaymentsSpec.coffee +0 -5
  148. data/spec/skr/screens/sale-report/SaleReportSpec.coffee +0 -5
data/db/seed.rb CHANGED
@@ -14,18 +14,6 @@ module Skr
14
14
  Lanes::User.scoped_to(user) do
15
15
  seeds_path = Pathname.new(__FILE__).dirname.join('seed')
16
16
 
17
- unless BankAccount.default
18
- BankAccount.create(code: Skr.config.default_bank_account_code, name: "System default",
19
- address: Address.new(name:"System default")
20
- )
21
- end
22
-
23
- unless Location.default
24
- Location.create( code: Skr.config.default_location_code, name: "System default",
25
- address: Address.new(name:"System default")
26
- )
27
- end
28
-
29
17
  YAML::load( seeds_path.join('chart_of_accounts.yml').read ).each do | acct_data |
30
18
  GlAccount.where(number: acct_data['number'].to_s).any? || GlAccount.create!(acct_data)
31
19
  end
@@ -54,6 +42,18 @@ module Skr
54
42
  )
55
43
  end
56
44
 
45
+ unless BankAccount.default
46
+ BankAccount.create(code: Skr.config.default_bank_account_code, name: "System default",
47
+ address: Address.new(name:"System default")
48
+ )
49
+ end
50
+
51
+ unless Location.default
52
+ Location.create( code: Skr.config.default_location_code, name: "System default",
53
+ address: Address.new(name:"System default")
54
+ )
55
+ end
56
+
57
57
  end
58
58
 
59
59
  end
@@ -14,7 +14,8 @@ module Lanes::Access
14
14
  Skr::Sku
15
15
 
16
16
  grant Skr::SalesOrder,
17
- Skr::TimeEntry
17
+ Skr::TimeEntry,
18
+ Skr::ExpenseEntry
18
19
  end
19
20
 
20
21
  # Accounting role for members who deal with finance
@@ -27,7 +28,9 @@ module Lanes::Access
27
28
  Skr::TimeEntry,
28
29
  Skr::GlTransaction,
29
30
  Skr::BankAccount,
30
- Skr::Payment
31
+ Skr::Payment,
32
+ Skr::ExpenseCategory,
33
+ Skr::ExpenseEntry
31
34
 
32
35
  lock_writes Skr::Customer, :terms
33
36
  lock Skr::Sku, :gl_asset_account
@@ -38,7 +41,8 @@ module Lanes::Access
38
41
  class Purchasing < Lanes::Access::Role
39
42
  read Skr::Customer
40
43
  grant Skr::Sku,
41
- Skr::SalesOrder
44
+ Skr::SalesOrder,
45
+ Skr::ExpenseEntry
42
46
  end
43
47
 
44
48
  # Standard employee role
@@ -47,7 +51,8 @@ module Lanes::Access
47
51
  Skr::Sku
48
52
  grant Skr::SalesOrder,
49
53
  Skr::Invoice,
50
- Skr::TimeEntry
54
+ Skr::TimeEntry,
55
+ Skr::ExpenseEntry
51
56
  end
52
57
  end
53
58
 
@@ -53,7 +53,7 @@ module Skr
53
53
  identifier = has_attribute?(:visible_id) ? visible_id : id
54
54
  {
55
55
  source: self,
56
- location: location,
56
+ location: try(:location) || Location.default,
57
57
  description: "#{self.class.to_s.demodulize} #{identifier}"
58
58
  }
59
59
  end
@@ -48,7 +48,9 @@ module Skr
48
48
  # Clearing account for inventory that's been
49
49
  inventory_receipts_clearing: '2600',
50
50
  # Holding account for funds that are awaiting deposit
51
- deposit_holding: '1010'
51
+ deposit_holding: '1010',
52
+ # Bank Account
53
+ bank: '1000'
52
54
  }
53
55
  end
54
56
 
@@ -43,7 +43,7 @@ module Skr
43
43
 
44
44
  options[:column] ||= to_table.to_s + '_id'
45
45
 
46
- column( options[:column], :integer, :null=>options[:null] || false )
46
+ column( options[:column], (options[:type] || :integer), :null=>options[:null] || false )
47
47
  to_table = options[:to_table] if options.has_key? :to_table
48
48
 
49
49
  if options[:single]
@@ -75,7 +75,7 @@ module Skr
75
75
  skr_add_foreign_key( table_name, to_table, options )
76
76
  end
77
77
  definition.skr_extra_indexes.each do | index_column, options |
78
- skr_add_index( table_name, index_column, options )
78
+ skr_add_index(table_name, index_column, options )
79
79
  end
80
80
  end
81
81
 
@@ -0,0 +1,16 @@
1
+ module Skr
2
+ module Handlers
3
+ class ApproveExpenseEntries < ::Lanes::API::ControllerBase
4
+
5
+ def create
6
+ bank_account = BankAccount.find(data['bank_account_id'])
7
+ entries = []
8
+ ExpenseEntry.where(id: data['expense_ids']).includes(:gl_transaction).find_each do | entry |
9
+ entries.push entry.approve!(bank_account) unless entry.gl_transaction
10
+ end
11
+ std_api_reply :create, { entries: entries }, success: true
12
+ end
13
+
14
+ end
15
+ end
16
+ end
@@ -10,7 +10,7 @@ module Skr
10
10
  @sku_loc = @project.sku.sku_locs.find_by(location: @location)
11
11
  end
12
12
 
13
- def perform_creation
13
+ def create
14
14
  invoice = Invoice.new(
15
15
  notes: @options['notes'],
16
16
  po_num: @options['po_num'] || @project.po_num,
@@ -13,7 +13,7 @@ module Skr
13
13
  @data = data
14
14
  end
15
15
 
16
- def perform_retrieval
16
+ def show
17
17
  ids = {}
18
18
  Skr::SequentialId.pluck(:name, :current_value).map do |name, count|
19
19
  ids[name.demodulize] = count
@@ -28,7 +28,7 @@ module Skr
28
28
  std_api_reply(:retrieve, {id: 'all', ids: list}, success: true)
29
29
  end
30
30
 
31
- def perform_update
31
+ def update
32
32
  data['ids'].each do | si |
33
33
  Lanes.logger.warn "#{si['id']}"
34
34
  id = if 0 == si['id'].index(Payment::SEQUENTIAL_ID_PREFIX)
@@ -91,8 +91,8 @@ module Skr::Jobs::FreshBooks
91
91
  def process_invoice(r)
92
92
  return nil if is_ignored?('invoices', r['invoice_id'])
93
93
 
94
- inv = Skr::Invoice.create(
95
- visible_id: r['number'].sub(/^0+/,''),
94
+ inv = Skr::Invoice.create!(
95
+ visible_id: r['number'].sub(/^0+/, '').gsub(/\D/, ''),
96
96
  options: { freshbooks_id: r['invoice_id'] },
97
97
  customer: customer_for_fb_id(r['client_id']),
98
98
  location: Skr::Location.default,
@@ -107,26 +107,27 @@ module Skr::Jobs::FreshBooks
107
107
  },
108
108
  lines_attributes: Array.wrap(r['lines']['line']).map { | l |
109
109
  is_time = 'Time' == l['type']
110
- if l['name'] or l['description'] # blank name == blank line
111
- sku = Skr::Sku.find_by(code: is_time ? 'LABOR' : 'MISC')
112
- invl = {
113
- sku_loc: sku.sku_locs.default,
114
- price: l['unit_cost'],
115
- description: l['description'],
116
- qty: l['quantity']
117
- }
118
- if l.has_key?('time_entries')
119
- invl['time_entry'] =
120
- Skr::TimeEntry.find_by("options ->>'freshbooks_id' = ?",
121
- l['time_entries']['time_entry']['time_entry_id'])
122
- end
123
- invl
110
+ next unless l['name'] or l['description'] # blank name == blank line
111
+ sku = Skr::Sku.find_by(code: is_time ? 'LABOR' : 'MISC')
112
+ invl = {
113
+ sku_loc: sku.sku_locs.default,
114
+ price: l['unit_cost'],
115
+ description: l['description'],
116
+ qty: l['quantity']
117
+ }
118
+ if l.has_key?('time_entries')
119
+ invl['time_entry'] =
120
+ Skr::TimeEntry.find_by("options ->>'freshbooks_id' = ?",
121
+ l['time_entries']['time_entry']['time_entry_id'])
124
122
  end
123
+ invl
125
124
  }.compact
126
125
  )
127
126
  if r['paid'].to_f > 0
128
127
  inv.payments.create!(
129
- amount: r['paid'], bank_account: Skr::BankAccount.default
128
+ amount: r['paid'],
129
+ name: inv.customer.name,
130
+ bank_account: Skr::BankAccount.default
130
131
  )
131
132
  end
132
133
  inv
@@ -54,4 +54,7 @@ module Skr
54
54
  autoload :BankAccount, "skr/models/bank_account"
55
55
  autoload :PaymentCategory, "skr/models/payment_category"
56
56
  autoload :Payment, "skr/models/payment"
57
+ autoload :ExpenseCategory, "skr/models/expense_category"
58
+ autoload :ExpenseEntry, "skr/models/expense_entry"
59
+ autoload :ExpenseEntryCategory, "skr/models/expense_entry_category"
57
60
  end
@@ -9,6 +9,8 @@ module Skr
9
9
  belongs_to :address, class_name: 'Skr::Address',
10
10
  export: { writable: true }, dependent: :destroy
11
11
 
12
+ before_validation :set_defaults, :on=>:create
13
+
12
14
  def self.default
13
15
  account = nil
14
16
  if default_id = Skr.system_settings['bank_acount_id']
@@ -19,6 +21,13 @@ module Skr
19
21
  BankAccount.first
20
22
  end
21
23
 
24
+ private
25
+
26
+ def set_defaults
27
+ self.gl_account ||= GlAccount.default_for(:bank)
28
+ true
29
+ end
30
+
22
31
  end
23
32
 
24
33
 
@@ -0,0 +1,27 @@
1
+ module Skr
2
+
3
+ class ExpenseCategory < Model
4
+
5
+ belongs_to :gl_account, class_name: 'Skr::GlAccount', export: true
6
+
7
+ validates :name, :gl_account, presence: true
8
+
9
+ has_many :entry_categories, foreign_key: 'category_id',
10
+ class_name: 'Skr::ExpenseEntryCategory' do
11
+
12
+ def total
13
+ proxy_association.loaded? ? inject(0){ | sum, cat | sum+cat.amount } : sum('amount')
14
+ end
15
+
16
+ end
17
+
18
+ has_many :entries, class_name: 'Skr::ExpenseEntry',
19
+ through: :entry_categories, source: :entry
20
+
21
+ def balance
22
+ entry_categories.total
23
+ end
24
+
25
+ end
26
+
27
+ end
@@ -0,0 +1,76 @@
1
+ module Skr
2
+
3
+ class ExpenseEntry < Model
4
+
5
+ self.primary_key = 'id'
6
+
7
+ has_one :gl_transaction, class_name: 'Skr::GlTransaction', as: :source
8
+
9
+ has_many :attachments, as: :owner, class_name: 'Lanes::Asset',
10
+ export: {writable: true}
11
+
12
+ has_many :categories, class_name: 'Skr::ExpenseEntryCategory',
13
+ inverse_of: :entry, export: {writable: true}, foreign_key: 'entry_id' do
14
+ def total
15
+ proxy_association.loaded? ? inject(0){ | sum, cat | sum+cat.amount } : sum('amount')
16
+ end
17
+ end
18
+
19
+ validates :categories, presence: true
20
+ validates :name, presence: true
21
+ validates :occured, presence: true, on: :update
22
+
23
+ before_create :set_defaults
24
+
25
+ export_sort :amount do |q, dir|
26
+ q.order("category_total #{dir}")
27
+ end
28
+
29
+ def self.access_limits_for_query(query, user, params)
30
+ if user.roles.include?('accounting') && (params['id'] || params['review'] == 'true')
31
+ query
32
+ else
33
+ query.where(created_by_id: user.id)
34
+ end
35
+ end
36
+
37
+ scope :with_category_details, lambda { | category_id = nil |
38
+ sql = "join skr_expense_entry_details as details on " +
39
+ "details.expense_entry_id = #{table_name}.#{primary_key}"
40
+ sql << " and #{category_id.to_i} = ANY(category_ids)" if category_id
41
+ q = joins(sql).select("details.*")
42
+ if current_scope.nil? || current_scope.select_values.exclude?("#{table_name}.*")
43
+ q = q.select("#{table_name}.*")
44
+ end
45
+ q
46
+ }, export: true
47
+
48
+ def amount
49
+ categories.total
50
+ end
51
+
52
+ def approve!(bank, location: Location.default)
53
+ debit = bank.gl_account
54
+ glt = GlTransaction.record(
55
+ location: location, description: "Expenses"
56
+ ) do | transaction |
57
+ transaction.source = self
58
+ categories.each do | entry_category |
59
+ GlTransaction.push_or_save(
60
+ owner: self, amount: entry_category.amount,
61
+ debit: debit, credit: entry_category.category.gl_account
62
+ )
63
+ end
64
+ end
65
+ end
66
+
67
+ private
68
+
69
+ def set_defaults
70
+ self.uuid ||= SecureRandom.uuid
71
+ self.occured ||= Time.now
72
+ end
73
+
74
+ end
75
+
76
+ end
@@ -0,0 +1,15 @@
1
+ module Skr
2
+
3
+ class ExpenseEntryCategory < Model
4
+
5
+ belongs_to :category,
6
+ class_name: 'Skr::ExpenseCategory', export: {writable: true}
7
+
8
+ belongs_to :entry,
9
+ class_name: 'Skr::ExpenseEntry', export: {writable: true}
10
+
11
+ validates :amount, :category, :entry, presence: true
12
+
13
+ end
14
+
15
+ end
@@ -53,7 +53,7 @@ module Skr
53
53
  # @param amount [BigDecimal] the amount to apply to each posting
54
54
  # @param debit [GlAccount]
55
55
  # @param credit [GlAccount]
56
- def add_posting( amount: nil, debit: nil, credit: nil )
56
+ def add_posting(amount: nil, debit: nil, credit: nil)
57
57
  Lanes.logger.debug "GlTransaction add_posting #{debit} : #{credit}"
58
58
  self.credits.build( location: @location, is_debit: false,
59
59
  account: credit, amount: amount )
@@ -112,7 +112,7 @@ module Skr
112
112
  if (glt = self.current) # we push
113
113
  glt.add_posting( amount: amount, debit: debit, credit: credit )
114
114
  else
115
- options.merge!(source: owner, location: options[:location] || owner.location)
115
+ options.merge!(source: owner, location: options[:location] || owner.try(:location))
116
116
  if owner.respond_to?(:attributes_for_gl_transaction)
117
117
  options.reverse_merge!( owner.attributes_for_gl_transaction )
118
118
  end
@@ -34,7 +34,9 @@ module Skr
34
34
  }, export: true
35
35
 
36
36
  scope :summarize_by, lambda { | values |
37
- select( "sum(inv_lines.qty) as qty, count(*) as num_sales, sum(inv_lines.price) as price, avg(inv_lines.price) as avg_price, s.code as sku_code, s.description, s.id as sku_id, 1 as uom_size, 'EA' as uom_code")
37
+ select( "sum(inv_lines.qty) as qty, count(*) as num_sales, sum(inv_lines.price) as price, " \
38
+ "avg(inv_lines.price) as avg_price, s.code as sku_code, s.description, " \
39
+ "s.id as sku_id, 1 as uom_size, 'EA' as uom_code")
38
40
  .joins("join sku_locs sl on sl.id = inv_lines.sku_loc_id join skus s on s.id = sl.sku_id")
39
41
  .where(["inv_lines.created_at between ? and ?",values['from'], values['to'] ])
40
42
  .group('s.code,s.description, s.id')
@@ -31,6 +31,8 @@ module Skr
31
31
  has_gl_transaction
32
32
  is_order_like
33
33
 
34
+ export_methods :total_hours
35
+
34
36
  belongs_to :sales_order, export: true
35
37
  belongs_to :customer_project, export: true
36
38
  belongs_to :customer, export: true
@@ -114,6 +116,12 @@ module Skr
114
116
  GlPeriod.is_date_locked?(self.invoice_date)
115
117
  end
116
118
 
119
+ def total_hours
120
+ lines.reduce(BigDecimal.new('0')){|t, l|
121
+ l.time_entry ? t + l.qty : t
122
+ }
123
+ end
124
+
117
125
  private
118
126
 
119
127
  # set the state if the amount_paid was changed
@@ -121,11 +129,7 @@ module Skr
121
129
  if self.fully_paid? && self.may_mark_paid?
122
130
  self.mark_paid!
123
131
  elsif self.payments.total > 0 && self.may_mark_partialy_paid?
124
- Lanes.logger_debug('paying')
125
-
126
- #self.mark_partialy_paid!
127
-
128
- Lanes.logger_debug('paid')
132
+ self.mark_partialy_paid!
129
133
  end
130
134
  end
131
135
 
@@ -85,7 +85,7 @@ module Skr
85
85
  self.name = invoice.billing_address.name
86
86
  end
87
87
  end
88
- if bank_account && outgoing?
88
+ if bank_account.present? && outgoing?
89
89
  self.check_number ||= SequentialId.next_for(SEQUENTIAL_ID_PREFIX + bank_account.id.to_s)
90
90
  end
91
91
  self.bank_account ||= BankAccount.default