summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIT Fixcomart <it@fixcomart.co.id>2023-01-23 09:20:18 +0000
committerIT Fixcomart <it@fixcomart.co.id>2023-01-23 09:20:18 +0000
commitda5f5134f56b2ccf1c1de16c3f7616ab3719f3ea (patch)
treebc1bcb4fb00f2659be81810d528a9cf2cc6ce20d
parente52cf84fd2284330412162b44066f29bd382f590 (diff)
parent8af5ee591aabc2d5d946c0eece93a5caab989975 (diff)
Merged in release (pull request #27)
Release
-rw-r--r--indoteknik_api/controllers/api_v1/category.py3
-rw-r--r--indoteknik_api/controllers/api_v1/content.py20
-rw-r--r--indoteknik_api/controllers/api_v1/customer.py38
-rw-r--r--indoteknik_api/controllers/api_v1/product.py68
-rw-r--r--indoteknik_api/models/product_product.py8
-rw-r--r--indoteknik_api/models/product_template.py13
-rw-r--r--indoteknik_api/models/x_manufactures.py6
-rwxr-xr-xindoteknik_custom/__manifest__.py1
-rwxr-xr-xindoteknik_custom/models/__init__.py1
-rwxr-xr-xindoteknik_custom/models/crm_lead.py9
-rw-r--r--indoteknik_custom/models/dunning_run.py76
-rw-r--r--indoteknik_custom/models/ir_attachment.py15
-rwxr-xr-xindoteknik_custom/models/product_template.py51
-rwxr-xr-xindoteknik_custom/models/sale_order.py4
-rw-r--r--indoteknik_custom/models/sales_target.py20
-rwxr-xr-xindoteknik_custom/models/stock_vendor.py36
-rwxr-xr-xindoteknik_custom/models/user_activity_log.py31
-rw-r--r--indoteknik_custom/models/website_ads.py18
-rwxr-xr-xindoteknik_custom/security/ir.model.access.csv3
-rw-r--r--indoteknik_custom/views/dunning_run.xml31
-rw-r--r--indoteknik_custom/views/sales_target.xml22
-rwxr-xr-xindoteknik_custom/views/stock_vendor.xml2
-rw-r--r--indoteknik_custom/views/website_ads.xml69
-rwxr-xr-xindoteknik_custom/views/x_manufactures.xml2
24 files changed, 448 insertions, 99 deletions
diff --git a/indoteknik_api/controllers/api_v1/category.py b/indoteknik_api/controllers/api_v1/category.py
index 36e67e01..62faff85 100644
--- a/indoteknik_api/controllers/api_v1/category.py
+++ b/indoteknik_api/controllers/api_v1/category.py
@@ -35,7 +35,8 @@ class Category(controller.Controller):
'name': category.category_id.name,
'image': base_url + 'api/image/website.categories.homepage/image/' + str(category.id) if category.image else '',
'url': category.url,
- 'brands': [y.x_name for y in brands],
+ # 'brands': [y.x_name for y in brands],
+ 'brands': [request.env['x_manufactures'].api_single_response(y) for y in brands],
'products': [request.env['product.template'].api_single_response(x) for x in products]
})
return self.response(data)
diff --git a/indoteknik_api/controllers/api_v1/content.py b/indoteknik_api/controllers/api_v1/content.py
index 3d5b15e5..3d4e443a 100644
--- a/indoteknik_api/controllers/api_v1/content.py
+++ b/indoteknik_api/controllers/api_v1/content.py
@@ -6,6 +6,26 @@ from odoo.http import request
class WebsiteContent(controller.Controller):
prefix = '/api/v1/'
+ @http.route(prefix + 'product_ads', auth='public', methods=['GET', 'OPTIONS'])
+ def get_product_ads(self, **kw):
+ if not self.authenticate():
+ return self.response(code=401, description='Unauthorized')
+ base_url = request.env['ir.config_parameter'].get_param('web.base.url')
+ query = [
+ ('page', '=', 'product'),
+ ('status', '=', 'tayang')
+ ]
+ ads = request.env['website.ads'].search(query, order='sequence')
+ data = []
+ for ad in ads:
+ data.append({
+ 'id': ad.id,
+ 'name': ad.name,
+ 'image': base_url + 'api/image/website.ads/image/' + str(ad.id) if ad.image else '',
+ 'url': ad.url,
+ })
+ return self.response(data)
+
@http.route(prefix + 'video_content', auth='public', methods=['GET', 'OPTIONS'])
def get_video_content(self, **kw):
if not self.authenticate():
diff --git a/indoteknik_api/controllers/api_v1/customer.py b/indoteknik_api/controllers/api_v1/customer.py
index f6d6d40d..57120751 100644
--- a/indoteknik_api/controllers/api_v1/customer.py
+++ b/indoteknik_api/controllers/api_v1/customer.py
@@ -7,6 +7,44 @@ import ast
class CustomerReview(controller.Controller):
prefix = '/api/v1/'
+ @http.route(prefix + 'last_seen_products', auth='public', methods=['GET', 'OPTIONS'])
+ def get_last_seen_products(self, **kw):
+ if not self.authenticate():
+ return self.response(code=401, description='Unauthorized')
+
+ email = str(kw.get('email', ''))
+ if not email:
+ return self.response(code=401, description='Unauthorized')
+
+ activity_logs = request.env['user.activity.log'].search([
+ ('url', 'ilike', 'https://indoteknik.co%/shop/product/%'),
+ ('email', '=', email),
+ ], order='create_date desc', limit=5)
+
+ data = []
+ templates = []
+ for activity_log in activity_logs:
+ strip_index = i = 0
+ for c in activity_log.url:
+ if c == '-':
+ strip_index = i
+ i += 1
+ template_id = activity_log.url[strip_index + 1:len(activity_log.url)]
+ if '#' in template_id:
+ continue
+ if any(ch.isalpha() for ch in template_id):
+ continue
+ template = request.env['product.template'].search([('id', '=', template_id)])
+ templates.append(template)
+
+ data.append({
+ 'email': email,
+ 'products': [request.env['product.template'].api_single_response(x) for x in templates]
+ })
+ return self.response(data)
+
+
+
@http.route(prefix + 'customer_review', auth='public', methods=['GET', 'OPTIONS'])
def get_customer_review(self, **kw):
if not self.authenticate():
diff --git a/indoteknik_api/controllers/api_v1/product.py b/indoteknik_api/controllers/api_v1/product.py
index 28a63ed5..23dcf48e 100644
--- a/indoteknik_api/controllers/api_v1/product.py
+++ b/indoteknik_api/controllers/api_v1/product.py
@@ -1,33 +1,85 @@
from .. import controller
from odoo import http
from odoo.http import request
+from datetime import datetime, timedelta
import ast
+import logging
+
+_logger = logging.getLogger(__name__)
class Product(controller.Controller):
prefix = '/api/v1/'
@http.route(prefix + 'new_product', auth='public', methods=['GET', 'OPTIONS'])
- def get_new_product(self):
+ def get_new_product(self, **kw):
if not self.authenticate():
return self.response(code=401, description='Unauthorized')
+
+ is_brand_only = int(kw.get('is_brand_only', 0))
+
base_url = request.env['ir.config_parameter'].get_param('web.base.url')
- query = [('show_as_new_product', '=', True)]
- brands = request.env['x_manufactures'].search(query, order='sequence')
+ limit_new_products = request.env['ir.config_parameter'].get_param('limit.new.product')
+ limit_new_products = int(limit_new_products)
+ # current_time = datetime.now()
+ # delta_time = current_time - timedelta(days=30)
+
+ # delta_time = delta_time.strftime('%Y-%m-%d %H:%M:%S')
+ query_products = [
+ ('type', '=', 'product'),
+ ('active', '=', True),
+ ('image_128', '!=', False),
+ ('website_description', '!=', False),
+ # ('write_uid', '!=', 1),
+ ('x_manufacture', '!=', False),
+ # ('create_date', '>=', delta_time),
+ ]
+ new_products = request.env['product.template'].search(query_products, order='create_date desc', limit=limit_new_products)
+ brands = []
+ for product in new_products:
+ brands.append(product.x_manufacture)
+ brands = list(dict.fromkeys(brands))
+
data = []
+ count = 0
for brand in brands:
- query_products = [
- ('is_new_product', '=', True),
+ if is_brand_only == 1:
+ data.append({
+ 'manufacture_id': brand.id,
+ 'sequence': brand.sequence if brand.sequence else count,
+ 'name': brand.x_name,
+ 'image': base_url + 'api/image/x_manufactures/x_logo_manufacture/' + str(
+ brand.id) if brand.x_logo_manufacture else '',
+ })
+ continue
+
+ if count == 11:
+ break
+ query = [
+ ('type', '=', 'product'),
+ ('active', '=', True),
('x_manufacture', '=', brand.id),
+ ('image_128', '!=', False),
+ ('website_description', '!=', False),
+ # ('write_uid', '!=', 1),
+ ('x_manufacture', '!=', False),
+ # ('create_date', '>=', delta_time),
]
- products = request.env['product.template'].search(query_products, order='name')
+ count_products = request.env['product.template'].search_count(query)
+ if count_products < 6:
+ _logger.info('Brand Skipped %s' % brand.x_name)
+ continue
+ products = request.env['product.template'].search(query, order='create_date desc', limit=12)
data.append({
'manufacture_id': brand.id,
- 'sequence': brand.sequence,
+ 'sequence': brand.sequence if brand.sequence else count,
'name': brand.x_name,
- 'image': base_url + 'api/image/x_manufactures/x_logo_manufacture/' + str(brand.id) if brand.x_logo_manufacture else '',
+ 'image': base_url + 'api/image/x_manufactures/x_logo_manufacture/' + str(
+ brand.id) if brand.x_logo_manufacture else '',
+ 'products_total': count_products,
'products': [request.env['product.template'].api_single_response(x) for x in products]
})
+ count += 1
return self.response(data)
@http.route(prefix + 'product', auth='public', methods=['GET', 'OPTIONS'])
diff --git a/indoteknik_api/models/product_product.py b/indoteknik_api/models/product_product.py
index 6b02d91e..2e84b9f4 100644
--- a/indoteknik_api/models/product_product.py
+++ b/indoteknik_api/models/product_product.py
@@ -5,7 +5,6 @@ class ProductProduct(models.Model):
_inherit = 'product.product'
def api_single_response(self, product_product):
- base_url = self.env['ir.config_parameter'].get_param('web.base.url')
product_pricelist_default_discount_id = self.env['ir.config_parameter'].get_param('product.pricelist.default_discount_id')
product_pricelist_default_discount_id = int(product_pricelist_default_discount_id)
product_template = product_product.product_tmpl_id
@@ -14,7 +13,7 @@ class ProductProduct(models.Model):
'parent': {
'id': product_template.id,
'name': product_template.name,
- 'image': base_url + 'api/image/product.template/image_256/' + str(product_template.id) if product_template.image_256 else '',
+ 'image': self.env['ir.attachment'].api_image('product.template', 'image_256', product_template.id),
},
'code': product_product.default_code or '',
'name': product_product.display_name,
@@ -27,13 +26,12 @@ class ProductProduct(models.Model):
return data
def api_manufacture(self, product_template):
- base_url = self.env['ir.config_parameter'].get_param('web.base.url')
if product_template.x_manufacture:
manufacture = product_template.x_manufacture
return {
'id': manufacture.id,
'name': manufacture.x_name,
- 'image_promotion_1': base_url + 'api/image/x_manufactures/image_promotion_1/' + str(manufacture.id) if manufacture.image_promotion_1 else '',
- 'image_promotion_2': base_url + 'api/image/x_manufactures/image_promotion_2/' + str(manufacture.id) if manufacture.image_promotion_2 else '',
+ 'image_promotion_1': self.env['ir.attachment'].api_image('x_manufactures', 'image_promotion_1', manufacture.id),
+ 'image_promotion_2': self.env['ir.attachment'].api_image('x_manufactures', 'image_promotion_2', manufacture.id),
}
return {} \ No newline at end of file
diff --git a/indoteknik_api/models/product_template.py b/indoteknik_api/models/product_template.py
index 9e8d04bc..72dda17f 100644
--- a/indoteknik_api/models/product_template.py
+++ b/indoteknik_api/models/product_template.py
@@ -5,12 +5,11 @@ class ProductTemplate(models.Model):
_inherit = 'product.template'
def api_single_response(self, product_template, with_detail=''):
- base_url = self.env['ir.config_parameter'].get_param('web.base.url')
product_pricelist_default_discount_id = self.env['ir.config_parameter'].get_param('product.pricelist.default_discount_id')
product_pricelist_default_discount_id = int(product_pricelist_default_discount_id)
data = {
'id': product_template.id,
- 'image': base_url + 'api/image/product.template/image_128/' + str(product_template.id) if product_template.image_128 else '',
+ 'image': self.env['ir.attachment'].api_image('product.template', 'image_128', product_template.id),
'code': product_template.default_code or '',
'name': product_template.name,
'lowest_price': self.env['product.pricelist'].get_lowest_product_variant_price(product_template, product_pricelist_default_discount_id),
@@ -23,7 +22,7 @@ class ProductTemplate(models.Model):
if with_detail != '':
data_with_detail = {
- 'image': base_url + 'api/image/product.template/image_512/' + str(product_template.id) if product_template.image_512 else '',
+ 'image': self.env['ir.attachment'].api_image('product.template', 'image_512', product_template.id),
'display_name': product_template.display_name,
'variants': [self.env['product.product'].api_single_response(variant) for variant in product_template.product_variant_ids],
'description': product_template.website_description or '',
@@ -31,12 +30,13 @@ class ProductTemplate(models.Model):
data.update(data_with_detail)
if with_detail == 'SOLR':
+ is_image_found = self.env['ir.attachment'].is_found('product.template', 'image_128', product_template.id)
rate = 0
if data['lowest_price']['price'] > 0:
rate += 1
if product_template.have_promotion_program:
rate += 1
- if product_template.image_128:
+ if is_image_found:
rate += 1
if product_template.website_description:
rate += 1
@@ -52,14 +52,13 @@ class ProductTemplate(models.Model):
return data
def api_manufacture(self, product_template):
- base_url = self.env['ir.config_parameter'].get_param('web.base.url')
if product_template.x_manufacture:
manufacture = product_template.x_manufacture
return {
'id': manufacture.id,
'name': manufacture.x_name,
- 'image_promotion_1': base_url + 'api/image/x_manufactures/image_promotion_1/' + str(manufacture.id) if manufacture.image_promotion_1 else '',
- 'image_promotion_2': base_url + 'api/image/x_manufactures/image_promotion_2/' + str(manufacture.id) if manufacture.image_promotion_2 else '',
+ 'image_promotion_1': self.env['ir.attachment'].api_image('x_manufactures', 'image_promotion_1', manufacture.id),
+ 'image_promotion_2': self.env['ir.attachment'].api_image('x_manufactures', 'image_promotion_2', manufacture.id),
}
return {}
diff --git a/indoteknik_api/models/x_manufactures.py b/indoteknik_api/models/x_manufactures.py
index 19fdcb9c..988d7a45 100644
--- a/indoteknik_api/models/x_manufactures.py
+++ b/indoteknik_api/models/x_manufactures.py
@@ -8,16 +8,16 @@ class Manufactures(models.Model):
base_url = self.env['ir.config_parameter'].get_param('web.base.url')
data = {
'id': manufacture.id,
- 'logo': base_url + 'api/image/x_manufactures/x_logo_manufacture/' + str(manufacture.id) if manufacture.x_logo_manufacture else '',
+ 'logo': self.env['ir.attachment'].api_image('x_manufactures', 'x_logo_manufacture', manufacture.id),
'name': manufacture.x_name
}
if with_detail:
data_with_detail = {
'description': manufacture.x_short_desc,
'banners': [
- base_url + 'api/image/x_banner.banner/x_banner_image/' + str(x.id)
+ self.env['ir.attachment'].api_image('x_banner.banner', 'x_banner_image', x.id)
for x in manufacture.x_manufactures_banners
- if x.x_status_banner == 'tayang' and x.x_banner_image
+ if x.x_status_banner == 'tayang'
]
}
data.update(data_with_detail)
diff --git a/indoteknik_custom/__manifest__.py b/indoteknik_custom/__manifest__.py
index 908e74df..66184081 100755
--- a/indoteknik_custom/__manifest__.py
+++ b/indoteknik_custom/__manifest__.py
@@ -57,6 +57,7 @@
'views/website_content_channel.xml',
'views/website_content.xml',
'views/custom_mail_marketing.xml',
+ 'views/website_ads.xml',
'report/report.xml',
'report/report_banner_banner.xml',
'report/report_banner_banner2.xml',
diff --git a/indoteknik_custom/models/__init__.py b/indoteknik_custom/models/__init__.py
index 8ada3b95..5d5ad0ec 100755
--- a/indoteknik_custom/models/__init__.py
+++ b/indoteknik_custom/models/__init__.py
@@ -44,3 +44,4 @@ from . import x_biaya_kirim
from . import x_manufactures
from . import x_partner_purchase_order
from . import x_product_tags
+from . import website_ads
diff --git a/indoteknik_custom/models/crm_lead.py b/indoteknik_custom/models/crm_lead.py
index e0a90d9c..3c8b842b 100755
--- a/indoteknik_custom/models/crm_lead.py
+++ b/indoteknik_custom/models/crm_lead.py
@@ -11,6 +11,15 @@ class CrmLead(models.Model):
file_siup = fields.Binary(string="Surat Izin Usaha Perdagangan")
body_html_lead = fields.Text('Body HTML', compute='compute_body_leads')
+ def revert_to_leads(self):
+ opportunities = self.env['crm.lead'].search([
+ ('type', '=', 'opportunity'),
+ ('active', '=', True),
+ ('user_id', '=', False),
+ ])
+ for opportunity in opportunities:
+ opportunity.type = 'lead'
+
@api.onchange('stage_id')
def update_stars(self):
for lead in self:
diff --git a/indoteknik_custom/models/dunning_run.py b/indoteknik_custom/models/dunning_run.py
index ed9aa7c0..ed5d7bb5 100644
--- a/indoteknik_custom/models/dunning_run.py
+++ b/indoteknik_custom/models/dunning_run.py
@@ -17,8 +17,37 @@ class DunningRun(models.Model):
required=True, change_default=True, index=True, tracking=1)
dunning_line = fields.One2many('dunning.run.line', 'dunning_id', string='Dunning Lines', auto_join=True)
# dunning_level = fields.Integer(string='Dunning Level', default=30, help='30 hari sebelum jatuh tempo invoice')
+ date_kirim_tukar_faktur = fields.Date(string='Kirim Faktur')
+ resi_tukar_faktur = fields.Char(string='Resi Faktur')
+ date_terima_tukar_faktur = fields.Date(string='Terima Faktur')
+ shipper_faktur_id = fields.Many2one('delivery.carrier', string='Shipper Faktur')
+ is_validated = fields.Boolean(string='Validated')
+
+ def copy_date_faktur(self):
+ if not self.is_validated:
+ raise UserError('Harus di validate dulu')
+ for line in self.dunning_line:
+ invoice = line.invoice_id
+ if not invoice.date_kirim_tukar_faktur:
+ invoice.date_kirim_tukar_faktur = self.date_kirim_tukar_faktur
+ if not invoice.resi_tukar_faktur:
+ invoice.resi_tukar_faktur = self.resi_tukar_faktur
+ if not invoice.date_terima_tukar_faktur:
+ invoice.date_terima_tukar_faktur = self.date_terima_tukar_faktur
+ if not invoice.shipper_faktur_id:
+ invoice.shipper_faktur_id = self.shipper_faktur_id
+
+ def validate_dunning(self):
+ if not self.dunning_line:
+ raise UserError('Dunning Line masih kosong, generate dulu')
+ else:
+ self.is_validated = True
def generate_dunning_line(self):
+ if self.is_validated:
+ raise UserError('Sudah di validate, tidak bisa digenerate ulang')
+ if self.dunning_line:
+ raise UserError('Harus hapus semua line jika ingin generate ulang')
if self.partner_id.parent_id:
raise UserError('Harus pilih parent company')
@@ -29,21 +58,27 @@ class DunningRun(models.Model):
for partner in partners:
query = [
('move_type', '=', 'out_invoice'),
+ ('state', '=', 'posted'),
('partner_id', '=', partner.id),
- ('outstanding_amount', '>', 0),
+ # ('amount_residual_signed', '>', 0),
+ ('date_kirim_tukar_faktur', '=', False),
]
invoices = self.env['account.move'].search(query, order='invoice_date')
+ count = 0
for invoice in invoices:
- parameter_line = {
+ self.env['dunning.run.line'].create([{
'dunning_id': self.id,
- 'partner_id': invoice.partner_id,
+ 'partner_id': invoice.partner_id.id,
'invoice_id': invoice.id,
'date_invoice': invoice.invoice_date,
- 'efaktur_id': invoice.efaktur_id,
+ 'efaktur_id': invoice.efaktur_id.id,
'reference': invoice.ref,
- 'open_amt': invoice.outstanding_amount
- }
- self.env['dunning.run.line'].create([parameter_line])
+ 'total_amt': invoice.amount_total,
+ 'open_amt': invoice.amount_residual_signed,
+ 'due_date': invoice.invoice_date_due
+ }])
+ count += 1
+ _logger.info("Dunning Line generated %s" % count)
@api.model
def create(self, vals):
@@ -51,33 +86,6 @@ class DunningRun(models.Model):
result = super(DunningRun, self).create(vals)
return result
- def generate_dunning_line(self):
- # validation
- if not self.partner_id:
- raise UserError('Customer harus diisi')
-
- invoices = self.env['account.move'].search([
- ('amount_residual_signed', '>', 0),
- ('partner_id', '=', self.partner_id.id),
- ('move_type', '=', 'out_invoice'),
- ('state', '=', 'posted'),
- ])
- count = 0
- for invoice in invoices:
- self.env['dunning.run.line'].create([{
- 'dunning_id': self.id,
- 'partner_id': invoice.partner_id.id,
- 'invoice_id': invoice.id,
- 'date_invoice': invoice.invoice_date,
- 'efaktur_id': invoice.efaktur_id.id,
- 'reference': invoice.ref,
- 'total_amt': invoice.amount_total,
- 'open_amt': invoice.amount_residual_signed,
- 'due_date': invoice.invoice_date_due
- }])
- count += 1
- _logger.info("Dunning Line generated %s" % count)
-
class DunningRunLine(models.Model):
_name = 'dunning.run.line'
diff --git a/indoteknik_custom/models/ir_attachment.py b/indoteknik_custom/models/ir_attachment.py
index 278eb938..fd86ab1b 100644
--- a/indoteknik_custom/models/ir_attachment.py
+++ b/indoteknik_custom/models/ir_attachment.py
@@ -9,4 +9,17 @@ class Attachment(models.Model):
@api.autovacuum
def _gc_file_store(self):
- _logger.info("filestore gc checked, removed - override") \ No newline at end of file
+ _logger.info("filestore gc checked, removed - override")
+
+ def is_found(self, model, field, id):
+ attachment = self.search([
+ ('res_model', '=', model),
+ ('res_field', '=', field),
+ ('res_id', '=', int(id))
+ ])
+ return True if attachment else False
+
+ def api_image(self, model, field, id):
+ base_url = self.env['ir.config_parameter'].get_param('web.base.url')
+ is_found = self.is_found(model, field, id)
+ return base_url + 'api/image/' + model + '/' + field + '/' + str(id) if is_found else '' \ No newline at end of file
diff --git a/indoteknik_custom/models/product_template.py b/indoteknik_custom/models/product_template.py
index 9f0410f4..74b4edb1 100755
--- a/indoteknik_custom/models/product_template.py
+++ b/indoteknik_custom/models/product_template.py
@@ -46,12 +46,33 @@ class ProductTemplate(models.Model):
material = fields.Char(string='Material')
is_new_product = fields.Boolean(string='Produk Baru',
help='Centang jika ingin ditammpilkan di website sebagai segment Produk Baru')
+ seq_new_product = fields.Integer(string='Seq New Product', help='Urutan Sequence New Product')
# def write(self, vals):
# if 'solr_flag' not in vals and self.solr_flag == 1:
# vals['solr_flag'] = 2
# return super().write(vals)
+ def update_new_product(self):
+ current_time = datetime.now()
+ delta_time = current_time - timedelta(days=30)
+
+ delta_time = delta_time.strftime('%Y-%m-%d %H:%M:%S')
+
+ products = self.env['product.template'].search([
+ ('type', '=', 'product'),
+ ('active', '=', True),
+ ('product_rating', '>', 3),
+ ('create_date', '>=', delta_time),
+ ], limit=100)
+
+ seq = 0
+ for product in products:
+ seq += 1
+ product.is_new_product = True
+ product.seq_new_product = seq
+ _logger.info('Updated New Product %s' % product.name)
+
def update_internal_reference(self):
templates_without_variant = self.env['product.template'].search([
('default_code', '=', False),
@@ -92,33 +113,21 @@ class ProductTemplate(models.Model):
for template in self:
product = self.env['product.product'].search([('product_tmpl_id', '=', template.id)], limit=1)
- # product_pricelist_default = self.env['ir.config_parameter'].sudo().get_param('product.pricelist.default')
- # product_pricelist_disc = self.env['product.pricelist.item'].search([
- # ('pricelist_id', '=', product_pricelist_default.int()),
- # ('product_id', '=', product.id)], limit=1)
- # disc = product_pricelist_disc.price_discount
-
product_pricelist_item = self.env['product.pricelist.item'].search([
('pricelist_id', '=', 1),
('product_id', '=', product.id)], limit=1)
price = product_pricelist_item.fixed_price
- #
- # if not disc and not price:
- # template.web_price = 0
- # elif not disc:
template.web_price = price
- # else:
- # price_disc = price - (price * disc / 100)
- # template.web_price = price_disc
def _have_promotion_program(self):
for template in self:
- domain = [
- ('rule_products_domain', 'ilike', template.x_manufacture.x_name),
- ('active', '=', True)
- ]
- coupon_program = self.env['coupon.program'].search(domain, limit=1)
- if coupon_program:
+ product = self.env['product.product'].search([('product_tmpl_id', '=', template.id)], limit=1)
+
+ product_pricelist_item = self.env['product.pricelist.item'].search([
+ ('pricelist_id', '=', 4),
+ ('product_id', '=', product.id)], limit=1)
+ discount = product_pricelist_item.price_discount
+ if discount:
template.have_promotion_program = True
else:
template.have_promotion_program = False
@@ -136,7 +145,7 @@ class ProductTemplate(models.Model):
('active', '=', True),
('last_calculate_rating', '=', False),
# ('id', '=', 22798),
- ], limit=10000)
+ ], limit=100)
for product in products:
# print("Calculate Rating Product ", product)
@@ -161,7 +170,7 @@ class ProductTemplate(models.Model):
('type', '=', 'product'),
('active', '=', True),
('last_calculate_rating', '<', delta_time),
- ], limit=10000)
+ ], limit=100)
for product in products:
print("Calculate Rating Product OutOfDate", product)
diff --git a/indoteknik_custom/models/sale_order.py b/indoteknik_custom/models/sale_order.py
index c8937ca4..5a4a653b 100755
--- a/indoteknik_custom/models/sale_order.py
+++ b/indoteknik_custom/models/sale_order.py
@@ -197,11 +197,15 @@ class SaleOrder(models.Model):
raise UserError("Payment Term pada Master Data Customer harus diisi")
if not order.partner_id.parent_id.active_limit:
raise UserError("Credit Limit pada Master Data Customer harus diisi")
+ if order.payment_term_id != order.partner_id.parent_id.property_payment_term_id:
+ raise UserError("Payment Term berbeda pada Master Data Customer")
else:
if not order.partner_id.property_payment_term_id:
raise UserError("Payment Term pada Master Data Customer harus diisi")
if not order.partner_id.active_limit:
raise UserError("Credit Limit pada Master Data Customer harus diisi")
+ if order.payment_term_id != order.partner_id.property_payment_term_id:
+ raise UserError("Payment Term berbeda pada Master Data Customer")
if not order.sales_tax_id:
raise UserError("Tax di Header harus diisi")
if not order.carrier_id:
diff --git a/indoteknik_custom/models/sales_target.py b/indoteknik_custom/models/sales_target.py
index ac6405e5..c31a4470 100644
--- a/indoteknik_custom/models/sales_target.py
+++ b/indoteknik_custom/models/sales_target.py
@@ -16,6 +16,26 @@ class SalesTarget(models.Model):
ongoing_omset_adempiere = fields.Float(string='Omset Berjalan ADempiere')
ongoing_omset_total = fields.Float(string='Total Omset', compute='_compute_total_omset')
target = fields.Float(string='Target')
+ ach_per_year = fields.Float(string='Ach/Year%', compute='_compute_achievement')
+ ach_per_month = fields.Float(string='Ach/Month%', compute='_compute_achievement')
+ sales_id = fields.Many2one('res.users', string='Salesperson', compute='_compute_partner')
+ reference = fields.Char(string='Reference', compute='_compute_partner')
+
+ def _compute_partner(self):
+ for sales_target in self:
+ sales_target.sales_id = sales_target.partner_id.user_id
+ sales_target.reference = sales_target.partner_id.reference_number
+
+ def _compute_achievement(self):
+ for sales_target in self:
+ if not sales_target.target or sales_target.target <= 0:
+ sales_target.ach_per_year = 0
+ sales_target.ach_per_month = 0
+ return
+ current_time = datetime.now()
+ current_month = current_time.month
+ sales_target.ach_per_year = sales_target.ongoing_omset_total/sales_target.target*100
+ sales_target.ach_per_month = sales_target.ongoing_omset_total/((sales_target.target/12)*current_month)
def _compute_total_omset(self):
for target in self:
diff --git a/indoteknik_custom/models/stock_vendor.py b/indoteknik_custom/models/stock_vendor.py
index 1a6b4a64..1e5bce16 100755
--- a/indoteknik_custom/models/stock_vendor.py
+++ b/indoteknik_custom/models/stock_vendor.py
@@ -11,27 +11,47 @@ class StockVendor(models.Model):
product_variant_id = fields.Many2one("product.product", string="Product Variant")
quantity = fields.Integer(string="Quantity")
+ cache_reset_status = fields.Selection([
+ ('reset', 'Reset'),
+ ('done', 'Done')
+ ], string="Cache Reset")
+
+ def cache_reset(self):
+ stocks = self.env['stock.vendor'].search([
+ ('cache_reset_status', '=', 'reset'),
+ ])
+
+ templates = []
+ for stock in stocks:
+ templates.append(stock.product_variant_id.product_tmpl_id)
+ # stock.cache_reset_status = 'done'
+ templates = list(dict.fromkeys(templates))
+
+ for template in templates:
+ if template.solr_flag == 1:
+ template.solr_flag = 2
+ _logger.info('Update Solr Flag to 2 %s' % template.name)
def update_product_template(self):
updated_virtual_qty_product_template = self.env['ir.config_parameter'].search([('key', '=', 'updated_virtual_qty_product_template')], limit=1)
updated_virtual_qty_product_template_value = int(updated_virtual_qty_product_template.value)
-
+
limit = 10000
query = [('active', '=', True), ('type', '=', 'product')]
templates = self.env['product.template'].search(query, limit=limit, offset=updated_virtual_qty_product_template_value)
template_count = self.env['product.template'].search_count(query)
-
+
if (updated_virtual_qty_product_template_value + limit) > template_count:
updated_virtual_qty_product_template.value = '0'
else:
updated_virtual_qty_product_template.value = str(limit + updated_virtual_qty_product_template_value)
-
+
for template in templates:
template.virtual_qty = template.qty_stock_vendor or 0
_logger.info("Update Stock Product Template %s : %s" % (template.id, template.virtual_qty))
- @api.onchange('quantity')
- def update_solr_flag(self):
- for stock in self:
- if stock.product_variant_id.product_tmpl_id.solr_flag == 1:
- stock.product_variant_id.product_tmpl_id.solr_flag = 2
+ # @api.onchange('quantity')
+ # def update_solr_flag(self):
+ # for stock in self:
+ # if stock.product_variant_id.product_tmpl_id.solr_flag == 1:
+ # stock.product_variant_id.product_tmpl_id.solr_flag = 2
diff --git a/indoteknik_custom/models/user_activity_log.py b/indoteknik_custom/models/user_activity_log.py
index bf1414db..32b389a1 100755
--- a/indoteknik_custom/models/user_activity_log.py
+++ b/indoteknik_custom/models/user_activity_log.py
@@ -14,14 +14,40 @@ class UserActivityLog(models.Model):
res_user_id = fields.Many2one("res.users", string="User")
email = fields.Char(string="Email")
update_product = fields.Boolean(string="Update Product")
+ product_id = fields.Many2one('product.template', string='Product')
+
+ def compile_product(self):
+ logs = self.env['user.activity.log'].search([
+ ('email', '!=', False),
+ ('product_id', '=', False),
+ ('url', 'ilike', 'https://indoteknik.co%/shop/product/%'),
+ ('url', 'not ilike', 'shopping')
+ ], limit=1000, order='create_date desc')
+ for log in logs:
+ _logger.info(log.url)
+ strip_index = i = 0
+ for c in log.url:
+ if c == '-':
+ strip_index = i
+ i += 1
+ product_id = log.url[strip_index + 1:len(log.url)]
+ if '#' in product_id:
+ continue
+ if any(ch.isalpha() for ch in product_id):
+ continue
+ product = self.env['product.template'].search([
+ ('id', '=', product_id)
+ ])
+ log.product_id = product
def clean_activity_log(self):
current_time = datetime.now()
- delta_time = current_time - timedelta(days=60)
+ delta_time = current_time - timedelta(days=180)
delta_time = delta_time.strftime('%Y-%m-%d %H:%M:%S')
self.env['user.activity.log'].search([
('create_date', '<', delta_time),
+ ('email', '=', 'False'),
]).unlink()
def reset_rank_search_weekly(self):
@@ -44,7 +70,8 @@ class UserActivityLog(models.Model):
activity_logs = self.env['user.activity.log'].search([
('url', 'ilike', 'https://indoteknik.co%/shop/product/%'),
('create_date', '>', delta_time),
- ], limit=4000)
+ ('url', 'not ilike', 'shopping'),
+ ], limit=1000)
for activity_log in activity_logs:
_logger.info(activity_log.url)
strip_index = i = 0
diff --git a/indoteknik_custom/models/website_ads.py b/indoteknik_custom/models/website_ads.py
new file mode 100644
index 00000000..ec360294
--- /dev/null
+++ b/indoteknik_custom/models/website_ads.py
@@ -0,0 +1,18 @@
+from odoo import fields, models
+
+
+class WebsiteAds(models.Model):
+ _name = 'website.ads'
+
+ sequence = fields.Integer(string='Sequence')
+ name = fields.Char(string='Name')
+ image = fields.Binary(string='Image')
+ url = fields.Char(string='URL')
+ page = fields.Selection([
+ ('product', 'Product'),
+ ('homepage', 'Home Page')
+ ], string='Page')
+ status = fields.Selection([
+ ('tayang', 'Tayang'),
+ ('tidak_tayang', 'Tidak Tayang')
+ ], string='Status')
diff --git a/indoteknik_custom/security/ir.model.access.csv b/indoteknik_custom/security/ir.model.access.csv
index 5eefa618..9349a566 100755
--- a/indoteknik_custom/security/ir.model.access.csv
+++ b/indoteknik_custom/security/ir.model.access.csv
@@ -25,4 +25,5 @@ access_customer_review,access.customer.review,model_customer_review,,1,1,1,1
access_website_content_channel,access.website.content.channel,model_website_content_channel,,1,1,1,1
access_website_content,access.website.content,model_website_content,,1,1,1,1
access_invoice_reklas,access.invoice.reklas,model_invoice_reklas,,1,1,1,1
-access_custom_mail_marketing,access.custom.mail.marketing,model_custom_mail_marketing,,1,1,1,1 \ No newline at end of file
+access_custom_mail_marketing,access.custom.mail.marketing,model_custom_mail_marketing,,1,1,1,1
+access_website_ads,access.website.ads,model_website_ads,,1,1,1,1 \ No newline at end of file
diff --git a/indoteknik_custom/views/dunning_run.xml b/indoteknik_custom/views/dunning_run.xml
index ab01d476..c251b206 100644
--- a/indoteknik_custom/views/dunning_run.xml
+++ b/indoteknik_custom/views/dunning_run.xml
@@ -5,10 +5,14 @@
<field name="model">dunning.run</field>
<field name="arch" type="xml">
<tree>
- <field name="id"/>
<field name="number"/>
<field name="dunning_date"/>
<field name="partner_id"/>
+ <field name="is_validated" readonly="1"/>
+ <field name="date_kirim_tukar_faktur"/>
+ <field name="resi_tukar_faktur"/>
+ <field name="date_terima_tukar_faktur"/>
+ <field name="shipper_faktur_id"/>
</tree>
</field>
</record>
@@ -39,14 +43,33 @@
<div class="oe_button_box" name="button_box"/>
<group>
<group>
- <field name="number"/>
- <field name="partner_id"/>
- <field name="dunning_date"/>
+ <div>
<button name="generate_dunning_line"
string="Generate"
type="object"
+ class="mr-2 oe_highlight oe_edit_only"
+ />
+ <button name="validate_dunning"
+ string="Validate"
+ type="object"
+ class="mr-2 oe_highlight oe_edit_only"
+ />
+ <button name="copy_date_faktur"
+ string="Copy Date"
+ type="object"
class="oe_highlight oe_edit_only"
/>
+ </div>
+ <field name="number"/>
+ <field name="partner_id"/>
+ <field name="dunning_date"/>
+ </group>
+ <group>
+ <field name="is_validated" readonly="1"/>
+ <field name="date_kirim_tukar_faktur"/>
+ <field name="resi_tukar_faktur"/>
+ <field name="date_terima_tukar_faktur"/>
+ <field name="shipper_faktur_id"/>
</group>
</group>
<notebook>
diff --git a/indoteknik_custom/views/sales_target.xml b/indoteknik_custom/views/sales_target.xml
index 6ccea260..08218913 100644
--- a/indoteknik_custom/views/sales_target.xml
+++ b/indoteknik_custom/views/sales_target.xml
@@ -1,26 +1,39 @@
<?xml version="1.0" encoding="UTF-8" ?>
<odoo>
<data>
+ <record id="view_sales_target_filter" model="ir.ui.view">
+ <field name="name">sales.target.list.select</field>
+ <field name="model">sales.target</field>
+ <field name="priority" eval="15"/>
+ <field name="arch" type="xml">
+ <search string="Search Content">
+ <field name="partner_id"/>
+ <field name="period"/>
+ </search>
+ </field>
+ </record>
<record id="sales_target_action" model="ir.actions.act_window">
<field name="name">Sales Target</field>
<field name="res_model">sales.target</field>
+ <field name="search_view_id" ref="view_sales_target_filter"/>
<field name="view_mode">tree,form</field>
</record>
-
<record id="sales_target_tree" model="ir.ui.view">
<field name="name">Sales Target</field>
<field name="model">sales.target</field>
<field name="arch" type="xml">
<tree>
<field name="partner_id"/>
+ <field name="sales_id"/>
<field name="period"/>
<field name="omset_last_year"/>
<field name="ongoing_omset_total"/>
<field name="target"/>
+ <field name="ach_per_year"/>
+ <field name="ach_per_month"/>
</tree>
</field>
</record>
-
<record id="sales_target_form" model="ir.ui.view">
<field name="name">Sales Target</field>
<field name="model">sales.target</field>
@@ -30,12 +43,17 @@
<group>
<group>
<field name="partner_id"/>
+ <field name="reference"/>
+ <field name="sales_id"/>
<field name="period"/>
<field name="omset_last_year"/>
<field name="ongoing_omset_odoo"/>
<field name="ongoing_omset_accurate"/>
<field name="ongoing_omset_adempiere"/>
+ <field name="ongoing_omset_total"/>
<field name="target"/>
+ <field name="ach_per_year"/>
+ <field name="ach_per_month"/>
</group>
</group>
</sheet>
diff --git a/indoteknik_custom/views/stock_vendor.xml b/indoteknik_custom/views/stock_vendor.xml
index ebf63a6a..35931750 100755
--- a/indoteknik_custom/views/stock_vendor.xml
+++ b/indoteknik_custom/views/stock_vendor.xml
@@ -18,6 +18,7 @@
<tree>
<field name="quantity" widget="badge" decoration-primary="True"/>
<field name="product_variant_id"/>
+ <field name="cache_reset_status"/>
<field name="__last_update"/>
</tree>
</field>
@@ -33,6 +34,7 @@
<group>
<field name="product_variant_id"/>
<field name="quantity" widget="badge" decoration-primary="True"/>
+ <field name="cache_reset_status"/>
<field name="__last_update"/>
</group>
<group></group>
diff --git a/indoteknik_custom/views/website_ads.xml b/indoteknik_custom/views/website_ads.xml
new file mode 100644
index 00000000..b66b0346
--- /dev/null
+++ b/indoteknik_custom/views/website_ads.xml
@@ -0,0 +1,69 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<odoo>
+ <data>
+ <record id="view_website_ads_filter" model="ir.ui.view">
+ <field name="name">website.ads.list.select</field>
+ <field name="model">website.ads</field>
+ <field name="priority" eval="15"/>
+ <field name="arch" type="xml">
+ <search string="Search Content">
+ <field name="name"/>
+ <field name="url"/>
+ <field name="page"/>
+ <field name="status"/>
+ </search>
+ </field>
+ </record>
+
+ <record id="website_ads_action" model="ir.actions.act_window">
+ <field name="name">Website Ads</field>
+ <field name="res_model">website.ads</field>
+ <field name="search_view_id" ref="view_website_ads_filter"/>
+ <field name="view_mode">tree,form</field>
+ </record>
+
+ <record id="website_ads_tree" model="ir.ui.view">
+ <field name="name">Website Ads</field>
+ <field name="model">website.ads</field>
+ <field name="arch" type="xml">
+ <tree>
+ <field name="sequence"/>
+ <field name="name"/>
+ <field name="image"/>
+ <field name="url"/>
+ <field name="page"/>
+ <field name="status"/>
+ </tree>
+ </field>
+ </record>
+
+ <record id="website_ads_form" model="ir.ui.view">
+ <field name="name">Website Ads</field>
+ <field name="model">website.ads</field>
+ <field name="arch" type="xml">
+ <form>
+ <sheet>
+ <group>
+ <group>
+ <field name="sequence"/>
+ <field name="name"/>
+ <field name="image"/>
+ <field name="url"/>
+ <field name="page"/>
+ <field name="status"/>
+ </group>
+ </group>
+ </sheet>
+ </form>
+ </field>
+ </record>
+
+ <menuitem
+ id="website_ads"
+ name="Website Ads"
+ parent="website_sale.menu_orders"
+ sequence="5"
+ action="website_ads_action"
+ />
+ </data>
+</odoo> \ No newline at end of file
diff --git a/indoteknik_custom/views/x_manufactures.xml b/indoteknik_custom/views/x_manufactures.xml
index c7cedd9c..e51cb6a7 100755
--- a/indoteknik_custom/views/x_manufactures.xml
+++ b/indoteknik_custom/views/x_manufactures.xml
@@ -43,7 +43,6 @@
<field name="x_manufacture_level"/>
<field name="x_produk_aksesoris_sparepart"/>
<field name="cache_reset_status"/>
- <field name="show_as_new_product"/>
<field name="sequence"/>
</group>
<group>
@@ -64,7 +63,6 @@
<field name="create_date"/>
<field name="solr_flag"/>
<field name="product_rating"/>
- <field name="is_new_product"/>
</tree>
</field>
</page>