package com.yoshione.fingen.model; import android.content.ContentValues; import android.os.Parcel; import com.yoshione.fingen.DBHelper; import com.yoshione.fingen.interfaces.IAbstractModel; import java.math.BigDecimal; import java.math.RoundingMode; import java.util.ArrayList; import java.util.Date; import java.util.List; /** * Created by slv on 14.08.2015. */ public class Transaction extends BaseModel implements IAbstractModel { public static final String TAG = "com.yoshione.fingen.Model.Transaction"; public static final int TRANSACTION_TYPE_INCOME = 1; public static final int TRANSACTION_TYPE_EXPENSE = -1; public static final int TRANSACTION_TYPE_TRANSFER = 0; public static final int TRANSACTION_TYPE_UNDEFINED = -8; public static final Creator<Transaction> CREATOR = new Creator<Transaction>() { @Override public Transaction createFromParcel(Parcel source) { return new Transaction(source); } @Override public Transaction[] newArray(int size) { return new Transaction[size]; } }; public int headerPosition = 0; private Date mDateTime; private long mAccountID; private long mDestAccountID; private long mPayeeID; private long mCategoryID; private BigDecimal mAmount; private BigDecimal mFromAccountBalance; private BigDecimal mToAccountBalance; private long mProjectID; private long mSimpleDebtID; private long mDepartmentID; private long mLocationID; private double mLat; private double mLon; private int mAccuracy; private String mComment; private String mFile; private boolean mTransactionOpened = false; private BigDecimal mExchangeRate; private int mTransactionType; private boolean mSelected; private boolean mAutoCreated; private boolean isExRateEvalDisabled = false; private boolean isDayFirst = false; private boolean isDayLast = false; private long mFN; private long mFD; private long mFP; private List<ProductEntry> mProductEntries; public Transaction(long defaultDepartmentID) { super(); this.mDateTime = new Date(); this.mAccountID = -1; this.mPayeeID = -1; this.mCategoryID = -1; this.mAmount = BigDecimal.ZERO; this.mFromAccountBalance = BigDecimal.ZERO; this.mToAccountBalance = BigDecimal.ZERO; this.mExchangeRate = BigDecimal.ONE; this.mProjectID = -1; this.mSimpleDebtID = -1; this.mLocationID = -1; this.mComment = ""; this.mFile = ""; this.mDestAccountID = -1; this.mAutoCreated = false; this.mTransactionType = TRANSACTION_TYPE_EXPENSE; this.mLat = 0d; this.mLon = 0d; this.mAccuracy = -1; this.mSelected = false; this.mDepartmentID = defaultDepartmentID; this.mFN = 0; this.mFD = 0; this.mFP = 0; mProductEntries = new ArrayList<>(); } public Transaction(Transaction src) { super(); mDateTime = src.getDateTime(); mAccountID = src.getAccountID(); mPayeeID = src.getPayeeID(); mCategoryID = src.getCategoryID(); mAmount = src.getAmount().abs(); mFromAccountBalance = src.getFromAccountBalance(); mToAccountBalance = src.getToAccountBalance(); mExchangeRate = new BigDecimal(src.getExchangeRate().doubleValue()); mProjectID = src.getProjectID(); mSimpleDebtID = src.getSimpleDebtID(); mLocationID = src.getLocationID(); mComment = src.getComment(); mFile = src.getFile(); mDestAccountID = src.getDestAccountID(); mAutoCreated = src.isAutoCreated(); mTransactionType = src.getTransactionType(); mLat = src.getLat(); mLon = src.getLon(); mAccuracy = src.getAccuracy(); mSelected = src.isSelected(); mDepartmentID = src.mDepartmentID; mFN = src.mFN; mFD = src.mFD; mFP = src.mFP; mProductEntries = new ArrayList<>(); for (ProductEntry entry : src.getProductEntries()) { mProductEntries.add(new ProductEntry(-1, entry.getProductID(), entry.getQuantity(), entry.getPrice(), entry.getCategoryID(), entry.getProjectID(), getID())); } } protected Transaction(Parcel in) { super(in); this.headerPosition = in.readInt(); long tmpMDateTime = in.readLong(); this.mDateTime = tmpMDateTime == -1 ? null : new Date(tmpMDateTime); this.mAccountID = in.readLong(); this.mDestAccountID = in.readLong(); this.mPayeeID = in.readLong(); this.mCategoryID = in.readLong(); this.mAmount = (BigDecimal) in.readSerializable(); this.mFromAccountBalance = (BigDecimal) in.readSerializable(); this.mToAccountBalance = (BigDecimal) in.readSerializable(); this.mProjectID = in.readLong(); this.mSimpleDebtID = in.readLong(); this.mDepartmentID = in.readLong(); this.mLocationID = in.readLong(); this.mLat = in.readDouble(); this.mLon = in.readDouble(); this.mAccuracy = in.readInt(); this.mComment = in.readString(); this.mFile = in.readString(); this.mTransactionOpened = in.readByte() != 0; this.mExchangeRate = (BigDecimal) in.readSerializable(); this.mTransactionType = in.readInt(); this.mSelected = in.readByte() != 0; this.mAutoCreated = in.readByte() != 0; this.isExRateEvalDisabled = in.readByte() != 0; this.isDayFirst = in.readByte() != 0; this.isDayLast = in.readByte() != 0; this.mFN = in.readLong(); this.mFD = in.readLong(); this.mFP = in.readLong(); this.mProductEntries = in.createTypedArrayList(ProductEntry.CREATOR); } public BigDecimal getFromAccountBalance() { return mFromAccountBalance; } public void setFromAccountBalance(BigDecimal fromAccountBalance) { mFromAccountBalance = fromAccountBalance; } public BigDecimal getToAccountBalance() { return mToAccountBalance; } public void setToAccountBalance(BigDecimal toAccountBalance) { mToAccountBalance = toAccountBalance; } public long getDepartmentID() { return mDepartmentID; } public void setDepartmentID(long departmentID) { mDepartmentID = departmentID; } public long getCategoryID() { return mCategoryID; } public void setCategoryID(long mCategoryID) { this.mCategoryID = mCategoryID; } @Override public String toString() { return super.toString(); } @Override public long getID() { return super.getID(); } public boolean isSelected() { return mSelected; } public void setSelected(boolean selected) { mSelected = selected; } public int getAccuracy() { return mAccuracy; } public void setAccuracy(int mAccuracy) { this.mAccuracy = mAccuracy; } public double getLat() { return mLat; } public void setLat(double mLat) { this.mLat = mLat; } public double getLon() { return mLon; } public void setLon(double mLon) { this.mLon = mLon; } public Date getDateTime() { return mDateTime; } public void setDateTime(Date mDateTime) { this.mDateTime = mDateTime; } public long getAccountID() { return mAccountID; } public void setAccountID(long mAccountID) { this.mAccountID = mAccountID; } public long getDestAccountID() { return mDestAccountID; } public void setDestAccountID(long mDestAccountID) { this.mDestAccountID = mDestAccountID; } public long getPayeeID() { return mPayeeID; } public void setPayeeID(long mPayeeID) { this.mPayeeID = mPayeeID; } public BigDecimal getAmount() { BigDecimal sign = (mTransactionType > 0) ? BigDecimal.ONE : BigDecimal.ONE.negate(); return mAmount.multiply(sign); } public void setAmount(BigDecimal mAmount, int transactionType) { this.mAmount = mAmount.abs(); if (transactionType != TRANSACTION_TYPE_UNDEFINED) { this.mTransactionType = transactionType; } else { if (mDestAccountID >= 0) { mTransactionType = TRANSACTION_TYPE_TRANSFER; } else { mTransactionType = (mAmount.compareTo(BigDecimal.ZERO) < 0) ? TRANSACTION_TYPE_EXPENSE : TRANSACTION_TYPE_INCOME; } } } public long getProjectID() { return mProjectID; } public void setProjectID(long mProjectID) { this.mProjectID = mProjectID; } public long getSimpleDebtID() { return mSimpleDebtID; } public void setSimpleDebtID(long simpleDebtID) { mSimpleDebtID = simpleDebtID; } public long getLocationID() { return mLocationID; } public void setLocationID(long mLocationID) { this.mLocationID = mLocationID; } public boolean hasLocation() { return mLocationID >= 0 || (mLat + mLon) != 0; } public String getComment() { if (mComment != null) { return mComment; } else { mComment = ""; return mComment; } } public void setComment(String mComment) { this.mComment = mComment; } public String getFile() { return mFile; } public void setFile(String mFile) { this.mFile = mFile; } public boolean isAutoCreated() { return mAutoCreated; } public void setAutoCreated(boolean mAutoCreated) { this.mAutoCreated = mAutoCreated; } public BigDecimal getExchangeRate() { return mExchangeRate; } public void setExchangeRate(BigDecimal mExchangeRate) { this.mExchangeRate = mExchangeRate.abs(); } public int getTransactionType() { if (mTransactionType == TRANSACTION_TYPE_UNDEFINED) { if (getDestAccountID() >= 0) { mTransactionType = TRANSACTION_TYPE_TRANSFER; } else { if (mAmount.compareTo(BigDecimal.ZERO) <= 0) { mTransactionType = TRANSACTION_TYPE_EXPENSE; } else { mTransactionType = TRANSACTION_TYPE_INCOME; } } } return mTransactionType; } public void setTransactionType(int mTransactionType) { this.mTransactionType = mTransactionType; } public boolean getAmountSign() { return mTransactionType > 0; } public boolean isTransactionOpened() { return mTransactionOpened; } public void setTransactionOpened(boolean mTransactionOpened) { this.mTransactionOpened = mTransactionOpened; } public List<ProductEntry> getProductEntries() { return mProductEntries; } public void setProductEntries(List<ProductEntry> productEntries) { mProductEntries = productEntries; } public BigDecimal getResidue() { if (getProductEntries().isEmpty()) return BigDecimal.ZERO; BigDecimal residue = new BigDecimal(getAmount().doubleValue()).setScale(2, RoundingMode.HALF_UP); for (ProductEntry entry : mProductEntries) { residue = residue.subtract((entry.getPrice().multiply(entry.getQuantity())).setScale(2, RoundingMode.HALF_UP)).setScale(2, RoundingMode.HALF_UP); } return residue; } @Override public String getSearchString() { return ""; } public boolean isValidToAutoCreate() { boolean ok; ok = (getAccountID() > 0); if (getTransactionType() == TRANSACTION_TYPE_TRANSFER) { ok = ok & (getDestAccountID() > 0); } else { ok = ok & (getPayeeID() > 0); ok = ok & (getCategoryID() > 0); } ok = ok & (getAmount().compareTo(BigDecimal.ZERO) != 0); return ok; } @Override public ContentValues getCV() { ContentValues values = super.getCV(); values.put(DBHelper.C_LOG_TRANSACTIONS_DATETIME, getDateTime().getTime()); values.put(DBHelper.C_LOG_TRANSACTIONS_SRCACCOUNT, getAccountID()); values.put(DBHelper.C_LOG_TRANSACTIONS_PAYEE, getPayeeID()); values.put(DBHelper.C_LOG_TRANSACTIONS_CATEGORY, getCategoryID()); values.put(DBHelper.C_LOG_TRANSACTIONS_AMOUNT, getAmount().doubleValue()); values.put(DBHelper.C_LOG_TRANSACTIONS_EXCHANGERATE, getExchangeRate().doubleValue()); values.put(DBHelper.C_LOG_TRANSACTIONS_PROJECT, getProjectID()); values.put(DBHelper.C_LOG_TRANSACTIONS_SIMPLEDEBT, getSimpleDebtID()); values.put(DBHelper.C_LOG_TRANSACTIONS_DEPARTMENT, getDepartmentID()); values.put(DBHelper.C_LOG_TRANSACTIONS_LOCATION, getLocationID()); values.put(DBHelper.C_LOG_TRANSACTIONS_COMMENT, getComment()); values.put(DBHelper.C_LOG_TRANSACTIONS_FILE, getFile()); values.put(DBHelper.C_LOG_TRANSACTIONS_DESTACCOUNT, getDestAccountID()); values.put(DBHelper.C_LOG_TRANSACTIONS_AUTOCREATED, isAutoCreated() ? 1 : 0); values.put(DBHelper.C_LOG_TRANSACTIONS_LAT, getLat()); values.put(DBHelper.C_LOG_TRANSACTIONS_LON, getLon()); values.put(DBHelper.C_LOG_TRANSACTIONS_ACCURACY, getAccuracy()); values.put(DBHelper.C_LOG_TRANSACTIONS_FN, getFN()); values.put(DBHelper.C_LOG_TRANSACTIONS_FD, getFD()); values.put(DBHelper.C_LOG_TRANSACTIONS_FP, getFP()); values.put(DBHelper.C_LOG_TRANSACTIONS_SPLIT, getProductEntries().size() == 0 ? 0 : 1); return values; } @Override public String getLogTransactionsField() { return null; } public void setDayFirst(boolean dayFirst) { isDayFirst = dayFirst; } public boolean isDayLast() { return isDayLast; } public void setDayLast(boolean dayLast) { isDayLast = dayLast; } public long getFN() { return mFN; } public void setFN(long FN) { mFN = FN; } public long getFD() { return mFD; } public void setFD(long FD) { mFD = FD; } public long getFP() { return mFP; } public void setFP(long FP) { mFP = FP; } @Override public int describeContents() { return 0; } @Override public void writeToParcel(Parcel dest, int flags) { super.writeToParcel(dest, flags); dest.writeInt(this.headerPosition); dest.writeLong(this.mDateTime != null ? this.mDateTime.getTime() : -1); dest.writeLong(this.mAccountID); dest.writeLong(this.mDestAccountID); dest.writeLong(this.mPayeeID); dest.writeLong(this.mCategoryID); dest.writeSerializable(this.mAmount); dest.writeSerializable(this.mFromAccountBalance); dest.writeSerializable(this.mToAccountBalance); dest.writeLong(this.mProjectID); dest.writeLong(this.mSimpleDebtID); dest.writeLong(this.mDepartmentID); dest.writeLong(this.mLocationID); dest.writeDouble(this.mLat); dest.writeDouble(this.mLon); dest.writeInt(this.mAccuracy); dest.writeString(this.mComment); dest.writeString(this.mFile); dest.writeByte(this.mTransactionOpened ? (byte) 1 : (byte) 0); dest.writeSerializable(this.mExchangeRate); dest.writeInt(this.mTransactionType); dest.writeByte(this.mSelected ? (byte) 1 : (byte) 0); dest.writeByte(this.mAutoCreated ? (byte) 1 : (byte) 0); dest.writeByte(this.isExRateEvalDisabled ? (byte) 1 : (byte) 0); dest.writeByte(this.isDayFirst ? (byte) 1 : (byte) 0); dest.writeByte(this.isDayLast ? (byte) 1 : (byte) 0); dest.writeLong(this.mFN); dest.writeLong(this.mFD); dest.writeLong(this.mFP); dest.writeTypedList(this.mProductEntries); } }