1 /*
2 * *************************************************************************************************************************************************************
3 *
4 * blueHour: open source accounting
5 * http://tidalwave.it/projects/bluehour
6 *
7 * Copyright (C) 2013 - 2024 by Tidalwave s.a.s. (http://tidalwave.it)
8 *
9 * *************************************************************************************************************************************************************
10 *
11 * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License.
12 * You may obtain a copy of the License at
13 *
14 * http://www.apache.org/licenses/LICENSE-2.0
15 *
16 * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
17 * CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
18 *
19 * *************************************************************************************************************************************************************
20 *
21 * git clone https://bitbucket.org/tidalwave/bluehour-src
22 * git clone https://github.com/tidalwave-it/bluehour-src
23 *
24 * *************************************************************************************************************************************************************
25 */
26 package it.tidalwave.accounting.model;
27
28 import javax.annotation.Nonnull;
29 import javax.annotation.concurrent.Immutable;
30 import java.time.LocalDate;
31 import java.util.List;
32 import it.tidalwave.accounting.model.spi.ObjectFactory;
33 import it.tidalwave.accounting.model.types.Money;
34 import it.tidalwave.util.As;
35 import it.tidalwave.util.Finder;
36 import it.tidalwave.util.Id;
37 import it.tidalwave.role.Identifiable;
38 import lombok.AllArgsConstructor;
39 import lombok.Getter;
40 import lombok.ToString;
41 import lombok.With;
42
43 /***************************************************************************************************************************************************************
44 *
45 * @author Fabrizio Giudici
46 *
47 **************************************************************************************************************************************************************/
48 @Immutable
49 public interface Invoice extends Identifiable, As
50 {
51 /***********************************************************************************************************************************************************
52 *
53 **********************************************************************************************************************************************************/
54 @AllArgsConstructor// FIXME (access = PRIVATE)
55 @Immutable @With @Getter @ToString
56 public static class Builder
57 {
58 public static interface Callback // Lombok @With doesn't support builder subclasses
59 {
60 public void register (@Nonnull final Invoice invoice);
61
62 public static final Callback DEFAULT = (invoice) -> {};
63 }
64
65 private final Id id;
66 private final String number;
67 private final Project project;
68 private final List<? extends JobEvent> jobEvents; // FIXME: immutablelist
69 private final LocalDate date;
70 private final LocalDate dueDate;
71 private final Money earnings;
72 private final Money tax;
73 private final Callback callback;
74
75 public Builder()
76 {
77 this(Callback.DEFAULT);
78 }
79
80 public Builder (@Nonnull final Callback callback)
81 {
82 this(new Id(""), "", null, null, null, null, Money.ZERO, Money.ZERO, callback);
83 }
84
85 @Nonnull
86 public Builder with (@Nonnull final Builder builder)
87 {
88 return builder.withCallback(callback);
89 }
90
91 @Nonnull
92 public Invoice create()
93 {
94 // TODO
95 // if (!jobEvents.stream().allMatch(jobEvent -> jobEvent.getProject() == project))
96 // {
97 // // FIXME: better diagnostics
98 // throw new IllegalArgumentException("Illegal project for jobEvent");
99 // }
100
101 final var invoice = ObjectFactory.getInstance().createInvoice(this);
102 callback.register(invoice);
103 return invoice;
104 }
105 }
106
107 /***********************************************************************************************************************************************************
108 * Creates a finder for job events.
109 *
110 * @return the finder
111 **********************************************************************************************************************************************************/
112 @Nonnull
113 public Finder<JobEvent> findJobEvents();
114
115 /***********************************************************************************************************************************************************
116 * Returns a builder pre-populated with all the attributes.
117 *
118 * @return the builder
119 **********************************************************************************************************************************************************/
120 @Nonnull
121 public Builder toBuilder();
122 }