rails_finance 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (190) hide show
  1. checksums.yaml +7 -0
  2. data/LICENSE +20 -0
  3. data/README.md +20 -0
  4. data/Rakefile +32 -0
  5. data/app/controllers/finance/admin/assessments_controller.rb +55 -0
  6. data/app/controllers/finance/admin/base_controller.rb +4 -0
  7. data/app/controllers/finance/admin/budgets_controller.rb +83 -0
  8. data/app/controllers/finance/admin/expense_members_controller.rb +59 -0
  9. data/app/controllers/finance/admin/expenses_controller.rb +71 -0
  10. data/app/controllers/finance/admin/financial_taxons_controller.rb +67 -0
  11. data/app/controllers/finance/admin/fund_incomes_controller.rb +59 -0
  12. data/app/controllers/finance/admin/funds_controller.rb +58 -0
  13. data/app/controllers/finance/admin/home_controller.rb +8 -0
  14. data/app/controllers/finance/admin/stocks_controller.rb +60 -0
  15. data/app/controllers/finance/me/base_controller.rb +4 -0
  16. data/app/controllers/finance/me/budgets_controller.rb +111 -0
  17. data/app/controllers/finance/me/expense_members_controller.rb +73 -0
  18. data/app/controllers/finance/me/expenses_controller.rb +129 -0
  19. data/app/controllers/finance_controller/me.rb +14 -0
  20. data/app/models/budget/finance/fund_budget.rb +5 -0
  21. data/app/models/budget/finance/stock_budget.rb +5 -0
  22. data/app/models/expense/finance/payable_expense.rb +5 -0
  23. data/app/models/expense/finance/prepay_expense.rb +5 -0
  24. data/app/models/finance/application_record.rb +5 -0
  25. data/app/models/finance/assessment.rb +5 -0
  26. data/app/models/finance/budget.rb +7 -0
  27. data/app/models/finance/expense.rb +7 -0
  28. data/app/models/finance/expense_item.rb +5 -0
  29. data/app/models/finance/expense_member.rb +6 -0
  30. data/app/models/finance/ext/financial.rb +24 -0
  31. data/app/models/finance/ext/member.rb +13 -0
  32. data/app/models/finance/financial_taxon.rb +7 -0
  33. data/app/models/finance/fund.rb +6 -0
  34. data/app/models/finance/fund_income.rb +5 -0
  35. data/app/models/finance/model/assessment.rb +26 -0
  36. data/app/models/finance/model/budget/fund_budget.rb +5 -0
  37. data/app/models/finance/model/budget/stock_budget.rb +10 -0
  38. data/app/models/finance/model/budget.rb +152 -0
  39. data/app/models/finance/model/expense/payable_expense.rb +5 -0
  40. data/app/models/finance/model/expense/prepay_expense.rb +5 -0
  41. data/app/models/finance/model/expense.rb +168 -0
  42. data/app/models/finance/model/expense_item.rb +36 -0
  43. data/app/models/finance/model/expense_member.rb +130 -0
  44. data/app/models/finance/model/financial_taxon.rb +27 -0
  45. data/app/models/finance/model/fund.rb +36 -0
  46. data/app/models/finance/model/fund_income.rb +30 -0
  47. data/app/models/finance/model/stock.rb +33 -0
  48. data/app/models/finance/stock.rb +5 -0
  49. data/app/models/finance.rb +12 -0
  50. data/app/pdfs/borrow_expense_pdf.rb +70 -0
  51. data/app/pdfs/payout_expense_pdf.rb +70 -0
  52. data/app/pdfs/prepay_expense_pdf.rb +70 -0
  53. data/app/records/borrow_expense_record.rb +10 -0
  54. data/app/records/prepay_expense_record.rb +16 -0
  55. data/app/views/admin/_finance_nav.html.erb +14 -0
  56. data/app/views/admin/_nav_expense.html.erb +4 -0
  57. data/app/views/finance/admin/assessments/_edit_form.html.erb +4 -0
  58. data/app/views/finance/admin/assessments/_filter_form.html.erb +9 -0
  59. data/app/views/finance/admin/assessments/_form.html.erb +2 -0
  60. data/app/views/finance/admin/assessments/_index_tbody.html.erb +2 -0
  61. data/app/views/finance/admin/assessments/_index_thead.html.erb +3 -0
  62. data/app/views/finance/admin/assessments/_index_tr.html.erb +19 -0
  63. data/app/views/finance/admin/assessments/_new_form.html.erb +4 -0
  64. data/app/views/finance/admin/assessments/_show_table.html.erb +4 -0
  65. data/app/views/finance/admin/assessments/index.html.erb +5 -0
  66. data/app/views/finance/admin/base/_nav.html.erb +3 -0
  67. data/app/views/finance/admin/budgets/_breadcrumb.html.erb +9 -0
  68. data/app/views/finance/admin/budgets/_edit_form.html.erb +4 -0
  69. data/app/views/finance/admin/budgets/_filter_form.html.erb +10 -0
  70. data/app/views/finance/admin/budgets/_filter_table.html.erb +11 -0
  71. data/app/views/finance/admin/budgets/_form.html.erb +7 -0
  72. data/app/views/finance/admin/budgets/_index_tbody.html.erb +13 -0
  73. data/app/views/finance/admin/budgets/_index_thead.html.erb +6 -0
  74. data/app/views/finance/admin/budgets/_item_form.html.erb +17 -0
  75. data/app/views/finance/admin/budgets/_items.html.erb +16 -0
  76. data/app/views/finance/admin/budgets/_new_form.html.erb +4 -0
  77. data/app/views/finance/admin/budgets/_show/_breadcrumb.html.erb +6 -0
  78. data/app/views/finance/admin/budgets/_show_table.html.erb +62 -0
  79. data/app/views/finance/admin/budgets/index.html.erb +5 -0
  80. data/app/views/finance/admin/budgets/next.turbo_stream.erb +1 -0
  81. data/app/views/finance/admin/budgets/show.htmlx.erb +35 -0
  82. data/app/views/finance/admin/budgets/trigger.js.erb +1 -0
  83. data/app/views/finance/admin/expense_members/_edit_form.html.erb +3 -0
  84. data/app/views/finance/admin/expense_members/_form.html.erb +5 -0
  85. data/app/views/finance/admin/expense_members/_index_tbody.html.erb +53 -0
  86. data/app/views/finance/admin/expense_members/_index_thead.html.erb +12 -0
  87. data/app/views/finance/admin/expense_members/index.html.erb +8 -0
  88. data/app/views/finance/admin/expenses/_breadcrumb.html.erb +9 -0
  89. data/app/views/finance/admin/expenses/_edit_form.html.erb +4 -0
  90. data/app/views/finance/admin/expenses/_filter_form.html.erb +10 -0
  91. data/app/views/finance/admin/expenses/_filter_table.html.erb +11 -0
  92. data/app/views/finance/admin/expenses/_form.html.erb +12 -0
  93. data/app/views/finance/admin/expenses/_index_tbody.html.erb +13 -0
  94. data/app/views/finance/admin/expenses/_index_thead.html.erb +6 -0
  95. data/app/views/finance/admin/expenses/_item_form.html.erb +18 -0
  96. data/app/views/finance/admin/expenses/_items.html.erb +20 -0
  97. data/app/views/finance/admin/expenses/_member_form.html.erb +16 -0
  98. data/app/views/finance/admin/expenses/_new_form.html.erb +4 -0
  99. data/app/views/finance/admin/expenses/index.html.erb +5 -0
  100. data/app/views/finance/admin/expenses/next.turbo_stream.erb +1 -0
  101. data/app/views/finance/admin/expenses/show.html.erb +121 -0
  102. data/app/views/finance/admin/expenses/trigger.turbo_stream.erb +1 -0
  103. data/app/views/finance/admin/financial_taxons/_edit_form.html.erb +4 -0
  104. data/app/views/finance/admin/financial_taxons/_filter_form.html.erb +10 -0
  105. data/app/views/finance/admin/financial_taxons/_form.html.erb +5 -0
  106. data/app/views/finance/admin/financial_taxons/_index_tbody.html.erb +36 -0
  107. data/app/views/finance/admin/financial_taxons/_index_thead.html.erb +5 -0
  108. data/app/views/finance/admin/financial_taxons/_index_tr.html.erb +13 -0
  109. data/app/views/finance/admin/financial_taxons/_new_form.html.erb +4 -0
  110. data/app/views/finance/admin/financial_taxons/index.html.erb +6 -0
  111. data/app/views/finance/admin/fund_incomes/_breadcrumb.html.erb +7 -0
  112. data/app/views/finance/admin/fund_incomes/_edit_form.html.erb +4 -0
  113. data/app/views/finance/admin/fund_incomes/_filter_form.html.erb +9 -0
  114. data/app/views/finance/admin/fund_incomes/_form.html.erb +4 -0
  115. data/app/views/finance/admin/fund_incomes/_index_tbody.html.erb +5 -0
  116. data/app/views/finance/admin/fund_incomes/_index_thead.html.erb +4 -0
  117. data/app/views/finance/admin/fund_incomes/_new_form.html.erb +4 -0
  118. data/app/views/finance/admin/fund_incomes/_show_table.html.erb +12 -0
  119. data/app/views/finance/admin/fund_incomes/index.html.erb +5 -0
  120. data/app/views/finance/admin/funds/_edit_form.html.erb +3 -0
  121. data/app/views/finance/admin/funds/_filter_form.html.erb +9 -0
  122. data/app/views/finance/admin/funds/_form.html.erb +5 -0
  123. data/app/views/finance/admin/funds/_index_tbody.html.erb +14 -0
  124. data/app/views/finance/admin/funds/_index_thead.html.erb +8 -0
  125. data/app/views/finance/admin/funds/_new_form.html.erb +3 -0
  126. data/app/views/finance/admin/funds/_show_table.html.erb +16 -0
  127. data/app/views/finance/admin/funds/index.html.erb +5 -0
  128. data/app/views/finance/admin/home/index.html.erb +6 -0
  129. data/app/views/finance/admin/stocks/_breadcrumb.html.erb +7 -0
  130. data/app/views/finance/admin/stocks/_edit_form.html.erb +4 -0
  131. data/app/views/finance/admin/stocks/_filter_form.html.erb +9 -0
  132. data/app/views/finance/admin/stocks/_form.html.erb +4 -0
  133. data/app/views/finance/admin/stocks/_index_tbody.html.erb +6 -0
  134. data/app/views/finance/admin/stocks/_index_thead.html.erb +7 -0
  135. data/app/views/finance/admin/stocks/_new_form.html.erb +4 -0
  136. data/app/views/finance/admin/stocks/_show_table.html.erb +16 -0
  137. data/app/views/finance/admin/stocks/index.html.erb +5 -0
  138. data/app/views/finance/me/budgets/_breadcrumb.html.erb +6 -0
  139. data/app/views/finance/me/budgets/_filter_form.html.erb +8 -0
  140. data/app/views/finance/me/budgets/_filter_table.html.erb +11 -0
  141. data/app/views/finance/me/budgets/_index_tbody.html.erb +23 -0
  142. data/app/views/finance/me/budgets/_index_thead.html.erb +4 -0
  143. data/app/views/finance/me/budgets/_items.html.erb +22 -0
  144. data/app/views/finance/me/budgets/_show/_breadcrumb.html.erb +6 -0
  145. data/app/views/finance/me/budgets/admin.html.erb +5 -0
  146. data/app/views/finance/me/budgets/financial_taxons.js.erb +7 -0
  147. data/app/views/finance/me/budgets/index.html.erb +5 -0
  148. data/app/views/finance/me/budgets/index.js +45 -0
  149. data/app/views/finance/me/budgets/submit.turbo_stream.erb +1 -0
  150. data/app/views/finance/me/budgets/transfer.turbo_stream.erb +1 -0
  151. data/app/views/finance/me/expense_members/_breadcrumb.html.erb +6 -0
  152. data/app/views/finance/me/expense_members/_button.html.erb +0 -0
  153. data/app/views/finance/me/expense_members/_filter_form.html.erb +10 -0
  154. data/app/views/finance/me/expense_members/_form.html.erb +9 -0
  155. data/app/views/finance/me/expense_members/_index_tbody.html.erb +8 -0
  156. data/app/views/finance/me/expense_members/_index_thead.html.erb +7 -0
  157. data/app/views/finance/me/expense_members/_show_items.html.erb +1 -0
  158. data/app/views/finance/me/expense_members/admin.html.erb +3 -0
  159. data/app/views/finance/me/expense_members/index.html.erb +6 -0
  160. data/app/views/finance/me/expense_members/items.js.erb +1 -0
  161. data/app/views/finance/me/expense_members/show.html.erb +62 -0
  162. data/app/views/finance/me/expenses/_breadcrumb.html.erb +7 -0
  163. data/app/views/finance/me/expenses/_edit_form.html.erb +3 -0
  164. data/app/views/finance/me/expenses/_filter_form.html.erb +8 -0
  165. data/app/views/finance/me/expenses/_filter_table.html.erb +11 -0
  166. data/app/views/finance/me/expenses/_index_tbody.html.erb +16 -0
  167. data/app/views/finance/me/expenses/_index_thead.html.erb +6 -0
  168. data/app/views/finance/me/expenses/_index_tr.html.erb +14 -0
  169. data/app/views/finance/me/expenses/_new_form.html.erb +4 -0
  170. data/app/views/finance/me/expenses/_show/_breadcrumb.html.erb +6 -0
  171. data/app/views/finance/me/expenses/_show_table.html.erb +124 -0
  172. data/app/views/finance/me/expenses/admin.html.erb +5 -0
  173. data/app/views/finance/me/expenses/confirm.html.erb +27 -0
  174. data/app/views/finance/me/expenses/financial_taxons.js.erb +44 -0
  175. data/app/views/finance/me/expenses/index.html.erb +5 -0
  176. data/app/views/finance/me/expenses/index.js +42 -0
  177. data/app/views/finance/me/expenses/show.html.erb +3 -0
  178. data/app/views/me/_finance_nav.html.erb +11 -0
  179. data/config/locales/en.attributes.yml +6 -0
  180. data/config/locales/en.controller.yml +21 -0
  181. data/config/locales/en.enum.yml +18 -0
  182. data/config/locales/zh.attributes.yml +65 -0
  183. data/config/locales/zh.controller.yml +57 -0
  184. data/config/locales/zh.enum.yml +38 -0
  185. data/config/routes.rb +63 -0
  186. data/lib/rails_finance/config.rb +11 -0
  187. data/lib/rails_finance/engine.rb +26 -0
  188. data/lib/rails_finance/version.rb +3 -0
  189. data/lib/rails_finance.rb +2 -0
  190. metadata +259 -0
