stockor 0.3.0 → 0.4.0

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.
Files changed (142) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +3 -0
  3. data/.rubocop.yml +15 -0
  4. data/Gemfile +3 -1
  5. data/Gemfile.lock +97 -193
  6. data/client/skr/Extension.coffee +8 -4
  7. data/client/skr/api.js +21 -0
  8. data/client/skr/api.scss +148 -0
  9. data/client/skr/api/Components/AddressForm.cjsx +47 -0
  10. data/client/skr/api/Components/Base.coffee +7 -0
  11. data/client/skr/api/Components/SaleHistory.cjsx +32 -0
  12. data/client/skr/api/Components/SingleItemCart.cjsx +30 -0
  13. data/client/skr/api/Models/Base.coffee +10 -0
  14. data/client/skr/api/Models/Cart.coffee +40 -0
  15. data/client/skr/api/Models/Sale.coffee +43 -0
  16. data/client/skr/api/Models/SalesHistory.coffee +17 -0
  17. data/client/skr/api/Models/Sku.coffee +16 -0
  18. data/client/skr/api/SingleItemCheckout.cjsx +99 -0
  19. data/client/skr/api/namespace.js +6 -0
  20. data/client/skr/api/onReady.coffee +23 -0
  21. data/client/skr/components/CreditCardForm.cjsx +35 -0
  22. data/client/skr/components/CustomerFinder.cjsx +0 -3
  23. data/client/skr/components/InvoiceFinder.cjsx +1 -0
  24. data/client/skr/components/LatexSnippets.cjsx +65 -0
  25. data/client/skr/components/LocationChooser.cjsx +5 -1
  26. data/client/skr/components/PrintButton.cjsx +33 -0
  27. data/client/skr/components/PrintFormChooser.cjsx +10 -10
  28. data/client/skr/components/SalesOrderFinder.cjsx +2 -1
  29. data/client/skr/components/SystemSettings.cjsx +69 -9
  30. data/client/skr/components/address/index.js +1 -0
  31. data/client/skr/models/Address.coffee +3 -0
  32. data/client/skr/models/CreditCard.coffee +49 -0
  33. data/client/skr/models/CreditCardGateway.coffee +27 -0
  34. data/client/skr/models/Invoice.coffee +13 -5
  35. data/client/skr/models/Location.coffee +6 -4
  36. data/client/skr/models/Payment.coffee +33 -13
  37. data/client/skr/models/SalesOrder.coffee +7 -3
  38. data/client/skr/models/SequentialId.coffee +17 -0
  39. data/client/skr/models/Sku.coffee +1 -1
  40. data/client/skr/models/TimeEntry.coffee +3 -4
  41. data/client/skr/models/mixins/PrintSupport.coffee +4 -1
  42. data/client/skr/models/mixins/SkuLine.coffee +1 -1
  43. data/client/skr/screens/customer-maint/CustomerMaint.cjsx +1 -2
  44. data/client/skr/screens/customer-projects/CustomerProjects.cjsx +7 -3
  45. data/client/skr/screens/customer-projects/index.scss +1 -0
  46. data/client/skr/screens/fresh-books-import/ApiInfo.cjsx +1 -1
  47. data/client/skr/screens/gl-accounts/GlAccounts.cjsx +1 -1
  48. data/client/skr/screens/gl-transactions/GlTransactions.cjsx +1 -1
  49. data/client/skr/screens/invoice/Invoice.cjsx +9 -17
  50. data/client/skr/screens/invoice/Payment.cjsx +94 -13
  51. data/client/skr/screens/invoice/index.scss +32 -0
  52. data/client/skr/screens/locations/Locations.cjsx +3 -2
  53. data/client/skr/screens/payment-category/PaymentCategory.cjsx +1 -1
  54. data/client/skr/screens/payments/Payments.cjsx +5 -4
  55. data/client/skr/screens/sale-report/SaleReport.cjsx +73 -0
  56. data/client/skr/screens/sale-report/index.js +5 -0
  57. data/client/skr/screens/sale-report/index.scss +9 -0
  58. data/client/skr/screens/sales-order/SalesOrder.cjsx +4 -4
  59. data/client/skr/screens/sku-maint/SkuMaint.cjsx +5 -0
  60. data/client/skr/screens/sku-maint/SkuUomList.cjsx +45 -56
  61. data/client/skr/screens/sku-maint/index.scss +33 -13
  62. data/client/skr/screens/time-invoicing/TimeInvoicing.cjsx +2 -2
  63. data/client/skr/screens/time-tracking/EditEntry.cjsx +2 -4
  64. data/client/skr/screens/time-tracking/TimeTracking.cjsx +1 -1
  65. data/client/skr/screens/vendor-maint/VendorMaint.cjsx +1 -1
  66. data/client/skr/vendor/index.js +2438 -0
  67. data/config/lanes.rb +10 -3
  68. data/config/routes.rb +9 -7
  69. data/config/screens.rb +39 -13
  70. data/db/migrate/20160517032350_create_remove_location_logos.rb +11 -0
  71. data/db/migrate/20160531014306_create_public_skus.rb +7 -0
  72. data/db/migrate/20160604195848_create_null_addresses.rb +9 -0
  73. data/db/migrate/20160605024432_create_sku_associations_views.rb +48 -0
  74. data/db/migrate/20160608023553_create_invoice_payments.rb +9 -0
  75. data/db/migrate/20160620010455_add_payments_to_inv_details.rb +54 -0
  76. data/db/schema.sql +206 -38
  77. data/db/seed.rb +6 -0
  78. data/lib/skr.rb +1 -1
  79. data/lib/skr/access_roles.rb +6 -1
  80. data/lib/skr/concerns/has_gl_transaction.rb +8 -0
  81. data/lib/skr/concerns/inv_extensions.rb +11 -0
  82. data/lib/skr/concerns/is_order_like.rb +3 -3
  83. data/lib/skr/concerns/visible_id_identifier.rb +3 -8
  84. data/lib/skr/configuration.rb +2 -0
  85. data/lib/skr/extension.rb +6 -0
  86. data/lib/skr/handlers/credit_card_gateway.rb +31 -0
  87. data/lib/skr/handlers/invoice_from_time_entries.rb +12 -26
  88. data/lib/skr/handlers/sales.rb +44 -0
  89. data/lib/skr/handlers/sequential_ids.rb +46 -0
  90. data/lib/skr/handlers/skus.rb +36 -0
  91. data/lib/skr/jobs/fresh_books/import.rb +3 -1
  92. data/lib/skr/merchant_gateway.rb +37 -0
  93. data/lib/skr/models/address.rb +7 -5
  94. data/lib/skr/models/bank_account.rb +12 -0
  95. data/lib/skr/models/business_entity.rb +1 -1
  96. data/lib/skr/models/gl_transaction.rb +3 -0
  97. data/lib/skr/models/inv_line.rb +7 -2
  98. data/lib/skr/models/inventory_adjustment.rb +0 -5
  99. data/lib/skr/models/invoice.rb +25 -36
  100. data/lib/skr/models/location.rb +1 -1
  101. data/lib/skr/models/payment.rb +56 -10
  102. data/lib/skr/models/po_receipt.rb +0 -8
  103. data/lib/skr/models/sales_order.rb +7 -2
  104. data/lib/skr/models/sequential_id.rb +6 -1
  105. data/lib/skr/models/sku.rb +3 -0
  106. data/lib/skr/print.rb +1 -0
  107. data/lib/skr/print/context.rb +19 -0
  108. data/lib/skr/print/form.rb +7 -1
  109. data/lib/skr/version.rb +1 -1
  110. data/npm-build/package.json +26 -0
  111. data/npm-build/vendor.js +10 -0
  112. data/npm-build/webpack.config.js +25 -0
  113. data/spec/fixtures/skr/bank_account.yml +9 -0
  114. data/spec/fixtures/skr/customer.yml +10 -0
  115. data/spec/fixtures/skr/inv_line.yml +12 -0
  116. data/spec/fixtures/skr/invoice.yml +17 -0
  117. data/spec/fixtures/skr/payment_category.yml +6 -0
  118. data/spec/fixtures/skr/sales_order.yml +1 -1
  119. data/spec/fixtures/skr/sku.yml +10 -0
  120. data/spec/fixtures/skr/sku_loc.yml +4 -0
  121. data/spec/fixtures/skr/uom.yml +6 -0
  122. data/spec/server/handlers/invoice_from_time_entries_spec.rb +13 -6
  123. data/spec/server/handlers/sequential_ids_spec.rb +22 -0
  124. data/spec/server/models/invoice_spec.rb +36 -0
  125. data/spec/server/models/payment_spec.rb +50 -22
  126. data/spec/server/models/sales_order_spec.rb +12 -0
  127. data/spec/server/print/form_spec.rb +20 -4
  128. data/spec/skr/api/SingleItemCheckoutSpec.cjsx +10 -0
  129. data/spec/skr/screens/sale-report/SaleReportSpec.coffee +5 -0
  130. data/stockor.gemspec +5 -4
  131. data/templates/print/layout.tex.erb +1 -1
  132. data/templates/print/packages/INSTALL +7 -0
  133. data/templates/print/packages/qrcode.sty +3051 -0
  134. data/templates/print/packages/svgnam.def +186 -0
  135. data/templates/print/packages/x11nam.def +352 -0
  136. data/templates/print/packages/xcolor.pro +58 -0
  137. data/templates/print/packages/xcolor.sty +1460 -0
  138. data/templates/print/types/invoice/default.tex.erb +2 -0
  139. data/templates/print/types/invoice/labor.tex.erb +2 -1
  140. data/templates/print/types/invoice/ticket.tex.erb +41 -0
  141. data/templates/print/types/payment/default.tex.erb +13 -12
  142. metadata +78 -12
