stockor 0.1.9 → 0.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (313) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile +1 -1
  3. data/Gemfile.lock +254 -72
  4. data/Guardfile +1 -1
  5. data/README.md +24 -3
  6. data/app.json +28 -0
  7. data/client/skr/Extension.coffee +18 -0
  8. data/client/skr/components/BankAccountFinder.cjsx +34 -0
  9. data/client/skr/components/Currency.cjsx +19 -0
  10. data/client/skr/components/CustomerFinder.cjsx +37 -0
  11. data/client/skr/components/CustomerLink.cjsx +13 -0
  12. data/client/skr/components/CustomerProjectFinder.cjsx +49 -0
  13. data/client/skr/components/GlAccountChooser.cjsx +38 -0
  14. data/client/skr/components/InvoiceFinder.cjsx +37 -0
  15. data/client/skr/components/InvoiceLink.cjsx +13 -0
  16. data/client/skr/components/LocationChooser.cjsx +37 -0
  17. data/client/skr/components/PaymentCategoryFinder.cjsx +34 -0
  18. data/client/skr/components/PrintFormChooser.cjsx +29 -0
  19. data/client/skr/components/SalesOrderFinder.cjsx +38 -0
  20. data/client/skr/components/ScreenControls.cjsx +20 -0
  21. data/client/skr/components/SkuFinder.cjsx +30 -0
  22. data/client/skr/components/SkuLines.cjsx +76 -0
  23. data/client/skr/components/SystemSettings.cjsx +26 -0
  24. data/client/skr/components/TermsChooser.cjsx +40 -0
  25. data/client/skr/components/ToolbarButton.cjsx +7 -0
  26. data/client/skr/components/TotalsLine.cjsx +21 -0
  27. data/client/skr/components/TriStateIcon.cjsx +12 -0
  28. data/client/skr/components/UOMChooser.cjsx +24 -0
  29. data/client/skr/components/UserPreferences.cjsx +30 -0
  30. data/client/skr/components/VendorFinder.cjsx +40 -0
  31. data/client/skr/components/address/Address.cjsx +10 -10
  32. data/client/skr/components/styles.scss +16 -0
  33. data/client/skr/index.js +3 -1
  34. data/client/skr/models/Address.coffee +9 -1
  35. data/client/skr/models/BankAccount.coffee +17 -0
  36. data/client/skr/models/Base.coffee +6 -0
  37. data/client/skr/models/Customer.coffee +17 -10
  38. data/client/skr/models/CustomerProject.coffee +29 -0
  39. data/client/skr/models/GlAccount.coffee +22 -10
  40. data/client/skr/models/GlManualEntry.coffee +4 -2
  41. data/client/skr/models/GlPeriod.coffee +4 -6
  42. data/client/skr/models/GlPosting.coffee +7 -7
  43. data/client/skr/models/GlTransaction.coffee +3 -3
  44. data/client/skr/models/IaLine.coffee +9 -9
  45. data/client/skr/models/IaReason.coffee +4 -4
  46. data/client/skr/models/InvLine.coffee +30 -11
  47. data/client/skr/models/InventoryAdjustment.coffee +8 -6
  48. data/client/skr/models/Invoice.coffee +89 -18
  49. data/client/skr/models/Location.coffee +27 -6
  50. data/client/skr/models/Payment.coffee +36 -0
  51. data/client/skr/models/PaymentCategory.coffee +12 -0
  52. data/client/skr/models/PaymentTerm.coffee +17 -4
  53. data/client/skr/models/PickTicket.coffee +7 -5
  54. data/client/skr/models/PoLine.coffee +15 -15
  55. data/client/skr/models/PoReceipt.coffee +8 -6
  56. data/client/skr/models/PorLine.coffee +11 -11
  57. data/client/skr/models/PricingProvider.coffee +6 -0
  58. data/client/skr/models/PtLine.coffee +13 -13
  59. data/client/skr/models/PurchaseOrder.coffee +11 -9
  60. data/client/skr/models/SalesOrder.coffee +59 -22
  61. data/client/skr/models/Sku.coffee +17 -15
  62. data/client/skr/models/SkuLoc.coffee +14 -9
  63. data/client/skr/models/SkuTran.coffee +10 -10
  64. data/client/skr/models/SkuVendor.coffee +9 -9
  65. data/client/skr/models/SoLine.coffee +27 -20
  66. data/client/skr/models/TimeEntry.coffee +75 -0
  67. data/client/skr/models/Uom.coffee +27 -6
  68. data/client/skr/models/Vendor.coffee +14 -12
  69. data/client/skr/models/VoLine.coffee +11 -11
  70. data/client/skr/models/Voucher.coffee +7 -5
  71. data/client/skr/models/mixins/HasVisibleId.coffee +7 -0
  72. data/client/skr/models/mixins/PrintSupport.coffee +6 -0
  73. data/client/skr/models/mixins/SkuLine.coffee +61 -0
  74. data/client/skr/screens/Commands.coffee +29 -0
  75. data/client/skr/screens/bank-maint/BankMaint.cjsx +43 -0
  76. data/client/skr/screens/bank-maint/index.js +5 -0
  77. data/client/skr/screens/chart-of-accounts/ChartOfAccounts.cjsx +40 -0
  78. data/client/skr/screens/chart-of-accounts/index.js +1 -0
  79. data/client/skr/screens/chart-of-accounts/index.scss +12 -0
  80. data/client/skr/screens/customer-maint/CustomerMaint.cjsx +35 -36
  81. data/client/skr/screens/customer-projects/CustomerProjects.cjsx +70 -0
  82. data/client/skr/screens/customer-projects/index.js +5 -0
  83. data/client/skr/screens/customer-projects/index.scss +25 -0
  84. data/client/skr/screens/fresh-books-import/ApiInfo.cjsx +35 -0
  85. data/client/skr/screens/fresh-books-import/ChooseRecords.cjsx +116 -0
  86. data/client/skr/screens/fresh-books-import/FreshBooksImport.cjsx +31 -0
  87. data/client/skr/screens/fresh-books-import/Import.coffee +52 -0
  88. data/client/skr/screens/fresh-books-import/ViewRecords.cjsx +96 -0
  89. data/client/skr/screens/fresh-books-import/index.js +1 -0
  90. data/client/skr/screens/fresh-books-import/index.scss +39 -0
  91. data/client/skr/screens/gl-accounts/GlAccounts.cjsx +31 -0
  92. data/client/skr/screens/gl-accounts/index.js +5 -0
  93. data/client/skr/screens/gl-transactions/GlTransactions.cjsx +46 -0
  94. data/client/skr/screens/gl-transactions/index.js +1 -0
  95. data/client/skr/screens/gl-transactions/index.scss +12 -0
  96. data/client/skr/screens/invoice/Invoice.cjsx +92 -0
  97. data/client/skr/screens/invoice/Payment.cjsx +28 -0
  98. data/client/skr/screens/invoice/index.js +5 -0
  99. data/client/skr/screens/locations/Locations.cjsx +31 -0
  100. data/client/skr/screens/locations/index.js +5 -0
  101. data/client/skr/screens/payment-category/PaymentCategory.cjsx +28 -0
  102. data/client/skr/screens/payment-category/index.js +5 -0
  103. data/client/skr/screens/payment-category/index.scss +9 -0
  104. data/client/skr/screens/payment-terms/PaymentTerms.cjsx +28 -0
  105. data/client/skr/screens/payment-terms/index.js +5 -0
  106. data/client/skr/screens/payment-terms/index.scss +9 -0
  107. data/client/skr/screens/payments/Payments.cjsx +59 -0
  108. data/client/skr/screens/payments/index.js +5 -0
  109. data/client/skr/screens/sales-order/SalesOrder.cjsx +68 -0
  110. data/client/skr/screens/sales-order/index.js +1 -5
  111. data/client/skr/screens/sku-maint/SkuMaint.cjsx +53 -0
  112. data/client/skr/screens/sku-maint/SkuUomList.cjsx +209 -0
  113. data/client/skr/screens/sku-maint/index.js +2 -5
  114. data/client/skr/screens/sku-maint/index.scss +37 -6
  115. data/client/skr/screens/time-invoicing/TimeInvoicing.cjsx +156 -0
  116. data/client/skr/screens/time-invoicing/index.js +5 -0
  117. data/client/skr/screens/time-invoicing/index.scss +7 -0
  118. data/client/skr/screens/time-tracking/EditEntry.cjsx +54 -0
  119. data/client/skr/screens/time-tracking/Entries.coffee +132 -0
  120. data/client/skr/screens/time-tracking/Header.cjsx +71 -0
  121. data/client/skr/screens/time-tracking/Popover.cjsx +70 -0
  122. data/client/skr/screens/time-tracking/PopoverMiniControls.cjsx +25 -0
  123. data/client/skr/screens/time-tracking/TimeTracking.cjsx +63 -0
  124. data/client/skr/screens/time-tracking/WeekSummary.cjsx +16 -0
  125. data/client/skr/screens/time-tracking/index.js +1 -0
  126. data/client/skr/screens/time-tracking/index.scss +126 -0
  127. data/client/skr/screens/vendor-maint/VendorMaint.cjsx +45 -0
  128. data/client/skr/screens/vendor-maint/index.js +1 -5
  129. data/client/skr/styles.scss +1 -13
  130. data/config/puma.rb +4 -0
  131. data/config/routes.rb +21 -9
  132. data/config/screens.rb +147 -32
  133. data/db/migrate/20140202194700_create_skr_gl_transaction_details.rb +35 -0
  134. data/db/migrate/20140220031800_create_skr_locations.rb +2 -0
  135. data/db/migrate/20140220190836_create_skr_vendors.rb +1 -0
  136. data/db/migrate/20140220203029_create_skr_customers.rb +3 -2
  137. data/db/migrate/20140224034759_create_skr_skus.rb +2 -3
  138. data/db/migrate/20140322223912_create_skr_sales_orders.rb +4 -3
  139. data/db/migrate/20140322223920_create_skr_so_lines.rb +4 -5
  140. data/db/migrate/20140323001446_create_so_details_view.rb +7 -5
  141. data/db/migrate/20140327202209_create_skr_pt_lines.rb +2 -2
  142. data/db/migrate/20140327214000_create_customer_project.rb +16 -0
  143. data/db/migrate/20140327223002_create_time_entries.rb +17 -0
  144. data/db/migrate/20140327224000_create_skr_invoices.rb +5 -1
  145. data/db/migrate/20140327224002_create_skr_inv_lines.rb +3 -1
  146. data/db/migrate/20140422024010_create_skr_inv_details_view.rb +1 -1
  147. data/db/migrate/20151121211323_create_customer_project_details_views.rb +31 -0
  148. data/db/migrate/20160216142845_create_gl_account_balances_view.rb +20 -0
  149. data/db/migrate/20160229002044_create_bank_accounts.rb +18 -0
  150. data/db/migrate/20160229041711_create_payments.rb +33 -0
  151. data/db/migrate/20160307022705_create_create_combined_uom_views.rb +18 -0
  152. data/db/schema.sql +639 -140
  153. data/db/seed/chart_of_accounts.yml +8 -6
  154. data/db/seed/payment_categories.yml +12 -0
  155. data/db/seed/skus.yml +32 -0
  156. data/db/seed.rb +21 -0
  157. data/lib/skr/access_roles.rb +19 -6
  158. data/lib/skr/concerns/has_sku_loc_lines.rb +0 -16
  159. data/lib/skr/concerns/inv_extensions.rb +24 -0
  160. data/lib/skr/concerns/is_sku_loc_line.rb +3 -4
  161. data/lib/skr/concerns/so_extensions.rb +8 -0
  162. data/lib/skr/concerns/visible_id_identifier.rb +1 -1
  163. data/lib/skr/db/migration_helpers.rb +2 -4
  164. data/lib/skr/extension.rb +11 -4
  165. data/lib/skr/handlers/fresh_books_import.rb +20 -0
  166. data/lib/skr/handlers/invoice_from_time_entries.rb +49 -0
  167. data/lib/skr/jobs/fresh_books/base.rb +54 -0
  168. data/lib/skr/jobs/fresh_books/import.rb +151 -0
  169. data/lib/skr/jobs/fresh_books/retrieve.rb +62 -0
  170. data/lib/skr/model.rb +5 -0
  171. data/lib/skr/models/address.rb +1 -1
  172. data/lib/skr/models/bank_account.rb +13 -0
  173. data/lib/skr/models/business_entity.rb +3 -0
  174. data/lib/skr/models/customer.rb +1 -1
  175. data/lib/skr/models/customer_project.rb +22 -0
  176. data/lib/skr/models/gl_account.rb +13 -3
  177. data/lib/skr/models/gl_period.rb +6 -0
  178. data/lib/skr/models/gl_posting.rb +7 -4
  179. data/lib/skr/models/gl_transaction.rb +19 -33
  180. data/lib/skr/models/ia_line.rb +1 -1
  181. data/lib/skr/models/inv_line.rb +33 -15
  182. data/lib/skr/models/invoice.rb +47 -20
  183. data/lib/skr/models/location.rb +7 -1
  184. data/lib/skr/models/payment.rb +49 -0
  185. data/lib/skr/models/payment_category.rb +11 -0
  186. data/lib/skr/models/payment_term.rb +1 -1
  187. data/lib/skr/models/por_line.rb +1 -1
  188. data/lib/skr/models/pt_line.rb +1 -1
  189. data/lib/skr/models/sales_order.rb +9 -9
  190. data/lib/skr/models/sku_loc.rb +1 -1
  191. data/lib/skr/models/sku_tran.rb +6 -11
  192. data/lib/skr/models/so_line.rb +22 -12
  193. data/lib/skr/models/time_entry.rb +36 -0
  194. data/lib/skr/models/uom.rb +11 -10
  195. data/lib/skr/models/user_proxy.rb +1 -1
  196. data/lib/skr/number.rb +25 -0
  197. data/lib/skr/print/form.rb +46 -0
  198. data/lib/skr/print/template.rb +48 -0
  199. data/lib/skr/print.rb +11 -0
  200. data/lib/skr/string.rb +11 -0
  201. data/lib/skr/version.rb +1 -1
  202. data/lib/skr.rb +9 -0
  203. data/spec/fixtures/skr/address.yml +164 -4
  204. data/spec/fixtures/skr/bank_account.yml +8 -0
  205. data/spec/fixtures/skr/customer.yml +30 -4
  206. data/spec/fixtures/skr/customer_project.yml +20 -0
  207. data/spec/fixtures/skr/gl_account.yml +19 -1
  208. data/spec/fixtures/skr/gl_period.yml +3 -0
  209. data/spec/fixtures/skr/gl_posting.yml +22 -1
  210. data/spec/fixtures/skr/gl_transaction.yml +4 -1
  211. data/spec/fixtures/skr/inv_line.yml +35 -0
  212. data/spec/fixtures/skr/invoice.yml +13 -2
  213. data/spec/fixtures/skr/location.yml +5 -0
  214. data/spec/fixtures/skr/payment.yml +10 -0
  215. data/spec/fixtures/skr/payment_category.yml +8 -0
  216. data/spec/fixtures/skr/payment_term.yml +37 -3
  217. data/spec/fixtures/skr/sales_order.yml +12 -1
  218. data/spec/fixtures/skr/sku.yml +78 -1
  219. data/spec/fixtures/skr/sku_loc.yml +42 -1
  220. data/spec/fixtures/skr/sku_tran.yml +24 -1
  221. data/spec/fixtures/skr/so_line.yml +32 -0
  222. data/spec/fixtures/skr/time_entry.yml +82 -0
  223. data/spec/fixtures/skr/uom.yml +52 -1
  224. data/spec/fixtures/skr/vendor.yml +28 -1
  225. data/spec/fixtures/stockor.png +0 -0
  226. data/spec/server/bank_account_spec.rb +10 -0
  227. data/spec/server/customer_project_spec.rb +10 -0
  228. data/spec/server/handlers/invoice_from_time_entries_spec.rb +49 -0
  229. data/spec/server/jobs/fresh_books/import_spec.rb +69 -0
  230. data/spec/server/jobs/fresh_books/retrieve_spec.rb +37 -0
  231. data/spec/server/models/address_spec.rb +4 -3
  232. data/spec/server/models/gl_transaction_spec.rb +3 -3
  233. data/spec/server/models/inv_line_spec.rb +83 -3
  234. data/spec/server/models/invoice_spec.rb +32 -3
  235. data/spec/server/models/payment_spec.rb +40 -0
  236. data/spec/server/models/sales_order_spec.rb +1 -1
  237. data/spec/server/models/so_line_spec.rb +3 -3
  238. data/spec/server/models/spec_helper_spec.rb +1 -1
  239. data/spec/server/payment_spec.rb +10 -0
  240. data/spec/server/print/form_spec.rb +47 -0
  241. data/spec/server/print/template_spec.rb +36 -0
  242. data/spec/server/spec_helper.rb +14 -1
  243. data/spec/server/time_entry_spec.rb +10 -0
  244. data/spec/skr/components/SkuLinesSpec.coffee +61 -0
  245. data/spec/skr/models/BankAccountSpec.coffee +5 -0
  246. data/spec/skr/models/CustomerProjectSpec.coffee +5 -0
  247. data/spec/skr/models/CustomerSpec.coffee +2 -2
  248. data/spec/skr/models/PaymentSpec.coffee +5 -0
  249. data/spec/skr/models/SalesOrderSpec.coffee +21 -5
  250. data/spec/skr/models/SoLineSpec.coffee +7 -2
  251. data/spec/skr/models/TimeEntrySpec.coffee +5 -0
  252. data/spec/skr/screens/bank-maint/BankMaintSpec.coffee +5 -0
  253. data/spec/skr/screens/customer-projects/CustomerProjectsSpec.coffee +5 -0
  254. data/spec/skr/screens/fresh-books-import/FreshBooksImportSpec.coffee +1 -0
  255. data/spec/skr/screens/gl-accounts/GlAccountsSpec.coffee +5 -0
  256. data/spec/skr/screens/invoice/InvoiceSpec.coffee +5 -0
  257. data/spec/skr/screens/locations/LocationsSpec.coffee +5 -0
  258. data/spec/skr/screens/payment-category/PaymentCategorySpec.coffee +5 -0
  259. data/spec/skr/screens/payment-terms/PaymentTermsSpec.coffee +5 -0
  260. data/spec/skr/screens/payments/PaymentsSpec.coffee +5 -0
  261. data/spec/skr/screens/time-invoicing/TimeInvoicingSpec.coffee +5 -0
  262. data/spec/skr/screens/time-tracking/TimeTrackingSpec.coffee +14 -0
  263. data/spec/vcr/freshbooks.yml +698 -0
  264. data/stockor.gemspec +5 -1
  265. data/templates/print/fonts/GnuMICR.otf +0 -0
  266. data/templates/print/layout.tex.erb +39 -0
  267. data/templates/print/packages/booktabs.sty +182 -0
  268. data/templates/print/packages/fancybox.sty +966 -0
  269. data/templates/print/packages/fancyhdr.sty +485 -0
  270. data/templates/print/packages/graphbox.sty +129 -0
  271. data/templates/print/packages/lastpage.sty +283 -0
  272. data/templates/print/packages/lastpage209.sty +70 -0
  273. data/templates/print/packages/marginnote.sty +412 -0
  274. data/templates/print/packages/multirow.sty +159 -0
  275. data/templates/print/packages/rotating.sty +282 -0
  276. data/templates/print/packages/tabu.sty +2557 -0
  277. data/templates/print/packages/textpos.sty +361 -0
  278. data/templates/print/packages/varwidth.sty +318 -0
  279. data/templates/print/partials/address.tex.erb +6 -0
  280. data/templates/print/partials/bill_to_ship_to.tex.erb +13 -0
  281. data/templates/print/partials/header.tex.erb +13 -0
  282. data/templates/print/partials/invoice_paid_state.tex.erb +2 -0
  283. data/templates/print/partials/old/inv_lines_grouping.tex.erb +8 -0
  284. data/templates/print/partials/old/labor_lines_footer.tex.erb +18 -0
  285. data/templates/print/partials/skus_table.tex.erb +32 -0
  286. data/templates/print/partials/skus_table_col_hdr.tex.erb +8 -0
  287. data/templates/print/partials/skus_table_footer.tex.erb +5 -0
  288. data/templates/print/partials/skus_table_group_footer.tex.erb +4 -0
  289. data/templates/print/partials/skus_table_invoice_footer.tex.erb +25 -0
  290. data/templates/print/partials/skus_table_invoice_info_line.tex.erb +16 -0
  291. data/templates/print/partials/skus_table_labor_col_hdr.tex.erb +8 -0
  292. data/templates/print/partials/skus_table_labor_group_footer.tex.erb +7 -0
  293. data/templates/print/partials/skus_table_labor_line.tex.erb +11 -0
  294. data/templates/print/partials/skus_table_line.tex.erb +6 -0
  295. data/templates/print/partials/skus_table_other_charge_lines.tex.erb +7 -0
  296. data/templates/print/partials/so_info_line.tex.erb +14 -0
  297. data/templates/print/types/invoice/default.tex.erb +13 -0
  298. data/templates/print/types/invoice/labor.tex.erb +33 -0
  299. data/templates/print/types/payment/default.tex.erb +64 -0
  300. data/templates/print/types/sales-order/default.tex.erb +8 -0
  301. metadata +252 -15
  302. data/client/skr/components/address/address.html +0 -20
  303. data/client/skr/models/mixins/CodeField.coffee +0 -5
  304. data/client/skr/screens/customer-maint/index.scss +0 -11
  305. data/client/skr/screens/customer-maint/layout.html +0 -32
  306. data/client/skr/screens/sales-order/SalesOrder.coffee +0 -30
  307. data/client/skr/screens/sales-order/index.scss +0 -8
  308. data/client/skr/screens/sales-order/layout.html +0 -30
  309. data/client/skr/screens/sku-maint/SkuMaint.coffee +0 -18
  310. data/client/skr/screens/sku-maint/layout.html +0 -16
  311. data/client/skr/screens/vendor-maint/VendorMaint.coffee +0 -28
  312. data/client/skr/screens/vendor-maint/index.scss +0 -8
  313. data/client/skr/screens/vendor-maint/layout.html +0 -32
