diff --git a/pom.xml b/pom.xml index aa639590..04f34242 100644 --- a/pom.xml +++ b/pom.xml @@ -79,6 +79,11 @@ 3.23.1 test + + com.github.hervian + safety-mirror + 4.0.1 + diff --git a/src/main/java/com/kingsrook/qqq/backend/core/model/data/QRecord.java b/src/main/java/com/kingsrook/qqq/backend/core/model/data/QRecord.java index aa503b4f..6151c672 100644 --- a/src/main/java/com/kingsrook/qqq/backend/core/model/data/QRecord.java +++ b/src/main/java/com/kingsrook/qqq/backend/core/model/data/QRecord.java @@ -27,6 +27,7 @@ import java.math.BigDecimal; import java.time.LocalDate; import java.util.LinkedHashMap; import java.util.Map; +import com.kingsrook.qqq.backend.core.exceptions.QException; import com.kingsrook.qqq.backend.core.utils.ValueUtils; @@ -255,7 +256,6 @@ public class QRecord implements Serializable - /******************************************************************************* ** *******************************************************************************/ @@ -343,4 +343,13 @@ public class QRecord implements Serializable return (String) this.backendDetails.get(key); } + + + /******************************************************************************* + ** Convert this record to an QRecordEntity + *******************************************************************************/ + public T toEntity(Class c) throws QException + { + return (QRecordEntity.fromQRecord(c, this)); + } } diff --git a/src/main/java/com/kingsrook/qqq/backend/core/model/data/QRecordEntity.java b/src/main/java/com/kingsrook/qqq/backend/core/model/data/QRecordEntity.java new file mode 100644 index 00000000..df5c8ecc --- /dev/null +++ b/src/main/java/com/kingsrook/qqq/backend/core/model/data/QRecordEntity.java @@ -0,0 +1,213 @@ +/* + * QQQ - Low-code Application Framework for Engineers. + * Copyright (C) 2021-2022. Kingsrook, LLC + * 651 N Broad St Ste 205 # 6917 | Middletown DE 19709 | United States + * contact@kingsrook.com + * https://github.com/Kingsrook/ + * + * 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 . + */ + +package com.kingsrook.qqq.backend.core.model.data; + + +import java.io.Serializable; +import java.lang.reflect.Method; +import java.math.BigDecimal; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.Locale; +import java.util.Optional; +import com.kingsrook.qqq.backend.core.exceptions.QException; +import com.kingsrook.qqq.backend.core.utils.ListingHash; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; + + +/******************************************************************************* + ** Base class for entity beans that are interoperable with QRecords. + *******************************************************************************/ +public abstract class QRecordEntity +{ + private static final Logger LOG = LogManager.getLogger(QRecordEntity.class); + + private static final ListingHash, QRecordEntityField> fieldMapping = new ListingHash<>(); + + + + /******************************************************************************* + ** Build an entity of this QRecord type from a QRecord + ** + *******************************************************************************/ + public static T fromQRecord(Class c, QRecord qRecord) throws QException + { + try + { + T entity = c.getConstructor().newInstance(); + + List fieldList = getFieldList(c); + for(QRecordEntityField qRecordEntityField : fieldList) + { + Serializable value = qRecord.getValue(qRecordEntityField.getFieldName()); + Object typedValue = qRecordEntityField.convertValueType(value); + qRecordEntityField.getSetter().invoke(entity, typedValue); + } + + return (entity); + } + catch(Exception e) + { + throw (new QException("Error building entity from qRecord.", e)); + } + } + + + + /******************************************************************************* + ** Convert this entity to a QRecord. + ** + *******************************************************************************/ + public QRecord toQRecord() throws QException + { + try + { + QRecord qRecord = new QRecord(); + + List fieldList = getFieldList(this.getClass()); + for(QRecordEntityField qRecordEntityField : fieldList) + { + qRecord.setValue(qRecordEntityField.getFieldName(), (Serializable) qRecordEntityField.getGetter().invoke(this)); + } + + return (qRecord); + } + catch(Exception e) + { + throw (new QException("Error building qRecord from entity.", e)); + } + } + + + + /******************************************************************************* + ** + *******************************************************************************/ + private static List getFieldList(Class c) + { + if(!fieldMapping.containsKey(c)) + { + List fieldList = new ArrayList<>(); + for(Method possibleGetter : c.getMethods()) + { + if(isGetter(possibleGetter)) + { + Optional setter = getSetterForGetter(c, possibleGetter); + if(setter.isPresent()) + { + String name = getFieldNameFromGetter(possibleGetter); + fieldList.add(new QRecordEntityField(name, possibleGetter, setter.get(), possibleGetter.getReturnType())); + } + else + { + LOG.info("Getter method [" + possibleGetter.getName() + "] does not have a corresponding setter."); + } + } + } + fieldMapping.put(c, fieldList); + } + return (fieldMapping.get(c)); + } + + + + /******************************************************************************* + ** + *******************************************************************************/ + public static String getFieldNameFromGetter(Method getter) + { + String nameWithoutGet = getter.getName().replaceFirst("^get", ""); + if(nameWithoutGet.length() == 1) + { + return (nameWithoutGet.toLowerCase(Locale.ROOT)); + } + return (nameWithoutGet.substring(0, 1).toLowerCase(Locale.ROOT) + nameWithoutGet.substring(1)); + } + + + + /******************************************************************************* + ** + *******************************************************************************/ + private static boolean isGetter(Method method) + { + if(method.getParameterTypes().length == 0 && method.getName().matches("^get[A-Z].*")) + { + if(isSupportedFieldType(method.getReturnType())) + { + return (true); + } + else + { + if(!method.getName().equals("getClass")) + { + LOG.info("Method [" + method.getName() + "] looks like a getter, but its return type, [" + method.getReturnType() + "], isn't supported."); + } + } + } + return (false); + } + + + + /******************************************************************************* + ** + *******************************************************************************/ + private static Optional getSetterForGetter(Class c, Method getter) + { + String setterName = getter.getName().replaceFirst("^get", "set"); + for(Method method : c.getMethods()) + { + if(method.getName().equals(setterName)) + { + if(method.getParameterTypes().length == 1 && method.getParameterTypes()[0].equals(getter.getReturnType())) + { + return (Optional.of(method)); + } + else + { + LOG.info("Method [" + method.getName() + "] looks like a setter for [" + getter.getName() + "], but its parameters, [" + Arrays.toString(method.getParameterTypes()) + "], don't match the getter's return type [" + getter.getReturnType() + "]"); + } + } + } + return (Optional.empty()); + } + + + + /******************************************************************************* + ** + *******************************************************************************/ + private static boolean isSupportedFieldType(Class returnType) + { + // todo - more types!! + return (returnType.equals(String.class) + || returnType.equals(Integer.class) + || returnType.equals(int.class) + || returnType.equals(Boolean.class) + || returnType.equals(boolean.class) + || returnType.equals(BigDecimal.class)); + } + +} diff --git a/src/main/java/com/kingsrook/qqq/backend/core/model/data/QRecordEntityField.java b/src/main/java/com/kingsrook/qqq/backend/core/model/data/QRecordEntityField.java new file mode 100644 index 00000000..b03dbea6 --- /dev/null +++ b/src/main/java/com/kingsrook/qqq/backend/core/model/data/QRecordEntityField.java @@ -0,0 +1,138 @@ +/* + * QQQ - Low-code Application Framework for Engineers. + * Copyright (C) 2021-2022. Kingsrook, LLC + * 651 N Broad St Ste 205 # 6917 | Middletown DE 19709 | United States + * contact@kingsrook.com + * https://github.com/Kingsrook/ + * + * 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 . + */ + +package com.kingsrook.qqq.backend.core.model.data; + + +import java.io.Serializable; +import java.lang.reflect.Method; +import java.math.BigDecimal; +import com.kingsrook.qqq.backend.core.exceptions.QValueException; +import com.kingsrook.qqq.backend.core.utils.ValueUtils; + + +/******************************************************************************* + ** Reflective information about a field in a QRecordEntity + *******************************************************************************/ +public class QRecordEntityField +{ + private final String fieldName; + private final Method getter; + private final Method setter; + private final Class type; + + + + /******************************************************************************* + ** Constructor. + *******************************************************************************/ + public QRecordEntityField(String fieldName, Method getter, Method setter, Class type) + { + this.fieldName = fieldName; + this.getter = getter; + this.setter = setter; + this.type = type; + } + + + + /******************************************************************************* + ** Getter for fieldName + ** + *******************************************************************************/ + public String getFieldName() + { + return fieldName; + } + + + + /******************************************************************************* + ** Getter for getter + ** + *******************************************************************************/ + public Method getGetter() + { + return getter; + } + + + + /******************************************************************************* + ** Getter for setter + ** + *******************************************************************************/ + public Method getSetter() + { + return setter; + } + + + + /******************************************************************************* + ** Getter for type + ** + *******************************************************************************/ + public Class getType() + { + return type; + } + + + + /******************************************************************************* + ** + *******************************************************************************/ + public Object convertValueType(Serializable value) + { + if(value == null) + { + return (null); + } + + if(value.getClass().equals(type)) + { + return (value); + } + + if(type.equals(String.class)) + { + return (ValueUtils.getValueAsString(value)); + } + + if(type.equals(Integer.class) || type.equals(int.class)) + { + return (ValueUtils.getValueAsInteger(value)); + } + + if(type.equals(Boolean.class) || type.equals(boolean.class)) + { + return (ValueUtils.getValueAsBoolean(value)); + } + + if(type.equals(BigDecimal.class)) + { + return (ValueUtils.getValueAsBigDecimal(value)); + } + + throw (new QValueException("Unhandled value type [" + type + "] for field [" + fieldName + "]")); + } +} diff --git a/src/main/java/com/kingsrook/qqq/backend/core/model/metadata/QFieldMetaData.java b/src/main/java/com/kingsrook/qqq/backend/core/model/metadata/QFieldMetaData.java index 36a757c3..dc53cf76 100644 --- a/src/main/java/com/kingsrook/qqq/backend/core/model/metadata/QFieldMetaData.java +++ b/src/main/java/com/kingsrook/qqq/backend/core/model/metadata/QFieldMetaData.java @@ -23,6 +23,10 @@ package com.kingsrook.qqq.backend.core.model.metadata; import java.io.Serializable; +import java.lang.reflect.Method; +import com.github.hervian.reflection.Fun; +import com.kingsrook.qqq.backend.core.exceptions.QException; +import com.kingsrook.qqq.backend.core.model.data.QRecordEntity; /******************************************************************************* @@ -31,14 +35,14 @@ import java.io.Serializable; *******************************************************************************/ public class QFieldMetaData { - private String name; - private String label; - private String backendName; + private String name; + private String label; + private String backendName; private QFieldType type; - private boolean isRequired = false; + private boolean isRequired = false; private Serializable defaultValue; - private String possibleValueSourceName; + private String possibleValueSourceName; @@ -62,6 +66,30 @@ public class QFieldMetaData + /******************************************************************************* + ** Initialize a fieldMetaData from a reference to a getter on an entity. + ** e.g., new QFieldMetaData(Order::getOrderNo). + *******************************************************************************/ + public QFieldMetaData(Fun.With1ParamAndVoid getterRef) throws QException + { + try + { + Method getter = Fun.toMethod(getterRef); + this.name = QRecordEntity.getFieldNameFromGetter(getter); + this.type = QFieldType.fromClass(getter.getReturnType()); + } + catch(QException qe) + { + throw (qe); + } + catch(Exception e) + { + throw (new QException("Error constructing field from getterRef: " + getterRef, e)); + } + } + + + /******************************************************************************* ** *******************************************************************************/ diff --git a/src/main/java/com/kingsrook/qqq/backend/core/model/metadata/QFieldType.java b/src/main/java/com/kingsrook/qqq/backend/core/model/metadata/QFieldType.java index 4fca53d4..f52ef8d8 100644 --- a/src/main/java/com/kingsrook/qqq/backend/core/model/metadata/QFieldType.java +++ b/src/main/java/com/kingsrook/qqq/backend/core/model/metadata/QFieldType.java @@ -22,6 +22,10 @@ package com.kingsrook.qqq.backend.core.model.metadata; +import java.math.BigDecimal; +import com.kingsrook.qqq.backend.core.exceptions.QException; + + /******************************************************************************* ** Possible data types for Q-fields. ** @@ -36,5 +40,28 @@ public enum QFieldType DATE_TIME, TEXT, HTML, - PASSWORD + PASSWORD; + + + + /******************************************************************************* + ** Get a field type enum constant for a java class. + *******************************************************************************/ + public static QFieldType fromClass(Class c) throws QException + { + if(c.equals(String.class)) + { + return (STRING); + } + if(c.equals(Integer.class) || c.equals(int.class)) + { + return (INTEGER); + } + if(c.equals(BigDecimal.class)) + { + return (DECIMAL); + } + + throw (new QException("Unrecognized class [" + c + "]")); + } } diff --git a/src/test/java/com/kingsrook/qqq/backend/core/model/data/QRecordEntityTest.java b/src/test/java/com/kingsrook/qqq/backend/core/model/data/QRecordEntityTest.java new file mode 100644 index 00000000..f7289b1e --- /dev/null +++ b/src/test/java/com/kingsrook/qqq/backend/core/model/data/QRecordEntityTest.java @@ -0,0 +1,195 @@ +/* + * QQQ - Low-code Application Framework for Engineers. + * Copyright (C) 2021-2022. Kingsrook, LLC + * 651 N Broad St Ste 205 # 6917 | Middletown DE 19709 | United States + * contact@kingsrook.com + * https://github.com/Kingsrook/ + * + * 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 . + */ + +package com.kingsrook.qqq.backend.core.model.data; + + +import java.math.BigDecimal; +import com.kingsrook.qqq.backend.core.exceptions.QException; +import com.kingsrook.qqq.backend.core.model.data.testentities.Item; +import com.kingsrook.qqq.backend.core.model.data.testentities.ItemWithPrimitives; +import com.kingsrook.qqq.backend.core.model.metadata.QFieldMetaData; +import com.kingsrook.qqq.backend.core.model.metadata.QFieldType; +import com.kingsrook.qqq.backend.core.model.metadata.QTableMetaData; +import org.junit.jupiter.api.Test; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertNull; +import static org.junit.jupiter.api.Assertions.assertTrue; + + +/******************************************************************************* + ** + *******************************************************************************/ +class QRecordEntityTest +{ + + /******************************************************************************* + ** + *******************************************************************************/ + @Test + void testItemToQRecord() throws QException + { + Item item = new Item(); + item.setSku("ABC-123"); + item.setDescription("My Item"); + item.setQuantity(47); + item.setPrice(new BigDecimal("3.50")); + item.setFeatured(true); + + QRecord qRecord = item.toQRecord(); + assertEquals("ABC-123", qRecord.getValueString("sku")); + assertEquals("My Item", qRecord.getValueString("description")); + assertEquals(47, qRecord.getValueInteger("quantity")); + assertEquals(new BigDecimal("3.50"), qRecord.getValueBigDecimal("price")); + assertTrue(qRecord.getValueBoolean("featured")); + } + + + + /******************************************************************************* + ** + *******************************************************************************/ + @Test + void testQRecordToItem() throws QException + { + QRecord qRecord = new QRecord() + .withValue("sku", "WXYZ-9876") + .withValue("description", "Items are cool") + .withValue("quantity", 42) + .withValue("price", new BigDecimal("3.50")) + .withValue("featured", false); + + Item item = qRecord.toEntity(Item.class); + assertEquals("WXYZ-9876", item.getSku()); + assertEquals("Items are cool", item.getDescription()); + assertEquals(42, item.getQuantity()); + assertEquals(new BigDecimal("3.50"), item.getPrice()); + assertFalse(item.getFeatured()); + } + + + + /******************************************************************************* + ** + *******************************************************************************/ + @Test + void testItemWithPrimitivesToQRecord() throws QException + { + ItemWithPrimitives item = new ItemWithPrimitives(); + item.setSku("ABC-123"); + item.setDescription(null); + item.setQuantity(47); + item.setPrice(new BigDecimal("3.50")); + item.setFeatured(true); + + QRecord qRecord = item.toQRecord(); + assertEquals("ABC-123", qRecord.getValueString("sku")); + assertNull(qRecord.getValueString("description")); + assertEquals(47, qRecord.getValueInteger("quantity")); + assertEquals(new BigDecimal("3.50"), qRecord.getValueBigDecimal("price")); + assertTrue(qRecord.getValueBoolean("featured")); + } + + + + /******************************************************************************* + ** + *******************************************************************************/ + @Test + void testQRecordToItemWithPrimitives() throws QException + { + QRecord qRecord = new QRecord() + .withValue("sku", "WXYZ-9876") + .withValue("description", null) + .withValue("quantity", 42) + .withValue("price", new BigDecimal("3.50")) + .withValue("featured", false); + + ItemWithPrimitives item = qRecord.toEntity(ItemWithPrimitives.class); + assertEquals("WXYZ-9876", item.getSku()); + assertNull(item.getDescription()); + assertEquals(42, item.getQuantity()); + assertEquals(new BigDecimal("3.50"), item.getPrice()); + assertFalse(item.getFeatured()); + } + + + + /******************************************************************************* + ** + *******************************************************************************/ + @Test + void testQRecordWithAllStringValuesToItem() throws QException + { + QRecord qRecord = new QRecord() + .withValue("sku", "WXYZ-9876") + .withValue("description", "Items are cool") + .withValue("quantity", "42") + .withValue("price", "3.50") + .withValue("featured", "false"); + + Item item = qRecord.toEntity(Item.class); + assertEquals("WXYZ-9876", item.getSku()); + assertEquals("Items are cool", item.getDescription()); + assertEquals(42, item.getQuantity()); + assertEquals(new BigDecimal("3.50"), item.getPrice()); + assertFalse(item.getFeatured()); + } + + + + /******************************************************************************* + ** + *******************************************************************************/ + @SuppressWarnings("ResultOfMethodCallIgnored") + @Test + void testQTableConstructionFromEntity() throws QException + { + QTableMetaData qTableMetaData = new QTableMetaData() + .withField(new QFieldMetaData(Item::getSku)) + .withField(new QFieldMetaData(Item::getDescription)) + .withField(new QFieldMetaData(Item::getQuantity)); + + assertEquals(QFieldType.STRING, qTableMetaData.getField("sku").getType()); + assertEquals(QFieldType.INTEGER, qTableMetaData.getField("quantity").getType()); + } + + + + /******************************************************************************* + ** + *******************************************************************************/ + @SuppressWarnings("ResultOfMethodCallIgnored") + @Test + void testQTableConstructionWithPrimitives() throws QException + { + QTableMetaData qTableMetaData = new QTableMetaData() + .withField(new QFieldMetaData(ItemWithPrimitives::getSku)) + .withField(new QFieldMetaData(ItemWithPrimitives::getDescription)) + .withField(new QFieldMetaData(ItemWithPrimitives::getQuantity)); + + assertEquals(QFieldType.STRING, qTableMetaData.getField("sku").getType()); + assertEquals(QFieldType.INTEGER, qTableMetaData.getField("quantity").getType()); + + } + +} \ No newline at end of file diff --git a/src/test/java/com/kingsrook/qqq/backend/core/model/data/testentities/Item.java b/src/test/java/com/kingsrook/qqq/backend/core/model/data/testentities/Item.java new file mode 100644 index 00000000..4412122b --- /dev/null +++ b/src/test/java/com/kingsrook/qqq/backend/core/model/data/testentities/Item.java @@ -0,0 +1,149 @@ +/* + * QQQ - Low-code Application Framework for Engineers. + * Copyright (C) 2021-2022. Kingsrook, LLC + * 651 N Broad St Ste 205 # 6917 | Middletown DE 19709 | United States + * contact@kingsrook.com + * https://github.com/Kingsrook/ + * + * 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 . + */ + +package com.kingsrook.qqq.backend.core.model.data.testentities; + + +import java.math.BigDecimal; +import com.kingsrook.qqq.backend.core.model.data.QRecordEntity; + + +/******************************************************************************* + ** Sample of an entity that can be converted to & from a QRecord + *******************************************************************************/ +public class Item extends QRecordEntity +{ + private String sku; + private String description; + private Integer quantity; + private BigDecimal price; + private Boolean featured; + + + + /******************************************************************************* + ** Getter for sku + ** + *******************************************************************************/ + public String getSku() + { + return sku; + } + + + + /******************************************************************************* + ** Setter for sku + ** + *******************************************************************************/ + public void setSku(String sku) + { + this.sku = sku; + } + + + + /******************************************************************************* + ** Getter for description + ** + *******************************************************************************/ + public String getDescription() + { + return description; + } + + + + /******************************************************************************* + ** Setter for description + ** + *******************************************************************************/ + public void setDescription(String description) + { + this.description = description; + } + + + + /******************************************************************************* + ** Getter for quantity + ** + *******************************************************************************/ + public Integer getQuantity() + { + return quantity; + } + + + + /******************************************************************************* + ** Setter for quantity + ** + *******************************************************************************/ + public void setQuantity(Integer quantity) + { + this.quantity = quantity; + } + + + + /******************************************************************************* + ** Getter for price + ** + *******************************************************************************/ + public BigDecimal getPrice() + { + return price; + } + + + + /******************************************************************************* + ** Setter for price + ** + *******************************************************************************/ + public void setPrice(BigDecimal price) + { + this.price = price; + } + + + + /******************************************************************************* + ** Getter for featured + ** + *******************************************************************************/ + public Boolean getFeatured() + { + return featured; + } + + + + /******************************************************************************* + ** Setter for featured + ** + *******************************************************************************/ + public void setFeatured(Boolean featured) + { + this.featured = featured; + } +} diff --git a/src/test/java/com/kingsrook/qqq/backend/core/model/data/testentities/ItemWithPrimitives.java b/src/test/java/com/kingsrook/qqq/backend/core/model/data/testentities/ItemWithPrimitives.java new file mode 100644 index 00000000..df612118 --- /dev/null +++ b/src/test/java/com/kingsrook/qqq/backend/core/model/data/testentities/ItemWithPrimitives.java @@ -0,0 +1,149 @@ +/* + * QQQ - Low-code Application Framework for Engineers. + * Copyright (C) 2021-2022. Kingsrook, LLC + * 651 N Broad St Ste 205 # 6917 | Middletown DE 19709 | United States + * contact@kingsrook.com + * https://github.com/Kingsrook/ + * + * 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 . + */ + +package com.kingsrook.qqq.backend.core.model.data.testentities; + + +import java.math.BigDecimal; +import com.kingsrook.qqq.backend.core.model.data.QRecordEntity; + + +/******************************************************************************* + ** Sample of an entity that can be converted to & from a QRecord + *******************************************************************************/ +public class ItemWithPrimitives extends QRecordEntity +{ + private String sku; + private String description; + private int quantity; + private BigDecimal price; + private boolean featured; + + + + /******************************************************************************* + ** Getter for sku + ** + *******************************************************************************/ + public String getSku() + { + return sku; + } + + + + /******************************************************************************* + ** Setter for sku + ** + *******************************************************************************/ + public void setSku(String sku) + { + this.sku = sku; + } + + + + /******************************************************************************* + ** Getter for description + ** + *******************************************************************************/ + public String getDescription() + { + return description; + } + + + + /******************************************************************************* + ** Setter for description + ** + *******************************************************************************/ + public void setDescription(String description) + { + this.description = description; + } + + + + /******************************************************************************* + ** Getter for quantity + ** + *******************************************************************************/ + public int getQuantity() + { + return quantity; + } + + + + /******************************************************************************* + ** Setter for quantity + ** + *******************************************************************************/ + public void setQuantity(int quantity) + { + this.quantity = quantity; + } + + + + /******************************************************************************* + ** Getter for price + ** + *******************************************************************************/ + public BigDecimal getPrice() + { + return price; + } + + + + /******************************************************************************* + ** Setter for price + ** + *******************************************************************************/ + public void setPrice(BigDecimal price) + { + this.price = price; + } + + + + /******************************************************************************* + ** Getter for featured + ** + *******************************************************************************/ + public boolean getFeatured() + { + return featured; + } + + + + /******************************************************************************* + ** Setter for featured + ** + *******************************************************************************/ + public void setFeatured(boolean featured) + { + this.featured = featured; + } +}