[REPO REFACTOR]: changed to a better git repository structure with branches

This commit is contained in:
2025-10-31 03:32:24 +01:00
parent ad689049d5
commit 8360c7e8e0
212 changed files with 15955 additions and 0 deletions

1
microservices/huertos/.gitignore vendored Normal file
View File

@@ -0,0 +1 @@
/target/

View File

@@ -0,0 +1,55 @@
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>net.miarma.api</groupId>
<artifactId>huertos</artifactId>
<version>1.2.0</version>
<properties>
<maven.compiler.source>23</maven.compiler.source>
<maven.compiler.target>23</maven.compiler.target>
</properties>
<repositories>
<repository>
<id>MiarmaGit</id>
<url>https://git.miarma.net/api/packages/Gallardo7761/maven</url>
</repository>
</repositories>
<dependencies>
<dependency>
<groupId>net.miarma.api</groupId>
<artifactId>backlib</artifactId>
<version>1.2.0</version>
</dependency>
</dependencies>
<build>
<finalName>ME-Huertos</finalName>
<plugins>
<!-- Maven Shade Plugin -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>3.5.3</version>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
<configuration>
<createDependencyReducedPom>false</createDependencyReducedPom>
<transformers>
<transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
<mainClass>net.miarma.api.microservices.huertos.HuertosMainVerticle</mainClass>
</transformer>
</transformers>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>

View File

@@ -0,0 +1,133 @@
package net.miarma.api.microservices.huertos.dao;
import io.vertx.core.Future;
import io.vertx.core.Promise;
import io.vertx.sqlclient.Pool;
import net.miarma.api.backlib.db.DataAccessObject;
import net.miarma.api.backlib.db.DatabaseManager;
import net.miarma.api.backlib.db.QueryBuilder;
import net.miarma.api.backlib.http.QueryFilters;
import net.miarma.api.backlib.http.QueryParams;
import net.miarma.api.microservices.huertos.entities.AnnouncementEntity;
import java.util.List;
import java.util.Map;
public class AnnouncementDAO implements DataAccessObject<AnnouncementEntity, Integer> {
private final DatabaseManager db;
public AnnouncementDAO(Pool pool) {
this.db = DatabaseManager.getInstance(pool);
}
@Override
public Future<List<AnnouncementEntity>> getAll() {
return getAll(new QueryParams(Map.of(), new QueryFilters()));
}
@Override
public Future<AnnouncementEntity> getById(Integer id) {
Promise<AnnouncementEntity> promise = Promise.promise();
String query = QueryBuilder
.select(AnnouncementEntity.class)
.where(Map.of("announce_id", id.toString()))
.build();
db.executeOne(query, AnnouncementEntity.class,
promise::complete,
promise::fail
);
return promise.future();
}
public Future<List<AnnouncementEntity>> getAll(QueryParams params) {
Promise<List<AnnouncementEntity>> promise = Promise.promise();
String query = QueryBuilder
.select(AnnouncementEntity.class)
.where(params.getFilters())
.orderBy(params.getQueryFilters().getSort(), params.getQueryFilters().getOrder())
.limit(params.getQueryFilters().getLimit())
.offset(params.getQueryFilters().getOffset())
.build();
db.execute(query, AnnouncementEntity.class,
list -> promise.complete(list.isEmpty() ? List.of() : list),
promise::fail
);
return promise.future();
}
@Override
public Future<AnnouncementEntity> insert(AnnouncementEntity announce) {
Promise<AnnouncementEntity> promise = Promise.promise();
String query = QueryBuilder.insert(announce).build();
db.execute(query, AnnouncementEntity.class,
list -> promise.complete(list.isEmpty() ? null : list.getFirst()),
promise::fail
);
return promise.future();
}
@Override
public Future<AnnouncementEntity> upsert(AnnouncementEntity announcementEntity, String... conflictKeys) {
Promise<AnnouncementEntity> promise = Promise.promise();
String query = QueryBuilder.upsert(announcementEntity, conflictKeys).build();
db.executeOne(query, AnnouncementEntity.class,
promise::complete,
promise::fail
);
return promise.future();
}
@Override
public Future<AnnouncementEntity> update(AnnouncementEntity announce) {
Promise<AnnouncementEntity> promise = Promise.promise();
String query = QueryBuilder.update(announce).build();
db.executeOne(query, AnnouncementEntity.class,
promise::complete,
promise::fail
);
return promise.future();
}
@Override
public Future<Boolean> delete(Integer id) {
Promise<Boolean> promise = Promise.promise();
AnnouncementEntity announce = new AnnouncementEntity();
announce.setAnnounce_id(id);
String query = QueryBuilder.delete(announce).build();
db.executeOne(query, AnnouncementEntity.class,
result -> promise.complete(result != null),
promise::fail
);
return promise.future();
}
@Override
public Future<Boolean> exists(Integer id) {
Promise<Boolean> promise = Promise.promise();
String query = QueryBuilder
.select(AnnouncementEntity.class)
.where(Map.of("announce_id", id.toString()))
.build();
db.executeOne(query, AnnouncementEntity.class,
result -> promise.complete(result != null),
promise::fail
);
return promise.future();
}
}

View File

@@ -0,0 +1,134 @@
package net.miarma.api.microservices.huertos.dao;
import io.vertx.core.Future;
import io.vertx.core.Promise;
import io.vertx.sqlclient.Pool;
import net.miarma.api.backlib.db.DataAccessObject;
import net.miarma.api.backlib.db.DatabaseManager;
import net.miarma.api.backlib.db.QueryBuilder;
import net.miarma.api.microservices.huertos.entities.BalanceEntity;
import net.miarma.api.microservices.huertos.entities.ViewBalanceWithTotals;
import java.util.List;
import java.util.Map;
public class BalanceDAO implements DataAccessObject<BalanceEntity, Integer> {
private final DatabaseManager db;
public BalanceDAO(Pool pool) {
this.db = DatabaseManager.getInstance(pool);
}
@Override
public Future<List<BalanceEntity>> getAll() {
Promise<List<BalanceEntity>> promise = Promise.promise();
String query = QueryBuilder.select(BalanceEntity.class).build();
db.execute(query, BalanceEntity.class,
list -> promise.complete(list.isEmpty() ? List.of() : list),
promise::fail
);
return promise.future();
}
@Override
public Future<BalanceEntity> getById(Integer id) {
Promise<BalanceEntity> promise = Promise.promise();
String query = QueryBuilder
.select(BalanceEntity.class)
.where(Map.of("id", id.toString()))
.build();
db.executeOne(query, BalanceEntity.class,
promise::complete,
promise::fail
);
return promise.future();
}
public Future<List<ViewBalanceWithTotals>> getAllWithTotals() {
Promise<List<ViewBalanceWithTotals>> promise = Promise.promise();
String query = QueryBuilder.select(ViewBalanceWithTotals.class).build();
db.execute(query, ViewBalanceWithTotals.class,
list -> promise.complete(list.isEmpty() ? List.of() : list),
promise::fail
);
return promise.future();
}
@Override
public Future<BalanceEntity> insert(BalanceEntity balance) {
Promise<BalanceEntity> promise = Promise.promise();
String query = QueryBuilder.insert(balance).build();
db.execute(query, BalanceEntity.class,
list -> promise.complete(list.isEmpty() ? null : list.getFirst()),
promise::fail
);
return promise.future();
}
@Override
public Future<BalanceEntity> upsert(BalanceEntity balanceEntity, String... conflictKeys) {
Promise<BalanceEntity> promise = Promise.promise();
String query = QueryBuilder.upsert(balanceEntity, conflictKeys).build();
db.executeOne(query, BalanceEntity.class,
promise::complete,
promise::fail
);
return promise.future();
}
@Override
public Future<BalanceEntity> update(BalanceEntity balance) {
Promise<BalanceEntity> promise = Promise.promise();
String query = QueryBuilder.update(balance).build();
db.executeOne(query, BalanceEntity.class,
_ -> promise.complete(balance),
promise::fail
);
return promise.future();
}
@Override
public Future<Boolean> delete(Integer id) {
Promise<Boolean> promise = Promise.promise();
BalanceEntity balance = new BalanceEntity();
balance.setId(id);
String query = QueryBuilder.delete(balance).build();
db.executeOne(query, BalanceEntity.class,
result -> promise.complete(result != null),
promise::fail
);
return promise.future();
}
@Override
public Future<Boolean> exists(Integer id) {
Promise<Boolean> promise = Promise.promise();
String query = QueryBuilder
.select(BalanceEntity.class)
.where(Map.of("id", id.toString()))
.build();
db.executeOne(query, BalanceEntity.class,
result -> promise.complete(result != null),
promise::fail
);
return promise.future();
}
}

View File

@@ -0,0 +1,133 @@
package net.miarma.api.microservices.huertos.dao;
import io.vertx.core.Future;
import io.vertx.core.Promise;
import io.vertx.sqlclient.Pool;
import net.miarma.api.backlib.db.DataAccessObject;
import net.miarma.api.backlib.db.DatabaseManager;
import net.miarma.api.backlib.db.QueryBuilder;
import net.miarma.api.backlib.http.QueryFilters;
import net.miarma.api.backlib.http.QueryParams;
import net.miarma.api.microservices.huertos.entities.ExpenseEntity;
import java.util.List;
import java.util.Map;
public class ExpenseDAO implements DataAccessObject<ExpenseEntity, Integer> {
private final DatabaseManager db;
public ExpenseDAO(Pool pool) {
this.db = DatabaseManager.getInstance(pool);
}
@Override
public Future<List<ExpenseEntity>> getAll() {
return getAll(new QueryParams(Map.of(), new QueryFilters()));
}
@Override
public Future<ExpenseEntity> getById(Integer id) {
Promise<ExpenseEntity> promise = Promise.promise();
String query = QueryBuilder
.select(ExpenseEntity.class)
.where(Map.of("expense_id", id.toString()))
.build();
db.executeOne(query, ExpenseEntity.class,
promise::complete,
promise::fail
);
return promise.future();
}
public Future<List<ExpenseEntity>> getAll(QueryParams params) {
Promise<List<ExpenseEntity>> promise = Promise.promise();
String query = QueryBuilder
.select(ExpenseEntity.class)
.where(params.getFilters())
.orderBy(params.getQueryFilters().getSort(), params.getQueryFilters().getOrder())
.limit(params.getQueryFilters().getLimit())
.offset(params.getQueryFilters().getOffset())
.build();
db.execute(query, ExpenseEntity.class,
list -> promise.complete(list.isEmpty() ? List.of() : list),
promise::fail
);
return promise.future();
}
@Override
public Future<ExpenseEntity> insert(ExpenseEntity expense) {
Promise<ExpenseEntity> promise = Promise.promise();
String query = QueryBuilder.insert(expense).build();
db.execute(query, ExpenseEntity.class,
list -> promise.complete(list.isEmpty() ? null : list.getFirst()),
promise::fail
);
return promise.future();
}
@Override
public Future<ExpenseEntity> upsert(ExpenseEntity expenseEntity, String... conflictKeys) {
Promise<ExpenseEntity> promise = Promise.promise();
String query = QueryBuilder.upsert(expenseEntity, conflictKeys).build();
db.executeOne(query, ExpenseEntity.class,
promise::complete,
promise::fail
);
return promise.future();
}
@Override
public Future<ExpenseEntity> update(ExpenseEntity expense) {
Promise<ExpenseEntity> promise = Promise.promise();
String query = QueryBuilder.update(expense).build();
db.executeOne(query, ExpenseEntity.class,
_ -> promise.complete(expense),
promise::fail
);
return promise.future();
}
@Override
public Future<Boolean> delete(Integer id) {
Promise<Boolean> promise = Promise.promise();
ExpenseEntity expense = new ExpenseEntity();
expense.setExpense_id(id);
String query = QueryBuilder.delete(expense).build();
db.executeOne(query, ExpenseEntity.class,
result -> promise.complete(result != null),
promise::fail
);
return promise.future();
}
@Override
public Future<Boolean> exists(Integer id) {
Promise<Boolean> promise = Promise.promise();
String query = QueryBuilder
.select(ExpenseEntity.class)
.where(Map.of("expense_id", id.toString()))
.build();
db.executeOne(query, ExpenseEntity.class,
result -> promise.complete(result != null),
promise::fail
);
return promise.future();
}
}

View File

@@ -0,0 +1,171 @@
package net.miarma.api.microservices.huertos.dao;
import io.vertx.core.Future;
import io.vertx.core.Promise;
import io.vertx.sqlclient.Pool;
import net.miarma.api.backlib.db.DataAccessObject;
import net.miarma.api.backlib.db.DatabaseManager;
import net.miarma.api.backlib.db.QueryBuilder;
import net.miarma.api.backlib.http.QueryFilters;
import net.miarma.api.backlib.http.QueryParams;
import net.miarma.api.microservices.huertos.entities.IncomeEntity;
import net.miarma.api.microservices.huertos.entities.ViewIncomesWithFullNames;
import java.util.List;
import java.util.Map;
public class IncomeDAO implements DataAccessObject<IncomeEntity, Integer> {
private final DatabaseManager db;
public IncomeDAO(Pool pool) {
this.db = DatabaseManager.getInstance(pool);
}
@Override
public Future<List<IncomeEntity>> getAll() {
return getAll(new QueryParams(Map.of(), new QueryFilters()));
}
@Override
public Future<IncomeEntity> getById(Integer id) {
Promise<IncomeEntity> promise = Promise.promise();
String query = QueryBuilder
.select(IncomeEntity.class)
.where(Map.of("income_id", id.toString()))
.build();
db.executeOne(query, IncomeEntity.class,
promise::complete,
promise::fail
);
return promise.future();
}
public Future<List<IncomeEntity>> getAll(QueryParams params) {
Promise<List<IncomeEntity>> promise = Promise.promise();
String query = QueryBuilder
.select(IncomeEntity.class)
.where(params.getFilters())
.orderBy(params.getQueryFilters().getSort(), params.getQueryFilters().getOrder())
.limit(params.getQueryFilters().getLimit())
.offset(params.getQueryFilters().getOffset())
.build();
db.execute(query, IncomeEntity.class,
list -> promise.complete(list.isEmpty() ? List.of() : list),
promise::fail
);
return promise.future();
}
public Future<List<ViewIncomesWithFullNames>> getAllWithNames() {
return getAllWithNames(new QueryParams(Map.of(), new QueryFilters()));
}
public Future<List<ViewIncomesWithFullNames>> getAllWithNames(QueryParams params) {
Promise<List<ViewIncomesWithFullNames>> promise = Promise.promise();
String query = QueryBuilder
.select(ViewIncomesWithFullNames.class)
.where(params.getFilters())
.orderBy(params.getQueryFilters().getSort(), params.getQueryFilters().getOrder())
.limit(params.getQueryFilters().getLimit())
.offset(params.getQueryFilters().getOffset())
.build();
db.execute(query, ViewIncomesWithFullNames.class,
list -> promise.complete(list.isEmpty() ? List.of() : list),
promise::fail
);
return promise.future();
}
public Future<List<IncomeEntity>> getUserIncomes(Integer memberNumber) {
Promise<List<IncomeEntity>> promise = Promise.promise();
String query = QueryBuilder
.select(IncomeEntity.class)
.where(Map.of("member_number", memberNumber.toString()))
.build();
db.execute(query, IncomeEntity.class,
list -> promise.complete(list.isEmpty() ? List.of() : list),
promise::fail
);
return promise.future();
}
@Override
public Future<IncomeEntity> insert(IncomeEntity income) {
Promise<IncomeEntity> promise = Promise.promise();
String query = QueryBuilder.insert(income).build();
db.execute(query, IncomeEntity.class,
list -> promise.complete(list.isEmpty() ? null : list.getFirst()),
promise::fail
);
return promise.future();
}
@Override
public Future<IncomeEntity> upsert(IncomeEntity incomeEntity, String... conflictKeys) {
Promise<IncomeEntity> promise = Promise.promise();
String query = QueryBuilder.upsert(incomeEntity, conflictKeys).build();
db.executeOne(query, IncomeEntity.class,
promise::complete,
promise::fail
);
return promise.future();
}
@Override
public Future<IncomeEntity> update(IncomeEntity income) {
Promise<IncomeEntity> promise = Promise.promise();
String query = QueryBuilder.update(income).build();
db.executeOne(query, IncomeEntity.class,
_ -> promise.complete(income),
promise::fail
);
return promise.future();
}
@Override
public Future<Boolean> delete(Integer id) {
Promise<Boolean> promise = Promise.promise();
IncomeEntity income = new IncomeEntity();
income.setIncome_id(id);
String query = QueryBuilder.delete(income).build();
db.executeOne(query, IncomeEntity.class,
result -> promise.complete(result != null),
promise::fail
);
return promise.future();
}
@Override
public Future<Boolean> exists(Integer id) {
Promise<Boolean> promise = Promise.promise();
String query = QueryBuilder
.select(IncomeEntity.class)
.where(Map.of("income_id", id.toString()))
.build();
db.executeOne(query, IncomeEntity.class,
result -> promise.complete(result != null),
promise::fail
);
return promise.future();
}
}

View File

@@ -0,0 +1,235 @@
package net.miarma.api.microservices.huertos.dao;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import io.vertx.core.Future;
import io.vertx.core.Promise;
import io.vertx.sqlclient.Pool;
import net.miarma.api.backlib.Constants;
import net.miarma.api.backlib.db.DataAccessObject;
import net.miarma.api.backlib.db.DatabaseManager;
import net.miarma.api.backlib.db.QueryBuilder;
import net.miarma.api.backlib.http.QueryFilters;
import net.miarma.api.backlib.http.QueryParams;
import net.miarma.api.microservices.huertos.entities.MemberEntity;
public class MemberDAO implements DataAccessObject<MemberEntity, Integer> {
private final DatabaseManager db;
public MemberDAO(Pool pool) {
this.db = DatabaseManager.getInstance(pool);
}
@Override
public Future<List<MemberEntity>> getAll() {
return getAll(new QueryParams(Map.of(), new QueryFilters()));
}
@Override
public Future<MemberEntity> getById(Integer id) {
Promise<MemberEntity> promise = Promise.promise();
String query = QueryBuilder
.select(MemberEntity.class)
.where(Map.of("user_id", id.toString()))
.build();
db.executeOne(query, MemberEntity.class,
promise::complete,
promise::fail
);
return promise.future();
}
public Future<List<MemberEntity>> getAll(QueryParams params) {
Promise<List<MemberEntity>> promise = Promise.promise();
String query = QueryBuilder
.select(MemberEntity.class)
.where(params.getFilters())
.orderBy(params.getQueryFilters().getSort(), params.getQueryFilters().getOrder())
.limit(params.getQueryFilters().getLimit())
.offset(params.getQueryFilters().getOffset())
.build();
db.execute(query, MemberEntity.class,
list -> promise.complete(list.isEmpty() ? List.of() : list),
promise::fail
);
return promise.future();
}
public Future<MemberEntity> getByMemberNumber(Integer memberNumber) {
Promise<MemberEntity> promise = Promise.promise();
String query = QueryBuilder
.select(MemberEntity.class)
.where(Map.of("member_number", memberNumber.toString()))
.build();
db.executeOne(query, MemberEntity.class,
promise::complete,
promise::fail
);
return promise.future();
}
public Future<MemberEntity> getByPlotNumber(Integer plotNumber) {
Promise<MemberEntity> promise = Promise.promise();
String query = QueryBuilder
.select(MemberEntity.class)
.where(Map.of("plot_number", plotNumber.toString()))
.build();
db.executeOne(query, MemberEntity.class,
promise::complete,
promise::fail
);
return promise.future();
}
public Future<MemberEntity> getByEmail(String email) {
Promise<MemberEntity> promise = Promise.promise();
String query = QueryBuilder
.select(MemberEntity.class)
.where(Map.of("email", email))
.build();
db.executeOne(query, MemberEntity.class,
promise::complete,
promise::fail
);
return promise.future();
}
public Future<MemberEntity> getByDni(String dni) {
Promise<MemberEntity> promise = Promise.promise();
String query = QueryBuilder
.select(MemberEntity.class)
.where(Map.of("dni", dni))
.build();
db.executeOne(query, MemberEntity.class,
promise::complete,
promise::fail
);
return promise.future();
}
public Future<MemberEntity> getByPhone(Integer phone) {
Promise<MemberEntity> promise = Promise.promise();
String query = QueryBuilder
.select(MemberEntity.class)
.where(Map.of("phone", phone.toString()))
.build();
db.executeOne(query, MemberEntity.class,
promise::complete,
promise::fail
);
return promise.future();
}
public Future<List<MemberEntity>> getWaitlist() {
Promise<List<MemberEntity>> promise = Promise.promise();
String query = QueryBuilder
.select(MemberEntity.class)
.where(Map.of("type", "0", "status", String.valueOf(Constants.HuertosUserStatus.ACTIVE.getValue())))
.build();
db.execute(query, MemberEntity.class,
list -> promise.complete(list.isEmpty() ? List.of() : list),
promise::fail
);
return promise.future();
}
public Future<Integer> getLastMemberNumber() {
Promise<Integer> promise = Promise.promise();
String query = QueryBuilder
.select(MemberEntity.class, "member_number")
.orderBy(Optional.of("member_number"), Optional.of("DESC"))
.limit(Optional.of(1))
.build();
db.executeOne(query, MemberEntity.class,
result -> promise.complete(result != null ? result.getMember_number() : 0),
promise::fail
);
return promise.future();
}
public Future<Boolean> hasCollaborator(Integer plotNumber) {
Promise<Boolean> promise = Promise.promise();
String query = QueryBuilder
.select(MemberEntity.class)
.where(Map.of("plot_number", plotNumber.toString(), "type", String.valueOf(Constants.HuertosUserType.COLLABORATOR.getValue())))
.build();
db.executeOne(query, MemberEntity.class,
result -> promise.complete(result != null),
promise::fail
);
return promise.future();
}
public Future<MemberEntity> getCollaborator(Integer plotNumber) {
Promise<MemberEntity> promise = Promise.promise();
String query = QueryBuilder
.select(MemberEntity.class)
.where(Map.of("plot_number", plotNumber.toString(), "type", String.valueOf(Constants.HuertosUserType.COLLABORATOR.getValue())))
.build();
db.executeOne(query, MemberEntity.class,
promise::complete,
promise::fail
);
return promise.future();
}
@Override
public Future<MemberEntity> insert(MemberEntity user) {
throw new UnsupportedOperationException("Insert not supported on view-based DAO");
}
@Override
public Future<MemberEntity> upsert(MemberEntity memberEntity, String... conflictKeys) {
throw new UnsupportedOperationException("Upsert not supported on view-based DAO");
}
@Override
public Future<MemberEntity> update(MemberEntity user) {
throw new UnsupportedOperationException("Update not supported on view-based DAO");
}
@Override
public Future<Boolean> delete(Integer id) {
throw new UnsupportedOperationException("Delete not supported on view-based DAO");
}
@Override
public Future<Boolean> exists(Integer id) {
Promise<Boolean> promise = Promise.promise();
String query = QueryBuilder
.select(MemberEntity.class)
.where(Map.of("user_id", id.toString()))
.build();
db.executeOne(query, MemberEntity.class,
result -> promise.complete(result != null),
promise::fail
);
return promise.future();
}
}

View File

