stockor 0.1.9 → 0.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/Gemfile +1 -1
- data/Gemfile.lock +254 -72
- data/Guardfile +1 -1
- data/README.md +24 -3
- data/app.json +28 -0
- data/client/skr/Extension.coffee +18 -0
- data/client/skr/components/BankAccountFinder.cjsx +34 -0
- data/client/skr/components/Currency.cjsx +19 -0
- data/client/skr/components/CustomerFinder.cjsx +37 -0
- data/client/skr/components/CustomerLink.cjsx +13 -0
- data/client/skr/components/CustomerProjectFinder.cjsx +49 -0
- data/client/skr/components/GlAccountChooser.cjsx +38 -0
- data/client/skr/components/InvoiceFinder.cjsx +37 -0
- data/client/skr/components/InvoiceLink.cjsx +13 -0
- data/client/skr/components/LocationChooser.cjsx +37 -0
- data/client/skr/components/PaymentCategoryFinder.cjsx +34 -0
- data/client/skr/components/PrintFormChooser.cjsx +29 -0
- data/client/skr/components/SalesOrderFinder.cjsx +38 -0
- data/client/skr/components/ScreenControls.cjsx +20 -0
- data/client/skr/components/SkuFinder.cjsx +30 -0
- data/client/skr/components/SkuLines.cjsx +76 -0
- data/client/skr/components/SystemSettings.cjsx +26 -0
- data/client/skr/components/TermsChooser.cjsx +40 -0
- data/client/skr/components/ToolbarButton.cjsx +7 -0
- data/client/skr/components/TotalsLine.cjsx +21 -0
- data/client/skr/components/TriStateIcon.cjsx +12 -0
- data/client/skr/components/UOMChooser.cjsx +24 -0
- data/client/skr/components/UserPreferences.cjsx +30 -0
- data/client/skr/components/VendorFinder.cjsx +40 -0
- data/client/skr/components/address/Address.cjsx +10 -10
- data/client/skr/components/styles.scss +16 -0
- data/client/skr/index.js +3 -1
- data/client/skr/models/Address.coffee +9 -1
- data/client/skr/models/BankAccount.coffee +17 -0
- data/client/skr/models/Base.coffee +6 -0
- data/client/skr/models/Customer.coffee +17 -10
- data/client/skr/models/CustomerProject.coffee +29 -0
- data/client/skr/models/GlAccount.coffee +22 -10
- data/client/skr/models/GlManualEntry.coffee +4 -2
- data/client/skr/models/GlPeriod.coffee +4 -6
- data/client/skr/models/GlPosting.coffee +7 -7
- data/client/skr/models/GlTransaction.coffee +3 -3
- data/client/skr/models/IaLine.coffee +9 -9
- data/client/skr/models/IaReason.coffee +4 -4
- data/client/skr/models/InvLine.coffee +30 -11
- data/client/skr/models/InventoryAdjustment.coffee +8 -6
- data/client/skr/models/Invoice.coffee +89 -18
- data/client/skr/models/Location.coffee +27 -6
- data/client/skr/models/Payment.coffee +36 -0
- data/client/skr/models/PaymentCategory.coffee +12 -0
- data/client/skr/models/PaymentTerm.coffee +17 -4
- data/client/skr/models/PickTicket.coffee +7 -5
- data/client/skr/models/PoLine.coffee +15 -15
- data/client/skr/models/PoReceipt.coffee +8 -6
- data/client/skr/models/PorLine.coffee +11 -11
- data/client/skr/models/PricingProvider.coffee +6 -0
- data/client/skr/models/PtLine.coffee +13 -13
- data/client/skr/models/PurchaseOrder.coffee +11 -9
- data/client/skr/models/SalesOrder.coffee +59 -22
- data/client/skr/models/Sku.coffee +17 -15
- data/client/skr/models/SkuLoc.coffee +14 -9
- data/client/skr/models/SkuTran.coffee +10 -10
- data/client/skr/models/SkuVendor.coffee +9 -9
- data/client/skr/models/SoLine.coffee +27 -20
- data/client/skr/models/TimeEntry.coffee +75 -0
- data/client/skr/models/Uom.coffee +27 -6
- data/client/skr/models/Vendor.coffee +14 -12
- data/client/skr/models/VoLine.coffee +11 -11
- data/client/skr/models/Voucher.coffee +7 -5
- data/client/skr/models/mixins/HasVisibleId.coffee +7 -0
- data/client/skr/models/mixins/PrintSupport.coffee +6 -0
- data/client/skr/models/mixins/SkuLine.coffee +61 -0
- data/client/skr/screens/Commands.coffee +29 -0
- data/client/skr/screens/bank-maint/BankMaint.cjsx +43 -0
- data/client/skr/screens/bank-maint/index.js +5 -0
- data/client/skr/screens/chart-of-accounts/ChartOfAccounts.cjsx +40 -0
- data/client/skr/screens/chart-of-accounts/index.js +1 -0
- data/client/skr/screens/chart-of-accounts/index.scss +12 -0
- data/client/skr/screens/customer-maint/CustomerMaint.cjsx +35 -36
- data/client/skr/screens/customer-projects/CustomerProjects.cjsx +70 -0
- data/client/skr/screens/customer-projects/index.js +5 -0
- data/client/skr/screens/customer-projects/index.scss +25 -0
- data/client/skr/screens/fresh-books-import/ApiInfo.cjsx +35 -0
- data/client/skr/screens/fresh-books-import/ChooseRecords.cjsx +116 -0
- data/client/skr/screens/fresh-books-import/FreshBooksImport.cjsx +31 -0
- data/client/skr/screens/fresh-books-import/Import.coffee +52 -0
- data/client/skr/screens/fresh-books-import/ViewRecords.cjsx +96 -0
- data/client/skr/screens/fresh-books-import/index.js +1 -0
- data/client/skr/screens/fresh-books-import/index.scss +39 -0
- data/client/skr/screens/gl-accounts/GlAccounts.cjsx +31 -0
- data/client/skr/screens/gl-accounts/index.js +5 -0
- data/client/skr/screens/gl-transactions/GlTransactions.cjsx +46 -0
- data/client/skr/screens/gl-transactions/index.js +1 -0
- data/client/skr/screens/gl-transactions/index.scss +12 -0
- data/client/skr/screens/invoice/Invoice.cjsx +92 -0
- data/client/skr/screens/invoice/Payment.cjsx +28 -0
- data/client/skr/screens/invoice/index.js +5 -0
- data/client/skr/screens/locations/Locations.cjsx +31 -0
- data/client/skr/screens/locations/index.js +5 -0
- data/client/skr/screens/payment-category/PaymentCategory.cjsx +28 -0
- data/client/skr/screens/payment-category/index.js +5 -0
- data/client/skr/screens/payment-category/index.scss +9 -0
- data/client/skr/screens/payment-terms/PaymentTerms.cjsx +28 -0
- data/client/skr/screens/payment-terms/index.js +5 -0
- data/client/skr/screens/payment-terms/index.scss +9 -0
- data/client/skr/screens/payments/Payments.cjsx +59 -0
- data/client/skr/screens/payments/index.js +5 -0
- data/client/skr/screens/sales-order/SalesOrder.cjsx +68 -0
- data/client/skr/screens/sales-order/index.js +1 -5
- data/client/skr/screens/sku-maint/SkuMaint.cjsx +53 -0
- data/client/skr/screens/sku-maint/SkuUomList.cjsx +209 -0
- data/client/skr/screens/sku-maint/index.js +2 -5
- data/client/skr/screens/sku-maint/index.scss +37 -6
- data/client/skr/screens/time-invoicing/TimeInvoicing.cjsx +156 -0
- data/client/skr/screens/time-invoicing/index.js +5 -0
- data/client/skr/screens/time-invoicing/index.scss +7 -0
- data/client/skr/screens/time-tracking/EditEntry.cjsx +54 -0
- data/client/skr/screens/time-tracking/Entries.coffee +132 -0
- data/client/skr/screens/time-tracking/Header.cjsx +71 -0
- data/client/skr/screens/time-tracking/Popover.cjsx +70 -0
- data/client/skr/screens/time-tracking/PopoverMiniControls.cjsx +25 -0
- data/client/skr/screens/time-tracking/TimeTracking.cjsx +63 -0
- data/client/skr/screens/time-tracking/WeekSummary.cjsx +16 -0
- data/client/skr/screens/time-tracking/index.js +1 -0
- data/client/skr/screens/time-tracking/index.scss +126 -0
- data/client/skr/screens/vendor-maint/VendorMaint.cjsx +45 -0
- data/client/skr/screens/vendor-maint/index.js +1 -5
- data/client/skr/styles.scss +1 -13
- data/config/puma.rb +4 -0
- data/config/routes.rb +21 -9
- data/config/screens.rb +147 -32
- data/db/migrate/20140202194700_create_skr_gl_transaction_details.rb +35 -0
- data/db/migrate/20140220031800_create_skr_locations.rb +2 -0
- data/db/migrate/20140220190836_create_skr_vendors.rb +1 -0
- data/db/migrate/20140220203029_create_skr_customers.rb +3 -2
- data/db/migrate/20140224034759_create_skr_skus.rb +2 -3
- data/db/migrate/20140322223912_create_skr_sales_orders.rb +4 -3
- data/db/migrate/20140322223920_create_skr_so_lines.rb +4 -5
- data/db/migrate/20140323001446_create_so_details_view.rb +7 -5
- data/db/migrate/20140327202209_create_skr_pt_lines.rb +2 -2
- data/db/migrate/20140327214000_create_customer_project.rb +16 -0
- data/db/migrate/20140327223002_create_time_entries.rb +17 -0
- data/db/migrate/20140327224000_create_skr_invoices.rb +5 -1
- data/db/migrate/20140327224002_create_skr_inv_lines.rb +3 -1
- data/db/migrate/20140422024010_create_skr_inv_details_view.rb +1 -1
- data/db/migrate/20151121211323_create_customer_project_details_views.rb +31 -0
- data/db/migrate/20160216142845_create_gl_account_balances_view.rb +20 -0
- data/db/migrate/20160229002044_create_bank_accounts.rb +18 -0
- data/db/migrate/20160229041711_create_payments.rb +33 -0
- data/db/migrate/20160307022705_create_create_combined_uom_views.rb +18 -0
- data/db/schema.sql +639 -140
- data/db/seed/chart_of_accounts.yml +8 -6
- data/db/seed/payment_categories.yml +12 -0
- data/db/seed/skus.yml +32 -0
- data/db/seed.rb +21 -0
- data/lib/skr/access_roles.rb +19 -6
- data/lib/skr/concerns/has_sku_loc_lines.rb +0 -16
- data/lib/skr/concerns/inv_extensions.rb +24 -0
- data/lib/skr/concerns/is_sku_loc_line.rb +3 -4
- data/lib/skr/concerns/so_extensions.rb +8 -0
- data/lib/skr/concerns/visible_id_identifier.rb +1 -1
- data/lib/skr/db/migration_helpers.rb +2 -4
- data/lib/skr/extension.rb +11 -4
- data/lib/skr/handlers/fresh_books_import.rb +20 -0
- data/lib/skr/handlers/invoice_from_time_entries.rb +49 -0
- data/lib/skr/jobs/fresh_books/base.rb +54 -0
- data/lib/skr/jobs/fresh_books/import.rb +151 -0
- data/lib/skr/jobs/fresh_books/retrieve.rb +62 -0
- data/lib/skr/model.rb +5 -0
- data/lib/skr/models/address.rb +1 -1
- data/lib/skr/models/bank_account.rb +13 -0
- data/lib/skr/models/business_entity.rb +3 -0
- data/lib/skr/models/customer.rb +1 -1
- data/lib/skr/models/customer_project.rb +22 -0
- data/lib/skr/models/gl_account.rb +13 -3
- data/lib/skr/models/gl_period.rb +6 -0
- data/lib/skr/models/gl_posting.rb +7 -4
- data/lib/skr/models/gl_transaction.rb +19 -33
- data/lib/skr/models/ia_line.rb +1 -1
- data/lib/skr/models/inv_line.rb +33 -15
- data/lib/skr/models/invoice.rb +47 -20
- data/lib/skr/models/location.rb +7 -1
- data/lib/skr/models/payment.rb +49 -0
- data/lib/skr/models/payment_category.rb +11 -0
- data/lib/skr/models/payment_term.rb +1 -1
- data/lib/skr/models/por_line.rb +1 -1
- data/lib/skr/models/pt_line.rb +1 -1
- data/lib/skr/models/sales_order.rb +9 -9
- data/lib/skr/models/sku_loc.rb +1 -1
- data/lib/skr/models/sku_tran.rb +6 -11
- data/lib/skr/models/so_line.rb +22 -12
- data/lib/skr/models/time_entry.rb +36 -0
- data/lib/skr/models/uom.rb +11 -10
- data/lib/skr/models/user_proxy.rb +1 -1
- data/lib/skr/number.rb +25 -0
- data/lib/skr/print/form.rb +46 -0
- data/lib/skr/print/template.rb +48 -0
- data/lib/skr/print.rb +11 -0
- data/lib/skr/string.rb +11 -0
- data/lib/skr/version.rb +1 -1
- data/lib/skr.rb +9 -0
- data/spec/fixtures/skr/address.yml +164 -4
- data/spec/fixtures/skr/bank_account.yml +8 -0
- data/spec/fixtures/skr/customer.yml +30 -4
- data/spec/fixtures/skr/customer_project.yml +20 -0
- data/spec/fixtures/skr/gl_account.yml +19 -1
- data/spec/fixtures/skr/gl_period.yml +3 -0
- data/spec/fixtures/skr/gl_posting.yml +22 -1
- data/spec/fixtures/skr/gl_transaction.yml +4 -1
- data/spec/fixtures/skr/inv_line.yml +35 -0
- data/spec/fixtures/skr/invoice.yml +13 -2
- data/spec/fixtures/skr/location.yml +5 -0
- data/spec/fixtures/skr/payment.yml +10 -0
- data/spec/fixtures/skr/payment_category.yml +8 -0
- data/spec/fixtures/skr/payment_term.yml +37 -3
- data/spec/fixtures/skr/sales_order.yml +12 -1
- data/spec/fixtures/skr/sku.yml +78 -1
- data/spec/fixtures/skr/sku_loc.yml +42 -1
- data/spec/fixtures/skr/sku_tran.yml +24 -1
- data/spec/fixtures/skr/so_line.yml +32 -0
- data/spec/fixtures/skr/time_entry.yml +82 -0
- data/spec/fixtures/skr/uom.yml +52 -1
- data/spec/fixtures/skr/vendor.yml +28 -1
- data/spec/fixtures/stockor.png +0 -0
- data/spec/server/bank_account_spec.rb +10 -0
- data/spec/server/customer_project_spec.rb +10 -0
- data/spec/server/handlers/invoice_from_time_entries_spec.rb +49 -0
- data/spec/server/jobs/fresh_books/import_spec.rb +69 -0
- data/spec/server/jobs/fresh_books/retrieve_spec.rb +37 -0
- data/spec/server/models/address_spec.rb +4 -3
- data/spec/server/models/gl_transaction_spec.rb +3 -3
- data/spec/server/models/inv_line_spec.rb +83 -3
- data/spec/server/models/invoice_spec.rb +32 -3
- data/spec/server/models/payment_spec.rb +40 -0
- data/spec/server/models/sales_order_spec.rb +1 -1
- data/spec/server/models/so_line_spec.rb +3 -3
- data/spec/server/models/spec_helper_spec.rb +1 -1
- data/spec/server/payment_spec.rb +10 -0
- data/spec/server/print/form_spec.rb +47 -0
- data/spec/server/print/template_spec.rb +36 -0
- data/spec/server/spec_helper.rb +14 -1
- data/spec/server/time_entry_spec.rb +10 -0
- data/spec/skr/components/SkuLinesSpec.coffee +61 -0
- data/spec/skr/models/BankAccountSpec.coffee +5 -0
- data/spec/skr/models/CustomerProjectSpec.coffee +5 -0
- data/spec/skr/models/CustomerSpec.coffee +2 -2
- data/spec/skr/models/PaymentSpec.coffee +5 -0
- data/spec/skr/models/SalesOrderSpec.coffee +21 -5
- data/spec/skr/models/SoLineSpec.coffee +7 -2
- data/spec/skr/models/TimeEntrySpec.coffee +5 -0
- data/spec/skr/screens/bank-maint/BankMaintSpec.coffee +5 -0
- data/spec/skr/screens/customer-projects/CustomerProjectsSpec.coffee +5 -0
- data/spec/skr/screens/fresh-books-import/FreshBooksImportSpec.coffee +1 -0
- data/spec/skr/screens/gl-accounts/GlAccountsSpec.coffee +5 -0
- data/spec/skr/screens/invoice/InvoiceSpec.coffee +5 -0
- data/spec/skr/screens/locations/LocationsSpec.coffee +5 -0
- data/spec/skr/screens/payment-category/PaymentCategorySpec.coffee +5 -0
- data/spec/skr/screens/payment-terms/PaymentTermsSpec.coffee +5 -0
- data/spec/skr/screens/payments/PaymentsSpec.coffee +5 -0
- data/spec/skr/screens/time-invoicing/TimeInvoicingSpec.coffee +5 -0
- data/spec/skr/screens/time-tracking/TimeTrackingSpec.coffee +14 -0
- data/spec/vcr/freshbooks.yml +698 -0
- data/stockor.gemspec +5 -1
- data/templates/print/fonts/GnuMICR.otf +0 -0
- data/templates/print/layout.tex.erb +39 -0
- data/templates/print/packages/booktabs.sty +182 -0
- data/templates/print/packages/fancybox.sty +966 -0
- data/templates/print/packages/fancyhdr.sty +485 -0
- data/templates/print/packages/graphbox.sty +129 -0
- data/templates/print/packages/lastpage.sty +283 -0
- data/templates/print/packages/lastpage209.sty +70 -0
- data/templates/print/packages/marginnote.sty +412 -0
- data/templates/print/packages/multirow.sty +159 -0
- data/templates/print/packages/rotating.sty +282 -0
- data/templates/print/packages/tabu.sty +2557 -0
- data/templates/print/packages/textpos.sty +361 -0
- data/templates/print/packages/varwidth.sty +318 -0
- data/templates/print/partials/address.tex.erb +6 -0
- data/templates/print/partials/bill_to_ship_to.tex.erb +13 -0
- data/templates/print/partials/header.tex.erb +13 -0
- data/templates/print/partials/invoice_paid_state.tex.erb +2 -0
- data/templates/print/partials/old/inv_lines_grouping.tex.erb +8 -0
- data/templates/print/partials/old/labor_lines_footer.tex.erb +18 -0
- data/templates/print/partials/skus_table.tex.erb +32 -0
- data/templates/print/partials/skus_table_col_hdr.tex.erb +8 -0
- data/templates/print/partials/skus_table_footer.tex.erb +5 -0
- data/templates/print/partials/skus_table_group_footer.tex.erb +4 -0
- data/templates/print/partials/skus_table_invoice_footer.tex.erb +25 -0
- data/templates/print/partials/skus_table_invoice_info_line.tex.erb +16 -0
- data/templates/print/partials/skus_table_labor_col_hdr.tex.erb +8 -0
- data/templates/print/partials/skus_table_labor_group_footer.tex.erb +7 -0
- data/templates/print/partials/skus_table_labor_line.tex.erb +11 -0
- data/templates/print/partials/skus_table_line.tex.erb +6 -0
- data/templates/print/partials/skus_table_other_charge_lines.tex.erb +7 -0
- data/templates/print/partials/so_info_line.tex.erb +14 -0
- data/templates/print/types/invoice/default.tex.erb +13 -0
- data/templates/print/types/invoice/labor.tex.erb +33 -0
- data/templates/print/types/payment/default.tex.erb +64 -0
- data/templates/print/types/sales-order/default.tex.erb +8 -0
- metadata +252 -15
- data/client/skr/components/address/address.html +0 -20
- data/client/skr/models/mixins/CodeField.coffee +0 -5
- data/client/skr/screens/customer-maint/index.scss +0 -11
- data/client/skr/screens/customer-maint/layout.html +0 -32
- data/client/skr/screens/sales-order/SalesOrder.coffee +0 -30
- data/client/skr/screens/sales-order/index.scss +0 -8
- data/client/skr/screens/sales-order/layout.html +0 -30
- data/client/skr/screens/sku-maint/SkuMaint.coffee +0 -18
- data/client/skr/screens/sku-maint/layout.html +0 -16
- data/client/skr/screens/vendor-maint/VendorMaint.coffee +0 -28
- data/client/skr/screens/vendor-maint/index.scss +0 -8
- data/client/skr/screens/vendor-maint/layout.html +0 -32
@@ -0,0 +1,132 @@
|
|
1
|
+
class TimeEntries extends Skr.Models.TimeEntry.Collection
|
2
|
+
|
3
|
+
constructor: (@projects) ->
|
4
|
+
super()
|
5
|
+
|
6
|
+
projectForEntry: (entry) ->
|
7
|
+
@projects.get( entry.customer_project_id )
|
8
|
+
|
9
|
+
loadEntries: (range, query = {}) ->
|
10
|
+
query.end_at = { op: 'gt', value: range.start.toISOString() }
|
11
|
+
query.start_at = { op: 'lt', value: range.end.toISOString() }
|
12
|
+
@fetch({query, reset: true})
|
13
|
+
|
14
|
+
resetEntries: (projectId, range) ->
|
15
|
+
@projectId = projectId
|
16
|
+
query = if @projectId and @projectId isnt -1
|
17
|
+
{customer_project_id: @projectId}
|
18
|
+
else {}
|
19
|
+
@loadEntries(range, query)
|
20
|
+
|
21
|
+
class Skr.Screens.TimeTracking.Entries extends Lanes.Models.Base
|
22
|
+
|
23
|
+
session:
|
24
|
+
date: { type: 'object', 'required': true, default: -> _.moment() }
|
25
|
+
display: { type: 'string', values: ['day', 'week', 'month'], default: 'week' }
|
26
|
+
isLoading: { type: 'boolean', default: false }
|
27
|
+
customer_project_id: 'integer'
|
28
|
+
editing: 'any'
|
29
|
+
|
30
|
+
derived:
|
31
|
+
project:
|
32
|
+
deps: ['customer_project_id'], fn: ->
|
33
|
+
@available_projects.get(@customer_project_id)
|
34
|
+
isMonth:
|
35
|
+
deps: ['display'], fn: -> 'month' == @display
|
36
|
+
range:
|
37
|
+
deps: ['date', 'isMonth'], fn: ->
|
38
|
+
_.moment.range(
|
39
|
+
@date.clone().startOf( @display ), @date.clone().endOf( @display )
|
40
|
+
)
|
41
|
+
|
42
|
+
calLegend:
|
43
|
+
deps: ['range', 'display'], fn: ->
|
44
|
+
if @display is 'month'
|
45
|
+
@date.format('MMMM YYYY')
|
46
|
+
else if @display is 'week'
|
47
|
+
"#{@range.start.format('MMM Do')} - #{@range.end.format('MMM Do')}"
|
48
|
+
else if @display is 'day'
|
49
|
+
@date.format('MMMM Do YYYY')
|
50
|
+
|
51
|
+
events:
|
52
|
+
'change:range': 'fetchEvents'
|
53
|
+
'change:display': 'onDisplayChange'
|
54
|
+
'change:customer_project_id': 'fetchEvents'
|
55
|
+
|
56
|
+
constructor: ->
|
57
|
+
super
|
58
|
+
@available_projects = new Skr.Models.CustomerProject.Collection
|
59
|
+
@listenTo(@available_projects, 'sync', @onProjectsRequest)
|
60
|
+
@available_projects.ensureLoaded()
|
61
|
+
@entries = new TimeEntries(@available_projects)
|
62
|
+
@listenTo(@entries, 'request', @onRequest)
|
63
|
+
@listenTo(@entries, 'sync', @onLoad)
|
64
|
+
|
65
|
+
onProjectsRequest: ->
|
66
|
+
@available_projects.add({id:-1, code: 'ALL', options:{color: 1}}, at: 0)
|
67
|
+
@set(customer_project_id: Lanes.current_user.options.project_id or -1 )
|
68
|
+
@trigger('change', @)
|
69
|
+
|
70
|
+
startEditing: (editingEvent) ->
|
71
|
+
for event in @calEvents().events
|
72
|
+
event.setEditing(event is editingEvent)
|
73
|
+
|
74
|
+
stopEditing: ->
|
75
|
+
for event in @calEvents().events when event.isEditing()
|
76
|
+
entry = event.get('entry')
|
77
|
+
if entry.isNew()
|
78
|
+
event.remove()
|
79
|
+
else
|
80
|
+
entry.setEditing(false)
|
81
|
+
|
82
|
+
addEvent: (date) ->
|
83
|
+
date = date.clone()
|
84
|
+
rounded = Math.round( date.minute() / 15 ) * 15
|
85
|
+
date.minute(rounded).second(0)
|
86
|
+
entry = @entries.add({
|
87
|
+
start_at: date.subtract(1, 'hour'), end_at: date.clone().add(2, 'hour')
|
88
|
+
customer_project: @project unless @project.id is -1
|
89
|
+
})
|
90
|
+
@calEvents().add( entry.toCalEvent() )
|
91
|
+
|
92
|
+
onRequest: ->
|
93
|
+
@isLoading = !!@entries.requestInProgress
|
94
|
+
@trigger('change', @)
|
95
|
+
|
96
|
+
onLoad: ->
|
97
|
+
delete @_cachedEvents unless @entries.requestInProgress
|
98
|
+
@isLoading = !!@entries.requestInProgress
|
99
|
+
@trigger('change', @)
|
100
|
+
|
101
|
+
reset: ->
|
102
|
+
@entries.loadEntries(@range.clone())
|
103
|
+
|
104
|
+
fetchEvents: ->
|
105
|
+
@entries.resetEntries(@customer_project_id, @range)
|
106
|
+
|
107
|
+
calEvents: ->
|
108
|
+
@_cachedEvents ||= new LC.Calendar.Events( @entries.invoke('toCalEvent') )
|
109
|
+
|
110
|
+
back: ->
|
111
|
+
@set(editing: false, date: @date.clone().subtract(1, @display) )
|
112
|
+
|
113
|
+
forward: ->
|
114
|
+
@set(editing: false, date: @date.clone().add(1, @display) )
|
115
|
+
|
116
|
+
onDisplayChange: ->
|
117
|
+
@editing = false
|
118
|
+
|
119
|
+
totalHours: ->
|
120
|
+
@entries.reduce( (sum, entry) =>
|
121
|
+
sum.add( entry.lengthInRange(@range, 'hours') )
|
122
|
+
, _.bigDecimal('0') )
|
123
|
+
|
124
|
+
totalsForWeek: (week) ->
|
125
|
+
start = @range.start.clone().add(week - 1, 'week').startOf('week')
|
126
|
+
days = _.moment.range( start, start.clone().endOf('week') )
|
127
|
+
entries = @entries.filter (entry) -> days.overlaps( entry.range )
|
128
|
+
byProject = _.groupBy entries, (entry) -> entry.customer_project_id
|
129
|
+
_.mapValues byProject, (entries, projectId) ->
|
130
|
+
_.reduce( entries, (total, entry) ->
|
131
|
+
total.plus(entry.lengthInRange(days, 'hours'))
|
132
|
+
, _.bigDecimal('0'))
|
@@ -0,0 +1,71 @@
|
|
1
|
+
class Skr.Screens.TimeTracking.Header extends Lanes.React.BaseComponent
|
2
|
+
|
3
|
+
back: ->
|
4
|
+
@props.entries.back()
|
5
|
+
forward: ->
|
6
|
+
@props.entries.forward()
|
7
|
+
changeDisplay: (ev) ->
|
8
|
+
@props.entries.display = ev.target.value
|
9
|
+
setProject: (project) ->
|
10
|
+
@props.entries.set(customer_project_id: project.id)
|
11
|
+
ProjectOption: (props) ->
|
12
|
+
color = props.item.options?.color || 0
|
13
|
+
<div className={"color-#{color}"}>{props.item.code}</div>
|
14
|
+
getProjects: ->
|
15
|
+
@props.entries.available_projects.models
|
16
|
+
|
17
|
+
onProjectsToggle: (isOpen) ->
|
18
|
+
if isOpen and not @props.entries.available_projects.requestInProgress
|
19
|
+
@props.entries.available_projects.fetch()
|
20
|
+
@forceUpdate()
|
21
|
+
|
22
|
+
render: ->
|
23
|
+
<BS.Row className='calendar-header'>
|
24
|
+
|
25
|
+
<div className="paging">
|
26
|
+
|
27
|
+
<span className="legend">
|
28
|
+
{@props.entries.calLegend}
|
29
|
+
</span>
|
30
|
+
|
31
|
+
<BS.ButtonGroup>
|
32
|
+
<BS.Button bsSize="small" onClick={@back}>
|
33
|
+
<LC.Icon size='2x' type="caret-left" />
|
34
|
+
</BS.Button>
|
35
|
+
<BS.Button bsSize="small" onClick={@forward}>
|
36
|
+
<LC.Icon size='2x' type="caret-right" />
|
37
|
+
</BS.Button>
|
38
|
+
</BS.ButtonGroup>
|
39
|
+
|
40
|
+
</div>
|
41
|
+
|
42
|
+
<div className="display">
|
43
|
+
<BS.ButtonGroup>
|
44
|
+
<BS.Button
|
45
|
+
value='month' onClick={@changeDisplay}
|
46
|
+
active={@props.entries.display == 'month'}>Month</BS.Button>
|
47
|
+
|
48
|
+
<BS.Button
|
49
|
+
value='week' onClick={@changeDisplay}
|
50
|
+
active={@props.entries.display == 'week'}>Week</BS.Button>
|
51
|
+
|
52
|
+
<BS.Button
|
53
|
+
value='day' onClick={@changeDisplay}
|
54
|
+
active={@props.entries.display == 'day'}>Day</BS.Button>
|
55
|
+
</BS.ButtonGroup>
|
56
|
+
</div>
|
57
|
+
|
58
|
+
<div className="select">
|
59
|
+
<Lanes.Vendor.ReactWidgets.DropdownList
|
60
|
+
data={@getProjects()}
|
61
|
+
busy={!!@props.entries.available_projects.requestInProgress}
|
62
|
+
onToggle={@onProjectsToggle}
|
63
|
+
valueField='id' textField='code'
|
64
|
+
value={@props.entries.project}
|
65
|
+
onChange={@setProject}
|
66
|
+
valueComponent={@ProjectOption}
|
67
|
+
itemComponent={@ProjectOption}
|
68
|
+
/>
|
69
|
+
</div>
|
70
|
+
|
71
|
+
</BS.Row>
|
@@ -0,0 +1,70 @@
|
|
1
|
+
##= require ./PopoverMiniControls
|
2
|
+
##= require ./EditEntry
|
3
|
+
|
4
|
+
class Skr.Screens.TimeTracking.Popover extends Lanes.React.Component
|
5
|
+
|
6
|
+
componentWillReceiveProps: (nextProps) ->
|
7
|
+
if @state.editing and nextProps.editing is false
|
8
|
+
@onCancel()
|
9
|
+
else
|
10
|
+
@setState(isCanceled: false)
|
11
|
+
|
12
|
+
onCancel: ->
|
13
|
+
if @state.editing?.get('entry').isNew()
|
14
|
+
@state.editing.remove()
|
15
|
+
@props.entries.stopEditing()
|
16
|
+
@setState(isCanceled: true, editing: null)
|
17
|
+
|
18
|
+
onAddEntry: ->
|
19
|
+
event = @props.entries.addEvent(@props.date)
|
20
|
+
@setState(editing: event)
|
21
|
+
|
22
|
+
onEditEvent: (event) ->
|
23
|
+
@setState(editing: event)
|
24
|
+
|
25
|
+
EditEntry: ->
|
26
|
+
return null unless @state.editing
|
27
|
+
<Skr.Screens.TimeTracking.EditEntry
|
28
|
+
event={@state.editing}
|
29
|
+
entries={@props.entries}
|
30
|
+
date={@props.date}
|
31
|
+
onCancel={@onCancel}
|
32
|
+
/>
|
33
|
+
|
34
|
+
MiniControls: ->
|
35
|
+
return null if @state.editing
|
36
|
+
<Skr.Screens.TimeTracking.MiniControls
|
37
|
+
date={@props.date}
|
38
|
+
event={@props.event}
|
39
|
+
onCancel={@onCancel}
|
40
|
+
onAddEntry={@onAddEntry}
|
41
|
+
onEditEvent={@onEditEvent}
|
42
|
+
/>
|
43
|
+
|
44
|
+
render: ->
|
45
|
+
return null if @state.isCanceled or not @props.date
|
46
|
+
|
47
|
+
classes = _.classnames('edit-control', 'in')
|
48
|
+
{x, y} = @props.position
|
49
|
+
[width, height] = if @state.editing
|
50
|
+
[320, 400]
|
51
|
+
else
|
52
|
+
[175, 60]
|
53
|
+
|
54
|
+
# expand to show edit button
|
55
|
+
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
|
+
x -= width if placement is 'left'
|
60
|
+
|
61
|
+
<BS.Popover className={classes}
|
62
|
+
style={{width, height}}
|
63
|
+
id='edit-controls'
|
64
|
+
placement={placement}
|
65
|
+
positionLeft={x}
|
66
|
+
positionTop={y - (height / 2)}
|
67
|
+
>
|
68
|
+
<@MiniControls />
|
69
|
+
<@EditEntry />
|
70
|
+
</BS.Popover>
|
@@ -0,0 +1,25 @@
|
|
1
|
+
class Skr.Screens.TimeTracking.MiniControls extends Lanes.React.Component
|
2
|
+
|
3
|
+
onEditEvent: ->
|
4
|
+
@props.onEditEvent(@props.event)
|
5
|
+
|
6
|
+
EditButton: ->
|
7
|
+
return null unless @props.event
|
8
|
+
<BS.Button onClick={@onEditEvent} title="Edit Time Entry">
|
9
|
+
<LC.Icon type='pencil-square-o' 2x flush />
|
10
|
+
</BS.Button>
|
11
|
+
|
12
|
+
render: ->
|
13
|
+
<div className="mini-controls">
|
14
|
+
<div className='l'>
|
15
|
+
{@props.date.format('MMM')}
|
16
|
+
{@props.date.format('Do')}
|
17
|
+
</div>
|
18
|
+
<BS.Button onClick={@props.onCancel} title="Hide Controls">
|
19
|
+
<LC.Icon type='ban' 2x flush />
|
20
|
+
</BS.Button>
|
21
|
+
<@EditButton />
|
22
|
+
<BS.Button onClick={@props.onAddEntry} title="Create Time Entry">
|
23
|
+
<LC.Icon type='plus-square' 2x flush />
|
24
|
+
</BS.Button>
|
25
|
+
</div>
|
@@ -0,0 +1,63 @@
|
|
1
|
+
##= require_self
|
2
|
+
##= require ./Popover
|
3
|
+
##= require ./WeekSummary
|
4
|
+
##= require ./Entries
|
5
|
+
##= require ./Header
|
6
|
+
|
7
|
+
class Skr.Screens.TimeTracking extends Skr.Screens.Base
|
8
|
+
|
9
|
+
dataObjects:
|
10
|
+
entries: ->
|
11
|
+
new Skr.Screens.TimeTracking.Entries
|
12
|
+
|
13
|
+
onDayClick: (ev, date) ->
|
14
|
+
@showPopup(ev, date)
|
15
|
+
|
16
|
+
showPopup: (ev, date, eventEditing = false) ->
|
17
|
+
rect = _.dom(this).el.getBoundingClientRect()
|
18
|
+
@entries.editing = {
|
19
|
+
event: eventEditing,
|
20
|
+
date: date, bounds: rect,
|
21
|
+
position: {x: ev.clientX - rect.left, y: ev.clientY - rect.top}
|
22
|
+
}
|
23
|
+
|
24
|
+
onEventClick: (ev, event) ->
|
25
|
+
@showPopup(ev, event.start(), event)
|
26
|
+
|
27
|
+
stopEdit: ->
|
28
|
+
@entries.editing = false
|
29
|
+
|
30
|
+
onEventResize: (ev, event) ->
|
31
|
+
entry = event.get('entry')
|
32
|
+
entry.fromCalEvent(event)
|
33
|
+
entry.save() unless entry.isNew()
|
34
|
+
|
35
|
+
renderSummaryDays: ->
|
36
|
+
return null unless @entries.isMonth
|
37
|
+
for week in [1..5]
|
38
|
+
<Skr.Screens.TimeTracking.WeekSummary
|
39
|
+
key={week} week={week} entries={@entries} />
|
40
|
+
|
41
|
+
renderTotals: ->
|
42
|
+
return null unless @entries.isMonth
|
43
|
+
<div className="monthly-totals">{@entries.totalHours().toFixed(2)}</div>
|
44
|
+
|
45
|
+
render: ->
|
46
|
+
<LC.ScreenWrapper identifier="time-tracking" flexVertical>
|
47
|
+
<Skr.Screens.TimeTracking.Popover entries={@entries} {...@entries.editing} />
|
48
|
+
<LC.NetworkActivityOverlay visible={@entries.isLoading} model={@entries}/>
|
49
|
+
<Skr.Screens.TimeTracking.Header entries={@entries} />
|
50
|
+
<BS.Row className="calendar-panel">
|
51
|
+
{@renderTotals()}
|
52
|
+
<LC.Calendar ref='calendar'
|
53
|
+
onDayClick={@onDayClick}
|
54
|
+
onEventResize={@onEventResize}
|
55
|
+
onEventClick={@onEventClick}
|
56
|
+
date={@entries.date}
|
57
|
+
events={@entries.calEvents()}
|
58
|
+
display={@entries.display}
|
59
|
+
>
|
60
|
+
{@renderSummaryDays()}
|
61
|
+
</LC.Calendar>
|
62
|
+
</BS.Row>
|
63
|
+
</LC.ScreenWrapper>
|
@@ -0,0 +1,16 @@
|
|
1
|
+
class Skr.Screens.TimeTracking.WeekSummary extends Lanes.React.BaseComponent
|
2
|
+
|
3
|
+
color: (projectId) ->
|
4
|
+
project = @props.entries.available_projects.get(projectId)
|
5
|
+
project?.options?.color || 0
|
6
|
+
|
7
|
+
render: ->
|
8
|
+
order = (@props.week * 7) - 1
|
9
|
+
totals = @props.entries.totalsForWeek(@props.week)
|
10
|
+
|
11
|
+
<div className="day summary" style={order: order}>
|
12
|
+
{for projectId, total of totals
|
13
|
+
<div key={projectId} className="color-#{@color(projectId)}">
|
14
|
+
{Lanes.u.format.currency(total)}
|
15
|
+
</div>}
|
16
|
+
</div>
|
@@ -0,0 +1 @@
|
|
1
|
+
//= require ./TimeTracking
|
@@ -0,0 +1,126 @@
|
|
1
|
+
@import "lanes/screens/styles";
|
2
|
+
|
3
|
+
.time-tracking {
|
4
|
+
position: relative;
|
5
|
+
|
6
|
+
.edit-control {
|
7
|
+
|
8
|
+
.mini-controls {
|
9
|
+
display: flex;
|
10
|
+
flex-direction: row;
|
11
|
+
justify-content: space-between;
|
12
|
+
.l {
|
13
|
+
display: flex;
|
14
|
+
flex-direction: column;
|
15
|
+
align-items: flex-end;
|
16
|
+
}
|
17
|
+
}
|
18
|
+
&.left {
|
19
|
+
.mini-controls {
|
20
|
+
flex-direction: row-reverse;
|
21
|
+
}
|
22
|
+
}
|
23
|
+
}
|
24
|
+
|
25
|
+
.calendar-header {
|
26
|
+
display: flex;
|
27
|
+
flex-direction: row;
|
28
|
+
justify-content: space-around;
|
29
|
+
flex-wrap: wrap;
|
30
|
+
align-items: center;
|
31
|
+
.display label+label {
|
32
|
+
padding-left: 1rem;
|
33
|
+
}
|
34
|
+
.paging {
|
35
|
+
display: flex;
|
36
|
+
flex-direction: row;
|
37
|
+
align-items: center;
|
38
|
+
.legend{
|
39
|
+
font-size: 1.4rem;
|
40
|
+
margin-right: 1rem;
|
41
|
+
}
|
42
|
+
i {
|
43
|
+
margin: 0 0.5em;
|
44
|
+
}
|
45
|
+
}
|
46
|
+
.select {
|
47
|
+
width: 200px;
|
48
|
+
@include lanes-unpadded-dropdown();
|
49
|
+
}
|
50
|
+
}
|
51
|
+
|
52
|
+
.calendar-panel {
|
53
|
+
margin: 5px 20px 20px 20px;
|
54
|
+
@include flexbox();
|
55
|
+
@include flex-grow(1);
|
56
|
+
@include flex-direction(column);
|
57
|
+
}
|
58
|
+
|
59
|
+
.monthly-totals {
|
60
|
+
align-self: flex-end;
|
61
|
+
display: inline;
|
62
|
+
width: 52px;
|
63
|
+
position: relative;
|
64
|
+
top: 18px;
|
65
|
+
|
66
|
+
text-align: right;
|
67
|
+
border-top-right-radius: 8px;
|
68
|
+
border: 1px solid lightgrey;
|
69
|
+
border-top-left-radius: 8px;
|
70
|
+
border-bottom: 0;
|
71
|
+
padding-right: 3px;
|
72
|
+
|
73
|
+
}
|
74
|
+
|
75
|
+
@each $current-color in $lanes-color-selections {
|
76
|
+
$i: index($lanes-color-selections, $current-color);
|
77
|
+
.calendar-header .select .color-#{$i} {
|
78
|
+
background: $current-color;
|
79
|
+
color: nth($lanes-text-color-selections, $i);
|
80
|
+
}
|
81
|
+
.day.summary .color-#{$i} {
|
82
|
+
background: $current-color;
|
83
|
+
color: nth($lanes-text-color-selections, $i);
|
84
|
+
}
|
85
|
+
}
|
86
|
+
|
87
|
+
.dayz {
|
88
|
+
flex: 1;
|
89
|
+
&.month {
|
90
|
+
.x-labels {
|
91
|
+
width: 94.5%;
|
92
|
+
.day-label {
|
93
|
+
width: (100%/7);
|
94
|
+
}
|
95
|
+
}
|
96
|
+
.days {
|
97
|
+
.day {
|
98
|
+
width: 13.5%;
|
99
|
+
}
|
100
|
+
.summary {
|
101
|
+
width: 5.5%;
|
102
|
+
flex-direction: column;
|
103
|
+
display: flex;
|
104
|
+
justify-content: center;
|
105
|
+
text-align: right;
|
106
|
+
}
|
107
|
+
}
|
108
|
+
}
|
109
|
+
}
|
110
|
+
|
111
|
+
.popover {
|
112
|
+
.controls {
|
113
|
+
border-top: 2px solid lightgrey;
|
114
|
+
padding-top: 1rem;
|
115
|
+
display: flex;
|
116
|
+
flex-direction: row;
|
117
|
+
justify-content: space-between;
|
118
|
+
button { width: 6rem; }
|
119
|
+
}
|
120
|
+
}
|
121
|
+
|
122
|
+
.dayz .label {
|
123
|
+
font-size: 1rem;
|
124
|
+
color: darkgrey;
|
125
|
+
}
|
126
|
+
}
|
@@ -0,0 +1,45 @@
|
|
1
|
+
class Skr.Screens.VendorMaint extends Lanes.React.Screen
|
2
|
+
|
3
|
+
syncOptions:
|
4
|
+
include: ['billing_address', 'shipping_address']
|
5
|
+
|
6
|
+
dataObjects:
|
7
|
+
vendor: ->
|
8
|
+
@loadOrCreateModel({
|
9
|
+
syncOptions: @syncOptions, klass: Skr.Models.Vendor,
|
10
|
+
prop: 'vendor', attribute: 'code'
|
11
|
+
})
|
12
|
+
|
13
|
+
getInitialState: ->
|
14
|
+
commands: new Skr.Screens.Commands(this, modelName: 'vendor')
|
15
|
+
|
16
|
+
modelForAccess: 'vendor'
|
17
|
+
|
18
|
+
render: ->
|
19
|
+
<LC.ScreenWrapper identifier="vendor-maint">
|
20
|
+
<SC.ScreenControls commands={@state.commands} />
|
21
|
+
<BS.Row>
|
22
|
+
<SC.VendorFinder model={@vendor} sm=4 editOnly autofocus
|
23
|
+
syncOptions={@syncOptions}
|
24
|
+
model={@vendor} name='code'
|
25
|
+
commands={@state.commands} />
|
26
|
+
<LC.Input sm=8 name="name" model={@vendor} />
|
27
|
+
</BS.Row>
|
28
|
+
<BS.Row>
|
29
|
+
<LC.Input sm=12 type='textarea' name="notes" model={@vendor} />
|
30
|
+
</BS.Row>
|
31
|
+
<BS.Row>
|
32
|
+
<SC.GlAccountChooser sm=4 label="Payables Account"
|
33
|
+
name="gl_payables_account" model={@vendor} />
|
34
|
+
<SC.GlAccountChooser sm=4 label="Freight Account"
|
35
|
+
name="gl_freight_account" model={@vendor} />
|
36
|
+
<SC.TermsChooser sm=4 model={@vendor} />
|
37
|
+
</BS.Row>
|
38
|
+
<BS.Row>
|
39
|
+
<LC.FieldSet sm=12 title="Address">
|
40
|
+
<SC.Address lg=6 title="Billing" model={@vendor.billing_address} />
|
41
|
+
<SC.Address lg=6 title="Shipping" model={@vendor.shipping_address} />
|
42
|
+
</LC.FieldSet>
|
43
|
+
</BS.Row>
|
44
|
+
|
45
|
+
</LC.ScreenWrapper>
|
data/client/skr/styles.scss
CHANGED
@@ -1,17 +1,5 @@
|
|
1
1
|
/* Enter styles for your application in scss format here */
|
2
2
|
|
3
|
-
.header-top {
|
4
|
-
.logo {
|
5
|
-
display: inline-block;
|
6
|
-
height: 48px;
|
7
|
-
width: 150px;
|
8
|
-
margin: 2px;
|
9
|
-
text-indent: -9999px;
|
10
|
-
background: url(asset_path('images/skr/logo-sm.png')) no-repeat;
|
11
|
-
}
|
12
|
-
}
|
13
|
-
|
14
|
-
|
15
3
|
.record-finder-dialog {
|
16
4
|
min-height: 250px;
|
17
5
|
.clause {
|
@@ -31,4 +19,4 @@
|
|
31
19
|
}
|
32
20
|
}
|
33
21
|
|
34
|
-
@import "components/
|
22
|
+
@import "components/styles";
|
data/config/puma.rb
ADDED
data/config/routes.rb
CHANGED
@@ -1,6 +1,9 @@
|
|
1
1
|
require 'stockor'
|
2
2
|
|
3
|
-
Lanes::API.routes.
|
3
|
+
Lanes::API.routes.for_extension 'skr' do
|
4
|
+
|
5
|
+
resources Skr::CustomerProject
|
6
|
+
resources Skr::TimeEntry
|
4
7
|
resources Skr::Customer
|
5
8
|
resources Skr::Address
|
6
9
|
resources Skr::GlAccount
|
@@ -8,11 +11,14 @@ Lanes::API.routes.draw do
|
|
8
11
|
resources Skr::GlPeriod
|
9
12
|
resources Skr::GlPosting
|
10
13
|
resources Skr::GlTransaction
|
14
|
+
resources Skr::BankAccount
|
15
|
+
resources Skr::PaymentCategory
|
16
|
+
resources Skr::Payment
|
11
17
|
resources Skr::IaLine
|
12
18
|
resources Skr::IaReason
|
13
|
-
resources Skr::InvLine
|
19
|
+
resources Skr::InvLine, indestructible: true
|
14
20
|
resources Skr::InventoryAdjustment
|
15
|
-
resources Skr::Invoice
|
21
|
+
resources Skr::Invoice, indestructible: true
|
16
22
|
resources Skr::Location
|
17
23
|
resources Skr::PaymentTerm
|
18
24
|
resources Skr::Sku
|
@@ -20,22 +26,28 @@ Lanes::API.routes.draw do
|
|
20
26
|
resources Skr::SkuTran
|
21
27
|
resources Skr::Uom
|
22
28
|
resources Skr::Vendor
|
23
|
-
|
24
|
-
|
25
29
|
resources Skr::PickTicket
|
26
30
|
resources Skr::PtLine
|
27
|
-
|
28
31
|
resources Skr::PoReceipt
|
29
32
|
resources Skr::PorLine
|
30
|
-
|
31
33
|
resources Skr::PurchaseOrder
|
32
34
|
resources Skr::PoLine
|
33
|
-
|
34
35
|
resources Skr::Voucher
|
35
36
|
resources Skr::VoLine
|
36
|
-
|
37
37
|
resources Skr::SalesOrder
|
38
38
|
resources Skr::SoLine
|
39
39
|
|
40
|
+
post 'invoices/from-time-entries.json',
|
41
|
+
&Skr::Handlers::InvoiceFromTimeEntries.handler
|
42
|
+
|
43
|
+
get 'print/:type/:id.pdf' do
|
44
|
+
content_type 'application/pdf'
|
45
|
+
form = Skr::Print::Form.new(params[:type], params[:id])
|
46
|
+
form.as_pdf
|
47
|
+
end
|
48
|
+
|
49
|
+
post 'fresh-books-imports.json',
|
50
|
+
&Skr::Handlers::FreshBooksImport.handler
|
51
|
+
|
40
52
|
|
41
53
|
end
|