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.Collections; 32 import java.util.List; 33 import it.tidalwave.accounting.model.ProjectRegistry.JobEventFinder; 34 import it.tidalwave.accounting.model.spi.ObjectFactory; 35 import it.tidalwave.accounting.model.types.Money; 36 import it.tidalwave.util.As; 37 import it.tidalwave.util.Id; 38 import it.tidalwave.role.Identifiable; 39 import it.tidalwave.role.SimpleComposite; 40 import lombok.AllArgsConstructor; 41 import lombok.Getter; 42 import lombok.ToString; 43 import lombok.With; 44 45 /*************************************************************************************************************************************************************** 46 * 47 * This class models a project. 48 * 49 * @author Fabrizio Giudici 50 * 51 **************************************************************************************************************************************************************/ 52 @Immutable 53 public interface Project extends SimpleComposite<JobEvent>, Identifiable, As 54 { 55 public enum Status { OPEN, CLOSED } 56 57 /*********************************************************************************************************************************************************** 58 * 59 **********************************************************************************************************************************************************/ 60 @AllArgsConstructor // FIXME (access = PROTECTED) 61 @Immutable @With @Getter @ToString 62 public static class Builder 63 { 64 public static interface Callback // Lombok @With doesn't support builder subclasses 65 { 66 public void register (@Nonnull final Project project); 67 68 public static final Callback DEFAULT = (project) -> {}; 69 } 70 71 private final Id id; 72 private final Customer customer; 73 private final String name; 74 private final String number; 75 private final String description; 76 private final String notes; 77 private final Status status; 78 private final Money hourlyRate; 79 private final Money budget; 80 private final LocalDate startDate; 81 private final LocalDate endDate; 82 private final List<? extends JobEvent> events; // FIXME: immutable 83 private final Callback callback; 84 85 public Builder() 86 { 87 this(Callback.DEFAULT); 88 } 89 90 public Builder (@Nonnull final Callback callback) 91 { 92 // FIXME: avoid null 93 this(new Id(""), null, "", "", "", "", Status.OPEN, Money.ZERO, Money.ZERO, null, null, 94 Collections.emptyList(), callback); 95 } 96 97 @Nonnull 98 public Builder with (@Nonnull final Builder builder) 99 { 100 return builder.withCallback(callback); 101 } 102 103 @Nonnull 104 public Project create() 105 { 106 final var project = ObjectFactory.getInstance().createProject(this); 107 callback.register(project); 108 return project; 109 } 110 } 111 112 /*********************************************************************************************************************************************************** 113 * 114 **********************************************************************************************************************************************************/ 115 @Nonnull 116 public static Project.Builder builder() 117 { 118 return new Project.Builder(); 119 } 120 121 /*********************************************************************************************************************************************************** 122 * 123 **********************************************************************************************************************************************************/ 124 @Nonnull 125 public Customer getCustomer(); 126 127 /*********************************************************************************************************************************************************** 128 * {@inheritDoc} 129 **********************************************************************************************************************************************************/ 130 @Nonnull 131 public JobEventFinder findChildren(); 132 133 /*********************************************************************************************************************************************************** 134 * Returns a builder pre-populated with all the attributes. 135 * 136 * @return the builder 137 **********************************************************************************************************************************************************/ 138 @Nonnull 139 public Builder toBuilder(); 140 }