working on loading items for location
This commit is contained in:
@@ -9,6 +9,9 @@ public class Constants {
|
|||||||
private Constants(){}
|
private Constants(){}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
public static final String ADDRESS = "address";
|
public static final String ADDRESS = "address";
|
||||||
public static final String ALLOWED_STATES = "allowed_states";
|
public static final String ALLOWED_STATES = "allowed_states";
|
||||||
public static final String ATTACHMENTS = "attachments";
|
public static final String ATTACHMENTS = "attachments";
|
||||||
@@ -117,6 +120,7 @@ public class Constants {
|
|||||||
public static final String LANGUAGE = "language";
|
public static final String LANGUAGE = "language";
|
||||||
public static final String LAST_CUSTOMER_NUMBER = "last_customer_number";
|
public static final String LAST_CUSTOMER_NUMBER = "last_customer_number";
|
||||||
public static final String LIMIT = "limit";
|
public static final String LIMIT = "limit";
|
||||||
|
public static final String LOCATION = "location";
|
||||||
public static final String LOCATION_ID = "location_id";
|
public static final String LOCATION_ID = "location_id";
|
||||||
public static final String LOGIN = "login";
|
public static final String LOGIN = "login";
|
||||||
|
|
||||||
@@ -144,7 +148,10 @@ public class Constants {
|
|||||||
public static final String PRIORITY = "priority";
|
public static final String PRIORITY = "priority";
|
||||||
public static final String PROJECT = "project";
|
public static final String PROJECT = "project";
|
||||||
public static final String PROJECT_ID = "project_id";
|
public static final String PROJECT_ID = "project_id";
|
||||||
|
public static final String PROPERTIES = "properties";
|
||||||
|
|
||||||
|
public static final String QUANTITY = "quantity";
|
||||||
|
|
||||||
public static final String RECEIVERS = "receivers";
|
public static final String RECEIVERS = "receivers";
|
||||||
public static final String REDIRECT = "redirect";
|
public static final String REDIRECT = "redirect";
|
||||||
public static final String RENDERED = "rendered";
|
public static final String RENDERED = "rendered";
|
||||||
|
|||||||
@@ -1,12 +1,53 @@
|
|||||||
/* © SRSoftware 2025 */
|
/* © SRSoftware 2025 */
|
||||||
package de.srsoftware.umbrella.core.model;
|
package de.srsoftware.umbrella.core.model;
|
||||||
|
|
||||||
import java.util.Collection;
|
import de.srsoftware.tools.Mappable;
|
||||||
|
|
||||||
public class Item {
|
import java.sql.ResultSet;
|
||||||
|
import java.sql.SQLException;
|
||||||
|
import java.util.Collection;
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
import static de.srsoftware.umbrella.core.Constants.*;
|
||||||
|
|
||||||
|
public class Item implements Mappable {
|
||||||
private long id;
|
private long id;
|
||||||
private String code;
|
private Mappable owner;
|
||||||
private boolean physical;
|
private String code, name;
|
||||||
private Location location;
|
private Location location;
|
||||||
private Collection<Property> properties;
|
private Collection<Property> properties;
|
||||||
|
|
||||||
|
private Item(Mappable owner, long id, Location location, String code, String name) {
|
||||||
|
this.owner = owner;
|
||||||
|
this.id = id;
|
||||||
|
this.location = location;
|
||||||
|
this.code = code;
|
||||||
|
this.name = name;
|
||||||
|
this.properties = new HashSet<>();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Item of(ResultSet rs, Mappable owner, Location location) throws SQLException {
|
||||||
|
var id = rs.getLong(ID);
|
||||||
|
var code = rs.getString(CODE);
|
||||||
|
var name = rs.getString(NAME);
|
||||||
|
return new Item(owner, id, location, code, name);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Map<String, Object> toMap() {
|
||||||
|
return Map.of(
|
||||||
|
OWNER, owner.toMap(),
|
||||||
|
ID, id,
|
||||||
|
LOCATION, location.toMap(),
|
||||||
|
CODE, code,
|
||||||
|
NAME, name,
|
||||||
|
PROPERTIES, properties.stream().map(Property::toMap).toList()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return name;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -64,4 +64,9 @@ public class Location implements Mappable {
|
|||||||
NAME,name,
|
NAME,name,
|
||||||
DESCRIPTION,description);
|
DESCRIPTION,description);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return name;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,10 +1,27 @@
|
|||||||
/* © SRSoftware 2025 */
|
/* © SRSoftware 2025 */
|
||||||
package de.srsoftware.umbrella.core.model;
|
package de.srsoftware.umbrella.core.model;
|
||||||
|
|
||||||
public class Property {
|
import de.srsoftware.tools.Mappable;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
import static de.srsoftware.umbrella.core.Constants.*;
|
||||||
|
|
||||||
|
public class Property implements Mappable {
|
||||||
long id;
|
long id;
|
||||||
String name;
|
String name;
|
||||||
Object value;
|
Object value;
|
||||||
String unit;
|
String unit;
|
||||||
String quantity;
|
String quantity;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Map<String, Object> toMap() {
|
||||||
|
return Map.of(
|
||||||
|
ID, id,
|
||||||
|
NAME, name,
|
||||||
|
VALUE, value,
|
||||||
|
UNIT, unit,
|
||||||
|
QUANTITY, quantity
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,6 +10,21 @@
|
|||||||
|
|
||||||
|
|
||||||
let top_level = $state(null);
|
let top_level = $state(null);
|
||||||
|
let selected = $state(null);
|
||||||
|
let items = $derived(loadItems(selected));
|
||||||
|
|
||||||
|
async function loadItems(loc){
|
||||||
|
if (!loc) return null;
|
||||||
|
const url = api(`stock/items_at/${loc.id}`)
|
||||||
|
const res = await fetch(url,{credentials:'include'});
|
||||||
|
if (res.ok){
|
||||||
|
yikes();
|
||||||
|
return loc.name;
|
||||||
|
} else {
|
||||||
|
error(res);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
async function load(){
|
async function load(){
|
||||||
const url = api('stock/locations/of_user')
|
const url = api('stock/locations/of_user')
|
||||||
@@ -32,12 +47,18 @@
|
|||||||
{#each top_level as realm,idx}
|
{#each top_level as realm,idx}
|
||||||
<h3>{realm.name}</h3>
|
<h3>{realm.name}</h3>
|
||||||
{#if realm.locations}
|
{#if realm.locations}
|
||||||
<Locations locations={realm.locations} />
|
<Locations locations={realm.locations} bind:selected />
|
||||||
{/if}
|
{/if}
|
||||||
{/each}
|
{/each}
|
||||||
{/if}
|
{/if}
|
||||||
</td>
|
</td>
|
||||||
<td class="items">
|
<td class="items">
|
||||||
|
{#if selected}
|
||||||
|
<h3>{selected.name}</h3>
|
||||||
|
{/if}
|
||||||
|
{#if items}
|
||||||
|
<pre>{JSON.stringify(items)}</pre>
|
||||||
|
{/if}
|
||||||
<ItemList />
|
<ItemList />
|
||||||
</td>
|
</td>
|
||||||
<td class="properties">
|
<td class="properties">
|
||||||
|
|||||||
@@ -3,11 +3,12 @@
|
|||||||
import { error, yikes } from '../../warn.svelte';
|
import { error, yikes } from '../../warn.svelte';
|
||||||
import { t } from '../../translations.svelte';
|
import { t } from '../../translations.svelte';
|
||||||
|
|
||||||
let { locations } = $props();
|
let { locations, selected = $bindable(null) } = $props();
|
||||||
|
|
||||||
async function toggleChildren(ev, location){
|
async function toggleChildren(ev, location){
|
||||||
ev.preventDefault();
|
ev.preventDefault();
|
||||||
ev.stopPropagation();
|
ev.stopPropagation();
|
||||||
|
selected = location;
|
||||||
if (location.locations) {
|
if (location.locations) {
|
||||||
delete location.locations;
|
delete location.locations;
|
||||||
} else {
|
} else {
|
||||||
@@ -32,7 +33,7 @@
|
|||||||
<li onclick={e => toggleChildren(e, location)} class={location.locations?'expanded':'collapsed'}>
|
<li onclick={e => toggleChildren(e, location)} class={location.locations?'expanded':'collapsed'}>
|
||||||
{location.name}
|
{location.name}
|
||||||
{#if location.locations}
|
{#if location.locations}
|
||||||
<svelte:self locations={location.locations} />
|
<svelte:self locations={location.locations} bind:selected />
|
||||||
{/if}
|
{/if}
|
||||||
</li>
|
</li>
|
||||||
{/each}
|
{/each}
|
||||||
|
|||||||
@@ -5,9 +5,11 @@ public class Constants {
|
|||||||
|
|
||||||
private Constants(){}
|
private Constants(){}
|
||||||
|
|
||||||
|
|
||||||
public static final String BELOW = "below";
|
public static final String BELOW = "below";
|
||||||
public static final String CONFIG_DATABASE = "umbrella.modules.stock.database";
|
public static final String CONFIG_DATABASE = "umbrella.modules.stock.database";
|
||||||
public static final String ITEM_ID = "item_id";
|
public static final String ITEM_ID = "item_id";
|
||||||
|
public static final String ITEMS_AT = "items_at";
|
||||||
public static final String LOCATIONS = "locations";
|
public static final String LOCATIONS = "locations";
|
||||||
public static final String OF_USER = "of_user";
|
public static final String OF_USER = "of_user";
|
||||||
public static final String PROPERTY_ID = "prop_id";
|
public static final String PROPERTY_ID = "prop_id";
|
||||||
|
|||||||
@@ -13,7 +13,9 @@ import static java.lang.System.Logger.Level.ERROR;
|
|||||||
import static java.lang.System.Logger.Level.WARNING;
|
import static java.lang.System.Logger.Level.WARNING;
|
||||||
import static java.text.MessageFormat.format;
|
import static java.text.MessageFormat.format;
|
||||||
|
|
||||||
|
import de.srsoftware.tools.Mappable;
|
||||||
import de.srsoftware.umbrella.core.BaseDb;
|
import de.srsoftware.umbrella.core.BaseDb;
|
||||||
|
import de.srsoftware.umbrella.core.ModuleRegistry;
|
||||||
import de.srsoftware.umbrella.core.exceptions.UmbrellaException;
|
import de.srsoftware.umbrella.core.exceptions.UmbrellaException;
|
||||||
import de.srsoftware.umbrella.core.model.Company;
|
import de.srsoftware.umbrella.core.model.Company;
|
||||||
import de.srsoftware.umbrella.core.model.Item;
|
import de.srsoftware.umbrella.core.model.Item;
|
||||||
@@ -139,6 +141,38 @@ public class SqliteDb extends BaseDb implements StockDb {
|
|||||||
return List.of();
|
return List.of();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Collection<Item> listItemsAt(long locationId) {
|
||||||
|
try {
|
||||||
|
var rs = select(ALL).from(TABLE_ITEMS).where(LOCATION_ID,equal(locationId)).exec(db);
|
||||||
|
var list = new ArrayList<Item>();
|
||||||
|
|
||||||
|
while (rs.next()) {
|
||||||
|
var ownerId = rs.getLong(OWNER);
|
||||||
|
Mappable owner = ownerId < 0 ? ModuleRegistry.companyService().get(-ownerId) : ModuleRegistry.userService().loadUser(ownerId);
|
||||||
|
var location = loadLocation(rs.getLong(LOCATION_ID));
|
||||||
|
list.add(Item.of(rs, owner, location));
|
||||||
|
}
|
||||||
|
rs.close();
|
||||||
|
return list;
|
||||||
|
} catch (SQLException e){
|
||||||
|
throw databaseException("Failed to load items at {0}",locationId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private Location loadLocation(long locationId) {
|
||||||
|
try {
|
||||||
|
var rs = select(ALL).from(TABLE_LOCATIONS).where(ID,equal(locationId)).exec(db);
|
||||||
|
Location loc = null;
|
||||||
|
if (rs.next()) loc = Location.of(rs);
|
||||||
|
rs.close();
|
||||||
|
if (loc != null) return loc;
|
||||||
|
throw databaseException("Failed to load location with id = {0}",locationId);
|
||||||
|
} catch (SQLException e){
|
||||||
|
throw databaseException("Failed to load location with id = {0}",locationId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Collection<Location> listLocations(long companyId) {
|
public Collection<Location> listLocations(long companyId) {
|
||||||
return List.of();
|
return List.of();
|
||||||
|
|||||||
@@ -19,6 +19,7 @@ import de.srsoftware.umbrella.core.BaseHandler;
|
|||||||
import de.srsoftware.umbrella.core.ModuleRegistry;
|
import de.srsoftware.umbrella.core.ModuleRegistry;
|
||||||
import de.srsoftware.umbrella.core.api.StockService;
|
import de.srsoftware.umbrella.core.api.StockService;
|
||||||
import de.srsoftware.umbrella.core.exceptions.UmbrellaException;
|
import de.srsoftware.umbrella.core.exceptions.UmbrellaException;
|
||||||
|
import de.srsoftware.umbrella.core.model.Item;
|
||||||
import de.srsoftware.umbrella.core.model.Location;
|
import de.srsoftware.umbrella.core.model.Location;
|
||||||
import de.srsoftware.umbrella.core.model.Token;
|
import de.srsoftware.umbrella.core.model.Token;
|
||||||
import de.srsoftware.umbrella.core.model.UmbrellaUser;
|
import de.srsoftware.umbrella.core.model.UmbrellaUser;
|
||||||
@@ -45,14 +46,26 @@ public class StockApi extends BaseHandler implements StockService {
|
|||||||
if (user.isEmpty()) return unauthorized(ex);
|
if (user.isEmpty()) return unauthorized(ex);
|
||||||
var head = path.pop();
|
var head = path.pop();
|
||||||
return switch (head) {
|
return switch (head) {
|
||||||
|
case ITEMS_AT -> {
|
||||||
|
try {
|
||||||
|
var id = Long.parseLong(path.pop());
|
||||||
|
yield getItemsAt(user.get(),id,ex);
|
||||||
|
} catch (Exception e){
|
||||||
|
yield super.doGet(path,ex);
|
||||||
|
}
|
||||||
|
}
|
||||||
case LOCATIONS -> getLocations(path,user.get(),ex);
|
case LOCATIONS -> getLocations(path,user.get(),ex);
|
||||||
case null, default -> doGet(path,ex);
|
case null, default -> super.doGet(path,ex);
|
||||||
};
|
};
|
||||||
} catch (UmbrellaException e){
|
} catch (UmbrellaException e){
|
||||||
return send(ex,e);
|
return send(ex,e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private boolean getItemsAt(UmbrellaUser user, long locationId, HttpExchange ex) throws IOException {
|
||||||
|
return sendContent(ex, stockDb.listItemsAt(locationId).stream().map(Item::toMap).toList());
|
||||||
|
}
|
||||||
|
|
||||||
private boolean getLocations(Path path, UmbrellaUser user, HttpExchange ex) throws IOException {
|
private boolean getLocations(Path path, UmbrellaUser user, HttpExchange ex) throws IOException {
|
||||||
var head = path.pop();
|
var head = path.pop();
|
||||||
return switch (head){
|
return switch (head){
|
||||||
|
|||||||
@@ -14,6 +14,8 @@ public interface StockDb {
|
|||||||
|
|
||||||
Collection<Item> listItems(long companyId) throws UmbrellaException;
|
Collection<Item> listItems(long companyId) throws UmbrellaException;
|
||||||
|
|
||||||
|
Collection<Item> listItemsAt(long locationId);
|
||||||
|
|
||||||
Collection<Location> listLocations(long companyId);
|
Collection<Location> listLocations(long companyId);
|
||||||
|
|
||||||
Collection<Location> listUserLocations(UmbrellaUser userId);
|
Collection<Location> listUserLocations(UmbrellaUser userId);
|
||||||
|
|||||||
Reference in New Issue
Block a user