Skip to content
Snippets Groups Projects
Commit 48b6c9eb authored by Florian Spreckelsen's avatar Florian Spreckelsen
Browse files

Merge branch 'f-datamodel-ui' into 'main'

MAINT: move datamodel config to a separate file

See merge request !5
parents 445dde8c 6993d10c
No related branches found
No related tags found
1 merge request!5MAINT: move datamodel config to a separate file
Pipeline #61761 passed with warnings
Showing with 1052 additions and 427 deletions
...@@ -16,10 +16,29 @@ Mount the custom folder by adding it to the `profile.yml`. E.g. ...@@ -16,10 +16,29 @@ Mount the custom folder by adding it to the `profile.yml`. E.g.
Also, you need to add the python package to the scripting interface in the Also, you need to add the python package to the scripting interface in the
profile: profile:
``` ```
TODO scripting:
packages:
loanpy:
mode: "copy"
path: "loan/loanpy"
package: "linkahead-sss-loanpy"
``` ```
## Configuration
There is an example datamodel in `datamodel-default.yml` in this
repository that contains the minimal datamodel for LinkAhead Loan
using all default names for the required entities.
Note that you can adjust names of Recordtypes and Properties that are used.
If you want to do this, you need to
1. Create a configuration file for `loanpy`. Place a `~/linkahead_loan.ini` in
the sss home directory (`caosdb-server/scripting/home`) and add those keys,
that you want to change. Check out the available options in the default file
`loanpy/src/loan/default_config.ini`.
- Add a `caosdb-server/caosdb-webui/src/ext/js/a_box_loan_config.js` to your
custom folder such that it overwrites the corresponding file of loan-custom.
## Integration tests ## Integration tests
Run `pytest .` in the integration tests folder Run `pytest .` in the integration tests folder
......
# Copyright (C) 2025 IndiScale GmbH <info@indiscale.com>
# Copyright (C) 2025 Florian Spreckelsen <f.spreckelsen@indiscale.com>
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as
# published by the Free Software Foundation, either version 3 of the
# License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
# Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public
# License along with this program. If not, see
# <https://www.gnu.org/licenses/>.
#
Box:
recommended_properties:
Location:
Content:
Number:
datatype: TEXT
Person:
recommended_properties:
firstName:
datatype: TEXT
lastName:
datatype: TEXT
email:
datatype: TEXT
Loan:
recommended_properties:
Box:
Borrower:
datatype: Person
expected_return:
datatype: DATETIME
exhaustContents:
datatype: BOOLEAN
comment:
datatype: TEXT
LoanLocation:
datatype: Location
loanRequested:
datatype: DATETIME
loanAccepted:
datatype: DATETIME
lent:
datatype: DATETIME
returnRequested:
datatype: DATETIME
Content:
datatype: TEXT
ReturnLocation:
datatype: Location
returnAccepted:
datatype: DATETIME
returned:
datatype: DATETIME
Location:
BUILD_MODULE_BOX_LOAN=ENABLED
/*
* This file is a part of the LinkAhead Project.
*
* Copyright (C) 2025 Henrik tom Wörden (h.tomwoerden@indiscale.com)
* Copyright (C) 2025 IndiScale GmbH (info@indiscale.com)
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*
*/
var box_loan_config = function() {
var datamodel = {
loan: "Loan",
box: "Box",
returned: "returned",
returnAccepted: "returnAccepted",
returnRequested: "returnRequested",
lent: "lent",
loanAccepted: "loanAccepted",
loanRequested: "loanRequested",
location: "Location",
firstName: "firstName",
lastName: "lastName",
email: "email",
number: "Number",
expectedReturn: "expectedReturn",
}
var init = function() {}
return {
init: init,
datamodel: datamodel
};
}();
$(document).ready(function() {
if ("${BUILD_MODULE_BOX_LOAN}" == "ENABLED") {
caosdb_modules.register(box_loan_config);
}
});
...@@ -24,10 +24,26 @@ classifiers = [ ...@@ -24,10 +24,26 @@ classifiers = [
requires-python = ">= 3.8" requires-python = ">= 3.8"
dependencies = [ dependencies = [
"caosadvancedtools", "caosadvancedtools",
"importlib_resources",
"py3-validate-email", "py3-validate-email",
"linkahead@git+https://gitlab.indiscale.com/caosdb/src/caosdb-pylib.git@dev" "linkahead@git+https://gitlab.indiscale.com/caosdb/src/caosdb-pylib.git@dev"
] ]
[project.optional-dependencies]
test = [
"pytest",
"pytest-env",
"pytest-cov",
"coverage>=4.4.2",
]
[tool.setuptools.packages.find]
where = ["src"]
[tool.setuptools.package-data]
"loan" = ["*.ini"]
[project.urls] [project.urls]
Homepage = "https://getlinkahead.com" Homepage = "https://getlinkahead.com"
Documentation = "https://docs.indiscale.com" Documentation = "https://docs.indiscale.com"
......
import linkahead as db import linkahead as db
import os
import configparser
from importlib_resources import files, as_file
with as_file(files('loan').joinpath('default_config.ini')) as default_config_path:
user_config_path = os.path.expanduser('~/.linkahead_loan.ini')
config = configparser.ConfigParser()
config.read([default_config_path, user_config_path])
global rts, ps
rts = config['RecordTypes']
ps = config['Properties']
# RecordTypes # RecordTypes
BOX = db.RecordType(name="Box") BOX = db.RecordType(name=rts['BOX'])
PERSON = db.RecordType(name="Person") PERSON = db.RecordType(name=rts['PERSON'])
LOAN = db.RecordType(name="Loan") LOAN = db.RecordType(name=rts['LOAN'])
LOCATION = db.RecordType(name=rts['LOCATION'])
# Properties # Properties
FIRST_NAME = db.Property(name="firstName", datatype=db.TEXT) FIRST_NAME = db.Property(name=ps['FIRST_NAME'], datatype=db.TEXT)
LAST_NAME = db.Property(name="lastName", datatype=db.TEXT) LAST_NAME = db.Property(name=ps['LAST_NAME'], datatype=db.TEXT)
EMAIL = db.Property(name="email", datatype=db.TEXT) EMAIL = db.Property(name=ps['EMAIL'], datatype=db.TEXT)
LOCATION = db.RecordType(name="Location")
DESTINATION = db.Property(name="LoanLocation", datatype="Location") DESTINATION = db.Property(name=ps['DESTINATION'], datatype=rts['LOCATION'])
RETURNLOCATION = db.Property(name="ReturnLocation", datatype="Location") RETURNLOCATION = db.Property(name=ps['RETURNLOCATION'], datatype=rts['LOCATION'])
COMMENT = db.Property(name="comment", datatype=db.TEXT) COMMENT = db.Property(name=ps['COMMENT'], datatype=db.TEXT)
EXHAUST_CONTENTS = db.Property(name="exhaustContents", datatype=db.BOOLEAN) EXHAUST_CONTENTS = db.Property(name=ps['EXHAUST_CONTENTS'], datatype=db.BOOLEAN)
BORROWER = db.Property(name="Borrower", datatype=PERSON.name) BORROWER = db.Property(name=ps['BORROWER'], datatype=rts['PERSON'])
CONTENT = db.Property(name="Content", datatype=db.TEXT) CONTENT = db.Property(name=ps['CONTENT'], datatype=db.TEXT)
LOAN_REQUESTED = db.Property(name="loanRequested", datatype=db.DATETIME) LOAN_REQUESTED = db.Property(name=ps['LOAN_REQUESTED'], datatype=db.DATETIME)
EXPECTED_RETURN = db.Property(name="expectedReturn", datatype=db.DATETIME) EXPECTED_RETURN = db.Property(name=ps['EXPECTED_RETURN'], datatype=db.DATETIME)
LOAN_ACCEPTED = db.Property(name="loanAccepted", datatype=db.DATETIME) LOAN_ACCEPTED = db.Property(name=ps['LOAN_ACCEPTED'], datatype=db.DATETIME)
LENT = db.Property(name="lent", datatype=db.DATETIME) LENT = db.Property(name=ps['LENT'], datatype=db.DATETIME)
RETURN_REQUESTED = db.Property(name="returnRequested", datatype=db.DATETIME) RETURN_REQUESTED = db.Property(name=ps['RETURN_REQUESTED'], datatype=db.DATETIME)
RETURN_ACCEPTED = db.Property(name="returnAccepted", datatype=db.DATETIME) RETURN_ACCEPTED = db.Property(name=ps['RETURN_ACCEPTED'], datatype=db.DATETIME)
RETURNED = db.Property(name="returned", datatype=db.DATETIME) RETURNED = db.Property(name=ps['RETURNED'], datatype=db.DATETIME)
BOX_NUMBER = db.Property(name="Number", datatype=db.TEXT) BOX_NUMBER = db.Property(name=ps['BOX_NUMBER'], datatype=db.TEXT)
# Other Strings # Other Strings
# TODO: Adapt datamodel and remove name override # TODO: Adapt datamodel and remove name override
......
[RecordTypes]
BOX = Box
PERSON = Person
LOAN = Loan
LOCATION = Location
[Properties]
FIRST_NAME = firstName
LAST_NAME = lastName
EMAIL = email
DESTINATION = LoanLocation
RETURNLOCATION = ReturnLocation
COMMENT = comment
EXHAUST_CONTENTS = exhaustContents
BORROWER = Borrower
CONTENT = Content
LOAN_REQUESTED = loanRequested
EXPECTED_RETURN = expectedReturn
LOAN_ACCEPTED = loanAccepted
LENT = lent
RETURN_REQUESTED = returnRequested
RETURN_ACCEPTED = returnAccepted
RETURNED = returned
BOX_NUMBER = Number
...@@ -83,8 +83,8 @@ def _check_data(data): ...@@ -83,8 +83,8 @@ def _check_data(data):
bad_references.append(item) bad_references.append(item)
if bad_references: if bad_references:
raise ValueError( raise ValueError(
f"The following value(s) of {F_BOX} has/have the wrong type. It should be " f"The following value(s) of {F_BOX} has/have the wrong type. It should be "
f"integers or string representations thereof.\n{bad_references}") f"integers or string representations thereof.\n{bad_references}")
assert_date_in_future( assert_date_in_future(
data[F_EXPECTED_RETURN_DATE], data[F_EXPECTED_RETURN_DATE],
("The expected return date needs to be in the future." ("The expected return date needs to be in the future."
......
File deleted
File added
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment