summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMqdd <ahmadmiqdad27@gmail.com>2025-12-05 16:46:24 +0700
committerMqdd <ahmadmiqdad27@gmail.com>2025-12-05 16:46:24 +0700
commit8ee7bd9211a75809e1819de32ddf974c3736ebde (patch)
treef1b25d2793c823597d7ff1efae16002c6228f24c
parent28355b77ffedbc87f9e8f211e2fed91c15022e4c (diff)
<Miqdad> Initial COmmit baru
-rwxr-xr-xindoteknik_custom/__manifest__.py5
-rwxr-xr-xindoteknik_custom/models/__init__.py1
-rw-r--r--indoteknik_custom/models/keywords.py52
-rwxr-xr-xindoteknik_custom/models/product_template.py171
-rwxr-xr-xindoteknik_custom/security/ir.model.access.csv1
-rw-r--r--indoteknik_custom/views/find_page.xml2
-rw-r--r--indoteknik_custom/views/keywords.xml55
7 files changed, 198 insertions, 89 deletions
diff --git a/indoteknik_custom/__manifest__.py b/indoteknik_custom/__manifest__.py
index 66962a24..dcb23344 100755
--- a/indoteknik_custom/__manifest__.py
+++ b/indoteknik_custom/__manifest__.py
@@ -90,7 +90,7 @@
'views/product_sla.xml',
'views/voucher.xml',
'views/bill_receipt.xml',
- 'views/account_financial_report_view.xml',
+ 'views/account_financial_report_view.xml',
'views/account_report_general_ledger_view.xml',
'views/account_move_multi_update.xml',
'views/airway_bill.xml',
@@ -192,7 +192,8 @@
'views/close_tempo_mail_template.xml',
'views/domain_apo.xml',
'views/uom_uom.xml',
- 'views/commission_internal.xml'
+ 'views/commission_internal.xml',
+ 'views/keywords.xml'
],
'demo': [],
'css': [],
diff --git a/indoteknik_custom/models/__init__.py b/indoteknik_custom/models/__init__.py
index a14c766e..328c76b0 100755
--- a/indoteknik_custom/models/__init__.py
+++ b/indoteknik_custom/models/__init__.py
@@ -165,3 +165,4 @@ from . import partial_delivery
from . import domain_apo
from . import uom_uom
from . import commission_internal
+from . import keywords
diff --git a/indoteknik_custom/models/keywords.py b/indoteknik_custom/models/keywords.py
new file mode 100644
index 00000000..38b6e2fe
--- /dev/null
+++ b/indoteknik_custom/models/keywords.py
@@ -0,0 +1,52 @@
+from itertools import product
+from odoo import fields, models, api, tools, _
+import logging
+import re
+import pysolr
+from odoo.exceptions import UserError
+import base64
+import xlrd, xlwt
+import io
+
+
+_logger = logging.getLogger(__name__)
+
+class Keywords(models.Model):
+ _name = 'keywords'
+ _order= 'id desc'
+
+ category_id = fields.Many2one('product.public.category', string='Category')
+ keywords = fields.Char('Keywords')
+ product_ids = fields.One2many('product.product', 'keyword_id', string='Products')
+
+ @api.constrains('product_ids', 'keywords', 'category_id')
+ def action_generate_products(self):
+ for record in self:
+ if not record.keywords:
+ continue
+
+ domain = [
+ ('name', 'ilike', record.keywords),
+ ('product_rating', '>=', 8),
+ ('unpublish', '=', False)
+ ]
+
+ # if record.category_id:
+ # domain += [(record.product_ids.id, 'in', record.category_id.id)]
+
+ matched_products = self.env['product.product'].search(domain)
+
+ record.product_ids = [(6, 0, matched_products.ids)]
+
+ _logger.info('Generated %s products for keyword "%s"', len(matched_products), record.keywords)
+
+ @api.model
+ def create(self, vals):
+ record = super().create(vals)
+ record.action_generate_products()
+ return record
+
+ def write(self, vals):
+ result = super().write(vals)
+ self.action_generate_products()
+ return result
diff --git a/indoteknik_custom/models/product_template.py b/indoteknik_custom/models/product_template.py
index ee33a185..400d31e0 100755
--- a/indoteknik_custom/models/product_template.py
+++ b/indoteknik_custom/models/product_template.py
@@ -68,7 +68,7 @@ class ProductTemplate(models.Model):
('sp', 'Spare Part'),
('acc', 'Accessories')
], string='Kind of', copy=False)
- sni = fields.Boolean(string='SNI')
+ sni = fields.Boolean(string='SNI')
tkdn = fields.Boolean(string='TKDN')
short_spesification = fields.Char(string='Short Spesification')
merchandise_ok = fields.Boolean(string='Product Promotion')
@@ -85,7 +85,7 @@ class ProductTemplate(models.Model):
raise UserError('Hanya MD yang bisa membuat Product')
result = super(ProductTemplate, self).create(vals)
return result
-
+
# def write(self, values):
# group_id = self.env.ref('indoteknik_custom.group_role_merchandiser').id
# users_in_group = self.env['res.users'].search([('groups_id', 'in', [group_id])])
@@ -112,7 +112,7 @@ class ProductTemplate(models.Model):
# qr_code_img = base64.b64encode(buffer.getvalue()).decode()
# rec.qr_code = qr_code_img
-
+
@api.constrains('name', 'internal_reference', 'x_manufacture')
def required_public_categ_ids(self):
for rec in self:
@@ -125,7 +125,7 @@ class ProductTemplate(models.Model):
def day_product_to_edit(self):
day_products = []
-
+
for product in self:
day_product = (product.write_date - product.create_date).days
day_products.append(day_product)
@@ -138,25 +138,25 @@ class ProductTemplate(models.Model):
variants = product.product_variant_ids
names = [x.name for x in variants] if variants else [product.name]
default_codes = [x.default_code for x in variants] if variants else [product.default_code]
-
+
domain = [
- ('default_code', '!=', False),
+ ('default_code', '!=', False),
('id', '!=', product.id),
- '|',
- ('name', 'in', names),
+ '|',
+ ('name', 'in', names),
('default_code', 'in', default_codes)
]
-
+
product_exist = self.search(domain, limit=1)
if len(product_exist) > 0:
raise UserError('Name atau Internal Reference sudah digunakan pada produk lain')
-
+
if self.env.user.is_purchasing_manager or self.env.user.is_editor_product or self.env.user.id in [1, 25]:
continue
-
+
if sum(product.day_product_to_edit()) > 0:
raise UserError('Produk ini tidak dapat diubah')
-
+
@api.constrains('name')
def _validate_name(self):
rule_regex = self.env['ir.config_parameter'].sudo().get_param('product.product.rule_name_regex') or ''
@@ -165,7 +165,7 @@ class ProductTemplate(models.Model):
pattern_suggest = rf"{rule_regex}"
suggest = ''.join(re.findall(pattern_suggest, self.name))
raise UserError(f'Contoh yang benar adalah {suggest}')
-
+
# def write(self, vals):
# if 'solr_flag' not in vals and self.solr_flag == 1:
# vals['solr_flag'] = 2
@@ -204,7 +204,7 @@ class ProductTemplate(models.Model):
def unlink(self):
if self._name == 'product.template':
raise UserError('Maaf anda tidak bisa delete product')
-
+
def update_new_product(self):
current_time = datetime.now()
delta_time = current_time - timedelta(days=30)
@@ -235,7 +235,7 @@ class ProductTemplate(models.Model):
for template in templates:
if not template.default_code:
template.default_code = 'IT.'+str(template.id)
-
+
for variant in template.product_variant_ids:
if not variant.default_code:
variant.default_code = 'ITV.%s' % str(variant.id)
@@ -327,7 +327,7 @@ class ProductTemplate(models.Model):
def _get_stock_website(self):
qty = self._get_stock_altama()
print(qty)
-
+
def get_stock_altama(self, item_code):
current_time = datetime.now()
current_time = current_time.strftime('%Y-%m-%d %H:%M:%S')
@@ -338,7 +338,7 @@ class ProductTemplate(models.Model):
token = token_data['access_token']
else:
token = token_data.access_token
-
+
url = "https://erpapi.altama.co.id/erp/api/stock/buffer/btob"
auth = "Bearer "+token
headers = {
@@ -352,7 +352,7 @@ class ProductTemplate(models.Model):
response = requests.post(url, headers=headers, json=json_data)
if response.status_code != 200:
return 0
-
+
datas = json.loads(response.text)['data']
qty = 0
for data in datas:
@@ -371,12 +371,12 @@ class ProductTemplate(models.Model):
data = {
'grant_type': 'client_credentials',
}
-
+
response = requests.post(url, headers=headers, data=data).json()
lookup_json = json.dumps(response, indent=4, sort_keys=True)
token = json.loads(lookup_json)['access_token']
expires_in = json.loads(lookup_json)['expires_in']
-
+
current_time = datetime.now()
delta_time = current_time + timedelta(seconds=int(expires_in))
@@ -392,18 +392,18 @@ class ProductTemplate(models.Model):
self.env['token.storage'].create([values])
return values
- # ==============================
+ # ==============================
def get_vendor_name(self, rec):
"""Get formatted name for vendor/supplier"""
return rec.name.name if rec.name else f"ID {rec.id}"
-
+
def get_attribute_line_name(self, rec):
"""Get formatted name for attribute line"""
if rec.attribute_id and rec.value_ids:
values = ", ".join(rec.value_ids.mapped('name'))
return f"{rec.attribute_id.name}: {values}"
return f"ID {rec.id}"
-
+
def _get_vendor_field_label(self, field_name):
"""Get human-readable label for vendor fields"""
field_labels = {
@@ -419,10 +419,10 @@ class ProductTemplate(models.Model):
'date_end': 'End Date',
'min_qty': 'Quantity'
}
- return field_labels.get(field_name, field_name.replace('_', ' ').title())
+ return field_labels.get(field_name, field_name.replace('_', ' ').title())
# ==============================
-
+
def _collect_old_values(self, vals):
"""Collect old values before write"""
return {
@@ -433,7 +433,7 @@ class ProductTemplate(models.Model):
}
for record in self
}
-
+
def _prepare_attribute_line_info(self):
"""Prepare attribute line info for logging and update comparison"""
line_info = {}
@@ -446,7 +446,7 @@ class ProductTemplate(models.Model):
'value_names': ", ".join(line.value_ids.mapped('name'))
}
return line_info
-
+
def _prepare_vendor_info(self):
"""Prepare vendor info for logging before they are deleted"""
vendor_info = {}
@@ -465,13 +465,13 @@ class ProductTemplate(models.Model):
'date_end': seller.date_end,
}
return vendor_info
-
+
# ==========================
-
+
def _get_context_with_all_info(self, vals):
"""Get context with all necessary info (attributes and vendors)"""
context = dict(self.env.context)
-
+
# Check for attribute line changes
if 'attribute_line_ids' in vals:
attribute_line_info = {}
@@ -479,7 +479,7 @@ class ProductTemplate(models.Model):
product_line_info = product._prepare_attribute_line_info()
attribute_line_info.update(product_line_info)
context['attribute_line_info'] = attribute_line_info
-
+
# Check for vendor changes - store both for deletion and for comparing old values
if 'seller_ids' in vals:
vendor_info = {}
@@ -488,18 +488,18 @@ class ProductTemplate(models.Model):
# For deletion logging
product_vendor_info = product._prepare_vendor_info()
vendor_info.update(product_vendor_info)
-
+
# For update comparison
product_vendor_old = product._prepare_vendor_info()
vendor_old_values.update(product_vendor_old)
-
+
context['vendor_info'] = vendor_info
context['vendor_old_values'] = vendor_old_values
-
+
return context
-
+
# ========================
-
+
def _log_image_changes(self, field_name, old_val, new_val):
"""Log image field changes"""
label_map = {
@@ -517,18 +517,18 @@ class ProductTemplate(models.Model):
elif old_val != new_val:
return f"<li><b>{label}</b>: image updated</li>"
return None
-
+
def _log_attribute_line_changes(self, commands):
"""Log changes to attribute lines with complete information"""
# Get stored info from context
stored_info = self.env.context.get('attribute_line_info', {})
-
+
for cmd in commands:
if cmd[0] == 0: # Add
new = self.env['product.template.attribute.line'].new(cmd[2])
attribute_name = new.attribute_id.name if new.attribute_id else 'Attribute'
values = ", ".join(new.value_ids.mapped('name')) if new.value_ids else ''
-
+
message = f"<b>Product Attribute</b>:<br/>{attribute_name} added<br/>"
if values:
message += f"Values: '{values}'"
@@ -537,7 +537,7 @@ class ProductTemplate(models.Model):
elif cmd[0] == 1: # Update
rec_id = cmd[1]
vals = cmd[2]
-
+
# Get old values from context
old_data = stored_info.get(rec_id, {})
if not old_data:
@@ -552,10 +552,10 @@ class ProductTemplate(models.Model):
'value_ids': [(v.id, v.name) for v in rec.value_ids],
'value_names': ", ".join(rec.value_ids.mapped('name'))
}
-
+
changes = []
attribute_name = old_data.get('attribute_name', 'Attribute')
-
+
# Check for attribute change
if 'attribute_id' in vals:
old_attr = old_data.get('attribute_name', '-')
@@ -567,7 +567,7 @@ class ProductTemplate(models.Model):
# Check for value changes
if 'value_ids' in vals:
old_vals = old_data.get('value_names', '')
-
+
# Parse the command for value_ids
new_value_ids = []
for value_cmd in vals['value_ids']:
@@ -579,14 +579,14 @@ class ProductTemplate(models.Model):
elif value_cmd[0] == 3: # Remove
# This is more complex, would need current state
pass
-
+
# Get new value names
if new_value_ids:
new_values = self.env['product.attribute.value'].browse(new_value_ids)
new_vals = ", ".join(new_values.mapped('name'))
else:
new_vals = ""
-
+
if old_vals != new_vals:
changes.append(f"Values: '{old_vals}' → '{new_vals}'")
@@ -596,7 +596,7 @@ class ProductTemplate(models.Model):
message += "<br/>".join(changes)
self.message_post(body=message)
- elif cmd[0] in (2, 3): # Remove
+ elif cmd[0] in (2, 3): # Remove
# Use info from stored data
line_data = stored_info.get(cmd[1])
if line_data:
@@ -610,7 +610,7 @@ class ProductTemplate(models.Model):
else:
attribute_name = 'Attribute'
values = f"ID {cmd[1]}"
-
+
message = f"<b>Product Attribute</b>:<br/>{attribute_name} removed<br/>"
if values:
message += f"Values: '{values}'"
@@ -618,25 +618,25 @@ class ProductTemplate(models.Model):
elif cmd[0] == 5: # Clear all
self.message_post(body=f"<b>Product Attribute</b>:<br/>All attributes removed")
-
+
def _log_vendor_pricelist_changes(self, commands):
"""Log changes to vendor pricelist with complete information"""
# Get stored info from context
stored_info = self.env.context.get('vendor_info', {})
old_values_info = self.env.context.get('vendor_old_values', {})
-
+
for cmd in commands:
if cmd[0] == 0: # Add
vals = cmd[2]
-
+
# Create temporary record to get proper display values
temp_values = vals.copy()
temp_values['product_tmpl_id'] = self.id
new = self.env['product.supplierinfo'].new(temp_values)
-
+
name = self.get_vendor_name(new)
details = []
-
+
if 'price' in vals and vals['price'] is not None:
details.append(f"<li>Price: {vals['price']}</li>")
if 'min_qty' in vals and vals['min_qty'] is not None:
@@ -653,18 +653,18 @@ class ProductTemplate(models.Model):
if 'product_uom' in vals and vals['product_uom']:
uom = self.env['uom.uom'].browse(vals['product_uom'])
details.append(f"<li>Unit of Measure: {uom.name}</li>")
-
+
if details:
detail_str = f" with:<ul>{''.join(details)}</ul>"
else:
detail_str = ""
-
+
self.message_post(body=f"<b>Vendor Pricelist</b>: added '{name}'{detail_str}")
-
+
elif cmd[0] == 1: # Update
rec_id = cmd[1]
vals = cmd[2]
-
+
# Get old values from context
old_data = old_values_info.get(rec_id, {})
if not old_data:
@@ -685,10 +685,10 @@ class ProductTemplate(models.Model):
'date_start': rec.date_start,
'date_end': rec.date_end,
}
-
+
name = old_data.get('name', f'ID {rec_id}')
changes = []
-
+
# Check each field in vals for changes
for field, new_value in vals.items():
if field == 'name':
@@ -698,9 +698,9 @@ class ProductTemplate(models.Model):
new_name = self.env['res.partner'].browse(new_value).name if new_value else 'None'
changes.append(f"<li>Vendor: {old_name} → {new_name}</li>")
continue
-
+
old_value = old_data.get(field)
-
+
# Format values based on field type
if field == 'currency_id':
if old_value != new_value:
@@ -732,14 +732,14 @@ class ProductTemplate(models.Model):
# Compare numeric values properly
old_num = float(old_value) if old_value is not None else 0.0
new_num = float(new_value) if new_value is not None else 0.0
-
+
if field == 'delay': # Integer field
old_num = int(old_num)
new_num = int(new_num)
-
+
if old_num == new_num:
continue
-
+
old_str = str(old_value) if old_value is not None else 'None'
new_str = str(new_value) if new_value is not None else 'None'
else:
@@ -748,20 +748,20 @@ class ProductTemplate(models.Model):
continue
old_str = str(old_value) if old_value is not None else 'None'
new_str = str(new_value) if new_value is not None else 'None'
-
+
label = self._get_vendor_field_label(field)
changes.append(f"<li>{label}: {old_str} → {new_str}</li>")
-
+
if changes:
changes_str = f"<ul>{''.join(changes)}</ul>"
self.message_post(body=f"<b>Vendor Pricelist</b>: updated '{name}':{changes_str}")
-
+
elif cmd[0] in (2, 3): # Remove
vendor_data = stored_info.get(cmd[1])
if vendor_data:
name = vendor_data['name']
details = []
-
+
if vendor_data.get('price'):
details.append(f"<li>Price: {vendor_data['price']}</li>")
if vendor_data.get('min_qty'):
@@ -770,7 +770,7 @@ class ProductTemplate(models.Model):
details.append(f"<li>Product Name: {vendor_data['product_name']}</li>")
if vendor_data.get('delay'):
details.append(f"<li>Delivery Lead Time: {vendor_data['delay']}</li>")
-
+
if details:
detail_str = f"<ul>{''.join(details)}</ul>"
else:
@@ -786,7 +786,7 @@ class ProductTemplate(models.Model):
details.append(f"<li>Quantity: {rec.min_qty}</li>")
if rec.product_name:
details.append(f"<li>Product Name: {rec.product_name}</li>")
-
+
if details:
detail_str = f"<ul>{''.join(details)}</ul>"
else:
@@ -794,12 +794,12 @@ class ProductTemplate(models.Model):
else:
name = f"ID {cmd[1]}"
detail_str = ""
-
+
self.message_post(body=f"<b>Vendor Pricelist</b>: removed '{name}'{detail_str}")
-
+
elif cmd[0] == 5: # Clear all
self.message_post(body=f"<b>Vendor Pricelist</b>: all removed")
-
+
def _log_field_changes_product(self, vals, old_values):
"""Revised - Log general field changes for product template without posting to variants"""
exclude_fields = ['solr_flag', 'desc_update_solr', 'last_update_solr', 'is_edited']
@@ -891,7 +891,7 @@ class ProductTemplate(models.Model):
# # raise UserError('Tidak dapat mengubah produk sementara')
# self._log_field_changes(vals)
# return super(ProductTemplate, self).write(vals)
-
+
class ProductProduct(models.Model):
_inherit = "product.product"
web_price = fields.Float(
@@ -929,6 +929,7 @@ class ProductProduct(models.Model):
qr_code_variant = fields.Binary("QR Code Variant", compute='_compute_qr_code_variant')
qty_pcs_box = fields.Float("Pcs Box")
barcode_box = fields.Char("Barcode Box")
+ keyword_id = fields.Many2one('keywords', string='Keyword')
def generate_product_sla(self):
product_variant_ids = self.env.context.get('active_ids', [])
@@ -951,7 +952,7 @@ class ProductProduct(models.Model):
raise UserError('Hanya MD yang bisa membuat Product')
result = super(ProductProduct, self).create(vals)
return result
-
+
# def write(self, values):
# group_id = self.env.ref('indoteknik_custom.group_role_merchandiser').id
# active_model = self.env.context.get('active_model')
@@ -967,7 +968,7 @@ class ProductProduct(models.Model):
if not rec.active:
rec.qr_code_variant = False # Clear the QR Code for archived variants
continue
-
+
qr = qrcode.QRCode(
version=1,
error_correction=qrcode.constants.ERROR_CORRECT_L,
@@ -1055,11 +1056,11 @@ class ProductProduct(models.Model):
if self.qty_available_bandengan < qty_purchase:
return 'harus beli'
return 'masih cukup'
-
+
def _get_qty_upcoming(self):
for product in self:
product.qty_upcoming = product.incoming_qty + product.qty_available
-
+
def _get_qty_sold(self):
for product in self:
order_line = self.env['sale.order.line'].search([
@@ -1070,13 +1071,13 @@ class ProductProduct(models.Model):
def day_product_to_edit(self):
day_products = []
-
+
for product in self:
day_product = (product.write_date - product.create_date).days
day_products.append(day_product)
return day_products
-
+
@api.constrains('name')
def _validate_name(self):
rule_regex = self.env['ir.config_parameter'].sudo().get_param('product.product.rule_name_regex') or ''
@@ -1085,7 +1086,7 @@ class ProductProduct(models.Model):
pattern_suggest = rf"{rule_regex}"
suggest = ''.join(re.findall(pattern_suggest, self.name))
raise UserError(f'Contoh yang benar adalah {suggest}')
-
+
def _get_qty_incoming_bandengan(self):
for product in self:
qty = self.env['v.move.outstanding'].read_group(
@@ -1207,11 +1208,11 @@ class ProductProduct(models.Model):
for product in self:
stock_vendor = self.env['stock.vendor'].search([('product_variant_id', '=', product.id)], limit=1)
product.qty_stock_vendor = stock_vendor.quantity + product.qty_available
-
+
def unlink(self):
if self._name == 'product.product':
raise UserError('Maaf anda tidak bisa delete product')
-
+
def _get_active_flash_sale(self):
current_time = datetime.now().strftime('%Y-%m-%d %H:%M:%S')
pricelist = self.env['product.pricelist'].search([
@@ -1237,7 +1238,7 @@ class ProductProduct(models.Model):
def _log_field_changes_product_variants(self, vals, old_values):
"""Revised - Log field changes for variants without posting to template"""
exclude_fields = ['solr_flag', 'desc_update_solr', 'last_update_solr', 'is_edited']
-
+
# Custom labels for image fields
custom_labels = {
'image_1920': 'Main Image',
@@ -1314,7 +1315,7 @@ class ProductProduct(models.Model):
'public_categ_ids', 'search_rank', 'search_rank_weekly',
'image_1920', 'unpublished', 'image_carousel_lines'
]
-
+
if any(field in vals for field in tracked_fields):
old_values = self._collect_old_values(vals)
result = super().write(vals)
@@ -1343,7 +1344,7 @@ class OutstandingMove(models.Model):
tools.drop_view_if_exists(self.env.cr, self._table)
self.env.cr.execute("""
CREATE OR REPLACE VIEW %s AS
- select sm.id, sm.reference, sm.product_id,
+ select sm.id, sm.reference, sm.product_id,
sm.product_uom_qty as qty_need,
sm.location_id, sm.location_dest_id,
sm.raw_material_production_id as mo_id,
diff --git a/indoteknik_custom/security/ir.model.access.csv b/indoteknik_custom/security/ir.model.access.csv
index bc8dc2a4..796e5275 100755
--- a/indoteknik_custom/security/ir.model.access.csv
+++ b/indoteknik_custom/security/ir.model.access.csv
@@ -214,3 +214,4 @@ access_surat_piutang_user,surat.piutang user,model_surat_piutang,,1,1,1,1
access_surat_piutang_line_user,surat.piutang.line user,model_surat_piutang_line,,1,1,1,1
access_sj_tele,access.sj.tele,model_sj_tele,base.group_system,1,1,1,1
access_stock_picking_sj_document,stock.picking.sj.document,model_stock_picking_sj_document,base.group_user,1,1,1,1
+access_keywords,keywords,model_keywords,base.group_user,1,1,1,1
diff --git a/indoteknik_custom/views/find_page.xml b/indoteknik_custom/views/find_page.xml
index e333559e..fc9bddbb 100644
--- a/indoteknik_custom/views/find_page.xml
+++ b/indoteknik_custom/views/find_page.xml
@@ -7,7 +7,6 @@
<tree>
<field name="category_id"/>
<field name="brand_id"/>
- <field name="keywords"/>
<field name="url"/>
<field name="create_uid"/>
<field name="write_uid"/>
@@ -26,7 +25,6 @@
<group>
<field name="category_id"/>
<field name="brand_id"/>
- <field name="keywords"/>
<field name="url" />
</group>
<group>
diff --git a/indoteknik_custom/views/keywords.xml b/indoteknik_custom/views/keywords.xml
new file mode 100644
index 00000000..872887a7
--- /dev/null
+++ b/indoteknik_custom/views/keywords.xml
@@ -0,0 +1,55 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<odoo>
+<record id="keywords_tree" model="ir.ui.view">
+ <field name="name">keywords.tree</field>
+ <field name="model">keywords</field>
+ <field name="arch" type="xml">
+ <tree >
+ <field name="category_id" />
+ <field name="keywords" />
+ <field name="product_ids" widget="many2many_tags" />
+ </tree>
+ </field>
+</record>
+
+<record id="keywords_form" model="ir.ui.view">
+ <field name="name">keywords.form</field>
+ <field name="model">keywords</field>
+ <field name="arch" type="xml">
+ <form>
+ <sheet>
+ <group>
+ <field name="category_id" />
+ <field name="keywords" />
+ <field name="product_ids" widget="many2many_tags" />
+ </group>
+ </sheet>
+ </form>
+ </field>
+</record>
+
+<record id="view_keywords_filter" model="ir.ui.view">
+ <field name="name">keywords.list.select</field>
+ <field name="model">keywords</field>
+ <field name="priority" eval="15"/>
+ <field name="arch" type="xml">
+ <search string="Search Keywords">
+ <field name="category_id"/>
+ <field name="keywords"/>
+ <field name="product_ids" widget="many2many_tags"/>
+ </search>
+ </field>
+</record>
+<record id="action_keywords" model="ir.actions.act_window">
+ <field name="name">Keywords</field>
+ <field name="type">ir.actions.act_window</field>
+ <field name="res_model">keywords</field>
+ <field name="search_view_id" ref="view_keywords_filter"/>
+ <field name="view_mode">tree,form</field>
+ </record>
+<menuitem id="menu_keywords"
+ name="Keywords"
+ parent="website_sale.menu_orders"
+ action="action_keywords"
+ sequence="100"/>
+</odoo>