Palmira: Additional models and endpoints
@1cgiar/palmira is requesting additional models and CRUD API endpoints to enhance existing GGCE schema.
Please add the following entities to org.gringlobal.model.community
package:
-
Location
represents a physical place (the original nameCONTAINER
is easily confused with material container (Alu pack, Glass jar)).Location#parentLocation
allows to organize places into a highly dynamic tree structure. -
LocationData
allows for attaching user-defined attributes (originally namedCONTAINER_DATA
) -
LocationReservation
keeps track of "bookings" at one location (proposed name wasSTORAGE_CONTAINER_MAP
)
/**
* Location represents a physical place at a {@link Site}: buildings - rooms - racks, fields, greenhouses, etc.
*
* Locations are organized into a tree structure where
* each location with <code>parentLocation == null</code> starts a new tree at the {#link Site}.
*
* Location may declare its {@link #capacity} and {@link #capacityUnitCode}, specifying
* its total available area/volume/length/duration.
*/
class Location extends CooperatorOwnedModel implements SelfCleaning {
@ManyToOne(required = false)
private Location parentLocation; // Locations have a hierarchical structure
@NotNull @ManyToOne(required = true)
private Site site; // Needs index
@NotNull @SimpleString
private String locationNumberPart1;
private Long locationNumberPart2;
@SimpleString
private String locationNumberPart3;
@NotNull @CodeValueField("LOCATION_TYPE")
private String locationTypeCode;
@ManyToOne(required=false)
private Geography geography;
@NotNull
private String barcode; // in @PrePersist use UUID.randomUUID().toString() if blank
@Min(0)
private int capacity = 0; // The capacity of this location, may be 0
@CodeValueField("UNIT_OF_CAPACITY")
private String capacityUnitCode; // If capacity != 0 then it must be provided
}
/**
* LocationData allows for attaching user-defined attributes to each {#link Location}.
*/
class LocationData extends CooperatorOwnedModel implements SelfCleaning {
private Location location;
@NotNull @CodeValueField("LOCATION_PROPERTY")
private String locationPropertyCode;
@NotNull
private String value;
}
/**
* Actions are performed on {@link Location}s.
*/
class LocationAction extends AbstractAction<LocationAction> {
// No extra fields for now
@Override
@CodeValueField("LOCATION_ACTION")
public String getActionNameCode() {
return this.actionNameCode;
}
}
/**
* Describes a reservation of capacity at a {@link Location} for the specified
* time frame (start and end date). A reservation is PENDING if the start date is
* in the future, it is ACTIVE if `startDate < now < endDate`
*/
class LocationReservation extends CooperatorOwnedModel implements SelfCleaning {
@NotNull @ManyToOne(required = true)
private Location location;
@NotNull @ManyToOne(required = false)
private Inventory inventory; // Does not require an inventory to reserve a location
@NotNull @Column(name = "start_date") @Temporal(TemporalType.DATE)
protected LocalDate startDate; // inclusive
@NotNull @Column(name = "end_date") @Temporal(TemporalType.DATE)
protected LocalDate endDate; // inclusive, must be greater or equal to startDate!
@IgnoreField
@Formula("datediff( day, start_date, end_date )") // FIXME or datediff() + 1?
private Integer reservedDays; // calculated field
@Min(1)
private int size; // The amount of reserved capacity at Location expressed in Location's capacityUnitCode
@Min(0)
private int offset = 0; // The offset is used to indicate where at the Location's capacity the space is reserved
}
We will need LocationFilter
and LocationReservationFilter
. Use sensible filtering options, we'll update later on demand.
Please add the following services:
LocationServiceImpl extends FilteredCRUDService<Location> implements LocationService {
protected static class ActionSupport extends BaseActionSupport<> {...
class LocationDataService extends CRUDService<LocationData> {...
}
LocationReservationServiceImpl extends FilteredCRUDService<Location> implements LocationService {
...
}
Add the basic controllers: LocationController extends CRUDController
at /location
and LocationReservationController
at /location/reservation
.
Note to self: These POJOs are based on several teleconferences around the excel file Prueba_escritorio_contenedores.xlsx.