better logging & double treatment plugin fix
This commit is contained in:
parent
442ff12aa1
commit
c90de88ec1
4 changed files with 26 additions and 79 deletions
|
@ -295,6 +295,7 @@ public class DatabaseHelper extends OrmLiteSqliteOpenHelper {
|
||||||
static public void scheduleBgChange() {
|
static public void scheduleBgChange() {
|
||||||
class PostRunnable implements Runnable {
|
class PostRunnable implements Runnable {
|
||||||
public void run() {
|
public void run() {
|
||||||
|
log.debug("Firing EventNewBg");
|
||||||
MainApp.bus().post(new EventNewBG());
|
MainApp.bus().post(new EventNewBG());
|
||||||
scheduledBgPost = null;
|
scheduledBgPost = null;
|
||||||
}
|
}
|
||||||
|
@ -445,21 +446,6 @@ public class DatabaseHelper extends OrmLiteSqliteOpenHelper {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public int update(Treatment treatment) {
|
|
||||||
treatment.date = treatment.date - treatment.date % 1000;
|
|
||||||
int updated = 0;
|
|
||||||
try {
|
|
||||||
boolean historyChange = changeAffectingIobCob(treatment);
|
|
||||||
updated = getDaoTreatments().update(treatment);
|
|
||||||
if (historyChange)
|
|
||||||
latestTreatmentChange = treatment.date;
|
|
||||||
} catch (SQLException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
scheduleTreatmentChange();
|
|
||||||
return updated;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Dao.CreateOrUpdateStatus createOrUpdate(Treatment treatment) {
|
public Dao.CreateOrUpdateStatus createOrUpdate(Treatment treatment) {
|
||||||
treatment.date = treatment.date - treatment.date % 1000;
|
treatment.date = treatment.date - treatment.date % 1000;
|
||||||
Dao.CreateOrUpdateStatus status = null;
|
Dao.CreateOrUpdateStatus status = null;
|
||||||
|
@ -475,17 +461,6 @@ public class DatabaseHelper extends OrmLiteSqliteOpenHelper {
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void create(Treatment treatment) {
|
|
||||||
treatment.date = treatment.date - treatment.date % 1000;
|
|
||||||
try {
|
|
||||||
getDaoTreatments().create(treatment);
|
|
||||||
latestTreatmentChange = treatment.date;
|
|
||||||
} catch (SQLException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
scheduleTreatmentChange();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void delete(Treatment treatment) {
|
public void delete(Treatment treatment) {
|
||||||
try {
|
try {
|
||||||
getDaoTreatments().delete(treatment);
|
getDaoTreatments().delete(treatment);
|
||||||
|
@ -564,6 +539,7 @@ public class DatabaseHelper extends OrmLiteSqliteOpenHelper {
|
||||||
static public void scheduleTreatmentChange() {
|
static public void scheduleTreatmentChange() {
|
||||||
class PostRunnable implements Runnable {
|
class PostRunnable implements Runnable {
|
||||||
public void run() {
|
public void run() {
|
||||||
|
log.debug("Firing EventTreatmentChange");
|
||||||
MainApp.bus().post(new EventReloadTreatmentData());
|
MainApp.bus().post(new EventReloadTreatmentData());
|
||||||
MainApp.bus().post(new EventTreatmentChange());
|
MainApp.bus().post(new EventTreatmentChange());
|
||||||
if (latestTreatmentChange != null)
|
if (latestTreatmentChange != null)
|
||||||
|
@ -641,7 +617,6 @@ public class DatabaseHelper extends OrmLiteSqliteOpenHelper {
|
||||||
treatment.mealBolus = false;
|
treatment.mealBolus = false;
|
||||||
}
|
}
|
||||||
createOrUpdate(treatment);
|
createOrUpdate(treatment);
|
||||||
scheduleTreatmentChange();
|
|
||||||
} catch (SQLException e) {
|
} catch (SQLException e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
} catch (JSONException e) {
|
} catch (JSONException e) {
|
||||||
|
@ -690,6 +665,7 @@ public class DatabaseHelper extends OrmLiteSqliteOpenHelper {
|
||||||
static public void scheduleTemporaryTargetChange() {
|
static public void scheduleTemporaryTargetChange() {
|
||||||
class PostRunnable implements Runnable {
|
class PostRunnable implements Runnable {
|
||||||
public void run() {
|
public void run() {
|
||||||
|
log.debug("Firing EventTempTargetChange");
|
||||||
MainApp.bus().post(new EventTempTargetChange());
|
MainApp.bus().post(new EventTempTargetChange());
|
||||||
scheduledTemTargetPost = null;
|
scheduledTemTargetPost = null;
|
||||||
}
|
}
|
||||||
|
@ -836,18 +812,6 @@ public class DatabaseHelper extends OrmLiteSqliteOpenHelper {
|
||||||
|
|
||||||
// ------------ TemporaryBasal handling ---------------
|
// ------------ TemporaryBasal handling ---------------
|
||||||
|
|
||||||
public int update(TemporaryBasal tempBasal) {
|
|
||||||
int updated = 0;
|
|
||||||
try {
|
|
||||||
updated = getDaoTemporaryBasal().update(tempBasal);
|
|
||||||
latestTreatmentChange = tempBasal.date;
|
|
||||||
} catch (SQLException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
scheduleTemporaryBasalChange();
|
|
||||||
return updated;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void createOrUpdate(TemporaryBasal tempBasal) {
|
public void createOrUpdate(TemporaryBasal tempBasal) {
|
||||||
tempBasal.date = tempBasal.date - tempBasal.date % 1000;
|
tempBasal.date = tempBasal.date - tempBasal.date % 1000;
|
||||||
try {
|
try {
|
||||||
|
@ -888,6 +852,7 @@ public class DatabaseHelper extends OrmLiteSqliteOpenHelper {
|
||||||
static public void scheduleTemporaryBasalChange() {
|
static public void scheduleTemporaryBasalChange() {
|
||||||
class PostRunnable implements Runnable {
|
class PostRunnable implements Runnable {
|
||||||
public void run() {
|
public void run() {
|
||||||
|
log.debug("Firing EventTempBasalChange");
|
||||||
MainApp.bus().post(new EventReloadTempBasalData());
|
MainApp.bus().post(new EventReloadTempBasalData());
|
||||||
MainApp.bus().post(new EventTempBasalChange());
|
MainApp.bus().post(new EventTempBasalChange());
|
||||||
scheduledTemBasalsPost = null;
|
scheduledTemBasalsPost = null;
|
||||||
|
@ -948,7 +913,6 @@ public class DatabaseHelper extends OrmLiteSqliteOpenHelper {
|
||||||
extendedBolus.insulin = trJson.getDouble("originalExtendedAmount");
|
extendedBolus.insulin = trJson.getDouble("originalExtendedAmount");
|
||||||
extendedBolus._id = trJson.getString("_id");
|
extendedBolus._id = trJson.getString("_id");
|
||||||
createOrUpdate(extendedBolus);
|
createOrUpdate(extendedBolus);
|
||||||
scheduleExtendedBolusChange();
|
|
||||||
} else if (trJson.has("isFakedTempBasal")) { // extended bolus end uploaded as temp basal end
|
} else if (trJson.has("isFakedTempBasal")) { // extended bolus end uploaded as temp basal end
|
||||||
QueryBuilder<ExtendedBolus, Long> queryBuilder = null;
|
QueryBuilder<ExtendedBolus, Long> queryBuilder = null;
|
||||||
queryBuilder = getDaoExtendedBolus().queryBuilder();
|
queryBuilder = getDaoExtendedBolus().queryBuilder();
|
||||||
|
@ -976,7 +940,6 @@ public class DatabaseHelper extends OrmLiteSqliteOpenHelper {
|
||||||
extendedBolus.insulin = 0;
|
extendedBolus.insulin = 0;
|
||||||
extendedBolus._id = trJson.getString("_id");
|
extendedBolus._id = trJson.getString("_id");
|
||||||
createOrUpdate(extendedBolus);
|
createOrUpdate(extendedBolus);
|
||||||
scheduleExtendedBolusChange();
|
|
||||||
} else {
|
} else {
|
||||||
QueryBuilder<TemporaryBasal, Long> queryBuilder = null;
|
QueryBuilder<TemporaryBasal, Long> queryBuilder = null;
|
||||||
queryBuilder = getDaoTemporaryBasal().queryBuilder();
|
queryBuilder = getDaoTemporaryBasal().queryBuilder();
|
||||||
|
@ -1013,7 +976,6 @@ public class DatabaseHelper extends OrmLiteSqliteOpenHelper {
|
||||||
}
|
}
|
||||||
tempBasal._id = trJson.getString("_id");
|
tempBasal._id = trJson.getString("_id");
|
||||||
createOrUpdate(tempBasal);
|
createOrUpdate(tempBasal);
|
||||||
scheduleTemporaryBasalChange();
|
|
||||||
}
|
}
|
||||||
} catch (SQLException e) {
|
} catch (SQLException e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
|
@ -1048,18 +1010,6 @@ public class DatabaseHelper extends OrmLiteSqliteOpenHelper {
|
||||||
|
|
||||||
// ------------ ExtendedBolus handling ---------------
|
// ------------ ExtendedBolus handling ---------------
|
||||||
|
|
||||||
public int update(ExtendedBolus extendedBolus) {
|
|
||||||
int updated = 0;
|
|
||||||
try {
|
|
||||||
updated = getDaoExtendedBolus().update(extendedBolus);
|
|
||||||
latestTreatmentChange = extendedBolus.date;
|
|
||||||
} catch (SQLException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
scheduleExtendedBolusChange();
|
|
||||||
return updated;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void createOrUpdate(ExtendedBolus extendedBolus) {
|
public void createOrUpdate(ExtendedBolus extendedBolus) {
|
||||||
extendedBolus.date = extendedBolus.date - extendedBolus.date % 1000;
|
extendedBolus.date = extendedBolus.date - extendedBolus.date % 1000;
|
||||||
try {
|
try {
|
||||||
|
@ -1166,7 +1116,6 @@ public class DatabaseHelper extends OrmLiteSqliteOpenHelper {
|
||||||
extendedBolus.insulin = trJson.getDouble("relative");
|
extendedBolus.insulin = trJson.getDouble("relative");
|
||||||
extendedBolus._id = trJson.getString("_id");
|
extendedBolus._id = trJson.getString("_id");
|
||||||
createOrUpdate(extendedBolus);
|
createOrUpdate(extendedBolus);
|
||||||
scheduleExtendedBolusChange();
|
|
||||||
} catch (SQLException e) {
|
} catch (SQLException e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
} catch (JSONException e) {
|
} catch (JSONException e) {
|
||||||
|
@ -1177,10 +1126,10 @@ public class DatabaseHelper extends OrmLiteSqliteOpenHelper {
|
||||||
static public void scheduleExtendedBolusChange() {
|
static public void scheduleExtendedBolusChange() {
|
||||||
class PostRunnable implements Runnable {
|
class PostRunnable implements Runnable {
|
||||||
public void run() {
|
public void run() {
|
||||||
|
log.debug("Firing EventExtendedBolusChange");
|
||||||
MainApp.bus().post(new EventReloadTreatmentData());
|
MainApp.bus().post(new EventReloadTreatmentData());
|
||||||
MainApp.bus().post(new EventExtendedBolusChange());
|
MainApp.bus().post(new EventExtendedBolusChange());
|
||||||
scheduledExtendedBolusPost = null;
|
scheduledExtendedBolusPost = null;
|
||||||
log.debug("Firing EventExtendedBolusChange");
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// prepare task for execution in 1 sec
|
// prepare task for execution in 1 sec
|
||||||
|
@ -1196,17 +1145,6 @@ public class DatabaseHelper extends OrmLiteSqliteOpenHelper {
|
||||||
|
|
||||||
// ------------ CareportalEvent handling ---------------
|
// ------------ CareportalEvent handling ---------------
|
||||||
|
|
||||||
public int update(CareportalEvent careportalEvent) {
|
|
||||||
int updated = 0;
|
|
||||||
try {
|
|
||||||
updated = getDaoCareportalEvents().update(careportalEvent);
|
|
||||||
} catch (SQLException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
scheduleCareportalEventChange();
|
|
||||||
return updated;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void createOrUpdate(CareportalEvent careportalEvent) {
|
public void createOrUpdate(CareportalEvent careportalEvent) {
|
||||||
careportalEvent.date = careportalEvent.date - careportalEvent.date % 1000;
|
careportalEvent.date = careportalEvent.date - careportalEvent.date % 1000;
|
||||||
try {
|
try {
|
||||||
|
@ -1299,7 +1237,6 @@ public class DatabaseHelper extends OrmLiteSqliteOpenHelper {
|
||||||
careportalEvent.json = trJson.toString();
|
careportalEvent.json = trJson.toString();
|
||||||
careportalEvent._id = trJson.getString("_id");
|
careportalEvent._id = trJson.getString("_id");
|
||||||
createOrUpdate(careportalEvent);
|
createOrUpdate(careportalEvent);
|
||||||
scheduleCareportalEventChange();
|
|
||||||
} catch (SQLException e) {
|
} catch (SQLException e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
} catch (JSONException e) {
|
} catch (JSONException e) {
|
||||||
|
@ -1310,9 +1247,9 @@ public class DatabaseHelper extends OrmLiteSqliteOpenHelper {
|
||||||
static public void scheduleCareportalEventChange() {
|
static public void scheduleCareportalEventChange() {
|
||||||
class PostRunnable implements Runnable {
|
class PostRunnable implements Runnable {
|
||||||
public void run() {
|
public void run() {
|
||||||
|
log.debug("Firing scheduleCareportalEventChange");
|
||||||
MainApp.bus().post(new EventCareportalEventChange());
|
MainApp.bus().post(new EventCareportalEventChange());
|
||||||
scheduledCareportalEventPost = null;
|
scheduledCareportalEventPost = null;
|
||||||
log.debug("Firing scheduleCareportalEventChange");
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// prepare task for execution in 1 sec
|
// prepare task for execution in 1 sec
|
||||||
|
|
|
@ -48,6 +48,8 @@ public interface TreatmentsInterface {
|
||||||
void addToHistoryExtendedBolusStop(long time);
|
void addToHistoryExtendedBolusStop(long time);
|
||||||
OverlappingIntervals<ExtendedBolus> getExtendedBolusesFromHistory();
|
OverlappingIntervals<ExtendedBolus> getExtendedBolusesFromHistory();
|
||||||
|
|
||||||
|
void addTreatmentToHistory(Treatment treatment);
|
||||||
|
|
||||||
TempTarget getTempTargetFromHistory(long time);
|
TempTarget getTempTargetFromHistory(long time);
|
||||||
OverlappingIntervals<TempTarget> getTempTargetsFromHistory();
|
OverlappingIntervals<TempTarget> getTempTargetsFromHistory();
|
||||||
|
|
||||||
|
|
|
@ -432,7 +432,7 @@ public class ConfigBuilderPlugin implements PluginBase, PumpInterface, Constrain
|
||||||
t.carbs = (double) result.carbsDelivered; // with different carbTime record will come back from nightscout
|
t.carbs = (double) result.carbsDelivered; // with different carbTime record will come back from nightscout
|
||||||
t.date = new Date().getDate();
|
t.date = new Date().getDate();
|
||||||
t.mealBolus = result.carbsDelivered > 0;
|
t.mealBolus = result.carbsDelivered > 0;
|
||||||
MainApp.getDbHelper().create(t);
|
addTreatmentToHistory(t);
|
||||||
t.carbs = (double) result.carbsDelivered;
|
t.carbs = (double) result.carbsDelivered;
|
||||||
NSUpload.uploadBolusWizardRecord(t, glucose, glucoseType, carbTime, boluscalc);
|
NSUpload.uploadBolusWizardRecord(t, glucose, glucoseType, carbTime, boluscalc);
|
||||||
}
|
}
|
||||||
|
@ -444,7 +444,7 @@ public class ConfigBuilderPlugin implements PluginBase, PumpInterface, Constrain
|
||||||
t.carbs = (double) carbs;
|
t.carbs = (double) carbs;
|
||||||
t.date = new Date().getDate();
|
t.date = new Date().getDate();
|
||||||
t.mealBolus = t.carbs > 0;
|
t.mealBolus = t.carbs > 0;
|
||||||
MainApp.getDbHelper().create(t);
|
addTreatmentToHistory(t);
|
||||||
NSUpload.uploadTreatment(t);
|
NSUpload.uploadTreatment(t);
|
||||||
result = new PumpEnactResult();
|
result = new PumpEnactResult();
|
||||||
result.success = true;
|
result.success = true;
|
||||||
|
@ -497,7 +497,7 @@ public class ConfigBuilderPlugin implements PluginBase, PumpInterface, Constrain
|
||||||
t.carbs = (double) result.carbsDelivered;
|
t.carbs = (double) result.carbsDelivered;
|
||||||
t.date = new Date().getTime();
|
t.date = new Date().getTime();
|
||||||
t.mealBolus = t.carbs > 0;
|
t.mealBolus = t.carbs > 0;
|
||||||
MainApp.getDbHelper().create(t);
|
addTreatmentToHistory(t);
|
||||||
NSUpload.uploadTreatment(t);
|
NSUpload.uploadTreatment(t);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
@ -930,6 +930,11 @@ public class ConfigBuilderPlugin implements PluginBase, PumpInterface, Constrain
|
||||||
return activeTreatments.getExtendedBolusesFromHistory();
|
return activeTreatments.getExtendedBolusesFromHistory();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void addTreatmentToHistory(Treatment treatment) {
|
||||||
|
activeTreatments.addTreatmentToHistory(treatment);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public TempTarget getTempTargetFromHistory(long time) {
|
public TempTarget getTempTargetFromHistory(long time) {
|
||||||
return activeTreatments.getTempTargetFromHistory(time);
|
return activeTreatments.getTempTargetFromHistory(time);
|
||||||
|
|
|
@ -21,7 +21,6 @@ import info.nightscout.androidaps.db.ExtendedBolus;
|
||||||
import info.nightscout.androidaps.db.TempTarget;
|
import info.nightscout.androidaps.db.TempTarget;
|
||||||
import info.nightscout.androidaps.db.TemporaryBasal;
|
import info.nightscout.androidaps.db.TemporaryBasal;
|
||||||
import info.nightscout.androidaps.db.Treatment;
|
import info.nightscout.androidaps.db.Treatment;
|
||||||
import info.nightscout.androidaps.events.EventExtendedBolusChange;
|
|
||||||
import info.nightscout.androidaps.events.EventReloadTempBasalData;
|
import info.nightscout.androidaps.events.EventReloadTempBasalData;
|
||||||
import info.nightscout.androidaps.events.EventReloadTreatmentData;
|
import info.nightscout.androidaps.events.EventReloadTreatmentData;
|
||||||
import info.nightscout.androidaps.events.EventTempTargetChange;
|
import info.nightscout.androidaps.events.EventTempTargetChange;
|
||||||
|
@ -52,12 +51,6 @@ public class TreatmentsPlugin implements PluginBase, TreatmentsInterface {
|
||||||
private static boolean fragmentEnabled = true;
|
private static boolean fragmentEnabled = true;
|
||||||
private static boolean fragmentVisible = true;
|
private static boolean fragmentVisible = true;
|
||||||
|
|
||||||
private static TreatmentsPlugin treatmentsPlugin = new TreatmentsPlugin();
|
|
||||||
|
|
||||||
public static TreatmentsPlugin getPlugin() {
|
|
||||||
return treatmentsPlugin;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getFragmentClass() {
|
public String getFragmentClass() {
|
||||||
return TreatmentsFragment.class.getName();
|
return TreatmentsFragment.class.getName();
|
||||||
|
@ -347,6 +340,7 @@ public class TreatmentsPlugin implements PluginBase, TreatmentsInterface {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void addToHistoryExtendedBolusStart(ExtendedBolus extendedBolus) {
|
public void addToHistoryExtendedBolusStart(ExtendedBolus extendedBolus) {
|
||||||
|
log.debug("Adding new ExtentedBolus record" + extendedBolus);
|
||||||
MainApp.getDbHelper().createOrUpdate(extendedBolus);
|
MainApp.getDbHelper().createOrUpdate(extendedBolus);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -355,6 +349,7 @@ public class TreatmentsPlugin implements PluginBase, TreatmentsInterface {
|
||||||
ExtendedBolus extendedBolus = new ExtendedBolus();
|
ExtendedBolus extendedBolus = new ExtendedBolus();
|
||||||
extendedBolus.date = time;
|
extendedBolus.date = time;
|
||||||
extendedBolus.durationInMinutes = 0;
|
extendedBolus.durationInMinutes = 0;
|
||||||
|
log.debug("Adding new ExtentedBolus stop record" + extendedBolus);
|
||||||
MainApp.getDbHelper().createOrUpdate(extendedBolus);
|
MainApp.getDbHelper().createOrUpdate(extendedBolus);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -394,6 +389,7 @@ public class TreatmentsPlugin implements PluginBase, TreatmentsInterface {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void addToHistoryTempBasalStart(TemporaryBasal tempBasal) {
|
public void addToHistoryTempBasalStart(TemporaryBasal tempBasal) {
|
||||||
|
log.debug("Adding new TemporaryBasal record" + tempBasal);
|
||||||
MainApp.getDbHelper().createOrUpdate(tempBasal);
|
MainApp.getDbHelper().createOrUpdate(tempBasal);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -402,9 +398,16 @@ public class TreatmentsPlugin implements PluginBase, TreatmentsInterface {
|
||||||
TemporaryBasal temporaryBasal = new TemporaryBasal();
|
TemporaryBasal temporaryBasal = new TemporaryBasal();
|
||||||
temporaryBasal.date = time;
|
temporaryBasal.date = time;
|
||||||
temporaryBasal.durationInMinutes = 0;
|
temporaryBasal.durationInMinutes = 0;
|
||||||
|
log.debug("Adding new TemporaryBasal stop record" + temporaryBasal);
|
||||||
MainApp.getDbHelper().createOrUpdate(temporaryBasal);
|
MainApp.getDbHelper().createOrUpdate(temporaryBasal);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void addTreatmentToHistory(Treatment treatment) {
|
||||||
|
log.debug("Adding new Treatment record" + treatment);
|
||||||
|
MainApp.getDbHelper().createOrUpdate(treatment);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public long oldestDataAvaialable() {
|
public long oldestDataAvaialable() {
|
||||||
long oldestTime = new Date().getTime();
|
long oldestTime = new Date().getTime();
|
||||||
|
|
Loading…
Reference in a new issue