@things-factory/accounting 8.0.0-beta.9 → 8.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (196) hide show
  1. package/client/activities/activity-book-edit.ts +88 -0
  2. package/client/activities/activity-book-view.ts +88 -0
  3. package/client/activities/activity-expense-edit.ts +88 -0
  4. package/client/activities/activity-expense-view.ts +88 -0
  5. package/client/bootstrap.ts +10 -0
  6. package/client/components/accounting-category-selector.ts +136 -0
  7. package/client/components/accounting-category-view.ts +75 -0
  8. package/client/grist-editors/grist-editor-accounting-category-object.ts +83 -0
  9. package/client/grist-editors/grist-renderer-accounting-category-object.ts +13 -0
  10. package/client/index.ts +0 -0
  11. package/client/pages/account/account-importer.ts +97 -0
  12. package/client/pages/account/account-list-page.ts +364 -0
  13. package/client/pages/accounting-category/accounting-category-importer.ts +97 -0
  14. package/client/pages/accounting-category/accounting-category-list-page.ts +368 -0
  15. package/client/pages/accounting-category/accounting-category-tree-page.ts +338 -0
  16. package/client/pages/accounting-document/accounting-document-importer.ts +90 -0
  17. package/client/pages/accounting-document/accounting-document-list-page.ts +398 -0
  18. package/client/pages/financial-statement/financial-statement-importer.ts +97 -0
  19. package/client/pages/financial-statement/financial-statement-list-page.ts +338 -0
  20. package/client/pages/fiscal-month/fiscal-month-importer.ts +90 -0
  21. package/client/pages/fiscal-month/fiscal-month-list-page.ts +398 -0
  22. package/client/pages/fiscal-quarter/fiscal-quarter-importer.ts +90 -0
  23. package/client/pages/fiscal-quarter/fiscal-quarter-list-page.ts +398 -0
  24. package/client/pages/fiscal-year/fiscal-year-importer.ts +90 -0
  25. package/client/pages/fiscal-year/fiscal-year-list-page.ts +398 -0
  26. package/client/pages/income-statement/income-statement-importer.ts +97 -0
  27. package/client/pages/income-statement/income-statement-list-page.ts +338 -0
  28. package/client/pages/payment/payment-importer.ts +90 -0
  29. package/client/pages/payment/payment-list-page.ts +398 -0
  30. package/client/pages/transaction/transaction-importer.ts +97 -0
  31. package/client/pages/transaction/transaction-list-page.ts +338 -0
  32. package/client/route.ts +35 -0
  33. package/client/tsconfig.json +13 -0
  34. package/client/types/accounting-category.ts +23 -0
  35. package/client/types/index.ts +1 -0
  36. package/dist-client/pages/accounting-category/accounting-category-tree-page.js +1 -1
  37. package/dist-client/pages/accounting-category/accounting-category-tree-page.js.map +1 -1
  38. package/dist-client/tsconfig.tsbuildinfo +1 -1
  39. package/dist-server/service/index.d.ts +2 -3
  40. package/dist-server/service/index.js +0 -5
  41. package/dist-server/service/index.js.map +1 -1
  42. package/dist-server/service/payment/index.d.ts +2 -1
  43. package/dist-server/service/payment/payment-history.d.ts +1 -8
  44. package/dist-server/service/payment/payment-history.js +10 -41
  45. package/dist-server/service/payment/payment-history.js.map +1 -1
  46. package/dist-server/service/payment/payment-type.d.ts +1 -7
  47. package/dist-server/service/payment/payment-type.js +0 -24
  48. package/dist-server/service/payment/payment-type.js.map +1 -1
  49. package/dist-server/service/payment/payment.d.ts +0 -12
  50. package/dist-server/service/payment/payment.js +1 -36
  51. package/dist-server/service/payment/payment.js.map +1 -1
  52. package/dist-server/tsconfig.tsbuildinfo +1 -1
  53. package/package.json +7 -7
  54. package/server/activities/activity-book.ts +172 -0
  55. package/server/activities/activity-expense.ts +149 -0
  56. package/server/activities/index.ts +18 -0
  57. package/server/controllers/index.ts +1 -0
  58. package/server/controllers/summary-statements.ts +166 -0
  59. package/server/index.ts +6 -0
  60. package/server/middlewares/index.ts +3 -0
  61. package/server/migrations/1725200507196-seed-fiscal-entities.ts +106 -0
  62. package/server/migrations/1725201467183-seed-accounts.ts +339 -0
  63. package/server/migrations/index.ts +9 -0
  64. package/server/routes.ts +26 -0
  65. package/server/service/account/account-history.ts +117 -0
  66. package/server/service/account/account-mutation.ts +140 -0
  67. package/server/service/account/account-query.ts +51 -0
  68. package/server/service/account/account-type.ts +44 -0
  69. package/server/service/account/account.ts +97 -0
  70. package/server/service/account/event-subscriber.ts +17 -0
  71. package/server/service/account/index.ts +9 -0
  72. package/server/service/accounting-category/accounting-category-history.ts +129 -0
  73. package/server/service/accounting-category/accounting-category-mutation.ts +148 -0
  74. package/server/service/accounting-category/accounting-category-query.ts +74 -0
  75. package/server/service/accounting-category/accounting-category-type.ts +48 -0
  76. package/server/service/accounting-category/accounting-category.ts +100 -0
  77. package/server/service/accounting-category/event-subscriber.ts +20 -0
  78. package/server/service/accounting-category/index.ts +9 -0
  79. package/server/service/accounting-document/accounting-document-history.ts +123 -0
  80. package/server/service/accounting-document/accounting-document-mutation.ts +137 -0
  81. package/server/service/accounting-document/accounting-document-query.ts +48 -0
  82. package/server/service/accounting-document/accounting-document-type.ts +52 -0
  83. package/server/service/accounting-document/accounting-document.ts +93 -0
  84. package/server/service/accounting-document/event-subscriber.ts +17 -0
  85. package/server/service/accounting-document/index.ts +9 -0
  86. package/server/service/common-type.ts +12 -0
  87. package/server/service/financial-statement/event-subscriber.ts +17 -0
  88. package/server/service/financial-statement/financial-statement-history.ts +129 -0
  89. package/server/service/financial-statement/financial-statement-line-item.ts +82 -0
  90. package/server/service/financial-statement/financial-statement-mutation.ts +148 -0
  91. package/server/service/financial-statement/financial-statement-query.ts +53 -0
  92. package/server/service/financial-statement/financial-statement-type.ts +51 -0
  93. package/server/service/financial-statement/financial-statement.ts +116 -0
  94. package/server/service/financial-statement/index.ts +10 -0
  95. package/server/service/fiscal-month/fiscal-month-mutation.ts +145 -0
  96. package/server/service/fiscal-month/fiscal-month-query.ts +58 -0
  97. package/server/service/fiscal-month/fiscal-month-type.ts +66 -0
  98. package/server/service/fiscal-month/fiscal-month.ts +84 -0
  99. package/server/service/fiscal-month/index.ts +7 -0
  100. package/server/service/fiscal-quarter/fiscal-quarter-mutation.ts +148 -0
  101. package/server/service/fiscal-quarter/fiscal-quarter-query.ts +60 -0
  102. package/server/service/fiscal-quarter/fiscal-quarter-type.ts +60 -0
  103. package/server/service/fiscal-quarter/fiscal-quarter.ts +80 -0
  104. package/server/service/fiscal-quarter/index.ts +7 -0
  105. package/server/service/fiscal-year/fiscal-year-mutation.ts +145 -0
  106. package/server/service/fiscal-year/fiscal-year-query.ts +53 -0
  107. package/server/service/fiscal-year/fiscal-year-type.ts +54 -0
  108. package/server/service/fiscal-year/fiscal-year.ts +76 -0
  109. package/server/service/fiscal-year/index.ts +7 -0
  110. package/server/service/income-statement/event-subscriber.ts +17 -0
  111. package/server/service/income-statement/income-statement-history.ts +133 -0
  112. package/server/service/income-statement/income-statement-line-item.ts +84 -0
  113. package/server/service/income-statement/income-statement-mutation.ts +147 -0
  114. package/server/service/income-statement/income-statement-query.ts +50 -0
  115. package/server/service/income-statement/income-statement-type.ts +51 -0
  116. package/server/service/income-statement/income-statement.ts +120 -0
  117. package/server/service/income-statement/index.ts +10 -0
  118. package/server/service/index.ts +108 -0
  119. package/server/service/payment/event-subscriber.ts +17 -0
  120. package/server/service/payment/index.ts +9 -0
  121. package/server/service/payment/payment-history.ts +132 -0
  122. package/server/service/payment/payment-mutation.ts +139 -0
  123. package/server/service/payment/payment-query.ts +50 -0
  124. package/server/service/payment/payment-type.ts +64 -0
  125. package/server/service/payment/payment.ts +123 -0
  126. package/server/service/transaction/event-subscriber.ts +17 -0
  127. package/server/service/transaction/index.ts +9 -0
  128. package/server/service/transaction/transaction-history.ts +161 -0
  129. package/server/service/transaction/transaction-mutation.ts +146 -0
  130. package/server/service/transaction/transaction-query.ts +50 -0
  131. package/server/service/transaction/transaction-type.ts +48 -0
  132. package/server/service/transaction/transaction.ts +230 -0
  133. package/server/tsconfig.json +10 -0
  134. package/dist-client/pages/bank/bank-importer.d.ts +0 -23
  135. package/dist-client/pages/bank/bank-importer.js +0 -93
  136. package/dist-client/pages/bank/bank-importer.js.map +0 -1
  137. package/dist-client/pages/bank/bank-list-page.d.ts +0 -66
  138. package/dist-client/pages/bank/bank-list-page.js +0 -370
  139. package/dist-client/pages/bank/bank-list-page.js.map +0 -1
  140. package/dist-client/pages/bank-account/bank-account-importer.d.ts +0 -23
  141. package/dist-client/pages/bank-account/bank-account-importer.js +0 -93
  142. package/dist-client/pages/bank-account/bank-account-importer.js.map +0 -1
  143. package/dist-client/pages/bank-account/bank-account-list-page.d.ts +0 -66
  144. package/dist-client/pages/bank-account/bank-account-list-page.js +0 -370
  145. package/dist-client/pages/bank-account/bank-account-list-page.js.map +0 -1
  146. package/dist-client/pages/financial-institution/financial-institution-importer.d.ts +0 -23
  147. package/dist-client/pages/financial-institution/financial-institution-importer.js +0 -93
  148. package/dist-client/pages/financial-institution/financial-institution-importer.js.map +0 -1
  149. package/dist-client/pages/financial-institution/financial-institution-list-page.d.ts +0 -66
  150. package/dist-client/pages/financial-institution/financial-institution-list-page.js +0 -370
  151. package/dist-client/pages/financial-institution/financial-institution-list-page.js.map +0 -1
  152. package/dist-server/migrations/1725201567284-seed-country-codes.d.ts +0 -5
  153. package/dist-server/migrations/1725201567284-seed-country-codes.js +0 -248
  154. package/dist-server/migrations/1725201567284-seed-country-codes.js.map +0 -1
  155. package/dist-server/migrations/1725201667385-seed-financial-institutions.d.ts +0 -5
  156. package/dist-server/migrations/1725201667385-seed-financial-institutions.js +0 -348
  157. package/dist-server/migrations/1725201667385-seed-financial-institutions.js.map +0 -1
  158. package/dist-server/service/bank-account/bank-account-history.d.ts +0 -34
  159. package/dist-server/service/bank-account/bank-account-history.js +0 -172
  160. package/dist-server/service/bank-account/bank-account-history.js.map +0 -1
  161. package/dist-server/service/bank-account/bank-account-mutation.d.ts +0 -10
  162. package/dist-server/service/bank-account/bank-account-mutation.js +0 -128
  163. package/dist-server/service/bank-account/bank-account-mutation.js.map +0 -1
  164. package/dist-server/service/bank-account/bank-account-query.d.ts +0 -11
  165. package/dist-server/service/bank-account/bank-account-query.js +0 -79
  166. package/dist-server/service/bank-account/bank-account-query.js.map +0 -1
  167. package/dist-server/service/bank-account/bank-account-type.d.ts +0 -39
  168. package/dist-server/service/bank-account/bank-account-type.js +0 -153
  169. package/dist-server/service/bank-account/bank-account-type.js.map +0 -1
  170. package/dist-server/service/bank-account/bank-account.d.ts +0 -38
  171. package/dist-server/service/bank-account/bank-account.js +0 -164
  172. package/dist-server/service/bank-account/bank-account.js.map +0 -1
  173. package/dist-server/service/bank-account/event-subscriber.d.ts +0 -7
  174. package/dist-server/service/bank-account/event-subscriber.js +0 -21
  175. package/dist-server/service/bank-account/event-subscriber.js.map +0 -1
  176. package/dist-server/service/bank-account/index.d.ts +0 -7
  177. package/dist-server/service/bank-account/index.js +0 -12
  178. package/dist-server/service/bank-account/index.js.map +0 -1
  179. package/dist-server/service/financial-institution/financial-institution-mutation.d.ts +0 -10
  180. package/dist-server/service/financial-institution/financial-institution-mutation.js +0 -169
  181. package/dist-server/service/financial-institution/financial-institution-mutation.js.map +0 -1
  182. package/dist-server/service/financial-institution/financial-institution-query.d.ts +0 -12
  183. package/dist-server/service/financial-institution/financial-institution-query.js +0 -97
  184. package/dist-server/service/financial-institution/financial-institution-query.js.map +0 -1
  185. package/dist-server/service/financial-institution/financial-institution-type.d.ts +0 -32
  186. package/dist-server/service/financial-institution/financial-institution-type.js +0 -126
  187. package/dist-server/service/financial-institution/financial-institution-type.js.map +0 -1
  188. package/dist-server/service/financial-institution/financial-institution.d.ts +0 -34
  189. package/dist-server/service/financial-institution/financial-institution.js +0 -137
  190. package/dist-server/service/financial-institution/financial-institution.js.map +0 -1
  191. package/dist-server/service/financial-institution/index.d.ts +0 -6
  192. package/dist-server/service/financial-institution/index.js +0 -10
  193. package/dist-server/service/financial-institution/index.js.map +0 -1
  194. package/helps/accounting/bank-account.md +0 -160
  195. package/helps/accounting/bank.md +0 -160
  196. package/helps/accounting/financial-institution.md +0 -160