@@ -0,0 +1,31 @@
1
+ ##= require_self
2
+ ##= require ./Import
3
+ ##= require ./ApiInfo
4
+ ##= require ./ChooseRecords
5
+ ##= require ./ViewRecords
6
+
7
+ class Skr.Screens.FreshBooksImport extends Skr.Screens.Base
8
+ modelForAccess: 'invoice'
9
+ getInitialState: -> isEditing: true
10
+ dataObjects:
11
+ import: ->
12
+ new Skr.Screens.FreshBooksImport.Import
13
+
14
+ JobStatus: ->
15
+ return null unless @import.job.isExecuting
16
+ message = if @import.stage is 'complete'
17
+ "Importing records from Fresh Books"
18
+ else
19
+ "Loading record summaries from Fresh Books"
20
+ <LC.JobStatus job={@import.job} onlyExecuting
21
+ message={message} />
22
+
23
+ render: ->
24
+ <LC.ScreenWrapper identifier="fresh-books-import">
25
+ <LC.ErrorDisplay model={@import} />
26
+
27
+ <Skr.Screens.FreshBooksImport.ApiInfo import={@import} />
28
+ <@JobStatus />
29
+ <Skr.Screens.FreshBooksImport.ChooseRecords import={@import} />
30
+ <Skr.Screens.FreshBooksImport.ViewRecords import={@import} />
31
+ </LC.ScreenWrapper>
@@ -0,0 +1,52 @@
1
+ class Skr.Screens.FreshBooksImport.Import extends Skr.Models.Base
2
+
3
+ modelTypeIdentifier: -> 'fresh-books-import'
4
+
5
+ props:
6
+ domain: 'string'
7
+ api_key: 'string'
8
+ stage: {type: 'string', default: 'fetch'}
9
+ ignored_ids: 'object'
10
+ user_mappings: 'object'
11
+ customer_codes: 'object'
12
+
13
+ associations:
14
+ job: {model: 'Lanes.Models.JobStatus'}
15
+
16
+ hasPendingRecords: ->
17
+ @stage is 'fetch' and @hasRecords() and not @job?.isActive
18
+
19
+ hasImportedRecords: ->
20
+ @stage is 'complete' and @hasRecords() and not @job?.isActive
21
+
22
+ hasRecords: ->
23
+ not _.isEmpty(@job.data?.output)
24
+
25
+ recordTypes: ['clients', 'projects', 'invoices', 'time_entries', 'staff']
26
+
27
+ recordsForType: (type) ->
28
+ @job.data.output[type] || []
29
+
30
+ isComplete: ->
31
+ @stage is 'complete'
32
+
33
+ complete: ->
34
+ @ignored_ids = {}
35
+ for type in @recordTypes
36
+ @ignored_ids[type] = ids = []
37
+ idprop = _.singularize(type) + '_id'
38
+ for record in @recordsForType(type) when record.selected is false
39
+ ids.push(record[idprop])
40
+
41
+ @user_mappings = {}
42
+ for row in @recordsForType('staff')
43
+ if row.mapped_user_id
44
+ @user_mappings[row.staff_id] = row.mapped_user_id
45
+
46
+ @customer_codes = {}
47
+ for row in @recordsForType('clients')
48
+ if row.customer_code
49
+ @customer_codes[row.client_id] = row.customer_code
50
+
51
+ @stage = 'complete'
52
+ @save(excludeAssociations: true)
@@ -0,0 +1,96 @@
1
+ # coffeelint: disable=max_line_length
2
+ class Skr.Screens.FreshBooksImport.ViewRecords extends Lanes.React.Component
3
+ listenNetworkEvents: true
4
+ dataObjects:
5
+ import: 'props'
6
+ job: -> @props.import.job
7
+
8
+ getCustomer: (id) ->
9
+ _.find @import.recordsForType('clients'), (c) -> c.id is id
10
+
11
+ Staff: (props) ->
12
+ <BS.Table responsive striped bordered condensed hover>
13
+ <thead>
14
+ <tr>
15
+ <th>Login</th><th>Name</th><th>Email</th>
16
+ </tr>
17
+ </thead>
18
+ <tbody>
19
+ {for row, i in props.records
20
+ <tr key={i}><td>{row.login}</td><td>{row.name}</td><td>{row.email}</td></tr>}
21
+ </tbody>
22
+ </BS.Table>
23
+
24
+ Clients: (props) ->
25
+ <BS.Table responsive striped bordered condensed hover>
26
+ <thead>
27
+ <tr><th>Code</th><th>Name</th><th>Notes</th></tr>
28
+ </thead>
29
+ <tbody>
30
+ {for row, i in props.records
31
+ cust = new Skr.Models.Customer(row)
32
+ <tr key={i}>
33
+ <td><SC.CustomerLink customer={cust} /></td>
34
+ <td>{row.name}</td><td>{row.notes}</td>
35
+ </tr>}
36
+ </tbody>
37
+ </BS.Table>
38
+
39
+ Projects: (props) ->
40
+ <BS.Table responsive striped bordered condensed hover>
41
+ <thead>
42
+ <tr><th>Code</th><th>Description</th><th>Customer</th></tr>
43
+ </thead>
44
+ <tbody>
45
+ {for row, i in props.records
46
+ <tr key={i}>
47
+ <td>{row.code}</td><td>{row.description}</td>
48
+ <td>{@getCustomer(row.customer_id)?.code}</td>
49
+ </tr>}
50
+ </tbody>
51
+ </BS.Table>
52
+
53
+ Invoices: (props) ->
54
+ <BS.Table responsive striped bordered condensed hover>
55
+ <thead>
56
+ <tr><th>ID</th><th>Customer</th><th>Date</th><th>Notes</th></tr>
57
+ </thead>
58
+ <tbody>
59
+ {for row, i in props.records
60
+ inv = new Skr.Models.Invoice(row)
61
+ <tr key={i}>
62
+ <td><SC.InvoiceLink invoice={inv} /></td><td>{@getCustomer(row.customer_id)?.code}</td>
63
+ <td>{row.invoice_date}</td><td>{row.notes}</td>
64
+ </tr>}
65
+ </tbody>
66
+ </BS.Table>
67
+
68
+ Time_entries: (props) ->
69
+ <BS.Table responsive striped bordered condensed hover>
70
+ <thead>
71
+ <tr><th>Start At</th><th>End At</th><th>Description</th></tr>
72
+ </thead>
73
+ <tbody>
74
+ {for row, i in props.records
75
+ <tr key={i}>
76
+ <td>{row.start_at}</td><td>{row.end_at}</td>
77
+ <td>{row.description}</td>
78
+ </tr>}
79
+ </tbody>
80
+ </BS.Table>
81
+
82
+
83
+ BlankTable: (props) ->
84
+ <span />
85
+
86
+ render: ->
87
+ return null unless @import.hasImportedRecords()
88
+
89
+ <h3>Import Success!</h3>
90
+ <BS.Tabs animation={false} defaultActiveKey={0}>
91
+ {for type, i in @import.recordTypes
92
+ TableType = @[_.capitalize(type)] || @BlankTable
93
+ <BS.Tab eventKey={i} key={i} title={_.titleize(type)} animation={false}>
94
+ <TableType type={type} records={@import.recordsForType(type)} />
95
+ </BS.Tab>}
96
+ </BS.Tabs>
@@ -0,0 +1 @@
1
+ //= require ./FreshBooksImport
@@ -0,0 +1,39 @@
1
+ .fresh-books-import {
2
+ .domain .value {
3
+ margin-top: 15px;
4
+ }
5
+ .job-executing {
6
+ width: 80%;
7
+ margin: 80px auto;
8
+ }
9
+
10
+ .import-records {
11
+ .clients tbody tr td:last-child {
12
+ width: 130px;
13
+ input { width: 100%; }
14
+ }
15
+ .header {
16
+ display: flex;
17
+ flex-direction: row;
18
+ justify-content: space-between;
19
+ align-items: center;
20
+ }
21
+ h3 { margin: 0; }
22
+ td,th {
23
+ &:first-child {
24
+ width: 80px;
25
+ text-align: center;
26
+ }
27
+ }
28
+ .table-responsive {
29
+ overflow: visible;
30
+ }
31
+ table.staff {
32
+ td,th {
33
+ &:last-child {
34
+ width: 200px;
35
+ }
36
+ }
37
+ }
38
+ }
39
+ }
@@ -0,0 +1,31 @@
1
+ class Skr.Screens.GlAccounts extends Skr.Screens.Base
2
+
3
+ dataObjects:
4
+ account: ->
5
+ @loadOrCreateModel({
6
+ klass: Skr.Models.GlAccount,
7
+ prop: 'account', attribute: 'number'
8
+ })
9
+
10
+ getInitialState: ->
11
+ commands: new Skr.Screens.Commands(this, modelName: 'account', print: true)
12
+
13
+ render: ->
14
+ <LC.ScreenWrapper identifier="gl-accounts">
15
+ <SC.ScreenControls commands={@state.commands} />
16
+ <BS.Row>
17
+
18
+ <SC.GlAccountChooser sm=2 model={@account}
19
+ commands={@state.commands}
20
+ label='Number' name="number" editOnly finderField />
21
+
22
+ <LC.ToggleField sm=2 align='center' label="Active?"
23
+ name="is_active" model={@account} />
24
+
25
+ <LC.Input sm=8 name="name" model={@account} />
26
+
27
+ </BS.Row>
28
+ <BS.Row>
29
+ <LC.Input type='textarea' sm=12 name="description" model={@account} />
30
+ </BS.Row>
31
+ </LC.ScreenWrapper>
@@ -0,0 +1,5 @@
1
+ //= require_tree .
2
+
3
+ /*
4
+ Add additional requirement statements for other files that the screen uses
5
+ */
@@ -0,0 +1,46 @@
1
+ RenderPosting = (props) ->
2
+ contents = _.map props.value, (posting, i) ->
3
+ <span className='posting' key={i}>
4
+ {posting.account_number}
5
+ <SC.Currency amount={posting.amount} />
6
+ </span>
7
+ <div>{contents}</div>
8
+
9
+ class Transactions extends Skr.Models.Base
10
+
11
+ query: new Lanes.Models.Query
12
+ title: 'Lines', src: Skr.Models.GlTransaction
13
+ syncOptions: { with: ['with_details'] }
14
+ fields: [
15
+ { id: 'id', visible: false }
16
+ { id: 'created_at', title: 'Date', format: Lanes.u.format.shartDate, fixedWidth: 100 }
17
+ { id: 'debit_details', title: 'Debit', component: RenderPosting }
18
+ { id: 'credit_details', title: 'Credit', component: RenderPosting }
19
+ { id: 'source_type', fixedWidth: 180 }
20
+ { id: 'description' }
21
+ ]
22
+
23
+ associations:
24
+ account: { model: "GlAccount" }
25
+
26
+ events:
27
+ 'change:account': 'onAccountChange'
28
+
29
+ onAccountChange: (account) ->
30
+ acct_num = if @account?.number then "#{@account.number}%" else ''
31
+ @query.syncOptions = { with: { with_details: acct_num } }
32
+ @query.results.reload()
33
+
34
+ class Skr.Screens.GlTransactions extends Skr.Screens.Base
35
+
36
+ modelForAccess: 'gl-transaction'
37
+
38
+ dataObjects:
39
+ transactions: -> new Transactions(account: @props.account)
40
+
41
+ render: ->
42
+ <LC.ScreenWrapper flexVertical identifier="gl-transactions">
43
+ <h3>GL Transactions</h3>
44
+ <SC.GlAccountChooser model={@transactions} name='account' editOnly sm={4} />
45
+ <LC.Grid query={@transactions.query} />
46
+ </LC.ScreenWrapper>
@@ -0,0 +1 @@
1
+ //=require ./GlTransactions
@@ -0,0 +1,12 @@
1
+ .gl-transactions {
2
+
3
+ .grid-body {
4
+
5
+ .posting {
6
+ & + .posting { margin-left: 3px; }
7
+ padding: 3px;
8
+ background-color: lightGrey;
9
+ border-radius: 4px;
10
+ }
11
+ }
12
+ }
@@ -0,0 +1,92 @@
1
+ ##= require_self
2
+ ##= require ./Payment
3
+
4
+ class Skr.Screens.Invoice extends Skr.Screens.Base
5
+
6
+ syncOptions:
7
+ with: [ 'with_details' ]
8
+ include: [ 'sales_order', 'billing_address', 'shipping_address', 'lines' ]
9
+
10
+ dataObjects:
11
+ invoice: ->
12
+ @loadOrCreateModel({
13
+ syncOptions: @syncOptions, klass: Skr.Models.Invoice,
14
+ prop: 'invoice', attribute: 'visible_id'
15
+ })
16
+
17
+ getInitialState: ->
18
+ commands: new Skr.Screens.Commands(this, modelName: 'invoice', print: true)
19
+
20
+ setSalesOrder: (so) -> @invoice.setFromSalesOrder(so)
21
+ onPayment: -> @invoice.save()
22
+
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} />
28
+
29
+ PaymentButton: ->
30
+ return null if @invoice.isNew() or @invoice.isPaidInFull()
31
+ <SC.ToolbarButton onClick={@getPayment}>
32
+ <LC.Icon type="money" />Payment
33
+ </SC.ToolbarButton>
34
+
35
+ shouldSaveLinesImmediately: ->
36
+ not @invoice.isNew()
37
+
38
+ render: ->
39
+ <LC.ScreenWrapper identifier="invoice" flexVertical>
40
+
41
+ <SC.ScreenControls commands={@state.commands}>
42
+ <@PaymentButton />
43
+ </SC.ScreenControls>
44
+
45
+ <BS.Row>
46
+ <SC.InvoiceFinder ref='finder' editOnly sm=2 xs=3
47
+ model={@invoice} commands={@state.commands}
48
+ syncOptions={@syncOptions} />
49
+
50
+ <SC.SalesOrderFinder autoFocus={false} sm=2 xs=3 editOnly={false}
51
+ onModelSet={@setSalesOrder} associationName='sales_order'
52
+ syncOptions={@syncOptions} parentModel={@invoice} />
53
+
54
+ <SC.CustomerFinder
55
+ selectField sm=3 xs=6 model={@invoice} />
56
+
57
+ <SC.TermsChooser model={@invoice} sm=3 xs=6 />
58
+
59
+ <LC.DisplayValue sm=2 xs=4
60
+ name='state' model={@invoice} />
61
+ </BS.Row>
62
+ <BS.Row>
63
+ <LC.Input name='po_num' model={@invoice} sm=3 xs=6 />
64
+
65
+ <LC.DateTime name='invoice_date' format='ddd, MMM Do YYYY'
66
+ sm=3 model={@invoice} />
67
+
68
+ <SC.PrintFormChooser label="Print Form" sm=3 xs=4 model={@invoice} />
69
+
70
+ <SC.LocationChooser sm=3 xs=4
71
+ label='Src Location' model={@invoice} />
72
+ </BS.Row>
73
+
74
+ <BS.Row>
75
+ <LC.Input sm=12 type='textarea' name="notes" model={@invoice} />
76
+ </BS.Row>
77
+
78
+ <BS.Row>
79
+ <LC.FieldSet sm=12 title="Address" expanded={@invoice.isNew()}>
80
+ <SC.Address lg=6 title="Billing"
81
+ model={@invoice.billing_address} />
82
+ <SC.Address lg=6 title="Shipping"
83
+ model={@invoice.shipping_address} />
84
+ </LC.FieldSet>
85
+ </BS.Row>
86
+
87
+ <SC.SkuLines location={@invoice.location}
88
+ saveImmediately={@shouldSaveLinesImmediately}
89
+ commands={@state.commands} lines={@invoice.lines} />
90
+
91
+ <SC.TotalsLine model={@invoice} />
92
+ </LC.ScreenWrapper>
@@ -0,0 +1,28 @@
1
+ class Skr.Screens.Invoice.Payment extends Lanes.React.Component
2
+
3
+ dataObjects:
4
+ invoice: 'props'
5
+
6
+ componentDidMount: ->
7
+ @invoice.amount_paid = @invoice.open_amount
8
+
9
+ onEnter: -> @props.modal.onButton()
10
+
11
+ render: ->
12
+ <LC.ScreenWrapper identifier="payment">
13
+ <BS.Row>
14
+
15
+ <LC.DisplayValue name='total' getValue={->
16
+ _.sprintf('%0.2f', Number(@total))
17
+ } model={@invoice} align='right' />
18
+
19
+ <LC.DisplayValue name='prev_amount_paid' label='Amount Paid' getValue={->
20
+ _.sprintf('%0.2f', Number(@prev_amount_paid))
21
+ } model={@invoice} align='right' />
22
+
23
+ <LC.Input label='Amount' editOnly autoFocus getValue={->
24
+ _.sprintf('%0.2f', Number(@amount_paid))
25
+ } onEnter={@onEnter} name='amount_paid' align='right' model={@invoice} />
26
+
27
+ </BS.Row>
28
+ </LC.ScreenWrapper>
@@ -0,0 +1,5 @@
1
+ //= require_tree .
2
+
3
+ /*
4
+ Add additional requirement statements for other files that the screen uses
5
+ */
@@ -0,0 +1,31 @@
1
+ class Skr.Screens.Locations extends Skr.Screens.Base
2
+
3
+ syncOptions:
4
+ include: [ 'address' ]
5
+
6
+ dataObjects:
7
+ location: ->
8
+ @loadOrCreateModel({
9
+ syncOptions: @syncOptions, klass: Skr.Models.Location
10
+ prop: 'location', attribute: 'code'
11
+ })
12
+
13
+ getInitialState: ->
14
+ commands: new Skr.Screens.Commands(this, modelName: 'location')
15
+
16
+ render: ->
17
+ <LC.ScreenWrapper identifier="locations">
18
+ <SC.ScreenControls commands={@state.commands} />
19
+ <BS.Row>
20
+ <SC.LocationChooser label='Code' editOnly displayFinder
21
+ commands={@state.commands} model={@location} name="code" />
22
+ <LC.Input sm=6 name='name' model={@location} />
23
+ </BS.Row>
24
+ <BS.Row>
25
+ <LC.ImageSaver label='Logo' sm=3 model={@location} name='logo' />
26
+ </BS.Row>
27
+ <BS.Row>
28
+ <SC.Address lg=6 model={@location.address} />
29
+ </BS.Row>
30
+
31
+ </LC.ScreenWrapper>
@@ -0,0 +1,5 @@
1
+ //= require_tree .
2
+
3
+ /*
4
+ Add additional requirement statements for other files that the screen uses
5
+ */
@@ -0,0 +1,28 @@
1
+ class Skr.Screens.PaymentCategory extends Skr.Screens.Base
2
+
3
+ dataObjects:
4
+ category: ->
5
+ @loadOrCreateModel({
6
+ klass: Skr.Models.PaymentCategory
7
+ prop: 'category', attribute: 'code'
8
+ })
9
+
10
+ getInitialState: ->
11
+ commands: new Skr.Screens.Commands(this, modelName: 'category')
12
+
13
+ render: ->
14
+ <LC.ScreenWrapper identifier="payment-category">
15
+ <SC.ScreenControls commands={@state.commands} />
16
+ <BS.Row>
17
+
18
+ <SC.PaymentCategoryFinder name='code'
19
+ commands={@state.commands} model={@category} />
20
+
21
+ <LC.Input sm=9 name='name' model={@category} />
22
+
23
+ <SC.GlAccountChooser sm=3 label="GL Account"
24
+ name="gl_account" model={@category} />
25
+
26
+ </BS.Row>
27
+
28
+ </LC.ScreenWrapper>
@@ -0,0 +1,5 @@
1
+ //= require_tree .
2
+
3
+ /*
4
+ Add additional requirement statements for other files that the screen uses
5
+ */
@@ -0,0 +1,9 @@
1
+ /*
2
+ You should remove this file if your screen does not use any custom styles
3
+
4
+ Otherwise Lanes will continue to fetch an empty file whenever
5
+ the screen is displayed
6
+ */
7
+ .payment-category {
8
+
9
+ }
@@ -0,0 +1,28 @@
1
+ class Skr.Screens.PaymentTerms extends Skr.Screens.Base
2
+
3
+ dataObjects:
4
+ term: ->
5
+ @loadOrCreateModel({
6
+ klass: Skr.Models.PaymentTerm
7
+ prop: 'term', attribute: 'code'
8
+ })
9
+
10
+ getInitialState: ->
11
+ commands: new Skr.Screens.Commands(this, modelName: 'term')
12
+
13
+ render: ->
14
+ <LC.ScreenWrapper identifier="payment-terms">
15
+ <SC.ScreenControls commands={@state.commands} />
16
+ <BS.Row>
17
+ <SC.TermsChooser useFinder ref='finder' name='code'
18
+ sm=3 autoFocus editOnly model={@term}
19
+ commands={@state.commands} />
20
+
21
+ <LC.Input sm=9 name='description' model={@term} />
22
+ </BS.Row>
23
+ <BS.Row>
24
+ <LC.NumberInput sm=2 name='days' format='##' model={@term} />
25
+ <LC.NumberInput sm=2 name='discount_days' format='##' model={@term} />
26
+ <LC.Input sm=2 name='discount_amount' model={@term} />
27
+ </BS.Row>
28
+ </LC.ScreenWrapper>
@@ -0,0 +1,5 @@
1
+ //= require_tree .
2
+
3
+ /*
4
+ Add additional requirement statements for other files that the screen uses
5
+ */
@@ -0,0 +1,9 @@
1
+ /*
2
+ You should remove this file if your screen does not use any custom styles
3
+
4
+ Otherwise Lanes will continue to fetch an empty file whenever
5
+ the screen is displayed
6
+ */
7
+ .payment-terms {
8
+
9
+ }
@@ -0,0 +1,59 @@
1
+ class Skr.Screens.Payments extends Skr.Screens.Base
2
+
3
+ syncOptions:
4
+ include: [ 'address', 'bank_account', 'category', 'vendor' ]
5
+
6
+ dataObjects:
7
+ payment: ->
8
+ @loadOrCreateModel({
9
+ syncOptions: @syncOptions
10
+ klass: Skr.Models.Payment
11
+ prop: 'payment', attribute: 'visible_id'
12
+ })
13
+
14
+ query: ->
15
+ new Lanes.Models.Query({
16
+ syncOptions: @syncOptions
17
+ src: Skr.Models.Payment, fields: [
18
+ {id:'id', visible: false}
19
+ {id:'visible_id', label: 'Payment ID', fixedWidth: 130 },
20
+ {id:'name', flex: 1}
21
+ {
22
+ id:'amount', fixedWidth: 120, textAlign: 'right',
23
+ format: Lanes.u.format.currency
24
+ }
25
+ ]
26
+ })
27
+
28
+ getInitialState: ->
29
+ commands: new Skr.Screens.Commands(this, modelName: 'payment')
30
+
31
+ render: ->
32
+ <LC.ScreenWrapper identifier="payments">
33
+ <SC.ScreenControls commands={@state.commands} />
34
+ <BS.Row>
35
+ <LC.RecordFinder ref="finder" sm=3 autoFocus
36
+ commands={@state.commands} model={@category}
37
+ label='Payment ID' name='visible_id' model={@payment} query={@query}
38
+ />
39
+ <SC.BankAccountFinder smOffset=1 selectField name='bank_account'
40
+ model={@payment} />
41
+ <SC.PaymentCategoryFinder selectField name='category' labelField='code'
42
+ model={@payment} />
43
+ <LC.DateTime smOffset=1 name='date' format='ddd, MMM Do YYYY'
44
+ sm=3 model={@payment} />
45
+ </BS.Row>
46
+ <BS.Row>
47
+ <SC.VendorFinder sm=2 selectField
48
+ syncOptions={include:['billing_address']} model={@payment} />
49
+ <LC.Input sm=6 name="name" model={@payment} />
50
+ <LC.NumberInput smOffset=1 sm=3 name="amount" align='right' model={@payment} />
51
+ </BS.Row>
52
+ <BS.Row>
53
+ <LC.Input type='textarea' smOffset=2 sm=6 name="address" model={@payment} />
54
+ </BS.Row>
55
+ <BS.Row>
56
+ <LC.Input sm=12 name="notes" model={@payment} />
57
+ </BS.Row>
58
+
59
+ </LC.ScreenWrapper>
@@ -0,0 +1,5 @@
1
+ //= require_tree .
2
+
3
+ /*
4
+ Add additional requirement statements for other files that the screen uses
5
+ */