Skip to content

Commit

Permalink
initial commit
Browse files Browse the repository at this point in the history
  • Loading branch information
mariodavid committed Aug 12, 2020
0 parents commit d2ca234
Show file tree
Hide file tree
Showing 305 changed files with 11,163 additions and 0 deletions.
12 changes: 12 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
.gradle
.studio
*.ipr
*.iml
*.iws
*/build/*
*/deploy/*
*/modules/*/build/*
out
test-run
*.DS_Store
.idea
30 changes: 30 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
# CUBA Petclinic Product Customizations

<p align="center">
<img src="https://github.com/cuba-platform/cuba-petclinic/blob/master/img/petclinic_logo_with_slogan.svg"/>
</p>

This example shows how to use CUBA's application components in order to build customizations to the Petclinic product on a customer-by-customer basis.

### Repository Structure

#### Petclinic Core
The [petclinic-core](/petclinic-core) directory contains the regular CUBA Petclinic project. In order to act as an application component the [app-component.xml](/petclinic-core/modules/global/src/com/haulmont/sample/petclinic/app-component.xml) has been created (via CUBA studio).

#### Lancaster Petclinic

The [lancaster-petclinic](/lancaster-petclinic) project is a CUBA application, that uses the Petclinic as a basis. It contains some customizations, that are described in the [README](/lancaster-petclinic/README.md) of the project.

The way it uses the petclinic-core is by adding it as a application-component in the [build.gradle](/lancaster-petclinic/build.gradle#L39).



#### Rocky Mount Petclinic

The [rocky-mount-petclinic](/rocky-mount-petclinic) project is a CUBA application, that uses the Petclinic as a basis. It contains some customizations, that are described in the [README](/rocky-mount-petclinic/README.md) of the project.

The way it uses the petclinic-core is by adding it as a application-component in the [build.gradle](/rocky-mount/build.gradle#L37).

### Running Locally

In order to run the different applications locally, the petclinic-core project has to be installed into the local Maven repository. This can be achieved via running the shell script `./install-petclinic-core.sh`. Alternatively the petclinic-core project can be opened in CUBA Studio and installed from there via the Main Menu: `CUBA > Advanced > Install App Component`.
11 changes: 11 additions & 0 deletions alabastia-petclinic/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
.gradle
.studio
*.ipr
*.iml
*.iws
build/*
deploy/*
modules/*/build/*
.idea/*
out
test-run
200 changes: 200 additions & 0 deletions alabastia-petclinic/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,200 @@
### Alabastia Petclinic

The Alabastia Petclinic application is a tailored Petclinic towards the Alabastia Petclinic Inc.
which needs some adjustments over the standard Petclinic product.

In particular the following adjustments have been made:

### Functional Adjustments

#### Visit Creation

* a visit needs to be assigned to a treatment room
* the treatment room should be set to the default treatment room, that is assigned to the current user

#### Visit Management

* Visit Calendars default view is monthly, not weekly

#### Workflow Adjustments

* at the Alabastia Petclinic there is a dedicated reception which deals with the process of onboarding new Owners and Pets

### Technical Adjustments

#### Data Model

In order to support those business requirements the data model has been adjusted accordingly:

* an entity `TreatmentRoom` has been added to model the rooms that are available within the Petclinic.
* an entity `DefaultTreatmentRoom` links a User to a Treatment Room

##### Visit Entity extension
The Visit entity has been extended to store a link to the Treatment Room:

```java
@Extends(Visit.class)
@Entity(name = "alabastiapetclinic_AlabastiaVisit")
@DiscriminatorValue("AlabastiaVisit")
public class AlabastiaVisit extends Visit {

private static final long serialVersionUID = 430933193584847493L;

@Lookup(type = LookupType.DROPDOWN, actions = {})
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "TREATMENT_ROOM_ID")
private TreatmentRoom treatmentRoom;

public TreatmentRoom getTreatmentRoom() {
return treatmentRoom;
}

public void setTreatmentRoom(TreatmentRoom treatmentRoom) {
this.treatmentRoom = treatmentRoom;
}
}
```

#### Screen Extensions

the Visit Editor screen has been extend to place the `treatmentRoom` lookup field inside the form component:

```xml
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<window xmlns="http://schemas.haulmont.com/cuba/screen/window.xsd"
messagesPack="com.alabastia.petclinic.web.screens.visit"
xmlns:ext="http://schemas.haulmont.com/cuba/window-ext.xsd"
extends="com/haulmont/sample/petclinic/web/screens/visit/visit-edit.xml">
<data>
<collection id="treatmentRoomsDc" class="com.alabastia.petclinic.entity.TreatmentRoom"
view="_minimal">
<loader>
<query>
<![CDATA[select e from alabastiapetclinic_TreatmentRoom e]]>
</query>
</loader>
</collection>
</data>
<layout>
<form id="fieldGroup">
<column id="column2">
<lookupField ext:index="2" id="treatmentRoomField" property="treatmentRoom"
optionsContainer="treatmentRoomsDc"/>
</column>
</form>
</layout>
</window>
```

The lookup field is placed at the correct position within the form via the `ext:index="2"` XML attribute.

#### Security Extensions

In order to give the users access to the new Entities and screens, the design time roles have been extended in this project:

```java

@Role(name = NurseRole.NAME)
public class AlabastiaNurseRole extends NurseRole {

@EntityAccess(entityClass = Visit.class, operations = {EntityOp.CREATE, EntityOp.READ, EntityOp.UPDATE, EntityOp.DELETE})
// ...

@EntityAccess(entityClass = TreatmentRoom.class, operations = {EntityOp.READ})
@EntityAccess(entityClass = DefaultTreatmentRoom.class, operations = {EntityOp.READ})
@Override
public EntityPermissionsContainer entityPermissions() {
return super.entityPermissions();
}


@EntityAttributeAccess(entityClass = Owner.class, modify = "*")
// ...

@EntityAttributeAccess(entityClass = TreatmentRoom.class, view = "*")
@EntityAttributeAccess(entityClass = DefaultTreatmentRoom.class, view = "*")
@Override
public EntityAttributePermissionsContainer entityAttributePermissions() {
return super.entityAttributePermissions();
}


@ScreenAccess(screenIds = {
"petclinic_myVisits",
// ...
"petclinic_Specialty.edit",

"application-alabastiapetclinic",
"alabastiapetclinic_DefaultTreatmentRoom.browse",
"alabastiapetclinic_DefaultTreatmentRoom.edit",
"alabastiapetclinic_TreatmentRoom.browse",
"alabastiapetclinic_TreatmentRoom.edit"
})
@Override
public ScreenPermissionsContainer screenPermissions() {
return super.screenPermissions();
}

}
```


Instead of Nurses at Alabastia there is a new Role `Receptionist` that is responsible for managing Pets and Owners:

```java
package com.alabastia.petclinic.core.role;

import com.haulmont.cuba.security.app.role.AnnotatedRoleDefinition;
import com.haulmont.cuba.security.app.role.annotation.EntityAccess;
import com.haulmont.cuba.security.app.role.annotation.EntityAttributeAccess;
import com.haulmont.cuba.security.app.role.annotation.Role;
import com.haulmont.cuba.security.app.role.annotation.ScreenAccess;
import com.haulmont.cuba.security.entity.EntityOp;
import com.haulmont.cuba.security.entity.User;
import com.haulmont.cuba.security.role.EntityAttributePermissionsContainer;
import com.haulmont.cuba.security.role.EntityPermissionsContainer;
import com.haulmont.cuba.security.role.ScreenPermissionsContainer;
import com.haulmont.sample.petclinic.entity.owner.Owner;
import com.haulmont.sample.petclinic.entity.pet.Pet;
import com.haulmont.sample.petclinic.entity.pet.PetType;
import com.haulmont.sample.petclinic.entity.veterinarian.Specialty;
import com.haulmont.sample.petclinic.entity.veterinarian.Veterinarian;
import com.haulmont.sample.petclinic.entity.visit.Visit;
import com.alabastia.petclinic.entity.DefaultTreatmentRoom;
import com.alabastia.petclinic.entity.TreatmentRoom;

@Role(name = ReceptionistRole.NAME)
public class ReceptionistRole extends AnnotatedRoleDefinition {

public final static String NAME = "Receptionist";

@EntityAccess(entityClass = Pet.class, operations = {EntityOp.CREATE, EntityOp.READ, EntityOp.UPDATE, EntityOp.DELETE})
@EntityAccess(entityClass = Owner.class, operations = {EntityOp.CREATE, EntityOp.READ, EntityOp.UPDATE, EntityOp.DELETE})
@Override
public EntityPermissionsContainer entityPermissions() {
return super.entityPermissions();
}


@EntityAttributeAccess(entityClass = Owner.class, modify = "*")
@EntityAttributeAccess(entityClass = Pet.class, modify = "*")
@EntityAttributeAccess(entityClass = User.class, view = "*")
@Override
public EntityAttributePermissionsContainer entityAttributePermissions() {
return super.entityAttributePermissions();
}


@ScreenAccess(screenIds = {
"petclinic_Pet.browse",
"petclinic_Pet.edit",
"petclinic_Owner.browse",
"petclinic_Owner.edit"
})
@Override
public ScreenPermissionsContainer screenPermissions() {
return super.screenPermissions();
}

}
```
Loading

0 comments on commit d2ca234

Please sign in to comment.