Develop and Download Open Source Software

Browse Subversion Repository

Annotation of /aoiro/trunk/src/main/java/net/osdn/aoiro/report/BalanceSheet.java

Parent Directory Parent Directory | Revision Log Revision Log


Revision 120 - (hide annotations) (download) (as text)
Sat Mar 4 02:37:28 2023 UTC (13 months, 2 weeks ago) by hirukawa_ryo
File MIME type: text/x-java
File size: 54817 byte(s)
aoiro 1.1.2
次年度の元入金に繰り越す勘定科目の金額がすべて0円の場合は、先頭の勘定科目1つを次年度の元入金として繰り越すようにしました。これによって、現金 0 / 元入金 0 が次年度にも繰り越されるようになりました。従来は次年度は 元入金 0 / 元入金 0 となっていました。
1 hirukawa_ryo 2 package net.osdn.aoiro.report;
2    
3     import java.io.BufferedReader;
4     import java.io.IOException;
5     import java.io.InputStream;
6     import java.io.InputStreamReader;
7 hirukawa_ryo 61 import java.io.OutputStream;
8 hirukawa_ryo 2 import java.nio.charset.StandardCharsets;
9 hirukawa_ryo 116 import java.nio.file.AccessDeniedException;
10 hirukawa_ryo 82 import java.nio.file.AtomicMoveNotSupportedException;
11 hirukawa_ryo 50 import java.nio.file.Files;
12     import java.nio.file.Path;
13 hirukawa_ryo 67 import java.nio.file.StandardCopyOption;
14     import java.nio.file.StandardOpenOption;
15 hirukawa_ryo 36 import java.text.NumberFormat;
16     import java.time.LocalDate;
17 hirukawa_ryo 41 import java.time.chrono.JapaneseChronology;
18 hirukawa_ryo 36 import java.time.format.DateTimeFormatter;
19 hirukawa_ryo 2 import java.util.ArrayList;
20 hirukawa_ryo 84 import java.util.Collections;
21 hirukawa_ryo 2 import java.util.HashMap;
22 hirukawa_ryo 90 import java.util.HashSet;
23 hirukawa_ryo 2 import java.util.List;
24     import java.util.Map;
25     import java.util.Map.Entry;
26    
27     import net.osdn.aoiro.AccountSettlement;
28 hirukawa_ryo 49 import net.osdn.aoiro.Util;
29 hirukawa_ryo 71 import net.osdn.aoiro.loader.yaml.YamlBeansUtil;
30 hirukawa_ryo 77 import net.osdn.aoiro.model.Account;
31 hirukawa_ryo 2 import net.osdn.aoiro.model.AccountTitle;
32     import net.osdn.aoiro.model.AccountType;
33     import net.osdn.aoiro.model.Amount;
34     import net.osdn.aoiro.model.Creditor;
35     import net.osdn.aoiro.model.Debtor;
36     import net.osdn.aoiro.model.JournalEntry;
37     import net.osdn.aoiro.model.Node;
38 hirukawa_ryo 51 import net.osdn.aoiro.report.layout.BalanceSheetLayout;
39 hirukawa_ryo 2 import net.osdn.pdf_brewer.BrewerData;
40 hirukawa_ryo 61 import net.osdn.pdf_brewer.FontLoader;
41 hirukawa_ryo 2 import net.osdn.pdf_brewer.PdfBrewer;
42    
43     /** ���������������
44     *
45     */
46     public class BalanceSheet {
47    
48     public static String MINUS_SIGN = "���";
49     private static final int ROWS = 40;
50     private static final double ROW_HEIGHT = 6.0;
51    
52 hirukawa_ryo 51 private BalanceSheetLayout bsLayout;
53 hirukawa_ryo 2 private List<JournalEntry> journalEntries;
54 hirukawa_ryo 17 private boolean isSoloProprietorship;
55 hirukawa_ryo 51
56 hirukawa_ryo 36 private LocalDate openingDate;
57     private LocalDate closingDate;
58 hirukawa_ryo 2 private Map<AccountTitle, Amount> openingBalances = new HashMap<AccountTitle, Amount>();
59     private Map<AccountTitle, Amount> closingBalances = new HashMap<AccountTitle, Amount>();
60 hirukawa_ryo 18 private List<Node<Entry<List<AccountTitle>, Amount[]>>> assetsList;
61     private List<Node<Entry<List<AccountTitle>, Amount[]>>> liabilitiesList;
62     private List<Node<Entry<List<AccountTitle>, Amount[]>>> equityList;
63 hirukawa_ryo 2
64     private List<String> pageData = new ArrayList<String>();
65     private List<String> printData;
66 hirukawa_ryo 61 private FontLoader fontLoader;
67 hirukawa_ryo 62 private boolean bindingMarginEnabled = true;
68 hirukawa_ryo 2
69 hirukawa_ryo 36 private List<String> warnings = new ArrayList<String>();
70    
71 hirukawa_ryo 51 public BalanceSheet(BalanceSheetLayout bsLayout, List<JournalEntry> journalEntries, boolean isSoloProprietorship) throws IOException {
72     this.bsLayout = bsLayout;
73 hirukawa_ryo 2 this.journalEntries = journalEntries;
74 hirukawa_ryo 17 this.isSoloProprietorship = isSoloProprietorship;
75 hirukawa_ryo 51
76 hirukawa_ryo 10 this.openingDate = AccountSettlement.getOpeningDate(journalEntries, isSoloProprietorship);
77     this.closingDate = AccountSettlement.getClosingDate(journalEntries, isSoloProprietorship);
78 hirukawa_ryo 2
79     InputStream in = getClass().getResourceAsStream("/templates/���������������.pb");
80     BufferedReader r = new BufferedReader(new InputStreamReader(in, StandardCharsets.UTF_8));
81     String line;
82     while((line = r.readLine()) != null) {
83     pageData.add(line);
84     }
85     r.close();
86    
87     //������������(���������)������������������������
88     for(JournalEntry entry : journalEntries) {
89     //������������(���������)
90 hirukawa_ryo 89 if(entry.isOpening(isSoloProprietorship, openingDate)) {
91 hirukawa_ryo 2 for(Debtor debtor : entry.getDebtors()) {
92     Amount amount = openingBalances.get(debtor.getAccountTitle());
93     if(amount == null) {
94     amount = new Amount(debtor.getAccountTitle().getType().getNormalBalance(), 0);
95     openingBalances.put(debtor.getAccountTitle(), amount);
96     }
97     if(debtor.getAccountTitle().getType().getNormalBalance() == Debtor.class) {
98     amount.increase(debtor.getAmount());
99     } else {
100     amount.decrease(debtor.getAmount());
101     }
102     }
103     for(Creditor creditor : entry.getCreditors()) {
104     Amount amount = openingBalances.get(creditor.getAccountTitle());
105     if(amount == null) {
106     amount = new Amount(creditor.getAccountTitle().getType().getNormalBalance(), 0);
107     openingBalances.put(creditor.getAccountTitle(), amount);
108     }
109     if(creditor.getAccountTitle().getType().getNormalBalance() == Creditor.class) {
110     amount.increase(creditor.getAmount());
111     } else {
112     amount.decrease(creditor.getAmount());
113     }
114     }
115     }
116     //������������
117     if(entry.isBalance()) {
118     for(Debtor debtor : entry.getDebtors()) {
119     if(!debtor.getAccountTitle().equals(AccountTitle.BALANCE)) {
120     Amount amount = closingBalances.get(debtor.getAccountTitle());
121     if(amount == null) {
122     amount = new Amount(debtor.getAccountTitle().getType().getNormalBalance(), 0);
123     closingBalances.put(debtor.getAccountTitle(), amount);
124     }
125     if(debtor.getAccountTitle().getType().getNormalBalance() != Debtor.class) {
126     amount.increase(debtor.getAmount());
127     } else {
128     amount.decrease(debtor.getAmount());
129     }
130     }
131     }
132     for(Creditor creditor : entry.getCreditors()) {
133     if(!creditor.getAccountTitle().equals(AccountTitle.BALANCE)) {
134     Amount amount = closingBalances.get(creditor.getAccountTitle());
135     if(amount == null) {
136     amount = new Amount(creditor.getAccountTitle().getType().getNormalBalance(), 0);
137     closingBalances.put(creditor.getAccountTitle(), amount);
138     }
139     if(creditor.getAccountTitle().getType().getNormalBalance() != Creditor.class) {
140     amount.increase(creditor.getAmount());
141     } else {
142     amount.decrease(creditor.getAmount());
143     }
144     }
145     }
146     }
147     }
148    
149     /*
150     for(Entry<AccountTitle, Amount> e : openingBalances.entrySet()) {
151     AccountTitle at = e.getKey();
152     Amount a = e.getValue();
153     System.out.println("#OPEN# " + at + ", " + a);
154    
155     }
156     */
157     /*
158     for(Entry<AccountTitle, Amount> e : closingBalances.entrySet()) {
159     AccountTitle at = e.getKey();
160     Amount a = e.getValue();
161     System.out.println("#CLOSE# " + at + ", " + a);
162     }
163     */
164    
165     //������������
166 hirukawa_ryo 77 retrieve(null, bsLayout.getRoot(), journalEntries);
167 hirukawa_ryo 2 //dump(bsRoot);
168    
169     //���������
170 hirukawa_ryo 51 for(Node<Entry<List<AccountTitle>, Amount[]>> child : bsLayout.getRoot().getChildren()) {
171 hirukawa_ryo 2 if(child.getName().equals("������")) {
172     assetsList = getList(child);
173     } else if(child.getName().equals("������")) {
174     liabilitiesList = getList(child);
175 hirukawa_ryo 52 } else if(child.getName().equals("������") || child.getName().equals("���������")) {
176 hirukawa_ryo 2 equityList = getList(child);
177     }
178     }
179     if(assetsList == null) {
180 hirukawa_ryo 18 assetsList = new ArrayList<Node<Entry<List<AccountTitle>, Amount[]>>>();
181 hirukawa_ryo 2 }
182     if(liabilitiesList == null) {
183 hirukawa_ryo 18 liabilitiesList = new ArrayList<Node<Entry<List<AccountTitle>, Amount[]>>>();
184 hirukawa_ryo 2 }
185     if(equityList == null) {
186 hirukawa_ryo 18 equityList = new ArrayList<Node<Entry<List<AccountTitle>, Amount[]>>>();
187 hirukawa_ryo 2 }
188 hirukawa_ryo 36
189     //
190     // ���������������������������������������������������������������������������������������������������
191 hirukawa_ryo 109 // ���������������������������������������������������������������������������������������������������������������������������������������������������������������
192 hirukawa_ryo 36 // ������������������������������������������������������������������������������������������������������������������������������������������������
193     //
194     for(Entry<AccountTitle, Amount> entry : openingBalances.entrySet()) {
195     AccountTitle accountTitle = entry.getKey();
196     Amount amount = entry.getValue();
197     NumberFormat.getNumberInstance();
198 hirukawa_ryo 109 int sign = bsLayout.isSignReversed(accountTitle.getDisplayName()) ? -1 : 1;
199     if(sign * amount.getValue() < 0
200 hirukawa_ryo 36 && (accountTitle.getType() == AccountType.Assets || accountTitle.getType() == AccountType.Liabilities)) {
201     String msg = " [������] ���������������������"
202     + accountTitle.getDisplayName()
203     + "������������������������������������������������������("
204     + accountTitle.getDisplayName()
205     + " "
206     + NumberFormat.getNumberInstance().format(amount.getValue())
207     + ")";
208     warnings.add(msg);
209     }
210     }
211     //
212     // ���������������������������������������������������������������������������������������������������
213 hirukawa_ryo 109 // ���������������������������������������������������������������������������������������������������������������������������������������������������������������
214 hirukawa_ryo 36 // ������������������������������������������������������������������������������������������������������������������������������������������������
215     //
216     for(Entry<AccountTitle, Amount> entry : closingBalances.entrySet()) {
217     AccountTitle accountTitle = entry.getKey();
218     Amount amount = entry.getValue();
219     NumberFormat.getNumberInstance();
220 hirukawa_ryo 109 int sign = bsLayout.isSignReversed(accountTitle.getDisplayName()) ? -1 : 1;
221     if(sign * amount.getValue() < 0
222 hirukawa_ryo 36 && (accountTitle.getType() == AccountType.Assets || accountTitle.getType() == AccountType.Liabilities)) {
223     String msg = " [������] ���������������������"
224     + accountTitle.getDisplayName()
225     + "������������������������������������������������������("
226     + accountTitle.getDisplayName()
227     + " "
228     + NumberFormat.getNumberInstance().format(amount.getValue())
229     + ")";
230     warnings.add(msg);
231     }
232     }
233 hirukawa_ryo 2 }
234    
235 hirukawa_ryo 66 public List<JournalEntry> getJournalEntries() {
236     return journalEntries;
237     }
238    
239     public Map<AccountTitle, Amount> getOpeningBalances() {
240     return openingBalances;
241     }
242    
243     public Map<AccountTitle, Amount> getClosingBalances() {
244     return closingBalances;
245     }
246    
247 hirukawa_ryo 60 // PDF���������������������������������������������������������
248     // ���������������������������������������������PDF���������������������������������������������������������������
249     public List<Node<Entry<List<AccountTitle>, Amount[]>>> getAssetsList() {
250     return assetsList;
251     }
252    
253     // PDF���������������������������������������������������������
254     // ���������������������������������������������PDF���������������������������������������������������������������
255     public List<Node<Entry<List<AccountTitle>, Amount[]>>> getLiabilitiesList() {
256     return liabilitiesList;
257     }
258    
259     // PDF������������������������������������������������������������������������
260     // ���������������������������������������������PDF���������������������������������������������������������������
261     public List<Node<Entry<List<AccountTitle>, Amount[]>>> getEquityList() {
262     return equityList;
263     }
264    
265 hirukawa_ryo 36 public List<String> getWarnings() {
266     return warnings;
267     }
268    
269 hirukawa_ryo 77 private Amount[] retrieve(Class<? extends Account> normalBalance, Node<Entry<List<AccountTitle>, Amount[]>> node, List<JournalEntry> journalEntries) {
270     if(normalBalance == null && node.getLevel() == 1) {
271     if(node.getName().equals("������")) {
272     normalBalance = Debtor.class;
273     } else if(node.getName().equals("������") || node.getName().equals("������") || node.getName().equals("���������")) {
274     normalBalance = Creditor.class;
275     }
276     }
277    
278 hirukawa_ryo 2 Amount openingBalance = null;
279     Amount closingBalance = null;
280 hirukawa_ryo 18 for(Node<Entry<List<AccountTitle>, Amount[]>> child : node.getChildren()) {
281 hirukawa_ryo 77 Amount[] a = retrieve(normalBalance, child, journalEntries);
282 hirukawa_ryo 2 if(a[0] != null) {
283     if(openingBalance == null) {
284 hirukawa_ryo 77 openingBalance = new Amount(normalBalance != null ? normalBalance : a[0].getNormalBalance(), 0);
285 hirukawa_ryo 2 }
286 hirukawa_ryo 77 openingBalance.increase(a[0]);
287 hirukawa_ryo 2 }
288     if(a[1] != null) {
289     if(closingBalance == null) {
290 hirukawa_ryo 77 closingBalance = new Amount(normalBalance != null ? normalBalance : a[1].getNormalBalance(), 0);
291 hirukawa_ryo 2 }
292 hirukawa_ryo 77 closingBalance.increase(a[1]);
293 hirukawa_ryo 2 }
294     }
295 hirukawa_ryo 18 if(node.getValue().getKey() != null) {
296     for(AccountTitle accountTitle : node.getValue().getKey()) {
297 hirukawa_ryo 2 Amount o = openingBalances.get(accountTitle);
298     if(o != null) {
299     if(openingBalance == null) {
300 hirukawa_ryo 77 openingBalance = new Amount(normalBalance != null ? normalBalance : o.getNormalBalance(), 0);
301 hirukawa_ryo 2 }
302 hirukawa_ryo 77 openingBalance.increase(o);
303 hirukawa_ryo 2 }
304     Amount c = closingBalances.get(accountTitle);
305     if(c != null) {
306     if(closingBalance == null) {
307 hirukawa_ryo 77 closingBalance = new Amount(normalBalance != null ? normalBalance : o.getNormalBalance(), 0);
308 hirukawa_ryo 2 }
309 hirukawa_ryo 77 closingBalance.increase(c);
310 hirukawa_ryo 2 }
311     }
312     }
313     Amount[] amounts = new Amount[2];
314     amounts[0] = openingBalance;
315     amounts[1] = closingBalance;
316 hirukawa_ryo 18 node.getValue().setValue(amounts);
317 hirukawa_ryo 2 return amounts;
318     }
319    
320 hirukawa_ryo 18 protected List<Node<Entry<List<AccountTitle>, Amount[]>>> getList(Node<Entry<List<AccountTitle>, Amount[]>> node) {
321     List<Node<Entry<List<AccountTitle>, Amount[]>>> list = new ArrayList<Node<Entry<List<AccountTitle>, Amount[]>>>();
322 hirukawa_ryo 2 list.add(node);
323 hirukawa_ryo 18 for(Node<Entry<List<AccountTitle>, Amount[]>> child : node.getChildren()) {
324 hirukawa_ryo 2 list.addAll(getList(child));
325     }
326     return list;
327     }
328    
329     protected void prepare() {
330 hirukawa_ryo 41 DateTimeFormatter dtf = DateTimeFormatter.ofPattern("GGGG y ��� M ��� d ���").withChronology(JapaneseChronology.INSTANCE);
331     String openingDate = dtf.format(this.openingDate).replace(" 1 ���", "������");
332 hirukawa_ryo 36 String openingMonth = Integer.toString(this.openingDate.getMonthValue());
333     String openingDay = Integer.toString(this.openingDate.getDayOfMonth());
334 hirukawa_ryo 41 String closingDate = dtf.format(this.closingDate).replace(" 1 ���", "������");
335 hirukawa_ryo 36 String closingMonth = Integer.toString(this.closingDate.getMonthValue());
336     String closingDay = Integer.toString(this.closingDate.getDayOfMonth());
337    
338 hirukawa_ryo 2 printData = new ArrayList<String>();
339 hirukawa_ryo 62 if(bindingMarginEnabled) {
340     printData.add("\\media A4");
341 hirukawa_ryo 2
342 hirukawa_ryo 62 //������������������������������������������������������������������������������������������������������
343     printData.add("\\line-style thin dot");
344     printData.add("\\line 0 148.5 5 148.5");
345 hirukawa_ryo 2
346 hirukawa_ryo 62 printData.add("\\box 15 0 0 0");
347     printData.add("\\line-style thin dot");
348     printData.add("\\line 0 0 0 -0");
349     printData.add("\\box 25 0 -10 -10");
350     } else {
351     // ���������������������������15mm������������������������������195mm���������������(A4������������������210mm)
352     // ���������������������������������������������������������
353     printData.add("\\media 195 297");
354    
355     printData.add("\\box 10 0 -10 -10");
356     }
357    
358 hirukawa_ryo 2 printData.addAll(pageData);
359    
360     //������
361     printData.add("\t\\box 0 16 -0 7");
362     printData.add("\t\\font serif 10");
363     printData.add("\t\\align center");
364     printData.add("\t\\text " + openingDate + " ��� " + closingDate);
365     printData.add("\t\\box 0 31 -0 6");
366 hirukawa_ryo 78 printData.add("\t\\align center center");
367     printData.add("\t\t\\box 37.0 0 5 -0");
368 hirukawa_ryo 2 printData.add("\t\t\\text " + openingMonth);
369 hirukawa_ryo 78 printData.add("\t\t\\box 44.7 0 5 -0");
370 hirukawa_ryo 2 printData.add("\t\t\\text " + openingDay);
371 hirukawa_ryo 78 printData.add("\t\t\\box 124.5 0 5 -0");
372 hirukawa_ryo 2 printData.add("\t\t\\text " + openingMonth);
373 hirukawa_ryo 78 printData.add("\t\t\\box 132.2 0 5 -0");
374 hirukawa_ryo 2 printData.add("\t\t\\text " + openingDay);
375 hirukawa_ryo 78 printData.add("\t\t\\box 63.0 0 5 -0");
376 hirukawa_ryo 2 printData.add("\t\t\\text " + closingMonth);
377 hirukawa_ryo 78 printData.add("\t\t\\box 70.7 0 5 -0");
378 hirukawa_ryo 2 printData.add("\t\t\\text " + closingDay);
379 hirukawa_ryo 78 printData.add("\t\t\\box 150.5 0 5 -0");
380 hirukawa_ryo 2 printData.add("\t\t\\text " + closingMonth);
381 hirukawa_ryo 78 printData.add("\t\t\\box 158.2 0 5 -0");
382 hirukawa_ryo 2 printData.add("\t\t\\text " + closingDay);
383    
384 hirukawa_ryo 27 //������������������������������������������
385     //2006���������������������������������������������������������������������������������������������������������������
386     //���������������������������������������������������������������������������������������������������������������������������������������������������������������������������
387     //������������������������������������������������������������������������������������������������
388     //aoiro���������������������������������������������������������������������������������������������������������������������������������������������������
389     printData.add("\t\\box 0 25 -0 6");
390     printData.add("\t\t\\font sans-serif 9");
391     printData.add("\t\t\\align center");
392     printData.add("\t\t\\box 87.5 0 87.5 -0");
393     if(isSoloProprietorship) {
394     printData.add("\t\t\\text ���������������������������������������");
395     } else {
396     printData.add("\t\t\\text ���������������������������������������������");
397     }
398    
399 hirukawa_ryo 42 // ������������������������������������������������������������������������������������������������������������������������������������������������������������
400     long maxAmount = 0;
401     if(assetsList.size() > 0) {
402     Node<Entry<List<AccountTitle>, Amount[]>> node = assetsList.get(0);
403     Amount openingAmount = node.getValue().getValue()[0];
404     Amount closingAmount = node.getValue().getValue()[1];
405     if(openingAmount != null) {
406     long v = Math.abs(openingAmount.getValue());
407     if(v > maxAmount) {
408     maxAmount = v;
409     }
410     }
411     if(closingAmount != null) {
412     long v = Math.abs(closingAmount.getValue());
413     if(v > maxAmount) {
414     maxAmount = v;
415     }
416     }
417     }
418     if(liabilitiesList.size() > 0) {
419     Node<Entry<List<AccountTitle>, Amount[]>> node = liabilitiesList.get(0);
420     Amount openingAmount = node.getValue().getValue()[0];
421     Amount closingAmount = node.getValue().getValue()[1];
422     if(openingAmount != null) {
423     long v = Math.abs(openingAmount.getValue());
424     if(v > maxAmount) {
425     maxAmount = v;
426     }
427     }
428     if(closingAmount != null) {
429     long v = Math.abs(closingAmount.getValue());
430     if(v > maxAmount) {
431     maxAmount = v;
432     }
433     }
434     }
435     if(equityList.size() > 0) {
436     Node<Entry<List<AccountTitle>, Amount[]>> node = liabilitiesList.get(0);
437     Amount openingAmount = node.getValue().getValue()[0];
438     Amount closingAmount = node.getValue().getValue()[1];
439     if(openingAmount != null) {
440     long v = Math.abs(openingAmount.getValue());
441     if(v > maxAmount) {
442     maxAmount = v;
443     }
444     }
445     if(closingAmount != null) {
446     long v = Math.abs(closingAmount.getValue());
447     if(v > maxAmount) {
448     maxAmount = v;
449     }
450     }
451     }
452    
453 hirukawa_ryo 2 //���������������������
454 hirukawa_ryo 22 int assetsRows = 1;
455     for(int i = 1; i < assetsList.size(); i++) {
456     Node<Entry<List<AccountTitle>, Amount[]>> node = assetsList.get(i);
457     String displayName = node.getName();
458     Amount openingAmount = node.getValue().getValue()[0];
459     Amount closingAmount = node.getValue().getValue()[1];
460 hirukawa_ryo 42 if(openingAmount != null) {
461     long v = Math.abs(openingAmount.getValue());
462     if(v > maxAmount) {
463     maxAmount = v;
464     }
465     }
466     if(closingAmount != null) {
467     long v = Math.abs(closingAmount.getValue());
468     if(v > maxAmount) {
469     maxAmount = v;
470     }
471     }
472 hirukawa_ryo 22 //������������������������������������������������������������������������������������������������������������������������������������������������������������������
473 hirukawa_ryo 51 if(openingAmount == null && closingAmount == null && !bsLayout.isAlwaysShown(displayName)) {
474 hirukawa_ryo 22 continue;
475     }
476 hirukawa_ryo 28 //���������������������������������������������������������������������������������������������������������������������������
477 hirukawa_ryo 51 if((openingAmount == null || openingAmount.getValue() == 0)
478     && (closingAmount == null || closingAmount.getValue() == 0) && bsLayout.isHidden(displayName)) {
479 hirukawa_ryo 28 continue;
480     }
481 hirukawa_ryo 22 assetsRows++;
482     }
483     int liabilitiesRows = 1;
484     for(int i = 1; i < liabilitiesList.size(); i++) {
485     Node<Entry<List<AccountTitle>, Amount[]>> node = liabilitiesList.get(i);
486     String displayName = node.getName();
487     Amount openingAmount = node.getValue().getValue()[0];
488     Amount closingAmount = node.getValue().getValue()[1];
489 hirukawa_ryo 42 if(openingAmount != null) {
490     long v = Math.abs(openingAmount.getValue());
491     if(v > maxAmount) {
492     maxAmount = v;
493     }
494     }
495     if(closingAmount != null) {
496     long v = Math.abs(closingAmount.getValue());
497     if(v > maxAmount) {
498     maxAmount = v;
499     }
500     }
501 hirukawa_ryo 22 //������������������������������������������������������������������������������������������������������������������������������������������������������������������
502 hirukawa_ryo 51 if(openingAmount == null && closingAmount == null && !bsLayout.isAlwaysShown(displayName)) {
503 hirukawa_ryo 22 continue;
504     }
505 hirukawa_ryo 28 //���������������������������������������������������������������������������������������������������������������������������
506 hirukawa_ryo 51 if((openingAmount == null || openingAmount.getValue() == 0)
507     && (closingAmount == null || closingAmount.getValue() == 0) && bsLayout.isHidden(displayName)) {
508 hirukawa_ryo 28 continue;
509     }
510 hirukawa_ryo 22 liabilitiesRows++;
511     }
512     int equityRows = 1;
513     for(int i = 1; i < equityList.size(); i++) {
514     Node<Entry<List<AccountTitle>, Amount[]>> node = equityList.get(i);
515     String displayName = node.getName();
516     Amount openingAmount = node.getValue().getValue()[0];
517     Amount closingAmount = node.getValue().getValue()[1];
518 hirukawa_ryo 42 if(openingAmount != null) {
519     long v = Math.abs(openingAmount.getValue());
520     if(v > maxAmount) {
521     maxAmount = v;
522     }
523     }
524     if(closingAmount != null) {
525     long v = Math.abs(closingAmount.getValue());
526     if(v > maxAmount) {
527     maxAmount = v;
528     }
529     }
530 hirukawa_ryo 22 //������������������������������������������������������������������������������������������������������������������������������������������������������������������
531 hirukawa_ryo 51 if(openingAmount == null && closingAmount == null && !bsLayout.isAlwaysShown(displayName)) {
532 hirukawa_ryo 22 continue;
533     }
534 hirukawa_ryo 28 //���������������������������������������������������������������������������������������������������������������������������
535 hirukawa_ryo 51 if((openingAmount == null || openingAmount.getValue() == 0)
536     && (closingAmount == null || closingAmount.getValue() == 0) && bsLayout.isHidden(displayName)) {
537 hirukawa_ryo 28 continue;
538     }
539 hirukawa_ryo 22 equityRows++;
540     }
541 hirukawa_ryo 42
542     // ���������������������������������������������22mm������������������ 99999999999���11���������������������������26mm���
543     // 9999999999���10���������������������������25mm���999999999���9���������������������������24mm ���������������
544     double amountPrintWidth = 22;
545     if(maxAmount > 99999999999L) {
546     amountPrintWidth = 26;
547     } else if(maxAmount > 9999999999L) {
548     amountPrintWidth = 25;
549     } else if(maxAmount > 999999999L) {
550     amountPrintWidth = 24;
551     }
552    
553 hirukawa_ryo 22 int rows = Math.max(assetsRows, liabilitiesRows + equityRows);
554 hirukawa_ryo 2 printData.add("\t\\box 0 0 -0 -0");
555     printData.add("\t\\line-style thin solid");
556     printData.add("\t\\line " + String.format("87.3 %.2f 87.3 %.2f", 25.2, 37.0 + rows * ROW_HEIGHT));
557     printData.add("\t\\line " + String.format("87.7 %.2f 87.7 %.2f", 25.2, 37.0 + rows * ROW_HEIGHT));
558     printData.add("\t\\line " + String.format("35.5 %.2f 35.5 %.2f", 31.0, 37.0 + rows * ROW_HEIGHT));
559     printData.add("\t\\line " + String.format("61.5 %.2f 61.5 %.2f", 31.0, 37.0 + rows * ROW_HEIGHT));
560     printData.add("\t\\line " + String.format("123 %.2f 123 %.2f", 31.0, 37.0 + rows * ROW_HEIGHT));
561     printData.add("\t\\line " + String.format("149 %.2f 149 %.2f", 31.0, 37.0 + rows * ROW_HEIGHT));
562    
563     printData.add("\t\\box 0 37 -0 -0");
564     printData.add("\t\\font serif 10");
565     printData.add("\t\\line-style thin dot");
566    
567     double y = 0.0;
568     for(int i = 1; i < rows; i++) {
569     printData.add("\t\\line " + String.format("0 %.2f -0 %.2f", y, y));
570     y += ROW_HEIGHT;
571     }
572     printData.add("\t\\line-style thin solid");
573     printData.add("\t\\line " + String.format("0 %.2f -0 %.2f", y, y));
574     y += ROW_HEIGHT;
575     printData.add("\t\\line " + String.format("0 %.2f -0 %.2f", y, y));
576     printData.add("\t\\line " + String.format("0 %.2f -0 %.2f", y + 0.4, y + 0.4));
577    
578     //������
579     y = 0.0;
580     for(int i = 1; i < assetsList.size(); i++) {
581 hirukawa_ryo 18 Node<Entry<List<AccountTitle>, Amount[]>> node = assetsList.get(i);
582 hirukawa_ryo 2 String displayName = node.getName();
583 hirukawa_ryo 18 Amount openingAmount = node.getValue().getValue()[0];
584     Amount closingAmount = node.getValue().getValue()[1];
585 hirukawa_ryo 51 int sign = bsLayout.isSignReversed(node.getName()) ? -1 : 1;
586 hirukawa_ryo 39
587     // ������������������������������������������������������
588     if("������������".equals(node.getName())) {
589     printData.add("\t\t\\box " + String.format("35.5 %.2f 26 %.2f", y, ROW_HEIGHT));
590     printData.add("\t\t\\line-style thin dot");
591     printData.add("\t\t\\line -0 0.15 0 -0.15");
592     }
593 hirukawa_ryo 22 //������������������������������������������������������������������������������������������������������������������������������������������������������������������
594 hirukawa_ryo 51 if(openingAmount == null && closingAmount == null && !bsLayout.isAlwaysShown(displayName)) {
595 hirukawa_ryo 22 continue;
596     }
597 hirukawa_ryo 28 //���������������������������������������������������������������������������������������������������������������������������
598 hirukawa_ryo 51 if((openingAmount == null || openingAmount.getValue() == 0)
599     && (closingAmount == null || closingAmount.getValue() == 0) && bsLayout.isHidden(displayName)) {
600 hirukawa_ryo 28 continue;
601     }
602 hirukawa_ryo 2 printData.add("\t\t\\box " + String.format("2 %.2f 35.5 %.2f", y, ROW_HEIGHT));
603     printData.add("\t\t\\align center left");
604     printData.add("\t\t\\text " + displayName);
605     printData.add("\t\t\\align center right");
606     if(openingAmount != null) {
607 hirukawa_ryo 42 printData.add("\t\t\\box " + String.format("35.5 %.2f %.2f %.2f", y, amountPrintWidth, ROW_HEIGHT));
608 hirukawa_ryo 38 printData.add("\t\t\\text " + formatMoney(sign * openingAmount.getValue()));
609 hirukawa_ryo 2 }
610     if(closingAmount != null) {
611 hirukawa_ryo 42 printData.add("\t\t\\box " + String.format("61.5 %.2f %.2f %.2f", y, amountPrintWidth, ROW_HEIGHT));
612 hirukawa_ryo 38 printData.add("\t\t\\text " + formatMoney(sign * closingAmount.getValue()));
613 hirukawa_ryo 2 }
614     y += ROW_HEIGHT;
615     }
616     //������
617     y = 0.0;
618     for(int i = 1; i < liabilitiesList.size(); i++) {
619 hirukawa_ryo 18 Node<Entry<List<AccountTitle>, Amount[]>> node = liabilitiesList.get(i);
620 hirukawa_ryo 2 String displayName = node.getName();
621 hirukawa_ryo 18 Amount openingAmount = node.getValue().getValue()[0];
622     Amount closingAmount = node.getValue().getValue()[1];
623 hirukawa_ryo 51 int sign = bsLayout.isSignReversed(node.getName()) ? -1 : 1;
624 hirukawa_ryo 22
625     //������������������������������������������������������������������������������������������������������������������������������������������������������������������
626 hirukawa_ryo 51 if(openingAmount == null && closingAmount == null && !bsLayout.isAlwaysShown(displayName)) {
627 hirukawa_ryo 22 continue;
628     }
629 hirukawa_ryo 28 //���������������������������������������������������������������������������������������������������������������������������
630 hirukawa_ryo 51 if((openingAmount == null || openingAmount.getValue() == 0)
631     && (closingAmount == null || closingAmount.getValue() == 0) && bsLayout.isHidden(displayName)) {
632 hirukawa_ryo 28 continue;
633     }
634 hirukawa_ryo 2 printData.add("\t\t\\box " + String.format("89.5 %.2f 35.5 %.2f", y, ROW_HEIGHT));
635     printData.add("\t\t\\align center left");
636     printData.add("\t\t\\text " + displayName);
637     printData.add("\t\t\\align center right");
638     if(openingAmount != null) {
639 hirukawa_ryo 42 printData.add("\t\t\\box " + String.format("123 %.2f %.2f %.2f", y, amountPrintWidth, ROW_HEIGHT));
640 hirukawa_ryo 38 printData.add("\t\t\\text " + formatMoney(sign * openingAmount.getValue()));
641 hirukawa_ryo 2 }
642     if(closingAmount != null) {
643 hirukawa_ryo 42 printData.add("\t\t\\box " + String.format("149 %.2f %.2f %.2f", y, amountPrintWidth, ROW_HEIGHT));
644 hirukawa_ryo 38 printData.add("\t\t\\text " + formatMoney(sign * closingAmount.getValue()));
645 hirukawa_ryo 2 }
646     y += ROW_HEIGHT;
647     }
648 hirukawa_ryo 52 //���������������������
649 hirukawa_ryo 2 y = (rows - equityList.size()) * ROW_HEIGHT;
650     printData.add("\t\\line " + String.format("87.7 %.2f -0 %.2f", y, y));
651     for(int i = 1; i < equityList.size(); i++) {
652 hirukawa_ryo 18 Node<Entry<List<AccountTitle>, Amount[]>> node = equityList.get(i);
653 hirukawa_ryo 2 String displayName = node.getName();
654 hirukawa_ryo 18 Amount openingAmount = node.getValue().getValue()[0];
655     Amount closingAmount = node.getValue().getValue()[1];
656 hirukawa_ryo 51 int sign = bsLayout.isSignReversed(node.getName()) ? -1 : 1;
657 hirukawa_ryo 39
658     // ���������������������������������������������������������������������������������������
659     if("������������".equals(node.getName()) || "������������������������".equals(node.getName())) {
660     printData.add("\t\t\\box " + String.format("123 %.2f 26 %.2f", y, ROW_HEIGHT));
661     printData.add("\t\t\\line-style thin dot");
662     printData.add("\t\t\\line -0 0.15 0 -0.15");
663     }
664 hirukawa_ryo 22 //������������������������������������������������������������������������������������������������������������������������������������������������������������������
665 hirukawa_ryo 51 if(openingAmount == null && closingAmount == null && !bsLayout.isAlwaysShown(displayName)) {
666 hirukawa_ryo 22 continue;
667     }
668 hirukawa_ryo 28 //���������������������������������������������������������������������������������������������������������������������������
669 hirukawa_ryo 51 if((openingAmount == null || openingAmount.getValue() == 0)
670     && (closingAmount == null || closingAmount.getValue() == 0) && bsLayout.isHidden(displayName)) {
671 hirukawa_ryo 28 continue;
672     }
673 hirukawa_ryo 2 printData.add("\t\t\\box " + String.format("89.5 %.2f 35.5 %.2f", y, ROW_HEIGHT));
674     printData.add("\t\t\\align center left");
675     printData.add("\t\t\\text " + displayName);
676     printData.add("\t\t\\align center right");
677     if(openingAmount != null) {
678 hirukawa_ryo 42 printData.add("\t\t\\box " + String.format("123 %.2f %.2f %.2f", y, amountPrintWidth, ROW_HEIGHT));
679 hirukawa_ryo 38 printData.add("\t\t\\text " + formatMoney(sign * openingAmount.getValue()));
680 hirukawa_ryo 2 }
681     if(closingAmount != null) {
682 hirukawa_ryo 42 printData.add("\t\t\\box " + String.format("149 %.2f %.2f %.2f", y, amountPrintWidth, ROW_HEIGHT));
683 hirukawa_ryo 38 printData.add("\t\t\\text " + formatMoney(sign * closingAmount.getValue()));
684 hirukawa_ryo 2 }
685     y += ROW_HEIGHT;
686     }
687    
688     //������
689     y = (rows - 1) * ROW_HEIGHT;
690     if(assetsList.size() > 0) {
691     //������(������)
692 hirukawa_ryo 18 Node<Entry<List<AccountTitle>, Amount[]>> node = assetsList.get(0);
693 hirukawa_ryo 2 String displayName = "������";
694 hirukawa_ryo 18 Amount openingAmount = node.getValue().getValue()[0];
695     Amount closingAmount = node.getValue().getValue()[1];
696 hirukawa_ryo 2 printData.add("\t\t\\font serif 10 bold");
697     printData.add("\t\t\\box " + String.format("2 %.2f 35.5 %.2f", y, ROW_HEIGHT));
698     printData.add("\t\t\\align center left");
699     printData.add("\t\t\\text " + displayName);
700     printData.add("\t\t\\align center right");
701 hirukawa_ryo 88 printData.add("\t\t\\box " + String.format("35.5 %.2f %.2f %.2f", y, amountPrintWidth, ROW_HEIGHT));
702     printData.add("\t\t\\text " + formatMoney(openingAmount != null ? openingAmount.getValue() : 0));
703     printData.add("\t\t\\box " + String.format("61.5 %.2f %.2f %.2f", y, amountPrintWidth, ROW_HEIGHT));
704     printData.add("\t\t\\text " + formatMoney(closingAmount != null ? closingAmount.getValue() : 0));
705 hirukawa_ryo 2 }
706     if(liabilitiesList.size() > 0 || equityList.size() > 0) {
707 hirukawa_ryo 52 //���������������������������
708 hirukawa_ryo 2 String displayName = "������";
709     int openingAmount = 0;
710     int closingAmount = 0;
711     if(liabilitiesList.size() > 0) {
712 hirukawa_ryo 18 Amount o = liabilitiesList.get(0).getValue().getValue()[0];
713 hirukawa_ryo 2 if(o != null) {
714     openingAmount += o.getValue();
715     }
716 hirukawa_ryo 18 Amount c = liabilitiesList.get(0).getValue().getValue()[1];
717 hirukawa_ryo 2 if(c != null) {
718     closingAmount += c.getValue();
719     }
720     }
721     if(equityList.size() > 0) {
722 hirukawa_ryo 18 Amount o = equityList.get(0).getValue().getValue()[0];
723 hirukawa_ryo 2 if(o != null) {
724     openingAmount += o.getValue();
725     }
726 hirukawa_ryo 18 Amount c = equityList.get(0).getValue().getValue()[1];
727 hirukawa_ryo 2 if(c != null) {
728     closingAmount += c.getValue();
729     }
730     }
731     printData.add("\t\t\\font serif 10 bold");
732     printData.add("\t\t\\box " + String.format("89.5 %.2f 35.5 %.2f", y, ROW_HEIGHT));
733     printData.add("\t\t\\align center left");
734     printData.add("\t\t\\text " + displayName);
735     printData.add("\t\t\\align center right");
736 hirukawa_ryo 42 printData.add("\t\t\\box " + String.format("123 %.2f %.2f %.2f", y, amountPrintWidth, ROW_HEIGHT));
737 hirukawa_ryo 2 printData.add("\t\t\\text " + formatMoney(openingAmount));
738 hirukawa_ryo 42 printData.add("\t\t\\box " + String.format("149 %.2f %.2f %.2f", y, amountPrintWidth, ROW_HEIGHT));
739 hirukawa_ryo 2 printData.add("\t\t\\text " + formatMoney(closingAmount));
740     }
741     }
742    
743 hirukawa_ryo 61 public void setFontLoader(FontLoader fontLoader) {
744     this.fontLoader = fontLoader;
745     }
746    
747 hirukawa_ryo 62 public void setBindingMarginEnabled(boolean enabled) {
748     this.bindingMarginEnabled = enabled;
749     }
750    
751 hirukawa_ryo 50 public void writeTo(Path path) throws IOException {
752 hirukawa_ryo 2 prepare();
753 hirukawa_ryo 27
754 hirukawa_ryo 61 PdfBrewer brewer;
755     if(fontLoader != null) {
756     brewer = new PdfBrewer(fontLoader);
757     } else {
758     brewer = new PdfBrewer();
759     }
760 hirukawa_ryo 49 brewer.setCreator(Util.getPdfCreator());
761 hirukawa_ryo 27 BrewerData pb = new BrewerData(printData, brewer.getFontLoader());
762 hirukawa_ryo 2 brewer.setTitle("���������������");
763     brewer.process(pb);
764 hirukawa_ryo 50 brewer.save(path);
765 hirukawa_ryo 55 brewer.close();
766 hirukawa_ryo 2 }
767    
768 hirukawa_ryo 61 public void writeTo(OutputStream out) throws IOException {
769     prepare();
770    
771     PdfBrewer brewer;
772     if(fontLoader != null) {
773     brewer = new PdfBrewer(fontLoader);
774     } else {
775     brewer = new PdfBrewer();
776     }
777     brewer.setCreator(Util.getPdfCreator());
778     BrewerData pb = new BrewerData(printData, brewer.getFontLoader());
779     brewer.setTitle("���������������");
780     brewer.process(pb);
781     brewer.save(out);
782     brewer.close();
783     }
784    
785 hirukawa_ryo 71 /** ���������������������������������������������
786     * ���������������������JSON������������������������������������������
787     *
788     * @param path ������������������������������������������������������null���������������������������������������������������������������������
789     * @return ���������������������������YAML���������
790 hirukawa_ryo 2 * @throws IOException
791     */
792 hirukawa_ryo 84 public String createNextOpeningJournalEntries(List<AccountTitle> accountTitles, Path path) throws IOException {
793 hirukawa_ryo 42 List<Entry<AccountTitle, Amount>> debtors = new ArrayList<>();
794     long debtorsTotal = 0;
795     List<Entry<AccountTitle, Amount>> creditors = new ArrayList<>();
796     long creditorsTotal = 0;
797 hirukawa_ryo 2
798     StringBuilder sb = new StringBuilder();
799 hirukawa_ryo 67 String nextOpeningDate = null;
800     if(this.closingDate != null) {
801     nextOpeningDate = DateTimeFormatter.ISO_LOCAL_DATE.format(this.closingDate.plusDays(1));
802     }
803 hirukawa_ryo 36
804 hirukawa_ryo 17 if(isSoloProprietorship) {
805 hirukawa_ryo 52 //���������������������������������������������������������������������������������������������������������������������������������������������������������
806 hirukawa_ryo 17 //���������������������������������������������������������������������������������������������������������
807     //���������������������������������������������������������
808 hirukawa_ryo 84
809     List<Entry<AccountTitle, Amount>> list = new ArrayList<>(closingBalances.entrySet());
810     Collections.sort(list, (o1, o2) -> {
811     return accountTitles.indexOf(o1.getKey()) - accountTitles.indexOf(o2.getKey());
812     });
813 hirukawa_ryo 120 Entry<AccountTitle, Amount> reserved = null;
814 hirukawa_ryo 84 for(Entry<AccountTitle, Amount> e : list) {
815 hirukawa_ryo 17 AccountTitle accountTitle = e.getKey();
816     Amount amount = e.getValue();
817 hirukawa_ryo 90 // ��������������������������������������� ���������������������������
818     if(accountTitle.getDisplayName().equals("������������") || accountTitle.getDisplayName().equals("������������") || accountTitle.getDisplayName().equals("���������")) {
819 hirukawa_ryo 17 continue;
820 hirukawa_ryo 2 }
821 hirukawa_ryo 90 // ������������������������ ���������������������������
822     if(accountTitle.equals(AccountTitle.PRETAX_INCOME)) {
823     continue;
824     }
825 hirukawa_ryo 17 if(accountTitle.getType() == AccountType.Assets) {
826     if(amount.getValue() == 0) {
827 hirukawa_ryo 120 if(reserved == null) {
828     reserved = e;
829     }
830 hirukawa_ryo 17 continue;
831     } else if(amount.getValue() > 0) {
832     debtors.add(e);
833     debtorsTotal += amount.getValue();
834     } else {
835     creditors.add(e);
836     creditorsTotal -= amount.getValue();
837     }
838 hirukawa_ryo 90 } else if(accountTitle.getType() == AccountType.Liabilities || accountTitle.getType() == AccountType.Equity) {
839 hirukawa_ryo 17 if(amount.getValue() == 0) {
840 hirukawa_ryo 120 if(reserved == null) {
841     reserved = e;
842     }
843 hirukawa_ryo 17 continue;
844     } else if(amount.getValue() > 0) {
845     creditors.add(e);
846     creditorsTotal += amount.getValue();
847     } else {
848     debtors.add(e);
849     debtorsTotal -= amount.getValue();
850     }
851     }
852 hirukawa_ryo 2 }
853 hirukawa_ryo 90 AccountTitle capital = AccountTitle.getByDisplayName(new HashSet<>(accountTitles), "���������");
854 hirukawa_ryo 120 // ������������ 0 ������������������������������������������������������������������
855     // ��������������������������� 1���������������������������������������������������������������������������������������������
856     if(creditors.size() == 0 && debtors.size() == 0 && reserved != null && capital != null) {
857     Map.Entry<AccountTitle, Amount> e = Map.entry(capital, new Amount(Creditor.class, 0));
858     if(reserved.getKey().getType().getNormalBalance() == Debtor.class) {
859     debtors.add(reserved);
860     creditors.add(e);
861     } else {
862     debtors.add(e);
863     creditors.add(reserved);
864     }
865     } else if(capital != null) {
866     // ������������������������������������������������������������������
867 hirukawa_ryo 90 Map.Entry<AccountTitle, Amount> e = Map.entry(capital, new Amount(Creditor.class, (debtorsTotal - creditorsTotal)));
868     if(debtorsTotal >= creditorsTotal) {
869     creditors.add(e);
870     } else {
871     debtors.add(e);
872     }
873     }
874     if(debtors.size() > 0 && creditors.size() > 0) {
875 hirukawa_ryo 71 sb.append("- \"������\" : \"" + nextOpeningDate + "\"\r\n");
876     sb.append(" \"������\" : \"���������\"\r\n");
877     sb.append(" \"������\" : [ ");
878     for(int i = 0; i < debtors.size(); i++) {
879     AccountTitle accountTitle = debtors.get(i).getKey();
880     Amount amount = debtors.get(i).getValue();
881     sb.append("{ \"������������\" : \"" + YamlBeansUtil.escape(accountTitle.getDisplayName()) + "\", \"������\" : " + Math.abs(amount.getValue()) + " }");
882     if(i + 1 < debtors.size()) {
883     sb.append(", ");
884     }
885     }
886     sb.append(" ]\r\n");
887     sb.append(" \"������\" : [ ");
888     for(int i = 0; i < creditors.size(); i++) {
889     AccountTitle accountTitle = creditors.get(i).getKey();
890     Amount amount = creditors.get(i).getValue();
891     sb.append("{ \"������������\" : \"" + YamlBeansUtil.escape(accountTitle.getDisplayName()) + "\", \"������\" : " + Math.abs(amount.getValue()) + " }");
892     if(i + 1 < creditors.size()) {
893     sb.append(", ");
894     }
895     }
896     sb.append(" ]\r\n");
897     sb.append("\r\n");
898     }
899     } else {
900     //������������������������������������������������������������������������������
901 hirukawa_ryo 84 List<Entry<AccountTitle, Amount>> list = new ArrayList<>(closingBalances.entrySet());
902     Collections.sort(list, (o1, o2) -> {
903     return accountTitles.indexOf(o1.getKey()) - accountTitles.indexOf(o2.getKey());
904     });
905     for(Entry<AccountTitle, Amount> e : list) {
906 hirukawa_ryo 71 AccountTitle accountTitle = e.getKey();
907     Amount amount = e.getValue();
908     if(accountTitle.getType() == AccountType.Assets) {
909     if(amount.getValue() == 0) {
910     continue;
911     } else if(amount.getValue() > 0) {
912     debtors.add(e);
913     } else {
914     creditors.add(e);
915     }
916     } else if(accountTitle.getType() == AccountType.Liabilities || accountTitle.getType() == AccountType.Equity) {
917     if(amount.getValue() == 0) {
918     continue;
919     } else if(amount.getValue() > 0) {
920     creditors.add(e);
921     } else {
922     debtors.add(e);
923     }
924     }
925     }
926    
927     if(debtors.size() > 0 && creditors.size() > 0) {
928     sb.append("- \"������\" : \"" + nextOpeningDate + "\"\r\n");
929     sb.append(" \"������\" : \"������������\"\r\n");
930     sb.append(" \"������\" : [ ");
931     for(int i = 0; i < debtors.size(); i++) {
932     AccountTitle accountTitle = debtors.get(i).getKey();
933     Amount amount = debtors.get(i).getValue();
934     sb.append("{ \"������������\" : \"" + YamlBeansUtil.escape(accountTitle.getDisplayName()) + "\", \"������\" : " + Math.abs(amount.getValue()) + " }");
935     if(i + 1 < debtors.size()) {
936     sb.append(", ");
937     }
938     }
939     sb.append(" ]\r\n");
940     sb.append(" \"������\" : [ ");
941     for(int i = 0; i < creditors.size(); i++) {
942     AccountTitle accountTitle = creditors.get(i).getKey();
943     Amount amount = creditors.get(i).getValue();
944     sb.append("{ \"������������\" : \"" + YamlBeansUtil.escape(accountTitle.getDisplayName()) + "\", \"������\" : " + Math.abs(amount.getValue()) + " }");
945     if(i + 1 < creditors.size()) {
946     sb.append(", ");
947     }
948     }
949     sb.append(" ]\r\n");
950     sb.append("\r\n");
951     }
952     }
953    
954     //��������������������� ��� ���������������������������������������������������������������
955     // ������������������������������������������������������������������������������������������������������������������������isOpening���false���������������������
956     for(JournalEntry entry : journalEntries) {
957     if(entry.isClosing()) {
958     continue;
959     }
960     for(Creditor creditor : entry.getCreditors()) {
961     if(creditor.getAccountTitle().getDisplayName().equals("���������������������")) {
962     sb.append("- \"������\" : \"" + nextOpeningDate + "\"\r\n");
963     sb.append(" \"������\" : \"������������\"\r\n");
964     sb.append(" \"������\" : [ { \"������������\" : \"���������������������\", \"������\" : " + creditor.getAmount() + " } ]\r\n");
965     sb.append(" \"������\" : [ ");
966     for(int i = 0; i < entry.getDebtors().size(); i++) {
967     Debtor debtor = entry.getDebtors().get(i);
968     sb.append("{ \"������������\" : \"" + YamlBeansUtil.escape(debtor.getAccountTitle().getDisplayName()) + "\", \"������\": " + debtor.getAmount() + " }");
969     if(i + 1 < entry.getDebtors().size()) {
970     sb.append(", ");
971     }
972     }
973     sb.append(" ]\r\n");
974     sb.append("\r\n");
975     break;
976     }
977     }
978     for(Debtor debtor : entry.getDebtors()) {
979     if(debtor.getAccountTitle().getDisplayName().equals("���������������������")) {
980     sb.append("- \"������\" : \"" + nextOpeningDate + "\"\r\n");
981     sb.append(" \"������\" : \"������������\"\r\n");
982     sb.append(" \"������\" : [ ");
983     for(int i = 0; i < entry.getCreditors().size(); i++) {
984     Creditor creditor = entry.getCreditors().get(i);
985     sb.append("{ \"������������\" : \"" + YamlBeansUtil.escape(creditor.getAccountTitle().getDisplayName()) + "\", \"������\" : " + creditor.getAmount() + " }");
986     if(i + 1 < entry.getCreditors().size()) {
987     sb.append(", ");
988     }
989     }
990     sb.append(" ]\r\n");
991     sb.append("\r\n");
992     break;
993     }
994     }
995     }
996    
997    
998     String s = sb.toString();
999    
1000     if(path != null && Files.isDirectory(path.getParent())) {
1001     Path tmpFile = null;
1002     try {
1003     Path dir = path.getParent();
1004     // ���������������������������������������������������������������������������������������������������
1005     tmpFile = dir.resolve("������������������������.tmp");
1006 hirukawa_ryo 116 try {
1007     Files.writeString(tmpFile, s, StandardCharsets.UTF_8,
1008     StandardOpenOption.CREATE,
1009     StandardOpenOption.TRUNCATE_EXISTING,
1010     StandardOpenOption.WRITE,
1011     StandardOpenOption.SYNC);
1012     } catch(AccessDeniedException e) {
1013     Util.unsetDosAttributes(tmpFile);
1014     Files.writeString(tmpFile, s, StandardCharsets.UTF_8,
1015     StandardOpenOption.CREATE,
1016     StandardOpenOption.TRUNCATE_EXISTING,
1017     StandardOpenOption.WRITE,
1018     StandardOpenOption.SYNC);
1019     }
1020 hirukawa_ryo 71
1021 hirukawa_ryo 82 try {
1022 hirukawa_ryo 116 try {
1023     Files.move(tmpFile, path,
1024 hirukawa_ryo 118 StandardCopyOption.ATOMIC_MOVE,
1025     StandardCopyOption.REPLACE_EXISTING);
1026 hirukawa_ryo 116 } catch(AccessDeniedException e) {
1027     Util.unsetDosAttributes(tmpFile, path);
1028     Files.move(tmpFile, path,
1029 hirukawa_ryo 118 StandardCopyOption.ATOMIC_MOVE,
1030     StandardCopyOption.REPLACE_EXISTING);
1031 hirukawa_ryo 116 }
1032 hirukawa_ryo 82 } catch(AtomicMoveNotSupportedException e) {
1033     // ���������������������������������������������������������������������������������������������������������������
1034     // AtomicMoveNotSupportedException ���������������������������������������������������
1035     // AtomicMoveNotSupportedException ������������������������������ATOMIC_MOVE ���������������������������������
1036 hirukawa_ryo 116 try {
1037     Files.move(tmpFile, path,
1038     StandardCopyOption.REPLACE_EXISTING);
1039     } catch(AccessDeniedException e2) {
1040     Util.unsetDosAttributes(tmpFile, path);
1041     Files.move(tmpFile, path,
1042     StandardCopyOption.REPLACE_EXISTING);
1043     }
1044 hirukawa_ryo 82 }
1045 hirukawa_ryo 71 } finally {
1046     if(tmpFile != null) {
1047     try { Files.deleteIfExists(tmpFile); } catch(Exception ignore) {}
1048     }
1049     }
1050     }
1051    
1052     return s;
1053     }
1054    
1055     /** ������������������������������������������������������������
1056     * ���������������������������������������������������������������JSON���������������������������������������������
1057     * ���������������������CUI���������������������
1058     *
1059     * @param path ������������������������������������������������������null���������������������������������������������������������������������
1060     * @return ���������������������������������YAML���������
1061     * @throws IOException
1062     */
1063 hirukawa_ryo 84 public String createNextOpeningJournalEntriesCompat(List<AccountTitle> accountTitles, Path path) throws IOException {
1064 hirukawa_ryo 71 List<Entry<AccountTitle, Amount>> debtors = new ArrayList<>();
1065     long debtorsTotal = 0;
1066     List<Entry<AccountTitle, Amount>> creditors = new ArrayList<>();
1067     long creditorsTotal = 0;
1068    
1069     StringBuilder sb = new StringBuilder();
1070     String nextOpeningDate = null;
1071     if(this.closingDate != null) {
1072     nextOpeningDate = DateTimeFormatter.ISO_LOCAL_DATE.format(this.closingDate.plusDays(1));
1073     }
1074    
1075     if(isSoloProprietorship) {
1076     //���������������������������������������������������������������������������������������������������������������������������������������������������������
1077     //���������������������������������������������������������������������������������������������������������
1078     //���������������������������������������������������������
1079 hirukawa_ryo 84
1080     List<Entry<AccountTitle, Amount>> list = new ArrayList<>(closingBalances.entrySet());
1081     Collections.sort(list, (o1, o2) -> {
1082     return accountTitles.indexOf(o1.getKey()) - accountTitles.indexOf(o2.getKey());
1083     });
1084     for(Entry<AccountTitle, Amount> e : list) {
1085 hirukawa_ryo 71 AccountTitle accountTitle = e.getKey();
1086     Amount amount = e.getValue();
1087 hirukawa_ryo 90 // ��������������������������������������� ���������������������������
1088     if(accountTitle.getDisplayName().equals("������������") || accountTitle.getDisplayName().equals("������������") || accountTitle.getDisplayName().equals("���������")) {
1089 hirukawa_ryo 71 continue;
1090     }
1091 hirukawa_ryo 90 // ������������������������ ���������������������������
1092     if(accountTitle.equals(AccountTitle.PRETAX_INCOME)) {
1093     continue;
1094     }
1095 hirukawa_ryo 71 if(accountTitle.getType() == AccountType.Assets) {
1096     if(amount.getValue() == 0) {
1097     continue;
1098     } else if(amount.getValue() > 0) {
1099     debtors.add(e);
1100     debtorsTotal += amount.getValue();
1101     } else {
1102     creditors.add(e);
1103     creditorsTotal -= amount.getValue();
1104     }
1105 hirukawa_ryo 90 } else if(accountTitle.getType() == AccountType.Liabilities || accountTitle.getType() == AccountType.Equity) {
1106 hirukawa_ryo 71 if(amount.getValue() == 0) {
1107     continue;
1108     } else if(amount.getValue() > 0) {
1109     creditors.add(e);
1110     creditorsTotal += amount.getValue();
1111     } else {
1112     debtors.add(e);
1113     debtorsTotal -= amount.getValue();
1114     }
1115     }
1116     }
1117 hirukawa_ryo 90 AccountTitle capital = AccountTitle.getByDisplayName(new HashSet<>(accountTitles), "���������");
1118     if(capital != null) {
1119     Map.Entry<AccountTitle, Amount> e = Map.entry(capital, new Amount(Creditor.class, (debtorsTotal - creditorsTotal)));
1120     if(debtorsTotal >= creditorsTotal) {
1121     creditors.add(e);
1122     } else {
1123     debtors.add(e);
1124     }
1125     }
1126     if(debtors.size() > 0 && creditors.size() > 0) {
1127 hirukawa_ryo 36 sb.append("- ������: " + nextOpeningDate + "\r\n");
1128 hirukawa_ryo 17 sb.append(" ������: ���������\r\n");
1129     sb.append(" ������: [ ");
1130     for(int i = 0; i < debtors.size(); i++) {
1131     AccountTitle accountTitle = debtors.get(i).getKey();
1132     Amount amount = debtors.get(i).getValue();
1133     sb.append("{������������: " + accountTitle.getDisplayName() + ", ������: " + Math.abs(amount.getValue()) + "}");
1134     if(i + 1 < debtors.size()) {
1135     sb.append(", ");
1136     }
1137 hirukawa_ryo 2 }
1138 hirukawa_ryo 17 sb.append(" ]\r\n");
1139     sb.append(" ������: [ ");
1140     for(int i = 0; i < creditors.size(); i++) {
1141     AccountTitle accountTitle = creditors.get(i).getKey();
1142     Amount amount = creditors.get(i).getValue();
1143     sb.append("{������������: " + accountTitle.getDisplayName() + ", ������: " + Math.abs(amount.getValue()) + "}");
1144     if(i + 1 < creditors.size()) {
1145     sb.append(", ");
1146     }
1147     }
1148     sb.append(" ]\r\n");
1149     sb.append("\r\n");
1150     }
1151     } else {
1152     //������������������������������������������������������������������������������
1153 hirukawa_ryo 84 List<Entry<AccountTitle, Amount>> list = new ArrayList<>(closingBalances.entrySet());
1154     Collections.sort(list, (o1, o2) -> {
1155     return accountTitles.indexOf(o1.getKey()) - accountTitles.indexOf(o2.getKey());
1156     });
1157     for(Entry<AccountTitle, Amount> e : list) {
1158 hirukawa_ryo 17 AccountTitle accountTitle = e.getKey();
1159     Amount amount = e.getValue();
1160     if(accountTitle.getType() == AccountType.Assets) {
1161     if(amount.getValue() == 0) {
1162     continue;
1163     } else if(amount.getValue() > 0) {
1164     debtors.add(e);
1165     } else {
1166     creditors.add(e);
1167     }
1168 hirukawa_ryo 52 } else if(accountTitle.getType() == AccountType.Liabilities || accountTitle.getType() == AccountType.Equity) {
1169 hirukawa_ryo 17 if(amount.getValue() == 0) {
1170     continue;
1171     } else if(amount.getValue() > 0) {
1172     creditors.add(e);
1173     } else {
1174     debtors.add(e);
1175     }
1176     }
1177     }
1178 hirukawa_ryo 71
1179 hirukawa_ryo 17 if(debtors.size() > 0 && creditors.size() > 0) {
1180 hirukawa_ryo 36 sb.append("- ������: " + nextOpeningDate + "\r\n");
1181 hirukawa_ryo 17 sb.append(" ������: ������������\r\n");
1182     sb.append(" ������: [ ");
1183     for(int i = 0; i < debtors.size(); i++) {
1184     AccountTitle accountTitle = debtors.get(i).getKey();
1185     Amount amount = debtors.get(i).getValue();
1186     sb.append("{������������: " + accountTitle.getDisplayName() + ", ������: " + Math.abs(amount.getValue()) + "}");
1187     if(i + 1 < debtors.size()) {
1188     sb.append(", ");
1189     }
1190     }
1191     sb.append(" ]\r\n");
1192     sb.append(" ������: [ ");
1193     for(int i = 0; i < creditors.size(); i++) {
1194     AccountTitle accountTitle = creditors.get(i).getKey();
1195     Amount amount = creditors.get(i).getValue();
1196     sb.append("{������������: " + accountTitle.getDisplayName() + ", ������: " + Math.abs(amount.getValue()) + "}");
1197     if(i + 1 < creditors.size()) {
1198     sb.append(", ");
1199     }
1200     }
1201     sb.append(" ]\r\n");
1202     sb.append("\r\n");
1203     }
1204 hirukawa_ryo 2 }
1205 hirukawa_ryo 71
1206 hirukawa_ryo 2 //��������������������� ��� ���������������������������������������������������������������
1207 hirukawa_ryo 68 // ������������������������������������������������������������������������������������������������������������������������isOpening���false���������������������
1208 hirukawa_ryo 2 for(JournalEntry entry : journalEntries) {
1209     if(entry.isClosing()) {
1210     continue;
1211     }
1212     for(Creditor creditor : entry.getCreditors()) {
1213     if(creditor.getAccountTitle().getDisplayName().equals("���������������������")) {
1214 hirukawa_ryo 36 sb.append("- ������: " + nextOpeningDate + "\r\n");
1215 hirukawa_ryo 68 sb.append(" ������: ������������\r\n");
1216 hirukawa_ryo 2 sb.append(" ������: [ {������������: ���������������������, ������: " + creditor.getAmount() + "} ]\r\n");
1217     sb.append(" ������: [ ");
1218     for(int i = 0; i < entry.getDebtors().size(); i++) {
1219     Debtor debtor = entry.getDebtors().get(i);
1220     sb.append("{������������: " + debtor.getAccountTitle().getDisplayName() + ", ������: " + debtor.getAmount() + "}");
1221     if(i + 1 < entry.getDebtors().size()) {
1222     sb.append(", ");
1223     }
1224     }
1225     sb.append(" ]\r\n");
1226     sb.append("\r\n");
1227     break;
1228     }
1229     }
1230     for(Debtor debtor : entry.getDebtors()) {
1231     if(debtor.getAccountTitle().getDisplayName().equals("���������������������")) {
1232 hirukawa_ryo 36 sb.append("- ������: " + nextOpeningDate + "\r\n");
1233 hirukawa_ryo 68 sb.append(" ������: ������������\r\n");
1234 hirukawa_ryo 2 sb.append(" ������: [ ");
1235     for(int i = 0; i < entry.getCreditors().size(); i++) {
1236     Creditor creditor = entry.getCreditors().get(i);
1237     sb.append("{������������: " + creditor.getAccountTitle().getDisplayName() + ", ������: " + creditor.getAmount() + "}");
1238     if(i + 1 < entry.getCreditors().size()) {
1239     sb.append(", ");
1240     }
1241     }
1242     sb.append(" ]\r\n");
1243     sb.append("\r\n");
1244     break;
1245     }
1246     }
1247     }
1248 hirukawa_ryo 71
1249    
1250 hirukawa_ryo 2 String s = sb.toString();
1251 hirukawa_ryo 71
1252 hirukawa_ryo 67 if(path != null && Files.isDirectory(path.getParent())) {
1253     Path tmpFile = null;
1254     try {
1255     Path dir = path.getParent();
1256     // ���������������������������������������������������������������������������������������������������
1257     tmpFile = dir.resolve("������������������������.tmp");
1258 hirukawa_ryo 116 try {
1259     Files.writeString(tmpFile, s, StandardCharsets.UTF_8,
1260     StandardOpenOption.CREATE,
1261     StandardOpenOption.TRUNCATE_EXISTING,
1262     StandardOpenOption.WRITE,
1263     StandardOpenOption.SYNC);
1264     } catch(AccessDeniedException e) {
1265     Util.unsetDosAttributes(tmpFile);
1266     Files.writeString(tmpFile, s, StandardCharsets.UTF_8,
1267     StandardOpenOption.CREATE,
1268     StandardOpenOption.TRUNCATE_EXISTING,
1269     StandardOpenOption.WRITE,
1270     StandardOpenOption.SYNC);
1271     }
1272 hirukawa_ryo 67
1273 hirukawa_ryo 82 try {
1274 hirukawa_ryo 116 try {
1275     Files.move(tmpFile, path,
1276 hirukawa_ryo 118 StandardCopyOption.ATOMIC_MOVE,
1277     StandardCopyOption.REPLACE_EXISTING);
1278 hirukawa_ryo 116 } catch(AccessDeniedException e) {
1279     Util.unsetDosAttributes(tmpFile, path);
1280     Files.move(tmpFile, path,
1281 hirukawa_ryo 118 StandardCopyOption.ATOMIC_MOVE,
1282     StandardCopyOption.REPLACE_EXISTING);
1283 hirukawa_ryo 116 }
1284 hirukawa_ryo 82 } catch(AtomicMoveNotSupportedException e) {
1285     // ���������������������������������������������������������������������������������������������������������������
1286     // AtomicMoveNotSupportedException ���������������������������������������������������
1287     // AtomicMoveNotSupportedException ������������������������������ATOMIC_MOVE ���������������������������������
1288 hirukawa_ryo 116 try {
1289     Files.move(tmpFile, path,
1290     StandardCopyOption.REPLACE_EXISTING);
1291     } catch(AccessDeniedException e2) {
1292     Util.unsetDosAttributes(tmpFile, path);
1293     Files.move(tmpFile, path,
1294     StandardCopyOption.REPLACE_EXISTING);
1295     }
1296 hirukawa_ryo 82 }
1297 hirukawa_ryo 67 } finally {
1298     if(tmpFile != null) {
1299     try { Files.deleteIfExists(tmpFile); } catch(Exception ignore) {}
1300     }
1301 hirukawa_ryo 50 }
1302 hirukawa_ryo 2 }
1303 hirukawa_ryo 71
1304 hirukawa_ryo 2 return s;
1305     }
1306 hirukawa_ryo 71
1307 hirukawa_ryo 42 private static String formatMoney(long amount) {
1308 hirukawa_ryo 2 if(MINUS_SIGN != null && amount < 0) {
1309 hirukawa_ryo 42 return MINUS_SIGN + String.format("%,d", -amount);
1310 hirukawa_ryo 2 }
1311     return String.format("%,d", amount);
1312     }
1313    
1314 hirukawa_ryo 18 private void dump(Node<Entry<List<AccountTitle>, Amount[]>> node) {
1315 hirukawa_ryo 2 StringBuilder sb = new StringBuilder();
1316     for(int i = 0; i < node.getLevel(); i++) {
1317     sb.append(" - ");
1318     }
1319     sb.append(node.getName());
1320 hirukawa_ryo 18 Amount[] amounts = node.getValue().getValue();
1321 hirukawa_ryo 2 sb.append("{ " + amounts[0] + ", " + amounts[1] + " } ");
1322 hirukawa_ryo 18 if(node.getValue().getKey() != null) {
1323 hirukawa_ryo 2 sb.append(": [");
1324 hirukawa_ryo 18 for(int i = 0; i < node.getValue().getKey().size(); i++) {
1325     sb.append(node.getValue().getKey().get(i).getDisplayName());
1326     if(i + 1 < node.getValue().getKey().size()) {
1327 hirukawa_ryo 2 sb.append(", ");
1328     }
1329     }
1330     sb.append("]");
1331     }
1332     System.out.println(sb.toString());
1333 hirukawa_ryo 18 for(Node<Entry<List<AccountTitle>, Amount[]>> child : node.getChildren()) {
1334 hirukawa_ryo 2 dump(child);
1335     }
1336     }
1337     }

Back to OSDN">Back to OSDN
ViewVC Help
Powered by ViewVC 1.1.26