Merge pull request 'feature/improve-history' (#168) from feature/improve-history into main

Reviewed-on: #168
This commit is contained in:
Fujimatsu 2024-07-23 04:32:58 +00:00
commit bef4d02dae
13 changed files with 534 additions and 21 deletions

View File

@ -16,5 +16,7 @@ public interface RewardData {
CompletableFuture<List<HistoryModel>> getRewardHistoryList(String childId);
CompletableFuture<Void> payReward(String historyId);
CompletableFuture<Void> payReward(List<String> historyIds);
}

View File

@ -159,7 +159,7 @@ public class KSActionsImpl implements KSActions {
@Override
public CompletableFuture<List<HistoryModel>> syncHistory(String childId) {
CompletableFuture<HistoryListResponse> callHistoryApi = CompletableFuture.supplyAsync(() -> {
Call<HistoryListResponse> call = kidShiftApiService.getHistory(childId);
Call<HistoryListResponse> call = kidShiftApiService.getHistory(childId, true); // TODO: containPaidを引数に
try {
Response<HistoryListResponse> response = call.execute();
if (!response.isSuccessful()) {

View File

@ -10,11 +10,13 @@ import one.nem.kidshift.data.ChildData;
import one.nem.kidshift.data.KSActions;
import one.nem.kidshift.data.RewardData;
import one.nem.kidshift.data.UserSettings;
import one.nem.kidshift.data.retrofit.KidShiftApiService;
import one.nem.kidshift.data.room.utils.CacheWrapper;
import one.nem.kidshift.model.ChildModel;
import one.nem.kidshift.model.HistoryModel;
import one.nem.kidshift.utils.KSLogger;
import one.nem.kidshift.utils.factory.KSLoggerFactory;
import retrofit2.Call;
public class RewardDataImpl implements RewardData {
@ -23,14 +25,15 @@ public class RewardDataImpl implements RewardData {
private final CacheWrapper cacheWrapper;
private final KSLogger logger;
private final ChildData childData;
private final KidShiftApiService kidShiftApiService;
@Inject
public RewardDataImpl(KSLoggerFactory ksLoggerFactory, CacheWrapper cacheWrapper, UserSettings userSettings, KSActions ksActions, ChildData childData) {
public RewardDataImpl(KSLoggerFactory ksLoggerFactory, CacheWrapper cacheWrapper, UserSettings userSettings, KSActions ksActions, ChildData childData, KidShiftApiService kidShiftApiService) {
this.userSettings = userSettings;
this.ksActions = ksActions;
this.cacheWrapper = cacheWrapper;
this.childData = childData;
this.kidShiftApiService = kidShiftApiService;
this.logger = ksLoggerFactory.create("RewardDataImpl");
}
@ -53,4 +56,30 @@ public class RewardDataImpl implements RewardData {
public CompletableFuture<List<HistoryModel>> getRewardHistoryList(String childId) { // TODO: localCacheを使う
return CompletableFuture.supplyAsync(() -> ksActions.syncHistory(childId).join());
}
@Override
public CompletableFuture<Void> payReward(String historyId) {
return CompletableFuture.runAsync(() -> {
Call<Void> call = kidShiftApiService.payHistory(historyId, true);
try {
call.execute();
} catch (Exception e) {
logger.error("Failed to pay reward : " + e.getMessage());
}
});
}
@Override
public CompletableFuture<Void> payReward(List<String> historyIds) {
return CompletableFuture.runAsync(() -> {
historyIds.forEach(historyId -> { // TODO: API側でリストに対応する
Call<Void> call = kidShiftApiService.payHistory(historyId, true);
try {
call.execute();
} catch (Exception e) {
logger.error("Failed to pay reward : " + e.getMessage());
}
});
});
}
}

View File

@ -185,6 +185,9 @@ public interface KidShiftApiService {
@GET("/task/history/{childId}")
@Headers(AuthorizationInterceptor.HEADER_PLACEHOLDER)
Call<HistoryListResponse> getHistory(@Path("childId") String childId);
Call<HistoryListResponse> getHistory(@Path("childId") String childId, @Query("containPaid") boolean containPaid);
@POST("/task/history/{historyId}/paid")
@Headers(AuthorizationInterceptor.HEADER_PLACEHOLDER)
Call<Void> payHistory(@Path("historyId") String historyId, @Query("isPaid") boolean isPaid);
}

View File

@ -19,6 +19,7 @@ public class HistoryModelConverter { // TODO: JavaDoc
historyModel.setTaskId(historyResponse.getTaskId());
historyModel.setChildId(historyResponse.getChildId());
historyModel.setRegisteredAt(historyResponse.getRegisteredAt());
historyModel.setPaid(historyResponse.isPaid());
return historyModel;
}
@ -28,6 +29,7 @@ public class HistoryModelConverter { // TODO: JavaDoc
historyResponse.setTaskId(historyModel.getTaskId());
historyResponse.setChildId(historyModel.getChildId());
historyResponse.setRegisteredAt(historyModel.getRegisteredAt());
historyResponse.setPaid(historyModel.isPaid());
return historyResponse;
}

View File

@ -7,12 +7,14 @@ public class HistoryBaseItem {
private String taskId;
private String childId;
private Date registeredAt;
private boolean isPaid;
public HistoryBaseItem(String id, String taskId, String childId, Date registeredAt) {
public HistoryBaseItem(String id, String taskId, String childId, Date registeredAt, boolean isPaid) {
this.id = id;
this.taskId = taskId;
this.childId = childId;
this.registeredAt = registeredAt;
this.isPaid = isPaid;
}
public HistoryBaseItem() {
@ -49,4 +51,12 @@ public class HistoryBaseItem {
public void setRegisteredAt(Date registeredAt) {
this.registeredAt = registeredAt;
}
public boolean isPaid() {
return isPaid;
}
public void setPaid(boolean isPaid) {
this.isPaid = isPaid;
}
}

View File

@ -0,0 +1,253 @@
package one.nem.kidshift.wallet;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.CheckBox;
import android.widget.ImageButton;
import android.widget.LinearLayout;
import android.widget.TextView;
import android.widget.Toast;
import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;
import java.util.ArrayList;
import java.util.List;
import one.nem.kidshift.model.HistoryModel;
public class HistoryItemListAdapter extends RecyclerView.Adapter<HistoryItemListAdapter.ViewHolder> {
enum ViewType {
WITH_HEADER(1),
ITEM(0);
private final int value;
ViewType(int value) {
this.value = value;
}
public int getValue() {
return value;
}
}
public static class HistoryModelExtended extends HistoryModel {
private boolean isChecked;
public boolean isChecked() {
return isChecked;
}
public void setChecked(boolean checked) {
isChecked = checked;
}
// add isChecked to the constructor
public HistoryModelExtended() {
super();
isChecked = false;
}
// copy constructor
public HistoryModelExtended(HistoryModel historyModel) {
super();
this.setId(historyModel.getId());
this.setPaid(historyModel.isPaid());
this.setChildId(historyModel.getChildId());
this.setRegisteredAt(historyModel.getRegisteredAt());
this.setTaskId(historyModel.getTaskId());
this.setTaskName(historyModel.getTaskName());
this.setReward(historyModel.getReward());
this.setChecked(false);
}
}
public static class HistoryModelExtendedList {
private List<HistoryModelExtended> list;
public List<HistoryModelExtended> getList() {
return list;
}
public void setList(List<HistoryModelExtended> list) {
this.list = list;
}
// clear all checked items
public void clearChecked() {
for (HistoryModelExtended item : list) {
item.setChecked(false);
}
}
// constructor
public HistoryModelExtendedList() {
list = new ArrayList<>();
}
}
public interface CheckBoxChangedCallback {
void onCheckBoxChanged();
}
public boolean hasChecked() {
for (HistoryModelExtended historyModelExtended : historyDataList.getList()) {
if (historyModelExtended.isChecked()) {
return true;
}
}
return false;
}
private HistoryModelExtendedList historyDataList;
private CheckBoxChangedCallback callback;
private boolean hideCheckBox; // for child mode
public void setHistoryDataList(List<HistoryModel> historyDataList) {
this.historyDataList = new HistoryModelExtendedList();
for (HistoryModel historyModel : historyDataList) {
this.historyDataList.getList().add(new HistoryModelExtended(historyModel));
}
}
public void setCallback(CheckBoxChangedCallback callback) {
this.callback = callback;
}
public void setHideCheckBox(boolean hideCheckBox) {
this.hideCheckBox = hideCheckBox;
}
public List<HistoryModel> getCheckedHistoryDataList() {
List<HistoryModel> checkedHistoryDataList = new ArrayList<>();
for (HistoryModelExtended historyModelExtended : historyDataList.getList()) {
if (historyModelExtended.isChecked()) {
checkedHistoryDataList.add(historyModelExtended);
}
}
return checkedHistoryDataList;
}
@Override
public int getItemViewType(int position) {
if (position == 0) {
return ViewType.WITH_HEADER.getValue();
} else {
if (isFirstOfMonth(historyDataList.getList().get(position))) {
return ViewType.WITH_HEADER.getValue();
} else {
return ViewType.ITEM.getValue();
}
}
}
@NonNull
@Override
public HistoryItemListAdapter.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
if (viewType == ViewType.WITH_HEADER.getValue()) {
LinearLayout view = new LinearLayout(parent.getContext());
view.setOrientation(LinearLayout.VERTICAL);
view.setLayoutParams(new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT));
view.addView(LayoutInflater.from(parent.getContext()).inflate(R.layout.list_item_history_month_header, parent, false));
view.addView(LayoutInflater.from(parent.getContext()).inflate(R.layout.list_item_history_list_item, parent, false));
return new MonthHeaderViewHolder(view);
} else {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.list_item_history_list_item, parent, false);
return new ViewHolder(view);
}
}
@Override
public void onBindViewHolder(@NonNull HistoryItemListAdapter.ViewHolder holder, int position) {
HistoryModelExtended historyData = this.historyDataList.getList().get(position);
if (historyData.isPaid() || hideCheckBox) {
holder.historyItemCheckBox.setVisibility(View.GONE);
} else {
holder.historyItemCheckBox.setVisibility(View.VISIBLE);
}
holder.historyItemNameTextView.setText(historyData.getTaskName());
holder.historyItemRewardTextView.setText(historyData.getReward() + "");
holder.historyItemCheckBox.setChecked(historyData.isChecked());
holder.historyItemCheckBox.setOnCheckedChangeListener((buttonView, isChecked) -> {
if (holder.historyItemCheckBox.isShown()) {
historyData.setChecked(isChecked);
callback.onCheckBoxChanged();
}
});
if (holder instanceof MonthHeaderViewHolder) {
// ((MonthHeaderViewHolder) holder).monthHeaderTextView.setText(historyData.getRegisteredAt().getMonth() + "");
// DEBUG: 月をまたぐデータがないので
((MonthHeaderViewHolder) holder).monthHeaderTitle.setText(historyData.getRegisteredAt().getDate() + "");
((MonthHeaderViewHolder) holder).monthTotalTextView.setText(getMonthTotal(historyData) + "");
((MonthHeaderViewHolder) holder).checkAllButton.setOnClickListener(v -> {
Toast.makeText(v.getContext(), "実装中", Toast.LENGTH_SHORT).show();
});
}
}
private boolean isFirstOfMonth(HistoryModel historyModel) {
// 1個前の要素と比較して月が変わったかどうかを判定する
if (historyDataList.getList().indexOf(historyModel) == 0) {
return true;
} else {
HistoryModel previousHistoryModel = historyDataList.getList().get(historyDataList.getList().indexOf(historyModel) - 1);
// getMonth()はDeprecated TODO: やめる
// return historyModel.getRegisteredAt().getMonth() != previousHistoryModel.getRegisteredAt().getMonth();
// DEBUG: 月をまたぐデータがないので
return historyModel.getRegisteredAt().getDate() != previousHistoryModel.getRegisteredAt().getDate();
}
}
private int getMonthTotal(HistoryModel historyModel) {
int total = historyModel.getReward();
int index = historyDataList.getList().indexOf(historyModel) + 1;
try {
while (!isFirstOfMonth(this.historyDataList.getList().get(index))) {
total += historyModel.getReward();
index++;
}
} catch (IndexOutOfBoundsException e) {
// 1個しかない場合 Workaround
// TODO: 例外をひねり潰すのではなくそもそも発生しないようにするべき
}
return total;
}
@Override
public int getItemCount() {
return historyDataList == null ? 0 : historyDataList.getList().size();
}
public static class ViewHolder extends RecyclerView.ViewHolder {
TextView historyItemNameTextView;
TextView historyItemRewardTextView;
CheckBox historyItemCheckBox;
public ViewHolder(@NonNull View itemView) {
super(itemView);
historyItemNameTextView = itemView.findViewById(R.id.historyItemNameTextView);
historyItemRewardTextView = itemView.findViewById(R.id.historyItemRewardTextView);
historyItemCheckBox = itemView.findViewById(R.id.checkBox);
}
}
public static class MonthHeaderViewHolder extends HistoryItemListAdapter.ViewHolder {
// かなり邪道な方法だけどとりあえず取得できるので
TextView monthHeaderTitle;
TextView monthTotalTextView;
ImageButton checkAllButton;
public MonthHeaderViewHolder(@NonNull View itemView) {
super(itemView);
monthHeaderTitle = itemView.findViewById(R.id.monthHeaderTitle);
monthTotalTextView = itemView.findViewById(R.id.monthTotalTextView);
checkAllButton = itemView.findViewById(R.id.checkAllButton);
}
}
}

View File

@ -12,10 +12,15 @@ import dagger.hilt.android.AndroidEntryPoint;
import one.nem.kidshift.data.KSActions;
import one.nem.kidshift.data.RewardData;
import one.nem.kidshift.data.UserSettings;
import one.nem.kidshift.model.HistoryModel;
import one.nem.kidshift.utils.FabManager;
import one.nem.kidshift.utils.KSLogger;
import one.nem.kidshift.utils.ToolBarManager;
import one.nem.kidshift.utils.factory.KSLoggerFactory;
import one.nem.kidshift.utils.models.FabEventCallback;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import androidx.swiperefreshlayout.widget.SwipeRefreshLayout;
@AndroidEntryPoint
@ -41,6 +46,8 @@ public class WalletContentFragment extends Fragment {
private TextView totalRewardTextView;
private SwipeRefreshLayout swipeRefreshLayout;
private HistoryItemListAdapter historyItemListAdapter;
public WalletContentFragment() {
// Required empty public constructor
}
@ -85,16 +92,76 @@ public class WalletContentFragment extends Fragment {
swipeRefreshLayout = view.findViewById(R.id.swipeRefreshLayout);
swipeRefreshLayout.setOnRefreshListener(() -> {
updateTotalReward();
// updateTotalReward();
updateItems();
swipeRefreshLayout.setRefreshing(false);
});
RecyclerView historyItemRecyclerView = view.findViewById(R.id.historyItemRecyclerView);
historyItemListAdapter = new HistoryItemListAdapter();
historyItemRecyclerView.setAdapter(historyItemListAdapter);
historyItemRecyclerView.setLayoutManager(new LinearLayoutManager(requireContext()));
historyItemListAdapter.setCallback(() -> {
if (historyItemListAdapter.hasChecked()) {
fabManager.show();
initFab();
} else {
fabManager.hide();
}
});
return view;
}
private void initFab() {
fabManager.setFabEventCallback(new FabEventCallback() {
@Override
public void onClicked() {
historyItemListAdapter.getCheckedHistoryDataList().forEach(historyModel -> {
rewardData.payReward(historyModel.getId()).thenRun(() -> {
logger.debug("Paid reward: " + historyModel.getId());
updateItems();
}).exceptionally(throwable -> {
logger.error("Failed to pay reward: " + throwable.getMessage());
return null;
});
});
updateItems(); // workaround
}
@Override
public void onLongClicked() {
}
});
}
@Override
public void onViewCreated(View view, Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
updateItems();
}
private void updateItems() {
swipeRefreshLayout.setRefreshing(true);
rewardData.getRewardHistoryList(childId).thenAccept(historyList -> {
historyItemListAdapter.setHistoryDataList(historyList);
// totalRewardTextView.setText(String.valueOf(historyList.stream().mapToInt(HistoryModel::getReward).sum()) + "");
requireActivity().runOnUiThread(() -> {
historyItemListAdapter.notifyDataSetChanged();
totalRewardTextView.setText(String.valueOf(historyList.stream().filter(HistoryModel::isPaid).mapToInt(HistoryModel::getReward).sum()) + "");
});
}).thenRun(() -> {
requireActivity().runOnUiThread(() -> {
swipeRefreshLayout.setRefreshing(false);
});
}).exceptionally(throwable -> {
logger.error("Failed to get history list: " + throwable.getMessage());
return null;
});
}
private void updateTotalReward() {
@ -110,13 +177,22 @@ public class WalletContentFragment extends Fragment {
logger.error("Failed to get total reward: " + throwable.getMessage());
return null;
});
rewardData.getRewardHistoryList(childId).thenAccept(historyList -> { // test
historyItemListAdapter.setHistoryDataList(historyList);
historyItemListAdapter.notifyDataSetChanged();
}).exceptionally(throwable -> {
logger.error("Failed to get history list: " + throwable.getMessage());
return null;
});
}
@Override
public void onResume() {
super.onResume();
updateTotalReward();
fabManager.hide();
// updateTotalReward();
// updateItems();
// fabManager.hide();
toolBarManager.setTitle("ウォレット");
toolBarManager.setSubtitle(null);
}

View File

@ -26,6 +26,7 @@ import dagger.hilt.android.AndroidEntryPoint;
import one.nem.kidshift.data.ChildData;
import one.nem.kidshift.data.RewardData;
import one.nem.kidshift.model.ChildModel;
import one.nem.kidshift.model.callback.ChildModelCallback;
import one.nem.kidshift.utils.FabManager;
import one.nem.kidshift.utils.KSLogger;
import one.nem.kidshift.utils.ToolBarManager;
@ -51,6 +52,7 @@ public class WalletParentWrapperFragment extends Fragment {
private TabLayout tabLayout;
private ViewPager2 viewPager;
private TabAdapter tabAdapter;
public WalletParentWrapperFragment() {
// Required empty public constructor
@ -70,22 +72,50 @@ public class WalletParentWrapperFragment extends Fragment {
tabLayout = view.findViewById(R.id.tabLayout);
viewPager = view.findViewById(R.id.viewPager);
TabAdapter tabAdapter = new TabAdapter(requireActivity());
// デバッグ用
List<ChildModel> childList = childData.getChildListDirect().join();
tabAdapter.setChildList(childList);
tabAdapter = new TabAdapter(requireActivity());
viewPager.setAdapter(tabAdapter);
new TabLayoutMediator(tabLayout, viewPager, (tab, position) -> {
tab.setText(childList.get(position).getName());
}).attach();
setupViewPager();
return view;
}
private void setupViewPager() {
// デバッグ用
childData.getChildList(new ChildModelCallback() {
@Override
public void onUnchanged() {
// TODO: impl
}
@Override
public void onUpdated(List<ChildModel> childModelList) {
// TODO: impl
}
@Override
public void onFailed(String message) {
// TODO: impl
}
}).thenAccept(childModels -> {
// childData.getChildListDirect().thenAccept(childModels -> {
tabAdapter.setChildList(childModels);
requireActivity().runOnUiThread(() -> {
tabAdapter.notifyDataSetChanged();
new TabLayoutMediator(tabLayout, viewPager, (tab, position) -> {
tab.setText(childModels.get(position).getName());
}).attach();
});
});
}
private static class TabAdapter extends FragmentStateAdapter {
private List<ChildModel> childList;

View File

@ -16,9 +16,12 @@
android:id="@+id/frameLayout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="24dp"
android:layout_marginBottom="24dp"
android:background="@color/colorSurface"
android:backgroundTintMode="add"
android:elevation="16px"
app:layout_constraintBottom_toTopOf="@+id/historyItemRecyclerView"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent">
<LinearLayout
@ -32,6 +35,7 @@
android:layout_height="wrap_content"
android:text="今月の支払い総額"
android:textAppearance="@style/TextAppearance.AppCompat.Display1"
android:textColor="@color/colorOnSurface"
android:textSize="20sp" />
<TextView
@ -40,7 +44,8 @@
android:layout_height="wrap_content"
android:gravity="center"
android:text="0000円"
android:textAppearance="@style/TextAppearance.AppCompat.Display2" />
android:textAppearance="@style/TextAppearance.AppCompat.Display2"
android:textColor="@color/colorOnSurface" />
</LinearLayout>
</FrameLayout>

View File

@ -0,0 +1,45 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="32px">
<CheckBox
android:id="@+id/checkBox"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="12dp"
android:layout_marginEnd="12dp"
android:layout_marginBottom="12dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="16px"
android:orientation="vertical"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent">
<TextView
android:id="@+id/historyItemNameTextView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="TextView"
android:textAppearance="@style/TextAppearance.AppCompat.Medium" />
<TextView
android:id="@+id/historyItemRewardTextView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="TextView"
android:textAppearance="@style/TextAppearance.AppCompat.Small" />
</LinearLayout>
</androidx.constraintlayout.widget.ConstraintLayout>

View File

@ -0,0 +1,48 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingHorizontal="48px"
android:paddingVertical="24px">
<LinearLayout
android:id="@+id/linearLayout"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent">
<TextView
android:id="@+id/monthHeaderTitle"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="ふが月"
android:textAppearance="@style/TextAppearance.AppCompat.Display1" />
<TextView
android:id="@+id/monthTotalTextView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="0000000円"
android:textAppearance="@style/TextAppearance.AppCompat.Medium" />
</LinearLayout>
<ImageButton
android:id="@+id/checkAllButton"
style="@style/Widget.AppCompat.ImageButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="@android:color/transparent"
android:padding="24px"
android:tint="@color/colorOnBackground"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:srcCompat="@drawable/done_all_24px" />
</androidx.constraintlayout.widget.ConstraintLayout>

View File

@ -9,14 +9,16 @@ public class HistoryModel {
private String childId;
private Date registeredAt;
private int reward;
private boolean isPaid;
public HistoryModel(String id, String taskId, String taskName, String childId, Date registeredAt, int reward) {
public HistoryModel(String id, String taskId, String taskName, String childId, Date registeredAt, int reward, boolean isPaid) {
this.id = id;
this.taskId = taskId;
this.taskName = taskName;
this.childId = childId;
this.registeredAt = registeredAt;
this.reward = reward;
this.isPaid = isPaid;
}
public HistoryModel(String id, String taskId, String childId, Date registeredAt) { // 他モデルとのマージが必要なので
@ -76,4 +78,12 @@ public class HistoryModel {
public void setReward(int reward) {
this.reward = reward;
}
public boolean isPaid() {
return isPaid;
}
public void setPaid(boolean isPaid) {
this.isPaid = isPaid;
}
}