@@ -0,0 +1 @@
1
+ //=require ./Address
@@ -12,6 +12,9 @@ class Skr.Models.Address extends Skr.Models.Base
12
12
  state: "string"
13
13
  postal_code:"string"
14
14
 
15
+ session:
16
+ parent: 'object'
17
+
15
18
  modelForAccess: ->
16
19
  @parent || this
17
20
 
@@ -0,0 +1,49 @@
1
+ class Skr.Models.CreditCard extends Skr.Models.Base
2
+
3
+ props:
4
+ name: 'string'
5
+ number: 'string'
6
+ month: 'integer'
7
+ year: 'integer'
8
+ cvc: 'integer'
9
+
10
+ session:
11
+ parent: 'object'
12
+ expiry: 'string'
13
+ linkToAddress: 'object'
14
+
15
+ derived:
16
+ cardType:
17
+ deps: ['number'], fn: -> Skr.Vendor.Payment.fns.cardType(@number)
18
+ cardIsValid:
19
+ deps: ['name', 'number', 'month', 'year', 'cvc', 'cardType'], fn: ->
20
+ v = Skr.Vendor.Payment.fns
21
+ @name and _.trim(@name.length) > 2 and
22
+ @cardType and
23
+ v.validateCardNumber(@number) and
24
+ v.validateCardExpiry(@month, @year) and
25
+ v.validateCardCVC(@cvc, @cardType)
26
+
27
+
28
+ events:
29
+ 'change:expiry': 'onExpiryChange'
30
+ 'change:name': 'onNameChange'
31
+
32
+ initialize: ->
33
+ @listenTo(@linkToAddress, 'change:name', @onAddressNameChange) if @linkToAddress
34
+
35
+ onAddressNameChange: ->
36
+ if @name is @linkToAddress.previousAttributes().name
37
+ @name = @linkToAddress.name
38
+
39
+ onNameChange: ->
40
+ @parent.name = @name
41
+
42
+ onExpiryChange: ->
43
+ [@month, @year] = @expiry.split(' / ')
44
+
45
+ dataForSave: (options = {}) ->
46
+ attrs = super
47
+ # ActiveMerchant uses 'verification_value'
48
+ attrs.verification_value = attrs.cvc
49
+ attrs
@@ -0,0 +1,27 @@
1
+ class Skr.Models.CreditCardGateway extends Skr.Models.Base
2
+
3
+ pubsub: false
4
+
5
+ props:
6
+ login: "string"
7
+ password: "string"
8
+ type: "string"
9
+
10
+ modelTypeIdentifier: -> 'credit-card-gateway'
11
+
12
+ @allTypes: ->
13
+ [
14
+ {id: 'authorize_net_gateway', name: 'AuthorizeNet' }
15
+ {id: 'balanced_gateway', name: 'Balanced' }
16
+ {id: 'card_stream_gateway', name: 'Card Stream' }
17
+ {id: 'first_pay_gateway', name: 'FirstPay' }
18
+ {id: 'global_transport_gateway', name: 'GlobalTransport' }
19
+ {id: 'link_point_gateway', name: 'Linkpoint' }
20
+ {id: 'paypal_express_gateway', name: 'Paypal Express' }
21
+ {id: 'paypal_gateway', name: 'Paypal' }
22
+ {id: 'sage_gateway', name: 'Sage' }
23
+ {id: 'sage_pay_gateway', name: 'SagePay' }
24
+ {id: 'secure_net_gateway', name: 'Secure Net' }
25
+ {id: 'secure_pay_gateway', name: 'Secure Pay' }
26
+ {id: 'stripe_gateway', name: 'Stripe' }
27
+ ]
@@ -13,7 +13,6 @@ class Skr.Models.Invoice extends Skr.Models.Base
13
13
  pick_ticket_id: "integer"
