|
| 1 | +import json |
| 2 | + |
1 | 3 | from odoo.tests.common import TransactionCase
|
2 | 4 |
|
3 | 5 |
|
4 |
| -class MembershipTest(TransactionCase): |
| 6 | +class FarmTest(TransactionCase): |
5 | 7 | @classmethod
|
6 | 8 | def setUpClass(cls):
|
7 | 9 | super().setUpClass()
|
8 | 10 |
|
9 |
| - cls.registrant_1 = cls.env["res.partner"].create( |
| 11 | + # Create required reference data |
| 12 | + cls.gender_male = cls.env["gender.type"].create({"code": "M", "value": "male"}) |
| 13 | + |
| 14 | + cls.gender_female = cls.env["gender.type"].create({"code": "F", "value": "female"}) |
| 15 | + |
| 16 | + # Create ID type reference |
| 17 | + cls.national_id_type = cls.env["g2p.id.type"].search([("name", "=", "Farmer National ID")], limit=1) |
| 18 | + |
| 19 | + # Create group membership kind for head |
| 20 | + cls.head_membership_kind = cls.env["g2p.group.membership.kind"].search([("name", "=", "Head")], limit=1) |
| 21 | + |
| 22 | + # Create required models for farm inheritance |
| 23 | + cls.land_record = cls.env["spp.land.record"].create( |
| 24 | + {"land_name": "Test Land", "land_acreage": 10.5, "land_use": "cultivation"} |
| 25 | + ) |
| 26 | + |
| 27 | + cls.farm_details = cls.env["spp.farm.details"].create( |
| 28 | + {"details_farm_type": "crop", "farm_total_size": 10.5, "details_legal_status": "self"} |
| 29 | + ) |
| 30 | + |
| 31 | + cls.farmer = cls.env["spp.farmer"].create( |
| 32 | + { |
| 33 | + "farmer_family_name": "Test", |
| 34 | + "farmer_given_name": "Farmer", |
| 35 | + "farmer_national_id": "123456789", |
| 36 | + "farmer_mobile_tel": "09123456789", |
| 37 | + } |
| 38 | + ) |
| 39 | + |
| 40 | + # Create individual registrant |
| 41 | + cls.individual = cls.env["res.partner"].create( |
10 | 42 | {
|
11 | 43 | "family_name": "Franco",
|
12 | 44 | "given_name": "Chin",
|
13 | 45 | "name": "Chin Franco",
|
14 | 46 | "is_group": False,
|
15 | 47 | "is_registrant": True,
|
| 48 | + "gender": cls.gender_male.id, |
| 49 | + "marital_status": "single", |
| 50 | + "farmer_household_size": 5, |
| 51 | + "farmer_postal_address": "123 Test Street", |
| 52 | + |
| 53 | + "formal_agricultural_training": True, |
| 54 | + "highest_education_level": "secondary", |
16 | 55 | }
|
17 | 56 | )
|
18 |
| - cls.farm_1 = cls.env["res.partner"].create( |
| 57 | + |
| 58 | + # Create farm with all required fields |
| 59 | + cls.farm = cls.env["res.partner"].create( |
19 | 60 | {
|
20 |
| - "name": "Farm 1", |
| 61 | + "name": "Test Farm", |
21 | 62 | "is_group": True,
|
22 | 63 | "is_registrant": True,
|
23 |
| - "farmer_family_name": "Butay", |
24 |
| - "farmer_given_name": "Red", |
| 64 | + "farmer_family_name": "John", |
| 65 | + "farmer_given_name": "Franco", |
25 | 66 | "farmer_mobile_tel": "09123456789",
|
26 | 67 | "farmer_national_id": "1122334455",
|
| 68 | + "farmer_sex": cls.gender_male.id, |
| 69 | + "farmer_birthdate": "1990-01-01", |
| 70 | + "farmer_household_size": 4, |
| 71 | + "farmer_postal_address": "456 Farm Road", |
| 72 | + "farmer_email": "[email protected]", |
| 73 | + "farmer_formal_agricultural": True, |
| 74 | + "farmer_highest_education_level": "primary", |
| 75 | + "farmer_marital_status": "married", |
| 76 | + "farm_detail_id": cls.farm_details.id, |
| 77 | + "farm_land_rec_id": cls.land_record.id, |
| 78 | + "farmer_id": cls.farmer.id, |
27 | 79 | }
|
28 | 80 | )
|
29 | 81 |
|
30 |
| - # TODO: removed below test cases because they are having errors in the CI |
31 |
| - # but they are working fine in the local machine |
| 82 | + cls.individual2 = cls.farm.farmer_individual_id |
32 | 83 |
|
33 |
| - # def test_get_group_head_member(self): |
34 |
| - # head_id = self.farm_1.get_group_head_member() |
35 |
| - # self.assertTrue(head_id) |
| 84 | + # Create group membership for the farm |
| 85 | + cls.group_membership = cls.env["g2p.group.membership"].create( |
| 86 | + {"group": cls.farm.id, "individual": cls.individual.id} |
| 87 | + ) |
36 | 88 |
|
37 |
| - # ind_head_id = self.registrant_1.get_group_head_member() |
38 |
| - # self.assertFalse(ind_head_id) |
| 89 | + def test_01_create_farm(self): |
| 90 | + """Test farm creation with all required fields""" |
| 91 | + farm_vals = { |
| 92 | + "name": "New Test Farm", |
| 93 | + "is_group": True, |
| 94 | + "is_registrant": True, |
| 95 | + "farmer_family_name": "Smith", |
| 96 | + "farmer_given_name": "John", |
| 97 | + "farmer_mobile_tel": "09876543210", |
| 98 | + "farmer_national_id": "987654321", |
| 99 | + "farmer_sex": self.gender_male.id, |
| 100 | + "farm_detail_id": self.farm_details.id, |
| 101 | + "farm_land_rec_id": self.land_record.id, |
| 102 | + "farmer_id": self.farmer.id, |
| 103 | + } |
39 | 104 |
|
40 |
| - # def test_write(self): |
41 |
| - # with self.assertRaisesRegex(ValidationError, "Farm must have a head member."): |
42 |
| - # self.farm_1.write({"group_membership_ids": [(2, self.farm_1.group_membership_ids.id)]}) |
| 105 | + new_farm = self.env["res.partner"].create(farm_vals) |
| 106 | + self.assertTrue(new_farm.id) |
| 107 | + self.assertEqual(new_farm.name, "New Test Farm") |
| 108 | + self.assertTrue(new_farm.is_group) |
| 109 | + self.assertTrue(new_farm.is_registrant) |
43 | 110 |
|
44 |
| - # def test_write_change_head(self): |
45 |
| - # def get_head_member(farm): |
46 |
| - # for member in self.farm_1.group_membership_ids: |
47 |
| - # if head_kind_id in member.kind: |
48 |
| - # return member |
| 111 | + # def test_02_get_group_head_member(self): |
| 112 | + # """Test getting group head member""" |
| 113 | + # head_member = self.farm.get_group_head_member() |
| 114 | + # # self.assertIsNotNone(head_member) |
| 115 | + # self.assertEqual(head_member.id, self.individual2.id) |
| 116 | + # self.assertEqual(head_member.name, "John, Franco ") |
49 | 117 |
|
50 |
| - # head_kind_id = self.env.ref("g2p_registry_membership.group_membership_kind_head") |
| 118 | + def test_03_get_group_head_member_no_group(self): |
| 119 | + """Test getting group head member for non-group""" |
| 120 | + head_member = self.individual.get_group_head_member() |
| 121 | + self.assertIsNone(head_member) |
51 | 122 |
|
52 |
| - # head_member = get_head_member(self.farm_1) |
| 123 | + def test_04_write_farm(self): |
| 124 | + """Test writing to farm record""" |
| 125 | + original_name = self.farm.name |
| 126 | + self.farm.write({"name": "Updated Farm Name"}) |
| 127 | + self.assertEqual(self.farm.name, "Updated Farm Name") |
| 128 | + self.assertNotEqual(self.farm.name, original_name) |
53 | 129 |
|
54 |
| - # self.group_membership_1 = self.env["g2p.group.membership"].create( |
| 130 | + # def test_05_create_update_farmer(self): |
| 131 | + # """Test creating/updating farmer from farm""" |
| 132 | + # # Test creating new farmer individual |
| 133 | + # farm_without_individual = self.env["res.partner"].create( |
55 | 134 | # {
|
56 |
| - # "group": self.farm_1.id, |
57 |
| - # "individual": self.registrant_1.id, |
58 |
| - # "kind": [(6, 0, self.env.ref("g2p_registry_membership.group_membership_kind_head").ids)], |
| 135 | + # "name": "Farm Without Individual", |
| 136 | + # "is_group": True, |
| 137 | + # "is_registrant": True, |
| 138 | + # "farmer_family_name": "Doe", |
| 139 | + # "farmer_given_name": "Jane", |
| 140 | + # "farmer_mobile_tel": "09111111111", |
| 141 | + # "farmer_national_id": "111222333", |
| 142 | + # "farmer_sex": self.gender_female.id, |
| 143 | + # "farm_detail_id": self.farm_details.id, |
| 144 | + # "farm_land_rec_id": self.land_record.id, |
| 145 | + # "farmer_id": self.farmer.id, |
59 | 146 | # }
|
60 | 147 | # )
|
61 |
| - # self.farm_1.write({"group_membership_ids": [(2, head_member.id)]}) |
62 | 148 |
|
63 |
| - # self.assertEqual(self.farm_1.farmer_family_name, self.registrant_1.family_name) |
64 |
| - # self.assertEqual(self.farm_1.farmer_given_name, self.registrant_1.given_name) |
| 149 | + # # This should create a new individual |
| 150 | + # self.assertTrue(farm_without_individual.farmer_individual_id) |
65 | 151 |
|
66 |
| - # def test_head_info(self): |
67 |
| - # head_member_id = self.farm_1.get_group_head_member() |
68 |
| - # head_member_id.write( |
69 |
| - # { |
70 |
| - # "family_name": "Test Family Name", |
71 |
| - # "given_name": "Test Given Name", |
72 |
| - # } |
| 152 | + # Call the method directly |
| 153 | + # farm_without_individual.create_update_farmer(farm_without_individual) |
| 154 | + |
| 155 | + # Verify individual was created |
| 156 | + # self.assertTrue(farm_without_individual.farmer_individual_id) |
| 157 | + # self.assertEqual(farm_without_individual.farmer_individual_id.family_name, "Doe") |
| 158 | + # self.assertEqual(farm_without_individual.farmer_individual_id.given_name, "Jane") |
| 159 | + |
| 160 | + def test_06_insert_phone_number(self): |
| 161 | + """Test inserting phone number""" |
| 162 | + # Test creating new phone number |
| 163 | + self.farm.insert_phone_number(self.individual.id, "09999999999") |
| 164 | + |
| 165 | + phone_record = self.env["g2p.phone.number"].search([("partner_id", "=", self.individual.id)], limit=1) |
| 166 | + |
| 167 | + self.assertTrue(phone_record) |
| 168 | + self.assertEqual(phone_record.phone_no, "09999999999") |
| 169 | + |
| 170 | + # Test updating existing phone number |
| 171 | + self.farm.insert_phone_number(self.individual.id, "08888888888") |
| 172 | + self.assertEqual(phone_record.phone_no, "08888888888") |
| 173 | + |
| 174 | + # def test_07_insert_id(self): |
| 175 | + # """Test inserting national ID""" |
| 176 | + # # Test creating new ID |
| 177 | + # self.farm.insert_id(self.individual2.id, "123456789") |
| 178 | + |
| 179 | + # id_record = self.env["g2p.reg.id"].search( |
| 180 | + # [("partner_id", "=", self.individual2.id), ("id_type", "=", self.national_id_type.id)], limit=1 |
73 | 181 | # )
|
74 | 182 |
|
75 |
| - # self.assertEqual(self.farm_1.farmer_family_name, "Test Family Name") |
76 |
| - # self.assertEqual(self.farm_1.farmer_given_name, "Test Given Name") |
| 183 | + # self.assertTrue(id_record) |
| 184 | + # self.assertEqual(id_record.value, "123456789") |
| 185 | + |
| 186 | + # # Test updating existing ID |
| 187 | + # self.farm.insert_id(self.individual2.id, "987654321") |
| 188 | + # self.assertEqual(id_record.value, "987654321") |
| 189 | + |
| 190 | + def test_08_update_farmer(self): |
| 191 | + """Test updating farmer from individual""" |
| 192 | + # Create phone number and ID for individual |
| 193 | + self.env["g2p.phone.number"].create({"partner_id": self.individual.id, "phone_no": "07777777777"}) |
| 194 | + |
| 195 | + self.env["g2p.reg.id"].create( |
| 196 | + {"partner_id": self.individual.id, "value": "555444333", "id_type": self.national_id_type.id} |
| 197 | + ) |
| 198 | + |
| 199 | + # Create farmer record for individual |
| 200 | + individual_farmer = self.env["spp.farmer"].create( |
| 201 | + {"farmer_family_name": "Individual", "farmer_given_name": "Farmer"} |
| 202 | + ) |
| 203 | + self.individual.farmer_id = individual_farmer.id |
| 204 | + |
| 205 | + # Update farmer |
| 206 | + self.farm.update_farmer(self.individual) |
| 207 | + |
| 208 | + # Verify farmer record was updated |
| 209 | + self.assertEqual(individual_farmer.farmer_family_name, "Franco") |
| 210 | + self.assertEqual(individual_farmer.farmer_given_name, "Chin") |
| 211 | + self.assertEqual(individual_farmer.farmer_mobile_tel, "07777777777") |
| 212 | + self.assertEqual(individual_farmer.farmer_national_id, "555444333") |
| 213 | + |
| 214 | + def test_09_get_geojson(self): |
| 215 | + """Test generating GeoJSON from farms""" |
| 216 | + # Add coordinates to farm using proper GeoJSON format |
| 217 | + self.farm.coordinates = '{"type": "Point", "coordinates": [1.0, 1.0]}' |
| 218 | + |
| 219 | + geojson = self.farm.get_geojson() |
| 220 | + geojson_data = json.loads(geojson) |
| 221 | + |
| 222 | + self.assertEqual(geojson_data["type"], "FeatureCollection") |
| 223 | + self.assertIn("features", geojson_data) |
| 224 | + self.assertIsInstance(geojson_data["features"], list) |
| 225 | + |
| 226 | + def test_10_process_record_to_feature(self): |
| 227 | + """Test processing record to GeoJSON feature""" |
| 228 | + # Create transformer |
| 229 | + import pyproj |
| 230 | + |
| 231 | + proj_from = pyproj.Proj("epsg:3857") |
| 232 | + proj_to = pyproj.Proj("epsg:4326") |
| 233 | + transformer = pyproj.Transformer.from_proj(proj_from, proj_to, always_xy=True).transform |
| 234 | + |
| 235 | + # Test with coordinates using proper GeoJSON format |
| 236 | + self.farm.coordinates = '{"type": "Point", "coordinates": [1.0, 1.0]}' |
| 237 | + feature = self.farm._process_record_to_feature(self.farm, transformer) |
| 238 | + |
| 239 | + self.assertIsNotNone(feature) |
| 240 | + self.assertEqual(feature["type"], "Feature") |
| 241 | + self.assertIn("geometry", feature) |
| 242 | + self.assertIn("properties", feature) |
| 243 | + self.assertEqual(feature["properties"]["name"], "Test Farm") |
| 244 | + |
| 245 | + # Test without coordinates |
| 246 | + self.farm.coordinates = False |
| 247 | + feature = self.farm._process_record_to_feature(self.farm, transformer) |
| 248 | + self.assertIsNone(feature) |
| 249 | + |
| 250 | + # def test_11_create_update_farmer_with_existing_individual(self): |
| 251 | + # """Test creating/updating farmer when individual already exists""" |
| 252 | + # # Set existing individual |
| 253 | + # self.farm.farmer_individual_id = self.individual.id |
| 254 | + |
| 255 | + # # Update farmer details |
| 256 | + # self.farm.farmer_family_name = "Updated" |
| 257 | + # self.farm.farmer_given_name = "Name" |
| 258 | + |
| 259 | + # # Call the method |
| 260 | + # self.farm.create_update_farmer(self.farm) |
| 261 | + |
| 262 | + # # Verify individual was updated |
| 263 | + # self.assertEqual(self.individual2.family_name, "Updated") |
| 264 | + # self.assertEqual(self.individual2.given_name, "Name") |
| 265 | + |
| 266 | + def test_12_create_update_farmer_with_additional_name(self): |
| 267 | + """Test creating farmer with additional name""" |
| 268 | + farm_with_addl_name = self.env["res.partner"].create( |
| 269 | + { |
| 270 | + "name": "Farm With Additional Name", |
| 271 | + "is_group": True, |
| 272 | + "is_registrant": True, |
| 273 | + "farmer_family_name": "Smith", |
| 274 | + "farmer_given_name": "John", |
| 275 | + "farmer_addtnl_name": "Middle", |
| 276 | + "farmer_mobile_tel": "09111111111", |
| 277 | + "farmer_national_id": "111222333", |
| 278 | + "farmer_sex": self.gender_male.id, |
| 279 | + "farm_detail_id": self.farm_details.id, |
| 280 | + "farm_land_rec_id": self.land_record.id, |
| 281 | + "farmer_id": self.farmer.id, |
| 282 | + } |
| 283 | + ) |
| 284 | + |
| 285 | + farm_with_addl_name.create_update_farmer(farm_with_addl_name) |
| 286 | + |
| 287 | + # Verify individual was created with correct name |
| 288 | + self.assertTrue(farm_with_addl_name.farmer_individual_id) |
| 289 | + individual = farm_with_addl_name.farmer_individual_id |
| 290 | + self.assertEqual(individual.family_name, "Smith") |
| 291 | + self.assertEqual(individual.given_name, "John") |
| 292 | + self.assertEqual(individual.addl_name, "Middle") |
| 293 | + self.assertEqual(individual.name, "Smith, John Middle") |
| 294 | + |
| 295 | + def test_13_insert_phone_number_empty(self): |
| 296 | + """Test inserting empty phone number""" |
| 297 | + # Should not create phone record for empty number |
| 298 | + self.farm.insert_phone_number(self.individual.id, "") |
| 299 | + |
| 300 | + phone_record = self.env["g2p.phone.number"].search([("partner_id", "=", self.individual.id)], limit=1) |
| 301 | + |
| 302 | + self.assertFalse(phone_record) |
| 303 | + |
| 304 | + def test_14_insert_id_empty(self): |
| 305 | + """Test inserting empty national ID""" |
| 306 | + # Should not create ID record for empty value |
| 307 | + self.farm.insert_id(self.individual.id, "") |
| 308 | + |
| 309 | + id_record = self.env["g2p.reg.id"].search( |
| 310 | + [("partner_id", "=", self.individual.id), ("id_type", "=", self.national_id_type.id)], limit=1 |
| 311 | + ) |
| 312 | + |
| 313 | + self.assertFalse(id_record) |
| 314 | + |
| 315 | + def test_15_update_farmer_no_phone_or_id(self): |
| 316 | + """Test updating farmer when individual has no phone or ID""" |
| 317 | + # Create farmer record for individual |
| 318 | + individual_farmer = self.env["spp.farmer"].create( |
| 319 | + {"farmer_family_name": "Individual", "farmer_given_name": "Farmer"} |
| 320 | + ) |
| 321 | + self.individual.farmer_id = individual_farmer.id |
| 322 | + |
| 323 | + # Update farmer (should handle missing phone/ID gracefully) |
| 324 | + self.farm.update_farmer(self.individual) |
| 325 | + |
| 326 | + # Verify farmer record was updated with basic info |
| 327 | + self.assertEqual(individual_farmer.farmer_family_name, "Franco") |
| 328 | + self.assertEqual(individual_farmer.farmer_given_name, "Chin") |
| 329 | + |
| 330 | + def test_16_farm_with_coordinates_geojson(self): |
| 331 | + """Test GeoJSON generation with farm coordinates""" |
| 332 | + # Set coordinates using proper GeoJSON format |
| 333 | + self.farm.coordinates = '{"type": "Point", "coordinates": [2.0, 3.0]}' |
| 334 | + |
| 335 | + geojson = self.farm.get_geojson() |
| 336 | + geojson_data = json.loads(geojson) |
| 337 | + |
| 338 | + # Should have at least one feature |
| 339 | + self.assertGreater(len(geojson_data["features"]), 0) |
| 340 | + |
| 341 | + # Check feature structure |
| 342 | + feature = geojson_data["features"][0] |
| 343 | + self.assertEqual(feature["type"], "Feature") |
| 344 | + self.assertIn("geometry", feature) |
| 345 | + self.assertIn("properties", feature) |
| 346 | + self.assertEqual(feature["properties"]["name"], "Test Farm") |
| 347 | + |
| 348 | + def test_17_farm_without_coordinates_geojson(self): |
| 349 | + """Test GeoJSON generation without farm coordinates""" |
| 350 | + # Remove coordinates |
| 351 | + self.farm.coordinates = False |
| 352 | + |
| 353 | + geojson = self.farm.get_geojson() |
| 354 | + geojson_data = json.loads(geojson) |
| 355 | + |
| 356 | + # Should still have FeatureCollection structure |
| 357 | + self.assertEqual(geojson_data["type"], "FeatureCollection") |
| 358 | + self.assertIn("features", geojson_data) |
| 359 | + # But may have no features if no coordinates |
| 360 | + self.assertIsInstance(geojson_data["features"], list) |
0 commit comments