package main import ( "fmt" "log" "time" "strings" "doormile/config" "doormile/db" "doormile/migrations" "doormile/models" "doormile/utils" "github.com/joho/godotenv" ) func main() { _ = godotenv.Load() cfg := config.Load() db.Connect(cfg) if db.DB == nil { log.Fatal("DB connection is nil") } // Run migrations to ensure configid is created if err := migrations.Migrate(db.DB); err != nil { log.Fatalf("Migration failed: %v", err) } // Create hash for password "admin" type SeedUser struct { Authname string Email string Role string Roleid int } usersList := []SeedUser{ {Authname: "Suriya", Email: "suriya@doormile.com", Role: "admin", Roleid: 1}, {Authname: "Fazul", Email: "fazul@doormile.com", Role: "admin", Roleid: 1}, {Authname: "Parthiban", Email: "parthiban@doormile.com", Role: "admin", Roleid: 1}, {Authname: "Aravinth", Email: "aravinth@doormile.com", Role: "admin", Roleid: 1}, {Authname: "Jonathan", Email: "jonathan@doormile.com", Role: "admin", Roleid: 1}, {Authname: "Ratan", Email: "ratan@doormile.com", Role: "admin", Roleid: 1}, {Authname: "Kamesh", Email: "kamesh@doormile.com", Role: "executive", Roleid: 4}, // 4 is rep/executive {Authname: "Yashwanth", Email: "yashwanth@doormile.com", Role: "executive", Roleid: 4}, {Authname: "Doormile Console Admin", Email: "doormile@gmail.com", Role: "admin", Roleid: 1}, } for _, u := range usersList { passwordRaw := "admin" if u.Email != "doormile@gmail.com" { passwordRaw = fmt.Sprintf("%s@123", strings.ToLower(u.Authname)) } phash, _ := utils.HashPassword(passwordRaw) user := models.AppUser{ Authname: u.Authname, Email: u.Email, Contactno: "9999999999", Password: phash, Roleid: u.Roleid, Configid: 1001, Tenantid: 1, Applocationid: 1, Status: "Active", } var existing models.AppUser err := db.DB.Where("email = ?", user.Email).First(&existing).Error if err == nil { fmt.Printf("User %s already exists, updating password and configid...\n", user.Email) existing.Password = user.Password existing.Configid = user.Configid existing.Roleid = user.Roleid if err := db.DB.Save(&existing).Error; err != nil { log.Fatalf("Failed to update user %s: %v", user.Email, err) } } else { fmt.Printf("Creating user %s...\n", user.Email) if err := db.DB.Create(&user).Error; err != nil { log.Fatalf("Failed to create user %s: %v", user.Email, err) } } // Also ensure DoormileAuth is seeded for Admin Login var auth models.DoormileAuth authErr := db.DB.Where("email = ?", user.Email).First(&auth).Error if authErr != nil { auth = models.DoormileAuth{ Email: user.Email, PasswordHash: phash, Role: u.Role, } db.DB.Create(&auth) fmt.Printf("Created DoormileAuth for %s\n", user.Email) } else { auth.PasswordHash = phash auth.Role = u.Role db.DB.Save(&auth) fmt.Printf("Updated DoormileAuth for %s\n", user.Email) } } // Clean up old user db.DB.Where("email = ?", "suresh@nearle.in").Delete(&models.AppUser{}) fmt.Println("Cleared old suresh@nearle.in admin user from database if existed.") // Seed operating cities locationsToSeed := []models.AppLocation{ {Applocationid: 1, Applocationname: "Coimbatore", Status: "Active"}, {Applocationid: 2, Applocationname: "Hyderabad", Status: "Active"}, {Applocationid: 3, Applocationname: "Bangalore", Status: "Active"}, } for _, loc := range locationsToSeed { var existing models.AppLocation err := db.DB.Where("applocationid = ?", loc.Applocationid).First(&existing).Error if err == nil { existing.Applocationname = loc.Applocationname existing.Status = loc.Status db.DB.Save(&existing) } else { db.DB.Create(&loc) } } fmt.Println("Seeded operating cities (Coimbatore, Hyderabad, Bangalore) into applocations table.") // Seed Hubs hubsToSeed := []models.Hub{ { Hubname: "Coimbatore Jupiter Hub", Hubtype: "sorting_center", Applocationid: 1, Contactno: "9876543210", Address: "Gandhipuram, Coimbatore", Latitude: 11.0168, Longitude: 76.9558, Pincode: "641012", Status: "Active", }, { Hubname: "Coimbatore Neptune Hub", Hubtype: "delivery_hub", Applocationid: 1, Contactno: "9876543210", Address: "Peelamedu, Coimbatore", Latitude: 11.0301, Longitude: 77.0034, Pincode: "641004", Status: "Active", }, { Hubname: "Hyderabad Mars Hub", Hubtype: "sorting_center", Applocationid: 2, Contactno: "9876543210", Address: "Gachibowli, Hyderabad", Latitude: 17.4483, Longitude: 78.3741, Pincode: "500032", Status: "Active", }, { Hubname: "Hyderabad Saturn Hub", Hubtype: "delivery_hub", Applocationid: 2, Contactno: "9876543210", Address: "Madhapur, Hyderabad", Latitude: 17.4485, Longitude: 78.3908, Pincode: "500081", Status: "Active", }, { Hubname: "Bangalore Earth Hub", Hubtype: "sorting_center", Applocationid: 3, Contactno: "9876543210", Address: "Koramangala, Bangalore", Latitude: 12.9352, Longitude: 77.6244, Pincode: "560034", Status: "Active", }, { Hubname: "Bangalore Venus Hub", Hubtype: "delivery_hub", Applocationid: 3, Contactno: "9876543210", Address: "Indiranagar, Bangalore", Latitude: 12.9719, Longitude: 77.6412, Pincode: "560038", Status: "Active", }, } for _, hub := range hubsToSeed { var existing models.Hub err := db.DB.Where("hubname = ? AND applocationid = ?", hub.Hubname, hub.Applocationid).First(&existing).Error if err == nil { existing.Hubtype = hub.Hubtype existing.Contactno = hub.Contactno existing.Address = hub.Address existing.Latitude = hub.Latitude existing.Longitude = hub.Longitude existing.Pincode = hub.Pincode existing.Status = hub.Status db.DB.Save(&existing) } else { db.DB.Create(&hub) } } fmt.Println("Seeded planet hubs under respective operational cities.") // 1. Seed Tenants & Tenant Locations tenantsToSeed := []models.Tenant{ { Tenantid: 1, Tenantname: "Doormile Coimbatore Logistics", Primaryemail: "cbe-ops@doormile.com", Primarycontact: "9876543210", Status: "Active", }, { Tenantid: 2, Tenantname: "Doormile Hyderabad Logistics", Primaryemail: "hyd-ops@doormile.com", Primarycontact: "9876543211", Status: "Active", }, { Tenantid: 3, Tenantname: "Doormile Bangalore Logistics", Primaryemail: "blr-ops@doormile.com", Primarycontact: "9876543212", Status: "Active", }, } for _, tenant := range tenantsToSeed { if err := db.DB.Save(&tenant).Error; err != nil { log.Fatalf("Failed to seed Tenant: %v", err) } } fmt.Println("Seeded location-based tenants.") tenantLocationsToSeed := []models.TenantLocation{ { Tenantlocationid: 1, Tenantid: 1, Address: "124 Gandhipuram Main Rd", City: "Coimbatore", State: "Tamil Nadu", Pincode: "641012", Latitude: 11.0168, Longitude: 76.9558, Isprimary: true, Status: "Active", }, { Tenantlocationid: 2, Tenantid: 2, Address: "Phases 3 Gachibowli", City: "Hyderabad", State: "Telangana", Pincode: "500032", Latitude: 17.4483, Longitude: 78.3741, Isprimary: true, Status: "Active", }, { Tenantlocationid: 3, Tenantid: 3, Address: "80 Feet Road Koramangala", City: "Bangalore", State: "Karnataka", Pincode: "560034", Latitude: 12.9352, Longitude: 77.6244, Isprimary: true, Status: "Active", }, } for _, loc := range tenantLocationsToSeed { if err := db.DB.Save(&loc).Error; err != nil { log.Fatalf("Failed to seed Tenant Location: %v", err) } } fmt.Println("Seeded physical tenant locations.") // 2. Seed Pricing now := time.Now() farFuture := now.AddDate(1, 0, 0) pricingToSeed := []models.Pricing{ { Tenantid: 1, Applocationid: 1, // Coimbatore Vehicletype: "Bike", Baseprice: 40.00, Baseweight: 5.00, Priceperkg: 8.00, Basedistance: 5.00, Priceperkm: 8.00, Handlingcharges: 5.00, Effectivefrom: now, Effectiveto: farFuture, Currency: "INR", Priority: 1, Status: "Active", }, { Tenantid: 1, Applocationid: 2, // Hyderabad Vehicletype: "Auto", Baseprice: 60.00, Baseweight: 10.00, Priceperkg: 10.00, Basedistance: 5.00, Priceperkm: 12.00, Handlingcharges: 10.00, Effectivefrom: now, Effectiveto: farFuture, Currency: "INR", Priority: 1, Status: "Active", }, { Tenantid: 1, Applocationid: 3, // Bangalore Vehicletype: "Tata Ace", Baseprice: 150.00, Baseweight: 500.00, Priceperkg: 5.00, Basedistance: 10.00, Priceperkm: 20.00, Handlingcharges: 25.00, Effectivefrom: now, Effectiveto: farFuture, Currency: "INR", Priority: 1, Status: "Active", }, } for _, pricing := range pricingToSeed { var existing models.Pricing err := db.DB.Where("tenantid = ? AND applocationid = ? AND vehicletype = ?", pricing.Tenantid, pricing.Applocationid, pricing.Vehicletype).First(&existing).Error if err == nil { pricing.Pricingid = existing.Pricingid db.DB.Save(&pricing) } else { db.DB.Create(&pricing) } } fmt.Println("Seeded staging pricing schedules.") // 3. Seed Customers (PIN is "1234") pinHash, _ := utils.HashPassword("1234") customersToSeed := []models.AppCustomer{ { Firstname: "Rahul", Lastname: "Sharma", Phone: "9876543222", Email: "rahul@gmail.com", Loginpinhash: pinHash, Defaultlatitude: 12.9716, Defaultlongitude: 77.5946, Defaultpincode: "560034", Status: "Active", Configid: 1001, }, { Firstname: "Priya", Lastname: "Nair", Phone: "9876543233", Email: "priya@gmail.com", Loginpinhash: pinHash, Defaultlatitude: 11.0168, Defaultlongitude: 76.9558, Defaultpincode: "641012", Status: "Active", Configid: 1001, }, } for _, customer := range customersToSeed { var existing models.AppCustomer err := db.DB.Where("phone = ?", customer.Phone).First(&existing).Error if err == nil { customer.Appcustomerid = existing.Appcustomerid db.DB.Save(&customer) } else { db.DB.Create(&customer) } } fmt.Println("Seeded customer accounts (Rahul & Priya with PIN: 1234).") // 4. Seed Vehicles (moved before Milers so we can link them) db.DB.Exec("TRUNCATE TABLE vehicles CASCADE") vehiclesToSeed := []models.Vehicle{ { Vehicleid: 1, Vehicleno: "TN-37-AB-1234", Vehicletype: "Bike", Maxweight: 25.00, Maxvolume: 0.50, Batterypercentage: 92, Status: "Available", }, { Vehicleid: 2, Vehicleno: "TS-09-CD-5678", Vehicletype: "Auto", Maxweight: 250.00, Maxvolume: 4.00, Batterypercentage: 84, Status: "Available", }, { Vehicleid: 3, Vehicleno: "KA-51-EF-9012", Vehicletype: "Tata Ace", Maxweight: 850.00, Maxvolume: 12.00, Batterypercentage: 98, Status: "Available", }, } for _, vehicle := range vehiclesToSeed { if err := db.DB.Create(&vehicle).Error; err != nil { log.Fatalf("Failed to create vehicle: %v", err) } } fmt.Println("Seeded staging vehicles (Bike, Auto, Tata Ace).") // 5. Seed Milers (AppUser with role 5 + MilerProfile) milersToSeed := []struct { User models.AppUser Profile models.MilerProfile }{ // Coimbatore Riders (TenantID: 1, AppLocationID: 1) { User: models.AppUser{ Authname: "Ramesh Kumar", Email: "ramesh@doormile.com", Contactno: "9876543255", Password: pinHash, Roleid: 5, // Miler Configid: 1001, Tenantid: 1, Applocationid: 1, // Coimbatore Status: "Active", }, Profile: models.MilerProfile{ Displayname: "Ramesh Coimbatore Rider", Phone: "9876543255", Availabilitystatus: "Available", Rating: 4.8, Currentlatitude: 11.0175, Currentlongitude: 76.9565, // near Coimbatore Jupiter Hub (11.0168, 76.9558) Currentpincode: "641012", Vehicleid: utils.IntPtr(1), // Vehicle 1 (Bike: TN-37-AB-1234) Defaultvehicletype: "Bike", Applocationid: 1, }, }, { User: models.AppUser{ Authname: "Rajesh Sekhar", Email: "rajesh@doormile.com", Contactno: "9876543256", Password: pinHash, Roleid: 5, // Miler Configid: 1001, Tenantid: 1, Applocationid: 1, // Coimbatore Status: "Active", }, Profile: models.MilerProfile{ Displayname: "Rajesh Coimbatore Rider", Phone: "9876543256", Availabilitystatus: "Available", Rating: 4.7, Currentlatitude: 11.0310, Currentlongitude: 77.0045, // near Coimbatore Neptune Hub (11.0301, 77.0034) Currentpincode: "641004", Defaultvehicletype: "Bike", Applocationid: 1, }, }, { User: models.AppUser{ Authname: "Karthi Keyan", Email: "karthi@doormile.com", Contactno: "9876543257", Password: pinHash, Roleid: 5, // Miler Configid: 1001, Tenantid: 1, Applocationid: 1, // Coimbatore Status: "Active", }, Profile: models.MilerProfile{ Displayname: "Karthi Coimbatore Rider", Phone: "9876543257", Availabilitystatus: "Available", Rating: 4.6, Currentlatitude: 11.0205, Currentlongitude: 76.9760, // in between Gandhipuram and Peelamedu Currentpincode: "641018", Defaultvehicletype: "Bike", Applocationid: 1, }, }, // Hyderabad Riders (TenantID: 2, AppLocationID: 2) { User: models.AppUser{ Authname: "Suresh Goud", Email: "suresh_rider@doormile.com", Contactno: "9876543261", Password: pinHash, Roleid: 5, // Miler Configid: 1001, Tenantid: 2, Applocationid: 2, // Hyderabad Status: "Active", }, Profile: models.MilerProfile{ Displayname: "Suresh Hyderabad Rider", Phone: "9876543261", Availabilitystatus: "Available", Rating: 4.5, Currentlatitude: 17.4490, Currentlongitude: 78.3750, // near Hyderabad Mars Hub (Gachibowli: 17.4483, 78.3741) Currentpincode: "500032", Vehicleid: utils.IntPtr(2), // Vehicle 2 (Auto: TS-09-CD-5678) Defaultvehicletype: "Auto", Applocationid: 2, }, }, { User: models.AppUser{ Authname: "Mohammad Ali", Email: "ali@doormile.com", Contactno: "9876543262", Password: pinHash, Roleid: 5, // Miler Configid: 1001, Tenantid: 2, Applocationid: 2, // Hyderabad Status: "Active", }, Profile: models.MilerProfile{ Displayname: "Ali Hyderabad Rider", Phone: "9876543262", Availabilitystatus: "Available", Rating: 4.8, Currentlatitude: 17.4495, Currentlongitude: 78.3915, // near Hyderabad Saturn Hub (Madhapur: 17.4485, 78.3908) Currentpincode: "500081", Defaultvehicletype: "Bike", Applocationid: 2, }, }, { User: models.AppUser{ Authname: "Venkatesh Rao", Email: "venkatesh@doormile.com", Contactno: "9876543263", Password: pinHash, Roleid: 5, // Miler Configid: 1001, Tenantid: 2, Applocationid: 2, // Hyderabad Status: "Active", }, Profile: models.MilerProfile{ Displayname: "Venkatesh Hyderabad Rider", Phone: "9876543263", Availabilitystatus: "Available", Rating: 4.7, Currentlatitude: 17.4510, Currentlongitude: 78.3810, // between hubs Currentpincode: "500081", Defaultvehicletype: "Bike", Applocationid: 2, }, }, // Bangalore Riders (TenantID: 3, AppLocationID: 3) { User: models.AppUser{ Authname: "Sanjay Singh", Email: "sanjay@doormile.com", Contactno: "9876543266", Password: pinHash, Roleid: 5, // Miler Configid: 1001, Tenantid: 3, // Bangalore Tenant Applocationid: 3, // Bangalore Status: "Active", }, Profile: models.MilerProfile{ Displayname: "Sanjay Bangalore Rider", Phone: "9876543266", Availabilitystatus: "Available", Rating: 4.9, Currentlatitude: 12.9360, Currentlongitude: 77.6255, // near Bangalore Earth Hub (Koramangala: 12.9352, 77.6244) Currentpincode: "560034", Vehicleid: utils.IntPtr(3), // Vehicle 3 (Tata Ace: KA-51-EF-9012) Defaultvehicletype: "Tata Ace", Applocationid: 3, }, }, { User: models.AppUser{ Authname: "Anil Gowda", Email: "anil@doormile.com", Contactno: "9876543271", Password: pinHash, Roleid: 5, // Miler Configid: 1001, Tenantid: 3, Applocationid: 3, // Bangalore Status: "Active", }, Profile: models.MilerProfile{ Displayname: "Anil Bangalore Rider", Phone: "9876543271", Availabilitystatus: "Available", Rating: 4.6, Currentlatitude: 12.9725, Currentlongitude: 77.6420, // near Bangalore Venus Hub (Indiranagar: 12.9719, 77.6412) Currentpincode: "560038", Defaultvehicletype: "Bike", Applocationid: 3, }, }, { User: models.AppUser{ Authname: "Vijay Kumar", Email: "vijay@doormile.com", Contactno: "9876543272", Password: pinHash, Roleid: 5, // Miler Configid: 1001, Tenantid: 3, Applocationid: 3, // Bangalore Status: "Active", }, Profile: models.MilerProfile{ Displayname: "Vijay Bangalore Rider", Phone: "9876543272", Availabilitystatus: "Available", Rating: 4.7, Currentlatitude: 12.9510, Currentlongitude: 77.6310, // between hubs Currentpincode: "560008", Defaultvehicletype: "Bike", Applocationid: 3, }, }, } for _, miler := range milersToSeed { var existingUser models.AppUser err := db.DB.Where("email = ?", miler.User.Email).First(&existingUser).Error var userID int if err == nil { existingUser.Password = miler.User.Password existingUser.Configid = miler.User.Configid existingUser.Roleid = miler.User.Roleid existingUser.Applocationid = miler.User.Applocationid existingUser.Tenantid = miler.User.Tenantid db.DB.Save(&existingUser) userID = existingUser.Userid } else { db.DB.Create(&miler.User) userID = miler.User.Userid } var existingProfile models.MilerProfile err = db.DB.Where("userid = ?", userID).First(&existingProfile).Error if err == nil { existingProfile.Displayname = miler.Profile.Displayname existingProfile.Phone = miler.Profile.Phone existingProfile.Availabilitystatus = miler.Profile.Availabilitystatus existingProfile.Rating = miler.Profile.Rating existingProfile.Vehicleid = miler.Profile.Vehicleid existingProfile.Currentlatitude = miler.Profile.Currentlatitude existingProfile.Currentlongitude = miler.Profile.Currentlongitude existingProfile.Currentpincode = miler.Profile.Currentpincode existingProfile.Defaultvehicletype = miler.Profile.Defaultvehicletype existingProfile.Applocationid = miler.Profile.Applocationid db.DB.Save(&existingProfile) } else { miler.Profile.Userid = userID db.DB.Create(&miler.Profile) } } // 7. Seed Consignments consignmentsToSeed := []models.Consignment{ { Trackingno: "DM-TRK-888888", Tenantid: 1, Pickuppincode: "560034", Deliverypincode: "560038", Originhubid: utils.IntPtr(5), // Bangalore Earth Hub Currenthubid: utils.IntPtr(5), Destinationhubid: utils.IntPtr(6), // Bangalore Venus Hub Deadweight: 3.50, Chargeableweight: 3.50, Paymentmode: "Prepaid", Billingstatus: "Unbilled", Status: "In_Transit", }, { Trackingno: "DM-TRK-999999", Tenantid: 1, Pickuppincode: "641012", Deliverypincode: "641004", Originhubid: utils.IntPtr(1), // Coimbatore Jupiter Hub Currenthubid: utils.IntPtr(2), // Coimbatore Neptune Hub Destinationhubid: utils.IntPtr(2), Deadweight: 1.20, Chargeableweight: 1.20, Paymentmode: "COD", Codamount: 450.00, Billingstatus: "Paid", Status: "Delivered", }, } for _, c := range consignmentsToSeed { var existing models.Consignment err := db.DB.Where("trackingno = ?", c.Trackingno).First(&existing).Error if err == nil { c.Consignmentid = existing.Consignmentid db.DB.Save(&c) } else { db.DB.Create(&c) } } fmt.Println("Seeded staging packages/consignments.") // Fetch dynamic auto-incremented IDs var c1 models.Consignment db.DB.Where("trackingno = ?", "DM-TRK-888888").First(&c1) c1Id := c1.Consignmentid var c2 models.Consignment db.DB.Where("trackingno = ?", "DM-TRK-999999").First(&c2) c2Id := c2.Consignmentid // 8. Seed Consignment History historyToSeed := []models.ConsignmentHistory{ // History for DM-TRK-888888 { Consignmentid: c1Id, Eventstatus: "Created", Remarks: "Booking converted to consignment, tracking no generated.", Createdat: now.Add(-4 * time.Hour), }, { Consignmentid: c1Id, Hubid: utils.IntPtr(5), Eventstatus: "Inwarded_at_Hub", Remarks: "Received and checked at Bangalore Earth Hub.", Createdat: now.Add(-3 * time.Hour), }, { Consignmentid: c1Id, Hubid: utils.IntPtr(5), Eventstatus: "Tripsheet_Loaded", Remarks: "Loaded onto tripsheet dispatch manifest.", Createdat: now.Add(-2 * time.Hour), }, { Consignmentid: c1Id, Hubid: utils.IntPtr(5), Eventstatus: "In_Transit", Remarks: "Tripsheet dispatched, package in transit to Bangalore Venus Hub.", Createdat: now.Add(-1 * time.Hour), }, // History for DM-TRK-999999 { Consignmentid: c2Id, Eventstatus: "Created", Remarks: "Booking converted to consignment, tracking no generated.", Createdat: now.Add(-10 * time.Hour), }, { Consignmentid: c2Id, Hubid: utils.IntPtr(1), Eventstatus: "Inwarded_at_Hub", Remarks: "Received and sorted at Coimbatore Jupiter Hub.", Createdat: now.Add(-8 * time.Hour), }, { Consignmentid: c2Id, Hubid: utils.IntPtr(2), Eventstatus: "Inwarded_at_Hub", Remarks: "Received and checked at destination Coimbatore Neptune Hub.", Createdat: now.Add(-4 * time.Hour), }, { Consignmentid: c2Id, Hubid: utils.IntPtr(2), Eventstatus: "Out_for_Delivery", Remarks: "Assigned to Coimbatore Rider for doorstep delivery.", Createdat: now.Add(-2 * time.Hour), }, { Consignmentid: c2Id, Hubid: utils.IntPtr(2), Eventstatus: "Delivered", Remarks: "Delivered successfully. COD Cash payment collected.", Createdat: now.Add(-1 * time.Hour), }, } // Delete old history first so we don't duplicate on multiple seeds db.DB.Where("consignmentid IN (?, ?)", c1Id, c2Id).Delete(&models.ConsignmentHistory{}) for _, h := range historyToSeed { db.DB.Create(&h) } fmt.Println("Seeded staging tracking event history logs.") fmt.Println("✅ Database admin seeding completed successfully!") }