14
14
  shipping_address_id:{type:"integer"}
15
15
  billing_address_id: {type:"integer"}
16
- amount_paid: {type:"bigdec", "default":"0"}
17
16
  state: {type:"string"}
18
17
  hash_code: {type:"string"}
19
18
  invoice_date: {type:"date", default: ->
@@ -30,6 +29,7 @@ class Skr.Models.Invoice extends Skr.Models.Base
30
29
  session:
31
30
  customer_code: {type:"string"}
32
31
  invoice_total: {type:"bigdec"}
32
+ amount_paid: {type:"bigdec", "default":"0"}
33
33
 
34
34
  derived:
35
35
  prev_amount_paid: deps:['updated_at'], fn: -> @amount_paid
@@ -58,6 +58,7 @@ class Skr.Models.Invoice extends Skr.Models.Base
58
58
  pick_ticket: { model: "PickTicket", readOnly:true }
59
59
  lines: { collection: "InvLine", inverse: 'invoice' }
60
60
  gl_transactions: { collection: "GlTransaction", readOnly:true }
61
+ payments: { collection: "Payment", inverse: 'invoice' }
61
62
 
62
63
  events:
63
64
  'change:customer': 'onSetCustomer'
@@ -68,8 +69,8 @@ class Skr.Models.Invoice extends Skr.Models.Base
68
69
  @unCacheDerived('total')
69
70
  @unset('invoice_total')
70
71
 
71
- onSetCustomer: (newCustomer) ->
72
- return if not newCustomer or newCustomer.isNew()
72
+ onSetCustomer: ->
73
+ return if not @customer or @customer.isNew() or @customer.id is @customer_id
73
74
  for attr in ['terms_id']
74
75
  @set(attr, newCustomer[attr])
75
76
  @copyAssociationsFrom( newCustomer, 'billing_address', 'shipping_address')
@@ -89,15 +90,22 @@ class Skr.Models.Invoice extends Skr.Models.Base
89
90
  @trigger('change', @, {})
90
91
 
91
92
  copyAssociationsFrom: ( model, associations... ) ->
93
+ addrs = ['billing_address', 'shipping_address']
92
94
  new _.Promise (res, rej) =>
93
95
  model.withAssociations(associations).then =>
94
- for name in associations
96
+ for name in addrs
97
+ @[name].set(
98
+ _.omit( @customer[name].serialize(), 'id' )
99
+ )
100
+ for name in _.without associations, addrs
95
101
  @associations.replace(@, name, model[name])
96
102
  res(@)
97
103
 
98
104
  dataForSave: ->
99
105
  # only send some associations
100
- super(onlyAssociations: ['lines', 'billing_address', 'shipping_address'])
106
+ super(onlyAssociations: [
107
+ 'lines', 'billing_address', 'shipping_address', 'payments', 'credit_card'
108
+ ])
101
109
 
102
110
  isPaidInFull: ->
103
111
  @state == 'paid'
@@ -3,8 +3,6 @@ SHARED_COLLECTION = null
3
3
 
4
4
  class Skr.Models.Location extends Skr.Models.Base
5
5
 
6
- cacheDuration: [1, 'day']
7
-
8
6
  mixins: [ 'FileSupport', 'HasCodeField' ]
9
7
 
10
8
  props:
@@ -14,16 +12,20 @@ class Skr.Models.Location extends Skr.Models.Base
14
12
  address_id: {type:"integer"}
15
13
  is_active: {type:"boolean", "default":true}
16
14
  gl_branch_code:{type:"string", "default":"01"}
17
- logo: "file"
18
- options: "any"
15
+ options: "any"
19
16
 
20
17
  associations:
21
18
  address: { model: "Address" }
22
19
  sku_locs: { collection: "SkuLoc" }
20
+ logo: { model: "Lanes.Models.Asset" }
23
21
 
24
22
  @initialize: (data) ->
25
23
  SHARED_DATA = data.locations
26
24
 
25
+ addChangeSet: (change) ->
26
+ if change.update.logo
27
+ change.update.logo[1] = change.update.logo[1].logo
28
+ super
27
29
 
28
30
  Object.defineProperties Skr.Models.Location, {
29
31
  all:
@@ -2,13 +2,18 @@ class Skr.Models.Payment extends Skr.Models.Base
2
2
 
3
3
  props:
4
4
  id: {type:"integer"}
5
- visible_id: {type:"string"}
5
+ visible_id: {type:"visible_id"}
6
6
  hash_code: {type:"string"}
7
7
  bank_account_id:{type:"integer"}
8
8
  category_id: {type:"integer"}
9
9
  vendor_id: "integer"
10
- location_id: "integer"
11
- amount: {type:"bigdec", required:true}
10
+ invoice_id: "integer"
11
+ location_id: {type:"integer", default: ->
12
+ Skr.Models.Location.default.id
13
+ }
14
+ amount: {type:"bigdec", required: true, default: ->
15
+ _.bigDecimal('0')
16
+ }
12
17
  check_number: {type:"integer"}
13
18
  date: {type:"date", default: ->
14
19
  new Date
@@ -16,21 +21,36 @@ class Skr.Models.Payment extends Skr.Models.Base
16
21
  name: {type: "string", required: true}
17
22
  address: "string"
18
23
  notes: "string"
24
+ metadata: "object"
19
25
 
20
26
  mixins: [ 'PrintSupport', 'HasVisibleId' ]
21
27
 
28
+ derived:
29
+ is_incoming: deps:['invoice'], fn: -> !!@invoice
30
+ is_outgoing: deps:['is_incoming'], fn: -> !@is_incoming
31
+
22
32
  associations:
23
- category: { model: "PaymentCategory" }
24
- vendor: { model: "Vendor" }
25
- bank_account: { model: "BankAccount" }
26
- location: { model: "Location" }
27
- gl_transaction: { model: "GlTransaction" }
33
+ category: { model: "PaymentCategory", readOnly: true}
34
+ invoice: { model: "Invoice", readOnly: true }
35
+ vendor: { model: "Vendor", readOnly: true }
36
+ bank_account: { model: "BankAccount", readOnly: true }
37
+ location: { model: "Location", readOnly: true, default: ->
38
+ Skr.Models.Location.all.get(@location_id) if @location_id
39
+ }
40
+ gl_transaction: { model: "GlTransaction", readOnly: true }
41
+ credit_card: { model: "CreditCard", inverse: 'payment' }
28
42
 
29
43
  events:
30
44
  'change:vendor': 'onSetVendor'
31
45
 
32
- onSetVendor: (newVendor) ->
33
- return unless newVendor and Lanes.u.isModel(newVendor)
34
- @name = newVendor.name
35
- newVendor.withAssociations(['billing_address']).then =>
36
- @address = newVendor.billing_address.toString()
46
+ describe: ->
47
+ metadata = _.toSentence( _.map(@metadata, (value, key) ->
48
+ _.titleize(key) + ': ' + value
49
+ ))
50
+ #{@name} #{metadata}"
51
+
52
+ onSetVendor: ->
53
+ return unless @vendor and @vendor.isPersistent()
54
+ @name = @vendor.name
55
+ @vendor.withAssociations(['billing_address']).then (v) =>
56
+ @address = v.billing_address.toString()
@@ -55,8 +55,8 @@ class Skr.Models.SalesOrder extends Skr.Models.Base
55
55
  pick_tickets: { collection: "PickTicket", inverse: 'sales_order' }
56
56
 
57
57
  events:
58
- 'change:customer': 'onCustomerChange'
59
58
  'lines add remove change:total': 'onTotalChange'
59
+ 'change:customer': 'onCustomerChange'
60
60
 
61
61
  onTotalChange: ->
62
62
  @trigger('change', @, {})
@@ -64,10 +64,14 @@ class Skr.Models.SalesOrder extends Skr.Models.Base
64
64
  @unset('order_total')
65
65
 
66
66
  onCustomerChange: ->
67
- return unless @isNew()
67
+ return if @customer.isProxy or not @isNew()
68
+
68
69
  associations = ['billing_address', 'shipping_address']
69
70
  for attr in ['terms_id']
70
71
  @set(attr, @customer[attr])
72
+
71
73
  @customer.withAssociations(associations).then =>
72
74
  for name in associations
73
- @associations.replace(@, name, @customer[name])
75
+ @[name].set(
76
+ _.omit( @customer[name].serialize(), 'id' )
77
+ )
@@ -0,0 +1,17 @@
1
+ class Skr.Models.SequentialId extends Skr.Models.Base
2
+
3
+ props:
4
+ id: 'integer'
5
+ ids:
6
+ type: 'array', required: true, default: -> []
7
+
8
+ registerforPubSub: false
9
+
10
+ modelTypeIdentifier: ->
11
+ 'sequential-ids'
12
+
13
+ updateValue: (id, count) ->
14
+ @ids = _.map @ids, (si) ->
15
+ si = _.clone si
16
+ si.count = parseInt(count) if si.id is id
17
+ si
@@ -5,7 +5,7 @@ class Skr.Models.Sku extends Skr.Models.Base
5
5
  id: {type:"integer"}
6
6
  default_vendor_id: {type:"integer"}
7
7
  gl_asset_account_id: {type:"integer", default: ->
8
- Skr.Models.GlAccount.default_ids.asset
8
+ Skr.Models.GlAccount.default_ids?.asset
9
9
  }
10
10
  default_uom_code: {type:"string"}
11
11
  code: {type:"code", required:true}
@@ -68,9 +68,8 @@ class Skr.Models.TimeEntry extends Skr.Models.Base
68
68
  _.extend attrs, colorIndex: project.options.color
69
69
  attrs
70
70
 
71
- fromCalEvent: (event) ->
72
- attrs =
73
- id: event.entryId,
71
+ setTimeFromCalEvent: (event) ->
72
+ return this.set(
74
73
  start_at: event.start()
75
74
  end_at: event.end()
76
- this.set(_.pick(attrs, _.identity))
75
+ )
@@ -1,6 +1,9 @@
1
1
  Skr.Models.Mixins.PrintSupport = {
2
2
 
3
+ _mixinPrintFormIdentifier: ->
4
+ if @printFormIdentifier then @printFormIdentifier() else @modelTypeIdentifier()
5
+
3
6
  pdfDownloadUrl: ->
4
- "#{Lanes.config.api_path}/skr/print/#{@modelTypeIdentifier()}/#{@hash_code}.pdf"
7
+ "#{Lanes.config.api_path}/skr/print/#{@_mixinPrintFormIdentifier()}/#{@hash_code}.pdf"
5
8
 
6
9
  }
@@ -40,7 +40,7 @@ Skr.Models.Mixins.SkuLine = {
40
40
  this.uom.set( uom.serialize() ) if uom
41
41
 
42
42
  onSkuChange: ->
43
- return unless @sku
43
+ return if @sku.isProxy
44
44
  sl = @sku.sku_locs.findWhere(sku_id: @sku.id)
45
45
  if sl
46
46
  @set(sku_loc: sl)
@@ -26,8 +26,7 @@ class Skr.Screens.CustomerMaint extends Skr.Screens.Base
26
26
  <LC.Input sm=8 name="name" model={@customer} />
27
27
  </BS.Row>
28
28
  <BS.Row>
29
- <LC.Input sm=12
30
- type='textarea'
29
+ <LC.TextArea sm=12
31
30
  name="notes"
32
31
  model={@customer} />
33
32
  </BS.Row>
@@ -15,6 +15,7 @@ class Skr.Screens.CustomerProjects extends Skr.Screens.Base
15
15
  getHourlyRate: -> @project.rates?.hourly
16
16
  setHourlyRate: (value) ->
17
17
  @project.rates = _.extend({}, @project.rates, {hourly: value.replace(/[^0-9.]/g, '')})
18
+
18
19
  ColorOption: (props) ->
19
20
  <div className={"color-#{props.item.id}"}>{props.item.name}</div>
20
21
 
@@ -24,7 +25,7 @@ class Skr.Screens.CustomerProjects extends Skr.Screens.Base
24
25
  getColorReadOnly: ->
25
26
  index = @getColor()
26
27
  color = _.find(Skr.Models.CustomerProject.COLORS, id: index)
27
- <div className={"ro color-#{index}"}>{color?.name}</div>
28
+ <div className={"ro color-#{index}"}>{color?.name or ''}</div>
28
29
 
29
30
  getColor: ->
30
31
  @project.options?.color
@@ -48,14 +49,17 @@ class Skr.Screens.CustomerProjects extends Skr.Screens.Base
48
49
 
49
50
  <LC.FieldWrapper sm=2
50
51
  label="Entry Color"
52
+ model={@project}
53
+ name={'color'}
51
54
  className="color-selection"
52
- value={@getColorReadOnly()}
55
+ displayComponent={@getColorReadOnly}
53
56
  >
54
57
  <Lanes.Vendor.ReactWidgets.DropdownList
55
58
  className='colors'
56
59
  data={Skr.Models.CustomerProject.COLORS}
57
60
  valueField='id' textField='name'
58
- value={@getColor()} onChange={@setColor}
61
+ value={@getColor()}
62
+ onChange={@setColor}
59
63
  valueComponent={@ColorOption}
60
64
  disabled={!@state.commands.isEditing()}
61
65
  itemComponent={@ColorOption} />
@@ -20,6 +20,7 @@
20
20
  .color-selection {
21
21
  .ro {
22
22
  padding-left: 0.5rem;
23
+ line-height: 30px;
23
24
  }
24
25
  }
25
26
  }
@@ -23,7 +23,7 @@ class Skr.Screens.FreshBooksImport.ApiInfo extends Lanes.React.Component
23
23
  <BS.Row>
24
24
  <LC.Input name='api_key' label='API Key' sm=7 model={@import} />
25
25
  <LC.Input name='domain' label='Company' sm=3 model={@import} />
26
- <LC.FormGroup className='domain' sm=2 label=''>.freshbooks.com</LC.FormGroup>
26
+ <BS.FormGroup className='domain' sm=2 label=''>.freshbooks.com</BS.FormGroup>
27
27
  </BS.Row>
28
28
  <BS.Row>
29
29
  <BS.Col smOffset=9 sm=2>
@@ -26,6 +26,6 @@ class Skr.Screens.GlAccounts extends Skr.Screens.Base
26
26
 
27
27
  </BS.Row>
28
28
  <BS.Row>
29
- <LC.Input type='textarea' sm=12 name="description" model={@account} />
29
+ <LC.TextArea sm=12 name="description" model={@account} />
30
30
  </BS.Row>
31
31
  </LC.ScreenWrapper>
@@ -13,7 +13,7 @@ class Transactions extends Skr.Models.Base
13
13
  syncOptions: { with: ['with_details'] }
14
14
  fields: [
15
15
  { id: 'id', visible: false }
16
- { id: 'created_at', title: 'Date', format: Lanes.u.format.shartDate, fixedWidth: 100 }
16
+ { id: 'created_at', title: 'Date', format: Lanes.u.format.shortDate, fixedWidth: 100 }
17
17
  { id: 'debit_details', title: 'Debit', component: RenderPosting }
18
18
  { id: 'credit_details', title: 'Credit', component: RenderPosting }
19
19
  { id: 'source_type', fixedWidth: 180 }
@@ -5,7 +5,7 @@ class Skr.Screens.Invoice extends Skr.Screens.Base
5
5
 
6
6
  syncOptions:
7
7
  with: [ 'with_details' ]
8
- include: [ 'sales_order', 'billing_address', 'shipping_address', 'lines' ]
8
+ include: [ 'sales_order', 'billing_address', 'shipping_address', 'lines', 'payments' ]
9
9
 
10
10
  dataObjects:
11
11
  invoice: ->
@@ -18,29 +18,19 @@ class Skr.Screens.Invoice extends Skr.Screens.Base
18
18
  commands: new Skr.Screens.Commands(this, modelName: 'invoice', print: true)
19
19
 
20
20
  setSalesOrder: (so) -> @invoice.setFromSalesOrder(so)
21
- onPayment: -> @invoice.save()
22
21
 
23
- getPayment: ->
24
- @context.viewport.displayModal
25
- title: "Accept Payment", autoHide: true, size: 'sm', onOk: @onPayment,
26
- body: =>
27
- <Skr.Screens.Invoice.Payment invoice={@invoice} />
22
+ showPayment: ->
23
+ Skr.Screens.Invoice.Payment.display(@context.viewport, @invoice)
28
24
 
29
25
  PaymentButton: ->
30
- return null if @invoice.isNew() or @invoice.isPaidInFull()
31
- <SC.ToolbarButton onClick={@getPayment}>
26
+ return null if @invoice.isNew()
27
+ <SC.ToolbarButton onClick={@showPayment}>
32
28
  <LC.Icon type="money" />Payment
33
29
  </SC.ToolbarButton>
34
30
 
35
31
  shouldSaveLinesImmediately: ->
36
32
  not @invoice.isNew()
37
33
 
38
- linesQueryBuilder: (attrs) ->
39
- unless this.invoice.isNew()
40
- sc = _.find attrs.fields, id: 'sku_code'
41
- sc.editable = false
42
- attrs
43
-
44
34
  render: ->
45
35
  <LC.ScreenWrapper identifier="invoice" flexVertical>
46
36
 
@@ -55,9 +45,11 @@ class Skr.Screens.Invoice extends Skr.Screens.Base
55
45
 
56
46
  <SC.SalesOrderFinder autoFocus={false} sm=2 xs=3 editOnly={false}
57
47
  onModelSet={@setSalesOrder} associationName='sales_order'
58
- syncOptions={@syncOptions} parentModel={@invoice} />
48
+ syncOptions={ include: ['customer', 'billing_address', 'shipping_address' ] }
49
+ parentModel={@invoice} />
59
50
 
60
51
  <SC.CustomerFinder
52
+ syncOptions={ include: ['billing_address', 'shipping_address' ] }
61
53
  selectField sm=3 xs=6 model={@invoice} />
62
54
 
63
55
  <SC.TermsChooser model={@invoice} sm=3 xs=6 />
@@ -78,7 +70,7 @@ class Skr.Screens.Invoice extends Skr.Screens.Base
78
70
  </BS.Row>
79
71
 
80
72
  <BS.Row>
81
- <LC.Input sm=12 type='textarea' name="notes" model={@invoice} />
73
+ <LC.TextArea name="notes" model={@invoice} xs=12 />
82
74
  </BS.Row>
83
75
 
84
76
  <BS.Row>