Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .env_template
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
GOOGLE_API_KEY=
5 changes: 4 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -51,4 +51,7 @@ __pycache__
.pytest_cache
pyenv
platform_config.yaml
videos
videos

# Env files
.env
19 changes: 15 additions & 4 deletions android/app/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,13 @@ if (keystorePropertiesFile.exists()) {
keystoreProperties.load(FileInputStream(keystorePropertiesFile))
}

// Load .env file
val envFile = file("../../.env")
val envProperties = Properties()
if (envFile.exists()) {
envProperties.load(FileInputStream(envFile))
}

android {
flavorDimensions += "store"

Expand Down Expand Up @@ -49,18 +56,22 @@ android {
targetSdk = flutter.targetSdkVersion
versionCode = flutter.versionCode
versionName = flutter.versionName

manifestPlaceholders.put("GOOGLE_API_KEY", envProperties.getProperty("GOOGLE_API_KEY") ?: "")
}

signingConfigs {
create("release") {
keyAlias = keystoreProperties["keyAlias"] as String
keyPassword = keystoreProperties["keyPassword"] as String
keyAlias = keystoreProperties["keyAlias"] as String?
keyPassword = keystoreProperties["keyPassword"] as String?
storeFile = keystoreProperties["storeFile"]?.let { file(it) }
storePassword = keystoreProperties["storePassword"] as String
storePassword = keystoreProperties["storePassword"] as String?
}
getByName("debug") {
// Debug signing config uses default values
}
}


buildTypes {

release {
Expand Down
2 changes: 2 additions & 0 deletions android/app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@
android:icon="@mipmap/ic_launcher"
android:allowBackup="false"
android:fullBackupOnly="false">
<meta-data android:name="com.google.android.geo.API_KEY"
android:value="${GOOGLE_API_KEY}"/>
<activity
android:name=".MainActivity"
android:exported="true"
Expand Down
20 changes: 20 additions & 0 deletions ios/Runner/AppDelegate.swift
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import UIKit
import Flutter
import flutter_local_notifications
import GoogleMaps

@main
@objc class AppDelegate: FlutterAppDelegate {
Expand All @@ -13,6 +14,25 @@ import flutter_local_notifications
GeneratedPluginRegistrant.register(with: registry)
}

var googleApiKey: String?

#if DEBUG
googleApiKey = Bundle.main.object(forInfoDictionaryKey: "GOOGLE_API_KEY") as? String
#endif

if googleApiKey == nil {
if let path = Bundle.main.path(forResource: "Info", ofType: "plist"),
let plist = NSDictionary(contentsOfFile: path) {
googleApiKey = plist["GOOGLE_API_KEY"] as? String
}
}

if let apiKey = googleApiKey, !apiKey.isEmpty && apiKey != "$(GOOGLE_API_KEY)" {
GMSServices.provideAPIKey(apiKey)
} else {
print("Warning: GOOGLE_API_KEY not found or empty")
}

if #available(iOS 10.0, *) {
UNUserNotificationCenter.current().delegate = self as? UNUserNotificationCenterDelegate
}
Expand Down
2 changes: 2 additions & 0 deletions ios/Runner/Info.plist
Original file line number Diff line number Diff line change
Expand Up @@ -57,5 +57,7 @@
<string>Access to documents is needed to import and export CSV files</string>
<key>UISupportsDocumentBrowser</key>
<true/>
<key>GOOGLE_API_KEY</key>
<string>$(GOOGLE_API_KEY)</string>
</dict>
</plist>
3 changes: 3 additions & 0 deletions lib/main.dart
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import 'package:flutter/material.dart';
import 'package:flutter_dotenv/flutter_dotenv.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:intl/date_symbol_data_local.dart';
import 'package:shared_preferences/shared_preferences.dart';
Expand All @@ -15,6 +16,8 @@ import 'services/notifications/notifications_service.dart';
late SharedPreferences _sharedPreferences;

void main() async {
await dotenv.load(fileName: ".env");

WidgetsFlutterBinding.ensureInitialized();
NotificationService().requestNotificationPermissions();
NotificationService().initializeNotifications();
Expand Down
149 changes: 88 additions & 61 deletions lib/model/recurring_transaction.dart
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,9 @@ class RecurringTransactionFields extends BaseEntityFields {
static String idCategory = 'idCategory';
static String idBankAccount = 'idBankAccount';
static String lastInsertion = 'lastInsertion';
static String lat = 'lat';
static String lon = 'lon';
static String locationName = 'locationName';
static String createdAt = BaseEntityFields.getCreatedAt;
static String updatedAt = BaseEntityFields.getUpdatedAt;

Expand All @@ -30,6 +33,9 @@ class RecurringTransactionFields extends BaseEntityFields {
idCategory,
idBankAccount,
lastInsertion,
lat,
lon,
locationName,
BaseEntityFields.createdAt,
BaseEntityFields.updatedAt,
];
Expand All @@ -55,72 +61,87 @@ class RecurringTransaction extends BaseEntity {
final int idBankAccount;
final TransactionType type;
final DateTime? lastInsertion;

const RecurringTransaction(
{super.id,
required this.fromDate,
this.toDate,
required this.amount,
required this.note,
required this.recurrency,
required this.idCategory,
required this.type,
required this.idBankAccount,
this.lastInsertion,
super.createdAt,
super.updatedAt});

RecurringTransaction copy(
{int? id,
DateTime? fromDate,
DateTime? toDate,
num? amount,
String? note,
String? recurrency,
int? idCategory,
TransactionType? type,
int? idBankAccount,
DateTime? lastInsertion,
DateTime? createdAt,
DateTime? updatedAt}) =>
final num? lat;
final num? lon;
final String? locationName;

const RecurringTransaction({
super.id,
required this.fromDate,
this.toDate,
required this.amount,
required this.note,
required this.recurrency,
required this.idCategory,
required this.type,
required this.idBankAccount,
this.lat,
this.lon,
this.locationName,
this.lastInsertion,
super.createdAt,
super.updatedAt,
});

RecurringTransaction copy({
int? id,
DateTime? fromDate,
DateTime? toDate,
num? amount,
String? note,
String? recurrency,
int? idCategory,
int? idBankAccount,
DateTime? lastInsertion,
num? lat,
num? lon,
String? locationName,
DateTime? createdAt,
DateTime? updatedAt,
}) =>
RecurringTransaction(
id: id ?? this.id,
fromDate: fromDate ?? this.fromDate,
toDate: toDate ?? this.toDate,
amount: amount ?? this.amount,
note: note ?? this.note,
recurrency: recurrency ?? this.recurrency,
idCategory: idCategory ?? this.idCategory,
type: type ?? this.type,
idBankAccount: idBankAccount ?? this.idBankAccount,
lastInsertion: lastInsertion ?? this.lastInsertion,
createdAt: createdAt ?? this.createdAt,
updatedAt: updatedAt ?? this.updatedAt);
id: id ?? this.id,
fromDate: fromDate ?? this.fromDate,
toDate: toDate ?? this.toDate,
amount: amount ?? this.amount,
note: note ?? this.note,
recurrency: recurrency ?? this.recurrency,
idCategory: idCategory ?? this.idCategory,
lat: lat ?? this.lat,
lon: lon ?? this.lon,
locationName: locationName ?? this.locationName,
type: type ?? this.type,
idBankAccount: idBankAccount ?? this.idBankAccount,
lastInsertion: lastInsertion ?? this.lastInsertion,
createdAt: createdAt ?? this.createdAt,
updatedAt: updatedAt ?? this.updatedAt,
);

static RecurringTransaction fromJson(Map<String, Object?> json) =>
RecurringTransaction(
id: json[BaseEntityFields.id] as int?,
fromDate: DateTime.parse(
json[RecurringTransactionFields.fromDate] as String),
toDate:
json[RecurringTransactionFields.toDate] != null
? DateTime.parse(
json[RecurringTransactionFields.toDate] as String)
: null,
amount: json[RecurringTransactionFields.amount] as num,
note: json[RecurringTransactionFields.note] as String,
recurrency: json[RecurringTransactionFields.recurrency] as String,
idCategory: json[RecurringTransactionFields.idCategory] as int,
type: TransactionType.fromJson(
id: json[BaseEntityFields.id] as int?,
fromDate:
DateTime.parse(json[RecurringTransactionFields.fromDate] as String),
toDate: json[RecurringTransactionFields.toDate] != null
? DateTime.parse(json[RecurringTransactionFields.toDate] as String)
: null,
amount: json[RecurringTransactionFields.amount] as num,
note: json[RecurringTransactionFields.note] as String,
recurrency: json[RecurringTransactionFields.recurrency] as String,
idCategory: json[RecurringTransactionFields.idCategory] as int,
type: TransactionType.fromJson(
json[RecurringTransactionFields.type] as String),
idBankAccount: json[RecurringTransactionFields.idBankAccount] as int,
lastInsertion: json[RecurringTransactionFields.lastInsertion] != null
? DateTime.parse(
json[RecurringTransactionFields.lastInsertion] as String)
: null,
createdAt: DateTime.parse(json[BaseEntityFields.createdAt] as String),
updatedAt:
DateTime.parse(json[BaseEntityFields.updatedAt] as String));
idBankAccount: json[RecurringTransactionFields.idBankAccount] as int,
lastInsertion: json[RecurringTransactionFields.lastInsertion] != null
? DateTime.parse(
json[RecurringTransactionFields.lastInsertion] as String)
: null,
createdAt: DateTime.parse(json[BaseEntityFields.createdAt] as String),
updatedAt: DateTime.parse(json[BaseEntityFields.updatedAt] as String),
lat: json[TransactionFields.lat] as num?,
lon: json[TransactionFields.lon] as num?,
locationName: json[TransactionFields.locationName] as String?,
);

Map<String, Object?> toJson() => {
BaseEntityFields.id: id,
Expand All @@ -132,6 +153,9 @@ class RecurringTransaction extends BaseEntity {
RecurringTransactionFields.recurrency: recurrency,
RecurringTransactionFields.idCategory: idCategory,
RecurringTransactionFields.idBankAccount: idBankAccount,
RecurringTransactionFields.lat: lat,
RecurringTransactionFields.lon: lon,
RecurringTransactionFields.locationName: locationName,
RecurringTransactionFields.lastInsertion:
lastInsertion?.toIso8601String(),
BaseEntityFields.createdAt: createdAt?.toIso8601String(),
Expand Down Expand Up @@ -348,6 +372,9 @@ class RecurringTransactionMethods extends SossoldiDatabase {
idBankAccount: transaction.idBankAccount,
recurring: true,
idRecurringTransaction: transaction.id,
locationName: transaction.locationName,
lat: transaction.lat,
lon: transaction.lon,
createdAt: DateTime.now(),
updatedAt: DateTime.now(),
);
Expand Down
24 changes: 24 additions & 0 deletions lib/model/transaction.dart
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,9 @@ class TransactionFields extends BaseEntityFields {
static String idBankAccountTransfer = 'idBankAccountTransfer';
static String bankAccountTransferName = 'bankAccountTransferName';
static String recurring = 'recurring';
static String lat = 'lat';
static String lon = 'lon';
static String locationName = 'locationName';
static String idRecurringTransaction = 'idRecurringTransaction';
static String createdAt = BaseEntityFields.getCreatedAt;
static String updatedAt = BaseEntityFields.getUpdatedAt;
Expand All @@ -34,6 +37,9 @@ class TransactionFields extends BaseEntityFields {
idBankAccount,
idBankAccountTransfer,
recurring,
lat,
lon,
locationName,
idRecurringTransaction,
BaseEntityFields.createdAt,
BaseEntityFields.updatedAt
Expand Down Expand Up @@ -128,6 +134,9 @@ class Transaction extends BaseEntity {
final int? idBankAccountTransfer;
final String? bankAccountTransferName;
final bool recurring;
final num? lat;
final num? lon;
final String? locationName;
final int? idRecurringTransaction;

const Transaction(
Expand All @@ -145,6 +154,9 @@ class Transaction extends BaseEntity {
this.idBankAccountTransfer,
this.bankAccountTransferName,
required this.recurring,
this.lat,
this.lon,
this.locationName,
this.idRecurringTransaction,
super.createdAt,
super.updatedAt});
Expand All @@ -159,6 +171,9 @@ class Transaction extends BaseEntity {
int? idBankAccount,
int? idBankAccountTransfer,
bool? recurring,
num? lat,
num? lon,
String? locationName,
int? idRecurringTransaction,
DateTime? createdAt,
DateTime? updatedAt}) =>
Expand All @@ -173,6 +188,9 @@ class Transaction extends BaseEntity {
idBankAccountTransfer:
idBankAccountTransfer ?? this.idBankAccountTransfer,
recurring: recurring ?? this.recurring,
lat: lat ?? this.lat,
lon: lon ?? this.lon,
locationName: locationName ?? this.locationName,
idRecurringTransaction:
idRecurringTransaction ?? this.idRecurringTransaction,
createdAt: createdAt ?? this.createdAt,
Expand All @@ -196,6 +214,9 @@ class Transaction extends BaseEntity {
bankAccountTransferName:
json[TransactionFields.bankAccountTransferName] as String?,
recurring: json[TransactionFields.recurring] == 1,
lat: json[TransactionFields.lat] as num?,
lon: json[TransactionFields.lon] as num?,
locationName: json[TransactionFields.locationName] as String?,
idRecurringTransaction:
json[TransactionFields.idRecurringTransaction] as int?,
createdAt: DateTime.parse(json[BaseEntityFields.createdAt] as String),
Expand All @@ -218,6 +239,9 @@ class Transaction extends BaseEntity {
TransactionFields.idBankAccount: idBankAccount,
TransactionFields.idBankAccountTransfer: idBankAccountTransfer,
TransactionFields.recurring: recurring ? 1 : 0,
TransactionFields.lat: lat,
TransactionFields.lon: lon,
TransactionFields.locationName: locationName,
TransactionFields.idRecurringTransaction: idRecurringTransaction,
BaseEntityFields.createdAt: createdAtDate,
BaseEntityFields.updatedAt: DateTime.now().toIso8601String(),
Expand Down
Loading