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
@@ -12,8 +12,9 @@ class Skr.Components.Currency extends Lanes.React.Component
|
|
12
12
|
symbol: React.PropTypes.string
|
13
13
|
|
14
14
|
render: ->
|
15
|
+
colProps = _.omit(@props, _.keys(@constructor.propTypes))
|
15
16
|
className = _.classnames 'currency', @props.className
|
16
|
-
<span {
|
17
|
+
<span {...colProps} className={className}>
|
17
18
|
<span className="sym">{@props.symbol}</span>
|
18
19
|
{Lanes.u.format.currency(@props.amount)}
|
19
20
|
</span>
|
@@ -10,7 +10,7 @@ class Skr.Components.CustomerFinder extends Lanes.React.Component
|
|
10
10
|
getDefaultProps: ->
|
11
11
|
autoFocus: false, label: 'Customer Code', name: 'customer'
|
12
12
|
|
13
|
-
|
13
|
+
modelBindings:
|
14
14
|
query: ->
|
15
15
|
new Lanes.Models.Query({
|
16
16
|
syncOptions: @props.syncOptions, autoRetrieve: true
|
@@ -10,7 +10,7 @@ class Skr.Components.CustomerProjectFinder extends Lanes.React.Component
|
|
10
10
|
getDefaultProps: ->
|
11
11
|
autoFocus: false, label: 'Project Code', name: 'code'
|
12
12
|
|
13
|
-
|
13
|
+
modelBindings:
|
14
14
|
query: ->
|
15
15
|
new Lanes.Models.Query({
|
16
16
|
autoRetrieve: true, syncOptions:
|
@@ -0,0 +1,34 @@
|
|
1
|
+
class Skr.Components.ExpenseCategoryFinder extends Lanes.React.Component
|
2
|
+
|
3
|
+
propTypes:
|
4
|
+
model: Lanes.PropTypes.Model
|
5
|
+
commands: React.PropTypes.object
|
6
|
+
autoFocus: React.PropTypes.bool
|
7
|
+
name: React.PropTypes.string
|
8
|
+
selectField: React.PropTypes.bool
|
9
|
+
|
10
|
+
getDefaultProps: ->
|
11
|
+
autoFocus: false, label: 'Expense Category', name: 'code'
|
12
|
+
|
13
|
+
modelBindings:
|
14
|
+
query: ->
|
15
|
+
new Lanes.Models.Query({
|
16
|
+
syncOptions: @props.syncOptions, autoRetrieve: true
|
17
|
+
src: Skr.Models.ExpenseCategory, fields: [
|
18
|
+
{id:'id', visible: false}
|
19
|
+
{id: 'code', fixedWidth: 130 },
|
20
|
+
{id: 'name', flex: 1}
|
21
|
+
]
|
22
|
+
})
|
23
|
+
|
24
|
+
render: ->
|
25
|
+
props = _.clone(@props)
|
26
|
+
|
27
|
+
if props.selectField
|
28
|
+
<LC.SelectField queryModel={Skr.Models.ExpenseCategory}
|
29
|
+
labelField='code' sm=2 {...props} fetchOnSelect={false} />
|
30
|
+
else
|
31
|
+
<LC.RecordFinder ref="finder" sm=3 autoFocus
|
32
|
+
commands={@props.commands}
|
33
|
+
query={@query}
|
34
|
+
{...props} />
|
@@ -9,7 +9,7 @@ class Skr.Components.GlAccountChooser extends Lanes.React.Component
|
|
9
9
|
getDefaultProps: ->
|
10
10
|
label: 'Account', name: 'gl_account'
|
11
11
|
|
12
|
-
|
12
|
+
modelBindings:
|
13
13
|
query: ->
|
14
14
|
new Lanes.Models.Query({
|
15
15
|
syncOptions: @props.syncOptions, autoRetrieve: true
|
@@ -34,5 +34,6 @@ class Skr.Components.GlAccountChooser extends Lanes.React.Component
|
|
34
34
|
choices={Skr.Models.GlAccount.all.models}
|
35
35
|
labelField="combined_name"
|
36
36
|
model={@props.model}
|
37
|
+
filter='contains'
|
37
38
|
{...props}
|
38
39
|
/>
|
@@ -1,14 +1,13 @@
|
|
1
1
|
class Skr.Components.LocationChooser extends Lanes.React.Component
|
2
2
|
|
3
3
|
propTypes:
|
4
|
-
onModelSet: React.PropTypes.func
|
5
4
|
name: React.PropTypes.string
|
6
5
|
hideSingle: React.PropTypes.bool
|
7
6
|
|
8
7
|
getDefaultProps: ->
|
9
8
|
label: 'Location', name: 'location'
|
10
9
|
|
11
|
-
|
10
|
+
modelBindings:
|
12
11
|
query: ->
|
13
12
|
new Lanes.Models.Query({
|
14
13
|
autoRetrieve: true
|
@@ -26,7 +25,8 @@ class Skr.Components.LocationChooser extends Lanes.React.Component
|
|
26
25
|
if @props.hideSingle and Skr.Models.Location.all.length < 2
|
27
26
|
return LC.SelectField.renderEmptyColumn(@props)
|
28
27
|
|
29
|
-
props = _.
|
28
|
+
props = _.omit(@props, 'hideSingle')
|
29
|
+
|
30
30
|
if props.displayFinder
|
31
31
|
<LC.RecordFinder ref="finder" sm=3 autoFocus
|
32
32
|
commands={@state.commands}
|
@@ -10,7 +10,7 @@ class Skr.Components.PaymentCategoryFinder extends Lanes.React.Component
|
|
10
10
|
getDefaultProps: ->
|
11
11
|
autoFocus: false, label: 'Payment Category', name: 'payment_category'
|
12
12
|
|
13
|
-
|
13
|
+
modelBindings:
|
14
14
|
query: ->
|
15
15
|
new Lanes.Models.Query({
|
16
16
|
syncOptions: @props.syncOptions, autoRetrieve: true
|
@@ -7,10 +7,9 @@ class Skr.Components.SalesOrderFinder extends Lanes.React.Component
|
|
7
7
|
autoFocus: React.PropTypes.bool
|
8
8
|
|
9
9
|
getDefaultProps: ->
|
10
|
-
editing: true
|
11
10
|
autoFocus: true, name: 'visible_id', label: 'Sales Order #'
|
12
11
|
|
13
|
-
|
12
|
+
modelBindings:
|
14
13
|
query: ->
|
15
14
|
new Lanes.Models.Query({
|
16
15
|
initialFieldIndex: 1, title: 'Sales Order', autoRetrieve: true
|
@@ -11,7 +11,7 @@ class Skr.Components.SkuFinder extends Lanes.React.Component
|
|
11
11
|
getDefaultProps: ->
|
12
12
|
autoFocus: false, label: 'SKU', name: 'code'
|
13
13
|
|
14
|
-
|
14
|
+
modelBindings:
|
15
15
|
query: ->
|
16
16
|
new Lanes.Models.Query({
|
17
17
|
syncOptions: @props.syncOptions, autoRetrieve: true
|
@@ -9,7 +9,7 @@ class Skr.Components.TermsChooser extends Lanes.React.Component
|
|
9
9
|
getDefaultProps: ->
|
10
10
|
label: 'Payment Terms', name: 'terms'
|
11
11
|
|
12
|
-
|
12
|
+
modelBindings:
|
13
13
|
query: ->
|
14
14
|
new Lanes.Models.Query({
|
15
15
|
syncOptions: @props.syncOptions, autoRetrieve: true
|
@@ -36,5 +36,5 @@ class Skr.Components.TermsChooser extends Lanes.React.Component
|
|
36
36
|
choices={Skr.Models.PaymentTerm.all.models}
|
37
37
|
labelField="code"
|
38
38
|
{...@props}
|
39
|
-
|
39
|
+
fetchOnSelect={false}
|
40
40
|
model={@props.model} />
|
@@ -1,7 +1,11 @@
|
|
1
1
|
class Skr.Components.ToolbarButton extends Lanes.React.BaseComponent
|
2
2
|
|
3
|
+
propTypes:
|
4
|
+
onClick: React.PropTypes.func.isRequired
|
5
|
+
className: React.PropTypes.string
|
6
|
+
|
3
7
|
render: ->
|
4
|
-
cn = _.classnames "navbar-btn", "control", @props.
|
5
|
-
<BS.
|
8
|
+
cn = _.classnames "navbar-btn", "control", @props.className
|
9
|
+
<BS.NavItem onClick={@props.onClick} className={cn}>
|
6
10
|
{@props.children}
|
7
|
-
</BS.
|
11
|
+
</BS.NavItem>
|
@@ -5,12 +5,16 @@ class Skr.Components.TotalsLine extends Lanes.React.Component
|
|
5
5
|
attribute: React.PropTypes.string
|
6
6
|
label: React.PropTypes.string
|
7
7
|
|
8
|
+
|
8
9
|
getDefaultProps: ->
|
9
10
|
attribute: 'total', label: 'Total:'
|
10
11
|
|
11
12
|
render: ->
|
12
13
|
<BS.Row className='totals'>
|
13
|
-
<BS.Col lg=
|
14
|
+
<BS.Col lg=10 sm=9 xs=8 className="text-right">
|
15
|
+
{@props.extraInfo}
|
16
|
+
</BS.Col>
|
17
|
+
<BS.Col xs=1 className="text-right">
|
14
18
|
<h4>{@props.label}</h4>
|
15
19
|
</BS.Col>
|
16
20
|
<BS.Col lg=1 sm=2 xs=3 className="total">
|
@@ -1,7 +1,20 @@
|
|
1
1
|
class Skr.Components.Address extends Lanes.React.Component
|
2
2
|
|
3
3
|
propTypes:
|
4
|
+
title: React.PropTypes.string
|
4
5
|
model: Lanes.PropTypes.State.isRequired
|
6
|
+
copyFrom: Lanes.PropTypes.State
|
7
|
+
|
8
|
+
modelBindings:
|
9
|
+
model: 'props'
|
10
|
+
copyFrom: -> @props.copyFrom or false
|
11
|
+
|
12
|
+
setModelState: (addr) ->
|
13
|
+
if (addr is @props.copyFrom)
|
14
|
+
for attr, val of addr.changedAttributes() when attr isnt 'isDirty'
|
15
|
+
@model[attr] = val if addr.previous(attr) is @model[attr]
|
16
|
+
else
|
17
|
+
@forceUpdate()
|
5
18
|
|
6
19
|
renderTitle: ->
|
7
20
|
<BS.Row>
|
@@ -11,7 +24,7 @@ class Skr.Components.Address extends Lanes.React.Component
|
|
11
24
|
</BS.Row>
|
12
25
|
|
13
26
|
render: ->
|
14
|
-
colProps = _.omit(@props,
|
27
|
+
colProps = _.omit(@props, _.keys(@constructor.propTypes))
|
15
28
|
colProps.className = _.classnames("address", @props.className)
|
16
29
|
|
17
30
|
<BS.Col {...colProps}>
|
data/client/skr/index.js
CHANGED
@@ -0,0 +1,32 @@
|
|
1
|
+
readLoadUrl = (matchRegex) ->
|
2
|
+
src = document.createElement('a')
|
3
|
+
for tag in document.querySelectorAll('script')
|
4
|
+
if tag.src.match matchRegex
|
5
|
+
src.href = tag.src
|
6
|
+
Lanes.config.api_host = src.host
|
7
|
+
break
|
8
|
+
if Lanes.config.api_host
|
9
|
+
css = src.href.replace(/\.js$/, '.css')
|
10
|
+
new Lanes.lib.AssetLoader([css], Lanes.emptyFn)
|
11
|
+
else
|
12
|
+
console.error("Unable to find script tag that Stockor was loaded from")
|
13
|
+
|
14
|
+
|
15
|
+
Skr.lib.Remote = {
|
16
|
+
|
17
|
+
onDocumentReady: (fn) ->
|
18
|
+
if document.readyState isnt 'loading'
|
19
|
+
fn()
|
20
|
+
else if document.addEventListener
|
21
|
+
document.addEventListener 'DOMContentLoaded', fn
|
22
|
+
else
|
23
|
+
document.attachEvent 'onreadystatechange', ->
|
24
|
+
fn() if document.readyState != 'loading'
|
25
|
+
|
26
|
+
configFromScriptTag: (matchRegex = /\/assets\/skr\/api\.js$/) ->
|
27
|
+
new _.Promise (resolve) ->
|
28
|
+
Skr.lib.Remote.onDocumentReady ->
|
29
|
+
readLoadUrl(matchRegex)
|
30
|
+
resolve(Lanes.config)
|
31
|
+
|
32
|
+
}
|
@@ -0,0 +1 @@
|
|
1
|
+
Skr.lib ||= {}
|
@@ -0,0 +1,11 @@
|
|
1
|
+
class Skr.Models.ExpenseCategory extends Skr.Models.Base
|
2
|
+
|
3
|
+
props:
|
4
|
+
id: {"type":"integer"}
|
5
|
+
code: {"type":"code", "required":true}
|
6
|
+
name: {"type":"string", "required":true}
|
7
|
+
is_active: {"type":"boolean", "required":true, default: true}
|
8
|
+
gl_account_id:{"type":"integer", "required":true}
|
9
|
+
|
10
|
+
associations:
|
11
|
+
gl_account: { model: "GlAccount" }
|
@@ -0,0 +1,64 @@
|
|
1
|
+
class ExpenseAssets extends Lanes.Models.AssociationCollection
|
2
|
+
|
3
|
+
|
4
|
+
comparator: (a) -> ! a.isPresent
|
5
|
+
|
6
|
+
constructor: ->
|
7
|
+
super
|
8
|
+
@listenTo(@parent, 'save', @onSave)
|
9
|
+
@on('change:length', @ensureBlank)
|
10
|
+
@on('change:isPresent', @ensureBlank)
|
11
|
+
@ensureBlank()
|
12
|
+
@present = @subcollection(watched: ['isPresent'], filter: (m) ->
|
13
|
+
m.isPresent
|
14
|
+
)
|
15
|
+
|
16
|
+
|
17
|
+
getId: -> @parent.getId()
|
18
|
+
modelTypeIdentifier: -> @parent.modelTypeIdentifier()
|
19
|
+
extensionIdentifier: -> @parent.extensionIdentifier()
|
20
|
+
|
21
|
+
ensureBlank: ->
|
22
|
+
blank = @find( (asset) -> !asset.isPresent )
|
23
|
+
@add({}) unless blank
|
24
|
+
|
25
|
+
onSave: ->
|
26
|
+
@each (asset) -> asset.save()
|
27
|
+
|
28
|
+
_prepareModel: (attrs, options) ->
|
29
|
+
attrs.parent || = @
|
30
|
+
attrs.parent_association = @options.association_name
|
31
|
+
super
|
32
|
+
|
33
|
+
|
34
|
+
class Skr.Models.ExpenseEntry extends Skr.Models.Base
|
35
|
+
|
36
|
+
props:
|
37
|
+
id: {type:"integer"}
|
38
|
+
uuid: {"type":"string"}
|
39
|
+
name: {"type":"string", "required":true}
|
40
|
+
occured: {"type":"date", "required":true}
|
41
|
+
gl_transaction_id: "integer"
|
42
|
+
memo: "string"
|
43
|
+
expense_category_id: {"type":"integer", "required":true}
|
44
|
+
|
45
|
+
session:
|
46
|
+
category_total: type:"bigdec", "required":true
|
47
|
+
category_list: type: "object"
|
48
|
+
gl_transaction_ids: type: 'array'
|
49
|
+
category_ids: type: 'array'
|
50
|
+
|
51
|
+
associations:
|
52
|
+
categories: { collection: "ExpenseEntryCategory", inverse: 'entry' }
|
53
|
+
gl_transaction: { model: "GlTransaction" }
|
54
|
+
attachments: { collection: "Lanes.Models.Asset", options: { 'collectionClass': ExpenseAssets } }
|
55
|
+
|
56
|
+
dataForSave: ->
|
57
|
+
super(includeAssociations: [
|
58
|
+
'categories'
|
59
|
+
])
|
60
|
+
|
61
|
+
total: ->
|
62
|
+
@categories.reduce (amt, cat) ->
|
63
|
+
cat.amount.add(amt)
|
64
|
+
, _.bigDecimal('0')
|
@@ -0,0 +1,11 @@
|
|
1
|
+
class Skr.Models.ExpenseEntryCategory extends Skr.Models.Base
|
2
|
+
|
3
|
+
props:
|
4
|
+
id: {"type":"any", "required":true}
|
5
|
+
entry_id: "integer"
|
6
|
+
category_id: {"type":"integer", "required":true}
|
7
|
+
amount: {"type":"bigdec"}
|
8
|
+
|
9
|
+
associations:
|
10
|
+
category: { model: "ExpenseCategory" }
|
11
|
+
entry: { model: "ExpenseEntry" }
|
@@ -25,11 +25,14 @@ class Skr.Models.Invoice extends Skr.Models.Base
|
|
25
25
|
|
26
26
|
mixins: [ 'HasVisibleId', 'PrintSupport' ]
|
27
27
|
|
28
|
-
# optional attributes from details view
|
28
|
+
# optional attributes from details view and other fields
|
29
29
|
session:
|
30
30
|
customer_code: {type:"string"}
|
31
|
+
customer_name: {type:"string"}
|
31
32
|
invoice_total: {type:"bigdec"}
|
32
33
|
amount_paid: {type:"bigdec", "default":"0"}
|
34
|
+
total_hours: "bigdec"
|
35
|
+
num_lines: {type:"integer"}
|
33
36
|
|
34
37
|
derived:
|
35
38
|
prev_amount_paid: deps:['updated_at'], fn: -> @amount_paid
|