@@ -0,0 +1,148 @@
package net.miarma.api.microservices.huertos.dao;
import io.vertx.core.Future;
import io.vertx.core.Promise;
import io.vertx.sqlclient.Pool;
import net.miarma.api.backlib.db.DataAccessObject;
import net.miarma.api.backlib.db.DatabaseManager;
import net.miarma.api.backlib.db.QueryBuilder;
import net.miarma.api.backlib.http.QueryFilters;
import net.miarma.api.backlib.http.QueryParams;
import net.miarma.api.microservices.huertos.entities.PreUserEntity;
import java.util.List;
import java.util.Map;
public class PreUserDAO implements DataAccessObject<PreUserEntity, Integer> {
private final DatabaseManager db;
public PreUserDAO(Pool pool) {
this.db = DatabaseManager.getInstance(pool);
}
@Override
public Future<List<PreUserEntity>> getAll() {
return getAll(new QueryParams(Map.of(), new QueryFilters()));
}
@Override
public Future<PreUserEntity> getById(Integer id) {
Promise<PreUserEntity> promise = Promise.promise();
String query = QueryBuilder
.select(PreUserEntity.class)
.where(Map.of("pre_user_id", id.toString()))
.build();
db.executeOne(query, PreUserEntity.class,
promise::complete,
promise::fail
);
return promise.future();
}
public Future<PreUserEntity> getByRequestId(Integer requestId) {
Promise<PreUserEntity> promise = Promise.promise();
String query = QueryBuilder
.select(PreUserEntity.class)
.where(Map.of("request_id", requestId.toString()))
.build();
db.executeOne(query, PreUserEntity.class,
promise::complete,
promise::fail
);
return promise.future();
}
public Future<List<PreUserEntity>> getAll(QueryParams params) {
Promise<List<PreUserEntity>> promise = Promise.promise();
String query = QueryBuilder
.select(PreUserEntity.class)
.where(params.getFilters())
.orderBy(params.getQueryFilters().getSort(), params.getQueryFilters().getOrder())
.limit(params.getQueryFilters().getLimit())
.offset(params.getQueryFilters().getOffset())
.build();
db.execute(query, PreUserEntity.class,
list -> promise.complete(list.isEmpty() ? List.of() : list),
promise::fail
);
return promise.future();
}
@Override
public Future<PreUserEntity> insert(PreUserEntity preUser) {
Promise<PreUserEntity> promise = Promise.promise();
String query = QueryBuilder.insert(preUser).build();
db.execute(query, PreUserEntity.class,
list -> promise.complete(list.isEmpty() ? null : list.getFirst()),
promise::fail
);
return promise.future();
}
@Override
public Future<PreUserEntity> upsert(PreUserEntity preUserEntity, String... conflictKeys) {
Promise<PreUserEntity> promise = Promise.promise();
String query = QueryBuilder.upsert(preUserEntity, conflictKeys).build();
db.execute(query, PreUserEntity.class,
list -> promise.complete(list.isEmpty() ? null : list.getFirst()),
promise::fail
);
return promise.future();
}
@Override
public Future<PreUserEntity> update(PreUserEntity preUser) {
Promise<PreUserEntity> promise = Promise.promise();
String query = QueryBuilder.update(preUser).build();
db.executeOne(query, PreUserEntity.class,
_ -> promise.complete(preUser),
promise::fail
);
return promise.future();
}
@Override
public Future<Boolean> delete(Integer id) {
Promise<Boolean> promise = Promise.promise();
PreUserEntity preUser = new PreUserEntity();
preUser.setPre_user_id(id);
String query = QueryBuilder.delete(preUser).build();
db.executeOne(query, PreUserEntity.class,
result -> promise.complete(result != null),
promise::fail
);
return promise.future();
}
@Override
public Future<Boolean> exists(Integer id) {
Promise<Boolean> promise = Promise.promise();
String query = QueryBuilder
.select(PreUserEntity.class)
.where(Map.of("pre_user_id", id.toString()))
.build();
db.execute(query, PreUserEntity.class,
list -> promise.complete(!list.isEmpty()),
promise::fail
);
return promise.future();
}
}

View File

@@ -0,0 +1,176 @@
package net.miarma.api.microservices.huertos.dao;
import io.vertx.core.Future;
import io.vertx.core.Promise;
import io.vertx.sqlclient.Pool;
import net.miarma.api.backlib.db.DataAccessObject;
import net.miarma.api.backlib.db.DatabaseManager;
import net.miarma.api.backlib.db.QueryBuilder;
import net.miarma.api.backlib.http.QueryFilters;
import net.miarma.api.backlib.http.QueryParams;
import net.miarma.api.microservices.huertos.entities.RequestEntity;
import net.miarma.api.microservices.huertos.entities.ViewRequestsWithPreUsers;
import java.util.List;
import java.util.Map;
public class RequestDAO implements DataAccessObject<RequestEntity, Integer> {
private final DatabaseManager db;
public RequestDAO(Pool pool) {
this.db = DatabaseManager.getInstance(pool);
}
@Override
public Future<List<RequestEntity>> getAll() {
return getAll(new QueryParams(Map.of(), new QueryFilters()));
}
@Override
public Future<RequestEntity> getById(Integer id) {
Promise<RequestEntity> promise = Promise.promise();
String query = QueryBuilder
.select(RequestEntity.class)
.where(Map.of("request_id", id.toString()))
.build();
db.executeOne(query, RequestEntity.class,
promise::complete,
promise::fail
);
return promise.future();
}
public Future<List<RequestEntity>> getAll(QueryParams params) {
Promise<List<RequestEntity>> promise = Promise.promise();
String query = QueryBuilder
.select(RequestEntity.class)
.where(params.getFilters())
.orderBy(params.getQueryFilters().getSort(), params.getQueryFilters().getOrder())
.limit(params.getQueryFilters().getLimit())
.offset(params.getQueryFilters().getOffset())
.build();
db.execute(query, RequestEntity.class,
list -> promise.complete(list.isEmpty() ? List.of() : list),
promise::fail
);
return promise.future();
}
public Future<List<ViewRequestsWithPreUsers>> getRequestsWithPreUsers() {
Promise<List<ViewRequestsWithPreUsers>> promise = Promise.promise();
String query = QueryBuilder
.select(ViewRequestsWithPreUsers.class)
.build();
db.execute(query, ViewRequestsWithPreUsers.class,
list -> promise.complete(list.isEmpty() ? List.of() : list),
promise::fail
);
return promise.future();
}
public Future<ViewRequestsWithPreUsers> getRequestWithPreUserById(Integer id) {
Promise<ViewRequestsWithPreUsers> promise = Promise.promise();
String query = QueryBuilder
.select(ViewRequestsWithPreUsers.class)
.where(Map.of("request_id", id.toString()))
.build();
db.executeOne(query, ViewRequestsWithPreUsers.class,
promise::complete,
promise::fail
);
return promise.future();
}
public Future<List<RequestEntity>> getByUserId(Integer userId) {
Promise<List<RequestEntity>> promise = Promise.promise();
String query = QueryBuilder
.select(RequestEntity.class)
.where(Map.of("requested_by", userId.toString()))
.build();
db.execute(query, RequestEntity.class,
list -> promise.complete(list.isEmpty() ? List.of() : list),
promise::fail
);
return promise.future();
}
@Override
public Future<RequestEntity> insert(RequestEntity request) {
Promise<RequestEntity> promise = Promise.promise();
String query = QueryBuilder.insert(request).build();
db.execute(query, RequestEntity.class,
list -> promise.complete(list.isEmpty() ? null : list.getFirst()),
promise::fail
);
return promise.future();
}
@Override
public Future<RequestEntity> upsert(RequestEntity requestEntity, String... conflictKeys) {
Promise<RequestEntity> promise = Promise.promise();
String query = QueryBuilder.upsert(requestEntity, conflictKeys).build();
db.executeOne(query, RequestEntity.class,
promise::complete,
promise::fail
);
return promise.future();
}
@Override
public Future<RequestEntity> update(RequestEntity request) {
Promise<RequestEntity> promise = Promise.promise();
String query = QueryBuilder.update(request).build();
db.executeOne(query, RequestEntity.class,
_ -> promise.complete(request),
promise::fail
);
return promise.future();
}
@Override
public Future<Boolean> delete(Integer id) {
Promise<Boolean> promise = Promise.promise();
RequestEntity request = new RequestEntity();
request.setRequest_id(id);
String query = QueryBuilder.delete(request).build();
db.executeOne(query, RequestEntity.class,
result -> promise.complete(result != null),
promise::fail
);
return promise.future();
}
@Override
public Future<Boolean> exists(Integer id) {
Promise<Boolean> promise = Promise.promise();
String query = QueryBuilder
.select(RequestEntity.class)
.where(Map.of("request_id", id.toString()))
.build();
db.executeOne(query, RequestEntity.class,
result -> promise.complete(result != null),
promise::fail
);
return promise.future();
}
}

View File

@@ -0,0 +1,146 @@
package net.miarma.api.microservices.huertos.dao;
import io.vertx.core.Future;
import io.vertx.core.Promise;
import io.vertx.sqlclient.Pool;
import net.miarma.api.backlib.db.DataAccessObject;
import net.miarma.api.backlib.db.DatabaseManager;
import net.miarma.api.backlib.db.QueryBuilder;
import net.miarma.api.backlib.http.QueryFilters;
import net.miarma.api.backlib.http.QueryParams;
import net.miarma.api.microservices.huertos.entities.UserMetadataEntity;
import java.util.List;
import java.util.Map;
public class UserMetadataDAO implements DataAccessObject<UserMetadataEntity, Integer> {
private final DatabaseManager db;
public UserMetadataDAO(Pool pool) {
this.db = DatabaseManager.getInstance(pool);
}
@Override
public Future<List<UserMetadataEntity>> getAll() {
return getAll(new QueryParams(Map.of(), new QueryFilters()));
}
@Override
public Future<UserMetadataEntity> getById(Integer id) {
Promise<UserMetadataEntity> promise = Promise.promise();
String query = QueryBuilder
.select(UserMetadataEntity.class)
.where(Map.of("user_id", id.toString()))
.build();
db.executeOne(query, UserMetadataEntity.class,
promise::complete,
promise::fail
);
return promise.future();
}
public Future<List<UserMetadataEntity>> getAll(QueryParams params) {
Promise<List<UserMetadataEntity>> promise = Promise.promise();
String query = QueryBuilder
.select(UserMetadataEntity.class)
.where(params.getFilters())
.orderBy(params.getQueryFilters().getSort(), params.getQueryFilters().getOrder())
.limit(params.getQueryFilters().getLimit())
.offset(params.getQueryFilters().getOffset())
.build();
db.execute(query, UserMetadataEntity.class,
list -> promise.complete(list.isEmpty() ? List.of() : list),
promise::fail
);
return promise.future();
}
@Override
public Future<UserMetadataEntity> insert(UserMetadataEntity user) {
Promise<UserMetadataEntity> promise = Promise.promise();
String query = QueryBuilder.insert(user).build();
db.executeOne(query, UserMetadataEntity.class,
promise::complete,
promise::fail
);
return promise.future();
}
@Override
public Future<UserMetadataEntity> upsert(UserMetadataEntity userMetadataEntity, String... conflictKeys) {
Promise<UserMetadataEntity> promise = Promise.promise();
String query = QueryBuilder.upsert(userMetadataEntity, conflictKeys).build();
db.executeOne(query, UserMetadataEntity.class,
promise::complete,
promise::fail
);
return promise.future();
}
@Override
public Future<UserMetadataEntity> update(UserMetadataEntity user) {
Promise<UserMetadataEntity> promise = Promise.promise();
String query = QueryBuilder.update(user).build();
db.executeOne(query, UserMetadataEntity.class,
_ -> promise.complete(user),
promise::fail
);
return promise.future();
}
public Future<UserMetadataEntity> updateWithNulls(UserMetadataEntity user) {
Promise<UserMetadataEntity> promise = Promise.promise();
String query = QueryBuilder.updateWithNulls(user).build();
db.executeOne(query, UserMetadataEntity.class,
_ -> promise.complete(user),
promise::fail
);
return promise.future();
}
@Override
public Future<Boolean> delete(Integer id) {
Promise<Boolean> promise = Promise.promise();
UserMetadataEntity user = new UserMetadataEntity();
user.setUser_id(id);
String query = QueryBuilder.delete(user).build();
db.executeOne(query, UserMetadataEntity.class,
result -> promise.complete(result != null),
promise::fail
);
return promise.future();
}
@Override
public Future<Boolean> exists(Integer id) {
Promise<Boolean> promise = Promise.promise();
String query = QueryBuilder
.select(UserMetadataEntity.class)
.where(Map.of("user_id", id.toString()))
.build();
db.executeOne(query, UserMetadataEntity.class,
result -> promise.complete(result != null),
promise::fail
);
return promise.future();
}
}

View File

@@ -0,0 +1,58 @@
package net.miarma.api.microservices.huertos.entities;
import io.vertx.sqlclient.Row;
import net.miarma.api.backlib.Constants.HuertosAnnouncePriority;
import net.miarma.api.backlib.annotations.Table;
import net.miarma.api.backlib.db.AbstractEntity;
import java.time.LocalDateTime;
@Table("huertos_announces")
public class AnnouncementEntity extends AbstractEntity {
private Integer announce_id;
private String body;
private HuertosAnnouncePriority priority;
private Integer published_by;
private LocalDateTime created_at;
public AnnouncementEntity() {
super();
}
public AnnouncementEntity(Row row) {
super(row);
}
public Integer getAnnounce_id() {
return announce_id;
}
public void setAnnounce_id(Integer announce_id) {
this.announce_id = announce_id;
}
public String getBody() {
return body;
}
public void setBody(String body) {
this.body = body;
}
public HuertosAnnouncePriority getPriority() {
return priority;
}
public void setPriority(HuertosAnnouncePriority priority) {
this.priority = priority;
}
public Integer getPublished_by() {
return published_by;
}
public void setPublished_by(Integer published_by) {
this.published_by = published_by;
}
public LocalDateTime getCreated_at() {
return created_at;
}
public void setCreated_at(LocalDateTime created_at) {
this.created_at = created_at;
}
}

View File