@@ -0,0 +1,36 @@
1
+ module Finance
2
+ module Model::ExpenseItem
3
+ extend ActiveSupport::Concern
4
+
5
+ included do
6
+ attribute :budget_amount, :decimal
7
+ attribute :amount, :decimal
8
+ attribute :note, :string
9
+ attribute :state, :string
10
+ attribute :quantity, :integer, default: 1
11
+ attribute :price, :decimal
12
+
13
+ belongs_to :expense, optional: true
14
+ belongs_to :budget, optional: true
15
+ belongs_to :financial_taxon, optional: true
16
+
17
+ before_save :ensure_amount, if: -> { budget_amount_changed? }
18
+ after_save :sync_budget_amount, if: -> { saved_change_to_budget_amount? }
19
+ after_update_commit :sync_member_amount, if: -> { saved_change_to_amount? }
20
+ end
21
+
22
+ def sync_budget_amount
23
+ budget.amount = budget.expense_items.sum(&:budget_amount)
24
+ budget.save
25
+ end
26
+
27
+ def ensure_amount
28
+ self.amount = budget_amount if budget
29
+ end
30
+
31
+ def sync_member_amount
32
+ self.expense.update(amount: self.expense.expense_items.sum(:amount)) if expense
33
+ end
34
+
35
+ end
36
+ end
@@ -0,0 +1,130 @@
1
+ module Finance
2
+ module Model::ExpenseMember
3
+ extend ActiveSupport::Concern
4
+
5
+ included do
6
+ attribute :amount, :decimal
7
+ attribute :advance, :decimal
8
+ attribute :state, :string
9
+ attribute :note, :string
10
+
11
+ belongs_to :member, class_name: 'Org::Member'
12
+
13
+ belongs_to :expense
14
+ belongs_to :payment_method, optional: true
15
+
16
+ has_many :expense_items, ->(o){ where(member_id: o.member_id) }, foreign_key: :expense_id, primary_key: :expense_id
17
+
18
+ validates :member_id, uniqueness: { scope: [:expense_id] }
19
+
20
+ enum state: {
21
+ pending_borrow: 'pending_borrow',
22
+ advance_pay: 'advance_pay',
23
+ advance_paid: 'advance_paid',
24
+ pending_reimburse: 'pending_reimburse',
25
+ to_pay: 'to_pay',
26
+ paid: 'paid'
27
+ }, _default: 'pending_borrow'
28
+
29
+ acts_as_notify(
30
+ :default,
31
+ only: [:amount, :advance],
32
+ methods: [:expense_subject, :state_i18n]
33
+ )
34
+ acts_as_notify(
35
+ :request,
36
+ only: [:amount, :advance],
37
+ methods: [:member_name, :expense_subject]
38
+ )
39
+
40
+ delegate :subject, to: :expense, prefix: true
41
+ delegate :name, to: :member, prefix: true
42
+ end
43
+
44
+ def approve_config
45
+ {
46
+ pending_borrow: advance_verifier,
47
+ advance_pay: member.cashier,
48
+ advance_paid: member,
49
+ pending_reimburse: verifier,
50
+ to_pay: member.cashier,
51
+ paid: member
52
+ }
53
+ end
54
+
55
+ def next_operator
56
+ approve_config[next_state(:state)]
57
+ end
58
+
59
+ def advance_verifier
60
+ if self.advance <= 5000
61
+ member.office.leader
62
+ elsif self.advance > 5000
63
+ Member.find_by(email: SETTING['cfo_email'])
64
+ end
65
+ end
66
+
67
+ def verifier
68
+ if self.amount <= 5000
69
+ member.office.leader
70
+ elsif self.amount > 5000
71
+ Member.find_by(email: SETTING['cfo_email'])
72
+ end
73
+ end
74
+
75
+ def can_operate?(member)
76
+ return true if member.admin?
77
+ self.next_operator == current_member && !['paid'].include?(self.state)
78
+ end
79
+
80
+ def amount_cn
81
+ NumHelper.to_rmb amount.to_f
82
+ end
83
+
84
+ def advance_cn
85
+ NumHelper.to_rmb advance.to_f
86
+ end
87
+
88
+ def payout_amount
89
+ self.amount.to_d - self.advance.to_d
90
+ end
91
+
92
+ def do_trigger(params = {})
93
+ self.trigger_to(state: params[:state])
94
+
95
+ # case state_was
96
+ # when 'pending_borrow'
97
+ # self.to_advance_payout
98
+ # when 'pending_reimburse'
99
+ # self.to_payout
100
+ # end
101
+
102
+ self.class.transaction do
103
+ self.save!
104
+ if next_operator
105
+ to_notification(
106
+ member: next_operator,
107
+ link: url_helpers.finance_expense_url(self.expense_id),
108
+ code: :request,
109
+ verbose: true
110
+ )
111
+ end
112
+ end
113
+ end
114
+
115
+ def details
116
+ text = ''
117
+ items = expense_items.limit(4).map do |item|
118
+ "#{item.financial_taxon&.name} #{item.note} #{item.amount}"
119
+ end.join("\n")
120
+
121
+ if expense.note.present?
122
+ text << expense.note
123
+ else
124
+ text << '详情请查看附件'
125
+ end
126
+ text
127
+ end
128
+
129
+ end
130
+ end
@@ -0,0 +1,27 @@
1
+ module Finance
2
+ module Model::FinancialTaxon
3
+ extend ActiveSupport::Concern
4
+
5
+ included do
6
+ attribute :name, :string
7
+ attribute :position, :integer
8
+ attribute :take_stock, :boolean, default: false, comment: '是否有库存'
9
+ attribute :individual, :boolean, default: false, comment: '是否可盘点'
10
+
11
+ belongs_to :organ, class_name: 'Org::Organ', optional: true
12
+
13
+ has_many :expense_items, dependent: :nullify
14
+
15
+ before_save :sync_verifier, if: -> { parent_id_changed? && parent }
16
+
17
+ acts_as_list
18
+ end
19
+
20
+ private
21
+ def sync_verifier
22
+ self.individual ||= self.parent.individual
23
+ self.take_stock ||= self.parent.take_stock
24
+ end
25
+
26
+ end
27
+ end
@@ -0,0 +1,36 @@
1
+ module Finance
2
+ module Model::Fund
3
+ extend ActiveSupport::Concern
4
+
5
+ included do
6
+ attribute :name, :string
7
+ attribute :amount, :decimal, default: 0
8
+ attribute :budget_amount, :decimal, default: 0
9
+ attribute :budget_detail, :json, default: {}
10
+ attribute :expense_amount, :decimal, default: 0
11
+ attribute :expense_detail, :json, default: {}
12
+ attribute :note, :string
13
+
14
+ belongs_to :organ, class_name: 'Org::Organ'
15
+
16
+ has_many :fund_incomes, dependent: :destroy
17
+ has_many :budgets, dependent: :destroy
18
+ has_many :expenses, dependent: :destroy
19
+
20
+ has_one_attached :proof
21
+ end
22
+
23
+ def sum_budget_amount(financial_type)
24
+ self.budget_detail.merge! financial_type => fund_budgets.where(financial_type: financial_type).sum(:amount)
25
+ end
26
+
27
+ def sum_income_amount
28
+ self.amount = fund_incomes.sum(:amount)
29
+ end
30
+
31
+ def sum_expense_amount(financial_type)
32
+ self.expense_detail.merge! financial_type => fund_expenses.where(financial_type: financial_type).sum(:amount)
33
+ end
34
+
35
+ end
36
+ end
@@ -0,0 +1,30 @@
1
+ module Finance
2
+ module Model::FundIncome
3
+ extend ActiveSupport::Concern
4
+
5
+ included do
6
+ attribute :amount, :decimal
7
+ attribute :visible, :boolean, default: false
8
+ attribute :note, :string
9
+
10
+ enum state: {
11
+ init: 'init',
12
+ done: 'done'
13
+ }, _default: 'init'
14
+
15
+ belongs_to :fund
16
+ belongs_to :user, optional: true
17
+ belongs_to :financial, polymorphic: true, optional: true
18
+
19
+ has_one_attached :proof
20
+
21
+ after_save :sum_fund_amount, if: -> { saved_change_to_amount? }
22
+ end
23
+
24
+ def sum_fund_amount
25
+ fund.sum_income_amount
26
+ fund.save
27
+ end
28
+
29
+ end
30
+ end
@@ -0,0 +1,33 @@
1
+ module Finance
2
+
3
+ # 股权
4
+ module Model::Stock
5
+ extend ActiveSupport::Concern
6
+
7
+ included do
8
+ attribute :ratio, :decimal, precision: 4, scale: 2
9
+ attribute :assess_amount, :decimal
10
+ attribute :amount, :integer, default: 0, comment: '发行量'
11
+ attribute :expense_amount, :integer, default: 0
12
+ attribute :expense_detail, :json, default: {}
13
+ attribute :note, :string
14
+
15
+ belongs_to :member, class_name: 'Org::Member' # 托管股东
16
+ belongs_to :organ, class_name: 'Org::Organ'
17
+
18
+ belongs_to :assessment
19
+
20
+ before_validation :compute_assess_amount, if: -> { ratio_changed? }
21
+ before_validation :sync_organ, if: -> { assessment_id_changed? }
22
+ end
23
+
24
+ def compute_assess_amount
25
+ self.assess_amount = assessment.amount * ratio
26
+ end
27
+
28
+ def sync_organ
29
+ self.organ = assessment.organ
30
+ end
31
+
32
+ end
33
+ end
@@ -0,0 +1,5 @@
1
+ module Finance
2
+ class Stock < ApplicationRecord
3
+ include Model::Stock
4
+ end
5
+ end
@@ -0,0 +1,12 @@
1
+ module Finance
2
+
3
+ def self.use_relative_model_naming?
4
+ true
5
+ end
6
+
7
+ def self.table_name_prefix
8
+ 'finance_'
9
+ end
10
+
11
+ end
12
+
@@ -0,0 +1,70 @@
1
+ require 'prawn'
2
+ class BorrowExpensePdf
3
+ include Prawn::View
4
+ include PdfTextHelper
5
+ include PdfTableHelper
6
+
7
+ attr_reader :document, :expense_member
8
+
9
+ def initialize(expense_member_id = nil)
10
+ @document = RailsDataPdf.new
11
+ @expense_member = ExpenseMember.find expense_member_id
12
+ write_content
13
+ end
14
+
15
+ def render
16
+ @document.render
17
+ end
18
+
19
+ def write_content
20
+ stroke do
21
+ dash [8, 4]
22
+ horizontal_line -36, (margin_box.width + 36), at: (160.mm - 36)
23
+ horizontal_line -36, (margin_box.width + 36), at: (99.mm - 36)
24
+ end
25
+ write_header
26
+ write_table_header
27
+ write_content_table
28
+ write_table_footer
29
+ end
30
+
31
+ def write_header
32
+ undash
33
+ text "<u>借 支 单</u>", header_style.merge(inline_format: true)
34
+ move_down 10
35
+ end
36
+
37
+ def write_table_header
38
+ grid_table(
39
+ [
40
+ ["单位:#{expense_member.member.office.company_name}", { rowspan: 2, content: expense_member.created_at.to_date.strftime('%Y 年 %m 月 %d 日') }],
41
+ ["部门:#{expense_member.member.department.full_name}"]
42
+ ]
43
+ )
44
+ move_down 10
45
+ end
46
+
47
+ def write_content_table
48
+ content_table(
49
+ [
50
+ ['摘要', { colspan: 3, content: expense_member.expense.subject }],
51
+ ['费用说明', { colspan: 3, content: expense_member.details }],
52
+ [ { content: '金额' }, { content: "¥#{expense_member.advance}" }, { colspan: 2, content: expense_member.advance_cn } ],
53
+ [ { content: '领款人签章' }, { colspan: 3, content:'' } ]
54
+ ]
55
+ ) do
56
+ row(0).style PdfTableHelper::NORMAL_TD
57
+ row(1).style PdfTableHelper::NORMAL_TD.merge height: 90
58
+ row(2..-1).style PdfTableHelper::NORMAL_TD
59
+ end
60
+ end
61
+
62
+ def write_table_footer
63
+ footer_table(
64
+ [
65
+ ['审批人', '审核', '出纳', "借支人: #{expense_member.member.name}"]
66
+ ]
67
+ )
68
+ end
69
+
70
+ end
@@ -0,0 +1,70 @@
1
+ require 'prawn'
2
+ class PayoutExpensePdf
3
+ include Prawn::View
4
+ include PdfTextHelper
5
+ include PdfTableHelper
6
+
7
+ attr_reader :document, :expense
8
+
9
+ def initialize(expense_id)
10
+ @document = RailsDataPdf.new
11
+ @expense = Expense.find(expense_id)
12
+ write_content
13
+ end
14
+
15
+ def render
16
+ @document.render
17
+ end
18
+
19
+ def write_content
20
+ stroke do
21
+ dash [8, 4]
22
+ horizontal_line -36, (margin_box.width + 36), at: (160.mm - 36)
23
+ horizontal_line -36, (margin_box.width + 36), at: (99.mm - 36)
24
+ end
25
+ write_header
26
+ write_table_header
27
+ write_content_table
28
+ write_table_footer
29
+ end
30
+
31
+ def write_header
32
+ undash
33
+ text "<u>付 款 申 请 单</u>", header_style.merge(inline_format: true)
34
+ move_down 10
35
+ end
36
+
37
+ def write_table_header
38
+ grid_table(
39
+ [
40
+ ["单位:#{expense.creator.office.company_name}", { rowspan: 2, content: expense.created_at.to_date.strftime('%Y 年 %m 月 %d 日') }],
41
+ ["部门:#{expense.creator.department.full_name}"]
42
+ ]
43
+ )
44
+ move_down 10
45
+ end
46
+
47
+ def write_content_table
48
+ content_table(
49
+ [
50
+ ['摘要', { colspan: 3, content: expense.subject }],
51
+ ['费用说明', { colspan: 3, content: expense.note }],
52
+ [ { content: '金额' }, { content: "¥#{expense.amount}" }, { colspan: 2, content: expense.amount_cn } ],
53
+ [ { content: '附单据张数', colspan: 2 }, { colspan: 2, content: expense.invoices_count.to_s } ]
54
+ ]
55
+ ) do
56
+ row(0).style PdfTableHelper::NORMAL_TD
57
+ row(1).style PdfTableHelper::NORMAL_TD.merge height: 90
58
+ row(2..-1).style PdfTableHelper::NORMAL_TD
59
+ end
60
+ end
61
+
62
+ def write_table_footer
63
+ footer_table(
64
+ [
65
+ ['审批人', '审核', '出纳', "申请人: #{expense.creator.name}"]
66
+ ]
67
+ )
68
+ end
69
+
70
+ end