@@ -0,0 +1,368 @@
1
+ import '@operato/data-grist'
2
+
3
+ import { CommonButtonStyles, CommonGristStyles, ScrollbarStyles } from '@operato/styles'
4
+ import { PageView, store } from '@operato/shell'
5
+ import { css, html } from 'lit'
6
+ import { customElement, property, query } from 'lit/decorators.js'
7
+ import { ScopedElementsMixin } from '@open-wc/scoped-elements'
8
+ import { ColumnConfig, DataGrist, FetchOption, SortersControl } from '@operato/data-grist'
9
+ import { client } from '@operato/graphql'
10
+ import { i18next, localize } from '@operato/i18n'
11
+ import { notify, openPopup } from '@operato/layout'
12
+ import { OxPopup } from '@operato/popup'
13
+ import { isMobileDevice } from '@operato/utils'
14
+
15
+ import { connect } from 'pwa-helpers/connect-mixin'
16
+ import gql from 'graphql-tag'
17
+
18
+ import { AccountingCategoryImporter } from './accounting-category-importer'
19
+
20
+ @customElement('accounting-category-list-page')
21
+ export class AccountingCategoryListPage extends connect(store)(localize(i18next)(ScopedElementsMixin(PageView))) {
22
+ static styles = [
23
+ ScrollbarStyles,
24
+ CommonGristStyles,
25
+ css`
26
+ :host {
27
+ display: flex;
28
+
29
+ width: 100%;
30
+
31
+ --grid-record-emphasized-background-color: #8b0000;
32
+ --grid-record-emphasized-color: #ff6b6b;
33
+ }
34
+
35
+ ox-grist {
36
+ overflow-y: auto;
37
+ flex: 1;
38
+ }
39
+ `
40
+ ]
41
+
42
+ static get scopedElements() {
43
+ return {
44
+ 'accounting-category-importer': AccountingCategoryImporter
45
+ }
46
+ }
47
+
48
+ @property({ type: Object }) gristConfig: any
49
+ @property({ type: String }) mode: 'CARD' | 'GRID' | 'LIST' = isMobileDevice() ? 'CARD' : 'GRID'
50
+
51
+ @query('ox-grist') private grist!: DataGrist
52
+ @query('#sorter-control') private sortersControl!: OxPopup
53
+
54
+ get context() {
55
+ return {
56
+ title: i18next.t('title.accounting-category list'),
57
+ search: {
58
+ handler: (search: string) => {
59
+ this.grist.searchText = search
60
+ },
61
+ value: this.grist?.searchText || '',
62
+ autofocus: true
63
+ },
64
+ filter: {
65
+ handler: () => {
66
+ this.grist.toggleHeadroom()
67
+ }
68
+ },
69
+ help: 'accounting/accounting-category',
70
+ actions: [
71
+ {
72
+ title: i18next.t('button.save'),
73
+ action: this._updateAccountingCategory.bind(this),
74
+ ...CommonButtonStyles.save
75
+ },
76
+ {
77
+ title: i18next.t('button.delete'),
78
+ action: this._deleteAccountingCategory.bind(this),
79
+ ...CommonButtonStyles.delete
80
+ }
81
+ ],
82
+ exportable: {
83
+ name: i18next.t('title.accounting-category list'),
84
+ data: this.exportHandler.bind(this)
85
+ },
86
+ importable: {
87
+ handler: this.importHandler.bind(this)
88
+ }
89
+ }
90
+ }
91
+
92
+ render() {
93
+ const mode = this.mode || (isMobileDevice() ? 'CARD' : 'GRID')
94
+
95
+ return html`
96
+ <ox-grist .mode=${mode} .config=${this.gristConfig} .fetchHandler=${this.fetchHandler.bind(this)}>
97
+ <div slot="headroom">
98
+ <div id="filters">
99
+ <ox-filters-form autofocus></ox-filters-form>
100
+ </div>
101
+
102
+ <div id="sorters">
103
+ Sort
104
+ <mwc-icon
105
+ @click=${e => {
106
+ const target = e.currentTarget
107
+ this.sortersControl.open({
108
+ right: 0,
109
+ top: target.offsetTop + target.offsetHeight
110
+ })
111
+ }}
112
+ >expand_more</mwc-icon
113
+ >
114
+ <ox-popup id="sorter-control">
115
+ <ox-sorters-control> </ox-sorters-control>
116
+ </ox-popup>
117
+ </div>
118
+
119
+ <div id="modes">
120
+ <mwc-icon @click=${() => (this.mode = 'GRID')} ?active=${mode == 'GRID'}>grid_on</mwc-icon>
121
+ <mwc-icon @click=${() => (this.mode = 'LIST')} ?active=${mode == 'LIST'}>format_list_bulleted</mwc-icon>
122
+ <mwc-icon @click=${() => (this.mode = 'CARD')} ?active=${mode == 'CARD'}>apps</mwc-icon>
123
+ </div>
124
+ </div>
125
+ </ox-grist>
126
+ `
127
+ }
128
+
129
+ async pageInitialized(lifecycle: any) {
130
+ this.gristConfig = {
131
+ list: {
132
+ fields: ['name', 'description'],
133
+ details: ['active', 'updatedAt']
134
+ },
135
+ columns: [
136
+ { type: 'gutter', gutterName: 'sequence' },
137
+ { type: 'gutter', gutterName: 'row-selector', multiple: true },
138
+ {
139
+ type: 'string',
140
+ name: 'code',
141
+ header: i18next.t('field.code'),
142
+ record: {
143
+ editable: true,
144
+ mandatory: true
145
+ },
146
+ filter: 'search',
147
+ sortable: true,
148
+ width: 150
149
+ },
150
+ {
151
+ type: 'string',
152
+ name: 'name',
153
+ header: i18next.t('field.name'),
154
+ record: {
155
+ editable: true,
156
+ mandatory: true
157
+ },
158
+ filter: 'search',
159
+ sortable: true,
160
+ width: 150
161
+ },
162
+ {
163
+ type: 'resource-object',
164
+ name: 'parent',
165
+ header: i18next.t('field.parent'),
166
+ record: {
167
+ editable: true
168
+ },
169
+ filter: true,
170
+ sortable: true,
171
+ width: 150
172
+ },
173
+ {
174
+ type: 'string',
175
+ name: 'description',
176
+ header: i18next.t('field.description'),
177
+ record: {
178
+ editable: true
179
+ },
180
+ filter: 'search',
181
+ width: 200
182
+ },
183
+ {
184
+ type: 'checkbox',
185
+ name: 'active',
186
+ label: true,
187
+ header: i18next.t('field.active'),
188
+ record: {
189
+ editable: true
190
+ },
191
+ filter: true,
192
+ sortable: true,
193
+ width: 60
194
+ },
195
+ {
196
+ type: 'resource-object',
197
+ name: 'updater',
198
+ header: i18next.t('field.updater'),
199
+ record: {
200
+ editable: false
201
+ },
202
+ sortable: true,
203
+ width: 120
204
+ },
205
+ {
206
+ type: 'datetime',
207
+ name: 'updatedAt',
208
+ header: i18next.t('field.updated_at'),
209
+ record: {
210
+ editable: false
211
+ },
212
+ sortable: true,
213
+ width: 180
214
+ }
215
+ ],
216
+ rows: {
217
+ selectable: {
218
+ multiple: true
219
+ }
220
+ },
221
+ sorters: [
222
+ {
223
+ name: 'name'
224
+ }
225
+ ]
226
+ }
227
+ }
228
+
229
+ async pageUpdated(changes: any, lifecycle: any) {
230
+ if (this.active) {
231
+ // do something here when this page just became as active
232
+ }
233
+ }
234
+
235
+ async fetchHandler({ page = 1, limit = 100, sortings = [], filters = [] }: FetchOption) {
236
+ const response = await client.query({
237
+ query: gql`
238
+ query ($filters: [Filter!], $pagination: Pagination, $sortings: [Sorting!]) {
239
+ responses: accountingCategories(filters: $filters, pagination: $pagination, sortings: $sortings) {
240
+ items {
241
+ id
242
+ code
243
+ name
244
+ description
245
+ active
246
+ parent {
247
+ code
248
+ name
249
+ description
250
+ }
251
+ updater {
252
+ id
253
+ name
254
+ }
255
+ updatedAt
256
+ }
257
+ total
258
+ }
259
+ }
260
+ `,
261
+ variables: {
262
+ filters,
263
+ pagination: { page, limit },
264
+ sortings
265
+ }
266
+ })
267
+
268
+ return {
269
+ total: response.data.responses.total || 0,
270
+ records: response.data.responses.items || []
271
+ }
272
+ }
273
+
274
+ async _deleteAccountingCategory() {
275
+ if (confirm(i18next.t('text.sure_to_x', { x: i18next.t('text.delete') }))) {
276
+ const ids = this.grist.selected.map(record => record.id)
277
+ if (ids && ids.length > 0) {
278
+ const response = await client.mutate({
279
+ mutation: gql`
280
+ mutation ($ids: [String!]!) {
281
+ deleteAccountingCategories(ids: $ids)
282
+ }
283
+ `,
284
+ variables: {
285
+ ids
286
+ }
287
+ })
288
+
289
+ if (!response.errors) {
290
+ this.grist.fetch()
291
+ notify({
292
+ message: i18next.t('text.info_x_successfully', { x: i18next.t('text.delete') })
293
+ })
294
+ }
295
+ }
296
+ }
297
+ }
298
+
299
+ async _updateAccountingCategory() {
300
+ let patches = this.grist.dirtyRecords
301
+ if (patches && patches.length) {
302
+ patches = patches.map(patch => {
303
+ let patchField: any = patch.id ? { id: patch.id } : {}
304
+ const dirtyFields = patch.__dirtyfields__
305
+ for (let key in dirtyFields) {
306
+ patchField[key] = dirtyFields[key].after
307
+ }
308
+ patchField.cuFlag = patch.__dirty__
309
+
310
+ return patchField
311
+ })
312
+
313
+ const response = await client.mutate({
314
+ mutation: gql`
315
+ mutation ($patches: [AccountingCategoryPatch!]!) {
316
+ updateMultipleAccountingCategory(patches: $patches) {
317
+ name
318
+ }
319
+ }
320
+ `,
321
+ variables: {
322
+ patches
323
+ }
324
+ })
325
+
326
+ if (!response.errors) {
327
+ this.grist.fetch()
328
+ }
329
+ }
330
+ }
331
+
332
+ async exportHandler() {
333
+ const exportTargets = this.grist.selected.length ? this.grist.selected : this.grist.dirtyData.records
334
+ const targetFieldSet = new Set(['id', 'name', 'description', 'active'])
335
+
336
+ return exportTargets.map(accountingCategory => {
337
+ let tempObj = {}
338
+ for (const field of targetFieldSet) {
339
+ tempObj[field] = accountingCategory[field]
340
+ }
341
+
342
+ return tempObj
343
+ })
344
+ }
345
+
346
+ async importHandler(records) {
347
+ const popup = openPopup(
348
+ html`
349
+ <accounting-category-importer
350
+ .accountingCategories=${records}
351
+ @imported=${() => {
352
+ history.back()
353
+ this.grist.fetch()
354
+ }}
355
+ ></accounting-category-importer>
356
+ `,
357
+ {
358
+ backdrop: true,
359
+ size: 'large',
360
+ title: i18next.t('title.import accounting-category')
361
+ }
362
+ )
363
+
364
+ popup.onclosed = () => {
365
+ this.grist.fetch()
366
+ }
367
+ }
368
+ }
@@ -0,0 +1,338 @@
1
+ import '@operato/data-tree'
2
+ import '@operato/context/ox-context-page-toolbar.js'
3
+
4
+ import { css, html, PropertyValues } from 'lit'
5
+ import { customElement, property, query, state } from 'lit/decorators.js'
6
+ import { ScopedElementsMixin } from '@open-wc/scoped-elements'
7
+ import { client } from '@operato/graphql'
8
+ import { i18next, localize } from '@operato/i18n'
9
+ import { CommonHeaderStyles, ScrollbarStyles } from '@operato/styles'
10
+ import { CustomAlert, PageView, store } from '@operato/shell'
11
+
12
+ import { connect } from 'pwa-helpers/connect-mixin'
13
+ import gql from 'graphql-tag'
14
+
15
+ import { AccountingCategory } from '../../types/accounting-category'
16
+
17
+ import { AccountingCategoryView } from '../../components/accounting-category-view'
18
+
19
+ const SubAccountingCategoryFragment = gql`
20
+ fragment SubAccountingCategoryFragment on AccountingCategory {
21
+ id
22
+ code
23
+ name
24
+ description
25
+ active
26
+ updater {
27
+ id
28
+ name
29
+ }
30
+ updatedAt
31
+ }
32
+ `
33
+
34
+ @customElement('accounting-category-tree-page')
35
+ export class AccountingCategoryTreePage extends connect(store)(localize(i18next)(ScopedElementsMixin(PageView))) {
36
+ static styles = [
37
+ CommonHeaderStyles,
38
+ ScrollbarStyles,
39
+ css`
40
+ :host {
41
+ display: flex;
42
+ flex-direction: column;
43
+
44
+ width: 100%;
45
+ overflow: auto;
46
+ }
47
+
48
+ content {
49
+ flex: 1;
50
+ display: flex;
51
+ flex-direction: row;
52
+ }
53
+
54
+ div[editor] {
55
+ width: 300px;
56
+ display: flex;
57
+ flex-direction: column;
58
+ }
59
+
60
+ ox-tree-vertical {
61
+ flex: 1;
62
+ overflow: auto;
63
+ }
64
+
65
+ accounting-category-view {
66
+ flex: 1;
67
+ padding: var(--spacing-medium);
68
+ background-color: var(--md-sys-color-surface-variant);
69
+ overflow: auto;
70
+ }
71
+
72
+ .footer button[disabled] {
73
+ color: var(--md-sys-color-surface-dim);
74
+ background-color: transparent;
75
+ }
76
+ `
77
+ ]
78
+
79
+ @state() root?: AccountingCategory
80
+ @state() selected?: AccountingCategory
81
+ @state() accountingCategory?: AccountingCategory
82
+ @state() modified: boolean = false
83
+ @state() appendable: boolean = false
84
+
85
+ @query('accounting-category-view') accountingCategoryView!: AccountingCategoryView
86
+
87
+ get context() {
88
+ return {
89
+ title: i18next.t('title.accounting-category list'),
90
+ help: 'accounting/accounting-category',
91
+ actions: [
92
+ {
93
+ icon: 'delete',
94
+ title: i18next.t('button.delete'),
95
+ action: this.delete.bind(this),
96
+ emphasis: {
97
+ danger: true
98
+ }
99
+ }
100
+ ].filter(Boolean),
101
+ toolbar: false
102
+ }
103
+ }
104
+
105
+ render() {
106
+ return html`
107
+ <div class="header">
108
+ <ox-context-page-toolbar class="actions" .context=${this.context}></ox-context-page-toolbar>
109
+ </div>
110
+
111
+ <content>
112
+ <ox-tree-vertical
113
+ .data=${this.root}
114
+ .selected=${this.selected}
115
+ @select=${this.onSelect.bind(this)}
116
+ id-property="code"
117
+ label-property="name"
118
+ description-property="description"
119
+ ></ox-tree-vertical>
120
+
121
+ <div editor>
122
+ <accounting-category-view
123
+ .accountingCategory=${this.accountingCategory}
124
+ @property-change=${(e: CustomEvent) => {
125
+ const { code, name } = e.detail || {}
126
+
127
+ this.modified = true
128
+ this.appendable = code && code !== this.selected?.code && name !== this.selected?.name
129
+ }}
130
+ ></accounting-category-view>
131
+ <div class="footer">
132
+ <button @click=${this.reset.bind(this)}><md-icon>restart_alt</md-icon>${i18next.t('button.reset')}</button>
133
+ <div filler></div>
134
+ <button @click=${this.create.bind(this)} ?disabled=${!this.appendable}>
135
+ <md-icon>add</md-icon>${i18next.t('button.add')}
136
+ </button>
137
+ <button @click=${this.save.bind(this)} ?disabled=${!this.modified} done>
138
+ <md-icon>save</md-icon>${i18next.t('button.save')}
139
+ </button>
140
+ </div>
141
+ </div>
142
+ </content>
143
+ `
144
+ }
145
+
146
+ updated(changes: PropertyValues<this>) {
147
+ if (changes.has('selected')) {
148
+ this.modified = false
149
+ this.accountingCategory = { ...this.selected }
150
+ }
151
+ }
152
+
153
+ onSelect(e: CustomEvent) {
154
+ this.selected = e.detail as AccountingCategory
155
+ this.updateContext()
156
+ }
157
+
158
+ reset() {
159
+ this.accountingCategoryView.accountingCategory = {}
160
+ }
161
+
162
+ async create() {
163
+ const { id: parentId } = this.accountingCategory || {}
164
+ const { code, name, description, active } = this.accountingCategory || {}
165
+
166
+ var accountingCategory = {
167
+ code,
168
+ name,
169
+ description,
170
+ active
171
+ } as any
172
+
173
+ if (parentId) {
174
+ accountingCategory.parent = { id: parentId }
175
+ }
176
+
177
+ const response = await client.mutate({
178
+ mutation: gql`
179
+ mutation ($accountingCategory: NewAccountingCategory!) {
180
+ createAccountingCategory(accountingCategory: $accountingCategory) {
181
+ ...SubAccountingCategoryFragment
182
+ }
183
+ }
184
+
185
+ ${SubAccountingCategoryFragment}
186
+ `,
187
+ variables: {
188
+ accountingCategory
189
+ }
190
+ })
191
+
192
+ this.selected = response.data.createAccountingCategory
193
+ this.updateContext()
194
+
195
+ await this.fetch()
196
+ }
197
+
198
+ async save() {
199
+ const { id, code, name, description, active } = this.accountingCategory || {}
200
+
201
+ if (!id) {
202
+ await CustomAlert({
203
+ type: 'warning',
204
+ title: 'accounting-category not selected',
205
+ text: 'Please select accounting-category first.',
206
+ confirmButton: { text: i18next.t('button.confirm') }
207
+ })
208
+
209
+ return
210
+ }
211
+
212
+ var patch = {
213
+ code,
214
+ name,
215
+ description,
216
+ active
217
+ } as any
218
+
219
+ const response = await client.mutate({
220
+ mutation: gql`
221
+ mutation ($id: String!, $patch: AccountingCategoryPatch!) {
222
+ updateAccountingCategory(id: $id, patch: $patch) {
223
+ ...SubAccountingCategoryFragment
224
+ }
225
+ }
226
+
227
+ ${SubAccountingCategoryFragment}
228
+ `,
229
+ variables: {
230
+ id,
231
+ patch
232
+ },
233
+ context: {
234
+ hasUpload: true
235
+ }
236
+ })
237
+
238
+ this.selected = response.data.updateAccountingCategory
239
+
240
+ this.fetch()
241
+ }
242
+
243
+ async delete() {
244
+ if (!this.selected) {
245
+ await CustomAlert({
246
+ type: 'warning',
247
+ title: 'accounting category not selected',
248
+ text: 'Please select accounting category first.',
249
+ confirmButton: { text: i18next.t('button.confirm') }
250
+ })
251
+
252
+ return
253
+ }
254
+
255
+ const children = this.selected?.children
256
+ if (children && children.length > 0) {
257
+ await CustomAlert({
258
+ type: 'warning',
259
+ title: 'AccountingCategorys with subordinates cannot be deleted.',
260
+ text: 'AccountingCategory having children cannot be deleted.',
261
+ confirmButton: { text: i18next.t('button.confirm') }
262
+ })
263
+
264
+ return
265
+ }
266
+
267
+ if (confirm(i18next.t('text.sure_to_x', { x: i18next.t('text.delete') }))) {
268
+ const { id } = this.selected || {}
269
+
270
+ const response = await client.mutate({
271
+ mutation: gql`
272
+ mutation ($id: String!) {
273
+ deleteAccountingCategory(id: $id)
274
+ }
275
+ `,
276
+ variables: {
277
+ id
278
+ }
279
+ })
280
+
281
+ this.selected = {}
282
+ this.updateContext()
283
+
284
+ await this.fetch()
285
+ }
286
+ }
287
+
288
+ async pageInitialized(lifecycle: any) {
289
+ this.fetch()
290
+ }
291
+
292
+ async pageUpdated(changes: any, lifecycle: any) {
293
+ if (this.active) {
294
+ // do something here when this page just became as active
295
+ }
296
+ }
297
+
298
+ async fetch() {
299
+ const response = await client.query({
300
+ query: gql`
301
+ query {
302
+ responses: accountingCategoryRoots {
303
+ total
304
+ items {
305
+ ...SubAccountingCategoryFragment
306
+ children {
307
+ ...SubAccountingCategoryFragment
308
+ children {
309
+ ...SubAccountingCategoryFragment
310
+ children {
311
+ ...SubAccountingCategoryFragment
312
+ children {
313
+ ...SubAccountingCategoryFragment
314
+ children {
315
+ ...SubAccountingCategoryFragment
316
+ children {
317
+ ...SubAccountingCategoryFragment
318
+ children {
319
+ ...SubAccountingCategoryFragment
320
+ }
321
+ }
322
+ }
323
+ }
324
+ }
325
+ }
326
+ }
327
+ }
328
+ }
329
+ }
330
+
331
+ ${SubAccountingCategoryFragment}
332
+ `
333
+ })
334
+ const { items: records, total } = response.data.responses
335
+
336
+ this.root = records[0]
337
+ }
338
+ }