@@ -0,0 +1,51 @@
package net.miarma.api.microservices.huertos.entities;
import io.vertx.sqlclient.Row;
import net.miarma.api.backlib.annotations.Table;
import net.miarma.api.backlib.db.AbstractEntity;
import java.math.BigDecimal;
import java.time.LocalDateTime;
@Table("huertos_balance")
public class BalanceEntity extends AbstractEntity {
private Integer id;
private BigDecimal initial_bank;
private BigDecimal initial_cash;
private LocalDateTime created_at;
public BalanceEntity() {
super();
}
public BalanceEntity(Row row) {
super(row);
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public BigDecimal getInitial_bank() {
return initial_bank;
}
public void setInitial_bank(BigDecimal initial_bank) {
this.initial_bank = initial_bank;
}
public BigDecimal getInitial_cash() {
return initial_cash;
}
public void setInitial_cash(BigDecimal initial_cash) {
this.initial_cash = initial_cash;
}
public LocalDateTime getCreated_at() {
return created_at;
}
public void setCreated_at(LocalDateTime created_at) {
this.created_at = created_at;
}
}

View File

@@ -0,0 +1,73 @@
package net.miarma.api.microservices.huertos.entities;
import io.vertx.sqlclient.Row;
import net.miarma.api.backlib.Constants.HuertosPaymentType;
import net.miarma.api.backlib.annotations.Table;
import net.miarma.api.backlib.db.AbstractEntity;
import java.math.BigDecimal;
import java.time.LocalDateTime;
@Table("huertos_expenses")
public class ExpenseEntity extends AbstractEntity{
private Integer expense_id;
private String concept;
private BigDecimal amount;
private String supplier;
private String invoice;
private HuertosPaymentType type;
private LocalDateTime created_at;
public ExpenseEntity() {
super();
}
public ExpenseEntity(Row row) {
super(row);
}
public Integer getExpense_id() {
return expense_id;
}
public void setExpense_id(Integer expense_id) {
this.expense_id = expense_id;
}
public String getConcept() {
return concept;
}
public void setConcept(String concept) {
this.concept = concept;
}
public BigDecimal getAmount() {
return amount;
}
public void setAmount(BigDecimal amount) {
this.amount = amount;
}
public String getSupplier() {
return supplier;
}
public void setSupplier(String supplier) {
this.supplier = supplier;
}
public String getInvoice() {
return invoice;
}
public void setInvoice(String invoice) {
this.invoice = invoice;
}
public HuertosPaymentType getType() {
return type;
}
public void setType(HuertosPaymentType type) {
this.type = type;
}
public LocalDateTime getCreated_at() {
return created_at;
}
public void setCreated_at(LocalDateTime created_at) {
this.created_at = created_at;
}
}

View File

@@ -0,0 +1,85 @@
package net.miarma.api.microservices.huertos.entities;
import io.vertx.sqlclient.Row;
import net.miarma.api.backlib.Constants.HuertosPaymentFrequency;
import net.miarma.api.backlib.Constants.HuertosPaymentType;
import net.miarma.api.backlib.annotations.Table;
import net.miarma.api.backlib.db.AbstractEntity;
import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.time.ZoneOffset;
@Table("huertos_incomes")
public class IncomeEntity extends AbstractEntity {
private Integer income_id;
private Integer member_number;
private String concept;
private BigDecimal amount;
private HuertosPaymentType type;
private HuertosPaymentFrequency frequency;
private LocalDateTime created_at;
public IncomeEntity() {
super();
}
public IncomeEntity(Row row) {
super(row);
}
public Integer getIncome_id() {
return income_id;
}
public void setIncome_id(Integer income_id) {
this.income_id = income_id;
}
public Integer getMember_number() {
return member_number;
}
public void setMember_number(Integer member_number) {
this.member_number = member_number;
}
public String getConcept() {
return concept;
}
public void setConcept(String concept) {
this.concept = concept;
}
public BigDecimal getAmount() {
return amount;
}
public void setAmount(BigDecimal amount) {
this.amount = amount;
}
public HuertosPaymentType getType() {
return type;
}
public void setType(HuertosPaymentType type) {
this.type = type;
}
public HuertosPaymentFrequency getFrequency() {
return frequency;
}
public void setFrequency(HuertosPaymentFrequency frequency) {
this.frequency = frequency;
}
public LocalDateTime getCreated_at() {
return created_at;
}
public void setCreated_at(LocalDateTime created_at) {
this.created_at = created_at;
}
public boolean isPaid() {
if(frequency == HuertosPaymentFrequency.BIYEARLY) {
return (System.currentTimeMillis() - created_at.toEpochSecond(ZoneOffset.UTC)) > 6L * 30 * 24 * 60 * 60 * 1000;
} else if(frequency == HuertosPaymentFrequency.YEARLY) {
return (System.currentTimeMillis() - created_at.toEpochSecond(ZoneOffset.UTC)) > 12L * 30 * 24 * 60 * 60 * 1000;
} else {
return false;
}
}
}

View File

@@ -0,0 +1,234 @@
package net.miarma.api.microservices.huertos.entities;
import io.vertx.sqlclient.Row;
import net.miarma.api.backlib.Constants.*;
import net.miarma.api.backlib.annotations.APIDontReturn;
import net.miarma.api.backlib.annotations.Table;
import net.miarma.api.backlib.db.AbstractEntity;
import net.miarma.api.backlib.interfaces.IUser;
import java.time.LocalDateTime;
@Table("v_huertos_members")
public class MemberEntity extends AbstractEntity implements IUser {
private Integer user_id;
private Integer member_number;
private Integer plot_number;
private String display_name;
private String dni;
private Integer phone;
private String email;
private String user_name;
@APIDontReturn
private String password;
private String avatar;
private LocalDateTime created_at;
private LocalDateTime assigned_at;
private LocalDateTime deactivated_at;
private String notes;
private HuertosUserType type;
private HuertosUserStatus status;
private HuertosUserRole role;
private CoreUserGlobalStatus global_status;
private CoreUserRole global_role;
public MemberEntity() {
super();
}
public MemberEntity(Row row) {
super(row);
}
public MemberEntity(IUser user, UserMetadataEntity metadata) {
this.user_id = user.getUser_id();
this.member_number = metadata.getMember_number();
this.plot_number = metadata.getPlot_number();
this.display_name = user.getDisplay_name();
this.dni = metadata.getDni();
this.phone = metadata.getPhone();
this.email = user.getEmail();
this.user_name = user.getUser_name();
this.password = user.getPassword();
this.avatar = user.getAvatar();
this.created_at = metadata.getCreated_at();
this.assigned_at = metadata.getAssigned_at();
this.deactivated_at = metadata.getDeactivated_at();
this.notes = metadata.getNotes();
this.type = metadata.getType();
this.status = metadata.getStatus();
this.role = metadata.getRole();
this.global_status = user.getGlobal_status();
this.global_role = user.getGlobal_role();
}
public Integer getUser_id() {
return user_id;
}
public void setUser_id(Integer user_id) {
this.user_id = user_id;
}
public Integer getMember_number() {
return member_number;
}
public void setMember_number(Integer member_number) {
this.member_number = member_number;
}
public Integer getPlot_number() {
return plot_number;
}
public void setPlot_number(Integer plot_number) {
this.plot_number = plot_number;
}
public String getDisplay_name() {
return display_name;
}
public void setDisplay_name(String display_name) {
this.display_name = display_name;
}
public String getDni() {
return dni;
}
public void setDni(String dni) {
this.dni = dni;
}
public Integer getPhone() {
return phone;
}
public void setPhone(Integer phone) {
this.phone = phone;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public String getUser_name() {
return user_name;
}
public void setUser_name(String user_name) {
this.user_name = user_name;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public String getAvatar() {
return avatar;
}
public void setAvatar(String avatar) {
this.avatar = avatar;
}
public LocalDateTime getCreated_at() {
return created_at;
}
public void setCreated_at(LocalDateTime created_at) {
this.created_at = created_at;
}
public LocalDateTime getAssigned_at() {
return assigned_at;
}
public void setAssigned_at(LocalDateTime assigned_at) {
this.assigned_at = assigned_at;
}
public LocalDateTime getDeactivated_at() {
return deactivated_at;
}
public void setDeactivated_at(LocalDateTime deactivated_at) {
this.deactivated_at = deactivated_at;
}
public String getNotes() {
return notes;
}
public void setNotes(String notes) {
this.notes = notes;
}
public HuertosUserType getType() {
return type;
}
public void setType(HuertosUserType type) {
this.type = type;
}
public HuertosUserStatus getStatus() {
return status;
}
public void setStatus(HuertosUserStatus status) {
this.status = status;
}
public HuertosUserRole getRole() {
return role;
}
public void setRole(HuertosUserRole role) {
this.role = role;
}
public CoreUserGlobalStatus getGlobal_status() {
return global_status;
}
public void setGlobal_status(CoreUserGlobalStatus global_status) {
this.global_status = global_status;
}
public CoreUserRole getGlobal_role() {
return global_role;
}
public void setGlobal_role(CoreUserRole global_role) {
this.global_role = global_role;
}
public static MemberEntity fromPreUser(PreUserEntity preUser) {
MemberEntity member = new MemberEntity();
member.setMember_number(preUser.getMember_number());
member.setPlot_number(preUser.getPlot_number());
member.setDisplay_name(preUser.getDisplay_name());
member.setDni(preUser.getDni());
member.setPhone(preUser.getPhone());
member.setEmail(preUser.getEmail());
member.setUser_name(preUser.getUser_name());
member.setCreated_at(preUser.getCreated_at());
member.setType(preUser.getType());
member.setStatus(preUser.getStatus());
member.setRole(HuertosUserRole.USER);
member.setGlobal_status(CoreUserGlobalStatus.ACTIVE);
member.setGlobal_role(CoreUserRole.USER);
return member;
}
}

View File

@@ -0,0 +1,135 @@
package net.miarma.api.microservices.huertos.entities;
import io.vertx.sqlclient.Row;
import net.miarma.api.backlib.Constants.HuertosUserStatus;
import net.miarma.api.backlib.Constants.HuertosUserType;
import net.miarma.api.backlib.annotations.Table;
import net.miarma.api.backlib.db.AbstractEntity;
import java.time.LocalDateTime;
@Table("huertos_pre_users")
public class PreUserEntity extends AbstractEntity {
private Integer pre_user_id;
private Integer request_id;
private String user_name;
private String display_name;
private String dni;
private Integer phone;
private String email;
private String password;
private String address;
private String zip_code;
private String city;
private Integer member_number;
private Integer plot_number;
private HuertosUserType type;
private HuertosUserStatus status;
private LocalDateTime created_at;
public PreUserEntity() {
super();
}
public PreUserEntity(Row row) {
super(row);
}
public Integer getPre_user_id() {
return pre_user_id;
}
public void setPre_user_id(Integer pre_user_id) {
this.pre_user_id = pre_user_id;
}
public Integer getRequest_id() {
return request_id;
}
public void setRequest_id(Integer request_id) {
this.request_id = request_id;
}
public String getUser_name() {
return user_name;
}
public void setUser_name(String user_name) {
this.user_name = user_name;
}
public String getDisplay_name() {
return display_name;
}
public void setDisplay_name(String display_name) {
this.display_name = display_name;
}
public String getDni() {
return dni;
}
public void setDni(String dni) {
this.dni = dni;
}
public Integer getPhone() {
return phone;
}
public void setPhone(Integer phone) {
this.phone = phone;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
public String getZip_code() {
return zip_code;
}
public void setZip_code(String zip_code) {
this.zip_code = zip_code;
}
public String getCity() {
return city;
}
public void setCity(String city) {
this.city = city;
}
public Integer getMember_number() {
return member_number;
}
public void setMember_number(Integer member_number) {
this.member_number = member_number;
}
public Integer getPlot_number() {
return plot_number;
}
public void setPlot_number(Integer plot_number) {
this.plot_number = plot_number;
}
public HuertosUserType getType() {
return type;
}
public void setType(HuertosUserType type) {
this.type = type;
}
public HuertosUserStatus getStatus() {
return status;
}
public void setStatus(HuertosUserStatus status) {
this.status = status;
}
public LocalDateTime getCreated_at() {
return created_at;
}
public void setCreated_at(LocalDateTime created_at) {
this.created_at = created_at;
}
}

View File

@@ -0,0 +1,57 @@
package net.miarma.api.microservices.huertos.entities;
import java.util.List;
public class ProfileDTO {
private MemberEntity member;
private List<RequestEntity> requests;
private List<IncomeEntity> payments;
private boolean hasCollaborator;
private boolean hasCollaboratorRequest;
private boolean hasGreenHouse;
private boolean hasGreenHouseRequest;
public MemberEntity getMember() {
return member;
}
public void setMember(MemberEntity member) {
this.member = member;
}
public List<RequestEntity> getRequests() {
return requests;
}
public void setRequests(List<RequestEntity> requests) {
this.requests = requests;
}
public List<IncomeEntity> getPayments() {
return payments;
}
public void setPayments(List<IncomeEntity> payments) {
this.payments = payments;
}
public boolean isHasCollaborator() {
return hasCollaborator;
}
public void setHasCollaborator(boolean hasCollaborator) {
this.hasCollaborator = hasCollaborator;
}
public boolean isHasCollaboratorRequest() {
return hasCollaboratorRequest;
}
public void setHasCollaboratorRequest(boolean hasCollaboratorRequest) {
this.hasCollaboratorRequest = hasCollaboratorRequest;
}
public boolean isHasGreenHouse() {
return hasGreenHouse;
}
public void setHasGreenHouse(boolean hasGreenHouse) {
this.hasGreenHouse = hasGreenHouse;
}
public boolean getHasGreenHouseRequest() {
return hasGreenHouseRequest;
}
public void setHasGreenHouseRequest(boolean hasGreenHouseRquest) {
this.hasGreenHouseRequest = hasGreenHouseRquest;
}
}

View File

@@ -0,0 +1,66 @@
package net.miarma.api.microservices.huertos.entities;
import io.vertx.sqlclient.Row;
import net.miarma.api.backlib.Constants.HuertosRequestStatus;
import net.miarma.api.backlib.Constants.HuertosRequestType;
import net.miarma.api.backlib.annotations.Table;
import net.miarma.api.backlib.db.AbstractEntity;
import java.time.LocalDateTime;
@Table("huertos_requests")
public class RequestEntity extends AbstractEntity {
private Integer request_id;
private HuertosRequestType type;
private HuertosRequestStatus status;
private Integer requested_by;
private Integer target_user_id;
private LocalDateTime created_at;
public RequestEntity() {
super();
}
public RequestEntity(Row row) {
super(row);
}
public Integer getRequest_id() {
return request_id;
}
public void setRequest_id(Integer request_id) {
this.request_id = request_id;
}
public HuertosRequestType getType() {
return type;
}
public void setType(HuertosRequestType type) {
this.type = type;
}
public HuertosRequestStatus getStatus() {
return status;
}
public void setStatus(HuertosRequestStatus status) {
this.status = status;
}
public Integer getRequested_by() {
return requested_by;
}
public void setRequested_by(Integer requested_by) {
this.requested_by = requested_by;
}
public Integer getTarget_user_id() {
return target_user_id;
}
public void setTarget_user_id(Integer target_user_id) {
this.target_user_id = target_user_id;
}
public LocalDateTime getCreated_at() {
return created_at;
}
public void setCreated_at(LocalDateTime created_at) {
this.created_at = created_at;
}
}

View File

@@ -0,0 +1,127 @@
package net.miarma.api.microservices.huertos.entities;
import java.time.LocalDateTime;
import io.vertx.sqlclient.Row;
import net.miarma.api.backlib.Constants.HuertosUserRole;
import net.miarma.api.backlib.Constants.HuertosUserStatus;
import net.miarma.api.backlib.Constants.HuertosUserType;
import net.miarma.api.backlib.annotations.Table;
import net.miarma.api.backlib.db.AbstractEntity;
@Table("huertos_user_metadata")
public class UserMetadataEntity extends AbstractEntity {
private Integer user_id;
private Integer member_number;
private Integer plot_number;
private String dni;
private Integer phone;
private LocalDateTime created_at;
private LocalDateTime assigned_at;
private LocalDateTime deactivated_at;
private String notes;
private HuertosUserType type;
private HuertosUserStatus status;
private HuertosUserRole role;
public UserMetadataEntity() {
super();
}
public UserMetadataEntity(Row row) {
super(row);
}
public Integer getUser_id() {
return user_id;
}
public void setUser_id(Integer user_id) {
this.user_id = user_id;
}
public Integer getMember_number() {
return member_number;
}
public void setMember_number(Integer member_number) {
this.member_number = member_number;
}
public Integer getPlot_number() {
return plot_number;
}
public void setPlot_number(Integer plot_number) {
this.plot_number = plot_number;
}
public String getDni() {
return dni;
}
public void setDni(String dni) {
this.dni = dni;
}
public Integer getPhone() {
return phone;
}
public void setPhone(Integer phone) {
this.phone = phone;
}
public LocalDateTime getCreated_at() {
return created_at;
}
public void setCreated_at(LocalDateTime created_at) {
this.created_at = created_at;
}
public LocalDateTime getAssigned_at() {
return assigned_at;
}
public void setAssigned_at(LocalDateTime assigned_at) {
this.assigned_at = assigned_at;
}
public LocalDateTime getDeactivated_at() {
return deactivated_at;
}
public void setDeactivated_at(LocalDateTime deactivated_at) {
this.deactivated_at = deactivated_at;
}
public String getNotes() {
return notes;
}
public void setNotes(String notes) {
this.notes = notes;
}
public HuertosUserType getType() {
return type;
}
public void setType(HuertosUserType type) {
this.type = type;
}
public HuertosUserStatus getStatus() {
return status;
}
public void setStatus(HuertosUserStatus status) {
this.status = status;
}
public HuertosUserRole getRole() {
return role;
}
public void setRole(HuertosUserRole role) {
this.role = role;
}
public static UserMetadataEntity fromMemberEntity(MemberEntity member) {
UserMetadataEntity meta = new UserMetadataEntity();
meta.setUser_id(member.getUser_id());
meta.setMember_number(member.getMember_number());
meta.setPlot_number(member.getPlot_number());
meta.setDni(member.getDni());
meta.setPhone(member.getPhone());
meta.setCreated_at(member.getCreated_at());
meta.setAssigned_at(member.getAssigned_at());
meta.setDeactivated_at(member.getDeactivated_at());
meta.setNotes(member.getNotes());
meta.setType(member.getType());
meta.setStatus(member.getStatus());
meta.setRole(member.getRole());
return meta;
}
}

View File

@@ -0,0 +1,95 @@
package net.miarma.api.microservices.huertos.entities;
import io.vertx.sqlclient.Row;
import net.miarma.api.backlib.annotations.Table;
import net.miarma.api.backlib.db.AbstractEntity;
import java.math.BigDecimal;
import java.time.LocalDateTime;
@Table("v_balance_with_totals")
public class ViewBalanceWithTotals extends AbstractEntity{
private Integer id;
private BigDecimal initial_bank;
private BigDecimal initial_cash;
private BigDecimal total_bank_expenses;
private BigDecimal total_cash_expenses;
private BigDecimal total_bank_incomes;
private BigDecimal total_cash_incomes;
private LocalDateTime created_at;
public ViewBalanceWithTotals() {
super();
}
public ViewBalanceWithTotals(Row row) {
super(row);
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public BigDecimal getInitial_bank() {
return initial_bank;
}
public void setInitial_bank(BigDecimal initial_bank) {
this.initial_bank = initial_bank;
}
public BigDecimal getInitial_cash() {
return initial_cash;
}
public void setInitial_cash(BigDecimal initial_cash) {
this.initial_cash = initial_cash;
}
public BigDecimal getTotal_bank_expenses() {
return total_bank_expenses;
}
public void setTotal_bank_expenses(BigDecimal total_bank_expenses) {
this.total_bank_expenses = total_bank_expenses;
}
public BigDecimal getTotal_cash_expenses() {
return total_cash_expenses;
}
public void setTotal_cash_expenses(BigDecimal total_cash_expenses) {
this.total_cash_expenses = total_cash_expenses;
}
public BigDecimal getTotal_bank_incomes() {
return total_bank_incomes;
}
public void setTotal_bank_incomes(BigDecimal total_bank_incomes) {
this.total_bank_incomes = total_bank_incomes;
}
public BigDecimal getTotal_cash_incomes() {
return total_cash_incomes;
}
public void setTotal_cash_incomes(BigDecimal total_cash_incomes) {
this.total_cash_incomes = total_cash_incomes;
}
public LocalDateTime getCreated_at() {
return created_at;
}
public void setCreated_at(LocalDateTime created_at) {
this.created_at = created_at;
}
}

View File

@@ -0,0 +1,47 @@
package net.miarma.api.microservices.huertos.entities;
import io.vertx.sqlclient.Row;
import net.miarma.api.backlib.Constants.HuertosPaymentFrequency;
import net.miarma.api.backlib.Constants.HuertosPaymentType;
import net.miarma.api.backlib.annotations.Table;
import net.miarma.api.backlib.db.AbstractEntity;
import java.math.BigDecimal;
import java.time.LocalDateTime;
@Table("v_incomes_with_full_names")
public class ViewIncomesWithFullNames extends AbstractEntity {
private Integer income_id;
private Integer member_number;
private String display_name;
private String concept;
private BigDecimal amount;
private HuertosPaymentType type;
private HuertosPaymentFrequency frequency;
private LocalDateTime created_at;
public ViewIncomesWithFullNames() {
super();
}
public ViewIncomesWithFullNames(Row row) {
super(row);
}
public Integer getIncome_id() { return income_id; }
public void setIncome_id(Integer income_id) { this.income_id = income_id; }
public Integer getMember_number() { return member_number; }
public void setMember_number(Integer member_number) { this.member_number = member_number; }
public String getDisplay_name() { return display_name; }
public void setDisplay_name(String display_name) { this.display_name = display_name; }
public String getConcept() { return concept; }
public void setConcept(String concept) { this.concept = concept; }
public BigDecimal getAmount() { return amount; }
public void setAmount(BigDecimal amount) { this.amount = amount; }
public HuertosPaymentType getType() { return type; }
public void setType(HuertosPaymentType type) { this.type = type; }
public HuertosPaymentFrequency getFrequency() { return frequency; }
public void setFrequency(HuertosPaymentFrequency frequency) { this.frequency = frequency; }
public LocalDateTime getCreated_at() { return created_at; }
public void setCreated_at(LocalDateTime created_at) { this.created_at = created_at; }
}

View File

@@ -0,0 +1,224 @@
package net.miarma.api.microservices.huertos.entities;
import io.vertx.sqlclient.Row;
import net.miarma.api.backlib.Constants.*;
import net.miarma.api.backlib.annotations.Table;
import net.miarma.api.backlib.db.AbstractEntity;
import java.time.LocalDateTime;
@Table("v_requests_with_pre_users")
public class ViewRequestsWithPreUsers extends AbstractEntity {
// huertos_requests
public Integer request_id;
public HuertosRequestType request_type;
public HuertosRequestStatus request_status;
public Integer requested_by;
// huertos_users
public String requested_by_name;
public Integer target_user_id;
public LocalDateTime request_created_at;
// huertos_pre_users
public Integer pre_user_id;
public String pre_user_name;
public String pre_display_name;
public String pre_dni;
public Integer pre_phone;
public String pre_email;
public String pre_address;
public String pre_zip_code;
public String pre_city;
public Integer pre_member_number;
public Integer pre_plot_number;
public HuertosUserType pre_type;
public HuertosUserStatus pre_status;
public HuertosUserRole pre_role;
public LocalDateTime pre_created_at;
public ViewRequestsWithPreUsers() {
super();
}
public ViewRequestsWithPreUsers(Row row) {
super(row);
}
public Integer getRequest_id() {
return request_id;
}
public void setRequest_id(Integer request_id) {
this.request_id = request_id;
}
public HuertosRequestType getRequest_type() {
return request_type;
}
public void setRequest_type(HuertosRequestType request_type) {
this.request_type = request_type;
}
public HuertosRequestStatus getRequest_status() {
return request_status;
}
public void setRequest_status(HuertosRequestStatus request_status) {
this.request_status = request_status;
}
public Integer getRequested_by() {
return requested_by;
}
public void setRequested_by(Integer requested_by) {
this.requested_by = requested_by;
}
public String getRequested_by_name() {
return requested_by_name;
}
public void setRequested_by_name(String requested_by_name) {
this.requested_by_name = requested_by_name;
}
public Integer getTarget_user_id() {
return target_user_id;
}
public void setTarget_user_id(Integer target_user_id) {
this.target_user_id = target_user_id;
}
public LocalDateTime getRequest_created_at() {
return request_created_at;
}
public void setRequest_created_at(LocalDateTime request_created_at) {
this.request_created_at = request_created_at;
}
public Integer getPre_user_id() {
return pre_user_id;
}
public void setPre_user_id(Integer pre_user_id) {
this.pre_user_id = pre_user_id;
}
public String getPre_user_name() {
return pre_user_name;
}
public void setPre_user_name(String pre_user_name) {
this.pre_user_name = pre_user_name;
}
public String getPre_display_name() {
return pre_display_name;
}
public void setPre_display_name(String pre_display_name) {
this.pre_display_name = pre_display_name;
}
public String getPre_dni() {
return pre_dni;
}
public void setPre_dni(String pre_dni) {
this.pre_dni = pre_dni;
}
public Integer getPre_phone() {
return pre_phone;
}
public void setPre_phone(Integer pre_phone) {
this.pre_phone = pre_phone;
}
public String getPre_email() {
return pre_email;
}
public void setPre_email(String pre_email) {
this.pre_email = pre_email;
}
public String getPre_address() {
return pre_address;
}
public void setPre_address(String pre_address) {
this.pre_address = pre_address;
}
public String getPre_zip_code() {
return pre_zip_code;
}
public void setPre_zip_code(String pre_zip_code) {
this.pre_zip_code = pre_zip_code;
}
public String getPre_city() {
return pre_city;
}
public void setPre_city(String pre_city) {
this.pre_city = pre_city;
}
public Integer getPre_member_number() {
return pre_member_number;
}
public void setPre_member_number(Integer pre_member_number) {
this.pre_member_number = pre_member_number;
}
public Integer getPre_plot_number() {
return pre_plot_number;
}
public void setPre_plot_number(Integer pre_plot_number) {
this.pre_plot_number = pre_plot_number;
}
public HuertosUserType getPre_type() {
return pre_type;
}
public void setPre_type(HuertosUserType pre_type) {
this.pre_type = pre_type;
}
public HuertosUserStatus getPre_status() {
return pre_status;
}
public void setPre_status(HuertosUserStatus pre_status) {
this.pre_status = pre_status;
}
public HuertosUserRole getPre_role() {
return pre_role;
}
public void setPre_role(HuertosUserRole pre_role) {
this.pre_role = pre_role;
}
public LocalDateTime getPre_created_at() {
return pre_created_at;
}
public void setPre_created_at(LocalDateTime pre_created_at) {
this.pre_created_at = pre_created_at;
}
}

View File

@@ -0,0 +1,59 @@
package net.miarma.api.microservices.huertos.handlers;
import io.vertx.ext.web.RoutingContext;
import io.vertx.sqlclient.Pool;
import net.miarma.api.backlib.Constants;
import net.miarma.api.backlib.http.ApiStatus;
import net.miarma.api.backlib.http.QueryParams;
import net.miarma.api.microservices.huertos.entities.AnnouncementEntity;
import net.miarma.api.microservices.huertos.services.AnnouncementService;
import net.miarma.api.backlib.util.JsonUtil;
@SuppressWarnings("unused")
public class AnnouncementDataHandler {
final AnnouncementService announcementService;
public AnnouncementDataHandler(Pool pool) {
this.announcementService = new AnnouncementService(pool);
}
public void getAll(RoutingContext ctx) {
QueryParams params = QueryParams.from(ctx);
announcementService.getAll(params)
.onSuccess(announces -> JsonUtil.sendJson(ctx, ApiStatus.OK, announces))
.onFailure(err -> JsonUtil.sendJson(ctx, ApiStatus.fromException(err), null, err.getMessage()));
}
public void getById(RoutingContext ctx) {
Integer announcementId = Integer.parseInt(ctx.pathParam("announce_id"));
announcementService.getById(announcementId)
.onSuccess(announce -> JsonUtil.sendJson(ctx, ApiStatus.OK, announce))
.onFailure(err -> JsonUtil.sendJson(ctx, ApiStatus.fromException(err), null, err.getMessage()));
}
public void create(RoutingContext ctx) {
AnnouncementEntity announce = Constants.GSON.fromJson(ctx.body().asString(), AnnouncementEntity.class);
announcementService.create(announce)
.onSuccess(result -> JsonUtil.sendJson(ctx, ApiStatus.CREATED, result))
.onFailure(err -> JsonUtil.sendJson(ctx, ApiStatus.fromException(err), null, err.getMessage()));
}
public void update(RoutingContext ctx) {
AnnouncementEntity announce = Constants.GSON.fromJson(ctx.body().asString(), AnnouncementEntity.class);
announcementService.update(announce)
.onSuccess(result -> JsonUtil.sendJson(ctx, ApiStatus.NO_CONTENT, null))
.onFailure(err -> JsonUtil.sendJson(ctx, ApiStatus.fromException(err), null, err.getMessage()));
}
public void delete(RoutingContext ctx) {
Integer announcementId = Integer.parseInt(ctx.pathParam("announce_id"));
announcementService.delete(announcementId)
.onSuccess(result -> JsonUtil.sendJson(ctx, ApiStatus.NO_CONTENT, null))
.onFailure(err -> JsonUtil.sendJson(ctx, ApiStatus.fromException(err), null, err.getMessage()));
}
}

View File

@@ -0,0 +1,5 @@
package net.miarma.api.microservices.huertos.handlers;
public class AnnouncementLogicHandler {
}

View File

@@ -0,0 +1,40 @@
package net.miarma.api.microservices.huertos.handlers;
import io.vertx.ext.web.RoutingContext;
import io.vertx.sqlclient.Pool;
import net.miarma.api.backlib.Constants;
import net.miarma.api.backlib.http.ApiStatus;
import net.miarma.api.microservices.huertos.entities.BalanceEntity;
import net.miarma.api.microservices.huertos.services.BalanceService;
import net.miarma.api.backlib.util.JsonUtil;
@SuppressWarnings("unused")
public class BalanceDataHandler {
private final BalanceService balanceService;
public BalanceDataHandler(Pool pool) {
this.balanceService = new BalanceService(pool);
}
public void getBalance(RoutingContext ctx) {
balanceService.getBalance()
.onSuccess(balance -> JsonUtil.sendJson(ctx, ApiStatus.OK, balance))
.onFailure(err -> JsonUtil.sendJson(ctx, ApiStatus.fromException(err), null, err.getMessage()));
}
public void create(RoutingContext ctx) {
BalanceEntity balance = Constants.GSON.fromJson(ctx.body().asString(), BalanceEntity.class);
balanceService.create(balance)
.onSuccess(result -> JsonUtil.sendJson(ctx, ApiStatus.CREATED, result))
.onFailure(err -> JsonUtil.sendJson(ctx, ApiStatus.fromException(err), null, err.getMessage()));
}
public void update(RoutingContext ctx) {
BalanceEntity balance = Constants.GSON.fromJson(ctx.body().asString(), BalanceEntity.class);
balanceService.update(balance)
.onSuccess(result -> JsonUtil.sendJson(ctx, ApiStatus.NO_CONTENT, null))
.onFailure(err -> JsonUtil.sendJson(ctx, ApiStatus.fromException(err), null, err.getMessage()));
}
}

View File

@@ -0,0 +1,25 @@
package net.miarma.api.microservices.huertos.handlers;
import io.vertx.core.Vertx;
import io.vertx.core.json.JsonObject;
import io.vertx.ext.web.RoutingContext;
import net.miarma.api.backlib.Constants;
import net.miarma.api.backlib.http.ApiStatus;
import net.miarma.api.backlib.util.EventBusUtil;
import net.miarma.api.backlib.util.JsonUtil;
public class BalanceLogicHandler {
private final Vertx vertx;
public BalanceLogicHandler(Vertx vertx) {
this.vertx = vertx;
}
public void getBalanceWithTotals(RoutingContext ctx) {
JsonObject request = new JsonObject().put("action", "getBalanceWithTotals");
vertx.eventBus().request(Constants.HUERTOS_EVENT_BUS, request, ar -> {
if (ar.succeeded()) JsonUtil.sendJson(ctx, ApiStatus.OK, ar.result().body());
else EventBusUtil.handleReplyError(ctx, ar.cause(), "Balance not found");
});
}
}

View File

@@ -0,0 +1,59 @@
package net.miarma.api.microservices.huertos.handlers;
import io.vertx.ext.web.RoutingContext;
import io.vertx.sqlclient.Pool;
import net.miarma.api.backlib.Constants;
import net.miarma.api.backlib.http.ApiStatus;
import net.miarma.api.backlib.http.QueryParams;
import net.miarma.api.microservices.huertos.entities.ExpenseEntity;
import net.miarma.api.microservices.huertos.services.ExpenseService;
import net.miarma.api.backlib.util.JsonUtil;
@SuppressWarnings("unused")
public class ExpenseDataHandler {
private final ExpenseService expenseService;
public ExpenseDataHandler(Pool pool) {
this.expenseService = new ExpenseService(pool);
}
public void getAll(RoutingContext ctx) {
QueryParams params = QueryParams.from(ctx);
expenseService.getAll(params)
.onSuccess(expenses -> JsonUtil.sendJson(ctx, ApiStatus.OK, expenses))
.onFailure(err -> JsonUtil.sendJson(ctx, ApiStatus.fromException(err), null, err.getMessage()));
}
public void getById(RoutingContext ctx) {
Integer expenseId = Integer.parseInt(ctx.pathParam("expense_id"));
expenseService.getById(expenseId)
.onSuccess(expense -> JsonUtil.sendJson(ctx, ApiStatus.OK, expense))
.onFailure(err -> JsonUtil.sendJson(ctx, ApiStatus.fromException(err), null, err.getMessage()));
}
public void create(RoutingContext ctx) {
ExpenseEntity expense = Constants.GSON.fromJson(ctx.body().asString(), ExpenseEntity.class);
expenseService.create(expense)
.onSuccess(result -> JsonUtil.sendJson(ctx, ApiStatus.CREATED, result))
.onFailure(err -> JsonUtil.sendJson(ctx, ApiStatus.fromException(err), null, err.getMessage()));
}
public void update(RoutingContext ctx) {
ExpenseEntity expense = Constants.GSON.fromJson(ctx.body().asString(), ExpenseEntity.class);
expenseService.update(expense)
.onSuccess(result -> JsonUtil.sendJson(ctx, ApiStatus.NO_CONTENT, null))
.onFailure(err -> JsonUtil.sendJson(ctx, ApiStatus.fromException(err), null, err.getMessage()));
}
public void delete(RoutingContext ctx) {
Integer expenseId = Integer.parseInt(ctx.pathParam("expense_id"));
expenseService.delete(expenseId)
.onSuccess(result -> JsonUtil.sendJson(ctx, ApiStatus.NO_CONTENT, null))
.onFailure(err -> JsonUtil.sendJson(ctx, ApiStatus.fromException(err), null, err.getMessage()));
}
}

View File

@@ -0,0 +1,5 @@
package net.miarma.api.microservices.huertos.handlers;
public class ExpenseLogicHandler {
}

View File

@@ -0,0 +1,67 @@
package net.miarma.api.microservices.huertos.handlers;
import io.vertx.ext.web.RoutingContext;
import io.vertx.sqlclient.Pool;
import net.miarma.api.backlib.Constants;
import net.miarma.api.backlib.http.ApiStatus;
import net.miarma.api.backlib.http.QueryParams;
import net.miarma.api.microservices.huertos.entities.IncomeEntity;
import net.miarma.api.microservices.huertos.services.IncomeService;
import net.miarma.api.backlib.util.JsonUtil;
@SuppressWarnings("unused")
public class IncomeDataHandler {
private final IncomeService incomeService;
public IncomeDataHandler(Pool pool) {
this.incomeService = new IncomeService(pool);
}
public void getAll(RoutingContext ctx) {
QueryParams params = QueryParams.from(ctx);
incomeService.getAll(params)
.onSuccess(incomes -> JsonUtil.sendJson(ctx, ApiStatus.OK, incomes))
.onFailure(err -> JsonUtil.sendJson(ctx, ApiStatus.fromException(err), null, err.getMessage()));
}
public void getIncomesWithNames(RoutingContext ctx) {
QueryParams params = QueryParams.from(ctx);
incomeService.getIncomesWithNames(params)
.onSuccess(incomes -> JsonUtil.sendJson(ctx, ApiStatus.OK, incomes))
.onFailure(err -> JsonUtil.sendJson(ctx, ApiStatus.fromException(err), null, err.getMessage()));
}
public void getById(RoutingContext ctx) {
Integer incomeId = Integer.parseInt(ctx.pathParam("income_id"));
incomeService.getById(incomeId)
.onSuccess(income -> JsonUtil.sendJson(ctx, ApiStatus.OK, income))
.onFailure(err -> JsonUtil.sendJson(ctx, ApiStatus.fromException(err), null, err.getMessage()));
}
public void create(RoutingContext ctx) {
IncomeEntity income = Constants.GSON.fromJson(ctx.body().asString(), IncomeEntity.class);
incomeService.create(income)
.onSuccess(result -> JsonUtil.sendJson(ctx, ApiStatus.CREATED, result))
.onFailure(err -> JsonUtil.sendJson(ctx, ApiStatus.fromException(err), null, err.getMessage()));
}
public void update(RoutingContext ctx) {
IncomeEntity income = Constants.GSON.fromJson(ctx.body().asString(), IncomeEntity.class);
incomeService.update(income)
.onSuccess(result -> JsonUtil.sendJson(ctx, ApiStatus.NO_CONTENT, null))
.onFailure(err -> JsonUtil.sendJson(ctx, ApiStatus.fromException(err), null, err.getMessage()));
}
public void delete(RoutingContext ctx) {
Integer incomeId = Integer.parseInt(ctx.pathParam("income_id"));
incomeService.delete(incomeId)
.onSuccess(result -> JsonUtil.sendJson(ctx, ApiStatus.NO_CONTENT, null))
.onFailure(err -> JsonUtil.sendJson(ctx, ApiStatus.fromException(err), null, err.getMessage()));
}
}

View File

@@ -0,0 +1,26 @@
package net.miarma.api.microservices.huertos.handlers;
import io.vertx.core.Vertx;
import io.vertx.core.json.JsonObject;
import io.vertx.ext.web.RoutingContext;
import net.miarma.api.backlib.Constants;
import net.miarma.api.backlib.http.ApiStatus;
import net.miarma.api.backlib.util.EventBusUtil;
import net.miarma.api.backlib.util.JsonUtil;
public class IncomeLogicHandler {
private final Vertx vertx;
public IncomeLogicHandler(Vertx vertx) {
this.vertx = vertx;
}
public void getMyIncomes(RoutingContext ctx) {
String token = ctx.request().getHeader("Authorization").substring("Bearer ".length());
JsonObject request = new JsonObject().put("action", "getMyIncomes").put("token", token);
vertx.eventBus().request(Constants.HUERTOS_EVENT_BUS, request, ar -> {
if (ar.succeeded()) JsonUtil.sendJson(ctx, ApiStatus.OK, ar.result().body());
else EventBusUtil.handleReplyError(ctx, ar.cause(), "Incomes not found");
});
}
}

View File

@@ -0,0 +1,171 @@
package net.miarma.api.microservices.huertos.handlers;
import java.util.List;
import io.vertx.core.AsyncResult;
import io.vertx.core.Future;
import io.vertx.core.Handler;
import io.vertx.core.Vertx;
import io.vertx.core.WorkerExecutor;
import io.vertx.core.json.Json;
import io.vertx.ext.web.RoutingContext;
import io.vertx.sqlclient.Pool;
import net.miarma.api.backlib.ConfigManager;
import net.miarma.api.backlib.Constants;
import net.miarma.api.backlib.http.ApiStatus;
import net.miarma.api.backlib.security.JWTManager;
import net.miarma.api.microservices.huertos.entities.MemberEntity;
import net.miarma.api.microservices.huertos.mail.Attachment;
import net.miarma.api.microservices.huertos.mail.ImapReader;
import net.miarma.api.microservices.huertos.mail.Mail;
import net.miarma.api.microservices.huertos.mail.MailCredentials;
import net.miarma.api.microservices.huertos.mail.MailManager;
import net.miarma.api.microservices.huertos.services.MemberService;
public class MailHandler {
private final MailManager mailManager;
private final WorkerExecutor mailExecutor;
private final MemberService memberService;
public MailHandler(Vertx vertx, Pool pool) {
this.mailManager = new MailManager(vertx);
this.mailExecutor = vertx.createSharedWorkerExecutor("mail-worker-pool", 10);
this.memberService = new MemberService(pool);
}
public void sendMail(RoutingContext ctx) {
Mail mail = Json.decodeValue(ctx.body().asString(), Mail.class);
List<Attachment> attachments = mail.getAttachments();
resolveMailCredentials(ctx, res -> {
if (res.failed()) {
ctx.response().setStatusCode(ApiStatus.UNAUTHORIZED.getCode()).end("Unauthorized: " + res.cause().getMessage());
return;
}
MailCredentials creds = res.result();
if (!attachments.isEmpty()) {
mailManager.sendEmailWithAttachment(mail, attachments, creds.username(), creds.password(), result -> {
if (result.succeeded()) {
ctx.response().setStatusCode(ApiStatus.OK.getCode()).end("Email has been sent successfully");
} else {
Constants.LOGGER.error(result.cause().getMessage());
ctx.response().setStatusCode(ApiStatus.INTERNAL_SERVER_ERROR.getCode()).end("Error sending email: " + result.cause().getMessage());
}
});
} else {
mailManager.sendEmail(mail, creds.username(), creds.password(), result -> {
if (result.succeeded()) {
ctx.response().setStatusCode(ApiStatus.OK.getCode()).end("Email has been sent successfully");
} else {
Constants.LOGGER.error(result.cause().getMessage());
ctx.response().setStatusCode(ApiStatus.INTERNAL_SERVER_ERROR.getCode()).end("Error sending email: " + result.cause().getMessage());
}
});
}
});
}
public void getFolder(RoutingContext ctx) {
String folderParam = ctx.pathParam("folder");
if (folderParam == null) {
ctx.response().setStatusCode(ApiStatus.BAD_REQUEST.getCode()).end("Missing folder name");
return;
}
resolveMailCredentials(ctx, res -> {
if (res.failed()) {
ctx.response().setStatusCode(ApiStatus.UNAUTHORIZED.getCode()).end("Unauthorized: " + res.cause().getMessage());
return;
}
MailCredentials creds = res.result();
mailExecutor.executeBlocking(() ->
ImapReader.listInboxEmails(folderParam, creds.username(), creds.password())
).onSuccess(mails -> {
ctx.response().putHeader("Content-Type", "application/json").end(Json.encodePrettily(mails));
}).onFailure(err -> {
ctx.response().setStatusCode(500).end("Error reading folder: " + err.getMessage());
});
});
}
public void getMail(RoutingContext ctx) {
String folderParam = ctx.pathParam("folder");
String indexParam = ctx.pathParam("index");
if (folderParam == null) {
ctx.response().setStatusCode(ApiStatus.BAD_REQUEST.getCode()).end("Missing folder name");
return;
}
int index;
try {
index = Integer.parseInt(indexParam);
} catch (NumberFormatException e) {
ctx.response().setStatusCode(400).end("Index must be a number");
return;
}
resolveMailCredentials(ctx, res -> {
if (res.failed()) {
ctx.response().setStatusCode(ApiStatus.UNAUTHORIZED.getCode()).end("Unauthorized: " + res.cause().getMessage());
return;
}
MailCredentials creds = res.result();
mailExecutor.executeBlocking(() ->
ImapReader.getEmailByIndex(folderParam, creds.username(), creds.password(), index)
).onSuccess(mail -> {
ctx.response().putHeader("Content-Type", "application/json").end(Json.encodePrettily(mail));
}).onFailure(err -> {
ctx.response().setStatusCode(500).end("Error getting email: " + err.getMessage());
});
});
}
private void resolveMailCredentials(RoutingContext ctx, Handler<AsyncResult<MailCredentials>> handler) {
String token = ctx.request().getHeader("Authorization");
if (token == null || !token.startsWith("Bearer ")) {
handler.handle(Future.failedFuture("Missing or invalid Authorization header"));
return;
}
int userId = JWTManager.getInstance().extractUserId(token.replace("Bearer ", ""));
memberService.getById(userId).onComplete(ar -> {
if (ar.failed()) {
handler.handle(Future.failedFuture(ar.cause()));
return;
}
MemberEntity member = ar.result();
String email = member.getEmail();
if (email == null || !email.contains("@")) {
handler.handle(Future.failedFuture("Invalid member email"));
return;
}
String role = email.split("@")[0];
String password = ConfigManager.getInstance().getStringProperty("smtp.password." + role);
if (password == null) {
handler.handle(Future.failedFuture("No password found for user"));
return;
}
handler.handle(Future.succeededFuture(new MailCredentials(email, password)));
});
}
}

View File

@@ -0,0 +1,65 @@
package net.miarma.api.microservices.huertos.handlers;
import io.vertx.ext.web.RoutingContext;
import io.vertx.sqlclient.Pool;
import net.miarma.api.backlib.Constants;
import net.miarma.api.backlib.http.ApiStatus;
import net.miarma.api.backlib.http.QueryParams;
import net.miarma.api.backlib.util.JsonUtil;
import net.miarma.api.microservices.huertos.entities.MemberEntity;
import net.miarma.api.microservices.huertos.services.MemberService;
@SuppressWarnings("unused")
public class MemberDataHandler {
private final MemberService memberService;
public MemberDataHandler(Pool pool) {
this.memberService = new MemberService(pool);
}
public void getAll(RoutingContext ctx) {
QueryParams params = QueryParams.from(ctx);
memberService.getAll(params)
.onSuccess(members -> JsonUtil.sendJson(ctx, ApiStatus.OK, members))
.onFailure(err -> JsonUtil.sendJson(ctx, ApiStatus.fromException(err), null, err.getMessage()));
}
public void getById(RoutingContext ctx) {
Integer id = Integer.parseInt(ctx.request().getParam("user_id"));
memberService.getById(id)
.onSuccess(member -> {
if (member == null) {
JsonUtil.sendJson(ctx, ApiStatus.NOT_FOUND, null, "Member not found");
} else {
JsonUtil.sendJson(ctx, ApiStatus.OK, member);
}
})
.onFailure(err -> JsonUtil.sendJson(ctx, ApiStatus.fromException(err), null, err.getMessage()));
}
public void create(RoutingContext ctx) {
MemberEntity member = Constants.GSON.fromJson(ctx.body().asString(), MemberEntity.class);
memberService.create(member)
.onSuccess(result -> JsonUtil.sendJson(ctx, ApiStatus.CREATED, result))
.onFailure(err -> JsonUtil.sendJson(ctx, ApiStatus.fromException(err), null, err.getMessage()));
}
public void update(RoutingContext ctx) {
MemberEntity member = Constants.GSON.fromJson(ctx.body().asString(), MemberEntity.class);
memberService.update(member)
.onSuccess(result -> JsonUtil.sendJson(ctx, ApiStatus.NO_CONTENT, null))
.onFailure(err -> JsonUtil.sendJson(ctx, ApiStatus.fromException(err), null, err.getMessage()));
}
public void delete(RoutingContext ctx) {
Integer id = Integer.parseInt(ctx.request().getParam("user_id"));
memberService.delete(id)
.onSuccess(result -> JsonUtil.sendJson(ctx, ApiStatus.NO_CONTENT, null))
.onFailure(err -> JsonUtil.sendJson(ctx, ApiStatus.fromException(err), null, err.getMessage()));
}
}

View File

@@ -0,0 +1,202 @@
package net.miarma.api.microservices.huertos.handlers;
import io.vertx.core.Vertx;
import io.vertx.core.json.JsonObject;
import io.vertx.ext.web.RoutingContext;
import net.miarma.api.backlib.Constants;
import net.miarma.api.backlib.http.ApiStatus;
import net.miarma.api.backlib.util.EventBusUtil;
import net.miarma.api.backlib.util.JsonUtil;
import net.miarma.api.microservices.huertos.entities.PreUserEntity;
public class MemberLogicHandler {
private final Vertx vertx;
public MemberLogicHandler(Vertx vertx) {
this.vertx = vertx;
}
public void login(RoutingContext ctx) {
JsonObject body = ctx.body().asJsonObject();
JsonObject request = new JsonObject()
.put("action", "login")
.put("email", body.getString("email", null))
.put("userName", body.getString("userName", null))
.put("password", body.getString("password"))
.put("keepLoggedIn",body.getBoolean("keepLoggedIn", false));
vertx.eventBus().request(Constants.HUERTOS_EVENT_BUS, request, ar -> {
if (ar.succeeded()) {
JsonObject result = (JsonObject) ar.result().body();
result.put("tokenTime", System.currentTimeMillis());
JsonUtil.sendJson(ctx, ApiStatus.OK, result);
} else {
EventBusUtil.handleReplyError(ctx, ar.cause(), "The member is inactive or banned");
}
});
}
public void getByMemberNumber(RoutingContext ctx) {
Integer memberNumber = Integer.parseInt(ctx.request().getParam("member_number"));
JsonObject request = new JsonObject().put("action", "getByMemberNumber").put("memberNumber", memberNumber);
vertx.eventBus().request(Constants.HUERTOS_EVENT_BUS, request, ar -> {
if (ar.succeeded()) JsonUtil.sendJson(ctx, ApiStatus.OK, ar.result().body());
else EventBusUtil.handleReplyError(ctx, ar.cause(), "Member not found");
});
}
public void getByPlotNumber(RoutingContext ctx) {
Integer plotNumber = Integer.parseInt(ctx.request().getParam("plot_number"));
JsonObject request = new JsonObject().put("action", "getByPlotNumber").put("plotNumber", plotNumber);
vertx.eventBus().request(Constants.HUERTOS_EVENT_BUS, request, ar -> {
if (ar.succeeded()) JsonUtil.sendJson(ctx, ApiStatus.OK, ar.result().body());
else EventBusUtil.handleReplyError(ctx, ar.cause(), "Member not found");
});
}
public void getByDni(RoutingContext ctx) {
String dni = ctx.request().getParam("dni");
JsonObject request = new JsonObject().put("action", "getByDNI").put("dni", dni);
vertx.eventBus().request(Constants.HUERTOS_EVENT_BUS, request, ar -> {
if (ar.succeeded()) JsonUtil.sendJson(ctx, ApiStatus.OK, ar.result().body());
else EventBusUtil.handleReplyError(ctx, ar.cause(), "Member not found");
});
}
public void getUserPayments(RoutingContext ctx) {
Integer memberNumber = Integer.parseInt(ctx.request().getParam("member_number"));
JsonObject request = new JsonObject().put("action", "getUserPayments").put("memberNumber", memberNumber);
vertx.eventBus().request(Constants.HUERTOS_EVENT_BUS, request, ar -> {
if (ar.succeeded()) JsonUtil.sendJson(ctx, ApiStatus.OK, ar.result().body());
else EventBusUtil.handleReplyError(ctx, ar.cause(), "Member not found");
});
}
public void hasPaid(RoutingContext ctx) {
Integer memberNumber = Integer.parseInt(ctx.request().getParam("member_number"));
JsonObject request = new JsonObject().put("action", "hasPaid").put("memberNumber", memberNumber);
vertx.eventBus().request(Constants.HUERTOS_EVENT_BUS, request, ar -> {
if (ar.succeeded()) JsonUtil.sendJson(ctx, ApiStatus.OK, ar.result().body());
else EventBusUtil.handleReplyError(ctx, ar.cause(), "Member not found");
});
}
public void getWaitlist(RoutingContext ctx) {
JsonObject request = new JsonObject().put("action", "getWaitlist");
vertx.eventBus().request(Constants.HUERTOS_EVENT_BUS, request, ar -> {
if (ar.succeeded()) JsonUtil.sendJson(ctx, ApiStatus.OK, ar.result().body());
else EventBusUtil.handleReplyError(ctx, ar.cause(), "Waitlist not found");
});
}
public void getLimitedWaitlist(RoutingContext ctx) {
JsonObject request = new JsonObject().put("action", "getLimitedWaitlist");
vertx.eventBus().request(Constants.HUERTOS_EVENT_BUS, request, ar -> {
if (ar.succeeded()) JsonUtil.sendJson(ctx, ApiStatus.OK, ar.result().body());
else EventBusUtil.handleReplyError(ctx, ar.cause(), "Waitlist not found");
});
}
public void getLastMemberNumber(RoutingContext ctx) {
JsonObject request = new JsonObject().put("action", "getLastMemberNumber");
vertx.eventBus().request(Constants.HUERTOS_EVENT_BUS, request, ar -> {
if (ar.succeeded()) JsonUtil.sendJson(ctx, ApiStatus.OK, ar.result().body());
else EventBusUtil.handleReplyError(ctx, ar.cause(), "Last member number not found");
});
}
public void getProfile(RoutingContext ctx) {
String token = ctx.request().getHeader("Authorization").substring("Bearer ".length());
JsonObject request = new JsonObject().put("action", "getProfile").put("token", token);
vertx.eventBus().request(Constants.HUERTOS_EVENT_BUS, request, ar -> {
if (ar.succeeded()) JsonUtil.sendJson(ctx, ApiStatus.OK, ar.result().body());
else EventBusUtil.handleReplyError(ctx, ar.cause(), "Profile not found");
});
}
public void hasCollaborator(RoutingContext ctx) {
String token = ctx.request().getHeader("Authorization").substring("Bearer ".length());
JsonObject request = new JsonObject().put("action", "hasCollaborator").put("token", token);
vertx.eventBus().request(Constants.HUERTOS_EVENT_BUS, request, ar -> {
if (ar.succeeded()) JsonUtil.sendJson(ctx, ApiStatus.OK, ar.result().body());
else EventBusUtil.handleReplyError(ctx, ar.cause(), "Profile not found");
});
}
public void hasCollaboratorRequest(RoutingContext ctx) {
String token = ctx.request().getHeader("Authorization").substring("Bearer ".length());
JsonObject request = new JsonObject().put("action", "hasCollaboratorRequest").put("token", token);
vertx.eventBus().request(Constants.HUERTOS_EVENT_BUS, request, ar -> {
if (ar.succeeded()) JsonUtil.sendJson(ctx, ApiStatus.OK, ar.result().body());
else EventBusUtil.handleReplyError(ctx, ar.cause(), "Profile not found");
});
}
public void hasGreenHouse(RoutingContext ctx) {
String token = ctx.request().getHeader("Authorization").substring("Bearer ".length());
JsonObject request = new JsonObject().put("action", "hasGreenHouse").put("token", token);
vertx.eventBus().request(Constants.HUERTOS_EVENT_BUS, request, ar -> {
if (ar.succeeded()) JsonUtil.sendJson(ctx, ApiStatus.OK, ar.result().body());
else EventBusUtil.handleReplyError(ctx, ar.cause(), "Profile not found");
});
}
public void hasGreenHouseRequest(RoutingContext ctx) {
String token = ctx.request().getHeader("Authorization").substring("Bearer ".length());
JsonObject request = new JsonObject().put("action", "hasGreenHouseRequest").put("token", token);
vertx.eventBus().request(Constants.HUERTOS_EVENT_BUS, request, ar -> {
if (ar.succeeded()) JsonUtil.sendJson(ctx, ApiStatus.OK, ar.result().body());
else EventBusUtil.handleReplyError(ctx, ar.cause(), "Profile not found");
});
}
public void changeMemberStatus(RoutingContext ctx) {
Integer memberNumber = Integer.parseInt(ctx.request().getParam("member_number"));
String status = ctx.request().getParam("status");
JsonObject request = new JsonObject()
.put("action", "changeMemberStatus")
.put("memberNumber", memberNumber)
.put("status", status);
vertx.eventBus().request(Constants.HUERTOS_EVENT_BUS, request, ar -> {
if (ar.succeeded()) JsonUtil.sendJson(ctx, ApiStatus.OK, ar.result().body());
else EventBusUtil.handleReplyError(ctx, ar.cause(), "Member not found");
});
}
public void changeMemberType(RoutingContext ctx) {
Integer memberNumber = Integer.parseInt(ctx.request().getParam("member_number"));
String type = ctx.request().getParam("type");
JsonObject request = new JsonObject()
.put("action", "changeMemberType")
.put("memberNumber", memberNumber)
.put("type", type);
vertx.eventBus().request(Constants.HUERTOS_EVENT_BUS, request, ar -> {
if (ar.succeeded()) JsonUtil.sendJson(ctx, ApiStatus.OK, ar.result().body());
else EventBusUtil.handleReplyError(ctx, ar.cause(), "Member not found");
});
}
public void validatePreUser(RoutingContext ctx) {
PreUserEntity preUser = Constants.GSON.fromJson(ctx.body().asJsonObject().encode(), PreUserEntity.class);
JsonObject request = new JsonObject()
.put("action", "validatePreUser")
.put("preUser", Constants.GSON.toJson(preUser));
vertx.eventBus().request(Constants.HUERTOS_EVENT_BUS, request, ar -> {
if (ar.succeeded()) {
JsonUtil.sendJson(ctx, ApiStatus.OK, ar.result().body());
} else {
Throwable cause = ar.cause();
if (cause instanceof io.vertx.core.eventbus.ReplyException replyEx && replyEx.failureCode() == 400) {
JsonObject errors = new JsonObject(replyEx.getMessage());
JsonUtil.sendJson(ctx, ApiStatus.BAD_REQUEST, null, errors.encode());
} else {
EventBusUtil.handleReplyError(ctx, cause, "Error validating pre-user");
}
}
});
}
}

View File

@@ -0,0 +1,58 @@
package net.miarma.api.microservices.huertos.handlers;
import io.vertx.ext.web.RoutingContext;
import io.vertx.sqlclient.Pool;
import net.miarma.api.backlib.http.ApiStatus;
import net.miarma.api.backlib.http.QueryParams;
import net.miarma.api.microservices.huertos.entities.PreUserEntity;
import net.miarma.api.microservices.huertos.services.PreUserService;
import net.miarma.api.backlib.util.JsonUtil;
@SuppressWarnings("unused")
public class PreUserDataHandler {
private final PreUserService preUserService;
public PreUserDataHandler(Pool pool) {
this.preUserService = new PreUserService(pool);
}
public void getAll(RoutingContext ctx) {
QueryParams params = QueryParams.from(ctx);
preUserService.getAll(params)
.onSuccess(preUsers -> JsonUtil.sendJson(ctx, ApiStatus.OK, preUsers))
.onFailure(err -> JsonUtil.sendJson(ctx, ApiStatus.fromException(err), null, err.getMessage()));
}
public void getById(RoutingContext ctx) {
Integer id = Integer.parseInt(ctx.request().getParam("id"));
preUserService.getById(id)
.onSuccess(preUser -> JsonUtil.sendJson(ctx, ApiStatus.OK, preUser))
.onFailure(err -> JsonUtil.sendJson(ctx, ApiStatus.fromException(err), null, err.getMessage()));
}
public void create(RoutingContext ctx) {
PreUserEntity preUser = net.miarma.api.backlib.Constants.GSON.fromJson(ctx.body().asString(), PreUserEntity.class);
preUserService.create(preUser)
.onSuccess(result -> JsonUtil.sendJson(ctx, ApiStatus.CREATED, result))
.onFailure(err -> JsonUtil.sendJson(ctx, ApiStatus.fromException(err), null, err.getMessage()));
}
public void update(RoutingContext ctx) {
PreUserEntity preUser = net.miarma.api.backlib.Constants.GSON.fromJson(ctx.body().asString(), PreUserEntity.class);
preUserService.update(preUser)
.onSuccess(result -> JsonUtil.sendJson(ctx, ApiStatus.OK, result))
.onFailure(err -> JsonUtil.sendJson(ctx, ApiStatus.fromException(err), null, err.getMessage()));
}
public void delete(RoutingContext ctx) {
Integer id = Integer.parseInt(ctx.request().getParam("pre_user_id"));
preUserService.delete(id)
.onSuccess(result -> JsonUtil.sendJson(ctx, ApiStatus.NO_CONTENT, null))
.onFailure(err -> JsonUtil.sendJson(ctx, ApiStatus.fromException(err), null, err.getMessage()));
}
}

View File

@@ -0,0 +1,5 @@
package net.miarma.api.microservices.huertos.handlers;
public class PreUserLogicHandler {
}

View File

@@ -0,0 +1,58 @@
package net.miarma.api.microservices.huertos.handlers;
import io.vertx.ext.web.RoutingContext;
import io.vertx.sqlclient.Pool;
import net.miarma.api.backlib.http.ApiStatus;
import net.miarma.api.backlib.http.QueryParams;
import net.miarma.api.microservices.huertos.entities.RequestEntity;
import net.miarma.api.microservices.huertos.services.RequestService;
import net.miarma.api.backlib.util.JsonUtil;
@SuppressWarnings("unused")
public class RequestDataHandler {
private final RequestService requestService;
public RequestDataHandler(Pool pool) {
this.requestService = new RequestService(pool);
}
public void getAll(RoutingContext ctx) {
QueryParams params = QueryParams.from(ctx);
requestService.getAll(params)
.onSuccess(requests -> JsonUtil.sendJson(ctx, ApiStatus.OK, requests))
.onFailure(err -> JsonUtil.sendJson(ctx, ApiStatus.fromException(err), null, err.getMessage()));
}
public void getById(RoutingContext ctx) {
Integer requestId = Integer.parseInt(ctx.pathParam("request_id"));
requestService.getById(requestId)
.onSuccess(request -> JsonUtil.sendJson(ctx, ApiStatus.OK, request))
.onFailure(err -> JsonUtil.sendJson(ctx, ApiStatus.fromException(err), null, err.getMessage()));
}
public void create(RoutingContext ctx) {
RequestEntity request = net.miarma.api.backlib.Constants.GSON.fromJson(ctx.body().asString(), RequestEntity.class);
requestService.create(request)
.onSuccess(result -> JsonUtil.sendJson(ctx, ApiStatus.CREATED, result))
.onFailure(err -> JsonUtil.sendJson(ctx, ApiStatus.fromException(err), null, err.getMessage()));
}
public void update(RoutingContext ctx) {
RequestEntity request = net.miarma.api.backlib.Constants.GSON.fromJson(ctx.body().asString(), RequestEntity.class);
requestService.update(request)
.onSuccess(result -> JsonUtil.sendJson(ctx, ApiStatus.NO_CONTENT, null))
.onFailure(err -> JsonUtil.sendJson(ctx, ApiStatus.fromException(err), null, err.getMessage()));
}
public void delete(RoutingContext ctx) {
Integer requestId = Integer.parseInt(ctx.pathParam("request_id"));
requestService.delete(requestId)
.onSuccess(result -> JsonUtil.sendJson(ctx, ApiStatus.NO_CONTENT, null))
.onFailure(err -> JsonUtil.sendJson(ctx, ApiStatus.fromException(err), null, err.getMessage()));
}
}

View File

@@ -0,0 +1,70 @@
package net.miarma.api.microservices.huertos.handlers;
import io.vertx.core.Vertx;
import io.vertx.core.json.JsonObject;
import io.vertx.ext.web.RoutingContext;
import net.miarma.api.backlib.Constants;
import net.miarma.api.backlib.http.ApiStatus;
import net.miarma.api.backlib.util.EventBusUtil;
import net.miarma.api.backlib.util.JsonUtil;
public class RequestLogicHandler {
private final Vertx vertx;
public RequestLogicHandler(Vertx vertx) {
this.vertx = vertx;
}
public void getRequestsWithPreUsers(RoutingContext ctx) {
JsonObject request = new JsonObject().put("action", "getRequestsWithPreUsers");
vertx.eventBus().request(Constants.HUERTOS_EVENT_BUS, request, ar -> {
if (ar.succeeded()) JsonUtil.sendJson(ctx, ApiStatus.OK, ar.result().body());
else EventBusUtil.handleReplyError(ctx, ar.cause(), "No requests found");
});
}
public void getRequestWithPreUser(RoutingContext ctx) {
Integer requestId = Integer.parseInt(ctx.request().getParam("request_id"));
JsonObject request = new JsonObject().put("action", "getRequestWithPreUser").put("requestId", requestId);
vertx.eventBus().request(Constants.HUERTOS_EVENT_BUS, request, ar -> {
if (ar.succeeded()) JsonUtil.sendJson(ctx, ApiStatus.OK, ar.result().body());
else EventBusUtil.handleReplyError(ctx, ar.cause(), "Request not found");
});
}
public void getRequestCount(RoutingContext ctx) {
JsonObject request = new JsonObject().put("action", "getRequestCount");
vertx.eventBus().request(Constants.HUERTOS_EVENT_BUS, request, ar -> {
if (ar.succeeded()) JsonUtil.sendJson(ctx, ApiStatus.OK, ar.result().body());
else EventBusUtil.handleReplyError(ctx, ar.cause(), "No requests found");
});
}
public void getMyRequests(RoutingContext ctx) {
String token = ctx.request().getHeader("Authorization").substring("Bearer ".length());
JsonObject request = new JsonObject().put("action", "getMyRequests").put("token", token);
vertx.eventBus().request(Constants.HUERTOS_EVENT_BUS, request, ar -> {
if (ar.succeeded()) JsonUtil.sendJson(ctx, ApiStatus.OK, ar.result().body());
else EventBusUtil.handleReplyError(ctx, ar.cause(), "No requests found");
});
}
public void acceptRequest(RoutingContext ctx) {
Integer requestId = Integer.parseInt(ctx.request().getParam("request_id"));
JsonObject request = new JsonObject().put("action", "acceptRequest").put("requestId", requestId);
vertx.eventBus().request(Constants.HUERTOS_EVENT_BUS, request, ar -> {
if (ar.succeeded()) JsonUtil.sendJson(ctx, ApiStatus.OK, ar.result().body());
else EventBusUtil.handleReplyError(ctx, ar.cause(), "Request not found");
});
}
public void rejectRequest(RoutingContext ctx) {
Integer requestId = Integer.parseInt(ctx.request().getParam("request_id"));
JsonObject request = new JsonObject().put("action", "rejectRequest").put("requestId", requestId);
vertx.eventBus().request(Constants.HUERTOS_EVENT_BUS, request, ar -> {
if (ar.succeeded()) JsonUtil.sendJson(ctx, ApiStatus.OK, ar.result().body());
else EventBusUtil.handleReplyError(ctx, ar.cause(), "Request not found");
});
}
}

View File

@@ -0,0 +1,72 @@
package net.miarma.api.microservices.huertos.mail;
import java.util.Arrays;
import java.util.Base64;
public class Attachment {
private String filename;
private String mimeType;
private transient byte[] data;
public Attachment() {}
public Attachment(String filename, String mimeType, byte[] data) {
this.filename = filename;
this.mimeType = mimeType;
this.data = data;
}
public String getFilename() {
return filename;
}
public void setFilename(String filename) {
this.filename = filename;
}
public String getMimeType() {
return mimeType;
}
public void setMimeType(String mimeType) {
this.mimeType = mimeType;
}
public byte[] getData() {
return data;
}
public void setData(byte[] data) {
this.data = data;
}
public String getBase64Data() {
return Base64.getEncoder().encodeToString(data);
}
@Override
public String toString() {
return "AttachmentEntity [filename=" + filename + ", mimeType=" + mimeType + ", data=" + Arrays.toString(data)
+ "]";
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + Arrays.hashCode(data);
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
Attachment other = (Attachment) obj;
return Arrays.equals(data, other.data);
}
}

View File

@@ -0,0 +1,153 @@
package net.miarma.api.microservices.huertos.mail;
import java.time.LocalDateTime;
import java.util.List;
import java.util.Properties;
import jakarta.mail.BodyPart;
import jakarta.mail.Folder;
import jakarta.mail.Message;
import jakarta.mail.MessagingException;
import jakarta.mail.Multipart;
import jakarta.mail.Part;
import jakarta.mail.Session;
import jakarta.mail.Store;
import jakarta.mail.internet.MimeMessage;
import jakarta.mail.internet.MimeUtility;
import net.miarma.api.backlib.ConfigManager;
public class ImapReader {
public static List<Mail> listInboxEmails(String folder, String username, String password) throws Exception {
Properties props = new Properties();
props.put("mail.store.protocol", "imaps");
System.setProperty("jakarta.mail.streamprovider", "jakarta.mail.util.DefaultStreamProvider");
Session session = Session.getInstance(props, null);
Store store = session.getStore();
store.connect(
ConfigManager.getInstance().getStringProperty("imap.server"),
ConfigManager.getInstance().getIntProperty("imap.port"),
username, password
);
Folder f = store.getFolder(folder);
f.open(Folder.READ_ONLY);
Message[] messages = f.getMessages();
List<Mail> emails = new java.util.ArrayList<>();
for (Message message : messages) {
String from = message.getFrom() != null ? message.getFrom()[0].toString() : "Desconocido";
from = MimeUtility.decodeText(from);
List<String> toList = new java.util.ArrayList<>();
if (message.getAllRecipients() != null) {
for (var address : message.getAllRecipients()) {
toList.add(address.toString());
}
}
String subject = message.getSubject();
String content = extractContent(message);
LocalDateTime date = message.getSentDate() != null
? message.getSentDate().toInstant().atZone(java.time.ZoneId.systemDefault()).toLocalDateTime()
: LocalDateTime.now();
List<Attachment> attachments = extractAttachments(message);
emails.add(new Mail(from, toList, subject, content, date, attachments));
}
f.close(false);
store.close();
return emails;
}
public static Mail getEmailByIndex(String folder, String username, String password, int index) throws Exception {
Properties props = new Properties();
props.put("mail.store.protocol", "imaps");
System.setProperty("jakarta.mail.streamprovider", "jakarta.mail.util.DefaultStreamProvider");
Session session = Session.getInstance(props, null);
Store store = session.getStore();
store.connect(
ConfigManager.getInstance().getStringProperty("imap.server"),
ConfigManager.getInstance().getIntProperty("imap.port"),
username, password
);
Folder f = store.getFolder(folder);
f.open(Folder.READ_ONLY);
Message[] messages = f.getMessages();
if (index < 0 || index >= messages.length) {
throw new IndexOutOfBoundsException("No message found with such index");
}
Message message = messages[index];
String from = message.getFrom() != null ? message.getFrom()[0].toString() : "Desconocido";
from = MimeUtility.decodeText(from);
List<String> toList = new java.util.ArrayList<>();
if (message.getAllRecipients() != null) {
for (var address : message.getAllRecipients()) {
toList.add(address.toString());
}
}
String subject = message.getSubject();
String content = extractContent(message);
LocalDateTime date = message.getSentDate() != null
? message.getSentDate().toInstant().atZone(java.time.ZoneId.systemDefault()).toLocalDateTime()
: LocalDateTime.now();
List<Attachment> attachments = extractAttachments(message);
f.close(false);
store.close();
return new Mail(from, toList, subject, content, date, attachments);
}
private static String extractContent(Message message) throws Exception {
Object content = message.getContent();
if (content instanceof String) {
return (String) content;
} else if (content instanceof Multipart) {
Multipart multipart = (Multipart) content;
for (int i = 0; i < multipart.getCount(); i++) {
BodyPart part = multipart.getBodyPart(i);
if (part.isMimeType("text/plain")) {
return part.getContent().toString();
} else if (part.isMimeType("text/html")) {
return part.getContent().toString();
}
}
}
return "";
}
private static List<Attachment> extractAttachments(Message message) throws Exception {
List<Attachment> attachments = new java.util.ArrayList<>();
if (message.getContent() instanceof Multipart multipart) {
for (int i = 0; i < multipart.getCount(); i++) {
BodyPart part = multipart.getBodyPart(i);
if (Part.ATTACHMENT.equalsIgnoreCase(part.getDisposition()) && part.getFileName() != null) {
String filename = part.getFileName();
String mimeType = part.getContentType().split(";")[0];
try (var inputStream = part.getInputStream()) {
byte[] data = inputStream.readAllBytes();
attachments.add(new Attachment(filename, mimeType, data));
}
}
}
}
return attachments;
}
}

View File

@@ -0,0 +1,85 @@
package net.miarma.api.microservices.huertos.mail;
import java.time.LocalDateTime;
import java.util.List;
public class Mail implements Comparable<Mail> {
private String from;
private List<String> to;
private String subject;
private String content;
private LocalDateTime date;
private List<Attachment> attachments;
public Mail() {}
public Mail(String from, List<String> to, String subject, String content, LocalDateTime date,
List<Attachment> attachments) {
this.from = from;
this.to = to;
this.subject = subject;
this.content = content;
this.date = date;
this.attachments = attachments;
}
public String getFrom() {
return from;
}
public void setFrom(String from) {
this.from = from;
}
public List<String> getTo() {
return to;
}
public void setTo(List<String> to) {
this.to = to;
}
public String getSubject() {
return subject;
}
public void setSubject(String subject) {
this.subject = subject;
}
public String getContent() {
return content;
}
public void setContent(String content) {
this.content = content;
}
public LocalDateTime getDate() {
return date;
}
public void setDate(LocalDateTime date) {
this.date = date;
}
public List<Attachment> getAttachments() {
return attachments;
}
public void setAttachments(List<Attachment> attachments) {
this.attachments = attachments;
}
@Override
public String toString() {
return "MailEntity [from=" + from + ", to=" + to + ", subject=" + subject + ", content=" + content + ", date="
+ date + ", attachments=" + attachments + "]";
}
@Override
public int compareTo(Mail other) {
return this.date.compareTo(other.date);
}
}

View File

@@ -0,0 +1,5 @@
package net.miarma.api.microservices.huertos.mail;
public record MailCredentials(String username, String password) {
}

View File

@@ -0,0 +1,126 @@
package net.miarma.api.microservices.huertos.mail;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.concurrent.ConcurrentHashMap;
import java.util.stream.Collectors;
import io.vertx.core.AsyncResult;
import io.vertx.core.Handler;
import io.vertx.core.Vertx;
import io.vertx.core.buffer.Buffer;
import io.vertx.ext.mail.LoginOption;
import io.vertx.ext.mail.MailAttachment;
import io.vertx.ext.mail.MailClient;
import io.vertx.ext.mail.MailConfig;
import io.vertx.ext.mail.MailMessage;
import io.vertx.ext.mail.MailResult;
import io.vertx.ext.mail.StartTLSOptions;
import jakarta.mail.Folder;
import jakarta.mail.Message;
import jakarta.mail.Session;
import jakarta.mail.Store;
import jakarta.mail.internet.InternetAddress;
import jakarta.mail.internet.MimeMessage;
import net.miarma.api.backlib.ConfigManager;
public class MailManager {
private final Vertx vertx;
private final String smtpHost;
private final int smtpPort;
private final Map<String, MailClient> clientCache = new ConcurrentHashMap<>();
public MailManager(Vertx vertx) {
this.vertx = vertx;
this.smtpHost = ConfigManager.getInstance().getStringProperty("smtp.server");
this.smtpPort = ConfigManager.getInstance().getIntProperty("smtp.port");
}
private MailClient getClientForUser(String username, String password) {
return clientCache.computeIfAbsent(username, _ -> {
MailConfig config = new MailConfig()
.setHostname(smtpHost)
.setPort(smtpPort)
.setStarttls(StartTLSOptions.REQUIRED)
.setLogin(LoginOption.REQUIRED)
.setUsername(username)
.setPassword(password)
.setKeepAlive(true);
return MailClient.createShared(vertx, config, "mail-pool-" + username);
});
}
public static void storeInSentFolder(Mail mail, String username, String password) {
try {
Properties props = new Properties();
props.put("mail.store.protocol", "imaps");
props.put("mail.imaps.host", ConfigManager.getInstance().getStringProperty("imap.server"));
props.put("mail.imaps.port", ConfigManager.getInstance().getIntProperty("imap.port"));
Session session = Session.getInstance(props);
Store store = session.getStore("imaps");
store.connect(username, password);
Folder sentFolder = store.getFolder("Sent");
if (!sentFolder.exists()) {
sentFolder.create(Folder.HOLDS_MESSAGES);
}
sentFolder.open(Folder.READ_WRITE);
MimeMessage message = new MimeMessage(session);
message.setFrom(new InternetAddress(mail.getFrom()));
for (String to : mail.getTo()) {
message.addRecipient(Message.RecipientType.TO, new InternetAddress(to));
}
message.setSubject(mail.getSubject());
message.setText(mail.getContent());
sentFolder.appendMessages(new Message[]{message});
sentFolder.close(false);
store.close();
} catch (Exception e) {
e.printStackTrace();
}
}
public void sendEmail(Mail mail, String username, String password, Handler<AsyncResult<MailResult>> resultHandler) {
MailMessage message = new MailMessage()
.setFrom(mail.getFrom())
.setTo(mail.getTo())
.setSubject(mail.getSubject())
.setText(mail.getContent());
getClientForUser(username, password).sendMail(message, ar -> {
resultHandler.handle(ar);
if(ar.succeeded()) {
storeInSentFolder(mail, username, password);
}
});
}
public void sendEmailWithAttachment(Mail mail, List<Attachment> attachments, String username, String password,
Handler<AsyncResult<MailResult>> resultHandler) {
List<MailAttachment> mailAttachments = attachments.stream().map(a -> {
return MailAttachment.create()
.setData(Buffer.buffer(a.getData()))
.setName(a.getFilename())
.setContentType(a.getMimeType())
.setDisposition("attachment");
}).collect(Collectors.toList());
MailMessage message = new MailMessage()
.setFrom(mail.getFrom())
.setTo(mail.getTo())
.setSubject(mail.getSubject())
.setText(mail.getContent())
.setAttachment(mailAttachments);
getClientForUser(username, password).sendMail(message, ar -> {
resultHandler.handle(ar);
if(ar.succeeded()) {
storeInSentFolder(mail, username, password);
}
});
}
}

View File

@@ -0,0 +1,76 @@
package net.miarma.api.microservices.huertos.routing;
import io.vertx.core.Vertx;
import io.vertx.ext.web.Router;
import io.vertx.ext.web.handler.BodyHandler;
import io.vertx.sqlclient.Pool;
import net.miarma.api.backlib.Constants.HuertosUserRole;
import net.miarma.api.backlib.util.RouterUtil;
import net.miarma.api.microservices.huertos.handlers.AnnouncementDataHandler;
import net.miarma.api.microservices.huertos.handlers.BalanceDataHandler;
import net.miarma.api.microservices.huertos.handlers.ExpenseDataHandler;
import net.miarma.api.microservices.huertos.handlers.IncomeDataHandler;
import net.miarma.api.microservices.huertos.handlers.MemberDataHandler;
import net.miarma.api.microservices.huertos.handlers.PreUserDataHandler;
import net.miarma.api.microservices.huertos.handlers.RequestDataHandler;
import net.miarma.api.microservices.huertos.routing.middlewares.HuertosAuthGuard;
import net.miarma.api.microservices.huertos.services.MemberService;
public class HuertosDataRouter {
public static void mount(Router router, Vertx vertx, Pool pool) {
AnnouncementDataHandler hAnnounceData = new AnnouncementDataHandler(pool);
BalanceDataHandler hBalanceData = new BalanceDataHandler(pool);
ExpenseDataHandler hExpenseData = new ExpenseDataHandler(pool);
IncomeDataHandler hIncomeData = new IncomeDataHandler(pool);
MemberDataHandler hMemberData = new MemberDataHandler(pool);
PreUserDataHandler hPreUserData = new PreUserDataHandler(pool);
RequestDataHandler hRequestData = new RequestDataHandler(pool);
MemberService memberService = new MemberService(pool);
HuertosAuthGuard authGuard = new HuertosAuthGuard(memberService);
router.route().handler(BodyHandler.create());
router.get(HuertosEndpoints.ANNOUNCES).handler(authGuard.check()).handler(hAnnounceData::getAll);
router.get(HuertosEndpoints.ANNOUNCE).handler(authGuard.check()).handler(hAnnounceData::getById);
router.post(HuertosEndpoints.ANNOUNCES).handler(authGuard.check(HuertosUserRole.ADMIN)).handler(hAnnounceData::create);
router.put(HuertosEndpoints.ANNOUNCE).handler(authGuard.check(HuertosUserRole.ADMIN)).handler(hAnnounceData::update);
router.delete(HuertosEndpoints.ANNOUNCE).handler(authGuard.check(HuertosUserRole.ADMIN)).handler(hAnnounceData::delete);
router.get(HuertosEndpoints.BALANCE).handler(authGuard.check(HuertosUserRole.ADMIN)).handler(hBalanceData::getBalance);
router.post(HuertosEndpoints.BALANCE).handler(authGuard.check(HuertosUserRole.ADMIN)).handler(hBalanceData::update);
router.delete(HuertosEndpoints.BALANCE).handler(authGuard.check(HuertosUserRole.ADMIN)).handler(hBalanceData::create);
router.get(HuertosEndpoints.EXPENSES).handler(authGuard.check(HuertosUserRole.ADMIN)).handler(hExpenseData::getAll);
router.get(HuertosEndpoints.EXPENSE).handler(authGuard.check(HuertosUserRole.ADMIN)).handler(hExpenseData::getById);
router.post(HuertosEndpoints.EXPENSES).handler(authGuard.check(HuertosUserRole.ADMIN)).handler(hExpenseData::create);
router.put(HuertosEndpoints.EXPENSE).handler(authGuard.check(HuertosUserRole.ADMIN)).handler(hExpenseData::update);
router.delete(HuertosEndpoints.EXPENSE).handler(authGuard.check(HuertosUserRole.ADMIN)).handler(hExpenseData::delete);
router.get(HuertosEndpoints.INCOMES).handler(authGuard.check(HuertosUserRole.ADMIN)).handler(hIncomeData::getAll);
router.get(HuertosEndpoints.INCOME).handler(authGuard.check(HuertosUserRole.ADMIN)).handler(hIncomeData::getById);
router.post(HuertosEndpoints.INCOMES).handler(authGuard.check(HuertosUserRole.ADMIN)).handler(hIncomeData::create);
router.put(HuertosEndpoints.INCOME).handler(authGuard.check(HuertosUserRole.ADMIN)).handler(hIncomeData::update);
router.delete(HuertosEndpoints.INCOME).handler(authGuard.check(HuertosUserRole.ADMIN)).handler(hIncomeData::delete);
router.get(HuertosEndpoints.INCOMES_WITH_NAMES).handler(authGuard.check(HuertosUserRole.ADMIN)).handler(hIncomeData::getIncomesWithNames);
router.get(HuertosEndpoints.MEMBERS).handler(authGuard.check(HuertosUserRole.ADMIN)).handler(hMemberData::getAll);
router.get(HuertosEndpoints.MEMBER).handler(authGuard.check(HuertosUserRole.ADMIN)).handler(hMemberData::getById);
router.post(HuertosEndpoints.MEMBERS).handler(authGuard.check(HuertosUserRole.ADMIN)).handler(hMemberData::create);
router.put(HuertosEndpoints.MEMBER).handler(authGuard.check(HuertosUserRole.ADMIN)).handler(hMemberData::update);
router.delete(HuertosEndpoints.MEMBER).handler(authGuard.check(HuertosUserRole.ADMIN)).handler(hMemberData::delete);
router.get(HuertosEndpoints.PRE_USERS).handler(authGuard.check(HuertosUserRole.ADMIN)).handler(hPreUserData::getAll);
router.get(HuertosEndpoints.PRE_USER).handler(authGuard.check(HuertosUserRole.ADMIN)).handler(hPreUserData::getById);
router.post(HuertosEndpoints.PRE_USERS).handler(hPreUserData::create);
router.put(HuertosEndpoints.PRE_USER).handler(authGuard.check(HuertosUserRole.ADMIN)).handler(hPreUserData::update);
router.delete(HuertosEndpoints.PRE_USER).handler(authGuard.check(HuertosUserRole.ADMIN)).handler(hPreUserData::delete);
router.get(HuertosEndpoints.REQUESTS).handler(authGuard.check(HuertosUserRole.ADMIN)).handler(hRequestData::getAll);
router.get(HuertosEndpoints.REQUEST).handler(authGuard.check(HuertosUserRole.ADMIN)).handler(hRequestData::getById);
router.post(HuertosEndpoints.REQUESTS).handler(hRequestData::create);
router.put(HuertosEndpoints.REQUEST).handler(authGuard.check(HuertosUserRole.ADMIN)).handler(hRequestData::update);
router.delete(HuertosEndpoints.REQUEST).handler(authGuard.check(HuertosUserRole.ADMIN)).handler(hRequestData::delete);
}
}

View File

@@ -0,0 +1,67 @@
package net.miarma.api.microservices.huertos.routing;
import net.miarma.api.backlib.Constants;
public class HuertosEndpoints {
// auth
public static final String LOGIN = Constants.HUERTOS_PREFIX + "/login";
// socios -> GET, POST, PUT, DELETE
public static final String MEMBERS = Constants.HUERTOS_PREFIX + "/members"; // GET, POST, PUT, DELETE
public static final String MEMBER = Constants.HUERTOS_PREFIX + "/members/:user_id"; // GET, POST, PUT, DELETE por id
public static final String MEMBER_BY_NUMBER = Constants.HUERTOS_PREFIX + "/members/number/:member_number"; // GET por número de socio
public static final String MEMBER_BY_PLOT = Constants.HUERTOS_PREFIX + "/members/plot/:plot_number"; // GET por número de parcela
public static final String MEMBER_BY_DNI = Constants.HUERTOS_PREFIX + "/members/dni/:dni"; // GET por DNI
public static final String MEMBER_PAYMENTS = Constants.HUERTOS_PREFIX + "/members/number/:member_number/incomes"; // GET ingresos de ese miembro
public static final String MEMBER_HAS_PAID = Constants.HUERTOS_PREFIX + "/members/number/:member_number/has-paid"; // GET si ha pagado
public static final String MEMBER_WAITLIST = Constants.HUERTOS_PREFIX + "/members/waitlist"; // GET todos los de la lista de espera
public static final String MEMBER_LIMITED_WAITLIST = Constants.HUERTOS_PREFIX + "/members/waitlist/limited"; // GET lista limitada
public static final String LAST_MEMBER_NUMBER = Constants.HUERTOS_PREFIX + "/members/latest-number"; // GET último número de socio usado
public static final String MEMBER_PROFILE = Constants.HUERTOS_PREFIX + "/members/profile"; // GET perfil del usuario logado (socio o admin)
public static final String MEMBER_HAS_COLLABORATOR = Constants.HUERTOS_PREFIX + "/members/number/:member_number/has-collaborator"; // GET si tiene colaborador asignado
public static final String MEMBER_HAS_COLLABORATOR_REQUEST = Constants.HUERTOS_PREFIX + "/members/number/:member_number/has-collaborator-request"; // GET si tiene solicitud de colaborador asignada
public static final String MEMBER_HAS_GREENHOUSE = Constants.HUERTOS_PREFIX + "/members/number/:member_number/has-greenhouse"; // GET si tiene invernadero asignado
public static final String MEMBER_HAS_GREENHOUSE_REQUEST = Constants.HUERTOS_PREFIX + "/members/number/:member_number/has-greenhouse-request"; // GET si tiene solicitud de invernadero asignada
public static final String CHANGE_MEMBER_STATUS = Constants.HUERTOS_PREFIX + "/members/:user_id/status"; // PUT cambiar estado de socio (activo, inactivo, baja, etc.)
public static final String CHANGE_MEMBER_TYPE = Constants.HUERTOS_PREFIX + "/members/:user_id/type"; // PUT cambiar tipo de socio (socio, colaborador, etc.)
// ingresos -> GET, POST, PUT, DELETE
public static final String INCOMES = Constants.HUERTOS_PREFIX + "/incomes";
public static final String INCOMES_WITH_NAMES = Constants.HUERTOS_PREFIX + "/incomes-with-names";
public static final String INCOME = Constants.HUERTOS_PREFIX + "/incomes/:income_id";
public static final String MY_INCOMES = Constants.HUERTOS_PREFIX + "/incomes/my-incomes"; // GET ingresos del usuario logado (socio o admin)
// gastos -> GET, POST, PUT, DELETE
public static final String EXPENSES = Constants.HUERTOS_PREFIX + "/expenses";
public static final String EXPENSE = Constants.HUERTOS_PREFIX + "/expenses/:expense_id";
// balance -> GET, POST, PUT, DELETE
public static final String BALANCE = Constants.HUERTOS_PREFIX + "/balance";
public static final String BALANCE_WITH_TOTALS = Constants.HUERTOS_PREFIX + "/balance/with-totals";
// anuncios -> GET, POST, PUT, DELETE
public static final String ANNOUNCES = Constants.HUERTOS_PREFIX + "/announces";
public static final String ANNOUNCE = Constants.HUERTOS_PREFIX + "/announces/:announce_id";
// solicitudes -> GET, POST, PUT, DELETE
public static final String REQUESTS = Constants.HUERTOS_PREFIX + "/requests";
public static final String REQUEST = Constants.HUERTOS_PREFIX + "/requests/:request_id";
public static final String REQUEST_COUNT = Constants.HUERTOS_PREFIX + "/requests/count"; // GET número de solicitudes
public static final String MY_REQUESTS = Constants.HUERTOS_PREFIX + "/requests/my-requests"; // GET solicitudes del usuario logado (socio o admin)
public static final String ACCEPT_REQUEST = Constants.HUERTOS_PREFIX + "/requests/:request_id/accept"; // PUT aceptar solicitud
public static final String REJECT_REQUEST = Constants.HUERTOS_PREFIX + "/requests/:request_id/reject"; // PUT rechazar solicitud
// pre-socios -> GET, POST, PUT, DELETE
public static final String PRE_USERS = Constants.HUERTOS_PREFIX + "/pre_users";
public static final String PRE_USER = Constants.HUERTOS_PREFIX + "/pre_users/:pre_user_id";
public static final String PRE_USER_VALIDATE = Constants.HUERTOS_PREFIX + "/pre_users/validate"; // POST validar pre-socio
// solicitud + pre-socio -> GET
public static final String REQUESTS_WITH_PRE_USERS = Constants.HUERTOS_PREFIX + "/requests-full";
public static final String REQUEST_WITH_PRE_USER = Constants.HUERTOS_PREFIX + "/requests-full/:request_id";
// mail
public static final String SEND_MAIL = Constants.HUERTOS_PREFIX + "/mails/send"; // POST
public static final String MAIL = Constants.HUERTOS_PREFIX + "/mails/:folder/:index"; // GET
public static final String MAILS = Constants.HUERTOS_PREFIX + "/mails/:folder"; // GET
}

View File

@@ -0,0 +1,60 @@
package net.miarma.api.microservices.huertos.routing;
import io.vertx.core.Vertx;
import io.vertx.ext.web.Router;
import io.vertx.ext.web.handler.BodyHandler;
import io.vertx.sqlclient.Pool;
import net.miarma.api.backlib.util.RouterUtil;
import net.miarma.api.microservices.huertos.handlers.BalanceLogicHandler;
import net.miarma.api.microservices.huertos.handlers.IncomeLogicHandler;
import net.miarma.api.microservices.huertos.handlers.MailHandler;
import net.miarma.api.microservices.huertos.handlers.MemberLogicHandler;
import net.miarma.api.microservices.huertos.handlers.RequestLogicHandler;
import net.miarma.api.microservices.huertos.routing.middlewares.HuertosAuthGuard;
import net.miarma.api.microservices.huertos.services.MemberService;
public class HuertosLogicRouter {
public static void mount(Router router, Vertx vertx, Pool pool) {
MemberLogicHandler hMemberLogic = new MemberLogicHandler(vertx);
MemberService memberService = new MemberService(pool);
IncomeLogicHandler hIncomeLogic = new IncomeLogicHandler(vertx);
BalanceLogicHandler hBalanceLogic = new BalanceLogicHandler(vertx);
RequestLogicHandler hRequestLogic = new RequestLogicHandler(vertx);
MailHandler hMail = new MailHandler(vertx, pool);
HuertosAuthGuard authGuard = new HuertosAuthGuard(memberService);
router.route().handler(BodyHandler.create());
router.post(HuertosEndpoints.LOGIN).handler(hMemberLogic::login);
router.get(HuertosEndpoints.MEMBER_BY_NUMBER).handler(authGuard.check()).handler(hMemberLogic::getByMemberNumber);
router.get(HuertosEndpoints.MEMBER_BY_PLOT).handler(authGuard.check()).handler(hMemberLogic::getByPlotNumber);
router.get(HuertosEndpoints.MEMBER_BY_DNI).handler(authGuard.check()).handler(hMemberLogic::getByDni);
router.get(HuertosEndpoints.MEMBER_PAYMENTS).handler(authGuard.check()).handler(hMemberLogic::getUserPayments);
router.get(HuertosEndpoints.MEMBER_HAS_PAID).handler(authGuard.check()).handler(hMemberLogic::hasPaid);
router.get(HuertosEndpoints.MEMBER_WAITLIST).handler(authGuard.check()).handler(hMemberLogic::getWaitlist);
router.get(HuertosEndpoints.MEMBER_LIMITED_WAITLIST).handler(hMemberLogic::getLimitedWaitlist);
router.get(HuertosEndpoints.LAST_MEMBER_NUMBER).handler(hMemberLogic::getLastMemberNumber);
router.get(HuertosEndpoints.BALANCE_WITH_TOTALS).handler(authGuard.check()).handler(hBalanceLogic::getBalanceWithTotals);
router.get(HuertosEndpoints.REQUESTS_WITH_PRE_USERS).handler(authGuard.check()).handler(hRequestLogic::getRequestsWithPreUsers);
router.get(HuertosEndpoints.REQUEST_WITH_PRE_USER).handler(authGuard.check()).handler(hRequestLogic::getRequestWithPreUser);
router.get(HuertosEndpoints.MEMBER_PROFILE).handler(hMemberLogic::getProfile);
router.get(HuertosEndpoints.REQUEST_COUNT).handler(authGuard.check()).handler(hRequestLogic::getRequestCount);
router.get(HuertosEndpoints.MY_INCOMES).handler(authGuard.check()).handler(hIncomeLogic::getMyIncomes);
router.get(HuertosEndpoints.MY_REQUESTS).handler(authGuard.check()).handler(hRequestLogic::getMyRequests);
router.put(HuertosEndpoints.ACCEPT_REQUEST).handler(authGuard.check()).handler(hRequestLogic::acceptRequest);
router.put(HuertosEndpoints.REJECT_REQUEST).handler(authGuard.check()).handler(hRequestLogic::rejectRequest);
router.put(HuertosEndpoints.CHANGE_MEMBER_STATUS).handler(authGuard.check()).handler(hMemberLogic::changeMemberStatus);
router.put(HuertosEndpoints.CHANGE_MEMBER_TYPE).handler(authGuard.check()).handler(hMemberLogic::changeMemberType);
router.get(HuertosEndpoints.MEMBER_HAS_COLLABORATOR).handler(authGuard.check()).handler(hMemberLogic::hasCollaborator);
router.get(HuertosEndpoints.MEMBER_HAS_COLLABORATOR_REQUEST).handler(authGuard.check()).handler(hMemberLogic::hasCollaboratorRequest);
router.get(HuertosEndpoints.MEMBER_HAS_GREENHOUSE).handler(authGuard.check()).handler(hMemberLogic::hasGreenHouse);
router.get(HuertosEndpoints.MEMBER_HAS_GREENHOUSE_REQUEST).handler(authGuard.check()).handler(hMemberLogic::hasGreenHouseRequest);
router.post(HuertosEndpoints.PRE_USER_VALIDATE).handler(hMemberLogic::validatePreUser);
router.get(HuertosEndpoints.MAILS).handler(hMail::getFolder);
router.get(HuertosEndpoints.MAIL).handler(hMail::getMail);
router.post(HuertosEndpoints.SEND_MAIL).handler(hMail::sendMail);
}
}

View File

@@ -0,0 +1,35 @@
package net.miarma.api.microservices.huertos.routing.middlewares;
import java.util.function.Consumer;
import io.vertx.ext.web.RoutingContext;
import net.miarma.api.backlib.Constants.HuertosUserRole;
import net.miarma.api.backlib.middlewares.AbstractAuthGuard;
import net.miarma.api.microservices.huertos.entities.MemberEntity;
import net.miarma.api.microservices.huertos.services.MemberService;
public class HuertosAuthGuard extends AbstractAuthGuard<MemberEntity, HuertosUserRole> {
private final MemberService memberService;
public HuertosAuthGuard(MemberService memberService) {
this.memberService = memberService;
}
@Override
protected HuertosUserRole parseRole(String roleStr) {
return HuertosUserRole.valueOf(roleStr.toUpperCase());
}
@Override
protected void getUserEntity(int userId, RoutingContext ctx, Consumer<MemberEntity> callback) {
memberService.getById(userId).onComplete(ar -> {
if (ar.succeeded()) callback.accept(ar.result());
else callback.accept(null);
});
}
@Override
protected boolean hasPermission(MemberEntity user, HuertosUserRole role) {
return user.getRole() == HuertosUserRole.ADMIN;
}
}

View File

@@ -0,0 +1,69 @@
package net.miarma.api.microservices.huertos.services;
import io.vertx.core.Future;
import io.vertx.sqlclient.Pool;
import net.miarma.api.backlib.Constants;
import net.miarma.api.backlib.exceptions.NotFoundException;
import net.miarma.api.backlib.exceptions.ValidationException;
import net.miarma.api.backlib.http.QueryParams;
import net.miarma.api.microservices.huertos.dao.AnnouncementDAO;
import net.miarma.api.microservices.huertos.entities.AnnouncementEntity;
import net.miarma.api.microservices.huertos.validators.AnnouncementValidator;
import java.util.List;
public class AnnouncementService {
private final AnnouncementDAO announcementDAO;
private final AnnouncementValidator announcementValidator;
public AnnouncementService(Pool pool) {
this.announcementDAO = new AnnouncementDAO(pool);
this.announcementValidator = new AnnouncementValidator();
}
public Future<List<AnnouncementEntity>> getAll(QueryParams params) {
return announcementDAO.getAll(params);
}
public Future<AnnouncementEntity> getById(Integer id) {
return announcementDAO.getById(id).compose(announce -> {
if (announce == null) {
return Future.failedFuture(new NotFoundException("Announce not found in the database"));
}
return Future.succeededFuture(announce);
});
}
public Future<AnnouncementEntity> create(AnnouncementEntity announce) {
return announcementValidator.validate(announce).compose(validation -> {
if (!validation.isValid()) {
return Future.failedFuture(new ValidationException(Constants.GSON.toJson(validation.getErrors())));
}
return announcementDAO.insert(announce);
});
}
public Future<AnnouncementEntity> update(AnnouncementEntity announce) {
return getById(announce.getAnnounce_id()).compose(existing -> {
if (existing == null) {
return Future.failedFuture(new NotFoundException("Announce not found in the database"));
}
return announcementValidator.validate(announce).compose(validation -> {
if (!validation.isValid()) {
return Future.failedFuture(new ValidationException(Constants.GSON.toJson(validation.getErrors())));
}
return announcementDAO.update(announce);
});
});
}
public Future<Boolean> delete(Integer id) {
return getById(id).compose(existing -> {
if (existing == null) {
return Future.failedFuture(new NotFoundException("Announce not found in the database"));
}
return announcementDAO.delete(id);
});
}
}

View File

@@ -0,0 +1,63 @@
package net.miarma.api.microservices.huertos.services;
import io.vertx.core.Future;
import io.vertx.sqlclient.Pool;
import net.miarma.api.backlib.Constants;
import net.miarma.api.backlib.exceptions.NotFoundException;
import net.miarma.api.backlib.exceptions.ValidationException;
import net.miarma.api.microservices.huertos.dao.BalanceDAO;
import net.miarma.api.microservices.huertos.entities.BalanceEntity;
import net.miarma.api.microservices.huertos.entities.ViewBalanceWithTotals;
import net.miarma.api.microservices.huertos.validators.BalanceValidator;
public class BalanceService {
private final BalanceDAO balanceDAO;
private final BalanceValidator balanceValidator;
public BalanceService(Pool pool) {
this.balanceDAO = new BalanceDAO(pool);
this.balanceValidator = new BalanceValidator();
}
public Future<BalanceEntity> getBalance() {
return balanceDAO.getAll().compose(balanceList -> {
if (balanceList.isEmpty()) {
return Future.failedFuture(new NotFoundException("Balance in the database"));
}
return Future.succeededFuture(balanceList.getFirst());
});
}
public Future<ViewBalanceWithTotals> getBalanceWithTotals() {
return balanceDAO.getAllWithTotals().compose(balanceList -> {
if (balanceList.isEmpty()) {
return Future.failedFuture(new NotFoundException("Balance in the database"));
}
return Future.succeededFuture(balanceList.getFirst());
});
}
public Future<BalanceEntity> update(BalanceEntity balance) {
return getBalance().compose(existing -> {
if (existing == null) {
return Future.failedFuture(new NotFoundException("Balance in the database"));
}
return balanceValidator.validate(balance).compose(validation -> {
if (!validation.isValid()) {
return Future.failedFuture(new ValidationException(Constants.GSON.toJson(validation.getErrors())));
}
return balanceDAO.update(balance);
});
});
}
public Future<BalanceEntity> create(BalanceEntity balance) {
return balanceValidator.validate(balance).compose(validation -> {
if (!validation.isValid()) {
return Future.failedFuture(new ValidationException(Constants.GSON.toJson(validation.getErrors())));
}
return balanceDAO.insert(balance);
});
}
}

View File

@@ -0,0 +1,74 @@
package net.miarma.api.microservices.huertos.services;
import io.vertx.core.Future;
import io.vertx.sqlclient.Pool;
import net.miarma.api.backlib.Constants;
import net.miarma.api.backlib.exceptions.NotFoundException;
import net.miarma.api.backlib.exceptions.ValidationException;
import net.miarma.api.backlib.http.QueryParams;
import net.miarma.api.microservices.huertos.dao.ExpenseDAO;
import net.miarma.api.microservices.huertos.entities.ExpenseEntity;
import net.miarma.api.microservices.huertos.validators.ExpenseValidator;
import java.util.List;
public class ExpenseService {
private final ExpenseDAO expenseDAO;
private final ExpenseValidator expenseValidator;
public ExpenseService(Pool pool) {
this.expenseDAO = new ExpenseDAO(pool);
this.expenseValidator = new ExpenseValidator();
}
public Future<List<ExpenseEntity>> getAll(QueryParams params) {
return expenseDAO.getAll(params);
}
public Future<ExpenseEntity> getById(Integer id) {
return expenseDAO.getAll().compose(expenses -> {
ExpenseEntity expense = expenses.stream()
.filter(e -> e.getExpense_id().equals(id))
.findFirst()
.orElse(null);
if (expense == null) {
return Future.failedFuture(new NotFoundException("Expense with id " + id + " not found"));
}
return Future.succeededFuture(expense);
});
}
public Future<ExpenseEntity> create(ExpenseEntity expense) {
return expenseValidator.validate(expense).compose(validation -> {
if (!validation.isValid()) {
return Future.failedFuture(new ValidationException(Constants.GSON.toJson(validation.getErrors())));
}
return expenseDAO.insert(expense);
});
}
public Future<ExpenseEntity> update(ExpenseEntity expense) {
return getById(expense.getExpense_id()).compose(existing -> {
if (existing == null) {
return Future.failedFuture(new NotFoundException("Expense not found"));
}
return expenseValidator.validate(expense).compose(validation -> {
if (!validation.isValid()) {
return Future.failedFuture(new ValidationException(Constants.GSON.toJson(validation.getErrors())));
}
return expenseDAO.update(expense);
});
});
}
public Future<Boolean> delete(Integer id) {
return getById(id).compose(expense -> {
if (expense == null) {
return Future.failedFuture(new NotFoundException("Expense with id " + id + " not found"));
}
return expenseDAO.delete(id);
});
}
}

View File

@@ -0,0 +1,92 @@
package net.miarma.api.microservices.huertos.services;
import java.util.List;
import io.vertx.core.Future;
import io.vertx.sqlclient.Pool;
import net.miarma.api.backlib.Constants;
import net.miarma.api.backlib.exceptions.NotFoundException;
import net.miarma.api.backlib.exceptions.ValidationException;
import net.miarma.api.backlib.http.QueryParams;
import net.miarma.api.backlib.security.JWTManager;
import net.miarma.api.microservices.huertos.dao.IncomeDAO;
import net.miarma.api.microservices.huertos.entities.IncomeEntity;
import net.miarma.api.microservices.huertos.entities.ViewIncomesWithFullNames;
import net.miarma.api.microservices.huertos.validators.IncomeValidator;
public class IncomeService {
private final IncomeDAO incomeDAO;
private final MemberService memberService;
private final IncomeValidator incomeValidator;
public IncomeService(Pool pool) {
this.incomeDAO = new IncomeDAO(pool);
this.memberService = new MemberService(pool);
this.incomeValidator = new IncomeValidator();
}
public Future<List<IncomeEntity>> getAll(QueryParams params) {
return incomeDAO.getAll(params);
}
public Future<List<ViewIncomesWithFullNames>> getIncomesWithNames(QueryParams params) {
return incomeDAO.getAllWithNames(params);
}
public Future<IncomeEntity> getById(Integer id) {
return incomeDAO.getById(id);
}
public Future<List<IncomeEntity>> getMyIncomes(String token) {
Integer userId = JWTManager.getInstance().getUserId(token);
return memberService.getById(userId).compose(memberEntity -> incomeDAO.getUserIncomes(memberEntity.getMember_number()));
}
public Future<List<IncomeEntity>> getUserPayments(Integer memberNumber) {
return incomeDAO.getUserIncomes(memberNumber);
}
public Future<Boolean> hasPaid(Integer memberNumber) {
return getUserPayments(memberNumber).compose(incomes -> {
boolean hasPaid = incomes.stream().anyMatch(IncomeEntity::isPaid);
return Future.succeededFuture(hasPaid);
});
}
public Future<IncomeEntity> create(IncomeEntity income) {
return incomeValidator.validate(income).compose(validation -> {
if (!validation.isValid()) {
return Future.failedFuture(new ValidationException(Constants.GSON.toJson(validation.getErrors())));
}
return incomeDAO.insert(income);
});
}
public Future<IncomeEntity> update(IncomeEntity income) {
return getById(income.getIncome_id()).compose(existing -> {
if (existing == null) {
return Future.failedFuture(new NotFoundException("Income in the database"));
}
return incomeValidator.validate(income).compose(validation -> {
if (!validation.isValid()) {
return Future.failedFuture(new ValidationException(Constants.GSON.toJson(validation.getErrors())));
}
return incomeDAO.update(income);
});
});
}
public Future<Boolean> delete(Integer id) {
return getById(id).compose(income -> {
if (income == null) {
return Future.failedFuture(new NotFoundException("Income with id " + id + " not found"));
}
return incomeDAO.delete(id);
});
}
}

View File

@@ -0,0 +1,304 @@
package net.miarma.api.microservices.huertos.services;
import java.util.List;
import io.vertx.core.Future;
import io.vertx.core.json.JsonObject;
import io.vertx.sqlclient.Pool;
import net.miarma.api.backlib.Constants;
import net.miarma.api.backlib.Constants.HuertosUserRole;
import net.miarma.api.backlib.Constants.HuertosUserStatus;
import net.miarma.api.backlib.Constants.HuertosUserType;
import net.miarma.api.backlib.exceptions.BadRequestException;
import net.miarma.api.backlib.exceptions.ForbiddenException;
import net.miarma.api.backlib.exceptions.NotFoundException;
import net.miarma.api.backlib.exceptions.ValidationException;
import net.miarma.api.backlib.http.QueryParams;
import net.miarma.api.backlib.security.JWTManager;
import net.miarma.api.backlib.security.PasswordHasher;
import net.miarma.api.backlib.core.dao.UserDAO;
import net.miarma.api.backlib.core.entities.UserEntity;
import net.miarma.api.backlib.core.services.UserService;
import net.miarma.api.microservices.huertos.dao.MemberDAO;
import net.miarma.api.microservices.huertos.dao.UserMetadataDAO;
import net.miarma.api.microservices.huertos.entities.MemberEntity;
import net.miarma.api.microservices.huertos.entities.PreUserEntity;
import net.miarma.api.microservices.huertos.entities.UserMetadataEntity;
import net.miarma.api.microservices.huertos.validators.MemberValidator;
@SuppressWarnings("unused")
public class MemberService {
private final UserDAO userDAO;
private final UserMetadataDAO userMetadataDAO;
private final MemberDAO memberDAO;
private final UserService userService;
private final MemberValidator memberValidator;
public MemberService(Pool pool) {
this.userDAO = new UserDAO(pool);
this.memberDAO = new MemberDAO(pool);
this.userMetadataDAO = new UserMetadataDAO(pool);
this.userService = new UserService(pool);
this.memberValidator = new MemberValidator();
}
public Future<JsonObject> login(String emailOrUserName, String password, boolean keepLoggedIn) {
return userService.login(emailOrUserName, password, keepLoggedIn).compose(json -> {
JsonObject loggedUserJson = json.getJsonObject("loggedUser");
UserEntity user = Constants.GSON.fromJson(loggedUserJson.encode(), UserEntity.class);
if (user == null) {
return Future.failedFuture(new BadRequestException("Invalid credentials"));
}
if (user.getGlobal_status() != Constants.CoreUserGlobalStatus.ACTIVE) {
return Future.failedFuture(new ForbiddenException("User is not active"));
}
return userMetadataDAO.getById(user.getUser_id()).compose(metadata -> {
if (metadata.getStatus() != HuertosUserStatus.ACTIVE) {
return Future.failedFuture(new ForbiddenException("User is not active"));
}
MemberEntity member = new MemberEntity(user, metadata);
return Future.succeededFuture(new JsonObject()
.put("token", json.getString("token"))
.put("member", new JsonObject(Constants.GSON.toJson(member)))
);
});
});
}
public Future<List<MemberEntity>> getAll() {
return memberDAO.getAll().compose(list -> Future.succeededFuture(list.stream()
.filter(m -> !m.getType().equals(HuertosUserType.DEVELOPER))
.toList()));
}
public Future<List<MemberEntity>> getAll(QueryParams params) {
return memberDAO.getAll(params).compose(list -> Future.succeededFuture(list.stream()
.filter(m -> !m.getType().equals(HuertosUserType.DEVELOPER))
.toList()));
}
public Future<MemberEntity> getById(Integer id) {
return memberDAO.getById(id).compose(member -> {
if (member == null) {
return Future.failedFuture(new NotFoundException("Member with id " + id));
}
return Future.succeededFuture(member);
});
}
public Future<MemberEntity> getByMemberNumber(Integer memberNumber) {
return memberDAO.getByMemberNumber(memberNumber).compose(member -> {
if (member == null) {
return Future.failedFuture(new NotFoundException("Member with member number " + memberNumber));
}
return Future.succeededFuture(member);
});
}
public Future<MemberEntity> getByPlotNumber(Integer plotNumber) {
return memberDAO.getByPlotNumber(plotNumber).compose(member -> {
if (member == null) {
return Future.failedFuture(new NotFoundException("Member with plot number " + plotNumber));
}
return Future.succeededFuture(member);
});
}
public Future<MemberEntity> getByEmail(String email) {
return memberDAO.getByEmail(email).compose(member -> {
if (member == null) {
return Future.failedFuture(new NotFoundException("Member with email " + email));
}
return Future.succeededFuture(member);
});
}
public Future<MemberEntity> getByDni(String dni) {
return memberDAO.getByDni(dni).compose(member -> {
if (member == null) {
return Future.failedFuture(new NotFoundException("Member with DNI " + dni));
}
return Future.succeededFuture(member);
});
}
public Future<MemberEntity> getByPhone(Integer phone) {
return memberDAO.getByPhone(phone).compose(member -> {
if (member == null) {
return Future.failedFuture(new NotFoundException("Member with phone " + phone));
}
return Future.succeededFuture(member);
});
}
public Future<List<MemberEntity>> getWaitlist() {
return memberDAO.getWaitlist().compose(list -> {
if (list.isEmpty()) {
return Future.failedFuture(new NotFoundException("No members in the waitlist"));
}
return Future.succeededFuture(list);
});
}
public Future<Integer> getLastMemberNumber() {
return memberDAO.getLastMemberNumber().compose(number -> {
if (number == null) {
return Future.failedFuture(new NotFoundException("No members found"));
}
return Future.succeededFuture(number);
});
}
public Future<Boolean> hasCollaborator(String token) {
Integer userId = JWTManager.getInstance().getUserId(token);
return getById(userId).compose(member -> {
Integer plotNumber = member.getPlot_number();
if (plotNumber == null || plotNumber == 0) {
return Future.succeededFuture(false);
}
return memberDAO.hasCollaborator(plotNumber).compose(hasCollaborator -> {
if (!hasCollaborator) {
return Future.failedFuture(new NotFoundException("User does not have a collaborator"));
}
return Future.succeededFuture(true);
});
});
}
public Future<MemberEntity> getCollaborator(Integer plotNumber) {
return memberDAO.getCollaborator(plotNumber).compose(collaborator -> {
if (collaborator == null) {
return Future.failedFuture(new NotFoundException("No collaborator found for plot number " + plotNumber));
}
return Future.succeededFuture(collaborator);
});
}
public Future<Boolean> hasGreenHouse(String token) {
Integer userId = JWTManager.getInstance().getUserId(token);
return getById(userId).map(user -> user.getType() == HuertosUserType.WITH_GREENHOUSE);
}
public Future<MemberEntity> updateRole(Integer userId, HuertosUserRole role) {
return getById(userId).compose(member -> {
member.setRole(role);
return userMetadataDAO.update(UserMetadataEntity.fromMemberEntity(member))
.compose(updated -> getById(userId));
});
}
public Future<MemberEntity> updateStatus(Integer userId, HuertosUserStatus status) {
return getById(userId).compose(member -> {
member.setStatus(status);
return userMetadataDAO.update(UserMetadataEntity.fromMemberEntity(member))
.compose(updated -> getById(userId));
});
}
public Future<MemberEntity> create(MemberEntity member) {
return memberValidator.validate(member).compose(validation -> {
if (!validation.isValid()) {
return Future.failedFuture(new ValidationException(Constants.GSON.toJson(validation.getErrors())));
}
member.setPassword(PasswordHasher.hash(member.getPassword()));
if (member.getEmail().isBlank()) member.setEmail(null);
return userDAO.insert(UserEntity.from(member)).compose(user -> {
UserMetadataEntity metadata = UserMetadataEntity.fromMemberEntity(member);
metadata.setUser_id(user.getUser_id());
return userMetadataDAO.insert(metadata).compose(meta -> {
String baseName = member.getDisplay_name().split(" ")[0].toLowerCase();
String userName = baseName + member.getMember_number();
user.setUser_name(userName);
return userDAO.update(user).map(updatedUser -> new MemberEntity(updatedUser, meta));
});
});
});
}
public Future<MemberEntity> createFromPreUser(PreUserEntity preUser) {
MemberEntity memberFromPreUser = MemberEntity.fromPreUser(preUser);
return memberValidator.validate(memberFromPreUser).compose(validation -> {
if (!validation.isValid()) {
return Future.failedFuture(new ValidationException(Constants.GSON.toJson(validation.getErrors())));
}
memberFromPreUser.setPassword(PasswordHasher.hash(memberFromPreUser.getPassword()));
return userDAO.insert(UserEntity.from(memberFromPreUser)).compose(user -> {
UserMetadataEntity metadata = UserMetadataEntity.fromMemberEntity(memberFromPreUser);
metadata.setUser_id(user.getUser_id());
return userMetadataDAO.insert(metadata)
.map(meta -> new MemberEntity(user, meta));
});
});
}
public Future<MemberEntity> update(MemberEntity member) {
return getById(member.getUser_id()).compose(existing -> {
if (existing == null) {
return Future.failedFuture(new NotFoundException("Member in the database"));
}
return memberValidator.validate(member).compose(validation -> {
if (!validation.isValid()) {
return Future.failedFuture(new ValidationException(Constants.GSON.toJson(validation.getErrors())));
}
if (member.getPassword() != null && !member.getPassword().isEmpty() &&
!member.getPassword().equals(existing.getPassword())) {
member.setPassword(PasswordHasher.hash(member.getPassword()));
} else {
member.setPassword(existing.getPassword());
}
return userDAO.update(UserEntity.from(member)).compose(user -> userMetadataDAO.updateWithNulls(UserMetadataEntity.fromMemberEntity(member))
.map(meta -> new MemberEntity(user, meta)));
});
});
}
public Future<MemberEntity> delete(Integer userId) {
return getById(userId).compose(member ->
userDAO.delete(userId).compose(deletedUser ->
userMetadataDAO.delete(member.getUser_id())
.map(deletedMetadata -> member)
)
);
}
public Future<MemberEntity> changeMemberStatus(Integer userId, HuertosUserStatus status) {
return getById(userId).compose(member -> {
member.setStatus(status);
return userMetadataDAO.update(UserMetadataEntity.fromMemberEntity(member))
.map(updated -> member);
});
}
public Future<MemberEntity> changeMemberType(Integer userId, HuertosUserType type) {
return getById(userId).compose(member -> {
member.setType(type);
return userMetadataDAO.update(UserMetadataEntity.fromMemberEntity(member))
.map(updated -> member);
});
}
}

View File

@@ -0,0 +1,83 @@
package net.miarma.api.microservices.huertos.services;
import io.vertx.core.Future;
import io.vertx.sqlclient.Pool;
import net.miarma.api.backlib.Constants;
import net.miarma.api.backlib.exceptions.NotFoundException;
import net.miarma.api.backlib.exceptions.ValidationException;
import net.miarma.api.backlib.http.QueryParams;
import net.miarma.api.microservices.huertos.dao.PreUserDAO;
import net.miarma.api.microservices.huertos.entities.PreUserEntity;
import net.miarma.api.microservices.huertos.validators.PreUserValidator;
import java.util.List;
public class PreUserService {
private final PreUserDAO preUserDAO;
private final PreUserValidator preUserValidator;
public PreUserService(Pool pool) {
this.preUserDAO = new PreUserDAO(pool);
this.preUserValidator = new PreUserValidator();
}
public Future<List<PreUserEntity>> getAll(QueryParams params) {
return preUserDAO.getAll(params);
}
public Future<PreUserEntity> getById(Integer id) {
return preUserDAO.getById(id).compose(preUser -> {
if (preUser == null) {
return Future.failedFuture(new NotFoundException("PreUser with id " + id));
}
return Future.succeededFuture(preUser);
});
}
public Future<PreUserEntity> getByRequestId(Integer requestId) {
return preUserDAO.getByRequestId(requestId).compose(preUser -> {
if (preUser == null) {
return Future.failedFuture(new NotFoundException("PreUser with request id " + requestId));
}
return Future.succeededFuture(preUser);
});
}
public Future<PreUserEntity> validatePreUser(String json) {
PreUserEntity preUser = Constants.GSON.fromJson(json, PreUserEntity.class);
return preUserValidator.validate(preUser, false).compose(validation -> {
if (!validation.isValid()) {
return Future.failedFuture(new ValidationException(Constants.GSON.toJson(validation.getErrors())));
}
return Future.succeededFuture(preUser);
});
}
public Future<PreUserEntity> create(PreUserEntity preUser) {
return preUserValidator.validate(preUser, true).compose(validation -> {
if (!validation.isValid()) {
return Future.failedFuture(new ValidationException(Constants.GSON.toJson(validation.getErrors())));
}
return preUserDAO.insert(preUser);
});
}
public Future<PreUserEntity> update(PreUserEntity preUser) {
return getById(preUser.getPre_user_id()).compose(existing -> preUserValidator.validate(preUser, true).compose(validation -> {
if (!validation.isValid()) {
return Future.failedFuture(new ValidationException(Constants.GSON.toJson(validation.getErrors())));
}
return preUserDAO.update(preUser);
}));
}
public Future<Boolean> delete(Integer id) {
return getById(id).compose(preUser -> {
if (preUser == null) {
return Future.failedFuture(new NotFoundException("PreUser with id " + id));
}
return preUserDAO.delete(id);
});
}
}

View File

@@ -0,0 +1,51 @@
package net.miarma.api.microservices.huertos.services;
import io.vertx.core.Future;
import io.vertx.sqlclient.Pool;
import net.miarma.api.backlib.Constants.HuertosUserStatus;
import net.miarma.api.backlib.exceptions.UnauthorizedException;
import net.miarma.api.backlib.security.JWTManager;
import net.miarma.api.microservices.huertos.entities.ProfileDTO;
public class ProfileService {
private final MemberService memberService;
private final RequestService requestService;
private final IncomeService incomeService;
public ProfileService(Pool pool) {
this.memberService = new MemberService(pool);
this.requestService = new RequestService(pool);
this.incomeService = new IncomeService(pool);
}
public Future<ProfileDTO> getProfile(String token) {
Integer userId = JWTManager.getInstance().getUserId(token);
ProfileDTO dto = new ProfileDTO();
return memberService.getById(userId).compose(member -> {
if (member.getStatus() == HuertosUserStatus.INACTIVE) {
return Future.failedFuture(new UnauthorizedException("Member is inactive"));
}
dto.setMember(member);
return Future.all(
requestService.getMyRequests(token),
incomeService.getMyIncomes(token),
memberService.hasCollaborator(token),
requestService.hasCollaboratorRequest(token),
memberService.hasGreenHouse(token),
requestService.hasGreenHouseRequest(token)
).map(f -> {
dto.setRequests(f.resultAt(0));
dto.setPayments(f.resultAt(1));
dto.setHasCollaborator(f.resultAt(2));
dto.setHasCollaboratorRequest(f.resultAt(3));
dto.setHasGreenHouse(f.resultAt(4));
dto.setHasGreenHouseRequest(f.resultAt(5));
return dto;
});
});
}
}

View File

@@ -0,0 +1,170 @@
package net.miarma.api.microservices.huertos.services;
import io.vertx.core.Future;
import io.vertx.sqlclient.Pool;
import net.miarma.api.backlib.Constants;
import net.miarma.api.backlib.Constants.HuertosRequestStatus;
import net.miarma.api.backlib.Constants.HuertosRequestType;
import net.miarma.api.backlib.Constants.HuertosUserStatus;
import net.miarma.api.backlib.Constants.HuertosUserType;
import net.miarma.api.backlib.exceptions.NotFoundException;
import net.miarma.api.backlib.exceptions.ValidationException;
import net.miarma.api.backlib.http.QueryParams;
import net.miarma.api.backlib.security.JWTManager;
import net.miarma.api.microservices.huertos.dao.RequestDAO;
import net.miarma.api.microservices.huertos.entities.RequestEntity;
import net.miarma.api.microservices.huertos.entities.ViewRequestsWithPreUsers;
import net.miarma.api.microservices.huertos.validators.RequestValidator;
import java.util.List;
public class RequestService {
private final RequestDAO requestDAO;
private final RequestValidator requestValidator;
private final PreUserService preUserService;
private final MemberService memberService;
public RequestService(Pool pool) {
this.requestDAO = new RequestDAO(pool);
this.requestValidator = new RequestValidator();
this.preUserService = new PreUserService(pool);
this.memberService = new MemberService(pool);
}
public Future<List<RequestEntity>> getAll() {
return requestDAO.getAll();
}
public Future<List<RequestEntity>> getAll(QueryParams params) {
return requestDAO.getAll(params);
}
public Future<RequestEntity> getById(Integer id) {
return requestDAO.getById(id).compose(request -> {
if (request == null) {
return Future.failedFuture(new NotFoundException("Request with id " + id));
}
return Future.succeededFuture(request);
});
}
public Future<List<ViewRequestsWithPreUsers>> getRequestsWithPreUsers() {
return requestDAO.getRequestsWithPreUsers();
}
public Future<ViewRequestsWithPreUsers> getRequestWithPreUserById(Integer id) {
return requestDAO.getRequestWithPreUserById(id).compose(request -> {
if (request == null) {
return Future.failedFuture(new NotFoundException("Request with id " + id));
}
return Future.succeededFuture(request);
});
}
public Future<Integer> getRequestCount() {
return requestDAO.getAll().compose(requests -> Future.succeededFuture(requests.stream()
.filter(r -> r.getStatus() == HuertosRequestStatus.PENDING)
.mapToInt(r -> 1)
.sum()));
}
public Future<List<RequestEntity>> getMyRequests(String token) {
Integer userId = JWTManager.getInstance().getUserId(token);
return requestDAO.getByUserId(userId).compose(Future::succeededFuture);
}
public Future<Boolean> hasCollaboratorRequest(String token) {
return getMyRequests(token).compose(requests -> {
boolean result = requests.stream()
.filter(r -> r.getStatus() == HuertosRequestStatus.PENDING)
.anyMatch(r -> r.getType() == HuertosRequestType.ADD_COLLABORATOR);
return Future.succeededFuture(result);
});
}
public Future<Boolean> hasGreenHouseRequest(String token) {
return getMyRequests(token).compose(requests -> Future.succeededFuture(requests.stream()
.filter(r -> r.getStatus() == HuertosRequestStatus.PENDING)
.anyMatch(r -> r.getType() == HuertosRequestType.ADD_GREENHOUSE)));
}
public Future<RequestEntity> create(RequestEntity request) {
return requestValidator.validate(request).compose(validation -> {
if (!validation.isValid()) {
return Future.failedFuture(new ValidationException(Constants.GSON.toJson(validation.getErrors())));
}
return requestDAO.insert(request);
});
}
public Future<RequestEntity> update(RequestEntity request) {
return getById(request.getRequest_id()).compose(existing -> requestValidator.validate(request).compose(validation -> {
if (!validation.isValid()) {
return Future.failedFuture(new ValidationException(Constants.GSON.toJson(validation.getErrors())));
}
return requestDAO.update(request);
}));
}
public Future<Boolean> delete(Integer id) {
return getById(id).compose(request -> {
if (request == null) {
return Future.failedFuture(new NotFoundException("Request with id " + id));
}
return requestDAO.delete(id);
});
}
public Future<RequestEntity> acceptRequest(Integer id) {
RequestEntity request = new RequestEntity();
request.setRequest_id(id);
request.setStatus(HuertosRequestStatus.APPROVED);
return requestDAO.update(request).compose(updatedRequest -> getById(id).compose(fullRequest -> {
HuertosRequestType type = fullRequest.getType();
return switch (type) {
case ADD_COLLABORATOR, REGISTER -> preUserService.getByRequestId(id).compose(preUser -> {
if (preUser == null) {
return Future.failedFuture("PreUser not found for request id " + id);
}
return memberService.createFromPreUser(preUser).compose(createdUser ->
preUserService.delete(preUser.getPre_user_id()).map(v -> fullRequest)
);
});
case UNREGISTER ->
memberService.changeMemberStatus(fullRequest.getRequested_by(), HuertosUserStatus.INACTIVE)
.map(v -> fullRequest);
case REMOVE_COLLABORATOR ->
memberService.getById(fullRequest.getRequested_by()).compose(requestingMember -> {
Integer plotNumber = requestingMember.getPlot_number();
return memberService.getCollaborator(plotNumber).compose(collaborator -> {
if (collaborator == null) {
return Future.failedFuture("No collaborator found for plot number " + plotNumber);
}
return memberService.changeMemberStatus(collaborator.getUser_id(), HuertosUserStatus.INACTIVE)
.map(v -> fullRequest);
});
});
case ADD_GREENHOUSE ->
memberService.changeMemberType(fullRequest.getRequested_by(), HuertosUserType.WITH_GREENHOUSE)
.map(v -> fullRequest);
case REMOVE_GREENHOUSE ->
memberService.changeMemberType(fullRequest.getRequested_by(), HuertosUserType.MEMBER)
.map(v -> fullRequest);
};
}));
}
public Future<RequestEntity> rejectRequest(Integer id) {
RequestEntity request = new RequestEntity();
request.setRequest_id(id);
request.setStatus(HuertosRequestStatus.REJECTED);
return requestDAO.update(request);
}
}

View File

@@ -0,0 +1,33 @@
package net.miarma.api.microservices.huertos.validators;
import io.vertx.core.Future;
import net.miarma.api.backlib.validation.ValidationResult;
import net.miarma.api.microservices.huertos.entities.AnnouncementEntity;
public class AnnouncementValidator {
public Future<ValidationResult> validate(AnnouncementEntity announce) {
ValidationResult result = new ValidationResult();
if (announce == null) {
result.addError("announce", "El anuncio no puede ser nulo");
return Future.succeededFuture(result);
}
if (announce.getBody() == null || announce.getBody().isBlank()) {
result.addError("body", "El cuerpo del anuncio es obligatorio");
} else if (announce.getBody().length() > 1000) {
result.addError("body", "El cuerpo del anuncio no puede exceder los 1000 caracteres");
}
if (announce.getPriority() == null) {
result.addError("priority", "La prioridad del anuncio es obligatoria");
}
if (announce.getPublished_by() == null || announce.getPublished_by() <= 0) {
result.addError("published_by", "El ID del usuario que publica el anuncio es obligatorio y debe ser mayor que 0");
}
return Future.succeededFuture(result);
}
}

View File

@@ -0,0 +1,35 @@
package net.miarma.api.microservices.huertos.validators;
import io.vertx.core.Future;
import net.miarma.api.backlib.validation.ValidationResult;
import net.miarma.api.backlib.validation.Validator;
import net.miarma.api.microservices.huertos.entities.BalanceEntity;
import java.math.BigDecimal;
public class BalanceValidator implements Validator<BalanceEntity> {
@Override
public Future<ValidationResult> validate(BalanceEntity balance) {
ValidationResult result = new ValidationResult();
if (balance == null) {
result.addError("balance", "Balance data is null");
return Future.succeededFuture(result);
}
if (balance.getInitial_bank() == null) {
result.addError("initial_bank", "Debe proporcionar el saldo inicial en banco.");
} else if (balance.getInitial_bank().compareTo(BigDecimal.ZERO) < 0) {
result.addError("initial_bank", "El saldo inicial en banco no puede ser negativo.");
}
if (balance.getInitial_cash() == null) {
result.addError("initial_cash", "Debe proporcionar el saldo inicial en efectivo.");
} else if (balance.getInitial_cash().compareTo(BigDecimal.ZERO) < 0) {
result.addError("initial_cash", "El saldo inicial en efectivo no puede ser negativo.");
}
return Future.succeededFuture(result);
}
}

View File

@@ -0,0 +1,45 @@
package net.miarma.api.microservices.huertos.validators;
import io.vertx.core.Future;
import net.miarma.api.backlib.validation.ValidationResult;
import net.miarma.api.microservices.huertos.entities.ExpenseEntity;
public class ExpenseValidator {
public Future<ValidationResult> validate(ExpenseEntity expense) {
ValidationResult result = new ValidationResult();
if (expense == null) {
result.addError("expense", "La entidad no puede ser nula");
return Future.succeededFuture(result);
}
if (expense.getConcept() == null || expense.getConcept().isBlank()) {
result.addError("concept", "El concepto es obligatorio");
}
if (expense.getAmount() == null) {
result.addError("amount", "El importe es obligatorio");
} else if (expense.getAmount().signum() < 0) {
result.addError("amount", "El importe no puede ser negativo");
}
if(expense.getSupplier() == null || expense.getSupplier().isBlank()) {
result.addError("supplier", "El proveedor es obligatorio");
} else if (expense.getSupplier() != null && expense.getSupplier().length() > 255) {
result.addError("supplier", "El nombre del proveedor es demasiado largo");
}
if(expense.getInvoice() == null || expense.getInvoice().isBlank()) {
result.addError("invoice", "El nombre de la factura es obligatorio");
} else if (expense.getInvoice() != null && expense.getInvoice().length() > 255) {
result.addError("invoice", "El nombre de la factura es demasiado largo");
}
if (expense.getType() == null) {
result.addError("type", "El tipo de pago es obligatorio");
}
return Future.succeededFuture(result);
}
}

View File

@@ -0,0 +1,41 @@
package net.miarma.api.microservices.huertos.validators;
import io.vertx.core.Future;
import net.miarma.api.backlib.validation.ValidationResult;
import net.miarma.api.microservices.huertos.entities.IncomeEntity;
public class IncomeValidator {
public Future<ValidationResult> validate(IncomeEntity income) {
ValidationResult result = new ValidationResult();
if (income == null) {
result.addError("income", "La entidad no puede ser nula");
return Future.succeededFuture(result);
}
if (income.getMember_number() == null || income.getMember_number() <= 0) {
result.addError("member_number", "El número de socio es obligatorio y debe ser mayor que 0");
}
if (income.getConcept() == null || income.getConcept().isBlank()) {
result.addError("concept", "El concepto es obligatorio");
}
if (income.getAmount() == null) {
result.addError("amount", "El importe es obligatorio");
} else if (income.getAmount().signum() < 0) {
result.addError("amount", "El importe no puede ser negativo");
}
if (income.getType() == null) {
result.addError("type", "El tipo de pago es obligatorio");
}
if (income.getFrequency() == null) {
result.addError("frequency", "La frecuencia del pago es obligatoria");
}
return Future.succeededFuture(result);
}
}

View File

@@ -0,0 +1,57 @@
package net.miarma.api.microservices.huertos.validators;
import io.vertx.core.Future;
import net.miarma.api.backlib.security.DNIValidator;
import net.miarma.api.backlib.validation.ValidationResult;
import net.miarma.api.microservices.huertos.entities.MemberEntity;
public class MemberValidator {
public Future<ValidationResult> validate(MemberEntity member) {
ValidationResult result = new ValidationResult();
if (member == null) {
result.addError("member", "La entidad no puede ser nula");
return Future.succeededFuture(result);
}
if (member.getDni() == null || member.getDni().isBlank()) {
result.addError("dni", "El DNI es obligatorio");
} else if (!DNIValidator.isValid(member.getDni())) {
result.addError("dni", "El DNI no es válido");
}
if (member.getDisplay_name() == null || member.getDisplay_name().isBlank()) {
result.addError("display_name", "El nombre es obligatorio");
}
if (member.getPhone() == null || member.getPhone() <= 0 ||
member.getPhone().toString().length() != 9) {
result.addError("phone", "El teléfono es obligatorio y debe ser válido");
}
if (member.getEmail() != null && !member.getEmail().isBlank()) {
if (!member.getEmail().matches("^[\\w-\\.]+@([\\w-]+\\.)+[\\w-]{2,4}$")) {
result.addError("email", "El correo electrónico no es válido");
}
}
if (member.getUser_name() == null || member.getUser_name().isBlank()) {
result.addError("user_name", "El nombre de usuario es obligatorio");
}
if (member.getType() == null) {
result.addError("type", "El tipo de usuario es obligatorio");
}
if (member.getStatus() == null) {
result.addError("status", "El estado del usuario es obligatorio");
}
if (member.getRole() == null) {
result.addError("role", "El rol del usuario en Huertos es obligatorio");
}
return Future.succeededFuture(result);
}
}

View File

@@ -0,0 +1,69 @@
package net.miarma.api.microservices.huertos.validators;
import io.vertx.core.Future;
import net.miarma.api.backlib.security.DNIValidator;
import net.miarma.api.backlib.validation.ValidationResult;
import net.miarma.api.microservices.huertos.entities.PreUserEntity;
public class PreUserValidator {
public Future<ValidationResult> validate(PreUserEntity preUser, boolean checkRequestId) {
ValidationResult result = new ValidationResult();
if (preUser == null) {
result.addError("preUser", "El preusuario no puede ser nulo");
return Future.succeededFuture(result);
}
if (preUser.getDni() == null || preUser.getDni().isBlank()) {
result.addError("dni", "El DNI es obligatorio");
} else if (!DNIValidator.isValid(preUser.getDni())) {
result.addError("dni", "El DNI no es válido");
}
if (preUser.getDisplay_name() == null || preUser.getDisplay_name().isBlank()) {
result.addError("display_name", "El nombre es obligatorio");
}
if (preUser.getUser_name() == null || preUser.getUser_name().isBlank()) {
result.addError("user_name", "El nombre de usuario es obligatorio");
}
if (preUser.getEmail() != null && !preUser.getEmail().isBlank()) {
if (!preUser.getEmail().matches("^[\\w-\\.]+@([\\w-]+\\.)+[\\w-]{2,4}$")) {
result.addError("email", "El correo electrónico no es válido");
}
}
if (preUser.getPhone() == null || preUser.getPhone() <= 0 ||
preUser.getPhone().toString().length() != 9) {
result.addError("phone", "El teléfono es obligatorio y debe ser válido");
}
if (preUser.getAddress() == null || preUser.getAddress().isBlank()) {
result.addError("address", "La dirección es obligatoria");
}
if (preUser.getZip_code() == null || preUser.getZip_code().isBlank() || preUser.getZip_code().length() != 5) {
result.addError("zip_code", "El código postal es obligatorio");
}
if (preUser.getCity() == null || preUser.getCity().isBlank()) {
result.addError("city", "La ciudad es obligatoria");
}
if (preUser.getType() == null) {
result.addError("type", "El tipo de usuario es obligatorio");
}
if (preUser.getStatus() == null) {
result.addError("status", "El estado del usuario es obligatorio");
}
if (checkRequestId && preUser.getRequest_id() == null) {
result.addError("request_id", "El ID de solicitud es obligatorio");
}
return Future.succeededFuture(result);
}
}

View File

@@ -0,0 +1,32 @@
package net.miarma.api.microservices.huertos.validators;
import io.vertx.core.Future;
import net.miarma.api.backlib.Constants.HuertosRequestType;
import net.miarma.api.backlib.validation.ValidationResult;
import net.miarma.api.microservices.huertos.entities.RequestEntity;
public class RequestValidator {
public Future<ValidationResult> validate(RequestEntity request) {
ValidationResult result = new ValidationResult();
if (request == null) {
result.addError("request", "La solicitud no puede ser nula");
return Future.succeededFuture(result);
}
if (request.getType() == null) {
result.addError("type", "El tipo de solicitud es obligatorio");
}
if (request.getStatus() == null) {
result.addError("status", "El estado de la solicitud es obligatorio");
}
if (request.getRequested_by() == null && request.getType() != HuertosRequestType.REGISTER) {
result.addError("requested_by", "El solicitante es obligatorio");
}
return Future.succeededFuture(result);
}
}

View File

@@ -0,0 +1,43 @@
package net.miarma.api.microservices.huertos.validators;
import io.vertx.core.Future;
import net.miarma.api.backlib.validation.ValidationResult;
import net.miarma.api.microservices.huertos.entities.UserMetadataEntity;
public class UserMetadataValidator {
public Future<ValidationResult> validate(UserMetadataEntity meta) {
ValidationResult result = new ValidationResult();
if (meta == null) {
result.addError("metadata", "Los metadatos no pueden ser nulos");
return Future.succeededFuture(result);
}
if (meta.getUser_id() == null)
result.addError("user_id", "El ID de usuario es obligatorio");
if (meta.getMember_number() == null || meta.getMember_number() <= 0)
result.addError("member_number", "El número de miembro debe ser mayor que 0");
if (meta.getPlot_number() == null || meta.getPlot_number() <= 0)
result.addError("plot_number", "El número de parcela debe ser mayor que 0");
if (meta.getDni() == null || meta.getDni().isBlank())
result.addError("dni", "El DNI es obligatorio");
if (meta.getPhone() == null || meta.getPhone() <= 0)
result.addError("phone", "El número de teléfono debe ser válido");
if (meta.getType() == null)
result.addError("type", "El tipo de usuario es obligatorio");
if (meta.getStatus() == null)
result.addError("status", "El estado del usuario es obligatorio");
if (meta.getRole() == null)
result.addError("role", "El rol del usuario es obligatorio");
return Future.succeededFuture(result);
}
}

View File

@@ -0,0 +1,266 @@
package net.miarma.api.microservices.huertos.verticles;
import java.util.stream.Collectors;
import io.vertx.core.AbstractVerticle;
import io.vertx.core.Promise;
import io.vertx.core.json.JsonArray;
import io.vertx.core.json.JsonObject;
import io.vertx.ext.web.Router;
import io.vertx.ext.web.handler.BodyHandler;
import io.vertx.sqlclient.Pool;
import net.miarma.api.backlib.ConfigManager;
import net.miarma.api.backlib.Constants;
import net.miarma.api.backlib.Constants.HuertosUserStatus;
import net.miarma.api.backlib.Constants.HuertosUserType;
import net.miarma.api.backlib.db.DatabaseProvider;
import net.miarma.api.backlib.util.EventBusUtil;
import net.miarma.api.backlib.util.NameCensorer;
import net.miarma.api.backlib.util.RouterUtil;
import net.miarma.api.microservices.huertos.routing.HuertosDataRouter;
import net.miarma.api.microservices.huertos.services.BalanceService;
import net.miarma.api.microservices.huertos.services.IncomeService;
import net.miarma.api.microservices.huertos.services.MemberService;
import net.miarma.api.microservices.huertos.services.PreUserService;
import net.miarma.api.microservices.huertos.services.ProfileService;
import net.miarma.api.microservices.huertos.services.RequestService;
public class HuertosDataVerticle extends AbstractVerticle {
private ConfigManager configManager;
private MemberService memberService;
private IncomeService incomeService;
private BalanceService balanceService;
private RequestService requestService;
private PreUserService preUserService;
private ProfileService profileService;
@Override
public void start(Promise<Void> startPromise) {
configManager = ConfigManager.getInstance();
Pool pool = DatabaseProvider.createPool(vertx, configManager);
memberService = new MemberService(pool);
incomeService = new IncomeService(pool);
balanceService = new BalanceService(pool);
requestService = new RequestService(pool);
preUserService = new PreUserService(pool);
profileService = new ProfileService(pool);
Router router = Router.router(vertx);
RouterUtil.attachLogger(router);
HuertosDataRouter.mount(router, vertx, pool);
registerLogicVerticleConsumer();
vertx.createHttpServer()
.requestHandler(router)
.listen(configManager.getIntProperty("huertos.data.port"), res -> {
if (res.succeeded()) startPromise.complete();
else startPromise.fail(res.cause());
});
}
private void registerLogicVerticleConsumer() {
vertx.eventBus().consumer(Constants.HUERTOS_EVENT_BUS, message -> {
JsonObject body = (JsonObject) message.body();
String action = body.getString("action");
switch (action) {
case "login" -> {
String email = body.getString("email", null);
String userName = body.getString("userName", null);
String password = body.getString("password");
boolean keepLoggedIn = body.getBoolean("keepLoggedIn", false);
memberService.login(email != null ? email : userName, password, keepLoggedIn)
.onSuccess(message::reply)
.onFailure(EventBusUtil.fail(message));
}
case "getByMemberNumber" ->
memberService.getByMemberNumber(body.getInteger("memberNumber"))
.onSuccess(member -> message.reply(new JsonObject(Constants.GSON.toJson(member))))
.onFailure(EventBusUtil.fail(message));
case "getByPlotNumber" ->
memberService.getByPlotNumber(body.getInteger("plotNumber"))
.onSuccess(member -> message.reply(new JsonObject(Constants.GSON.toJson(member))))
.onFailure(EventBusUtil.fail(message));
case "getByDNI" ->
memberService.getByDni(body.getString("dni"))
.onSuccess(member -> message.reply(new JsonObject(Constants.GSON.toJson(member))))
.onFailure(EventBusUtil.fail(message));
case "getUserPayments" -> incomeService.getUserPayments(body.getInteger("memberNumber"))
.onSuccess(payments -> {
String paymentsJson = payments.stream()
.map(Constants.GSON::toJson)
.collect(Collectors.joining(",", "[", "]"));
message.reply(new JsonArray(paymentsJson));
})
.onFailure(EventBusUtil.fail(message));
case "hasPaid" -> incomeService.hasPaid(body.getInteger("memberNumber"))
.onSuccess(result -> message.reply(new JsonObject().put("hasPaid", result)))
.onFailure(EventBusUtil.fail(message));
case "getWaitlist" ->
memberService.getWaitlist()
.onSuccess(list -> {
String listJson = list.stream()
.map(Constants.GSON::toJson)
.collect(Collectors.joining(",", "[", "]"));
message.reply(new JsonArray(listJson));
})
.onFailure(EventBusUtil.fail(message));
case "getLimitedWaitlist" ->
memberService.getWaitlist()
.onSuccess(list -> {
String listJson = list.stream()
.map(member -> {
JsonObject json = new JsonObject(Constants.GSON.toJson(member));
json.put("display_name", NameCensorer.censor(json.getString("display_name")));
json.remove("user_id");
json.remove("member_number");
json.remove("plot_number");
json.remove("dni");
json.remove("phone");
json.remove("email");
json.remove("user_name");
json.remove("notes");
json.remove("type");
json.remove("status");
json.remove("role");
json.remove("global_status");
json.remove("global_role");
return json;
})
.map(Constants.GSON::toJson)
.collect(Collectors.joining(",", "[", "]"));
message.reply(new JsonArray(listJson));
})
.onFailure(EventBusUtil.fail(message));
case "getLastMemberNumber" -> memberService.getLastMemberNumber()
.onSuccess(last -> message.reply(new JsonObject().put("lastMemberNumber", last)))
.onFailure(EventBusUtil.fail(message));
case "getBalanceWithTotals" -> balanceService.getBalanceWithTotals()
.onSuccess(balance -> {
String balanceJson = Constants.GSON.toJson(balance);
message.reply(new JsonObject(balanceJson));
})
.onFailure(EventBusUtil.fail(message));
case "getRequestsWithPreUsers" -> requestService.getRequestsWithPreUsers()
.onSuccess(requests -> {
String requestsJson = requests.stream()
.map(Constants.GSON::toJson)
.collect(Collectors.joining(",", "[", "]"));
message.reply(new JsonArray(requestsJson));
})
.onFailure(EventBusUtil.fail(message));
case "getRequestWithPreUser" -> requestService.getRequestWithPreUserById(body.getInteger("requestId"))
.onSuccess(request -> {
String requestJson = Constants.GSON.toJson(request);
message.reply(new JsonObject(requestJson));
})
.onFailure(EventBusUtil.fail(message));
case "getProfile" -> profileService.getProfile(body.getString("token"))
.onSuccess(profile -> {
String profileJson = Constants.GSON.toJson(profile);
message.reply(new JsonObject(profileJson));
})
.onFailure(EventBusUtil.fail(message));
case "getRequestCount" -> requestService.getRequestCount()
.onSuccess(count -> message.reply(new JsonObject().put("count", count)))
.onFailure(EventBusUtil.fail(message));
case "getMyIncomes" -> incomeService.getMyIncomes(body.getString("token"))
.onSuccess(incomes -> {
String incomesJson = incomes.stream()
.map(Constants.GSON::toJson)
.collect(Collectors.joining(",", "[", "]"));
message.reply(new JsonArray(incomesJson));
})
.onFailure(EventBusUtil.fail(message));
case "getMyRequests" -> requestService.getMyRequests(body.getString("token"))
.onSuccess(requests -> {
String requestsJson = requests.stream()
.map(Constants.GSON::toJson)
.collect(Collectors.joining(",", "[", "]"));
message.reply(new JsonArray(requestsJson));
})
.onFailure(EventBusUtil.fail(message));
case "hasCollaborator" -> memberService.hasCollaborator(body.getString("token"))
.onSuccess(result -> message.reply(new JsonObject().put("hasCollaborator", result)))
.onFailure(EventBusUtil.fail(message));
case "hasCollaboratorRequest" -> requestService.hasCollaboratorRequest(body.getString("token"))
.onSuccess(result -> message.reply(new JsonObject().put("hasCollaboratorRequest", result)))
.onFailure(EventBusUtil.fail(message));
case "hasGreenHouse" -> memberService.hasGreenHouse(body.getString("token"))
.onSuccess(result -> message.reply(new JsonObject().put("hasGreenHouse", result)))
.onFailure(EventBusUtil.fail(message));
case "hasGreenHouseRequest" -> requestService.hasGreenHouseRequest(body.getString("token"))
.onSuccess(result -> message.reply(new JsonObject().put("hasGreenHouseRequest", result)))
.onFailure(EventBusUtil.fail(message));
case "acceptRequest" -> requestService.acceptRequest(body.getInteger("requestId"))
.onSuccess(request -> {
String requestJson = Constants.GSON.toJson(request);
message.reply(new JsonObject(requestJson));
})
.onFailure(EventBusUtil.fail(message));
case "rejectRequest" -> requestService.rejectRequest(body.getInteger("requestId"))
.onSuccess(request -> {
String requestJson = Constants.GSON.toJson(request);
message.reply(new JsonObject(requestJson));
})
.onFailure(EventBusUtil.fail(message));
case "changeMemberStatus" -> {
HuertosUserStatus status = HuertosUserStatus.fromInt(body.getInteger("status"));
memberService.changeMemberStatus(body.getInteger("memberNumber"), status)
.onSuccess(member -> {
String memberJson = Constants.GSON.toJson(member);
message.reply(new JsonObject(memberJson));
})
.onFailure(EventBusUtil.fail(message));
}
case "changeMemberType" -> {
HuertosUserType type = HuertosUserType.fromInt(body.getInteger("type"));
memberService.changeMemberType(body.getInteger("memberNumber"), type)
.onSuccess(member -> {
String memberJson = Constants.GSON.toJson(member);
message.reply(new JsonObject(memberJson));
})
.onFailure(EventBusUtil.fail(message));
}
case "validatePreUser" -> preUserService.validatePreUser(body.getString("preUser"))
.onSuccess(preUser -> {
String preUserJson = Constants.GSON.toJson(preUser);
message.reply(new JsonObject(preUserJson));
})
.onFailure(EventBusUtil.fail(message));
default -> EventBusUtil.fail(message).handle(new IllegalArgumentException("Unknown action: " + action));
}
});
}
}

View File

@@ -0,0 +1,32 @@
package net.miarma.api.microservices.huertos.verticles;
import io.vertx.core.AbstractVerticle;
import io.vertx.core.Promise;
import io.vertx.ext.web.Router;
import io.vertx.ext.web.handler.BodyHandler;
import io.vertx.sqlclient.Pool;
import net.miarma.api.backlib.ConfigManager;
import net.miarma.api.backlib.db.DatabaseProvider;
import net.miarma.api.backlib.util.RouterUtil;
import net.miarma.api.microservices.huertos.routing.HuertosLogicRouter;
public class HuertosLogicVerticle extends AbstractVerticle{
private ConfigManager configManager;
@Override
public void start(Promise<Void> startPromise) {
configManager = ConfigManager.getInstance();
Pool pool = DatabaseProvider.createPool(vertx, configManager);
Router router = Router.router(vertx);
RouterUtil.attachLogger(router);
HuertosLogicRouter.mount(router, vertx, pool);
vertx.createHttpServer()
.requestHandler(router)
.listen(configManager.getIntProperty("huertos.logic.port"), res -> {
if (res.succeeded()) startPromise.complete();
else startPromise.fail(res.cause());
});
}
}

View File

@@ -0,0 +1,58 @@
package net.miarma.api.microservices.huertos.verticles;
import io.vertx.core.AbstractVerticle;
import io.vertx.core.Promise;
import net.miarma.api.backlib.ConfigManager;
import net.miarma.api.backlib.Constants;
import net.miarma.api.backlib.LogAccumulator;
import net.miarma.api.backlib.util.DeploymentUtil;
public class HuertosMainVerticle extends AbstractVerticle {
private ConfigManager configManager;
@Override
public void start(Promise<Void> startPromise) {
try {
this.configManager = ConfigManager.getInstance();
deployVerticles();
startPromise.complete();
} catch (Exception e) {
Constants.LOGGER.error(DeploymentUtil.failMessage(HuertosMainVerticle.class, e));
startPromise.fail(e);
}
}
private void deployVerticles() {
vertx.deployVerticle(new HuertosDataVerticle(), result -> {
if (result.succeeded()) {
String message = String.join("\n\r ",
DeploymentUtil.successMessage(HuertosDataVerticle.class),
DeploymentUtil.apiUrlMessage(
configManager.getHost(),
configManager.getIntProperty("huertos.data.port")
)
);
LogAccumulator.add(message);
} else {
LogAccumulator.add(DeploymentUtil.failMessage(HuertosDataVerticle.class, result.cause()));
}
});
vertx.deployVerticle(new HuertosLogicVerticle(), result -> {
if (result.succeeded()) {
String message = String.join("\n\r ",
DeploymentUtil.successMessage(HuertosLogicVerticle.class),
DeploymentUtil.apiUrlMessage(
configManager.getHost(),
configManager.getIntProperty("huertos.logic.port")
)
);
LogAccumulator.add(message);
} else {
LogAccumulator.add(DeploymentUtil.failMessage(HuertosLogicVerticle.class, result.cause()));
}
});
}
}