> For the complete documentation index, see [llms.txt](https://docs.licensespring.com/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.licensespring.com/sdks/java-sdk/java-modules/management-sdk.md).

# Management SDK

License management is a module that provides APIs for generating license keys, placing, searching and updating orders as well as licenses. See [**Management API**](/management-api/introduction.md) for more information on the API.

{% hint style="danger" %}
License Management APIs should not be implemented in application distributions. Keep your management keys safe.
{% endhint %}

If you wish to use license management in your Maven/Gradle project, use this snippet:

{% tabs %}
{% tab title="Maven" %}

```xml
     <dependencies>
       <dependency>
            <groupId>com.licensespring</groupId>
            <artifactId>licensespring-license-management</artifactId>
            <version>2.16.1</version>
        </dependency>
    </dependencies>

    <repositories>
        <repository>
            <id>jdk-java</id>
            <url>https://licensespring-maven.s3.eu-central-1.amazonaws.com/</url>
        </repository>
    </repositories>
```

{% endtab %}

{% tab title="Gradle" %}

```java
repositories {
    mavenLocal()
    maven {
        url = 'https://licensespring-maven.s3.eu-central-1.amazonaws.com/'
    }
}

dependencies {
    implementation 'com.licensespring:licensespring-license-management:2.16.1'
}
```

{% endtab %}
{% endtabs %}

*Javadoc, jar and OSGi bundle downloads can be found at:* [***Javadoc & Downloads***](/sdks/java-sdk/downloads-and-javadoc.md)

### Initializing the Management Client

There is only **one parameter** needed to initialize the `ManagementConfiguration`:

* `managementKey`, your company management API key

Management key is available to you in the LicenseSpring web platform under "Settings -> Keys" section.

**Optional** parameter:

* `requestLogging` default is `Logger.Level.NONE`
* `proxyPort` and `proxyHost` used to setup a forward proxy, see more in [**Java Advanced Usage**](/sdks/java-sdk/java-advanced-usage.md)
* `requestTimeout` set the timeout of requests make to API (in seconds), default is 10 seconds

```java
ManagementConfiguration configuration = ManagementConfiguration.builder()
                .managementKey("management-key")
                .build();

// if you want to see logs of the requests sent to Management API
// turn the logging in the configuration property
ManagementConfiguration configuration = ManagementConfiguration.builder()
                .managementKey("management-key")
                .requestLogging(Logger.Level.FULL)
                .build();
```

### License Management

Licenses can be managed through `LicenseService` object. You can make the `LicenseService` object by passing the configuration you made before.

```java
LicenseService licenseService = new LicenseService(configuration);
```

#### searchLicenses(SearchLicensesRequest request)

This method returns the paginated result that contains a list of licenses that satisfy your request. `SearchLicensesRequest` can be made with the builder.

```java
// example of a request with no filters requirements, by default it returns 20 licenses
SearchLicensesRequest request = SearchLicensesRequest.builder()
                .build();

SearchResult<BackOfficeLicense> response = licenseService.searchLicenses(request);

// example of a more complex request
SearchLicensesRequest request = SearchLicensesRequest.builder()
                .licenseKeyContains("GGGG")
                .licenseUserTrueEmailContains("@company.com")
                .limit(1)
                .customerCompanyNameContains("company")
                .build();

// example with a request with all possible queries except orderBy (example below)
// note that you can set as many fields as you want to
SearchLicensesRequest request = SearchLicensesRequest.builder()
                .licenseKey("GGGG-HHHH-FFFF")
  				// if you have multiple companies under your control, 
  				// you can specify which companies licenses you want to search 
  				// by putting in the company code
                .company(1)   
				// if you want to gather specific licenses by their ids
				// you can put a coma separated list of license ids
				.idIn("1593781774572379,1597395059215709,1597395059216729")
  				.customerCompanyNameContains("Enterprise")
                .customerEmail("@company.com")
                .customerId(12)
                .customerNameContains("John")
                .customerReferenceContains("reference")
                .licenseKeyContains("HHHHH")
                .licenseKeyStartsWith("GGGG")
				// if set to true, the result will contain only user-based licenses
				// if set to false, the result will contain only key-based licenses
				.licenseKeyIsNull(true)
                .licenseUserEmail("john@company.com")
                .licenseUserEmailContains("company")
                .licenseUserEmailStartsWith("john")
                .orderStoreId("123456789101112")
                .orderStoreIdContains("456")
                .orderStoreIdStartsWith("123")
				// case insensitive
				.noteContains("part of the note")
				// if true, the result will contain only floating licenses
				// if false, the result will contain only non-floating licenses
				.isAnyFloating(true)
  				// how many licenses you want to get at most
  				// default is 20
                .limit(3)
  				// offset from the beggining of the list of results
  				// default is 0
                .offset(1)
                .build();


// example of ordering results
// ascending order by the attribute created_at
try {
	SearchLicensesRequest request = SearchLicensesRequest.builder()
                .limit(15)
                .orderBy("created_at")
                .build();
} catch (LicenseSpringSortingException e) {
    log.error(e.getCause().getMessage());
}

// descending order by the attribute created_at
try {
	SearchLicensesRequest request = SearchLicensesRequest.builder()
                .limit(15)
                .orderBy("created_at")
                .sortDescending(true)
                .build();
} catch (LicenseSpringSortingException e) {
    log.error(e.getCause().getMessage());
}

// example of a wrong sort attribute, Builder will throw exception
try {
  	SearchLicensesRequest request = SearchLicensesRequest.builder()
                    .orderBy("wrong_filter")
                    .build();
} catch(LicenseSpringSortingException ex) {
  	log.error("Wrong filter used in searching licenses, see documentation on kwiki.");
}
```

Possible order options:

* `id`
* `status`
* `customer__email`
* `customer__company_name`
* `customer__reference`
* `created_at`
* `updated_at`
* `active`
* `enabled`
* `time_activated`
* `time_disabled`
* `max_activations`
* `times_activated`
* `valid_duration`
* `validity_period`
* `license_type`
* `enable_maintenance_period`
* `maintenance_duration`
* `maintenance_period`
* `is_trial`
* `max_consumptions`
* `total_consumptions`
* `subscription_id`
* `last_check`
* `prevent_vm`
* `allow_overages`
* `max_overages`
* `reset_consumption`
* `consumption_period`
* `trial_days`
* `is_floating`
* `is_floating_cloud`
* `floating_users`
* `note`
* `max_license_users`
* `order`
* `order_item`
* `license_key`
* `disabled_user`

If you set the `sortDescending` field to true, the order of the results will be descending, default order is ascending.

#### paginateThroughAllLicenses(SearchLicensesRequest request)

This method goes through all pages of the search result and puts all licenses in a list that is then returned. Should be used if there is a need for all licenses that satisfy the request so the user doesn't have to execute the search n times increasing the offset in the initial result.

```java
SearchLicensesRequest request = SearchLicensesRequest.builder()
                .licenseKeyContains("GGGG")
                .customerCompanyNameContains("company")
                .build();

List<BackOfficeLicense> licenses = licenseService.paginateThroughAllLicenses(request);
```

#### disableAllLicenses(Long\[] licenseIds)

Disables all the licenses whose ids are listed in the argument. This sets all the devices linked to the license to not active, sets the user who disabled the license, turns license status to inactive and sets the `time_disabled` field to now. Returns true if disabling was successful, false if disabling failed.

```java
Long[] licenseIds = {1234567890101112L, 12345678901011121L};

if (licenseService.disableAllLicenses(licenseIds)) {
    log.info("Disabling of licenses with " + ids + " ids was successful.");
} else {
    // try again, check if ids are correct.
}
```

#### getLicense(Long licenseId)

Retrieves detailed information from the server about the license with the provided id.

```java
Long licenseId = 1234567891234567L;

try {
    BackOfficeLicense license = licenseService.getLicense(licenseId);
} catch (LicenseSpringException ex) {
    // license with that id probably doesn't exist
}
```

#### updateLicense(Long licenseId, UpdateLicenseRequest request)

Updates the requested fields in the license with the provided id. Returns the updated license. `UpdateLicenseRequest` can be made with the builder.

```java
Long licenseId = 1234567891234567L;

UpdateLicenseRequest request = UpdateLicenseRequest.builder()
      .allowOverages(true)
      .build();

BackOfficeLicense updated = licenseService.updateLicense(licenseId, request);

// request with all possible fields
UpdateLicenseRequest request = UpdateLicenseRequest.builder()
                .allowOverages(true)
                .maxOverages(5)
                .maxConsumptions(100)
                .resetConsumption(true)
                .consumptionPeriod("daily")
                .floatingUsers(2)
                .isFloating(false)    // license can be either floating or floating cloud
                .isFloatingCloud(true)
                .isTrial(true)
                .trialDays(10)
                .enabled(true)
                .enableMaintenancePeriod(true)
                .maintenanceDuration("1year")
                .maxActivations(20)
                .preventVm(true)
                .validDuration("1year")
                .validityPeriod("2020-09-30")
                .build();
        
BackOfficeLicense updated = licensesService.updateLicense(id,request);
```

#### patchLicenseFeatures(Long licenseId, PatchLicenseFeaturesRequest request)

Patches the license (product) features available.

{% hint style="warning" %}
Thread carefully when using this method, posting an empty request will remove all features.
{% endhint %}

```java
// this will erase all features on the license
Long id = 1234567891011121L;  
  
PatchLicenseFeaturesRequest build = PatchLicenseFeaturesRequest.builder().  
        build();  
  
BackOfficeLicense backOfficeLicense = service.patchLicenseFeatures(id, build);

// putting all features from the product on the license
List<LicenseFeaturePatch> features = product.getProductFeatures()  
        .stream()  
        .map(feature -> LicenseFeaturePatch.builder()  
                .productFeature(feature.getCode())  
                .maxConsumption(feature.getMaxConsumption()))  
        .map(LicenseFeaturePatch.LicenseFeaturePatchBuilder::build)  
        .collect(Collectors.toList());  
  
BackOfficeLicense backOfficeLicenseWithFeatures = service.patchLicenseFeatures(id,  
 PatchLicenseFeaturesRequest.builder().productFeatures(features).build());
```

#### assignUser(Long licenseId, AssignUserToLicenseRequest licenseUser)

Assigns the provided user to the license with the provided id. `AssignedLicenseUser` can be made with the builder. Only required field is email. Returns a message that can either be:

* "License was successfully assigned and users new password is *password*". This will be returned when user assigned to the license is a first time user and password wasn't set as a field in `AssignUserToLicenseRequest` object, password will be generated from the server and passed in the string. The initial password can also be seen on the LicenseSpring platform. The other use case when this will be returned is when the user assigned to the license already owns at least one license and therefore already has a password, but if the field *password* in the `AssignUserToLicenseRequest` object was set, than users old password will be rewritten to the new password and sent as a confirmation in the message.
* "License was successfully assigned and user already has a password." This will be returned when the user assigned to the license already has at least one license and therefore already has a password and the *password* field in the `AssignUserToLicenseRequest` object wasn't set.

```java
Long licenseId = 1234567891234567L;

// example 1 - first time user with only required parameters
AssignUserToLicenseRequest request = AssignUserToLicenseRequest.builder()
      .email("someemail@gmail.com")
      .build();

// response will be "License was successfully assigned and users new password is *initial_password_that_server_set*."
// password will be random 8 characters including a-z, A-Z, 0-9, and special characters
String response = licenseService.assignUser(licenseId, request);

// example 2 - first time user with all parameters and set password
AssignUserToLicenseRequest request = AssignUserToLicenseRequest.builder()
      .email("someemail@gmail.com")
      .firstName("John")
      .lastName("Doe")
      .phoneNumber("000-111-000")
      .isManager(false)
      .password("password")
      .build();

// response will be "License was successfully assigned and users new password is password."
String response = licenseService.assignUser(licenseId, request);


// example 3 - assigning a user that already exists in the database but changing his password
AssignUserToLicenseRequest request = AssignUserToLicenseRequest.builder()
      .email("someemail@gmail.com")
      .password("password")
      .build();

// response will be License was successfully assigned and users new password is password."
String response = licenseService.assignUser(licenseId, request);

// example 4 - assigning a user that already exists in the databse and not setting the password field
AssignUserToLicenseRequest request = AssignUserToLicenseRequest.builder()
      .email("someemail@gmail.com")
      .build();

// response will be "License was successfully assigned and user already has a password."
String response = licenseService.assignUser(licenseId, request);
```

#### assignMultipleUsers(Long licenseId, AssignMultipleUsersRequest request)

Assigns multiple users to a single license if requesting manager has access permissions to it.

```java
Long licenseId = 1234567891011121L;  
AssignUserData data1 = AssignUserData.builder()  
        .email("user1@company.com")  
        .build();  
  
AssignUserData data2 = AssignUserData.builder()  
        .email("user2@company.com")  
        .build();  
  
AssignUserData[] userData = new AssignUserData[]{data1, data2};  
  
  
AssignMultipleUsersRequest request = AssignMultipleUsersRequest.builder()  
        .emails(userData)
        .sendEmail(false)  
        .build();  
  
List<MultipleAssignmentResponse> responses = service.assignMultipleUsers(licenseId, request);

System.out.println(responses.get(0).getEmail());  
System.out.println(responses.get(0).getNewUser());  
System.out.println(responses.get(0).getPassword());
```

#### unassignUser(Long licenseId, int licenseUserId)

Unassigns a user from a single license if requesting manager has access permissions to it.

```java
Long id = 1234567891011121L;  
int userId = 1;  
String email = "user@company.com";  
  
service.unassignUser(id,userId);
```

#### setUserPassword(int userId, String newPassword)

Sets the license users password to a new value.

```java
int userId = 11;  
String password = "new_pass";  
  
licenseService.setUserPassword(userId,password);
```

#### disableLicense(Long id)

Disables the license with the provided id. Will throw exception if license with that id doesn't exist. Sets the status of the license to *disabled*, `time_disabled` to now, all devices set to *inactive* and sets the user who disabled the license. Returns true if disabling was successful, false if otherwise.

```java
Long id = 1234567891234567L;

boolean isDeactivated = licenseService.disableLicense(id);
```

#### resetLicense(Long id)

Resets the license with the provided id. Sets the status to *inactive*, `times_activated` to 0, and all devices linked to the license to *inactive.*

```java
Long id = 1234567891234567L;

boolean isReset = licenseService.resetLicense(id);
```

#### enableLicense(Long id)

Enables the license with the provided id. Returns detailed license information that is now enabled.

```java
Long id = 1234567891234567L;

BackOfficeLicense license = licenseService.enableLicense(id);
```

#### resetTotalConsumptions(Long licenseId)

Resets the total consumptions on the license to zero.

```java
Long id = 1234567891011121L;  
  
BackOfficeLicense license = service.resetTotalConsumptions(id);
```

### License Custom Fields Management

To manage custom fields on licenses, call `LicenseCustomFieldsService` methods. Service is available through `LicenseService` class.

```java
// save the LicenseCustomFieldsService as a separate object
LicenseService licenseService = new LicenseService(configuration);  
LicenseCustomFieldsService cfService = licenseService.licenseCustomFieldsService()

// call the service through LicenseService object
... = licenseService.licenseCustomFieldsService().method();
```

#### search(SearchLicenseCustomFieldsRequest request)

Searches through all license custom fields and returns the search result which contains all license custom fields that satisfy the request queries.

```java
// basic request 
SearchLicenseCustomFieldsRequest request = SearchLicenseCustomFieldsRequest.builder()  
        .build();  
  
SearchResult<BackOfficeLicenseCustomField> response = cfService.search(request);

// search by license id
Long license = 1234567891011121L;  

SearchLicenseCustomFieldsRequest request = SearchLicenseCustomFieldsRequest.builder()  
        .license(license)  
        .build();  
  
SearchResult<BackOfficeLicenseCustomField> response = cfService.search(request);

// search with all possible queries
Long license = 1234567891011121L;  

SearchLicenseCustomFieldsRequest request = SearchLicenseCustomFieldsRequest.builder()  
        .license(license)
		.limit(5)
		.offset(2)
        .build();  
  
SearchResult<BackOfficeLicenseCustomField> response = cfService.search(request);
```

#### paginate(SearchLicenseCustomFieldsRequest request)

Goes through all pages of the search license custom fields response and returns a list with all possible license custom fields that satisfy the request. Makes multiple requests to the server until all results have been found.

```java
SearchLicenseCustomFieldsRequest request = SearchLicenseCustomFieldsRequest.builder()  
        .build();  
  
List<BackOfficeLicenseCustomField> allFields = licenseService.licenseCustomFieldsService().paginate(request);
```

#### get(Integer id)

Retrieves license custom field data.

```java
int id = 1;  
  
BackOfficeLicenseCustomField field = cfService.get(id);
```

#### create(CreateLicenseCustomFieldRequest request)

Creates a new license custom field.

```java
Long license = 1234567891011121L;  
String value = "value";  
int product = 11;  
  
CreateLicenseCustomFieldRequest request = CreateLicenseCustomFieldRequest.builder()  
        .license(license)  
        .value(value)  
        .productCustomField(product)  
        .build();  
  
BackOfficeLicenseCustomField field = cfService.create(request);
```

#### update(Integer id, UpdateCustomLicenseFieldRequest request)

Updates the license custom field.

```java
int id = 6;  
String value = "value";  
  
UpdateCustomLicenseFieldRequest request = UpdateCustomLicenseFieldRequest.builder()  
        .value(value)  
        .build();  
  
cfService.update(id, request);
```

#### delete(Integer id)

Deletes the license custom field.

```java
int id = 12;

cfService.delete(id);
```

### Device Management

Devices can be managed through `LicenseService` object. You can make the `LicenseService` object by passing the configuration you made before.

```java
LicenseService service = new LicenseService(configuration);
```

#### searchDevices(SearchDevicesRequest request)

This method returns the paginated result that contains a list of devices that satisfy your request. `SearchDevicesRequest` can be made using builder.

```java
// basic request, gets a list of 20 devices.
SearchDevicesRequest request = SearchDevicesRequest.builder()
                .build();

// gets the first 10 devices that are blacklisted
SearchDevicesRequest request = SearchDevicesRequest.builder()
                .blacklisted(true)
                .limit(10)
                .build();

// lists at most 20 devices that are linked with this license
SearchDevicesRequest request = SearchDevicesRequest.builder()
                .license(1234567890101112L)
                .build();

// search by hostname
SearchDevicesRequest request = SearchDevicesRequest.builder()
				.hostname("hostname")
                .build();
				
// search by hardware id
SearchDevicesRequest request = SearchDevicesRequest.builder()
				.hardwareId("G1G1-G1G1-G1G1-G1G1-G1G1-G1G1-G1G1-G1G1-G1G1-G1G1-G1G1-G1G1-G1G1-G1G1-G1G1-G1G1")
                .build();

// gets at most 100 devices with an offset equal to 10 and orders them by the license id attribute in ascending order
try {
	SearchDevicesRequest request = SearchDevicesRequest.builder()
                .limit(100)
                .orderBy("license")
  				.offset(10)
                .build();
} catch (LicenseSpringSortingException e) {
    log.error(e.getCause().getMessage());
}

// lists at most 100 devices that are sorted by the blacklisted in descending order 
try {
	SearchDevicesRequest request = SearchDevicesRequest.builder()
                .limit(100)
                .orderBy("blacklisted")
                .sortDescending(true)
                .build();
} catch (LicenseSpringSortingException e) {
    log.error(e.getCause().getMessage());
}    
List<Device> results = licensesService.searchDevices(request);
```

Possible filters:

* `license`
* `blacklisted`
* `hostname`
* `hardware_id`

The result list can be sorted in descending order if the flag `sortDescending` is set to true. This, of course, only works if `orderBy` is set. Default order is ascending.

#### paginateThroughAllDevices(SearchDevicesRequest request)

This method goes through all pages of the search result and puts all devices in a list that is then returned. Should be used if there is a need for all devices that satisfy the request so the user doesn't have to execute the search n times increasing the offset in the initial result.

```java
SearchDevicesRequest request = SearchDevicesRequest.builder()
                .blacklisted(true)
                .build();

List<Device> devices = licenseService.paginateThroughAllDevices(request);
```

#### getDevice(Long id)

Gets the device with the provided id.

```java
Long id = 1000100010010010L;
Device device = licenseService.getDevice(id);

log.info(device.getOs());
log.info(device.getMacAddress());
log.info(device.getAppVer());
log.info(device.getExternalIp());
log.info(device.getFloatingLastSeen());
log.info(device.getHardwareId());
log.info(device.getHostname());
log.info(device.getIp());
log.info(device.getLicense());
log.info(device.getSdkBuildVersion());
log.info(device.getType());
log.info(device.getVmInfo());
log.info(device.getDeviceVariables().toString());
log.info(String.valueOf(device.getCreatedAt().getYear()));
log.info(device.getId().toString());
log.info(device.getLastCheck().toString());
log.info(device.getTimeActivated().toString());
log.info(device.getTimeDeactivated().toString());
log.info(device.getUpdatedAt().toString());
log.info(device.getValidityPeriod().toString());
log.info(device.isBlacklisted() ? "blacklisted" : "not blacklisted");
log.info(device.isDeviceActive() ? "active" : "not active");
log.info(device.isFloatingInUse() ? "in use" : "not in use");
log.info(device.isVm() ? "vm" : "not vm");
```

#### resetDevice(Long id)

Resets the device.

```java
Long id = 1234567891011121L;  
  
service.resetDevice(id);
```

#### blacklistDevice(Long id)

Blacklists the device.

```java
Long id = 1234567891011121L;  
  
service.blacklistDevice(id);
```

### Device Variables Management

To manage device variables, call `DeviceVariablesService` methods. Service is available through `LicenseService` class.

```java
// save the DeviceVariablesService as a separate object
LicenseService licenseService = new LicenseService(configuration);  
DeviceVariablesService dvService = licenseService.deviceVariablesService()

// call the service through LicenseService object
... = licenseService.deviceVariablesService().someMethod();
```

#### search(SearchDeviceVariablesRequest request)

Searches through all device variables and returns the search result which contains all device variables that satisfy the request queries.

```java
// basic request 
SearchDeviceVariablesRequest request = SearchDeviceVariablesRequest.builder()  
        .build();  
  
SearchResult<BackOfficeDeviceVariable> response = dvService.search(request);

// search by id
Long id = 1234567891011121L;  

SearchDeviceVariablesRequest request = SearchDeviceVariablesRequest.builder()  
        .device(id)  
        .build();  
  
SearchResult<BackOfficeDeviceVariable> response = dvService.search(request);

// search with all possible queries
Long id = 1234567891011121L;  

SearchDeviceVariablesRequest request = SearchDeviceVariablesRequest.builder() 
        .device(id)
		.limit(5)
		.offset(2)
        .build();  
  
SearchResult<BackOfficeDeviceVariable> response = dvService.search(request);
```

#### paginate(SearchDeviceVariablesRequest request)

Goes through all pages of the search device variables response and returns a list with all possible device variables that satisfy the request. Makes multiple requests to the server until all results have been found.

```java
SearchDeviceVariablesRequest request = SearchDeviceVariablesRequest.builder()  
        .build();  
  
List<BackOfficeDeviceVariable> allFields = licenseService.deviceVariablesService().paginate(request);
```

#### get(Integer id)

Retrieves device variable data.

```java
Long id = 111L;  
  
BackOfficeDeviceVariable field = dvService.get(id);
```

#### create(CreateDeviceVariableRequest request)

Creates a new device variable.

```java
Long device = 1234567891011121L;
  
String variable = "var";  
String value = "val";

CreateDeviceVariableRequest request = CreateDeviceVariableRequest.builder()  
        .device(device)  
        .value(value)  
        .variable(variable)
        .build();  
  
BackOfficeDeviceVariable backOfficeDeviceVariable = dvService.create(request);
```

#### update(Integer id, UpdateDeviceVariableRequest request)

Updates the device variable

```java
String variable = "var";  
String value = "val";  
Long id = 111L;  
  
UpdateDeviceVariableRequest request = UpdateDeviceVariableRequest.builder()  
        .variable(variable)  
        .value(updatedValue)  
        .build();  
 
BackOfficeDeviceVariable updatedVariable = dvService.update(id, request);
```

#### delete(Integer id)

Deletes the device variable.

```java
Long id = 111L;

dvService.delete(id);
```

### Order Management

All requests for Orders API should be done via the `OrderService` object. You can make the `OrderService` object by passing the configuration you made before.

```java
OrderService orderService = new OrderService(configuration);
```

#### searchOrders(SearchOrdersRequest request)

This method returns the paginated result that contains a list of orders that satisfy your request. `SearchOrdersRequest` can be made with builder.

```java
// basic request without special queries, retrieves a list of 20 orders
SearchOrdersRequest request = SearchOrdersRequest.builder()
                .build();

// retrieves a list of at most 20 orders under the company with the id 10
SearchOrdersRequest request = SearchOrdersRequest.builder()
                .company(10)
                .build();

// request with all possible fields except the orderBy
SearchOrdersRequest request = SearchOrdersRequest.builder()
  				// if you have multiple companies under your control, 
                // you can specify which companies licenses you want to search 
                // by putting in the company code               
  				.company(10)
                .customerCompanyName("Company Example Co.")
                .customerCompanyNameContains("Example")
                .customerEmail("john-company@gmail.com")
                .customerEmailContains("company")
                .customerEmailStartsWith("john")
                .customerId(11)
                .customerNameContains("Doe")
                .customerReferenceContains("123")
                .storeId("1234567890101112")
                .storeIdContains("456")
                .storeIdStartsWith("123")
  				// how many orders you want to be retrieved, deafult is 20
                .limit(10)
  				// offset from the beggining of the result
                .offset(1)
                .build();

// sorts the orders in ascending order by the field company
try {
	SearchOrdersRequest request = SearchOrdersRequest.builder()
                .orderBy("company")
                .build();
} catch (LicenseSpringSortingException e) {
    log.error(e.getCause().getMessage());
}

// sorts the orders in descending order by the field customerId
try {
	SearchOrdersRequest request = SearchOrdersRequest.builder()
                .orderBy("customerId")
                .sortDescending(true)
                .build();
} catch (LicenseSpringSortingException e) {
    log.error(e.getCause().getMessage());
}

SearchResult<Order> response = ordersService.searchOrders(request);
```

Possible filters:

* `store_id`
* `store_id__startswith`
* `store_id__icontains`
* `customer__email`
* `customer__email__startswith`
* `customer__email__icontains`
* `company`
* `customer_id`
* `customer_email`
* `customer_company_name`
* `customer_company_name__icontains`
* `customer_reference__icontains`
* `customer_name__icontains`

Default order is ascending, to get descending order set the flag `sortDescending` to true.

#### getOrder(Long id)

Returns the order with the provided id.

```java
Long id = 1234567891234567L;

Order order = orderService.getOrder(id);

// there are a lot of fields that can be accessed with a getter
// this is just an example of a few of them
// we advise you to explore all the fields you can get from the order
log.info(order.getCustomerCompany());
log.info(order.getType().name());
log.info(order.getCustomer().getAddress());
log.info(order.getOrderItems().get(0).getProductId());
```

#### paginateThroughAllOrders(SearchOrdersRequest request)

This method goes through all pages of the search result and puts all orders in a list that is then returned. Should be used if there is a need for all orders that satisfy the request so the user doesn't have to execute the search n times increasing the offset in the initial result.

```java
SearchOrdersRequest request = SearchOrdersRequest.builder()
                .company(10)
                .build();

List<Order> orders = licenseService.paginateThroughAllOrders(request);
```

#### createOrder(WebhookOrder order)

Creates an `Order` and returns the generated orderId and a list of emails and their respective passwords if the user is new and was listed in the `WebHookOrder`.

```java
// example 1. - simple order with user based license
Customer customer = Customer.builder()
      .email("someemail@gmail.com")
      .build();

UserBasedLicense user = UserBasedLicense.builder()
      .email("anotheremail@gmail.com")
      .build();

OrderLicense license = OrderLicense.builder()
      .licenseType(LicenseType.CONSUMPTION)
      .user(user)
      .maxConsumptions(555)
      .consumptionPeriod("1m")
      .maxActivations(5)
      .build();

OrderItem item = OrderItem.builder()
      .productCode("pc")
      .license(license)
      .build();

WebhookOrder order = WebhookOrder.builder()
      .customer(customer)
      .id("my-application-order-reference-" + Instant.now().toEpochMilli())
      .item(item)
      .build();

CreateOrderResponse response = ordersService.createOrder(order);

log.info(response.getOrderId());
for (UserData data : response.getNewPasswords()) {
  		log.info(data.getEmail() + " -> " + data.getNewPassword());
}

// example 2. - simple key based order
Customer customer = Customer.builder()
        .email("someemail@gmail.com")
        .build();

GenerateLicenseRequest params = GenerateLicenseRequest.builder()
        .product("pc")
        .quantity(5)
        .build();

String[] keys = ordersService.generateLicenseKeys(params);

OrderLicense license = OrderLicense.builder()
        .licenseType(LicenseType.CONSUMPTION)
        .maxConsumptions(666)
        .resetConsumption(true)
        .preventVm(true)
  		// identity is either a LicenseIdentity object or its subclass ActivationLicense object
        .key(identity.getLicenseKey())
        .build();

OrderItem item = OrderItem.builderWith(this::consumptionFactory)
        .productCode("pc")
        .generateLicenses(keys)
        .build();

WebhookOrder order = WebhookOrder.builder()
        .customer(customer)
        .id("my-application-order-reference-" + Instant.now().toEpochMilli())
        .item(item)
        .build();

CreateOrderResponse response = ordersService.createOrder(order);

log.info(response.getOrderId());

private OrderLicense consumptionFactory(LicenseIdentity identity){

        return OrderLicense.builder()
                .licenseType(LicenseType.CONSUMPTION)
                .maxConsumptions(666)
                .allowOverages(true)
                .maxOverages(1666)
                .resetConsumption(true)
                .preventVm(true)
                .key(identity.getLicenseKey())
                .build();
}

// example 3. - this contains all objects needed to create an order 
// but with more verbose fields than just those that are required

Customer customer = Customer.builder()
      .email("someemail@gmail.com")
      .firstName("John")
      .lastName("Doe")
      .companyName("Company Example Co.")
      .reference("reference123")
      .phone("09-123-456-789")
      .build();
```

#### generateLicenseKeys(GenerateLicenseRequest request)

Returns a String array filled with generated license keys that can be used to place orders. `GenerateLicenseRequest` can be made with builder.

```java
// product and quantity are both required and only fields
GenerateLicenseRequest request = GenerateLicenseRequest.builder()
      .product("pc")
      .quantity(5)
      .build();

String[] keys = orderService.generateLicenseKeys(request);
System.out.println(keys);
```

#### addManagerToOrder(Long orderId, AddManagerToOrderRequest request)

Adds a manager to an order.

```java
AddManagerToOrderRequest request = AddManagerToOrderRequest  
        .builder()  
        .email("manager@company.com")  
        .password("password")  
        .build();  
  
Long orderId = 1234567891011121L;  
  
Manager manager = orderService.addManagerToOrder(orderId, request);
```

#### exportToCsv(LocalDate from, LocalDate to, String destination)

Makes a request to the server to send the csv file with all orders made in the requested range. Destination is a path where the file should be saved. If the argument is set to null, the SDK will try to save it to the desktop or home if desktop is unavailable. This method returns the filepath where the file was saved. From and to are `LocalDate` types, can be made like this: `LocalDate from = LocalDate.of(GGGG,MM,DD)`

Example of how the csv will be named: `2020-07-01to2020-09-01.csv`

```java
// saves the csv to desktop or home 
String filePath = orderService.exportToCsv(LocalDate.of(2020, 7, 1), LocalDate.of(2020, 9, 1), null);

// saves the csv to custom path
String filePath = orderService.exportToCsv(LocalDate.of(2020, 7, 1), LocalDate.of(2020, 9, 1), "home/user/Downloads/licensespring");
```

#### exportToCsv(Range range, String destination)

Makes a request to the server to send the csv file with all orders made in the requested range. Range is an enum with values: `last30`, `last60`, `last180`, `last365`, where numbers specify days (last30 is all orders from the last 30 days). Destination is a path where the file should be saved. If the argument is set to null, the SDK will try to save it to the desktop or home if desktop is unavailable. This method returns the filepath where the file was saved. From and to are `LocalDate` types, can be made like this: `LocalDate from = LocalDate.of(GGGG,MM,DD)`

Example of how the csv will be named: `2020-07-01to2020-09-01.csv`

```java
// saves the csv to desktop or home 
String filePath = orderService.exportToCsv(Range.LAST60, null);

// saves the csv to custom path
String filePath = orderService.exportToCsv(Range.LAST60, "home/user/Downloads/licensespring");
```

### Product Management

Products can be managed through `OrderService` object. You can make the `OrderService` object by passing the configuration you made before.

```java
OrderService orderService = new OrderService(configuration);
```

#### searchProducts(SearchProductsRequest request)

This method returns the paginated result that contains a list of products that satisfy your request. `SearchProductsRequest` can be made with builder.

```java
// basic request, no fields required, gets at most 20 products because limit is 20 by default
SearchProductsRequest request = SearchProductsRequest.builder()
                .build();

// gets at most 40 products that are archived
SearchProductsRequest request = SearchProductsRequest.builder()
                .isArchived(true)
  				.limit(40)
                .build();

// gets products, sorts them in ascending order by the isArchived field, and then gets 10 products with an offset of 10
try {
	SearchProductsRequest request = SearchProductsRequest.builder()
                .limit(10)
                .offset(10)
                .orderBy("is_archived")
                .build();
} catch (LicenseSpringSortingException e) {
    log.error(e.getCause().getMessage());
}

// gets products and sorts them by the isArchived field in descending order and sends back first 20 products
try {
	SearchProductsRequest request = SearchProductsRequest.builder()
                .orderBy("is_archived")
                .sortDescending(true)
                .build();
} catch (LicenseSpringSortingException e) {
    log.error(e.getCause().getMessage());
}        

SearchResult<BackOfficeProduct> response = ordersService.searchProducts(request);

// there are a lot of read-only fields at your disposal, these are just some of them
// we encourage you to explore them and see which ones interest you 
for(BackOfficeProduct product : response.getResults()) {
            log.info(product.getAuthorizationMethod());
            log.info(product.getConsumptionPeriod());
            log.info(product.getMaintenanceDuration());
            log.info(product.getShortCode());
            log.info(product.getSubscriptionDuration());
            log.info(product.getValidDuration());
            log.info(product.getCustomFields()[0].getName());
}
```

#### getProduct(Long id)

Gets details about the product with specified id.

```java
Long id = 1234567891234567L;

BackOfficeProduct product = orderService.getProduct(id);

// there are a lot of read-only fields at your disposal, these are just some of them
// we encourage you to explore them and see which ones interest you 
log.info(product.getAuthorizationMethod());
log.info(product.getConsumptionPeriod());
log.info(product.getMaintenanceDuration());
log.info(product.getShortCode());
log.info(product.getSubscriptionDuration());
log.info(product.getValidDuration());
log.info(product.getCustomFields()[0].getName());
```

#### paginateThroughAllProducts(SearchProductsRequest request)

This method goes through all pages of the search result and puts all products in a list that is then returned. Should be used if there is a need for all products that satisfy the request so the user doesn't have to execute the search n times increasing the offset in the initial result.

```java
SearchProductsRequest request = SearchProductsRequest.builder()
                .isArchived(true)
                .build();

List<BackOfficeProduct> products = licenseService.paginateThroughAllProducts(request);
```

### Installation File Management

Use `OrderService` object to manage installation files.

```java
OrderService orderService = new OrderService(configuration);
```

#### searchInstallationFiles(SearchInstallationFilesRequest request)

Searches the `InstallationFiles` by applying the filtering and ordering conditions in the `SearchInstallationFilesRequest` class.

```java
// example of a request with all possible queries
SearchInstallationFilesRequest request = SearchInstallationFilesRequest.builder()  
        .limit(3)  
        .offset(1)  
        .product(1234567891011121L)  
        .orderBy("product")
        .sortDescending(true)  
        .build();  
  
List<BackOfficeInstallationFile> files = orderService.searchInstallationFiles(request).getResults();
```

#### paginateThroughAllInstallationFiles(SearchInstallationFilesRequest request)

Goes through all pages of the response and returns a list with all possible installation files that satisfy the request. Makes multiple requests to the server until all results have been found.

```java
SearchInstallationFilesRequest searchRequest = SearchInstallationFilesRequest.builder()  
        .build();   
  
List<BackOfficeInstallationFile> products = orderService.paginateThroughAllInstallationFiles(searchRequest);
```

#### getInstallationFile(int id)

Gets the installation file with the provided id.

```java
int id = 1;  
  
BackOfficeInstallationFile file = orderService.getInstallationFile(id);
```

#### createInstallationFile(CreateInstallationFileRequest request)

Creates and returns a new `InstallationFile` with the details provided in the request.

```java
Long id = 1234567891011121L;  
  
CreateInstallationFileRequest request = CreateInstallationFileRequest.builder()
	// use Environment enum for options 
        .environment(Environment.MAC)
        .fullLink("https://company.com/product")  
        .hashMd5("hash")  
        .product(id) 
		// needs to be of YYYY-MM-DD format
		// will throw exception otherwise
        .releaseDate("2021-03-15")
        .version("2.8")
        .build();  
  
BackOfficeInstallationFile file = orderService.createInstallationFile(request);
```

### Product Custom Field Management

Use `OrderService.productCustomFieldsService()` method to get a service for managing products custom fields.

```java
// save product custom fields service as an object
ProductCustomFieldsService pcfService = orderService.productCustomFieldsService()

// call it directly without saving the object
Object response = orderService.productCustomFieldsService().method();
```

#### search(SearchProductCustomFieldsRequest request)

Searches through all product custom fields and returns the search result which contains all product custom fields that satisfy the request queries.

```java
SearchProductCustomFieldsRequest request = SearchProductCustomFieldsRequest.builder()  
        .limit(10)  
        .product(1234567891011121L)  
        .build();  
  
SearchResult<BackOfficeProductCustomField> result = orderService.productCustomFieldsService().search(request);
```

#### get(Integer id)

Retrieves product custom field data.

```java
int id = 11;  
  
BackOfficeProductCustomField backOfficeProductCustomField = pcfService.get(id);
```

#### create(CreateProductCustomFieldRequest request)

Creates a new product custom field.

```java
long product = 1234567891011121L;  
String name = "name";  
String defaultValue = "valueByDefualt";  
CreateProductCustomFieldRequest request = CreateProductCustomFieldRequest.builder()  
        .product(product)  
        .name(name)  
        .defaultValue(defaultValue)  
        .build();  
  
BackOfficeProductCustomField field = pcfService.create(request);
```

#### update(Integer id, UpdateProductCustomFieldRequest request)

Updates the product custom field.

```java
String updatedName = "updated name";  
String updatedValue = "updated value";  
int id = 18;  
  
UpdateProductCustomFieldRequest request = UpdateProductCustomFieldRequest.builder()  
        .name(updatedName)  
        .defaultValue(updatedValue)  
        .build();
  
BackOfficeProductCustomField updatedField = pcfService.update(id, request);
```

#### delete(Integer id)

Deletes the product custom field.

```java
int id = 18;  

pcfService.delete(id);
```

#### paginate(SearchProductCustomFieldsRequest request)

Goes through all pages of the search product custom fields response and returns a list with all possible product custom fields that satisfy the request. Makes multiple requests to the server until all results have been found.

```java
SearchProductCustomFieldsRequest request = SearchProductCustomFieldsRequest.builder()  
        .limit(10)  
        .product(1234567891011121L)
        .build();  
  
List<BackOfficeProductCustomField> result = orderService.productCustomFieldsService().paginate(request);
```


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://docs.licensespring.com/sdks/java-sdk/java-modules/management-sdk.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
