summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIndoteknik . <it@fixcomart.co.id>2025-06-12 19:26:46 +0700
committerIndoteknik . <it@fixcomart.co.id>2025-06-12 19:26:46 +0700
commita921017a829ebef8442740fac964260d98566e6a (patch)
tree8954724c74fc7e5cfe6d9387b9113854863e6b82
parent8ac5d556a6686c6b81d5e9178bff5d308e8f176f (diff)
(andri) try gmaps sebagai pengganti openstreetmaps
-rw-r--r--ab_openstreetmap/__manifest__.py2
-rw-r--r--ab_openstreetmap/static/src/js/googlemap_widget.js115
-rw-r--r--ab_openstreetmap/static/src/js/openstreetmap_widget.js106
-rw-r--r--ab_openstreetmap/static/src/xml/googlemap_template.xml8
-rw-r--r--ab_openstreetmap/static/src/xml/openstreetmap_template.xml8
-rw-r--r--ab_openstreetmap/views/templates.xml24
-rw-r--r--indoteknik_api/controllers/api_v1/partner.py2
-rw-r--r--indoteknik_custom/models/res_partner.py77
-rw-r--r--indoteknik_custom/views/res_partner.xml5
9 files changed, 217 insertions, 130 deletions
diff --git a/ab_openstreetmap/__manifest__.py b/ab_openstreetmap/__manifest__.py
index 745e57ab..9d76c34c 100644
--- a/ab_openstreetmap/__manifest__.py
+++ b/ab_openstreetmap/__manifest__.py
@@ -12,6 +12,6 @@
'category': 'Uncategorized',
'version': '0.1',
'depends': ['base'],
- "qweb": ['static/src/xml/openstreetmap_template.xml'],
+ "qweb": ['static/src/xml/googlemap_template.xml'],
'data': ['views/templates.xml'],
}
diff --git a/ab_openstreetmap/static/src/js/googlemap_widget.js b/ab_openstreetmap/static/src/js/googlemap_widget.js
new file mode 100644
index 00000000..2c639bc3
--- /dev/null
+++ b/ab_openstreetmap/static/src/js/googlemap_widget.js
@@ -0,0 +1,115 @@
+odoo.define("ab_openstreetmap.googlemap_widget", function (require) {
+ "use strict";
+
+ const AbstractField = require("web.AbstractField");
+ const fieldRegistry = require("web.field_registry");
+ const rpc = require("web.rpc");
+
+ const GoogleMapWidget = AbstractField.extend({
+ template: "googlemap_template",
+
+ start: async function () {
+ await this._super(...arguments);
+
+ const apiKey = await rpc.query({
+ model: "ir.config_parameter",
+ method: "get_param",
+ args: ["google.maps.api_key"],
+ });
+
+ this._waitForMapReady(apiKey);
+ },
+
+ _waitForMapReady(apiKey) {
+ const checkReady = () => {
+ const el = document.getElementById("mapid");
+ if (el && el.offsetHeight > 0 && el.offsetWidth > 0) {
+ this._loadGoogleMaps(apiKey);
+ } else {
+ setTimeout(checkReady, 150);
+ }
+ };
+ checkReady();
+ },
+
+ _loadGoogleMaps(apiKey) {
+ if (!window.google || !window.google.maps) {
+ const script = document.createElement("script");
+ script.src = `https://maps.googleapis.com/maps/api/js?key=${apiKey}&libraries=marker`;
+ script.async = true;
+ script.defer = true;
+ script.onload = this._initMap.bind(this);
+ document.head.appendChild(script);
+ } else {
+ this._initMap();
+ }
+ },
+
+ _initMap() {
+ const lat = parseFloat(this.recordData.latitude) || -6.2;
+ const lng = parseFloat(this.recordData.longtitude) || 106.816666;
+ const isEditable = this.mode === "edit";
+
+ const map = new google.maps.Map(document.getElementById("mapid"), {
+ center: { lat, lng },
+ zoom: 15,
+ });
+
+ // Use AdvancedMarkerElement if available
+ if (google.maps.marker && google.maps.marker.AdvancedMarkerElement) {
+ const { AdvancedMarkerElement } = google.maps.marker;
+
+ const marker = new AdvancedMarkerElement({
+ position: { lat, lng },
+ map: map,
+ gmpDraggable: isEditable,
+ });
+
+ if (isEditable) {
+ marker.addListener("dragend", (e) => {
+ const newLat = e.latLng.lat();
+ const newLng = e.latLng.lng();
+ this._saveCoords(newLat, newLng);
+ });
+ }
+ } else {
+ const marker = new google.maps.Marker({
+ position: { lat, lng },
+ map: map,
+ draggable: isEditable,
+ });
+
+ if (isEditable) {
+ marker.addListener("dragend", (e) => {
+ const newLat = e.latLng.lat();
+ const newLng = e.latLng.lng();
+ this._saveCoords(newLat, newLng);
+ });
+ }
+ }
+
+ // Handle resize if tab is hidden initially
+ setTimeout(() => {
+ google.maps.event.trigger(map, "resize");
+ map.setCenter({ lat, lng });
+ }, 500);
+ },
+
+ _saveCoords(lat, lng) {
+ this.trigger_up("field_changed", {
+ dataPointID: this.dataPointID,
+ changes: {
+ latitude: lat.toString(),
+ longtitude: lng.toString(),
+ },
+ viewType: this.viewType,
+ });
+ },
+
+ isSet() {
+ return true;
+ },
+ });
+
+ fieldRegistry.add("googlemap", GoogleMapWidget);
+});
diff --git a/ab_openstreetmap/static/src/js/openstreetmap_widget.js b/ab_openstreetmap/static/src/js/openstreetmap_widget.js
deleted file mode 100644
index c84a2293..00000000
--- a/ab_openstreetmap/static/src/js/openstreetmap_widget.js
+++ /dev/null
@@ -1,106 +0,0 @@
-odoo.define("ab_openstreetmap.openstreetmap_widget", function (require) {
- "use strict";
-
- const fieldRegistry = require("web.field_registry");
- const AbstractField = require("web.AbstractField");
-
- const OpenStreetMapWidget = AbstractField.extend({
- template: "openstreetmap_template",
-
- start: function () {
- const self = this;
- return this._super.apply(this, arguments).then(() => {
- setTimeout(() => {
- self._renderMapWhenReady();
- }, 100);
- });
- },
-
- _renderMapWhenReady: function () {
- const self = this;
- const check = () => {
- const container = document.getElementById("mapid");
- if (container && container.offsetWidth > 0 && container.offsetHeight > 0) {
- self._initMap();
- } else {
- setTimeout(check, 100);
- }
- };
- check();
- },
-
- _initMap: function () {
- const self = this;
- const container = document.getElementById("mapid");
-
- // Bersihkan Leaflet instance sebelumnya jika ada
- if (container && container._leaflet_id) {
- container._leaflet_id = null;
- }
-
- let lat = self.recordData.latitude;
- let lng = self.recordData.longtitude;
-
- if (!lat && !lng) {
- lat = -6.2349;
- lng = 106.9896;
- }
-
- const map = L.map("mapid").setView([lat, lng], 13);
-
- L.tileLayer("https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png", {
- attribution:
- '&copy; <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors',
- }).addTo(map);
-
- const edit = self.mode === "edit";
- const marker = L.marker([lat, lng], { draggable: edit }).addTo(map);
-
- // Simpan koordinat saat marker digeser
- marker.on("dragend", function (e) {
- const latlng = e.target._latlng;
- self.trigger_up("field_changed", {
- dataPointID: self.dataPointID,
- changes: {
- latitude: latlng.lat.toString(),
- longtitude: latlng.lng.toString(),
- },
- viewType: self.viewType,
- });
- });
-
- // Fitur cari lokasi (geocoder)
- if (edit) {
- const geocode = L.Control.geocoder({ defaultMarkGeocode: false }).addTo(map);
- geocode.on("markgeocode", function (e) {
- const lat = e.geocode.center.lat;
- const lng = e.geocode.center.lng;
- map.flyTo([lat, lng]);
- marker.setLatLng(new L.LatLng(lat, lng));
- self.trigger_up("field_changed", {
- dataPointID: self.dataPointID,
- changes: {
- latitude: lat.toString(),
- longtitude: lng.toString(),
- },
- viewType: self.viewType,
- });
- });
- }
-
- // Force render ulang map
- const interval = setInterval(() => {
- if (map && map._size.x > 0) {
- clearInterval(interval);
- }
- window.dispatchEvent(new Event("resize"));
- }, 500);
- },
-
- isSet: function () {
- return true;
- },
- });
-
- fieldRegistry.add("openstreetmap", OpenStreetMapWidget);
-});
diff --git a/ab_openstreetmap/static/src/xml/googlemap_template.xml b/ab_openstreetmap/static/src/xml/googlemap_template.xml
new file mode 100644
index 00000000..845be418
--- /dev/null
+++ b/ab_openstreetmap/static/src/xml/googlemap_template.xml
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<templates id="template" xml:space="preserve">
+ <t t-name="googlemap_template">
+ <div class="o_google_map_wrapper" style="height: 400px; width: 100%;">
+ <div id="mapid" style="height: 100%; width: 100%;"></div>
+ </div>
+ </t>
+</templates>
diff --git a/ab_openstreetmap/static/src/xml/openstreetmap_template.xml b/ab_openstreetmap/static/src/xml/openstreetmap_template.xml
deleted file mode 100644
index 82672748..00000000
--- a/ab_openstreetmap/static/src/xml/openstreetmap_template.xml
+++ /dev/null
@@ -1,8 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<templates id="template" xml:space="preserve">
- <t t-name="openstreetmap_template">
- <div style="width:100%">
- <div id="mapid" style="height: 500px;"/>
- </div>
- </t>
-</templates> \ No newline at end of file
diff --git a/ab_openstreetmap/views/templates.xml b/ab_openstreetmap/views/templates.xml
index ed82ae84..57357bda 100644
--- a/ab_openstreetmap/views/templates.xml
+++ b/ab_openstreetmap/views/templates.xml
@@ -1,13 +1,13 @@
<odoo>
- <data>
- <template id="assets_backend" inherit_id="web.assets_backend">
- <xpath expr="." position="inside">
- <link rel="stylesheet" href="https://unpkg.com/leaflet@1.7.1/dist/leaflet.css" integrity="sha512-xodZBNTC5n17Xt2atTPuE1HxjVMSvLVW9ocqUKLsCC5CXdbqCmblAshOMAS6/keqq/sMZMZ19scR4PsZChSR7A==" crossorigin=""/>
- <script src="https://unpkg.com/leaflet@1.7.1/dist/leaflet.js" integrity="sha512-XQoYMqMTK8LvdxXYG3nZ448hOEQiglfqkJs1NOQV44cWnUrBc8PkAOcXy20w0vlaXaVUearIOBhiXZ5V3ynxwA==" crossorigin=""></script>
- <link rel="stylesheet" href="https://unpkg.com/leaflet-control-geocoder/dist/Control.Geocoder.css" />
- <script src="https://unpkg.com/leaflet-control-geocoder/dist/Control.Geocoder.js"></script>
- <script type="text/javascript" src="/ab_openstreetmap/static/src/js/openstreetmap_widget.js"/>
- </xpath>
- </template>
- </data>
-</odoo> \ No newline at end of file
+ <data>
+ <template id="assets_backend" inherit_id="web.assets_backend">
+ <xpath expr="." position="inside">
+ <!-- Tambahkan Google Maps API Key -->
+ <script src="https://maps.googleapis.com/maps/api/js?key=AIzaSyB7bG9aSNAJnSrj0Z7f1abFsqKVoiJfsPE&amp;libraries=places" async="true" defer="true"/>
+
+ <!-- Tambahkan JS Widget -->
+ <script type="text/javascript" src="/ab_openstreetmap/static/src/js/googlemap_widget.js"/>
+ </xpath>
+ </template>
+ </data>
+</odoo>
diff --git a/indoteknik_api/controllers/api_v1/partner.py b/indoteknik_api/controllers/api_v1/partner.py
index c0f8f630..37ae8d5f 100644
--- a/indoteknik_api/controllers/api_v1/partner.py
+++ b/indoteknik_api/controllers/api_v1/partner.py
@@ -1,6 +1,6 @@
from .. import controller
from odoo import http
-from odoo.http import request
+from odoo.http import request, Response
from odoo import fields
import json
import base64
diff --git a/indoteknik_custom/models/res_partner.py b/indoteknik_custom/models/res_partner.py
index eeb8b67d..82aa1134 100644
--- a/indoteknik_custom/models/res_partner.py
+++ b/indoteknik_custom/models/res_partner.py
@@ -4,6 +4,8 @@ from datetime import datetime
from odoo.http import request
import re
import requests
+import logging
+_logger = logging.getLogger(__name__)
class GroupPartner(models.Model):
_name = 'group.partner'
@@ -583,3 +585,78 @@ class ResPartner(models.Model):
raise UserError("Tidak ditemukan hasil geocode untuk alamat tersebut.")
else:
raise UserError("Permintaan ke Google Maps gagal. Periksa koneksi internet atau API Key.")
+
+ # def _update_address_from_coords(self):
+ # for rec in self:
+ # if rec.latitude and rec.longtitude:
+ # address = self.reverse_geocode(rec.latitude, rec.longtitude)
+ # if not address:
+ # continue
+
+ # updates = {
+ # 'street': address.get('road') or '',
+ # 'zip': address.get('postcode') or '',
+ # 'city': address.get('city') or address.get('town') or address.get('village') or '',
+ # }
+
+ # # Kelurahan (vit.kelurahan)
+ # if address.get('suburb'):
+ # kel = self.env['vit.kelurahan'].search([
+ # ('name', 'ilike', address['suburb'])
+ # ], limit=1)
+ # if kel:
+ # updates['kelurahan_id'] = kel.id
+
+ # # Kecamatan (vit.kecamatan)
+ # kec_nama = address.get('district') or address.get('village')
+ # if kec_nama:
+ # kec = self.env['vit.kecamatan'].search([
+ # ('name', 'ilike', kec_nama)
+ # ], limit=1)
+ # if kec:
+ # updates['kecamatan_id'] = kec.id
+
+ # # Kota (vit.kota)
+ # kota_nama = address.get('city') or address.get('town')
+ # if kota_nama:
+ # kota = self.env['vit.kota'].search([
+ # ('name', 'ilike', kota_nama)
+ # ], limit=1)
+ # if kota:
+ # updates['kota_id'] = kota.id
+
+ # # Provinsi (res.country.state)
+ # if address.get('state'):
+ # state = self.env['res.country.state'].search([
+ # ('name', 'ilike', address['state'])
+ # ], limit=1)
+ # if state:
+ # updates['state_id'] = state.id
+
+ # # Negara (res.country)
+ # if address.get('country_code'):
+ # country = self.env['res.country'].search([
+ # ('code', '=', address['country_code'].upper())
+ # ], limit=1)
+ # if country:
+ # updates['country_id'] = country.id
+
+ # rec.write(updates)
+
+
+
+ # def reverse_geocode(self, lat, lon):
+ # try:
+ # url = f'https://nominatim.openstreetmap.org/reverse?format=jsonv2&lat={lat}&lon={lon}'
+ # headers = {
+ # 'User-Agent': 'Odoo/1.0 (andrifebriyadiputra@gmail.com)', # WAJIB: ganti dengan email domain kamu
+ # }
+ # response = requests.get(url, headers=headers, timeout=5)
+ # if response.ok:
+ # data = response.json()
+ # return data.get('address', {})
+ # else:
+ # _logger.warning("Reverse geocode failed with status %s: %s", response.status_code, response.text)
+ # except Exception as e:
+ # _logger.exception("Exception during reverse geocode: %s", e)
+ # return {}
diff --git a/indoteknik_custom/views/res_partner.xml b/indoteknik_custom/views/res_partner.xml
index 85ee5ef0..4cee0c47 100644
--- a/indoteknik_custom/views/res_partner.xml
+++ b/indoteknik_custom/views/res_partner.xml
@@ -66,14 +66,15 @@
<field name="leadtime"/>
</group>
<xpath expr="//notebook/page[@name='contact_addresses']" position="before">
- <page string="Pin Point Location" name="map_location">
+ <page string="Pin Point Location" name="map_location" autofocus="autofocus">
<group>
<button name="geocode_address" type="object" string="Get Pin Point Location" class="btn btn-primary"/>
</group>
<div style="margin: 16px 0;">
- <field name="map_view" widget="openstreetmap" nolabel="1" style="width: 100%;"/>
+ <field name="map_view" widget="googlemap" nolabel="1"/>
</div>
<group>
+ <field name="address_map"/>
<field name="latitude" readonly="1"/>
<field name="longtitude" readonly="1"/>
</group>