GGCE Server issueshttps://gitlab.croptrust.org/grin-global/grin-global-server/-/issues2022-07-01T08:43:59+02:00https://gitlab.croptrust.org/grin-global/grin-global-server/-/issues/312Problem updating OrderRequestItem2022-07-01T08:43:59+02:00Matija ObrezaProblem updating OrderRequestItemThe `OrderRequestItemServiceImpl#update` method takes the incoming data and directly applies it to `target`:
```java
public OrderRequestItem update(OrderRequestItem input, OrderRequestItem target) {
LOG.debug("Update OrderRequestItem. ...The `OrderRequestItemServiceImpl#update` method takes the incoming data and directly applies it to `target`:
```java
public OrderRequestItem update(OrderRequestItem input, OrderRequestItem target) {
LOG.debug("Update OrderRequestItem. Input data {}", input);
// save order request
input.setOrderRequest(target.getOrderRequest());
target.apply(input);
var saved = repository.save(target);
return _lazyLoad(saved);
}
```
While this works for basic fields, in this case the `@PreUpdate/@PrePersist` in `OrderRequestItem` does some validation against `this.inventory` and `this.withdrawnInventory`. But `withdrawnInventory` is not loaded from the database, it is simply applied to `target`.
When `{ ..., "withdrawnInventory": { "id": 127121 } }` is received, this object has no `accession`!
In the `#update(source, target)` method we should **get `source.withdrawnInventory` and `source.inventory` from the database** before applying them to `target`.
The current `update()` fails with `NPE` when we try to access `this.inventory.accession` and `this.withdrawnInventory.accession`.
## Stacktrace
```
2022-06-29 15:06:27 qtp542060780-12 WARN ApiExceptionHandler:238 - Wow! Such! Exception!
org.springframework.transaction.TransactionSystemException: Could not commit JPA transaction; nested exception is javax.persistence.RollbackException: Error while committing the transaction
at org.springframework.orm.jpa.JpaTransactionManager.doCommit(JpaTransactionManager.java:571)
at org.gringlobal.api.v1.CRUDController.update(CRUDController.java:147) ~[classes/:?]
at org.gringlobal.api.v1.FilteredCRUDController.update(FilteredCRUDController.java:140) ~[classes/:?]
Caused by: javax.persistence.RollbackException: Error while committing the transaction
Caused by: java.lang.NullPointerException
at org.gringlobal.model.OrderRequestItem.checkOrderRequestItem(OrderRequestItem.java:131) ~[classes/:?]
```2022.7Artem HrybeniukArtem Hrybeniukhttps://gitlab.croptrust.org/grin-global/grin-global-server/-/issues/311Trait API endpoints2022-06-29T11:50:28+02:00Matija ObrezaTrait API endpoints
The new endpoints are in the existing `CropTraitController` and require `Method#id`. They operate on `CropTraitObservation` (CTO) or CTOD:
- GET paged endpoint */observations/{methodId}/inventories* that returns a `Page<Inventory>`: g...
The new endpoints are in the existing `CropTraitController` and require `Method#id`. They operate on `CropTraitObservation` (CTO) or CTOD:
- GET paged endpoint */observations/{methodId}/inventories* that returns a `Page<Inventory>`: get distinct inventory from `CTO` for selected `method`
- GET paged endpoint */observations/{methodId}/traits*, returning `Page<CropTrait>`: get distinct crop trait from `CTO` for selected `method`
- GET paged endpoint */observations-data/{methodId}/inventories* that returns a `Page<Inventory>`: get distinct inventory from `CTOD` for selected `method`
- GET paged endpoint */observations-data/{methodId}/traits* returning `Page<CropTrait>`: get distinct crop trait from `CTOD` for selected method
For these methods to return "something" we implement an endpoint that ensures that **at least one CTO or CTOD** exists for the `method`, `cropTrait` and `inventory`: a new CTO or CTOD record is added only if there is no existing record for the combination:
- POST endpoint */observations/ensure* that receives `{ method: { id }, cropTraitId: [ 1, 3, 4 ..], inventoryId: [ 3, 5, 61, ... ]}`, creates new `CTOs` if missing, and returns the number of newly added records `int`.
- POST endpoint */observations-data/ensure* that receives `{ method: { id }, cropTraitId: [ 1, 3, 4 ..], inventoryId: [ 3, 5, 61, ... ]}`, creates new `CTODs` if missing, and returns the number of newly added records `int`.2022.7Artem HrybeniukArtem Hrybeniukhttps://gitlab.croptrust.org/grin-global/grin-global-server/-/issues/310Location API feedback2022-06-29T12:02:32+02:00Matija ObrezaLocation API feedback@jarias from @1cgiar/palmira reports in grin-global/support#113:
* Missing foreign key between the `location` table and `location_action`, it is only as an attribute in the `location` table:
- also `created_by`, `modified_by` and `own...@jarias from @1cgiar/palmira reports in grin-global/support#113:
* Missing foreign key between the `location` table and `location_action`, it is only as an attribute in the `location` table:
- also `created_by`, `modified_by` and `owned_by`
* In the `location_data` table, can the `unit_code` attribute be included?
* If possible, add a `status` attribute to the `location` table?
API:
* In the request `/api/v1/location/reservation/list`, it is returning `location` and `inventory` as `null`. They should be included `lazyLoad`
* In the request `/api/v1/location/action` (Add), it is returning `location` in `null`. `lazyLoad`
* In the request `/api/v1/location/action` (Update), it is returning `location` in null.
* CRUD API for `location_data` is not availableArtem HrybeniukArtem Hrybeniukhttps://gitlab.croptrust.org/grin-global/grin-global-server/-/issues/309Trait observation API2022-06-24T17:57:58+02:00Matija ObrezaTrait observation APIThis describes the updates to the API handling crop trait observations and observation data.
- `Method` is the primary mechanism that groups trait data and provides the context about the experiment.
- `CropTrait` defines a trait and may...This describes the updates to the API handling crop trait observations and observation data.
- `Method` is the primary mechanism that groups trait data and provides the context about the experiment.
- `CropTrait` defines a trait and may optionally have a limited set of `CropTraitCodes` that are allowed
It is best to imagine that `Method` represents a spreadsheet where columns are `CropTraits` and rows are `Inventories` (trait `x` inventory).
Each cell in this table contains one or more `CropTraitObservations`.
- `CropTraitObservation` contains one **result** of the observation. There can be multiple CTO for one trait `x` inventory.
- `CropTraitObservationData` contains the raw data trait `x` inventory `x` **individual**.
# Link between CTO and CTOD
`CropTraitObservationData` records the detailed trait observations of different **individuals** of one **inventory** and there are usually many CTOD records for one `inventory` and `cropTrait` in one `method`.
~~The `CTOD#cropTraitObservation` is required, so a CTOD record cannot exist without a corresponding CTO.~~
The `CTOD#cropTraitObservation` is **not required** and a CTOD record can exist without a corresponding CTO.
CTOD observations may be captured under a different `CropTrait` (e.g. numerical/quantitative values) while the corresponding CTO could be a coded trait.
**There is no direct link between `ctod` and `cto` records.** The following is **incorrect**:
> Regardless, must ensure that:
>
> 1. `ctod.method == cto.method`
> 1. `ctod.inventory == cto.inventory`
> 1. `ctod.cropTrait == cto.cropTrait`
> 1. `ctod.cropTraitCode == cto.cropTraitCode` (can be null if the `CropTrait` is not using codes)
> 1. `ctod.cropTraitCode.cropTrait == cto.cropTraitCode.cropTrait` (I think we handle that in `@PrePersist/@PreUpdate` already)
## CTO: `update(CropTraitObservation)`
The implementation of `create` and `delete` methods for CTO remains the same. The `update(CTO)` method is updated and behaves as following:
The following is **incorrect**:
> 1. If there exist 0 CTOD for this `cto`, just update the `cto`
> 1. ~~If there exists at least 1 CTOD for this `cto` then update `cto` only if `method`, `inventory`, `cropTrait` and `cropTraitCode` match the first `ctod`~~
> 1. Refuse to update CTO if there are any CTOD records linked to it -- CTO value must be generated from CTODs.
## CTOD: `create(CropTraitObservationData)` and `update(CropTraitObservationData)`
The following is **incorrect**:
> ~~To ensure that `CTO` and `CTOD` records are properly linked together, the API must ignore the incoming `ctod.cropTraitObservation`. The actual `CTO` is calculated by loading
existing CTO records by `ctod.method`, `inventory` and `cropTrait` because multiple records are possible according to unique constraint on the table for different `crop_trait_code_id`, `numeric_value` and `string_value`.~~
>
> ~~Every time a CTOD is created/updated/removed the server will **recalculate** CTO records based on all existing CTODs. This means that `CTOD#cropTraitObservation` may change as a result of CTOD modifications.~~
>
> ~~`create(ctod)` must assert that `ctod.cropTraitObservation == null`. Similarly, `update(ctod)` must assert that `ctod.cropTraitObservation == null`.~~
## Generating CTOs from CTODs
GGCE API is able to generate and **propose** CTO records calculated from CTODs. The user still needs to review and add them manually.2022.7Matija ObrezaMatija Obrezahttps://gitlab.croptrust.org/grin-global/grin-global-server/-/issues/308Inspect Log is not working.2022-06-23T12:33:39+02:00Juan Carlos Alarcon MaldonadoInspect Log is not working.The inspect Log is not working, when I clicked on it, the new tab is open but without any information.
![image](/uploads/23cf633ef29591ea3311517f1c71eefd/image.png)
and, this is the new tab.
![image](/uploads/558684d8d050b16772e0de2a2...The inspect Log is not working, when I clicked on it, the new tab is open but without any information.
![image](/uploads/23cf633ef29591ea3311517f1c71eefd/image.png)
and, this is the new tab.
![image](/uploads/558684d8d050b16772e0de2a29a02650/image.png)2022.6Artem HrybeniukArtem Hrybeniukhttps://gitlab.croptrust.org/grin-global/grin-global-server/-/issues/307Palmira: Additional models and endpoints2022-06-23T16:05:47+02:00Matija ObrezaPalmira: Additional models and endpoints@1cgiar/palmira is requesting additional models and CRUD API endpoints to enhance existing GGCE schema.
Please add the following entities to `org.gringlobal.model.community` package:
- `Location` represents a physical place (the origin...@1cgiar/palmira is requesting additional models and CRUD API endpoints to enhance existing GGCE schema.
Please add the following entities to `org.gringlobal.model.community` package:
- `Location` represents a physical place (the original name `CONTAINER` is easily confused with material container (Alu pack, Glass jar)). `Location#parentLocation` allows to organize places into a highly dynamic tree structure.
- `LocationData` allows for attaching user-defined attributes (originally named `CONTAINER_DATA`)
- `LocationReservation` keeps track of "bookings" at one location (proposed name was `STORAGE_CONTAINER_MAP`)
```java
/**
* Location represents a physical place at a {@link Site}: buildings - rooms - racks, fields, greenhouses, etc.
*
* Locations are organized into a tree structure where
* each location with <code>parentLocation == null</code> starts a new tree at the {#link Site}.
*
* Location may declare its {@link #capacity} and {@link #capacityUnitCode}, specifying
* its total available area/volume/length/duration.
*/
class Location extends CooperatorOwnedModel implements SelfCleaning {
@ManyToOne(required = false)
private Location parentLocation; // Locations have a hierarchical structure
@NotNull @ManyToOne(required = true)
private Site site; // Needs index
@NotNull @SimpleString
private String locationNumberPart1;
private Long locationNumberPart2;
@SimpleString
private String locationNumberPart3;
@NotNull @CodeValueField("LOCATION_TYPE")
private String locationTypeCode;
@ManyToOne(required=false)
private Geography geography;
@NotNull
private String barcode; // in @PrePersist use UUID.randomUUID().toString() if blank
@Min(0)
private int capacity = 0; // The capacity of this location, may be 0
@CodeValueField("UNIT_OF_CAPACITY")
private String capacityUnitCode; // If capacity != 0 then it must be provided
}
/**
* LocationData allows for attaching user-defined attributes to each {#link Location}.
*/
class LocationData extends CooperatorOwnedModel implements SelfCleaning {
private Location location;
@NotNull @CodeValueField("LOCATION_PROPERTY")
private String locationPropertyCode;
@NotNull
private String value;
}
/**
* Actions are performed on {@link Location}s.
*/
class LocationAction extends AbstractAction<LocationAction> {
// No extra fields for now
@Override
@CodeValueField("LOCATION_ACTION")
public String getActionNameCode() {
return this.actionNameCode;
}
}
/**
* Describes a reservation of capacity at a {@link Location} for the specified
* time frame (start and end date). A reservation is PENDING if the start date is
* in the future, it is ACTIVE if `startDate < now < endDate`
*/
class LocationReservation extends CooperatorOwnedModel implements SelfCleaning {
@NotNull @ManyToOne(required = true)
private Location location;
@NotNull @ManyToOne(required = false)
private Inventory inventory; // Does not require an inventory to reserve a location
@NotNull @Column(name = "start_date") @Temporal(TemporalType.DATE)
protected LocalDate startDate; // inclusive
@NotNull @Column(name = "end_date") @Temporal(TemporalType.DATE)
protected LocalDate endDate; // inclusive, must be greater or equal to startDate!
@IgnoreField
@Formula("datediff( day, start_date, end_date )") // FIXME or datediff() + 1?
private Integer reservedDays; // calculated field
@Min(1)
private int size; // The amount of reserved capacity at Location expressed in Location's capacityUnitCode
@Min(0)
private int offset = 0; // The offset is used to indicate where at the Location's capacity the space is reserved
}
```
We will need `LocationFilter` and `LocationReservationFilter`. Use sensible filtering options, we'll update later on demand.
Please add the following services:
```java
LocationServiceImpl extends FilteredCRUDService<Location> implements LocationService {
protected static class ActionSupport extends BaseActionSupport<> {...
class LocationDataService extends CRUDService<LocationData> {...
}
LocationReservationServiceImpl extends FilteredCRUDService<Location> implements LocationService {
...
}
```
Add the basic controllers: `LocationController extends CRUDController` at `/location` and `LocationReservationController` at `/location/reservation`.
Note to self: These POJOs are based on several teleconferences around the excel file [Prueba_escritorio_contenedores.xlsx](https://gitlab.croptrust.org/grin-global/support/uploads/58b5b9ee56c50c40db61f2d882574be0/Prueba_escritorio_contenedores.xlsx).2022.6Artem HrybeniukArtem Hrybeniukhttps://gitlab.croptrust.org/grin-global/grin-global-server/-/issues/306Update docker server documentation2023-09-05T06:54:54+02:00Juan Carlos Alarcon MaldonadoUpdate docker server documentationAdd a list of configuration documentation for new features as requests DOI to GLIS .Add a list of configuration documentation for new features as requests DOI to GLIS .Matija ObrezaMatija Obrezahttps://gitlab.croptrust.org/grin-global/grin-global-server/-/issues/305Allow edit group tag2022-06-16T14:57:45+02:00Artem HrybeniukAllow edit group tagAllow edit `SysGroup` `groupTag`.
![G1](https://gitlab.croptrust.org/grin-global/grin-global-ui/uploads/7f91fc637396c3f28b6a2b2c6ed1ebb8/G1.png)
This requires API update and flushing of permissions cache when a record is modified.Allow edit `SysGroup` `groupTag`.
![G1](https://gitlab.croptrust.org/grin-global/grin-global-ui/uploads/7f91fc637396c3f28b6a2b2c6ed1ebb8/G1.png)
This requires API update and flushing of permissions cache when a record is modified.2022.6Artem HrybeniukArtem Hrybeniukhttps://gitlab.croptrust.org/grin-global/grin-global-server/-/issues/304OAuth upgrade2022-09-22T06:38:38+02:00Matija ObrezaOAuth upgradeStrip out the legacy `org.springframework.security.oauth:spring-security-oauth2` and switch to `org.springframework.security:spring-security-oauth2-resource-server` and `spring-security-oauth2-authorization-server`.
If the `authorizatio...Strip out the legacy `org.springframework.security.oauth:spring-security-oauth2` and switch to `org.springframework.security:spring-security-oauth2-resource-server` and `spring-security-oauth2-authorization-server`.
If the `authorization-server` becomes a problem, then perhaps start with Google's OAuth 2 login (see https://docs.spring.io/spring-security/reference/servlet/oauth2/login/advanced.html#oauth2login-advanced-redirection-endpoint for example) or with [Okta](https://www.baeldung.com/spring-security-okta).
- https://docs.spring.io/spring-security/reference/servlet/oauth2/login/core.html#oauth2login-completely-override-autoconfiguration
- https://docs.spring.io/spring-security/reference/servlet/oauth2/resource-server/multitenancy.htmlMatija ObrezaMatija Obrezahttps://gitlab.croptrust.org/grin-global/grin-global-server/-/issues/303AclSid autocomplete endpoint by SysUser and OAuthClient2022-05-18T16:14:33+02:00Artem HrybeniukAclSid autocomplete endpoint by SysUser and OAuthClientAdd searching for `AclSid` by `SysUser` and `OAuthClient`.
For https://gitlab.croptrust.org/grin-global/grin-global-ui/-/merge_requests/402Add searching for `AclSid` by `SysUser` and `OAuthClient`.
For https://gitlab.croptrust.org/grin-global/grin-global-ui/-/merge_requests/4022022.5Artem HrybeniukArtem Hrybeniukhttps://gitlab.croptrust.org/grin-global/grin-global-server/-/issues/302User management in GGCE2022-08-04T05:48:23+02:00Matija ObrezaUser management in GGCEThe original GG maintains a separate user (`SysUser`, `WebUser`) database and GGCE adds `OAuthClient` to this list. Users may be organized into groups (`SysGroup`). User authentication and password management is handled by GG, GGCE adds ...The original GG maintains a separate user (`SysUser`, `WebUser`) database and GGCE adds `OAuthClient` to this list. Users may be organized into groups (`SysGroup`). User authentication and password management is handled by GG, GGCE adds OAuth token support.
In enterprise deployments, user management and authentication is generally managed centrally, either through AD or another identity management solution. GGCE is primarily a *resource server* and should therefore be designed primarily for use with external identity *auth servers* such as https://www.keycloak.org, [Okta](https://developer.okta.com/signup/), Azure AD and others.
For development or evaluation deployments, GGCE should provide a built-in *auth server* (`spring-security-oauth2-authorization-server`?) that only handles `LOCAL` accounts.
GGCE as a resource server then needs to support multiple auth servers: e.g. keycloak + built-in, or perhaps azuread + google + okta + built-in.
## Support for CT
The CT uses SOAP and passes user credentials with every SOAP request. Without changing the bulk of CT and the current GG webservices, the initial idea is to use a user-definable **application password** that is used for legacy applications.
## User provisioning
GGCE requires that user info is stored in the local database (`SysUser`). This is used in auditing info across the database.
SCIM or periodic updating can be used to synchronize the local "user database" with external IdP. But at the very least, a user may be denied access to the system as IdP will not issue a token for disabled accounts.
## Permission and role management
Permission management (ACL) remains within the domain of the application and permissions must be configurable in GGCE directly.
## Logging into GGCE
Since the API is only a *resource server*, access is only possible with a valid JWT token provided by one of the configured *auth servers*.
The login screens of GGCE Web and of GGCE Server should therefore include the all configured login options:
- Login with Microsoft
- Login with Google
- Login with...
- *Local* login (GGCE Auth Server)
Each one of these redirects the user to the respective "login page" and ideally results in a valid JWT for the application.
### Obtaining a GGCE token
The API should consider JWT from any of the configured IdP as valid, but we may want to exchange the external JWT for a GGCE-generated JWT (enhance it with `SysUser` data) after login.
Similarly, we should have a single "login screen" as described above, implemented in GGCE Server.Matija ObrezaMatija Obrezahttps://gitlab.croptrust.org/grin-global/grin-global-server/-/issues/301Type of Container2022-05-13T13:08:17+02:00Matija ObrezaType of ContainerThis ticket is to add the "Type of container" to `Inventory` and `OrderRequestItem` as `containerTypeCode`. The field will use `CodeValue` `CONTAINER_TYPE` and is optional (nullable in the database).
Update the registration of *withdraw...This ticket is to add the "Type of container" to `Inventory` and `OrderRequestItem` as `containerTypeCode`. The field will use `CodeValue` `CONTAINER_TYPE` and is optional (nullable in the database).
Update the registration of *withdrawn inventories* so that they use the code specified in `OrderRequestItem#containerTypeCode`.
@mtishchenko UI forms for `Inventory` and `OrderRequestItem` need a new dropdown for "Type of Container".2022.5Artem HrybeniukArtem Hrybeniukhttps://gitlab.croptrust.org/grin-global/grin-global-server/-/issues/300Jetty upgrade2022-05-18T16:14:33+02:00Matija ObrezaJetty upgradeThe server and docker container rely on *jetty:9* that is reaching end-of-life soon and this needs to be upgraded to either `jetty:10` or `11`.
Which version do we switch to?The server and docker container rely on *jetty:9* that is reaching end-of-life soon and this needs to be upgraded to either `jetty:10` or `11`.
Which version do we switch to?2022.5Artem HrybeniukArtem Hrybeniukhttps://gitlab.croptrust.org/grin-global/grin-global-server/-/issues/299Pagination2022-05-18T07:06:15+02:00Matija ObrezaPaginationOur implementation of pagination assumes that the database will always generate the same order of items from which the requested slice (offset + limit) are then returned. This works well when sorting by `id` column (usually default), but...Our implementation of pagination assumes that the database will always generate the same order of items from which the requested slice (offset + limit) are then returned. This works well when sorting by `id` column (usually default), but not so well when other fields are involved. See https://staging.ggce.genesys-pgr.org/t/species and sort by `Name Verification Date`. Then hit "Reload" button and observe that different order of records is returned.
To ensure the proper ordering of items and their slicing (offset + limit) the `id` column must always be included as the last of the `Sort` fields (`order by ..., id asc`) for page requests to the database.2022.5Artem HrybeniukArtem Hrybeniukhttps://gitlab.croptrust.org/grin-global/grin-global-server/-/issues/298Firehose notification system2022-06-23T12:32:52+02:00Matija ObrezaFirehose notification systemWe introduced the Firehose to have information about what data was committed to the database. Firehose emits notifications about entity changes.
This ticket is to design API support that allows users to:
1. Subscribe to specific Fireho...We introduced the Firehose to have information about what data was committed to the database. Firehose emits notifications about entity changes.
This ticket is to design API support that allows users to:
1. Subscribe to specific Firehose event types
1. Receive email notifications when those events happen
Involve @ahrybeniuk, @crabil, @jalarcon and @adovhopolenko in the user requirements and UI design.
## Ideas to consider
1. Alert me when `Accession.accessionNumber` is modified
1. Alert me whenever a new `Inventory` is registered
1. Alert me when an action of type XX is completed
## Message delivery
1. Alert me immediately
1. Daily update
1. Weekly update?Artem HrybeniukArtem Hrybeniukhttps://gitlab.croptrust.org/grin-global/grin-global-server/-/issues/297Accession similarity search2022-04-28T22:52:56+02:00Matija ObrezaAccession similarity searchgrin-global/grin-global-ui!391 requires API support to find similar `Accessions` in the database using the existing `DuplicateFinder` base implementation.
After implementing the `AccessionDuplicateFinder` component, add the following en...grin-global/grin-global-ui!391 requires API support to find similar `Accessions` in the database using the existing `DuplicateFinder` base implementation.
After implementing the `AccessionDuplicateFinder` component, add the following endpoints to `AccessionController`:
- *POST /a/similar* `public List<DuplicateFinder.Hit<Accession>> findSimilarForUnsaved(@RequestBody(required = true) final Accession source)`2022.5Artem HrybeniukArtem Hrybeniukhttps://gitlab.croptrust.org/grin-global/grin-global-server/-/issues/296Filtering by inventory group2022-05-18T16:14:34+02:00Artem HrybeniukFiltering by inventory groupExtend `AccessionFilter` and `InventoryFilter` with support to select by `AccessionInvGroup`.Extend `AccessionFilter` and `InventoryFilter` with support to select by `AccessionInvGroup`.2022.5Artem HrybeniukArtem Hrybeniukhttps://gitlab.croptrust.org/grin-global/grin-global-server/-/issues/295OrderRequest inventories updates2022-05-18T16:14:34+02:00Artem HrybeniukOrderRequest inventories updateshttps://gitlab.croptrust.org/grin-global/support/-/issues/150:
The quantity_on_hand(Inventory table) value must be automatic deducted after the item of one order was shipped.
The constraints for the auto-deduction are:
* Inventory.qua...https://gitlab.croptrust.org/grin-global/support/-/issues/150:
The quantity_on_hand(Inventory table) value must be automatic deducted after the item of one order was shipped.
The constraints for the auto-deduction are:
* Inventory.quantity_on_hand_unit_code = Inventory_maintenance_policy.Distribution_unit_code
* Inventory.form_type_code = Inventory_maintenance_policy.distribution_default_form_code
* Inventory.is_auto_deducted = Inventory_maintenance_policy.is_auto_deducted = `Yes`
https://gitlab.croptrust.org/grin-global/support/-/issues/151:
For the inventories created from an order (`WITHDRAWN INVENTORIES`), the quantity_on_hand value must be the quantity_shipped.2022.5Artem HrybeniukArtem Hrybeniukhttps://gitlab.croptrust.org/grin-global/grin-global-server/-/issues/294Error message when the user adds an inventory (is_available swtich problem).2022-04-18T11:05:08+02:00Juan Carlos Alarcon MaldonadoError message when the user adds an inventory (is_available swtich problem).When the user `change` the `is_available` switch
![image](/uploads/0c28e12798ae00901a940d8cb32f7dcf/image.png)
and it click on `Save` button, a error message got
![image](/uploads/fe910d0ce3fc5807c199f8ab96fa020a/image.png)
althoug...When the user `change` the `is_available` switch
![image](/uploads/0c28e12798ae00901a940d8cb32f7dcf/image.png)
and it click on `Save` button, a error message got
![image](/uploads/fe910d0ce3fc5807c199f8ab96fa020a/image.png)
although the error is showed, the inventory is recorded.
@mobrezaVladyslava MokliakVladyslava Mokliakhttps://gitlab.croptrust.org/grin-global/grin-global-server/-/issues/293Reset password improvements2022-05-18T16:14:34+02:00Artem HrybeniukReset password improvementsUpdates for https://gitlab.croptrust.org/grin-global/grin-global-ui/-/issues/400:
- update email reset password template
- send a confirmation Email of the successful password changeUpdates for https://gitlab.croptrust.org/grin-global/grin-global-ui/-/issues/400:
- update email reset password template
- send a confirmation Email of the successful password change2022.5Artem HrybeniukArtem Hrybeniuk