Primera app funcional
This commit is contained in:
185
lib/database/db_helper.dart
Normal file
185
lib/database/db_helper.dart
Normal file
@@ -0,0 +1,185 @@
|
||||
import 'package:sqflite/sqflite.dart';
|
||||
import 'package:path/path.dart';
|
||||
import '../models/models.dart';
|
||||
import '../models/route_model.dart';
|
||||
|
||||
class DbHelper {
|
||||
static Database? _db;
|
||||
|
||||
static Future<Database> get database async {
|
||||
_db ??= await _initDb();
|
||||
return _db!;
|
||||
}
|
||||
|
||||
static Future<Database> _initDb() async {
|
||||
final path = join(await getDatabasesPath(), 'celaya_v2.db');
|
||||
return openDatabase(path, version: 1, onCreate: _onCreate);
|
||||
}
|
||||
|
||||
static Future<void> _onCreate(Database db, int v) async {
|
||||
await db.execute('''CREATE TABLE users(
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT, nombre TEXT NOT NULL,
|
||||
email TEXT UNIQUE NOT NULL, password TEXT NOT NULL, rol TEXT NOT NULL)''');
|
||||
|
||||
await db.execute('''CREATE TABLE domicilios(
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT, user_id INTEGER NOT NULL,
|
||||
calle TEXT NOT NULL, colonia TEXT NOT NULL, route_id TEXT NOT NULL,
|
||||
horario_estimado TEXT NOT NULL, is_primary INTEGER DEFAULT 1)''');
|
||||
|
||||
await db.execute('''CREATE TABLE asignaciones(
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT, conductor_id INTEGER NOT NULL,
|
||||
route_id TEXT NOT NULL, dia_semana TEXT NOT NULL, turno TEXT NOT NULL)''');
|
||||
|
||||
await db.execute('''CREATE TABLE route_status(
|
||||
route_id TEXT PRIMARY KEY, status TEXT NOT NULL,
|
||||
mensaje TEXT, updated_at TEXT)''');
|
||||
|
||||
await db.execute('''CREATE TABLE alertas(
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT, tipo TEXT NOT NULL,
|
||||
route_id TEXT NOT NULL, mensaje TEXT NOT NULL,
|
||||
fecha TEXT NOT NULL, resuelta INTEGER DEFAULT 0)''');
|
||||
|
||||
await db.execute('''CREATE TABLE reportes(
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT, user_id INTEGER NOT NULL,
|
||||
tipo TEXT NOT NULL, descripcion TEXT NOT NULL, colonia TEXT NOT NULL,
|
||||
route_id TEXT, fecha TEXT NOT NULL, estado TEXT DEFAULT 'PENDIENTE',
|
||||
calificacion INTEGER DEFAULT 5)''');
|
||||
|
||||
// Seed: admin y conductor demo
|
||||
await db.insert('users', {'nombre':'Administrador','email':'admin@celaya.gob.mx',
|
||||
'password':'admin123','rol':'ADMINISTRADOR'});
|
||||
await db.insert('users', {'nombre':'Juan Conductor','email':'conductor@celaya.gob.mx',
|
||||
'password':'conductor123','rol':'CONDUCTOR'});
|
||||
}
|
||||
|
||||
// ── USERS ──────────────────────────────────────────────────────────────
|
||||
static Future<int> insertUser(UserModel u) async =>
|
||||
(await database).insert('users', u.toMap(), conflictAlgorithm: ConflictAlgorithm.abort);
|
||||
|
||||
static Future<UserModel?> getUserByEmail(String email) async {
|
||||
final res = await (await database).query('users', where:'email=?', whereArgs:[email]);
|
||||
return res.isEmpty ? null : UserModel.fromMap(res.first);
|
||||
}
|
||||
|
||||
static Future<UserModel?> getUserById(int id) async {
|
||||
final res = await (await database).query('users', where:'id=?', whereArgs:[id]);
|
||||
return res.isEmpty ? null : UserModel.fromMap(res.first);
|
||||
}
|
||||
|
||||
static Future<List<UserModel>> getUsersByRol(String rol) async {
|
||||
final res = await (await database).query('users', where:'rol=?', whereArgs:[rol]);
|
||||
return res.map((m) => UserModel.fromMap(m)).toList();
|
||||
}
|
||||
|
||||
// ── DOMICILIOS ─────────────────────────────────────────────────────────
|
||||
static Future<int> insertDomicilio(DomicilioModel d) async =>
|
||||
(await database).insert('domicilios', d.toMap());
|
||||
|
||||
static Future<DomicilioModel?> getPrimaryDomicilio(int userId) async {
|
||||
final res = await (await database).query('domicilios',
|
||||
where:'user_id=? AND is_primary=1', whereArgs:[userId]);
|
||||
return res.isEmpty ? null : DomicilioModel.fromMap(res.first);
|
||||
}
|
||||
|
||||
// ── ASIGNACIONES ───────────────────────────────────────────────────────
|
||||
static Future<void> upsertAsignacion(AssignmentModel a) async {
|
||||
final db = await database;
|
||||
final ex = await db.query('asignaciones',
|
||||
where:'conductor_id=? AND dia_semana=?',
|
||||
whereArgs:[a.conductorId, a.diaSemana]);
|
||||
if (ex.isEmpty) {
|
||||
await db.insert('asignaciones', a.toMap());
|
||||
} else {
|
||||
await db.update('asignaciones', {'route_id':a.routeId,'turno':a.turno},
|
||||
where:'conductor_id=? AND dia_semana=?',
|
||||
whereArgs:[a.conductorId, a.diaSemana]);
|
||||
}
|
||||
}
|
||||
|
||||
static Future<List<AssignmentModel>> getAsignacionesByConductor(int conductorId) async {
|
||||
final res = await (await database).query('asignaciones',
|
||||
where:'conductor_id=?', whereArgs:[conductorId]);
|
||||
return res.map((m) => AssignmentModel.fromMap(m)).toList();
|
||||
}
|
||||
|
||||
static Future<List<AssignmentModel>> getAllAsignaciones() async {
|
||||
final res = await (await database).query('asignaciones');
|
||||
return res.map((m) => AssignmentModel.fromMap(m)).toList();
|
||||
}
|
||||
|
||||
// ── ROUTE STATUS ───────────────────────────────────────────────────────
|
||||
static Future<void> upsertRouteStatus(RouteStatusModel s) async {
|
||||
final db = await database;
|
||||
await db.insert('route_status', s.toMap(),
|
||||
conflictAlgorithm: ConflictAlgorithm.replace);
|
||||
}
|
||||
|
||||
static Future<RouteStatusModel?> getRouteStatus(String routeId) async {
|
||||
final res = await (await database).query('route_status',
|
||||
where:'route_id=?', whereArgs:[routeId]);
|
||||
return res.isEmpty ? null : RouteStatusModel.fromMap(res.first);
|
||||
}
|
||||
|
||||
static Future<List<RouteStatusModel>> getAllRouteStatuses() async {
|
||||
final res = await (await database).query('route_status');
|
||||
return res.map((m) => RouteStatusModel.fromMap(m)).toList();
|
||||
}
|
||||
|
||||
// ── ALERTAS ────────────────────────────────────────────────────────────
|
||||
static Future<int> insertAlerta(AlertaModel a) async =>
|
||||
(await database).insert('alertas', a.toMap());
|
||||
|
||||
static Future<List<AlertaModel>> getAlertas({bool soloNoResueltas = false}) async {
|
||||
final db = await database;
|
||||
final res = soloNoResueltas
|
||||
? await db.query('alertas', where:'resuelta=0', orderBy:'fecha DESC')
|
||||
: await db.query('alertas', orderBy:'fecha DESC');
|
||||
return res.map((m) => AlertaModel.fromMap(m)).toList();
|
||||
}
|
||||
|
||||
static Future<void> resolverAlerta(int id) async =>
|
||||
(await database).update('alertas', {'resuelta':1}, where:'id=?', whereArgs:[id]);
|
||||
|
||||
// ── REPORTES ───────────────────────────────────────────────────────────
|
||||
static Future<int> insertReporte(ReporteModel r) async =>
|
||||
(await database).insert('reportes', r.toMap());
|
||||
|
||||
static Future<List<ReporteModel>> getReportesByUser(int userId) async {
|
||||
final res = await (await database).query('reportes',
|
||||
where:'user_id=?', whereArgs:[userId], orderBy:'fecha DESC');
|
||||
return res.map((m) => ReporteModel.fromMap(m)).toList();
|
||||
}
|
||||
|
||||
static Future<List<ReporteModel>> getAllReportes() async {
|
||||
final res = await (await database).query('reportes', orderBy:'fecha DESC');
|
||||
return res.map((m) => ReporteModel.fromMap(m)).toList();
|
||||
}
|
||||
|
||||
static Future<void> updateReporteEstado(int id, String estado) async =>
|
||||
(await database).update('reportes', {'estado':estado}, where:'id=?', whereArgs:[id]);
|
||||
|
||||
// ── REPORTES CON INFO DE USUARIO ──────────────────────────────────────
|
||||
static Future<List<Map<String, dynamic>>> getReportesConUsuario() async {
|
||||
final db = await database;
|
||||
return db.rawQuery('''
|
||||
SELECT r.*, u.nombre as user_nombre, u.email as user_email
|
||||
FROM reportes r
|
||||
LEFT JOIN users u ON r.user_id = u.id
|
||||
ORDER BY r.fecha DESC
|
||||
''');
|
||||
}
|
||||
|
||||
// ── INCIDENTES CONDUCTOR ───────────────────────────────────────────────
|
||||
static Future<List<AlertaModel>> getIncidentesConductor() async {
|
||||
final res = await (await database).query('alertas',
|
||||
where: "tipo LIKE 'INCIDENTE_%'", orderBy: 'fecha DESC');
|
||||
return res.map((m) => AlertaModel.fromMap(m)).toList();
|
||||
}
|
||||
|
||||
// ── DOMICILIOS POR RUTA ────────────────────────────────────────────────
|
||||
static Future<List<DomicilioModel>> getDomiciliosByRoute(String routeId) async {
|
||||
final res = await (await database).query('domicilios',
|
||||
where: 'route_id = ?', whereArgs: [routeId]);
|
||||
return res.map((m) => DomicilioModel.fromMap(m)).toList();
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user