stockor 0.4.0 → 0.5.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/Gemfile +2 -4
- data/Gemfile.lock +104 -87
- data/client/skr/api.js +3 -1
- data/client/skr/api/Components/AddressForm.cjsx +1 -1
- data/client/skr/api/Components/SingleItemCart.cjsx +1 -1
- data/client/skr/api/SingleItemCheckout.cjsx +3 -3
- data/client/skr/components/BankAccountFinder.cjsx +1 -1
- data/client/skr/components/CreditCardForm.cjsx +1 -1
- data/client/skr/components/Currency.cjsx +2 -1
- data/client/skr/components/CustomerFinder.cjsx +1 -1
- data/client/skr/components/CustomerProjectFinder.cjsx +1 -1
- data/client/skr/components/ExpenseCategoryFinder.cjsx +34 -0
- data/client/skr/components/GlAccountChooser.cjsx +2 -1
- data/client/skr/components/InvoiceFinder.cjsx +1 -1
- data/client/skr/components/LatexSnippets.cjsx +3 -0
- data/client/skr/components/LocationChooser.cjsx +3 -3
- data/client/skr/components/PaymentCategoryFinder.cjsx +1 -1
- data/client/skr/components/SalesOrderFinder.cjsx +1 -2
- data/client/skr/components/SkuFinder.cjsx +1 -1
- data/client/skr/components/SystemSettings.cjsx +4 -1
- data/client/skr/components/TermsChooser.cjsx +2 -2
- data/client/skr/components/ToolbarButton.cjsx +7 -3
- data/client/skr/components/TotalsLine.cjsx +5 -1
- data/client/skr/components/UserPreferences.cjsx +1 -1
- data/client/skr/components/VendorFinder.cjsx +1 -1
- data/client/skr/components/address/Address.cjsx +14 -1
- data/client/skr/components/styles.scss +6 -0
- data/client/skr/index.js +1 -0
- data/client/skr/lib/Remote.coffee +32 -0
- data/client/skr/lib/index.js +2 -0
- data/client/skr/lib/namespace.coffee +1 -0
- data/client/skr/models/CreditCardGateway.coffee +1 -1
- data/client/skr/models/ExpenseCategory.coffee +11 -0
- data/client/skr/models/ExpenseEntry.coffee +64 -0
- data/client/skr/models/ExpenseEntryCategory.coffee +11 -0
- data/client/skr/models/Invoice.coffee +4 -1
- data/client/skr/models/Payment.coffee +2 -2
- data/client/skr/models/SalesOrder.coffee +3 -2
- data/client/skr/models/SequentialId.coffee +1 -1
- data/client/skr/models/Vendor.coffee +1 -1
- data/client/skr/models/mixins/PrintSupport.coffee +1 -1
- data/client/skr/screens/bank-maint/BankMaint.cjsx +1 -1
- data/client/skr/screens/chart-of-accounts/ChartOfAccounts.cjsx +1 -1
- data/client/skr/screens/customer-maint/CustomerMaint.cjsx +1 -1
- data/client/skr/screens/customer-projects/CustomerProjects.cjsx +1 -1
- data/client/skr/screens/expense-categories/ExpenseCategories.cjsx +31 -0
- data/client/skr/screens/expense-categories/index.js +5 -0
- data/client/skr/screens/expense-categories/index.scss +9 -0
- data/client/skr/screens/expense-entry/ApprovalRequest.coffee +14 -0
- data/client/skr/screens/expense-entry/ApproveDialog.cjsx +30 -0
- data/client/skr/screens/expense-entry/Categories.cjsx +112 -0
- data/client/skr/screens/expense-entry/ExpenseEntry.cjsx +193 -0
- data/client/skr/screens/expense-entry/Form.cjsx +54 -0
- data/client/skr/screens/expense-entry/Grid.cjsx +51 -0
- data/client/skr/screens/expense-entry/ScreenState.coffee +1 -0
- data/client/skr/screens/expense-entry/index.js +1 -0
- data/client/skr/screens/expense-entry/index.scss +106 -0
- data/client/skr/screens/fresh-books-import/ApiInfo.cjsx +3 -3
- data/client/skr/screens/fresh-books-import/ChooseRecords.cjsx +6 -4
- data/client/skr/screens/fresh-books-import/FreshBooksImport.cjsx +1 -1
- data/client/skr/screens/fresh-books-import/ViewRecords.cjsx +2 -2
- data/client/skr/screens/fresh-books-import/index.scss +5 -4
- data/client/skr/screens/gl-accounts/GlAccounts.cjsx +1 -1
- data/client/skr/screens/gl-transactions/GlTransactions.cjsx +1 -1
- data/client/skr/screens/invoice/Invoice.cjsx +6 -2
- data/client/skr/screens/invoice/Payment.cjsx +1 -1
- data/client/skr/screens/invoice/TotalExtraInfo.cjsx +32 -0
- data/client/skr/screens/invoice/index.scss +4 -2
- data/client/skr/screens/locations/Locations.cjsx +1 -1
- data/client/skr/screens/payment-category/PaymentCategory.cjsx +1 -1
- data/client/skr/screens/payment-terms/PaymentTerms.cjsx +1 -1
- data/client/skr/screens/payments/Payments.cjsx +13 -6
- data/client/skr/screens/sale-report/SaleReport.cjsx +1 -1
- data/client/skr/screens/sales-order/SalesOrder.cjsx +2 -1
- data/client/skr/screens/sku-maint/SkuMaint.cjsx +1 -1
- data/client/skr/screens/sku-maint/SkuUomList.cjsx +2 -2
- data/client/skr/screens/time-invoicing/TimeInvoicing.cjsx +4 -4
- data/client/skr/screens/time-tracking/EditEntry.cjsx +2 -2
- data/client/skr/screens/time-tracking/Entries.coffee +6 -4
- data/client/skr/screens/time-tracking/Popover.cjsx +11 -6
- data/client/skr/screens/time-tracking/TimeTracking.cjsx +12 -5
- data/client/skr/screens/vendor-maint/VendorMaint.cjsx +2 -2
- data/config/database.yml +2 -0
- data/config/puma.rb +0 -4
- data/config/routes.rb +4 -0
- data/config/screens.rb +17 -0
- data/db/migrate/20140323001446_create_so_details_view.rb +2 -2
- data/db/migrate/20151121211323_create_customer_project_details_views.rb +1 -1
- data/db/migrate/20160216142845_create_gl_account_balances_view.rb +1 -1
- data/db/migrate/20160726004411_string_check_numbers.rb +5 -0
- data/db/migrate/20160805002717_create_expenses.rb +65 -0
- data/db/schema.sql +394 -229
- data/db/seed.rb +12 -12
- data/lib/skr/access_roles.rb +9 -4
- data/lib/skr/concerns/has_gl_transaction.rb +1 -1
- data/lib/skr/configuration.rb +3 -1
- data/lib/skr/db/migration_helpers.rb +2 -2
- data/lib/skr/handlers/approve_expense_entries.rb +16 -0
- data/lib/skr/handlers/invoice_from_time_entries.rb +1 -1
- data/lib/skr/handlers/sequential_ids.rb +2 -2
- data/lib/skr/jobs/fresh_books/import.rb +18 -17
- data/lib/skr/model.rb +3 -0
- data/lib/skr/models/bank_account.rb +9 -0
- data/lib/skr/models/expense_category.rb +27 -0
- data/lib/skr/models/expense_entry.rb +76 -0
- data/lib/skr/models/expense_entry_category.rb +15 -0
- data/lib/skr/models/gl_transaction.rb +2 -2
- data/lib/skr/models/inv_line.rb +3 -1
- data/lib/skr/models/invoice.rb +9 -5
- data/lib/skr/models/payment.rb +1 -1
- data/lib/skr/models/purchase_order.rb +4 -4
- data/lib/skr/models/uom.rb +2 -2
- data/lib/skr/models/voucher.rb +4 -4
- data/lib/skr/print/form.rb +17 -14
- data/lib/skr/version.rb +1 -1
- data/spec/fixtures/skr/expense_category.yml +17 -0
- data/spec/fixtures/skr/expense_entries.yml +20 -0
- data/spec/fixtures/skr/expense_entry_category.yml +19 -0
- data/spec/fixtures/skr/gl_account.yml +10 -0
- data/spec/server/handlers/invoice_from_time_entries_spec.rb +2 -2
- data/spec/server/handlers/sequential_ids_spec.rb +1 -1
- data/spec/server/models/expense_category_spec.rb +17 -0
- data/spec/server/models/expense_entry_spec.rb +44 -0
- data/spec/server/models/invoice_spec.rb +0 -1
- data/spec/server/models/spec_helper_spec.rb +5 -10
- data/spec/server/spec_helper.rb +12 -11
- data/spec/skr/components/SkuLinesSpec.coffee +11 -9
- data/spec/skr/models/CustomerSpec.coffee +1 -1
- data/spec/skr/models/ExpenseAccountSpec.coffee +5 -0
- data/spec/skr/screens/expense-categories/ExpenseCategoriesSpec.coffee +5 -0
- data/spec/skr/screens/expense-entry/ExpenseEntrySpec.coffee +5 -0
- data/spec/skr/screens/locations/LocationsSpec.coffee +4 -4
- data/spec/skr/screens/time-tracking/TimeTrackingSpec.coffee +4 -4
- data/stockor.gemspec +2 -3
- data/templates/print/partials/header.tex.erb +1 -1
- data/templates/print/partials/skus_table_invoice_footer.tex.erb +22 -19
- data/templates/print/partials/skus_table_invoice_info_line.tex.erb +5 -1
- data/templates/print/types/payment/default.tex.erb +10 -10
- metadata +40 -14
- data/client/skr/api/onReady.coffee +0 -23
- data/spec/skr/api/SingleItemCheckoutSpec.cjsx +0 -10
- data/spec/skr/screens/bank-maint/BankMaintSpec.coffee +0 -5
- data/spec/skr/screens/gl-accounts/GlAccountsSpec.coffee +0 -5
- data/spec/skr/screens/invoice/InvoiceSpec.coffee +0 -5
- data/spec/skr/screens/payment-category/PaymentCategorySpec.coffee +0 -5
- data/spec/skr/screens/payments/PaymentsSpec.coffee +0 -5
- data/spec/skr/screens/sale-report/SaleReportSpec.coffee +0 -5
@@ -3,7 +3,7 @@ class Skr.Screens.Payments extends Skr.Screens.Base
|
|
3
3
|
syncOptions:
|
4
4
|
include: [ 'address', 'bank_account', 'category', 'vendor' ]
|
5
5
|
|
6
|
-
|
6
|
+
modelBindings:
|
7
7
|
payment: ->
|
8
8
|
@loadOrCreateModel({
|
9
9
|
syncOptions: @syncOptions
|
@@ -16,7 +16,8 @@ class Skr.Screens.Payments extends Skr.Screens.Base
|
|
16
16
|
syncOptions: @syncOptions
|
17
17
|
src: Skr.Models.Payment, fields: [
|
18
18
|
{id:'id', visible: false}
|
19
|
-
{id:'visible_id',
|
19
|
+
{id:'visible_id', title: 'Payment ID', fixedWidth: 130 },
|
20
|
+
{id:'check_number', title: 'Check #', fixedWidth: 130 },
|
20
21
|
{id:'name', flex: 1}
|
21
22
|
{
|
22
23
|
id:'amount', fixedWidth: 120, textAlign: 'right',
|
@@ -32,17 +33,23 @@ class Skr.Screens.Payments extends Skr.Screens.Base
|
|
32
33
|
<LC.ScreenWrapper identifier="payments">
|
33
34
|
<SC.ScreenControls commands={@state.commands} />
|
34
35
|
<BS.Row>
|
35
|
-
<LC.RecordFinder ref="finder" sm=
|
36
|
+
<LC.RecordFinder ref="finder" sm=2 autoFocus editOnly
|
36
37
|
commands={@state.commands} model={@category}
|
37
38
|
label='Payment ID' name='visible_id' model={@payment} query={@query}
|
38
39
|
/>
|
39
40
|
<SC.LocationChooser hideSingle sm=2 model={@payment} />
|
40
41
|
<SC.BankAccountFinder selectField name='bank_account'
|
41
42
|
model={@payment} />
|
42
|
-
<SC.PaymentCategoryFinder selectField name='category'
|
43
|
+
<SC.PaymentCategoryFinder selectField name='category' sm=2
|
44
|
+
labelField='code' label="Cateogry" model={@payment} />
|
45
|
+
<LC.DateTime name='date' format='ddd, MMM Do YYYY' sm=3
|
43
46
|
model={@payment} />
|
44
|
-
<LC.
|
45
|
-
|
47
|
+
{<LC.DisplayValue align='right' label='Number' model={@payment}
|
48
|
+
name='check_number' sm=1
|
49
|
+
/> unless @payment.isNew()}
|
50
|
+
</BS.Row>
|
51
|
+
<BS.Row>
|
52
|
+
|
46
53
|
</BS.Row>
|
47
54
|
<BS.Row>
|
48
55
|
<SC.VendorFinder sm=2 selectField
|
@@ -4,7 +4,7 @@ class Skr.Screens.SalesOrder extends Lanes.React.Screen
|
|
4
4
|
include: [ 'billing_address', 'shipping_address', 'lines' ]
|
5
5
|
with: [ 'with_details' ]
|
6
6
|
|
7
|
-
|
7
|
+
modelBindings:
|
8
8
|
sales_order: ->
|
9
9
|
@loadOrCreateModel({
|
10
10
|
syncOptions: @syncOptions, klass: Skr.Models.SalesOrder
|
@@ -27,6 +27,7 @@ class Skr.Screens.SalesOrder extends Lanes.React.Screen
|
|
27
27
|
commands={@state.commands} />
|
28
28
|
|
29
29
|
<SC.CustomerFinder
|
30
|
+
fallBackValue={@sales_order.customer_code}
|
30
31
|
syncOptions={ include: ['billing_address', 'shipping_address' ] }
|
31
32
|
selectField sm=3 xs=4 model={@sales_order} />
|
32
33
|
|
@@ -35,7 +35,7 @@ class UomEdit extends Lanes.React.Component
|
|
35
35
|
list: React.PropTypes.instanceOf(UomList).isRequired
|
36
36
|
uom: React.PropTypes.instanceOf(Skr.Models.Uom).isRequired
|
37
37
|
|
38
|
-
|
38
|
+
modelBindings:
|
39
39
|
list: 'props'
|
40
40
|
uom: 'props'
|
41
41
|
|
@@ -79,7 +79,7 @@ class EditBody extends Lanes.React.Component
|
|
79
79
|
selected: React.PropTypes.instanceOf(Skr.Models.Uom)
|
80
80
|
uoms: Lanes.PropTypes.Collection.isRequired
|
81
81
|
|
82
|
-
|
82
|
+
modelBindings:
|
83
83
|
uoms: 'props'
|
84
84
|
|
85
85
|
add: ->
|
@@ -4,7 +4,7 @@ class Skr.Screens.TimeInvoicing extends Skr.Screens.Base
|
|
4
4
|
isEditing: true
|
5
5
|
commands: new Skr.Screens.Commands(this, modelName: 'request')
|
6
6
|
|
7
|
-
|
7
|
+
modelBindings:
|
8
8
|
request: -> new InvoiceRequest
|
9
9
|
query: ->
|
10
10
|
@gridSelections = new LC.Grid.Selections(onChange: @updateTotal)
|
@@ -27,7 +27,7 @@ class Skr.Screens.TimeInvoicing extends Skr.Screens.Base
|
|
27
27
|
]
|
28
28
|
})
|
29
29
|
|
30
|
-
|
30
|
+
setModelState: (state) ->
|
31
31
|
@updateTotal()
|
32
32
|
@setState(state)
|
33
33
|
|
@@ -37,7 +37,7 @@ class Skr.Screens.TimeInvoicing extends Skr.Screens.Base
|
|
37
37
|
return unless rate # the first call is when the model isn't parsed yet
|
38
38
|
selectedRows = 0
|
39
39
|
@query.results.eachRow (row, xd) ->
|
40
|
-
|
40
|
+
if LC.Grid.Selections.isSelected(row, xd)
|
41
41
|
selectedRows += 1
|
42
42
|
total = total.add( hoursForRow(row) * rate )
|
43
43
|
selectionState = if selectedRows is @query.results.length then 'all'
|
@@ -86,7 +86,7 @@ class Skr.Screens.TimeInvoicing extends Skr.Screens.Base
|
|
86
86
|
rs.eachRow (row) ->
|
87
87
|
xd = rs.xtraData(row)
|
88
88
|
xd.selected = false == xd.selected
|
89
|
-
@query.
|
89
|
+
@query.markModified()
|
90
90
|
renderToggleAllButton: ->
|
91
91
|
return null if 0 is @query.results.length
|
92
92
|
|
@@ -1,9 +1,9 @@
|
|
1
1
|
class Skr.Screens.TimeTracking.EditEntry extends Lanes.React.Component
|
2
2
|
|
3
|
-
|
3
|
+
modelBindings:
|
4
4
|
entry: -> @props.event?.get('entry')
|
5
5
|
|
6
|
-
|
6
|
+
setModelState: (change) ->
|
7
7
|
if change.event
|
8
8
|
@entry.fromCalEvent(change.event)
|
9
9
|
change.event.set({content: @entry.content}, {silent: true})
|
@@ -11,8 +11,7 @@ class TimeEntries extends Skr.Models.TimeEntry.Collection
|
|
11
11
|
query.start_at = { op: 'lt', value: range.end.toISOString() }
|
12
12
|
@fetch({query, reset: true})
|
13
13
|
|
14
|
-
resetEntries: (projectId, range) ->
|
15
|
-
@projectId = projectId
|
14
|
+
resetEntries: (@projectId, range) ->
|
16
15
|
query = if @projectId and @projectId isnt -1
|
17
16
|
{customer_project_id: @projectId}
|
18
17
|
else {}
|
@@ -71,6 +70,9 @@ class Skr.Screens.TimeTracking.Entries extends Lanes.Models.Base
|
|
71
70
|
for event in @calEvents().events
|
72
71
|
event.setEditing(event is editingEvent)
|
73
72
|
|
73
|
+
removeEntry: (entry) ->
|
74
|
+
@entries.remove(entry)
|
75
|
+
|
74
76
|
stopEditing: ->
|
75
77
|
for event in @calEvents().events when event.isEditing()
|
76
78
|
entry = event.get('entry')
|
@@ -85,7 +87,7 @@ class Skr.Screens.TimeTracking.Entries extends Lanes.Models.Base
|
|
85
87
|
date.minute(rounded).second(0)
|
86
88
|
entry = @entries.add({
|
87
89
|
start_at: date.subtract(1, 'hour'), end_at: date.clone().add(2, 'hour')
|
88
|
-
customer_project: @project unless @project
|
90
|
+
customer_project: @project unless @project?.id is -1
|
89
91
|
})
|
90
92
|
@calEvents().add( entry.toCalEvent() )
|
91
93
|
|
@@ -105,7 +107,7 @@ class Skr.Screens.TimeTracking.Entries extends Lanes.Models.Base
|
|
105
107
|
@entries.resetEntries(@customer_project_id, @range)
|
106
108
|
|
107
109
|
calEvents: ->
|
108
|
-
@_cachedEvents ||= new LC.Calendar.Events( @entries.
|
110
|
+
@_cachedEvents ||= new LC.Calendar.Events( @entries.invokeMap('toCalEvent') )
|
109
111
|
|
110
112
|
back: ->
|
111
113
|
@set(editing: false, date: @date.clone().subtract(1, @display) )
|
@@ -1,6 +1,7 @@
|
|
1
1
|
##= require ./PopoverMiniControls
|
2
2
|
##= require ./EditEntry
|
3
3
|
|
4
|
+
MARGIN = 10
|
4
5
|
class Skr.Screens.TimeTracking.Popover extends Lanes.React.Component
|
5
6
|
|
6
7
|
componentWillReceiveProps: (nextProps) ->
|
@@ -10,8 +11,11 @@ class Skr.Screens.TimeTracking.Popover extends Lanes.React.Component
|
|
10
11
|
@setState(isCanceled: false)
|
11
12
|
|
12
13
|
onCancel: ->
|
13
|
-
|
14
|
+
entry = @state.editing.get('entry')
|
15
|
+
if entry.isNew()
|
14
16
|
@state.editing.remove()
|
17
|
+
@props.entries.removeEntry(entry)
|
18
|
+
|
15
19
|
@props.entries.stopEditing()
|
16
20
|
@setState(isCanceled: true, editing: null)
|
17
21
|
|
@@ -51,19 +55,20 @@ class Skr.Screens.TimeTracking.Popover extends Lanes.React.Component
|
|
51
55
|
else
|
52
56
|
[175, 60]
|
53
57
|
|
54
|
-
# expand to show edit button
|
55
58
|
width += 60 if @props.event and not @state.editing
|
56
|
-
|
57
|
-
placement = if x > (this.props.bounds.width / 2) then 'left' else 'right'
|
58
|
-
|
59
|
+
placement = if x > (@props.bounds.width / 2) then 'left' else 'right'
|
59
60
|
x -= width if placement is 'left'
|
61
|
+
top = Math.max( MARGIN, y - (height / 2) )
|
62
|
+
if top + height > @props.bounds.height
|
63
|
+
top = @props.bounds.height - height - MARGIN
|
60
64
|
|
61
65
|
<BS.Popover className={classes}
|
62
66
|
style={{width, height}}
|
63
67
|
id='edit-controls'
|
68
|
+
arrowOffsetTop={y - top}
|
64
69
|
placement={placement}
|
65
70
|
positionLeft={x}
|
66
|
-
positionTop={
|
71
|
+
positionTop={top}
|
67
72
|
>
|
68
73
|
<@MiniControls />
|
69
74
|
<@EditEntry />
|
@@ -6,7 +6,7 @@
|
|
6
6
|
|
7
7
|
class Skr.Screens.TimeTracking extends Skr.Screens.Base
|
8
8
|
|
9
|
-
|
9
|
+
modelBindings:
|
10
10
|
entries: ->
|
11
11
|
new Skr.Screens.TimeTracking.Entries
|
12
12
|
|
@@ -14,10 +14,9 @@ class Skr.Screens.TimeTracking extends Skr.Screens.Base
|
|
14
14
|
@showPopup(ev, date)
|
15
15
|
|
16
16
|
showPopup: (ev, date, eventEditing = false) ->
|
17
|
-
rect = _.dom(this).
|
17
|
+
rect = _.dom(this).bounds
|
18
18
|
@entries.editing = {
|
19
|
-
event: eventEditing,
|
20
|
-
date: date, bounds: rect,
|
19
|
+
date: date, event: eventEditing, bounds: rect
|
21
20
|
position: {x: ev.clientX - rect.left, y: ev.clientY - rect.top}
|
22
21
|
}
|
23
22
|
|
@@ -42,9 +41,17 @@ class Skr.Screens.TimeTracking extends Skr.Screens.Base
|
|
42
41
|
return null unless @entries.isMonth
|
43
42
|
<div className="monthly-totals">{@entries.totalHours().toFixed(2)}</div>
|
44
43
|
|
44
|
+
getHeight: ->
|
45
|
+
_.dom(@).getBoundingClientRect().height
|
46
|
+
|
45
47
|
render: ->
|
48
|
+
|
46
49
|
<LC.ScreenWrapper identifier="time-tracking" flexVertical>
|
47
|
-
<Skr.Screens.TimeTracking.Popover
|
50
|
+
<Skr.Screens.TimeTracking.Popover
|
51
|
+
getHeight={@getHeight}
|
52
|
+
entries={@entries}
|
53
|
+
{...@entries.editing}
|
54
|
+
/>
|
48
55
|
<LC.NetworkActivityOverlay visible={@entries.isLoading} model={@entries}/>
|
49
56
|
<Skr.Screens.TimeTracking.Header entries={@entries} />
|
50
57
|
<BS.Row className="calendar-panel">
|
@@ -3,7 +3,7 @@ class Skr.Screens.VendorMaint extends Lanes.React.Screen
|
|
3
3
|
syncOptions:
|
4
4
|
include: ['billing_address', 'shipping_address']
|
5
5
|
|
6
|
-
|
6
|
+
modelBindings:
|
7
7
|
vendor: ->
|
8
8
|
@loadOrCreateModel({
|
9
9
|
syncOptions: @syncOptions, klass: Skr.Models.Vendor,
|
@@ -31,9 +31,9 @@ class Skr.Screens.VendorMaint extends Lanes.React.Screen
|
|
31
31
|
<BS.Row>
|
32
32
|
<SC.GlAccountChooser sm=4 label="Payables Account"
|
33
33
|
name="gl_payables_account" model={@vendor} />
|
34
|
+
<SC.TermsChooser sm=4 model={@vendor} />
|
34
35
|
<SC.GlAccountChooser sm=4 label="Freight Account"
|
35
36
|
name="gl_freight_account" model={@vendor} />
|
36
|
-
<SC.TermsChooser sm=4 model={@vendor} />
|
37
37
|
</BS.Row>
|
38
38
|
<BS.Row>
|
39
39
|
<LC.FieldSet sm=12 title="Address">
|
data/config/database.yml
CHANGED
data/config/puma.rb
CHANGED
data/config/routes.rb
CHANGED
@@ -37,9 +37,13 @@ Lanes::API.routes.for_extension 'skr' do
|
|
37
37
|
resources Skr::VoLine
|
38
38
|
resources Skr::SalesOrder
|
39
39
|
resources Skr::SoLine
|
40
|
+
resources Skr::ExpenseCategory
|
41
|
+
resources Skr::ExpenseEntry
|
40
42
|
resources Skr::SequentialId, controller: Skr::Handlers::SequentialIds
|
41
43
|
resources Skr::Invoice, controller: Skr::Handlers::InvoiceFromTimeEntries,
|
42
44
|
path: 'invoices/from-time-entries'
|
45
|
+
resources Skr::ExpenseEntry, controller: Skr::Handlers::ApproveExpenseEntries,
|
46
|
+
path: 'expense-entries/approve'
|
43
47
|
resources Skr::Sku, path: 'public/skus', controller: Skr::Handlers::Skus, cors: '*', public: true
|
44
48
|
resources Skr::Invoice, path: 'public/sales', controller: Skr::Handlers::Sales, cors: '*', public: true
|
45
49
|
get 'credit-card-gateways.json', &Skr::Handlers::CreditCardGateway.get
|
data/config/screens.rb
CHANGED
@@ -79,6 +79,14 @@ Lanes::Screen.for_extension 'skr' do | screens |
|
|
79
79
|
screen.model_class = "PaymentTerm"
|
80
80
|
screen.view_class = "PaymentTerms"
|
81
81
|
end
|
82
|
+
screens.define "expense-categories" do | screen |
|
83
|
+
screen.title = "Expense Categories"
|
84
|
+
screen.description = ""
|
85
|
+
screen.icon = "folder-open"
|
86
|
+
screen.group_id = "accounting"
|
87
|
+
screen.model_class = "ExpenseCategory"
|
88
|
+
screen.view_class = "ExpenseCategories"
|
89
|
+
end
|
82
90
|
screens.define "payment-category" do | screen |
|
83
91
|
screen.title = "Payment Categories"
|
84
92
|
screen.description = ""
|
@@ -187,4 +195,13 @@ Lanes::Screen.for_extension 'skr' do | screens |
|
|
187
195
|
screen.model_class = "TimeEntry"
|
188
196
|
screen.view_class = "TimeTracking"
|
189
197
|
end
|
198
|
+
screens.define "expense-entry" do | screen |
|
199
|
+
screen.title = "Expense Entry"
|
200
|
+
screen.description = ""
|
201
|
+
screen.icon = "shopping-bag"
|
202
|
+
screen.group_id = "customer"
|
203
|
+
screen.model_class = "ExpenseEntry"
|
204
|
+
screen.view_class = "ExpenseEntry"
|
205
|
+
end
|
206
|
+
|
190
207
|
end
|
@@ -2,7 +2,7 @@ require 'skr/db/migration_helpers'
|
|
2
2
|
|
3
3
|
class CreateSoDetailsView < ActiveRecord::Migration
|
4
4
|
def up
|
5
|
-
fk = "
|
5
|
+
fk = "sales_order_id"
|
6
6
|
execute <<-EOS.squish
|
7
7
|
create view #{skr_prefix}so_details as
|
8
8
|
select so.id as #{fk},
|
@@ -76,7 +76,7 @@ class CreateSoDetailsView < ActiveRecord::Migration
|
|
76
76
|
end
|
77
77
|
|
78
78
|
def down
|
79
|
-
execute "drop view #{skr_prefix}
|
79
|
+
execute "drop view #{skr_prefix}so_details"
|
80
80
|
execute "drop view #{skr_prefix}so_allocation_details"
|
81
81
|
execute "drop view #{skr_prefix}so_dailly_sales_history"
|
82
82
|
end
|
@@ -6,7 +6,7 @@ class CreateCustomerProjectDetailsViews < ActiveRecord::Migration
|
|
6
6
|
execute <<-EOS
|
7
7
|
create view #{view} as
|
8
8
|
select
|
9
|
-
cp.id as
|
9
|
+
cp.id as customer_project_id,
|
10
10
|
c.code as customer_code,
|
11
11
|
c.name as customer_description,
|
12
12
|
s.code as sku_code,
|
@@ -4,7 +4,7 @@ class CreateGlAccountBalancesView < ActiveRecord::Migration
|
|
4
4
|
def up
|
5
5
|
execute <<-EOS.squish
|
6
6
|
create view #{skr_prefix}gl_account_balances as select
|
7
|
-
gla.id as
|
7
|
+
gla.id as gl_account_id,
|
8
8
|
right(glp.account_number,2) as branch_number,
|
9
9
|
coalesce(sum(glp.amount), 0.00) as balance
|
10
10
|
from skr_gl_accounts gla
|
@@ -0,0 +1,65 @@
|
|
1
|
+
require 'skr/db/migration_helpers'
|
2
|
+
|
3
|
+
class CreateExpenses < ActiveRecord::Migration
|
4
|
+
def up
|
5
|
+
|
6
|
+
create_skr_table :expense_categories do |t|
|
7
|
+
t.skr_code_identifier
|
8
|
+
t.string :name, null: false
|
9
|
+
t.boolean :is_active, null: false, default: true
|
10
|
+
t.skr_reference :gl_account, null: false, single: true
|
11
|
+
t.skr_track_modifications
|
12
|
+
end
|
13
|
+
|
14
|
+
create_skr_table(:expense_entries) do |t|
|
15
|
+
t.column :uuid, 'uuid', null: false
|
16
|
+
t.text :name, null: false
|
17
|
+
t.text :memo
|
18
|
+
t.timestamp :occured, null: false
|
19
|
+
t.jsonb :metadata, default: {}
|
20
|
+
t.skr_track_modifications create_only: true
|
21
|
+
end
|
22
|
+
skr_add_index :expense_entries, :uuid, unique: true
|
23
|
+
|
24
|
+
create_skr_table(:expense_entry_categories) do |t|
|
25
|
+
t.skr_reference :category, to_table: 'expense_categories', single: true
|
26
|
+
t.skr_reference :entry, to_table: 'expense_entries', single: true
|
27
|
+
t.skr_currency :amount, null: false
|
28
|
+
end
|
29
|
+
skr_add_index :expense_entry_categories, :entry_id, unique: false
|
30
|
+
|
31
|
+
execute <<-EOS
|
32
|
+
create or replace view skr_expense_entry_details as
|
33
|
+
select
|
34
|
+
xref.expense_entry_id,
|
35
|
+
array_agg(xref.gl_transaction_id) filter (where xref.gl_transaction_id is not NULL) as gl_transaction_ids,
|
36
|
+
array_agg(xref.category_id) as category_ids,
|
37
|
+
sum(amount) as category_total,
|
38
|
+
json_agg(row_to_json(
|
39
|
+
(select t from (select category_id, amount, balance) as t(category_id, amount, balance))
|
40
|
+
)
|
41
|
+
) category_list
|
42
|
+
from (
|
43
|
+
select
|
44
|
+
entry.id as expense_entry_id,
|
45
|
+
gl.id as gl_transaction_id,
|
46
|
+
category_id, ec.amount,
|
47
|
+
sum(amount) over (partition by category_id order by occured) as balance
|
48
|
+
from
|
49
|
+
skr_expense_entries entry
|
50
|
+
left join skr_gl_transactions gl on
|
51
|
+
gl.source_type='Skr::ExpenseEntry' and gl.source_id = entry.id
|
52
|
+
join
|
53
|
+
skr_expense_entry_categories ec on entry.id = ec.entry_id
|
54
|
+
) as xref
|
55
|
+
group by expense_entry_id
|
56
|
+
EOS
|
57
|
+
end
|
58
|
+
|
59
|
+
def down
|
60
|
+
execute "drop view skr_expense_entry_details"
|
61
|
+
drop_skr_table :expense_entry_categories
|
62
|
+
drop_skr_table :expense_categories
|
63
|
+
drop_skr_table :expense_entries
|
64
|
+
end
|
65
|
+
end
|