summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--indoteknik_api/controllers/api_v1/category.py63
-rw-r--r--indoteknik_api/controllers/api_v1/partner.py5
-rw-r--r--indoteknik_api/controllers/api_v1/sale_order.py11
-rw-r--r--indoteknik_api/controllers/api_v1/user.py8
-rw-r--r--indoteknik_custom/models/approval_date_doc.py7
-rw-r--r--indoteknik_custom/models/automatic_purchase.py31
-rw-r--r--indoteknik_custom/models/midtrans.py4
-rwxr-xr-xindoteknik_custom/models/product_template.py26
-rwxr-xr-xindoteknik_custom/models/purchase_order.py15
-rwxr-xr-xindoteknik_custom/models/sale_order.py12
-rw-r--r--indoteknik_custom/models/solr/__init__.py1
-rw-r--r--indoteknik_custom/models/solr/product_product.py3
-rw-r--r--indoteknik_custom/models/solr/product_template.py15
-rw-r--r--indoteknik_custom/models/solr/website_categories_management.py95
-rw-r--r--indoteknik_custom/models/stock_picking.py5
-rw-r--r--indoteknik_custom/models/voucher.py1
-rw-r--r--indoteknik_custom/models/website_user_cart.py12
-rw-r--r--indoteknik_custom/views/approval_date_doc.xml10
-rw-r--r--indoteknik_custom/views/automatic_purchase.xml4
-rwxr-xr-xindoteknik_custom/views/product_template.xml3
-rwxr-xr-xindoteknik_custom/views/voucher.xml4
21 files changed, 179 insertions, 156 deletions
diff --git a/indoteknik_api/controllers/api_v1/category.py b/indoteknik_api/controllers/api_v1/category.py
index 09b8ff8c..7d66ad01 100644
--- a/indoteknik_api/controllers/api_v1/category.py
+++ b/indoteknik_api/controllers/api_v1/category.py
@@ -123,34 +123,47 @@ class Category(controller.Controller):
return self.response(response_data)
- @http.route(prefix + 'category/tree', auth='public', methods=['GET', 'OPTIONS'])
- @controller.Controller.must_authorized()
- def get_category_tree(self):
- parent_categories = request.env['product.public.category'].search_read([('parent_frontend_id', '=', False)], ['id', 'name'])
- data = []
- for parent_category in parent_categories:
- parent_data = {
- 'id': parent_category['id'],
- 'name': parent_category['name'],
- 'childs': []
- }
- child_1_categories = request.env['product.public.category'].search_read([('parent_frontend_id', '=', parent_category['id'])], ['id', 'name'])
- for child_1_category in child_1_categories:
- child_1_data = {
- 'id': child_1_category['id'],
- 'name': child_1_category['name'],
+ class CategoryManagement(controller.Controller):
+ prefix = '/api/v1/'
+
+ @http.route(prefix + 'category/tree', auth='public', methods=['GET', 'OPTIONS'], csrf=False)
+ @controller.Controller.must_authorized()
+ def get_category_tree(self):
+ parent_categories = request.env['product.public.category'].search_read([('parent_frontend_id', '=', False)],
+ ['id', 'name', 'image_1920'])
+ data = []
+ for parent_category in parent_categories:
+ category_data_ids = [parent_category['id']]
+ parent_data = {
+ 'id': parent_category['id'],
+ 'name': parent_category['name'],
+ 'image': request.env['ir.attachment'].sudo().api_image('product.public.category', 'image_1920',
+ parent_category['id']),
+ 'category_data_ids': category_data_ids,
'childs': []
}
- child_2_categories = request.env['product.public.category'].search_read([('parent_frontend_id', '=', child_1_category['id'])], ['id', 'name'])
- for child_2_category in child_2_categories:
- child_2_data = {
- 'id': child_2_category['id'],
- 'name': child_2_category['name'],
+ child_1_categories = request.env['product.public.category'].search_read(
+ [('parent_frontend_id', '=', parent_category['id'])], ['id', 'name'])
+ for child_1_category in child_1_categories:
+ child_1_data = {
+ 'id': child_1_category['id'],
+ 'name': child_1_category['name'],
+ 'childs': []
}
- child_1_data['childs'].append(child_2_data)
- parent_data['childs'].append(child_1_data)
- data.append(parent_data)
- return self.response(data, headers=[('Cache-Control', 'max-age=3600, public')])
+ category_data_ids.append(child_1_category['id'])
+ child_2_categories = request.env['product.public.category'].search_read(
+ [('parent_frontend_id', '=', child_1_category['id'])], ['id', 'name'])
+ for child_2_category in child_2_categories:
+ child_2_data = {
+ 'id': child_2_category['id'],
+ 'name': child_2_category['name'],
+ }
+ child_1_data['childs'].append(child_2_data)
+ category_data_ids.append(child_2_category['id'])
+ parent_data['childs'].append(child_1_data)
+ parent_data['category_data_ids'] = category_data_ids
+ data.append(parent_data)
+ return self.response(data, headers=[('Cache-Control', 'max-age=3600, public')])
@http.route(prefix + 'categories_homepage/ids', auth='public', methods=['GET', 'OPTIONS'])
@controller.Controller.must_authorized()
diff --git a/indoteknik_api/controllers/api_v1/partner.py b/indoteknik_api/controllers/api_v1/partner.py
index a6e14a19..69a2f861 100644
--- a/indoteknik_api/controllers/api_v1/partner.py
+++ b/indoteknik_api/controllers/api_v1/partner.py
@@ -142,9 +142,12 @@ class Partner(controller.Controller):
partner_industry = request.env['res.partner.industry'].search([])
data = []
for industry in partner_industry:
+ full_name = industry.full_name
+ category = full_name.title() if full_name else '-'
data.append({
'id': industry.id,
- 'name': industry.name
+ 'name': industry.name,
+ 'category': category
})
return self.response(data)
diff --git a/indoteknik_api/controllers/api_v1/sale_order.py b/indoteknik_api/controllers/api_v1/sale_order.py
index 0da7f894..b351bacc 100644
--- a/indoteknik_api/controllers/api_v1/sale_order.py
+++ b/indoteknik_api/controllers/api_v1/sale_order.py
@@ -403,20 +403,21 @@ class SaleOrder(controller.Controller):
'shipping_paid_by': 'customer',
'carrier_id': params['value']['carrier_id'],
'delivery_service_type': params['value']['delivery_service_type'],
- 'flash_sale': params['value']['flash_sale'],
+ 'flash_sale': params['value']['flash_sale'],
'note_website': params['value']['note_website'],
'customer_type': 'nonpkp',
'npwp': '0',
'user_id': 3222 # User ID: Nadia Rauhadatul Firdaus
}
+
+ sales_partner = request.env['res.partner'].browse(parameters['partner_id'])
+ if sales_partner and sales_partner.user_id and sales_partner.user_id.id not in [25]: # 25: System
+ parameters['user_id'] = sales_partner.user_id.id
+
if params['value']['type'] == 'sale_order':
parameters['approval_status'] = 'pengajuan1'
sale_order = request.env['sale.order'].create([parameters])
sale_order.onchange_partner_contact()
-
- sales_partner = sale_order.partner_id.user_id
- if sales_partner and sales_partner not in [25]: # 25: System
- parameters['user_id'] = sales_partner.id
user_id = params['value']['user_id']
user_cart = request.env['website.user.cart']
diff --git a/indoteknik_api/controllers/api_v1/user.py b/indoteknik_api/controllers/api_v1/user.py
index 9b89e82c..b9fd9f56 100644
--- a/indoteknik_api/controllers/api_v1/user.py
+++ b/indoteknik_api/controllers/api_v1/user.py
@@ -1,3 +1,5 @@
+import base64
+
from .. import controller
from odoo import http
from odoo.http import request
@@ -104,10 +106,10 @@ class User(controller.Controller):
password = kw.get('password')
if not name or not email or not password:
return self.response(code=400, description='email, name and password is required')
-
+
company = kw.get('company', False)
phone = kw.get('phone')
-
+
response = {
'register': False,
'reason': None
@@ -120,7 +122,7 @@ class User(controller.Controller):
else:
user.send_activation_mail()
response['reason'] = 'NOT_ACTIVE'
-
+
return self.response(response)
user_data = {
diff --git a/indoteknik_custom/models/approval_date_doc.py b/indoteknik_custom/models/approval_date_doc.py
index e00b7416..441ada3d 100644
--- a/indoteknik_custom/models/approval_date_doc.py
+++ b/indoteknik_custom/models/approval_date_doc.py
@@ -16,10 +16,12 @@ class ApprovalDateDoc(models.Model):
string='Driver Departure Date',
copy=False
)
- state = fields.Selection([('draft', 'Draft'), ('done', 'Done')], string='State', default='draft', tracking=True)
+ state = fields.Selection([('draft', 'Draft'), ('done', 'Done'), ('cancel', 'Cancel')], string='State', default='draft', tracking=True)
approve_date = fields.Datetime(string='Approve Date', copy=False)
approve_by = fields.Many2one('res.users', string='Approve By', copy=False)
sale_id = fields.Many2one('sale.order', string='Sale Order')
+ partner_id = fields.Many2one('res.partner', string='Partner', related='picking_id.partner_id')
+ note = fields.Char(string='Note')
@api.onchange('picking_id')
def onchange_picking_id(self):
@@ -42,6 +44,9 @@ class ApprovalDateDoc(models.Model):
self.approve_date = datetime.utcnow()
self.approve_by = self.env.user.id
+ def button_cancel(self):
+ self.state = 'cancel'
+
@api.model
def create(self, vals):
vals['number'] = self.env['ir.sequence'].next_by_code('approval.date.doc') or '0'
diff --git a/indoteknik_custom/models/automatic_purchase.py b/indoteknik_custom/models/automatic_purchase.py
index f5b1baf9..3561fc0f 100644
--- a/indoteknik_custom/models/automatic_purchase.py
+++ b/indoteknik_custom/models/automatic_purchase.py
@@ -545,6 +545,37 @@ class AutomaticPurchaseLine(models.Model):
def _calculate_subtotal(self):
for line in self:
line.subtotal = line.qty_purchase * line.last_price
+
+ @api.onchange('product_id')
+ def _onchange_product_id(self):
+ for line in self:
+ purchase_price = self.env['purchase.pricelist'].search([
+ ('product_id', '=', line.product_id.id),
+ ('vendor_id', '=', line.partner_id.id)
+ ], order='count_trx_po desc, count_trx_po_vendor desc', limit=1)
+ vendor_id = purchase_price.vendor_id.id
+ price, taxes = self._get_valid_purchase_price(purchase_price)
+ line.last_price = price
+ line.taxes_id = taxes
+ line.brand_id = line.product_id.product_tmpl_id.x_manufacture.id
+ line.partner_id = vendor_id
+
+ def _get_valid_purchase_price(self, purchase_price):
+ price = 0
+ taxes = ''
+ human_last_update = purchase_price.human_last_update or datetime.min
+ system_last_update = purchase_price.system_last_update or datetime.min
+
+ if purchase_price.taxes_product_id.type_tax_use == 'purchase':
+ price = purchase_price.product_price
+ taxes = purchase_price.taxes_product_id.id
+
+ if system_last_update > human_last_update:
+ if purchase_price.taxes_system_id.type_tax_use == 'purchase':
+ price = purchase_price.system_price
+ taxes = purchase_price.taxes_system_id.id
+
+ return price, taxes
class AutomaticPurchaseMatch(models.Model):
diff --git a/indoteknik_custom/models/midtrans.py b/indoteknik_custom/models/midtrans.py
index c99c8410..6acbe5a7 100644
--- a/indoteknik_custom/models/midtrans.py
+++ b/indoteknik_custom/models/midtrans.py
@@ -39,6 +39,10 @@ class MidtransNotification(models.Model):
orders = order_id.split('_')
order = orders[0].replace('-', '/')
+
+ if 'cpl' in order_id:
+ order = order.replace('/cpl', '')
+
sale_order = self.env['sale.order'].search([('name', '=', order)], limit=1)
notif.payment_status = payment_status
diff --git a/indoteknik_custom/models/product_template.py b/indoteknik_custom/models/product_template.py
index 56460821..e6778758 100755
--- a/indoteknik_custom/models/product_template.py
+++ b/indoteknik_custom/models/product_template.py
@@ -61,6 +61,12 @@ class ProductTemplate(models.Model):
tkdn = fields.Boolean(string='TKDN')
short_spesification = fields.Char(string='Short Spesification')
+ @api.constrains('name', 'internal_reference', 'x_manufacture')
+ def required_public_categ_ids(self):
+ for rec in self:
+ if not rec.public_categ_ids:
+ raise UserError('Field Categories harus diisi')
+
def _get_qty_sold(self):
for rec in self:
rec.qty_sold = sum(x.qty_sold for x in rec.product_variant_ids)
@@ -337,7 +343,7 @@ class ProductTemplate(models.Model):
raise UserError('Tidak dapat mengubah produk sementara')
return super(ProductTemplate, self).write(vals)
-
+
class ProductProduct(models.Model):
_inherit = "product.product"
web_price = fields.Float(
@@ -367,6 +373,24 @@ class ProductProduct(models.Model):
qty_sold = fields.Float(string='Sold Quantity', compute='_get_qty_sold')
short_spesification = fields.Char(string='Short Spesification')
+ @api.constrains('name', 'internal_reference', 'x_manufacture')
+ def required_public_categ_ids(self):
+ for rec in self:
+ if not rec.public_categ_ids:
+ raise UserError('Field Categories harus diisi')
+
+ @api.constrains('active')
+ def archive_product(self):
+ for product in self:
+ product_template = product.product_tmpl_id
+ variants = product_template.product_variant_ids
+
+ if product_template.active and product.active:
+ if not product.active and len(variants) == 1:
+ product_template.with_context(skip_active_constraint=True).active = False
+ elif not product.active and len(variants) > 1:
+ continue
+
def update_internal_reference_variants(self, limit=100):
variants = self.env['product.product'].search([
('default_code', '=', False),
diff --git a/indoteknik_custom/models/purchase_order.py b/indoteknik_custom/models/purchase_order.py
index c6512772..8ec904a9 100755
--- a/indoteknik_custom/models/purchase_order.py
+++ b/indoteknik_custom/models/purchase_order.py
@@ -434,6 +434,8 @@ class PurchaseOrder(models.Model):
def button_confirm(self):
res = super(PurchaseOrder, self).button_confirm()
current_time = datetime.now()
+ self.check_ppn_mix()
+ # self.check_data_vendor()
if self.total_percent_margin < self.total_so_percent_margin and not self.env.user.is_purchasing_manager and not self.env.user.is_leader:
raise UserError("Beda Margin dengan Sales, harus approval Manager")
@@ -477,9 +479,22 @@ class PurchaseOrder(models.Model):
self.date_planned = delta_time
self.date_deadline_ref_date_planned()
self.unlink_purchasing_job_state()
+
return res
+ def check_ppn_mix(self):
+ reference_taxes = self.order_line[0].taxes_id
+
+ for line in self.order_line:
+ if line.taxes_id != reference_taxes:
+ raise UserError("PPN harus sama untuk semua baris pada line.")
+
+ def check_data_vendor(self):
+ vendor = self.partner_id
+ if not vendor.email_finance or not vendor.email_sales:
+ raise UserError("Email Finance dan Email Sales pada vendor harus diisi")
+
def unlink_purchasing_job_state(self):
for line in self.order_line:
purchasing_job_state = self.env['purchasing.job.state'].search([
diff --git a/indoteknik_custom/models/sale_order.py b/indoteknik_custom/models/sale_order.py
index 0b0a679f..710e99de 100755
--- a/indoteknik_custom/models/sale_order.py
+++ b/indoteknik_custom/models/sale_order.py
@@ -277,7 +277,7 @@ class SaleOrder(models.Model):
if check_response.status_code == 200:
status_response = check_response.json()
- if status_response.get('transaction_status') == 'expire':
+ if status_response.get('transaction_status') == 'expire' or status_response.get('transaction_status') == 'cancel':
so_number = so_number + '-cpl'
json_data = {
@@ -507,6 +507,8 @@ class SaleOrder(models.Model):
raise UserError("SPPKP berbeda pada Master Data Customer")
if not order.client_order_ref and order.create_date > datetime(2024, 6, 27):
raise UserError("Customer Reference kosong, di isi dengan NO PO jika PO tidak ada mohon ditulis Tanpa PO")
+ if not order.user_id.active:
+ raise UserError("Salesperson sudah tidak aktif, mohon diisi yang benar pada data SO dan Contact")
def sale_order_approve(self):
self.check_due()
@@ -528,6 +530,8 @@ class SaleOrder(models.Model):
raise UserError("SPPKP berbeda pada Master Data Customer")
if not order.client_order_ref and order.create_date > datetime(2024, 6, 27):
raise UserError("Customer Reference kosong, di isi dengan NO PO jika PO tidak ada mohon ditulis Tanpa PO")
+ if not order.user_id.active:
+ raise UserError("Salesperson sudah tidak aktif, mohon diisi yang benar pada data SO dan Contact")
if order.validate_partner_invoice_due():
return self._create_notification_action('Notification', 'Terdapat invoice yang telah melewati batas waktu, mohon perbarui pada dokumen Due Extension')
@@ -878,7 +882,7 @@ class SaleOrder(models.Model):
('order_id.date_order', '>=', delta_time)
], limit=1, order='create_date desc')
- if rec_vendor_id != last_so.vendor_id.id:
+ if last_so and rec_vendor_id != last_so.vendor_id.id:
last_so = self.env['sale.order.line'].search([
# ('order_id.partner_id.id', '=', order_line.order_id.partner_id.id),
('order_id.partner_id', 'in', partners),
@@ -889,7 +893,7 @@ class SaleOrder(models.Model):
('order_id.date_order', '>=', delta_time)
], limit=1, order='create_date desc')
- if rec_purchase_price != last_so.purchase_price:
+ if last_so and rec_purchase_price != last_so.purchase_price:
rec_taxes = self.env['account.tax'].search([('id', '=', rec_taxes_id)], limit=1)
if rec_taxes.price_include:
selling_price = (rec_purchase_price / 1.11) / (1 - (last_so.item_percent_margin_without_deduction / 100))
@@ -911,7 +915,7 @@ class SaleOrder(models.Model):
tax_id = order_line.tax_id
discount = order_line.discount
- elif rec_vendor_id == order_line.vendor_id.id and rec_purchase_price != last_so.purchase_price:
+ elif last_so and rec_vendor_id == order_line.vendor_id.id and rec_purchase_price != last_so.purchase_price:
rec_taxes = self.env['account.tax'].search([('id', '=', rec_taxes_id)], limit=1)
if rec_taxes.price_include:
selling_price = (rec_purchase_price / 1.11) / (1 - (last_so.item_percent_margin_without_deduction / 100))
diff --git a/indoteknik_custom/models/solr/__init__.py b/indoteknik_custom/models/solr/__init__.py
index 925a8c14..606c0035 100644
--- a/indoteknik_custom/models/solr/__init__.py
+++ b/indoteknik_custom/models/solr/__init__.py
@@ -5,7 +5,6 @@ from . import product_pricelist_item
from . import product_product
from . import product_template
from . import website_categories_homepage
-from . import website_categories_management
from . import x_manufactures
from . import x_banner_banner
from . import product_public_category
diff --git a/indoteknik_custom/models/solr/product_product.py b/indoteknik_custom/models/solr/product_product.py
index f09c2dfb..35e3a4b3 100644
--- a/indoteknik_custom/models/solr/product_product.py
+++ b/indoteknik_custom/models/solr/product_product.py
@@ -57,7 +57,7 @@ class ProductProduct(models.Model):
'product_rating_f': variant.product_tmpl_id.virtual_rating,
'product_id_i': variant.id,
'template_id_i': variant.product_tmpl_id.id,
- 'image_s': ir_attachment.api_image('product.template', 'image_256', variant.product_tmpl_id.id),
+ 'image_s': ir_attachment.api_image('product.template', 'image_512', variant.product_tmpl_id.id),
'stock_total_f': variant.qty_stock_vendor,
'weight_f': variant.weight,
'manufacture_id_i': variant.product_tmpl_id.x_manufacture.id or 0,
@@ -65,6 +65,7 @@ class ProductProduct(models.Model):
'manufacture_name': variant.product_tmpl_id.x_manufacture.x_name or '',
'image_promotion_1_s': ir_attachment.api_image('x_manufactures', 'image_promotion_1', variant.product_tmpl_id.x_manufacture.id),
'image_promotion_2_s': ir_attachment.api_image('x_manufactures', 'image_promotion_2', variant.product_tmpl_id.x_manufacture.id),
+ 'x_logo_manufacture_s': ir_attachment.api_image('x_manufactures', 'x_logo_manufacture', variant.product_tmpl_id.x_manufacture.id),
'category_id_i': category_id,
'category_name_s': category_name,
'category_name': category_name,
diff --git a/indoteknik_custom/models/solr/product_template.py b/indoteknik_custom/models/solr/product_template.py
index 6ad49af7..6f76c529 100644
--- a/indoteknik_custom/models/solr/product_template.py
+++ b/indoteknik_custom/models/solr/product_template.py
@@ -77,7 +77,6 @@ class ProductTemplate(models.Model):
])
is_in_bu = bool(stock_quant)
- on_hand_qty = sum(stock_quant.mapped('quantity')) if stock_quant else 0
document = solr_model.get_doc('product', template.id)
document.update({
@@ -87,7 +86,7 @@ class ProductTemplate(models.Model):
"default_code_s": template.default_code or '',
"product_rating_f": template.virtual_rating,
"product_id_i": template.id,
- "image_s": self.env['ir.attachment'].api_image('product.template', 'image_256', template.id),
+ "image_s": self.env['ir.attachment'].api_image('product.template', 'image_512', template.id),
"variant_total_i": template.product_variant_count,
"stock_total_f": template.qty_stock_vendor,
"weight_f": template.weight,
@@ -96,6 +95,7 @@ class ProductTemplate(models.Model):
"manufacture_name": template.x_manufacture.x_name or '',
"image_promotion_1_s": self.env['ir.attachment'].api_image('x_manufactures', 'image_promotion_1', template.x_manufacture.id),
"image_promotion_2_s": self.env['ir.attachment'].api_image('x_manufactures', 'image_promotion_2', template.x_manufacture.id),
+ 'x_logo_manufacture_s': self.env['ir.attachment'].api_image('x_manufactures', 'x_logo_manufacture', template.x_manufacture.id),
"variants_name_t": variant_names,
"variants_code_t": variant_codes,
"search_rank_i": template.search_rank,
@@ -110,13 +110,10 @@ class ProductTemplate(models.Model):
'tkdn_b': template.unpublished,
"qty_sold_f": template.qty_sold,
"is_in_bu_b": is_in_bu,
- "on_hand_qty_i": on_hand_qty,
- "voucher_pastihemat" : {
- "min_purchase" : voucher.min_purchase_amount or 0,
- "discount_type" : voucher.discount_type or '',
- "discount_amount" : voucher.discount_amount or 0,
- "max_discount" : voucher.max_discount_amount or 0
- }
+ "voucher_min_purchase_f" : voucher.min_purchase_amount or 0,
+ "voucher_discount_type_s" : voucher.discount_type or '',
+ "voucher_discount_amount_f" : voucher.discount_amount or 0,
+ "voucher_max_discount_f" : voucher.max_discount_amount or 0
})
self.solr().add(docs=[document], softCommit=True)
diff --git a/indoteknik_custom/models/solr/website_categories_management.py b/indoteknik_custom/models/solr/website_categories_management.py
deleted file mode 100644
index 49f52378..00000000
--- a/indoteknik_custom/models/solr/website_categories_management.py
+++ /dev/null
@@ -1,95 +0,0 @@
-from odoo import models, fields, api
-from datetime import datetime
-import json
-
-import logging
-
-_logger = logging.getLogger(__name__)
-
-
-class WebsiteCategoriesManagement(models.Model):
- _inherit = 'website.categories.management'
-
- last_update_solr = fields.Datetime('Last Update Solr')
-
- def solr(self):
- return self.env['apache.solr'].connect('product_category_management')
-
- def update_last_update_solr(self):
- self.last_update_solr = datetime.utcnow()
-
- def _create_solr_queue(self, function_name):
- for rec in self:
- self.env['apache.solr.queue'].create_unique({
- 'res_model': self._name,
- 'res_id': rec.id,
- 'function_name': function_name
- })
-
- @api.constrains('status')
- def _create_solr_queue_sync_status(self):
- self._create_solr_queue('_sync_status_category_management_solr')
-
- @api.constrains('category_id', 'sequence', 'category_id2')
- def _create_solr_queue_sync_category_homepage(self):
- self._create_solr_queue('_sync_category_management_to_solr')
-
- def action_sync_to_solr(self):
- category_ids = self.env.context.get('active_ids', [])
- categories = self.search([('id', 'in', category_ids)])
- categories._create_solr_queue('_sync_category_management_to_solr')
-
- def unlink(self):
- res = super(WebsiteCategoriesManagement, self).unlink()
- for rec in self:
- self.solr().delete(rec.id)
- self.solr().optimize()
- self.solr().commit()
- return res
-
- def _sync_status_category_management_solr(self):
- for rec in self:
- if rec.status == 'tayang':
- rec._sync_category_management_to_solr()
- else:
- rec.unlink()
-
- def _sync_category_management_to_solr(self):
- solr_model = self.env['apache.solr']
-
- for category in self:
- if category.status == 'tidak_tayang':
- continue
-
- category_id2_data = [
- {
- 'id_level_2': x.id,
- 'name': x.name,
- 'image': x.image,
- 'child_frontend_id_i': [{'id_level_3': child.id, 'name': child.name, 'image': child.image} for child in
- x.child_frontend_id2]
- }
- for x in category.category_id2
- ]
- category_id2_json = json.dumps(category_id2_data)
- document = solr_model.get_doc('product_category_management', category.id)
- document.update({
- 'id': category.id,
- 'category_id_i': category.category_id.id,
- 'image_s': self.env['ir.attachment'].api_image('product.public.category', 'image_1920', category.category_id.id),
- 'name_s': category.category_id.name,
- 'sequence_i': category.sequence or '',
- 'category_id2_s': category_id2_json,
- })
- _logger.info('Category %s synchronized to Solr with document: %s', document)
- _logger.info('Category %s synchronized to Solr with category_id2_json: %s', category_id2_json)
- self.solr().add([document])
- category.update_last_update_solr()
-
- self.solr().commit()
-
- # def _sync_delete_solr(self):
- # for rec in self:
- # self.solr().delete(rec.id)
- # self.solr().optimize()
- # self.solr().commit() \ No newline at end of file
diff --git a/indoteknik_custom/models/stock_picking.py b/indoteknik_custom/models/stock_picking.py
index 5029a770..6083e9e7 100644
--- a/indoteknik_custom/models/stock_picking.py
+++ b/indoteknik_custom/models/stock_picking.py
@@ -107,8 +107,9 @@ class StockPicking(models.Model):
@api.constrains('arrival_time')
def constrains_arrival_time(self):
- if self.arrival_time > datetime.datetime.utcnow():
- raise UserError('Jam kedatangan harus kurang dari Effective Date')
+ for record in self:
+ if record.arrival_time and record.arrival_time > datetime.datetime.utcnow():
+ raise UserError('Jam kedatangan harus kurang dari Effective Date')
def reset_status_printed(self):
for rec in self:
diff --git a/indoteknik_custom/models/voucher.py b/indoteknik_custom/models/voucher.py
index c21ef209..f7305999 100644
--- a/indoteknik_custom/models/voucher.py
+++ b/indoteknik_custom/models/voucher.py
@@ -52,6 +52,7 @@ class Voucher(models.Model):
terms_conditions = fields.Html('Terms and Conditions')
apply_type = fields.Selection(string='Apply Type', default="all", selection=[
('all', "All product"),
+ ('shipping', "Shipping"),
('brand', "Selected product brand"),
])
count_order = fields.Integer(string='Count Order', compute='_compute_count_order')
diff --git a/indoteknik_custom/models/website_user_cart.py b/indoteknik_custom/models/website_user_cart.py
index 10821cd3..d9352abb 100644
--- a/indoteknik_custom/models/website_user_cart.py
+++ b/indoteknik_custom/models/website_user_cart.py
@@ -145,14 +145,15 @@ class WebsiteUserCart(models.Model):
}
return result
- def action_mail_reminder_to_checkout(self):
- user_ids = self.search([]).mapped('user_id')
+ def action_mail_reminder_to_checkout(self, limit=10):
+ user_ids = self.search([]).mapped('user_id')[:limit]
- # user_ids = [1102]
- for user in user_ids:
+ for user in user_ids:
latest_cart = self.search([('user_id', '=', user.id), ('is_reminder', '=', False)], order='create_date desc', limit=1)
+ # Proses semua keranjang untuk user tersebut
carts_to_remind = self.search([('user_id', '=', user.id)])
+
if latest_cart and not latest_cart.is_reminder:
for cart in carts_to_remind:
check = cart.check_product_flashsale(cart.product_id.id)
@@ -161,9 +162,12 @@ class WebsiteUserCart(models.Model):
if cart.program_line_id or check['is_flashsale'] or cart.product_id.default_code and 'BOM' in cart.product_id.default_code:
cart.is_selected = False
cart.is_reminder = True
+
+ # Mengirim email pengingat untuk keranjang terbaru
template = self.env.ref('indoteknik_custom.mail_template_user_cart_reminder_to_checkout')
template.send_mail(latest_cart.id, force_send=True)
+
def calculate_discount(self, user_id):
carts = self.search([('user_id', '=', user_id)])
voucher = self.env['voucher'].browse(146)
diff --git a/indoteknik_custom/views/approval_date_doc.xml b/indoteknik_custom/views/approval_date_doc.xml
index d6a70763..3d597aa8 100644
--- a/indoteknik_custom/views/approval_date_doc.xml
+++ b/indoteknik_custom/views/approval_date_doc.xml
@@ -7,11 +7,13 @@
<tree>
<field name="number"/>
<field name="picking_id"/>
+ <field name="partner_id"/>
<field name="sale_id"/>
<field name="driver_departure_date"/>
<field name="state"/>
<field name="approve_date"/>
<field name="approve_by"/>
+ <field name="create_uid"/>
</tree>
</field>
</record>
@@ -27,16 +29,24 @@
type="object"
attrs="{'invisible': [('state', '=', 'done')]}"
/>
+ <button name="button_cancel"
+ string="Cancel"
+ type="object"
+ attrs="{'invisible': [('state', '=', 'cancel')]}"
+ />
</header>
<sheet string="Approval Date Doc">
<group>
<group>
<field name="number"/>
<field name="picking_id"/>
+ <field name="partner_id"/>
<field name="sale_id"/>
<field name="driver_departure_date"/>
<field name="approve_date"/>
<field name="approve_by"/>
+ <field name="create_uid"/>
+ <field name="note" attrs="{'invisible': [('state', '!=', 'cancel')]}"/>
<field name="state" readonly="1"/>
</group>
</group>
diff --git a/indoteknik_custom/views/automatic_purchase.xml b/indoteknik_custom/views/automatic_purchase.xml
index cdaf6297..23aa1973 100644
--- a/indoteknik_custom/views/automatic_purchase.xml
+++ b/indoteknik_custom/views/automatic_purchase.xml
@@ -24,7 +24,7 @@
<tree editable="bottom">
<field name="brand_id"/>
<field name="product_id"/>
- <field name="taxes_id"/>
+ <field name="taxes_id" domain="[('type_tax_use','=','purchase')]"/>
<field name="qty_purchase"/>
<field name="qty_min"/>
<field name="qty_max"/>
@@ -32,7 +32,7 @@
<field name="qty_purchase"/>
<field name="partner_id" required="1"/>
<field name="last_price"/>
- <field name="taxes_id"/>
+ <field name="taxes_id" domain="[('type_tax_use','=','purchase')]"/>
<field name="subtotal"/>
<field name="last_order_id" readonly="1" optional="hide"/>
<field name="current_po_line_id" readonly="1" optional="hide"/>
diff --git a/indoteknik_custom/views/product_template.xml b/indoteknik_custom/views/product_template.xml
index 520af5c8..e3a39412 100755
--- a/indoteknik_custom/views/product_template.xml
+++ b/indoteknik_custom/views/product_template.xml
@@ -21,6 +21,9 @@
<field name="desc_update_solr" readonly="1" />
<field name="last_update_solr" readonly="1" />
</field>
+ <field name="public_categ_ids" position="attributes">
+ <attribute name="required">1</attribute>
+ </field>
<page name="inventory" position="after">
<page string="Marketplace" name="marketplace">
<group>
diff --git a/indoteknik_custom/views/voucher.xml b/indoteknik_custom/views/voucher.xml
index 71c0df0b..29d0ad4b 100755
--- a/indoteknik_custom/views/voucher.xml
+++ b/indoteknik_custom/views/voucher.xml
@@ -38,9 +38,9 @@
<field name="show_on_email" />
<field name="excl_pricelist_ids" widget="many2many_tags" domain="[('id', 'in', [4, 15037, 15038, 15039, 17023, 17024, 17025, 17026,17027])]"/>
</group>
- <group string="Discount Settings" attrs="{'invisible': [('apply_type', '!=', 'all')]}">
+ <group string="Discount Settings" attrs="{'invisible': [('apply_type', 'not in', ['all', 'shipping'])]}">
<field name="min_purchase_amount" widget="monetary" required="1" />
- <field name="discount_type" attrs="{'invisible': [('apply_type','!=','all')], 'required': [('apply_type', '=', 'all')]}" />
+ <field name="discount_type" attrs="{'invisible': [('apply_type','not in', ['all', 'shipping'])], 'required': [('apply_type', 'in', ['all', 'shipping'])]}" />
<label for="max_discount_amount" string="Discount Amount" />
<div class="d-flex align-items-center">