summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRafi Zadanly <zadanlyr@gmail.com>2023-11-10 13:40:58 +0700
committerRafi Zadanly <zadanlyr@gmail.com>2023-11-10 13:40:58 +0700
commit2aee5a44abbe36961dfe23cc3d656aa48e11e0f9 (patch)
tree8ec2b6552aaef4e14539aa52ed796552e24180d6
parent6a87e59e7220bdfa78e98b23003ccc4ef41bd0ce (diff)
parentb4e74170aeaf00937f78e5af9047218ddb17516c (diff)
Merge branch 'production' into change/feature/promotion-program
-rw-r--r--indoteknik_api/controllers/api_v1/cart.py7
-rw-r--r--indoteknik_api/controllers/api_v1/category.py17
-rw-r--r--indoteknik_api/controllers/api_v1/download.py4
-rw-r--r--indoteknik_api/controllers/api_v1/product.py182
-rw-r--r--indoteknik_api/controllers/api_v1/sale_order.py4
-rwxr-xr-xindoteknik_custom/__manifest__.py4
-rwxr-xr-xindoteknik_custom/models/__init__.py6
-rw-r--r--indoteknik_custom/models/account_bank_statement.py19
-rw-r--r--indoteknik_custom/models/account_move.py31
-rw-r--r--indoteknik_custom/models/automatic_purchase.py35
-rw-r--r--indoteknik_custom/models/commision.py275
-rw-r--r--indoteknik_custom/models/product_monitoring.py35
-rwxr-xr-xindoteknik_custom/models/product_template.py41
-rwxr-xr-xindoteknik_custom/models/purchase_order.py30
-rwxr-xr-xindoteknik_custom/models/purchase_order_line.py1
-rwxr-xr-xindoteknik_custom/models/purchase_pricelist.py2
-rw-r--r--indoteknik_custom/models/requisition.py223
-rw-r--r--indoteknik_custom/models/res_partner.py2
-rwxr-xr-xindoteknik_custom/models/sale_monitoring.py34
-rwxr-xr-xindoteknik_custom/models/sale_monitoring_detail.py2
-rwxr-xr-xindoteknik_custom/models/sale_order.py50
-rw-r--r--indoteknik_custom/models/sale_order_line.py32
-rw-r--r--indoteknik_custom/models/solr/apache_solr_queue.py5
-rw-r--r--indoteknik_custom/models/solr/product_product.py64
-rw-r--r--indoteknik_custom/models/solr/product_template.py94
-rw-r--r--indoteknik_custom/models/solr/x_manufactures.py2
-rw-r--r--indoteknik_custom/models/stock_picking.py8
-rw-r--r--indoteknik_custom/models/stock_warehouse_orderpoint.py10
-rw-r--r--indoteknik_custom/models/users.py1
-rw-r--r--indoteknik_custom/models/voucher.py2
-rw-r--r--indoteknik_custom/models/voucher_line.py2
-rw-r--r--indoteknik_custom/models/website_user_cart.py9
-rwxr-xr-xindoteknik_custom/models/x_manufactures.py2
-rwxr-xr-xindoteknik_custom/security/ir.model.access.csv6
-rw-r--r--indoteknik_custom/views/account_bank_statement.xml31
-rw-r--r--indoteknik_custom/views/account_move.xml13
-rw-r--r--indoteknik_custom/views/automatic_purchase.xml2
-rw-r--r--indoteknik_custom/views/customer_commision.xml189
-rw-r--r--indoteknik_custom/views/ir_sequence.xml10
-rw-r--r--indoteknik_custom/views/product_monitoring.xml55
-rwxr-xr-xindoteknik_custom/views/product_template.xml2
-rwxr-xr-xindoteknik_custom/views/purchase_order.xml41
-rwxr-xr-xindoteknik_custom/views/purchase_pricelist.xml6
-rw-r--r--indoteknik_custom/views/requisition.xml25
-rw-r--r--indoteknik_custom/views/res_partner.xml2
-rwxr-xr-xindoteknik_custom/views/sale_monitoring.xml10
-rwxr-xr-xindoteknik_custom/views/sale_order.xml9
-rw-r--r--indoteknik_custom/views/stock_picking.xml2
-rw-r--r--indoteknik_custom/views/stock_warehouse_orderpoint.xml15
-rw-r--r--indoteknik_custom/views/users.xml1
-rwxr-xr-xindoteknik_custom/views/x_manufactures.xml2
51 files changed, 1326 insertions, 330 deletions
diff --git a/indoteknik_api/controllers/api_v1/cart.py b/indoteknik_api/controllers/api_v1/cart.py
index 88fa9f88..8ef2c1c1 100644
--- a/indoteknik_api/controllers/api_v1/cart.py
+++ b/indoteknik_api/controllers/api_v1/cart.py
@@ -14,8 +14,9 @@ class Cart(controller.Controller):
user_id = int(user_id)
limit = int(kw.get('limit', 0))
offset = int(kw.get('offset', 0))
- query = [('user_id', '=', user_id), ('source', '=', 'add_to_cart')]
+ query = [('user_id', '=', user_id)]
carts = user_cart.search(query, limit=limit, offset=offset, order='create_date desc')
+ carts.write({'source': 'add_to_cart'})
data = {
'product_total': user_cart.search_count(query),
'products': carts.with_context(price_for="web").get_products()
@@ -26,7 +27,7 @@ class Cart(controller.Controller):
@controller.Controller.must_authorized()
def get_cart_count_by_user_id(self, user_id, **kw):
user_id = int(user_id)
- query = [('user_id', '=', user_id), ('source', '=', 'add_to_cart')]
+ query = [('user_id', '=', user_id)]
carts = request.env['website.user.cart'].search_count(query)
return self.response(carts)
@@ -77,7 +78,7 @@ class Cart(controller.Controller):
data_to_update['source'] = source
result = {}
- if cart and source in (None, 'add_to_cart'):
+ if cart:
# Update existing cart entry
cart.write(data_to_update)
result['id'] = cart.id
diff --git a/indoteknik_api/controllers/api_v1/category.py b/indoteknik_api/controllers/api_v1/category.py
index 3c5766e2..44a60bc9 100644
--- a/indoteknik_api/controllers/api_v1/category.py
+++ b/indoteknik_api/controllers/api_v1/category.py
@@ -120,4 +120,19 @@ class Category(controller.Controller):
'name': category.name
})
return self.response(data)
- \ No newline at end of file
+
+ @http.route(prefix + 'category/<id>/category-breadcrumb', auth='public', methods=['GET', 'OPTIONS'])
+ @controller.Controller.must_authorized()
+ def get_category_parents_by_id(self, id, **kw):
+ categories = []
+
+ category = request.env['product.public.category'].search([('id', '=', int(id))], limit=1)
+ if not category:
+ return self.response(code=400, description='Category not found')
+
+ while category:
+ categories.append({'id': category.id, 'name': category.name})
+ category = category.parent_frontend_id
+
+ categories.reverse()
+ return self.response(categories, headers=[('Cache-Control', 'max-age=3600, public')]) \ No newline at end of file
diff --git a/indoteknik_api/controllers/api_v1/download.py b/indoteknik_api/controllers/api_v1/download.py
index d9353896..54b09372 100644
--- a/indoteknik_api/controllers/api_v1/download.py
+++ b/indoteknik_api/controllers/api_v1/download.py
@@ -28,7 +28,7 @@ class Download(controller.Controller):
return rest_api.response_attachment({
'content': pdf,
'mimetype': 'application/pdf',
- 'filename': account_move[0]['name']
+ 'filename': account_move[0]['name'] + '.pdf'
})
@http.route(PREFIX + 'download/tax-invoice/<id>/<token>', auth='none', method=['GET'])
@@ -47,6 +47,6 @@ class Download(controller.Controller):
'content': attachment['datas'],
'decode_content': True,
'mimetype': attachment['mimetype'],
- 'filename': account_move[0]['name'],
+ 'filename': account_move[0]['name'] + '.pdf',
})
return self.response('Dokumen tidak ditemukan', code=404)
diff --git a/indoteknik_api/controllers/api_v1/product.py b/indoteknik_api/controllers/api_v1/product.py
index 2cbdede7..1b698f26 100644
--- a/indoteknik_api/controllers/api_v1/product.py
+++ b/indoteknik_api/controllers/api_v1/product.py
@@ -2,7 +2,10 @@ from .. import controller
from odoo import http
from odoo.http import request
from datetime import datetime, timedelta
-import ast, logging, math, json
+import ast
+import logging
+import math
+import json
_logger = logging.getLogger(__name__)
@@ -10,20 +13,43 @@ _logger = logging.getLogger(__name__)
class Product(controller.Controller):
prefix = '/api/v1/'
+ @http.route(prefix + 'product/<id>/category-breadcrumb', auth='public', methods=['GET', 'OPTIONS'])
+ @controller.Controller.must_authorized()
+ def get_product_categories_by_id(self, id, **kw):
+ categories = []
+
+ product = request.env['product.template'].search(
+ [('id', '=', int(id))], limit=1)
+ if not product:
+ return self.response(code=400, description='Product not found')
+
+ if len(product.public_categ_ids) == 0:
+ return self.response(categories)
+
+ category = product.public_categ_ids[0]
+ while category:
+ categories.append({'id': category.id, 'name': category.name})
+ category = category.parent_frontend_id
+
+ categories.reverse()
+ return self.response(categories, headers=[('Cache-Control', 'max-age=3600, public')])
+
@http.route(prefix + 'product_variant/<id>/stock', auth='public', methods=['GET', 'OPTIONS'])
@controller.Controller.must_authorized()
def get_product_template_stock_by_id(self, **kw):
id = int(kw.get('id'))
date_7_days_ago = datetime.now() - timedelta(days=7)
- product = request.env['product.product'].search([('id', '=', id)], limit=1)
- product_sla = request.env['product.sla'].search([('product_variant_id', '=', id)], limit=1)
+ product = request.env['product.product'].search(
+ [('id', '=', id)], limit=1)
+ product_sla = request.env['product.sla'].search(
+ [('product_variant_id', '=', id)], limit=1)
stock_vendor = request.env['stock.vendor'].search([
('product_variant_id', '=', id),
('write_date', '>=', date_7_days_ago.strftime("%Y-%m-%d %H:%M:%S"))
], limit=1)
qty_available = product.qty_onhand_bandengan
-
+
qty = 0
sla_date = '-'
@@ -33,22 +59,23 @@ class Product(controller.Controller):
qty_vendor = math.ceil(float(qty_vendor))
total_excell = qty_vendor
- is_altama_product = product.x_manufacture.id in [10,122,89]
+ is_altama_product = product.x_manufacture.id in [10, 122, 89]
if is_altama_product:
try:
# Qty Altama
- qty_altama = request.env['product.template'].get_stock_altama(product.default_code)
+ qty_altama = request.env['product.template'].get_stock_altama(
+ product.default_code)
qty_altama -= int(qty_altama * 0.1)
qty_altama = math.ceil(float(qty_altama))
- total_adem = qty_altama
-
+ total_adem = qty_altama
+
if qty_available > 0:
qty = qty_available + total_adem + total_excell
sla_date = '1 Hari'
elif qty_altama > 0 or qty_vendor > 0:
qty = total_adem if qty_altama > 0 else total_excell
sla_date = '2-4 Hari'
- else:
+ else:
sla_date = '3-7 Hari'
except:
print('error')
@@ -56,10 +83,9 @@ class Product(controller.Controller):
if qty_available > 0:
qty = qty_available
sla_date = product_sla.sla or '-'
- elif qty_vendor > 0:
+ elif qty_vendor > 0:
qty = total_excell
sla_date = '2-4 Hari'
-
data = {
'qty': qty,
@@ -68,14 +94,14 @@ class Product(controller.Controller):
return self.response(data, headers=[('Cache-Control', 'max-age=600, private')])
-
@http.route(prefix + 'product/template/price/<id>', auth='public', methods=['GET', 'OPTIONS'])
def get_product_template_price_by_id(self, **kw):
if not self.authenticate():
return self.response(code=401, description='Unauthorized')
id = kw.get('id')
partner_id = int(kw.get('partner_id', 0))
- product_template = request.env['product.template'].search([('id', '=', id)], limit=1)
+ product_template = request.env['product.template'].search(
+ [('id', '=', id)], limit=1)
data = {
'price_include': product_template.product_variant_id._get_website_price_include_tax(),
@@ -106,14 +132,15 @@ class Product(controller.Controller):
data.update(start_from)
return self.response(data, headers=[('Cache-Control', 'max-age=180, private')])
-
+
@http.route(prefix + 'product/product/price/<id>', auth='public', methods=['GET', 'OPTIONS'])
def get_product_product_price_by_id(self, **kw):
if not self.authenticate():
return self.response(code=401, description='Unauthorized')
id = kw.get('id')
- partner_id = int(kw.get('partner_id', 0))
- product_product = request.env['product.product'].search([('id', '=', id)], limit=1)
+ partner_id = int(kw.get('partner_id', 0))
+ product_product = request.env['product.product'].search(
+ [('id', '=', id)], limit=1)
data = {
'price_include': product_product._get_website_price_include_tax(),
@@ -132,7 +159,8 @@ class Product(controller.Controller):
is_brand_only = int(kw.get('is_brand_only', 0))
base_url = request.env['ir.config_parameter'].get_param('web.base.url')
- limit_new_products = request.env['ir.config_parameter'].get_param('limit.new.product')
+ 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)
@@ -147,8 +175,9 @@ class Product(controller.Controller):
('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 = []
+ 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))
@@ -179,11 +208,13 @@ class Product(controller.Controller):
('x_manufacture', '!=', False),
# ('create_date', '>=', delta_time),
]
- count_products = request.env['product.template'].search_count(query)
+ 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)
+ products = request.env['product.template'].search(
+ query, order='create_date desc', limit=12)
data.append({
'manufacture_id': brand.id,
'sequence': brand.sequence if brand.sequence else count,
@@ -205,18 +236,19 @@ class Product(controller.Controller):
categories = kw.get('categories')
promotions = kw.get('promotions')
ready_stock = kw.get('ready_stock')
-
- require_betweens = ['name', 'manufactures', 'categories', 'ready_stock', 'promotions']
- is_fulfill = False
+
+ require_betweens = ['name', 'manufactures',
+ 'categories', 'ready_stock', 'promotions']
+ is_fulfill = False
for required in require_betweens:
if kw.get(required):
is_fulfill = True
-
+
if not is_fulfill:
return self.response(code=400, description='name or manufactures or categories or ready_stock or promotions is required')
-
+
query = [('sale_ok', '=', True)]
-
+
if name:
name = '%' + name.replace(' ', '%') + '%'
query += [
@@ -224,44 +256,49 @@ class Product(controller.Controller):
('default_code', 'ilike', name),
('name', 'ilike', name),
]
-
+
if manufactures:
- query.append(('x_manufacture', 'in', [int(x) for x in manufactures.split(',')]))
-
+ query.append(('x_manufacture', 'in', [
+ int(x) for x in manufactures.split(',')]))
+
if categories:
- query.append(('public_categ_ids', 'child_of', [int(x) for x in categories.split(',')]))
-
+ query.append(('public_categ_ids', 'child_of', [
+ int(x) for x in categories.split(',')]))
+
if ready_stock == '1':
query.append(('virtual_qty', '>', 0))
-
+
if promotions:
- coupon_programs = request.env['coupon.program'].search([('id', 'in', promotions.split(','))])
- promotion_query = [x for coupon_program in coupon_programs for x in ast.literal_eval(coupon_program.rule_products_domain)]
+ coupon_programs = request.env['coupon.program'].search(
+ [('id', 'in', promotions.split(','))])
+ promotion_query = [x for coupon_program in coupon_programs for x in ast.literal_eval(
+ coupon_program.rule_products_domain)]
query += promotion_query
-
+
price_from = kw.get('price_from')
if price_from and int(price_from):
query.append(('web_price_sorting', '>=', int(price_from)))
-
+
price_to = kw.get('price_to')
if price_to and int(price_to):
query.append(('web_price_sorting', '<=', int(price_to)))
-
+
product_variants = request.env['product.product'].search(query)
product_variant_ids = [x.id for x in product_variants]
-
+
query = [('product_variant_ids', 'in', product_variant_ids)]
limit = int(kw.get('limit', 0))
offset = int(kw.get('offset', 0))
order = self.get_product_default_order(kw.get('order'))
-
- product_templates = request.env['product.template'].search(query, limit=limit, offset=offset, order=order)
+
+ product_templates = request.env['product.template'].search(
+ query, limit=limit, offset=offset, order=order)
data = {
'product_total': request.env['product.template'].search_count(query),
'products': [request.env['product.template'].api_single_response(x) for x in product_templates]
}
return self.response(data)
-
+
@http.route(prefix + 'product/solr', auth='public', methods=['GET'])
@controller.Controller.must_authorized()
def get_product_solr(self, **kw):
@@ -269,10 +306,10 @@ class Product(controller.Controller):
solr_flag = kw.get('flag')
limit = int(kw.get('limit', 0))
offset = int(kw.get('offset', 0))
-
+
if not solr_flag:
return self.response(code=400, description='flag is required')
-
+
query = [
('sale_ok', '=', True),
('solr_flag', '=', int(solr_flag))
@@ -284,13 +321,14 @@ class Product(controller.Controller):
('default_code', 'ilike', name),
('name', 'ilike', name),
]
- product_templates = request.env['product.template'].search(query, limit=limit, offset=offset)
+ product_templates = request.env['product.template'].search(
+ query, limit=limit, offset=offset)
data = {
'product_total': request.env['product.template'].search_count(query),
'products': [request.env['product.template'].api_single_response(x, with_detail='SOLR') for x in product_templates]
}
return self.response(data)
-
+
@http.route(prefix + 'product/<id>', auth='public', methods=['GET'])
@controller.Controller.must_authorized()
def get_product_by_id(self, **kw):
@@ -300,53 +338,60 @@ class Product(controller.Controller):
data = []
id = [int(x) for x in id.split(',')]
- product_templates = request.env['product.template'].search([('id', 'in', id)])
+ product_templates = request.env['product.template'].search(
+ [('id', 'in', id)])
if product_templates:
- data = [request.env['product.template'].api_single_response(x, with_detail='DEFAULT') for x in product_templates]
-
+ data = [request.env['product.template'].api_single_response(
+ x, with_detail='DEFAULT') for x in product_templates]
+
return self.response(data)
-
+
@http.route(prefix + 'product/<id>/similar', auth='public', methods=['GET', 'OPTIONS'])
@controller.Controller.must_authorized()
def get_product_similar_by_id(self, **kw):
id = kw.get('id')
if not id:
return self.response(code=400, description='id is required')
-
+
id = int(id)
- product_template = request.env['product.template'].search([('id', '=', id)])
-
- if not product_template: return self.response([])
-
+ product_template = request.env['product.template'].search(
+ [('id', '=', id)])
+
+ if not product_template:
+ return self.response([])
+
query = [('id', '!=', id)]
if product_template.x_manufacture:
- query.append(('x_manufacture', '=', product_template.x_manufacture.id))
+ query.append(
+ ('x_manufacture', '=', product_template.x_manufacture.id))
if product_template.public_categ_ids:
- query.append(('public_categ_ids', 'in', [x.id for x in product_template.public_categ_ids]))
+ query.append(('public_categ_ids', 'in', [
+ x.id for x in product_template.public_categ_ids]))
if len(query) == 2:
query.insert(0, '|')
-
+
limit = int(kw.get('limit', 0))
offset = int(kw.get('offset', 0))
order = self.get_product_default_order(kw.get('order'))
- product_templates = request.env['product.template'].search(query, limit=limit, offset=offset, order=order)
-
+ product_templates = request.env['product.template'].search(
+ query, limit=limit, offset=offset, order=order)
+
data = {
'product_total': request.env['product.template'].search_count(query),
'products': [request.env['product.template'].api_single_response(x) for x in product_templates]
}
return self.response(data)
-
+
def get_product_default_order(self, order):
orders = ['product_rating desc']
if order != 'price-asc':
orders.append('web_price_sorting desc')
- if order == 'price-asc':
+ if order == 'price-asc':
orders.append('web_price_sorting asc')
- elif order == 'latest':
+ elif order == 'latest':
orders.append('create_date desc')
return ','.join(orders)
-
+
@http.route(prefix + 'product/category-homepage', auth='public', methods=['GET', 'OPTIONS'])
@controller.Controller.must_authorized()
def get_product_category_homepage(self, **kw):
@@ -356,13 +401,14 @@ class Product(controller.Controller):
id = kw.get('id')
if id:
query = f'id:{id}'
-
- categories = solr_model.connect('product_category_homepage').search(query, sort='sequence_i asc').docs
+
+ categories = solr_model.connect('product_category_homepage').search(
+ query, sort='sequence_i asc').docs
categories = solr_model.clean_key_docs(categories)
for category in categories:
product_ids = category.get('product_ids', [])
category.pop('product_ids', None)
products = request.env['product.template'].browse(product_ids)
category['products'] = products.solr_results()
-
- return self.response(categories, headers=[('Cache-Control', 'max-age=3600, public')]) \ No newline at end of file
+
+ return self.response(categories, headers=[('Cache-Control', 'max-age=3600, public')])
diff --git a/indoteknik_api/controllers/api_v1/sale_order.py b/indoteknik_api/controllers/api_v1/sale_order.py
index 8209c751..0f236ffb 100644
--- a/indoteknik_api/controllers/api_v1/sale_order.py
+++ b/indoteknik_api/controllers/api_v1/sale_order.py
@@ -181,7 +181,7 @@ class SaleOrder(controller.Controller):
'content': attachment['datas'],
'decode_content': True,
'mimetype': attachment['mimetype'],
- 'filename': sale_order[0]['partner_purchase_order_name']
+ 'filename': sale_order[0]['partner_purchase_order_name'] + '.pdf'
})
return self.response('Dokumen tidak ditemukan', code=404)
@@ -202,7 +202,7 @@ class SaleOrder(controller.Controller):
return rest_api.response_attachment({
'content': pdf,
'mimetype': 'application/pdf',
- 'filename': sale_order[0]['name']
+ 'filename': sale_order[0]['name'] + '.pdf'
})
return self.response('Dokumen tidak ditemukan', code=404)
diff --git a/indoteknik_custom/__manifest__.py b/indoteknik_custom/__manifest__.py
index 6ae60345..bab86aab 100755
--- a/indoteknik_custom/__manifest__.py
+++ b/indoteknik_custom/__manifest__.py
@@ -98,6 +98,10 @@
'views/sale_orders_multi_update.xml',
'views/quotation_so_multi_update.xml',
'views/stock_move_line.xml',
+ 'views/product_monitoring.xml',
+ 'views/account_bank_statement.xml',
+ 'views/stock_warehouse_orderpoint.xml',
+ 'views/customer_commision.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 2eb4b9b9..37e6cce0 100755
--- a/indoteknik_custom/models/__init__.py
+++ b/indoteknik_custom/models/__init__.py
@@ -88,4 +88,8 @@ from . import account_account
from . import account_move_line
from . import stock_scheduler_compute
from . import sale_orders_multi_update
-from . import quotation_so_multi_update \ No newline at end of file
+from . import quotation_so_multi_update
+from . import product_monitoring
+from . import account_bank_statement
+from . import stock_warehouse_orderpoint
+from . import commision
diff --git a/indoteknik_custom/models/account_bank_statement.py b/indoteknik_custom/models/account_bank_statement.py
new file mode 100644
index 00000000..23008f13
--- /dev/null
+++ b/indoteknik_custom/models/account_bank_statement.py
@@ -0,0 +1,19 @@
+from odoo import fields, models, api, _
+from odoo.exceptions import AccessError, UserError, ValidationError
+
+class AccountBankStatement(models.Model):
+ _inherit = "account.bank.statement"
+
+ is_edit = fields.Boolean(string='Unlock', default=False)
+
+ def is_edited(self):
+ if not self.env.user.is_admin_reconcile:
+ raise UserError('Yang berhak hanya Mba Tania dan Iqmal Saputra')
+
+ self.is_edit = True
+
+ def not_edited(self):
+ if not self.env.user.is_admin_reconcile:
+ raise UserError('Yang berhak hanya Mba Tania dan Iqmal Saputra')
+
+ self.is_edit = False \ No newline at end of file
diff --git a/indoteknik_custom/models/account_move.py b/indoteknik_custom/models/account_move.py
index c3cd7ef9..fe9db583 100644
--- a/indoteknik_custom/models/account_move.py
+++ b/indoteknik_custom/models/account_move.py
@@ -1,6 +1,7 @@
from odoo import models, api, fields
from odoo.exceptions import AccessError, UserError, ValidationError
-from datetime import timedelta, date
+from datetime import timedelta, date, datetime
+from pytz import timezone, utc
import logging
import base64
import PyPDF2
@@ -13,6 +14,7 @@ _logger = logging.getLogger(__name__)
class AccountMove(models.Model):
_inherit = 'account.move'
invoice_day_to_due = fields.Integer(string="Day to Due", compute="_compute_invoice_day_to_due")
+ bill_day_to_due = fields.Date(string="Day to Due", compute="_compute_bill_day_to_due")
date_send_fp = fields.Datetime(string="Tanggal Kirim Faktur Pajak")
last_log_fp = fields.Char(string="Log Terakhir Faktur Pajak")
# use for industry business
@@ -28,6 +30,7 @@ class AccountMove(models.Model):
analytic_account_ids = fields.Many2many('account.analytic.account', string='Analytic Account')
due_line = fields.One2many('due.extension.line', 'invoice_id', compute='_compute_due_line', string='Due Extension Lines')
no_faktur_pajak = fields.Char(string='No Faktur Pajak')
+ date_completed = fields.Datetime(string='Date Completed')
@api.onchange('efaktur_id')
def change_efaktur_id(self):
@@ -59,6 +62,11 @@ class AccountMove(models.Model):
res = super(AccountMove, self).button_draft()
if not self.env.user.is_accounting:
raise UserError('Hanya Accounting yang bisa Reset to Draft')
+
+ for rec in self.line_ids:
+ if rec.write_date != rec.create_date:
+ if rec.statement_line_id and not rec.statement_line_id.statement_id.is_edit and rec.statement_line_id.statement_id.state == 'confirm':
+ raise UserError('Bank Statement di Lock, Minta admin reconcile untuk unlock')
return res
def action_post(self):
@@ -90,8 +98,10 @@ class AccountMove(models.Model):
# raise UserError('Hanya Accounting yang bisa Posting')
# if self._name == 'account.move':
for entry in self:
+ entry.date_completed = datetime.utcnow()
for line in entry.line_ids:
line.date_maturity = entry.date
+
return res
def _compute_invoice_day_to_due(self):
@@ -103,6 +113,10 @@ class AccountMove(models.Model):
invoice_day_to_due = invoice.new_due_date - date.today()
invoice_day_to_due = invoice_day_to_due.days
invoice.invoice_day_to_due = invoice_day_to_due
+
+ def _compute_bill_day_to_due(self):
+ for rec in self:
+ rec.bill_day_to_due = rec.payment_schedule or rec.invoice_date_due
@api.onchange('date_kirim_tukar_faktur')
def change_date_kirim_tukar_faktur(self):
@@ -136,4 +150,17 @@ class AccountMove(models.Model):
'move_ids': [x.id for x in self]
}
return action
- \ No newline at end of file
+
+ @api.constrains('efaktur_id', 'ref', 'date', 'journal_id', 'name')
+ def constrains_edit(self):
+ for rec in self.line_ids:
+ if rec.statement_line_id and not rec.statement_line_id.statement_id.is_edit and rec.statement_line_id.statement_id.state == 'confirm':
+ raise UserError('Bank Statement di Lock, Minta admin reconcile untuk unlock')
+
+ # def write(self, vals):
+ # res = super(AccountMove, self).write(vals)
+ # for rec in self.line_ids:
+ # if rec.write_date != rec.create_date:
+ # if rec.statement_line_id and not rec.statement_line_id.statement_id.is_edit and rec.statement_line_id.statement_id.state == 'confirm':
+ # raise UserError('Bank Statement di Lock, Minta admin reconcile untuk unlock')
+ # return res
diff --git a/indoteknik_custom/models/automatic_purchase.py b/indoteknik_custom/models/automatic_purchase.py
index e21b411d..502761e0 100644
--- a/indoteknik_custom/models/automatic_purchase.py
+++ b/indoteknik_custom/models/automatic_purchase.py
@@ -17,6 +17,7 @@ class AutomaticPurchase(models.Model):
is_po = fields.Boolean(string='Is PO')
purchase_match = fields.One2many('automatic.purchase.match', 'automatic_purchase_id', string='Matches', auto_join=True)
vendor_id = fields.Many2one('res.partner', string='Vendor', help='boleh kosong, jika diisi, maka hanya keluar data untuk vendor tersebut')
+ responsible_id = fields.Many2one('res.users', string='Responsible', required=True)
def create_po_from_automatic_purchase(self):
if not self.purchase_lines:
@@ -30,12 +31,13 @@ class AutomaticPurchase(models.Model):
for vendor in vendor_ids:
param_header = {
'partner_id': vendor['partner_id'][0],
- 'partner_ref': 'Automatic PO',
+ # 'partner_ref': 'Automatic PO',
'currency_id': 12,
'user_id': self.env.user.id,
'company_id': 1, # indoteknik dotcom gemilang
'picking_type_id': 28, # indoteknik bandengan receipts
- 'date_order': current_time
+ 'date_order': current_time,
+ 'note_description': 'Automatic PO'
}
# new_po = self.env['purchase.order'].create([param_header])
products_vendors = self.env['automatic.purchase.line'].search([
@@ -86,7 +88,8 @@ class AutomaticPurchase(models.Model):
raise UserError('Sudah digenerate sebelumnya, hapus line terlebih dahulu')
query = [
- ('product_min_qty', '>', 0)
+ ('product_min_qty', '>', 0),
+ ('product_id.x_manufacture.user_id.id', '=', self.responsible_id.id)
]
orderpoints = self.env['stock.warehouse.orderpoint'].search(query)
count = 0
@@ -100,13 +103,20 @@ class AutomaticPurchase(models.Model):
if self.vendor_id:
purchase_price = self.env['purchase.pricelist'].search([
('product_id', '=', point.product_id.id),
+ # ('product_id.x_manufacture.user_id.id', '=', self.responsible_id.id),
('vendor_id', '=', self.vendor_id.id)
- ], order='product_price asc', limit=1)
+ ], order='count_trx_po desc, count_trx_po_vendor desc', limit=1)
else:
- purchase_price = self.env['purchase.pricelist'].search([('product_id', '=', point.product_id.id)], order='product_price asc', limit=1)
+ purchase_price = self.env['purchase.pricelist'].search([
+ ('product_id', '=', point.product_id.id),
+ # ('product_id.x_manufacture.user_id.id', '=', self.responsible_id.id),
+ ], order='count_trx_po desc, count_trx_po_vendor desc', limit=1)
vendor_id = purchase_price.vendor_id.id
- price = purchase_price.product_price or 0
+ price = self._get_valid_purchase_price(purchase_price)
+
+ if self.vendor_id and self.vendor_id.id != vendor_id:
+ continue
self.env['automatic.purchase.line'].create([{
'automatic_purchase_id': self.id,
@@ -128,6 +138,19 @@ class AutomaticPurchase(models.Model):
_logger.info('Create Automatic Purchase Line %s' % point.product_id.name)
self.notification = "Automatic PO Created %s Lines" % count
+ def _get_valid_purchase_price(self, purchase_price):
+ p_price = 0
+ if purchase_price.system_price > 0 and purchase_price.product_price > 0:
+ if purchase_price.human_last_update > purchase_price.system_last_update:
+ p_price = purchase_price.product_price
+ else:
+ p_price = purchase_price.system_price
+ elif purchase_price.system_price > 0 and purchase_price.product_price == 0:
+ p_price = purchase_price.system_price
+ elif purchase_price.system_price == 0 and purchase_price.product_price > 0:
+ p_price = purchase_price.product_price
+ return p_price
+
class AutomaticPurchaseLine(models.Model):
_name = 'automatic.purchase.line'
diff --git a/indoteknik_custom/models/commision.py b/indoteknik_custom/models/commision.py
new file mode 100644
index 00000000..d4942a0d
--- /dev/null
+++ b/indoteknik_custom/models/commision.py
@@ -0,0 +1,275 @@
+from odoo import models, api, fields
+from odoo.exceptions import UserError
+from datetime import datetime
+import logging
+
+_logger = logging.getLogger(__name__)
+
+
+class CustomerRebate(models.Model):
+ _name = 'customer.rebate'
+ _order = 'id desc'
+ _inherit = ['mail.thread']
+
+ partner_id = fields.Many2one('res.partner', string='Customer', required=True)
+ date_from = fields.Date(string='Date From', required=True, help="Pastikan tanggal 1 januari, jika tidak, code akan break")
+ date_to = fields.Date(string='Date To', required=True, help="Pastikan tanggal 31 desember, jika tidak, code akan break")
+ description = fields.Char(string='Description')
+ target_1st = fields.Float(string='Target/Quarter 1st')
+ target_2nd = fields.Float(string='Target/Quarter 2nd')
+ achieve_1 = fields.Float(string='Achieve 1 %')
+ achieve_2 = fields.Float(string='Achieve 2 %')
+ dpp_q1 = fields.Float(string='DPP Q1', compute='_compute_current_dpp')
+ dpp_q2 = fields.Float(string='DPP Q2', compute='_compute_current_dpp')
+ dpp_q3 = fields.Float(string='DPP Q3', compute='_compute_current_dpp')
+ dpp_q4 = fields.Float(string='DPP Q4', compute='_compute_current_dpp')
+ status_q1 = fields.Char(string='Status Q1', compute='_compute_achievement')
+ status_q2 = fields.Char(string='Status Q2', compute='_compute_achievement')
+ status_q3 = fields.Char(string='Status Q3', compute='_compute_achievement')
+ status_q4 = fields.Char(string='Status Q4', compute='_compute_achievement')
+
+ # all code class CustomerRebate deprecated, cause lack of performance
+ def _compute_current_dpp(self):
+ for line in self:
+ line.dpp_q1 = line._get_current_dpp_q1(line)
+ line.dpp_q2 = line._get_current_dpp_q2(line)
+ line.dpp_q3 = line._get_current_dpp_q3(line)
+ line.dpp_q4 = line._get_current_dpp_q4(line)
+
+ def _compute_achievement(self):
+ for line in self:
+ line.status_q1 = line._check_achievement(line.target_1st, line.target_2nd, line.dpp_q1)
+ line.status_q2 = line._check_achievement(line.target_1st, line.target_2nd, line.dpp_q2)
+ line.status_q3 = line._check_achievement(line.target_1st, line.target_2nd, line.dpp_q3)
+ line.status_q4 = line._check_achievement(line.target_1st, line.target_2nd, line.dpp_q4)
+
+ def _check_achievement(self, target_1st, target_2nd, dpp):
+ status = 'not achieve'
+ if dpp >= target_1st:
+ status = '1st'
+ elif dpp >= target_2nd:
+ status = '2nd'
+ else:
+ status = 'not achieve'
+ return status
+
+ def _get_current_dpp_q1(self, line):
+ sum_dpp = 0
+ brand = [10, 89, 122]
+ where = [
+ ('move_id.move_type', '=', 'out_invoice'),
+ ('move_id.state', '=', 'posted'),
+ ('move_id.is_customer_commision', '=', False),
+ ('move_id.partner_id.id', '=', line.partner_id.id),
+ ('move_id.invoice_date', '>=', line.date_from),
+ ('move_id.invoice_date', '<=', '2023-03-31'),
+ ('product_id.x_manufacture', 'in', brand),
+ ]
+ invoice_lines = self.env['account.move.line'].search(where, order='id')
+ for invoice_line in invoice_lines:
+ sum_dpp += invoice_line.price_subtotal
+ return sum_dpp
+
+ def _get_current_dpp_q2(self, line):
+ sum_dpp = 0
+ brand = [10, 89, 122]
+ where = [
+ ('move_id.move_type', '=', 'out_invoice'),
+ ('move_id.state', '=', 'posted'),
+ ('move_id.is_customer_commision', '=', False),
+ ('move_id.partner_id.id', '=', line.partner_id.id),
+ ('move_id.invoice_date', '>=', '2023-04-01'),
+ ('move_id.invoice_date', '<=', '2023-06-30'),
+ ('product_id.x_manufacture', 'in', brand),
+ ]
+ invoices = self.env['account.move.line'].search(where, order='id')
+ for invoice in invoices:
+ sum_dpp += invoice.price_subtotal
+ return sum_dpp
+
+ def _get_current_dpp_q3(self, line):
+ sum_dpp = 0
+ brand = [10, 89, 122]
+ where = [
+ ('move_id.move_type', '=', 'out_invoice'),
+ ('move_id.state', '=', 'posted'),
+ ('move_id.is_customer_commision', '=', False),
+ ('move_id.partner_id.id', '=', line.partner_id.id),
+ ('move_id.invoice_date', '>=', '2023-07-01'),
+ ('move_id.invoice_date', '<=', '2023-09-30'),
+ ('product_id.x_manufacture', 'in', brand),
+ ]
+ invoices = self.env['account.move.line'].search(where, order='id')
+ for invoice in invoices:
+ sum_dpp += invoice.price_subtotal
+ return sum_dpp
+
+ def _get_current_dpp_q4(self, line):
+ sum_dpp = 0
+ brand = [10, 89, 122]
+ where = [
+ ('move_id.move_type', '=', 'out_invoice'),
+ ('move_id.state', '=', 'posted'),
+ ('move_id.is_customer_commision', '=', False),
+ ('move_id.partner_id.id', '=', line.partner_id.id),
+ ('move_id.invoice_date', '>=', '2023-10-01'),
+ ('move_id.invoice_date', '<=', line.date_to),
+ ('product_id.x_manufacture', 'in', brand),
+ ]
+ invoices = self.env['account.move.line'].search(where, order='id')
+ for invoice in invoices:
+ sum_dpp += invoice.price_subtotal
+ return sum_dpp
+
+
+class CustomerCommision(models.Model):
+ _name = 'customer.commision'
+ _order = 'id desc'
+ _inherit = ['mail.thread']
+ _rec_name = 'number'
+
+ number = fields.Char(string='Document No', index=True, copy=False, readonly=True)
+ date_from = fields.Date(string='Date From', required=True)
+ date_to = fields.Date(string='Date To', required=True)
+ partner_id = fields.Many2one('res.partner', String='Customer', required=True)
+ description = fields.Char(string='Description')
+ notification = fields.Char(string='Notification')
+ commision_lines = fields.One2many('customer.commision.line', 'customer_commision_id', string='Lines', auto_join=True)
+ status = fields.Selection([
+ ('pengajuan1', 'Menunggu Approval Marketing'),
+ ('pengajuan2', 'Menunggu Approval Pimpinan'),
+ ('approved', 'Approved')
+ ], string='Status', copy=False, readonly=True, tracking=3)
+ commision_percent = fields.Float(string='Commision %', tracking=3)
+ commision_amt = fields.Float(string='Commision Amount', tracking=3)
+ total_dpp = fields.Float(string='Total DPP', compute='_compute_total_dpp')
+ commision_type = fields.Selection([
+ ('fee', 'Fee'),
+ ('cashback', 'Cashback'),
+ ('rebate', 'Rebate'),
+ ], string='Commision Type', required=True)
+
+ # add status for type of commision, fee, rebate / cashback
+ # include child or not?
+
+ @api.constrains('commision_percent')
+ def _onchange_commision_percent(self):
+ print('masuk onchange commision percent')
+ self.commision_amt = self.commision_percent * self.total_dpp // 100
+
+ # @api.constrains('commision_amt')
+ # def _onchange_commision_amt(self):
+ # print('masuk onchange commision amt')
+ # self.commision_percent = (self.commision_amt / self.grand_total * 100)
+
+ def _compute_total_dpp(self):
+ for data in self:
+ total_dpp = 0
+ for line in data.commision_lines:
+ total_dpp = total_dpp + line.dpp
+ data.total_dpp = total_dpp
+
+ @api.model
+ def create(self, vals):
+ vals['number'] = self.env['ir.sequence'].next_by_code('customer.commision') or '0'
+ result = super(CustomerCommision, self).create(vals)
+ return result
+
+ def action_confirm_customer_commision(self):#add 2 step approval
+ if not self.status:
+ self.status = 'pengajuan1'
+ elif self.status == 'pengajuan1' and self.env.user.id == 19:
+ self.status = 'pengajuan2'
+ elif self.status == 'pengajuan2' and self.env.user.is_leader:
+ for line in self.commision_lines:
+ line.invoice_id.is_customer_commision = True
+ self.status = 'approved'
+ else:
+ raise UserError('Harus di approved oleh yang bersangkutan')
+ return
+
+ def generate_customer_commision(self):
+ if self.commision_lines:
+ raise UserError('Line sudah ada, tidak bisa di generate ulang')
+
+ if self.commision_type == 'fee':
+ self._generate_customer_commision_fee()
+ else:
+ self._generate_customer_commision_rebate()
+
+ def _generate_customer_commision_rebate(self):
+ partners = []
+ partners += self.partner_id.child_ids
+ partners.append(self.partner_id)
+
+ for partner in partners:
+ brand = [92, 10, 89, 12, 324, 11]
+ where = [
+ ('move_id.move_type', '=', 'out_invoice'),
+ ('move_id.state', '=', 'posted'),
+ ('move_id.is_customer_commision', '=', False),
+ ('move_id.amount_residual_signed', '=', 0),
+ ('move_id.partner_id.id', '=', partner.id),
+ ('move_id.invoice_date', '>=', self.date_from),
+ ('move_id.invoice_date', '<=', self.date_to),
+ ('product_id.x_manufacture', 'in', brand),
+ ]
+ invoice_lines = self.env['account.move.line'].search(where, order='id')
+ for invoice_line in invoice_lines:
+ tax = invoice_line.price_total - invoice_line.price_subtotal
+ self.env['customer.commision.line'].create([{
+ 'customer_commision_id': self.id,
+ 'partner_id': invoice_line.move_id.partner_id.id,
+ 'invoice_id': invoice_line.move_id.id,
+ 'state': invoice_line.move_id.state,
+ 'product_id': invoice_line.product_id.id,
+ 'dpp': invoice_line.price_subtotal,
+ 'tax': tax,
+ 'total': invoice_line.price_total
+ }])
+ return
+
+ def _generate_customer_commision_fee(self):
+ partners = []
+ partners += self.partner_id.child_ids
+ partners.append(self.partner_id)
+
+ for partner in partners:
+ where = [
+ ('move_type', '=', 'out_invoice'),
+ ('state', '=', 'posted'),
+ ('is_customer_commision', '=', False),
+ ('amount_residual_signed', '=', 0),
+ ('partner_id.id', '=', partner.id),
+ ('invoice_date', '>=', self.date_from),
+ ('invoice_date', '<=', self.date_to),
+ ]
+ invoices = self.env['account.move'].search(where, order='id')
+ for invoice in invoices:
+ self.env['customer.commision.line'].create([{
+ 'customer_commision_id': self.id,
+ 'partner_id': invoice.partner_id.id,
+ 'invoice_id': invoice.id,
+ 'state': invoice.state,
+ 'dpp': invoice.amount_untaxed_signed,
+ 'tax': invoice.amount_tax_signed,
+ 'total': invoice.amount_total_signed
+ }])
+ return
+
+class CustomerCommisionLine(models.Model):
+ _name = 'customer.commision.line'
+ _order = 'id'
+
+ customer_commision_id = fields.Many2one('customer.commision', string='Ref', required=True, ondelete='cascade', copy=False)
+ invoice_id = fields.Many2one('account.move', string='Invoice')
+ partner_id = fields.Many2one('res.partner', string='Customer')
+ state = fields.Char(string='InvStatus')
+ dpp = fields.Float(string='DPP')
+ tax = fields.Float(string='TaxAmt')
+ total = fields.Float(string='Total')
+ product_id = fields.Many2one('product.product', string='Product')
+
+class AccountMove(models.Model):
+ _inherit = 'account.move'
+ is_customer_commision = fields.Boolean(string='Customer Commision Used')
diff --git a/indoteknik_custom/models/product_monitoring.py b/indoteknik_custom/models/product_monitoring.py
new file mode 100644
index 00000000..df9701ab
--- /dev/null
+++ b/indoteknik_custom/models/product_monitoring.py
@@ -0,0 +1,35 @@
+from odoo import models, fields, tools, api
+
+class ProductMonitoring(models.Model):
+ _name = 'product.monitoring'
+ _auto = False
+ _rec_name = 'product_id'
+
+ id = fields.Integer()
+ product_id = fields.Many2one('product.product', string='Product')
+ outgoing_qty = fields.Float(string="Outgoing", related='product_id.outgoing_qty')
+ incoming_qty = fields.Float(string="Incoming", related='product_id.incoming_qty')
+ qty_available = fields.Float(string="On Hand", related='product_id.qty_available')
+ qty_upcoming = fields.Float(string="Upcoming", related='product_id.qty_upcoming')
+ status_stock = fields.Selection([
+ ('outgoing_gt_stock', 'Outgoing > Stock'),
+ ('outgoing_lt_stock', 'Outgoing < Stock'),
+ ], string="Status Stock", compute='_compute_status_stock')
+
+ def _compute_status_stock(self):
+ for product in self:
+ product.status_stock = 'outgoing_lt_stock' if product.outgoing_qty <= product.qty_upcoming else 'outgoing_gt_stock'
+
+ def init(self):
+ tools.drop_view_if_exists(self.env.cr, self._table)
+ self.env.cr.execute("""
+ CREATE OR REPLACE VIEW %s AS (
+ SELECT
+ sm.product_id AS id,
+ sm.product_id AS product_id
+ FROM stock_move sm
+ LEFT JOIN stock_picking sp ON sm.picking_id = sp.id
+ WHERE sp.state NOT IN ('cancel', 'done') AND sm.product_id IS NOT null
+ GROUP BY sm.product_id
+ )
+ """ % self._table) \ No newline at end of file
diff --git a/indoteknik_custom/models/product_template.py b/indoteknik_custom/models/product_template.py
index defcbdd4..d1de2221 100755
--- a/indoteknik_custom/models/product_template.py
+++ b/indoteknik_custom/models/product_template.py
@@ -52,7 +52,15 @@ class ProductTemplate(models.Model):
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')
is_edited = fields.Boolean(string='Is Edited')
-
+ qty_sold = fields.Float(string='Sold Quantity', compute='_get_qty_sold')
+ kind_of = fields.Selection([
+ ('sp', 'Spare Part'),
+ ('acc', 'Accessories')
+ ], string='Kind of', copy=False)
+
+ def _get_qty_sold(self):
+ for rec in self:
+ rec.qty_sold = sum(x.qty_sold for x in rec.product_variant_ids)
def day_product_to_edit(self):
day_products = []
@@ -184,12 +192,7 @@ class ProductTemplate(models.Model):
def _compute_web_price(self):
for template in self:
- products = self.env['product.product'].search([
- ('product_tmpl_id', '=', template.id),
- ('active', 'in', [True, False])
- ])
- for variants in products:
- template.web_price = variants[0].web_price
+ template.web_price = template.product_variant_id.web_price
def _have_promotion_program(self):
for template in self:
@@ -308,6 +311,12 @@ class ProductTemplate(models.Model):
}
self.env['token.storage'].create([values])
return values
+
+ def write(self, vals):
+ if self.id == 224484:
+ raise UserError('Tidak dapat mengubah produk sementara')
+
+ return super(ProductTemplate, self).write(vals)
class ProductProduct(models.Model):
_inherit = "product.product"
@@ -329,8 +338,22 @@ class ProductProduct(models.Model):
material = fields.Char(string='Material')
qty_onhand_bandengan = fields.Float(string='Qty Incoming Bandengan', compute='_get_qty_onhand_bandengan')
qty_incoming_bandengan = fields.Float(string='Qty Incoming Bandengan', compute='_get_qty_incoming_bandengan')
+ qty_upcoming = fields.Float(string='Qty Upcoming', compute='_get_qty_upcoming')
sla_version = fields.Integer(string="SLA Version", default=0)
is_edited = fields.Boolean(string='Is Edited')
+ qty_sold = fields.Float(string='Sold Quantity', compute='_get_qty_sold')
+
+ 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([
+ ('order_id.state', 'in', ['done', 'sale']),
+ ('product_id', '=', product.id)
+ ])
+ product.qty_sold = sum(x.product_uom_qty for x in order_line)
def day_product_to_edit(self):
day_products = []
@@ -401,9 +424,9 @@ class ProductProduct(models.Model):
def _compute_web_price(self):
for product in self:
- pricelist_id = self.env.context.get('pricelist')
+ pricelist_id = self.env['ir.config_parameter'].sudo().get_param('product.pricelist.default_price_id_v2')
- domain = [('pricelist_id', '=', pricelist_id or 1), ('product_id', '=', product.id)]
+ domain = [('pricelist_id.id', '=', pricelist_id or 17022), ('product_id.id', '=', product.id)]
product_pricelist_item = self.env['product.pricelist.item'].search(domain, limit=1)
if product_pricelist_item.base_pricelist_id:
diff --git a/indoteknik_custom/models/purchase_order.py b/indoteknik_custom/models/purchase_order.py
index 8ad25228..b0f1a569 100755
--- a/indoteknik_custom/models/purchase_order.py
+++ b/indoteknik_custom/models/purchase_order.py
@@ -47,6 +47,17 @@ class PurchaseOrder(models.Model):
count_line_product = fields.Float('Total Item', compute='compute_count_line_product')
note_description = fields.Char(string='Note', help='bisa diisi sebagai informasi indent barang tertentu atau apapun')
has_active_invoice = fields.Boolean(string='Has Active Invoice', compute='_compute_has_active_invoice')
+ description = fields.Char(string='Description', help='bisa diisi sebagai informasi indent barang tertentu atau apapun')
+ purchase_order_lines = fields.One2many('purchase.order.line', 'order_id', string='Indent', auto_join=True)
+ responsible_ids = fields.Many2many('res.users', string='Responsibles', compute='_compute_responsibles')
+
+ def _compute_responsibles(self):
+ for purchase in self:
+ resposible_ids = []
+ for line in purchase.order_line:
+ resposible_ids.append(line.product_id.x_manufacture.user_id.id)
+ resposible_ids = list(set(resposible_ids))
+ purchase.responsible_ids = resposible_ids
def _compute_has_active_invoice(self):
for order in self:
@@ -55,6 +66,14 @@ class PurchaseOrder(models.Model):
def add_product_to_pricelist(self):
for line in self.order_line:
current_time = datetime.utcnow()
+ price_unit = line.price_unit
+ taxes = line.taxes_id
+ for tax in taxes:
+ tax_include = tax.price_include
+ tax_amt = tax.amount
+ if taxes:
+ if not tax_include:
+ price_unit = price_unit + (price_unit * tax_amt / 100)
purchase_pricelist = self.env['purchase.pricelist'].search([
('product_id', '=', line.product_id.id),
@@ -66,7 +85,7 @@ class PurchaseOrder(models.Model):
'vendor_id': line.order_id.partner_id.id,
'product_id': line.product_id.id,
'product_price': 0.00,
- 'system_price': line.price_unit,
+ 'system_price': price_unit,
'system_last_update': current_time,
}])
return True
@@ -74,7 +93,7 @@ class PurchaseOrder(models.Model):
for pricelist in purchase_pricelist:
pricelist.write({
'system_last_update': current_time,
- 'system_price': line.price_unit
+ 'system_price': price_unit
})
def _compute_date_planned(self):
@@ -329,12 +348,11 @@ class PurchaseOrder(models.Model):
def re_calculate(self):
for line in self.order_line:
sale_order_line = self.env['sale.order.line'].search([
- ('id', '=', line.so_line_id.id),
+ ('product_id', 'in', [line.product_id.id]),
('order_id', '=', line.order_id.sale_order_id.id)
- ], limit=1, order='price_reduce_taxexcl')
+ ])
for so_line in sale_order_line:
- unit_price = line.price_unit
- so_line.purchase_price = unit_price
+ so_line.purchase_price = line.price_unit
def button_cancel(self):
res = super(PurchaseOrder, self).button_cancel()
diff --git a/indoteknik_custom/models/purchase_order_line.py b/indoteknik_custom/models/purchase_order_line.py
index 95e85122..2e91bb69 100755
--- a/indoteknik_custom/models/purchase_order_line.py
+++ b/indoteknik_custom/models/purchase_order_line.py
@@ -30,6 +30,7 @@ class PurchaseOrderLine(models.Model):
suggest = fields.Char(string='Suggest')
price_vendor = fields.Float(string='Price Vendor', compute='compute_price_vendor')
so_line_id = fields.Many2one('sale.order.line', string='ID SO Line')
+ indent = fields.Boolean(string='Indent', help='centang ini jika barang indent')
def compute_price_vendor(self):
for line in self:
diff --git a/indoteknik_custom/models/purchase_pricelist.py b/indoteknik_custom/models/purchase_pricelist.py
index 3607defe..b7c3785a 100755
--- a/indoteknik_custom/models/purchase_pricelist.py
+++ b/indoteknik_custom/models/purchase_pricelist.py
@@ -14,6 +14,8 @@ class PurchasePricelist(models.Model):
system_price = fields.Float(string='System Price', required=True)
human_last_update = fields.Datetime(string='Human Update')
system_last_update = fields.Datetime(string='System Update')
+ count_trx_po = fields.Integer(string='Count Trx Product')
+ count_trx_po_vendor = fields.Integer(string='Count Trx Vendor')
@api.depends('product_id', 'vendor_id')
def _compute_name(self):
diff --git a/indoteknik_custom/models/requisition.py b/indoteknik_custom/models/requisition.py
index 19f0ba7e..6408c4fd 100644
--- a/indoteknik_custom/models/requisition.py
+++ b/indoteknik_custom/models/requisition.py
@@ -9,6 +9,8 @@ _logger = logging.getLogger(__name__)
class Requisition(models.Model):
_name = 'requisition'
_order = 'id desc'
+ _inherit = ['mail.thread']
+ _rec_name = 'number'
number = fields.Char(string='Document No', index=True, copy=False, readonly=True)
date_doc = fields.Date(string='Date', help='isi tanggal hari ini')
@@ -26,108 +28,108 @@ class Requisition(models.Model):
result = super(Requisition, self).create(vals)
return result
- def create_requisition_from_sales_with_price(self):
- if self.requisition_lines:
- raise UserError('Sudah digenerate sebelumnya, hapus line terlebih dahulu')
- if not self.sale_order_id:
- raise UserError('Sale Order harus diisi')
- if self.is_po:
- raise UserError('Sudah jadi PO, tidak bisa di create ulang PO nya')
-
- count = 0
- for order_line in self.sale_order_id.order_line:
- # get purchase price altama, if nothing, then get other cheaper, if nothing then last po
- purchase_price = order_line.purchase_price
- vendor_id = order_line.vendor_id.id
-
- # get qty available bandengan
- qty_available = order_line.product_id.qty_onhand_bandengan + order_line.product_id.qty_incoming_bandengan - order_line.product_id.outgoing_qty
- suggest = 'harus beli'
- if qty_available > order_line.product_qty:
- suggest = 'masih cukup'
-
- self.env['requisition.line'].create([{
- 'requisition_id': self.id,
- 'partner_id': vendor_id,
- 'brand_id': order_line.product_id.product_tmpl_id.x_manufacture.id,
- 'product_id': order_line.product_id.id,
- 'qty_purchase': order_line.product_uom_qty,
- 'tax_id': order_line.purchase_tax_id.id,
- 'price_unit': purchase_price,
- 'subtotal': purchase_price * order_line.product_uom_qty,
- 'source': 'sales',
- 'qty_available_store': qty_available,
- 'suggest': suggest,
- }])
- count+=1
- _logger.info('Create Requisition %s' % order_line.product_id.name)
- self.notification = "Requisition Created %s lines" % count
-
- def create_requisition_from_sales(self):
- if self.requisition_lines:
- raise UserError('Sudah digenerate sebelumnya, hapus line terlebih dahulu')
- if not self.sale_order_id:
- raise UserError('Sale Order harus diisi')
- if self.is_po:
- raise UserError('Sudah jadi PO, tidak bisa di create ulang PO nya')
+ # def create_requisition_from_sales_with_price(self):
+ # if self.requisition_lines:
+ # raise UserError('Sudah digenerate sebelumnya, hapus line terlebih dahulu')
+ # if not self.sale_order_id:
+ # raise UserError('Sale Order harus diisi')
+ # if self.is_po:
+ # raise UserError('Sudah jadi PO, tidak bisa di create ulang PO nya')
+
+ # count = 0
+ # for order_line in self.sale_order_id.order_line:
+ # # get purchase price altama, if nothing, then get other cheaper, if nothing then last po
+ # purchase_price = order_line.purchase_price
+ # vendor_id = order_line.vendor_id.id
+
+ # # get qty available bandengan
+ # qty_available = order_line.product_id.qty_onhand_bandengan + order_line.product_id.qty_incoming_bandengan - order_line.product_id.outgoing_qty
+ # suggest = 'harus beli'
+ # if qty_available > order_line.product_qty:
+ # suggest = 'masih cukup'
+
+ # self.env['requisition.line'].create([{
+ # 'requisition_id': self.id,
+ # 'partner_id': vendor_id,
+ # 'brand_id': order_line.product_id.product_tmpl_id.x_manufacture.id,
+ # 'product_id': order_line.product_id.id,
+ # 'qty_purchase': order_line.product_uom_qty,
+ # 'tax_id': order_line.purchase_tax_id.id,
+ # 'price_unit': purchase_price,
+ # 'subtotal': purchase_price * order_line.product_uom_qty,
+ # 'source': 'sales',
+ # 'qty_available_store': qty_available,
+ # 'suggest': suggest,
+ # }])
+ # count+=1
+ # _logger.info('Create Requisition %s' % order_line.product_id.name)
+ # self.notification = "Requisition Created %s lines" % count
+
+ # def create_requisition_from_sales(self):
+ # if self.requisition_lines:
+ # raise UserError('Sudah digenerate sebelumnya, hapus line terlebih dahulu')
+ # if not self.sale_order_id:
+ # raise UserError('Sale Order harus diisi')
+ # if self.is_po:
+ # raise UserError('Sudah jadi PO, tidak bisa di create ulang PO nya')
- # old_requisition = self.env['requisition'].search([('sale_order_id', '=', self.sale_order_id.id)], limit=1)
- # if old_requisition:
- # raise UserError('Sudah pernah jadi Requisition')
-
- count = 0
- for order_line in self.sale_order_id.order_line:
- # get purchase price altama, if nothing, then get other cheaper, if nothing then last po
- purchase_price = 0
- vendor_id = 0
-
- # get qty available bandengan
- qty_available = order_line.product_id.qty_onhand_bandengan + order_line.product_id.qty_incoming_bandengan - order_line.product_id.outgoing_qty
- suggest = 'harus beli'
- if qty_available > order_line.product_qty:
- suggest = 'masih cukup'
-
- purchase_pricelist = self.env['purchase.pricelist'].search([
- ('product_id.id', '=', order_line.product_id.id),
- ('vendor_id.id', '=', 5571)
- ], order='product_price asc', limit=1)
- purchase_price = purchase_pricelist.product_price
- vendor_id = purchase_pricelist.vendor_id.id
- source = 'PriceList'
+ # # old_requisition = self.env['requisition'].search([('sale_order_id', '=', self.sale_order_id.id)], limit=1)
+ # # if old_requisition:
+ # # raise UserError('Sudah pernah jadi Requisition')
+
+ # count = 0
+ # for order_line in self.sale_order_id.order_line:
+ # # get purchase price altama, if nothing, then get other cheaper, if nothing then last po
+ # purchase_price = 0
+ # vendor_id = 0
+
+ # # get qty available bandengan
+ # qty_available = order_line.product_id.qty_onhand_bandengan + order_line.product_id.qty_incoming_bandengan - order_line.product_id.outgoing_qty
+ # suggest = 'harus beli'
+ # if qty_available > order_line.product_qty:
+ # suggest = 'masih cukup'
+
+ # purchase_pricelist = self.env['purchase.pricelist'].search([
+ # ('product_id.id', '=', order_line.product_id.id),
+ # ('vendor_id.id', '=', 5571)
+ # ], order='product_price asc', limit=1)
+ # purchase_price = purchase_pricelist.product_price
+ # vendor_id = purchase_pricelist.vendor_id.id
+ # source = 'PriceList'
- if not purchase_price or purchase_price <= 0:
- purchase_pricelist = self.env['purchase.pricelist'].search([('product_id', '=', order_line.product_id.id)], order='product_price asc', limit=1)
- purchase_price = purchase_pricelist.product_price
- vendor_id = purchase_pricelist.vendor_id.id
- source = 'PriceList'
+ # if not purchase_price or purchase_price <= 0:
+ # purchase_pricelist = self.env['purchase.pricelist'].search([('product_id', '=', order_line.product_id.id)], order='product_price asc', limit=1)
+ # purchase_price = purchase_pricelist.product_price
+ # vendor_id = purchase_pricelist.vendor_id.id
+ # source = 'PriceList'
- if not purchase_price or purchase_price <= 0:
- last_po_line = self.env['purchase.order.line'].search([('product_id', '=', order_line.product_id.id), ('order_id.state', '=', 'done')], order='id desc', limit=1)
- purchase_price = last_po_line.price_unit
- vendor_id = last_po_line.order_id.partner_id.id
- source = 'LastPO'
+ # if not purchase_price or purchase_price <= 0:
+ # last_po_line = self.env['purchase.order.line'].search([('product_id', '=', order_line.product_id.id), ('order_id.state', '=', 'done')], order='id desc', limit=1)
+ # purchase_price = last_po_line.price_unit
+ # vendor_id = last_po_line.order_id.partner_id.id
+ # source = 'LastPO'
- if not purchase_price or purchase_price <= 0:
- purchase_price = 0
- vendor_id = 5571
- source = 'Nothing'
-
- self.env['requisition.line'].create([{
- 'requisition_id': self.id,
- 'partner_id': vendor_id,
- 'brand_id': order_line.product_id.product_tmpl_id.x_manufacture.id,
- 'product_id': order_line.product_id.id,
- 'qty_purchase': order_line.product_uom_qty,
- 'tax_id': order_line.purchase_tax_id.id,
- 'price_unit': purchase_price,
- 'subtotal': purchase_price * order_line.product_uom_qty,
- 'source': source,
- 'qty_available_store': qty_available,
- 'suggest': suggest,
- }])
- count+=1
- _logger.info('Create Requisition %s' % order_line.product_id.name)
- self.notification = "Requisition Created %s lines" % count
+ # if not purchase_price or purchase_price <= 0:
+ # purchase_price = 0
+ # vendor_id = 5571
+ # source = 'Nothing'
+
+ # self.env['requisition.line'].create([{
+ # 'requisition_id': self.id,
+ # 'partner_id': vendor_id,
+ # 'brand_id': order_line.product_id.product_tmpl_id.x_manufacture.id,
+ # 'product_id': order_line.product_id.id,
+ # 'qty_purchase': order_line.product_uom_qty,
+ # 'tax_id': order_line.purchase_tax_id.id,
+ # 'price_unit': purchase_price,
+ # 'subtotal': purchase_price * order_line.product_uom_qty,
+ # 'source': source,
+ # 'qty_available_store': qty_available,
+ # 'suggest': suggest,
+ # }])
+ # count+=1
+ # _logger.info('Create Requisition %s' % order_line.product_id.name)
+ # self.notification = "Requisition Created %s lines" % count
def create_po_from_requisition(self):
if not self.requisition_lines:
@@ -141,13 +143,14 @@ class Requisition(models.Model):
for vendor in vendor_ids:
param_header = {
'partner_id': vendor['partner_id'][0],
- 'partner_ref': self.sale_order_id.name,
+ # 'partner_ref': self.sale_order_id.name,
'currency_id': 12,
'user_id': self.env.user.id,
'company_id': 1, # indoteknik dotcom gemilang
'picking_type_id': 28, # indoteknik bandengan receipts
'date_order': current_time,
- 'sale_order_id': self.sale_order_id.id
+ 'sale_order_id': self.sale_order_id.id,
+ 'note_description': 'from Purchase Requisition'
}
# new_po = self.env['purchase.order'].create([param_header])
products_vendors = self.env['requisition.line'].search([
@@ -156,9 +159,9 @@ class Requisition(models.Model):
('qty_purchase', '>', 0)
], order='brand_id')
count = brand_id = 0
- new_po = ''
+
for product in products_vendors:
- if not new_po or ((count == 200 or brand_id != product.brand_id.id) and vendor['partner_id'][0] == 5571):
+ if count == 200 or brand_id != product.brand_id.id:
count = 0
counter_po_number += 1
new_po = self.env['purchase.order'].create([param_header])
@@ -178,14 +181,16 @@ class Requisition(models.Model):
if qty_available > product.qty_purchase:
suggest = 'masih cukup'
+ tax = [22]
+
param_line = {
'order_id': new_po.id,
'sequence': count,
'product_id': product.product_id.id,
'product_qty': product.qty_purchase,
'product_uom_qty': product.qty_purchase,
- 'price_unit': product.last_price,
- 'taxes_id': product.tax_id,
+ 'price_unit': product.price_unit,
+ 'taxes_id': tax,
'qty_available_store': qty_available,
'suggest': suggest,
}
@@ -193,7 +198,7 @@ class Requisition(models.Model):
product.current_po_id = new_po.id
product.current_po_line_id = new_line.id
_logger.info('Create PO Line %s' % product.product_id.name)
- self.notification = self.notification + ' %s' % new_po.name
+ # self.notification = self.notification + ' %s' % new_po.name
self.is_po = True
class RequisitionLine(models.Model):
@@ -221,7 +226,13 @@ class RequisitionLine(models.Model):
@api.onchange('price_unit')
def _onchange_price_unit(self):
- self.subtotal = self.price_unit * self.qty_purchase
+ for line in self:
+ line.subtotal = line.price_unit * line.qty_purchase
+
+ @api.onchange('product_id')
+ def _onchange_product(self):
+ for line in self:
+ line.brand_id = line.product_id.product_tmpl_id.x_manufacture.id
class RequisitionPurchaseMatch(models.Model):
_name = 'requisition.purchase.match'
diff --git a/indoteknik_custom/models/res_partner.py b/indoteknik_custom/models/res_partner.py
index bc2a24b1..a1b57147 100644
--- a/indoteknik_custom/models/res_partner.py
+++ b/indoteknik_custom/models/res_partner.py
@@ -19,6 +19,8 @@ class ResPartner(models.Model):
])
sppkp = fields.Char(string="SPPKP")
counter = fields.Integer(string="Counter", default=0)
+ digital_invoice_tax = fields.Boolean(string="Digital Invoice & Faktur Pajak")
+ is_potential = fields.Boolean(string='Potential')
def get_child_ids(self):
partner = self.env['res.partner'].search([('id', '=', self.id)], limit=1)
diff --git a/indoteknik_custom/models/sale_monitoring.py b/indoteknik_custom/models/sale_monitoring.py
index ad15e0c2..107d5296 100755
--- a/indoteknik_custom/models/sale_monitoring.py
+++ b/indoteknik_custom/models/sale_monitoring.py
@@ -21,12 +21,42 @@ class SaleMonitoring(models.Model):
status = fields.Char(string="Status")
po_number = fields.Char(string="PO Number")
qty_reserved = fields.Integer(string="Qty Reserved")
- note = fields.Char(string="Note", compute='compute_note')
+ note_so_line = fields.Selection([
+ ('eta', 'ETA'),
+ ('info_sales', 'Info Sales'),
+ ('info_vendor', 'Info Vendor'),
+ ('penggabungan', 'Penggabungan'),
+ ], string="Note", compute='compute_note')
+ note = fields.Char(string="Note Detail", compute='compute_note_detail')
+ purchase_representative_id = fields.Many2one('res.users', string="Purchase Representative", readonly=True, compute='compute_purchase_representative')
+
+ def compute_purchase_representative(self):
+ for sale in self:
+ po = self.env['purchase.order'].search([
+ ('sale_order_id', '=', sale.sale_order_id.id),
+ ('user_id', '!=', False)
+ ])
+
+ user_id = False
+
+ if po:
+ user_id = po[0].user_id
+
+ sale.purchase_representative_id = user_id
def compute_note(self):
for sale in self:
lines = self.env['sale.order.line'].search([
('order_id', '=', sale.sale_order_id.id),
+ ('note', '!=', False)
+ ], limit=1)
+
+ sale.note_so_line = lines.note
+
+ def compute_note_detail(self):
+ for sale in self:
+ lines = self.env['sale.order.line'].search([
+ ('order_id', '=', sale.sale_order_id.id),
('note_procurement', '!=', False)
])
@@ -51,12 +81,12 @@ class SaleMonitoring(models.Model):
SUM(smd.qty_so_invoiced) AS qty_so_invoiced,
sum(smd.qty_reserved) as qty_reserved,
CASE
- when sum(qty_so_invoiced) = sum(qty_so) then 'Invoiced'
when sum(qty_so_delivered) = sum(qty_so) then 'Delivered'
when sum(qty_reserved) >= sum(qty_so) then 'Siap kirim'
when sum(qty_po) + sum(qty_reserved) - sum(qty_po_received) < sum(qty_so) then 'Belum/Kurang PO'
when sum(qty_po_received) = 0 then 'Belum terima'
when sum(qty_po_received) < sum(qty_po) then 'Terima sebagian'
+ when sum(qty_so_invoiced) = sum(qty_so) then 'Invoiced'
END AS status,
get_po_number(smd.sale_order_id) as po_number
FROM sale_monitoring_detail smd
diff --git a/indoteknik_custom/models/sale_monitoring_detail.py b/indoteknik_custom/models/sale_monitoring_detail.py
index dc4caa14..43b0b063 100755
--- a/indoteknik_custom/models/sale_monitoring_detail.py
+++ b/indoteknik_custom/models/sale_monitoring_detail.py
@@ -31,12 +31,12 @@ class SaleMonitoringDetail(models.Model):
SELECT
*,
CASE
- when qty_so_invoiced = qty_so then 'Invoiced'
when qty_so_delivered = qty_so then 'Delivered'
when qty_reserved >= qty_so then 'Siap kirim'
when qty_po + qty_reserved - qty_po_received < qty_so then 'Belum/Kurang PO'
when qty_po_received = 0 then 'Belum terima'
when qty_po_received < qty_po then 'Terima sebagian'
+ when qty_so_invoiced = qty_so then 'Invoiced'
END AS status
FROM
(
diff --git a/indoteknik_custom/models/sale_order.py b/indoteknik_custom/models/sale_order.py
index 9324930e..f9229bca 100755
--- a/indoteknik_custom/models/sale_order.py
+++ b/indoteknik_custom/models/sale_order.py
@@ -1,5 +1,6 @@
from odoo import fields, models, api, _
from odoo.exceptions import UserError
+from datetime import datetime
import logging, random, string, requests, math, json, re
_logger = logging.getLogger(__name__)
@@ -69,18 +70,28 @@ class SaleOrder(models.Model):
customer_type = fields.Selection([
('pkp', 'PKP'),
('nonpkp', 'Non PKP')
- ])
- sppkp = fields.Char(string="SPPKP")
- npwp = fields.Char(string="NPWP")
+ ], required=True)
+ sppkp = fields.Char(string="SPPKP", required=True)
+ npwp = fields.Char(string="NPWP", required=True)
purchase_total = fields.Monetary(string='Purchase Total', compute='_compute_purchase_total')
voucher_id = fields.Many2one(comodel_name='voucher', string='Voucher', copy=False)
applied_voucher_id = fields.Many2one(comodel_name='voucher', string='Applied Voucher', copy=False)
amount_voucher_disc = fields.Float(string='Voucher Discount')
- source_id = fields.Many2one('utm.source', 'Source', domain="[('id', 'in', [32, 59, 60, 61])]")
+ source_id = fields.Many2one('utm.source', 'Source', domain="[('id', 'in', [32, 59, 60, 61])]", required=True)
estimated_arrival_days = fields.Integer('Estimated Arrival Days', default=0)
email = fields.Char(string='Email')
picking_iu_id = fields.Many2one('stock.picking', 'Picking IU')
helper_by_id = fields.Many2one('res.users', 'Helper By')
+ # picking_ids = fields.Many2many('stock.picking', string='Pickings', compute='_get_pickings', readonly=True, copy=False, search="_search_picking_ids")
+
+ # def _get_pickings(self):
+ # state = ['assigned']
+ # for order in self:
+ # pickings = self.env['stock.picking'].search([
+ # ('sale_id.id', '=', order.id),
+ # ('state', 'in', state)
+ # ])
+ # order.picking_ids = pickings
@api.model
def action_multi_update_state(self):
@@ -193,8 +204,39 @@ class SaleOrder(models.Model):
sale.so_status = 'sebagian'
else:
sale.so_status = 'menunggu'
+
+ for picking in sale.picking_ids:
+ sum_qty_pick = sum(move_line.product_uom_qty for move_line in picking.move_ids_without_package)
+ sum_qty_reserved = sum(move_line.product_uom_qty for move_line in picking.move_line_ids_without_package)
+ if picking.state == 'done':
+ continue
+ elif sum_qty_pick == sum_qty_reserved and not picking.date_reserved:# baru ke reserved
+ current_time = datetime.now().strftime('%Y-%m-%d %H:%M:%S')
+ picking.date_reserved = current_time
+ elif sum_qty_pick == sum_qty_reserved:# sudah ada data reserved
+ picking.date_reserved = picking.date_reserved
+ else:
+ picking.date_reserved = ''
+
_logger.info('Calculate SO Status %s' % sale.id)
+ # def _search_picking_ids(self, operator, value):
+ # if operator == 'in' and value:
+ # self.env.cr.execute("""
+ # SELECT array_agg(so.sale_id)
+ # FROM stock_picking so
+ # WHERE
+ # so.sale_id is not null and so.id = ANY(%s)
+ # """, (list(value),))
+ # so_ids = self.env.cr.fetchone()[0] or []
+ # return [('id', 'in', so_ids)]
+ # elif operator == '=' and not value:
+ # order_ids = self._search([
+ # ('order_line.invoice_lines.move_id.move_type', 'in', ('out_invoice', 'out_refund'))
+ # ])
+ # return [('id', 'not in', order_ids)]
+ # return ['&', ('order_line.invoice_lines.move_id.move_type', 'in', ('out_invoice', 'out_refund')), ('order_line.invoice_lines.move_id', operator, value)]
+
@api.onchange('partner_shipping_id')
def onchange_partner_shipping(self):
self.real_shipping_id = self.partner_shipping_id
diff --git a/indoteknik_custom/models/sale_order_line.py b/indoteknik_custom/models/sale_order_line.py
index 69328325..eda003c7 100644
--- a/indoteknik_custom/models/sale_order_line.py
+++ b/indoteknik_custom/models/sale_order_line.py
@@ -18,7 +18,13 @@ class SaleOrderLine(models.Model):
delivery_amt_line = fields.Float('DeliveryAmtLine', compute='compute_delivery_amt_line')
fee_third_party_line = fields.Float('FeeThirdPartyLine', compute='compute_fee_third_party_line', default=0)
line_no = fields.Integer('No', default=0, copy=False)
- note_procurement = fields.Char(string='Note', help="Harap diisi jika ada keterangan tambahan dari Procurement, agar dapat dimonitoring")
+ note = fields.Selection([
+ ('eta', 'ETA'),
+ ('info_sales', 'Info Sales'),
+ ('info_vendor', 'Info Vendor'),
+ ('penggabungan', 'Penggabungan'),
+ ], string='Note', help="Harap diisi jika ada keterangan tambahan dari Procurement, agar dapat dimonitoring")
+ note_procurement = fields.Char(string='Note Detail', help="Harap diisi jika ada keterangan tambahan dari Procurement, agar dapat dimonitoring")
vendor_subtotal = fields.Float(string='Vendor Subtotal', compute="_compute_vendor_subtotal")
amount_voucher_disc = fields.Float(string='Voucher Discount')
@@ -66,21 +72,37 @@ class SaleOrderLine(models.Model):
cost = self.product_id.standard_price
self.purchase_price = cost
else:
+ # purchase_price = self.env['purchase.pricelist'].search(
+ # [('vendor_id', '=', self.vendor_id.id), ('product_id', '=', self.product_id.id)], limit=1)
purchase_price = self.env['purchase.pricelist'].search(
- [('vendor_id', '=', self.vendor_id.id), ('product_id', '=', self.product_id.id)], limit=1)
- self.purchase_price = purchase_price.product_price
+ [('vendor_id', '=', self.vendor_id.id), ('product_id', '=', self.product_id.id)],
+ limit=1, order='count_trx_po desc, count_trx_po_vendor desc')
+ self.purchase_price = self._get_valid_purchase_price(purchase_price)
self.purchase_tax_id = 22
+ def _get_valid_purchase_price(self, purchase_price):
+ p_price = 0
+ if purchase_price.system_price > 0 and purchase_price.product_price > 0:
+ if purchase_price.human_last_update > purchase_price.system_last_update:
+ p_price = purchase_price.product_price
+ else:
+ p_price = purchase_price.system_price
+ elif purchase_price.system_price > 0 and purchase_price.product_price == 0:
+ p_price = purchase_price.system_price
+ elif purchase_price.system_price == 0 and purchase_price.product_price > 0:
+ p_price = purchase_price.product_price
+ return p_price
+
@api.onchange('product_id')
def product_id_change(self):
super(SaleOrderLine, self).product_id_change()
for line in self:
if line.product_id and line.product_id.type == 'product':
purchase_price = self.env['purchase.pricelist'].search(
- [('product_id', '=', self.product_id.id)], limit=1, order='product_price ASC')
+ [('product_id', '=', self.product_id.id)], limit=1, order='count_trx_po desc, count_trx_po_vendor desc')
line.vendor_id = purchase_price.vendor_id
line.tax_id = line.order_id.sales_tax_id
- line.purchase_price = purchase_price.product_price
+ line.purchase_price = self._get_valid_purchase_price(purchase_price)
def compute_delivery_amt_line(self):
for line in self:
diff --git a/indoteknik_custom/models/solr/apache_solr_queue.py b/indoteknik_custom/models/solr/apache_solr_queue.py
index 8dd7c273..07274295 100644
--- a/indoteknik_custom/models/solr/apache_solr_queue.py
+++ b/indoteknik_custom/models/solr/apache_solr_queue.py
@@ -72,11 +72,12 @@ class ApacheSolrQueue(models.Model):
if count == 0:
self.create(payload)
- def delete_weekly_solr(self, limit=500):
+ def delete_weekly_solr(self, limit=500, days_after=30):
solr = self.search([
('execute_status', '=', 'success'),
- ('execute_date', '>=', (datetime.utcnow() - timedelta(days=7))),
+ ('execute_date', '>=', (datetime.utcnow() - timedelta(days=days_after))),
], limit=limit)
+
for rec in solr:
rec.unlink()
diff --git a/indoteknik_custom/models/solr/product_product.py b/indoteknik_custom/models/solr/product_product.py
index 31a0026d..03eaaf13 100644
--- a/indoteknik_custom/models/solr/product_product.py
+++ b/indoteknik_custom/models/solr/product_product.py
@@ -1,10 +1,11 @@
-from odoo import models, fields
+from odoo import models, fields, api
from datetime import datetime
class ProductProduct(models.Model):
_inherit = 'product.product'
+ unpublished = fields.Boolean(string='Unpublished')
last_update_solr = fields.Datetime(string='Last Update Solr')
desc_update_solr = fields.Char(string='Desc Update Solr')
@@ -24,6 +25,7 @@ class ProductProduct(models.Model):
def variant_solr_flag_to_solr(self, limit=500):
variant_products = self.search([('solr_flag', '=', 2)], limit=limit)
for product in variant_products:
+ product.product_tmpl_id._create_solr_queue('_sync_product_template_to_solr')
product.product_tmpl_id._create_solr_queue('_sync_price_to_solr')
product.solr_flag = 1
@@ -63,7 +65,8 @@ class ProductProduct(models.Model):
'search_rank_weekly_i': variant.product_tmpl_id.search_rank_weekly,
'attributes': [x.name for x in variant.product_template_attribute_value_ids],
'has_product_info_b': True,
- 'publish_b': variant.product_tmpl_id.active and variant.product_tmpl_id.type == 'product',
+ 'publish_b': not variant.unpublished,
+ 'qty_sold_f': variant.qty_sold
})
self.solr().add(docs=[document], softCommit=True)
@@ -74,24 +77,12 @@ class ProductProduct(models.Model):
def _sync_price_to_solr(self):
solr_model = self.env['apache.solr']
+ TIER_NUMBERS = ['1_v2', '2_v2', '3_v2', '4_v2', '5_v2']
for variant in self:
- price_excl_after_disc = price_excl = discount = tax = 0
- flashsale_data = {}
-
- if price_excl_after_disc == 0 or variant._get_website_price_after_disc_and_tax() < price_excl_after_disc:
- price_excl = variant._get_website_price_exclude_tax()
- price_excl_after_disc = variant._get_website_price_after_disc_and_tax()
- tax = variant._get_website_tax()
- discount = variant._get_website_disc(0)
- flashsale_data = variant.with_context(price_for="web")._get_flashsale_price()
+ flashsale_data = variant.with_context(price_for="web")._get_flashsale_price()
- price_excl_v2 = variant._v2_get_website_price_exclude_tax()
- price_excl_after_disc_v2 = variant._v2_get_website_price_after_disc_and_tax()
- tax_v2 = variant._v2_get_website_tax()
-
- document = solr_model.get_doc('variants', variant.id)
- document.update({
+ flashsale_doc = {
"id": variant.id,
"flashsale_id_i": flashsale_data.get('flashsale_id', 0),
"flashsale_tag_s": flashsale_data.get('flashsale_tag', ''),
@@ -101,25 +92,19 @@ class ProductProduct(models.Model):
"flashsale_base_price_f": flashsale_data.get('flashsale_base_price', 0),
"flashsale_discount_f": flashsale_data.get('flashsale_discount', 0),
"flashsale_price_f": flashsale_data.get('flashsale_price', 0),
- "price_f": price_excl,
- "discount_f": discount,
- "price_discount_f": price_excl_after_disc,
- "tax_f": tax,
- "price_v2_f": price_excl_v2,
- "price_discount_v2_f": price_excl_after_disc_v2,
- "tax_v2_f": tax_v2,
- })
-
- for tier_number in [1, 2, 3, '1_v2', '2_v2', '3_v2', '4_v2', '5_v2']:
+ }
+
+ price_doc = {}
+
+ for tier_number in TIER_NUMBERS:
tier = variant._get_pricelist_tier(tier_number)
- document.update({
- f"discount_tier{tier_number}_f": tier.get(f'discount_tier{tier_number}', 0),
- f"price_tier{tier_number}_f": tier.get(f'price_tier{tier_number}', 0),
- })
-
- # for tier_number in [1, 2, 3, '1_v2', '2_v2', '3_v2', '4_v2', '5_v2']:
- # tier = tier_data[tier_number]
+ price_doc[f"discount_tier{tier_number}_f"] = tier.get(f'discount_tier{tier_number}', 0)
+ price_doc[f"price_tier{tier_number}_f"] = tier.get(f'price_tier{tier_number}', 0)
+ document = solr_model.get_doc('variants', variant.id)
+ document['id'] = variant.id
+ document.update(flashsale_doc)
+ document.update(price_doc)
document.update({"has_price_info_b": True})
self.solr().add(docs=[document], softCommit=True)
@@ -185,4 +170,13 @@ class ProductProduct(models.Model):
results.append(result)
- return results \ No newline at end of file
+ return results
+
+ @api.constrains('unpublished')
+ def _constrains_unpublished(self):
+ for rec in self:
+ if rec.product_variant_count == 1:
+ rec.product_tmpl_id.unpublished = rec.unpublished
+
+ rec.product_tmpl_id._create_solr_queue_sync_product_template()
+ \ No newline at end of file
diff --git a/indoteknik_custom/models/solr/product_template.py b/indoteknik_custom/models/solr/product_template.py
index d7439bcb..648a0625 100644
--- a/indoteknik_custom/models/solr/product_template.py
+++ b/indoteknik_custom/models/solr/product_template.py
@@ -5,6 +5,7 @@ from datetime import datetime
class ProductTemplate(models.Model):
_inherit = "product.template"
+ unpublished = fields.Boolean(string='Unpublished')
last_update_solr = fields.Datetime(string='Last Update Solr')
desc_update_solr = fields.Char(string='Desc Update Solr')
@@ -23,7 +24,7 @@ class ProductTemplate(models.Model):
'function_name': function_name
})
- @api.constrains('name', 'default_code', 'weight', 'x_manufacture', 'public_categ_ids', 'search_rank', 'search_rank_weekly', 'image_1920', 'active')
+ @api.constrains('name', 'default_code', 'weight', 'x_manufacture', 'public_categ_ids', 'search_rank', 'search_rank_weekly', 'image_1920', 'unpublished')
def _create_solr_queue_sync_product_template(self):
self._create_solr_queue('_sync_product_template_to_solr')
@@ -35,6 +36,7 @@ class ProductTemplate(models.Model):
def solr_flag_to_solr(self, limit=500):
template_products = self.search([('solr_flag', '=', 2)], limit=limit)
for product in template_products:
+ product._create_solr_queue('_sync_product_template_to_solr')
product._create_solr_queue('_sync_price_to_solr')
product.solr_flag = 1
@@ -80,7 +82,8 @@ class ProductTemplate(models.Model):
"category_name": category_name,
"description_t": template.website_description or '',
'has_product_info_b': True,
- 'publish_b': template.active and template.type == 'product'
+ 'publish_b': not template.unpublished,
+ "qty_sold_f": template.qty_sold
})
self.solr().add(docs=[document], softCommit=True)
@@ -96,56 +99,52 @@ class ProductTemplate(models.Model):
def _sync_price_to_solr(self):
solr_model = self.env['apache.solr']
+ TIER_NUMBERS = ['1_v2', '2_v2', '3_v2', '4_v2', '5_v2']
for template in self:
- flashsale_data = {}
- price_excl = price_excl_after_disc = discount = tax = 0
- tier_data = {}
+ cheapest_flashsale = {}
for variant in template.product_variant_ids:
variant_flashsale = variant.with_context(price_for="web")._get_flashsale_price()
variant_flashsale_price = variant_flashsale.get('flashsale_price', 0)
- flashsale_data_price = flashsale_data.get('flashsale_price', 0)
-
- if flashsale_data_price == 0 or (variant_flashsale_price != 0 and variant_flashsale_price < flashsale_data_price):
- flashsale_data = variant_flashsale
-
- price_excl = variant._get_website_price_exclude_tax()
- price_excl_after_disc = variant._get_website_price_after_disc_and_tax()
- discount = variant._get_website_disc(0)
- tax = variant._get_website_tax()
-
- price_excl_v2 = variant._v2_get_website_price_exclude_tax()
- price_excl_after_disc_v2 = variant._v2_get_website_price_after_disc_and_tax()
- tax_v2 = variant._v2_get_website_tax()
-
+ cheapest_flashsale_price = cheapest_flashsale.get('flashsale_price', 0)
+
+ if cheapest_flashsale_price == 0 or (variant_flashsale_price != 0 and variant_flashsale_price < cheapest_flashsale_price):
+ cheapest_flashsale = variant_flashsale
+
+ flashsale_doc = {
+ "flashsale_id_i": cheapest_flashsale.get('flashsale_id', 0),
+ "flashsale_tag_s": cheapest_flashsale.get('flashsale_tag', ''),
+ "flashsale_name_s": cheapest_flashsale.get('flashsale_name', ''),
+ "flashsale_start_date_s": cheapest_flashsale.get('flashsale_start_date', ''),
+ "flashsale_end_date_s": cheapest_flashsale.get('flashsale_end_date', ''),
+ "flashsale_base_price_f": cheapest_flashsale.get('flashsale_base_price', 0),
+ "flashsale_discount_f": cheapest_flashsale.get('flashsale_discount', 0),
+ "flashsale_price_f": cheapest_flashsale.get('flashsale_price', 0)
+ }
+
+ price_doc = {}
+
+ # Loop tier to get each variant price
+ for tier_number in TIER_NUMBERS:
+ for variant in template.product_variant_ids:
+ tier = variant._get_pricelist_tier(tier_number)
+ discount_tier_key = f'discount_tier{tier_number}'
+ price_tier_key = f'price_tier{tier_number}'
+
+ variant_discount = tier.get(discount_tier_key, 0)
+ variant_price = tier.get(price_tier_key, 0)
+
+ price_tier = price_doc.get(f"{price_tier_key}_f", 0)
+ # When price tier is 0 or variant_price less than price tier then use variant price
+ if price_tier == 0 or (variant_price < price_tier and variant_price > 0):
+ price_doc[f"{discount_tier_key}_f"] = variant_discount
+ price_doc[f"{price_tier_key}_f"] = variant_price
+
document = solr_model.get_doc('product', template.id)
- document.update({
- "id": template.id,
- "flashsale_id_i": flashsale_data.get('flashsale_id', 0),
- "flashsale_tag_s": flashsale_data.get('flashsale_tag', ''),
- "flashsale_name_s": flashsale_data.get('flashsale_name', ''),
- "flashsale_start_date_s": flashsale_data.get('flashsale_start_date', ''),
- "flashsale_end_date_s": flashsale_data.get('flashsale_end_date', ''),
- "flashsale_base_price_f": flashsale_data.get('flashsale_base_price', 0),
- "flashsale_discount_f": flashsale_data.get('flashsale_discount', 0),
- "flashsale_price_f": flashsale_data.get('flashsale_price', 0),
- "price_f": price_excl,
- "discount_f": discount,
- "price_discount_f": price_excl_after_disc,
- "tax_f": tax,
- "price_v2_f": price_excl_v2,
- "price_discount_v2_f": price_excl_after_disc_v2,
- "tax_v2_f": tax_v2,
- })
-
- for tier_number in [1, 2, 3, '1_v2', '2_v2', '3_v2', '4_v2', '5_v2']:
- tier = variant._get_pricelist_tier(tier_number)
- document.update({
- f"discount_tier{tier_number}_f": tier.get(f'discount_tier{tier_number}', 0),
- f"price_tier{tier_number}_f": tier.get(f'price_tier{tier_number}', 0),
- })
-
+ document['id'] = template.id
+ document.update(flashsale_doc)
+ document.update(price_doc)
document.update({"has_price_info_b": True})
self.solr().add(docs=[document], softCommit=True)
@@ -220,3 +219,8 @@ class ProductTemplate(models.Model):
results.append(result)
return results
+
+ @api.constrains('active')
+ def constrains_active(self):
+ for rec in self:
+ rec._create_solr_queue_sync_product_template() \ No newline at end of file
diff --git a/indoteknik_custom/models/solr/x_manufactures.py b/indoteknik_custom/models/solr/x_manufactures.py
index 375b7708..98b1d01d 100644
--- a/indoteknik_custom/models/solr/x_manufactures.py
+++ b/indoteknik_custom/models/solr/x_manufactures.py
@@ -40,7 +40,7 @@ class XManufactures(models.Model):
document.update({
'id': brands.id,
'display_name_s': brands.display_name,
- 'name_s': brands.x_name,
+ 'name_s': brands.x_name.lower(),
'sequence_i': brands.sequence or '',
'negara_asal_s': brands.x_negara_asal or '',
'short_desc_s': brands.x_short_desc or '',
diff --git a/indoteknik_custom/models/stock_picking.py b/indoteknik_custom/models/stock_picking.py
index 418649b1..a5e533b1 100644
--- a/indoteknik_custom/models/stock_picking.py
+++ b/indoteknik_custom/models/stock_picking.py
@@ -1,6 +1,7 @@
from odoo import fields, models, api, _
from odoo.exceptions import AccessError, UserError, ValidationError
from odoo.tools.float_utils import float_is_zero
+from datetime import datetime
from itertools import groupby
import pytz, datetime
@@ -69,11 +70,12 @@ class StockPicking(models.Model):
('hold', 'Hold by Sales'),
('not_paid', 'Customer belum bayar'),
('partial', 'Kirim Parsial')
- ], string='Note', help='jika field ini diisi maka tidak akan dihitung ke lead time')
+ ], string='Note Logistic', help='jika field ini diisi maka tidak akan dihitung ke lead time')
waybill_id = fields.One2many(comodel_name='airway.bill', inverse_name='do_id', string='Airway Bill')
purchase_representative_id = fields.Many2one('res.users', related='move_lines.purchase_line_id.order_id.user_id', string="Purchase Representative", readonly=True)
carrier_id = fields.Many2one('delivery.carrier', string='Shipping Method')
shipping_status = fields.Char(string='Shipping Status', compute="_compute_shipping_status")
+ date_reserved = fields.Datetime(string="Date Reserved", help='Tanggal ter-reserved semua barang nya')
def _compute_shipping_status(self):
for rec in self:
@@ -309,6 +311,10 @@ class StockPicking(models.Model):
if product:
product.product_tmpl_id._create_solr_queue('_sync_product_stock_to_solr')
+ if not self.date_reserved:
+ current_time = datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S')
+ self.date_reserved = current_time
+
res = super(StockPicking, self).button_validate()
self.calculate_line_no()
return res
diff --git a/indoteknik_custom/models/stock_warehouse_orderpoint.py b/indoteknik_custom/models/stock_warehouse_orderpoint.py
new file mode 100644
index 00000000..277c8dc3
--- /dev/null
+++ b/indoteknik_custom/models/stock_warehouse_orderpoint.py
@@ -0,0 +1,10 @@
+from odoo import fields, models, api, _
+
+class StockWarehouseOrderpoint(models.Model):
+ _inherit = 'stock.warehouse.orderpoint'
+
+ responsible_id = fields.Many2one('res.users', string='Responsible', compute='_compute_responsible')
+
+ def _compute_responsible(self):
+ for stock in self:
+ stock.responsible_id = stock.product_id.x_manufacture.user_id
diff --git a/indoteknik_custom/models/users.py b/indoteknik_custom/models/users.py
index b90c0097..2ff9933e 100644
--- a/indoteknik_custom/models/users.py
+++ b/indoteknik_custom/models/users.py
@@ -11,6 +11,7 @@ class Users(models.Model):
is_accounting = fields.Boolean(string='Accounting', help='Berhak Approval Internal Use')
is_logistic_approver = fields.Boolean(string='Logistic Approver', help='Berhak Approval Penerimaan Barang')
is_editor_product = fields.Boolean(string='Editor Product', help='Berhak Mengedit Data Product')
+ is_admin_reconcile = fields.Boolean(string='Admin Reconcile', help='Berhak Mengedit Journal Reconcile')
def notify_internal_users(self, message, title):
users = self.search([('share', '=', False)])
diff --git a/indoteknik_custom/models/voucher.py b/indoteknik_custom/models/voucher.py
index a40f8c42..66c50c24 100644
--- a/indoteknik_custom/models/voucher.py
+++ b/indoteknik_custom/models/voucher.py
@@ -12,7 +12,7 @@ class Voucher(models.Model):
image = fields.Binary(string='Image')
code = fields.Char(string='Code', help='Kode voucher yang akan berlaku untuk pengguna')
description = fields.Text(string='Description')
- discount_amount = fields.Integer(string='Discount Amount')
+ discount_amount = fields.Float(string='Discount Amount')
discount_type = fields.Selection(string='Discount Type',
selection=[
('percentage', 'Percentage'),
diff --git a/indoteknik_custom/models/voucher_line.py b/indoteknik_custom/models/voucher_line.py
index 8b449d1f..890471dc 100644
--- a/indoteknik_custom/models/voucher_line.py
+++ b/indoteknik_custom/models/voucher_line.py
@@ -7,7 +7,7 @@ class Voucher(models.Model):
voucher_id = fields.Many2one('voucher', string='Voucher')
manufacture_id = fields.Many2one('x_manufactures', string='Brand')
min_purchase_amount = fields.Integer(string='Min. Purchase Amount', help='Nominal minimum untuk dapat menggunakan voucher. Isi 0 jika tidak ada minimum purchase amount')
- discount_amount = fields.Integer(string='Discount Amount')
+ discount_amount = fields.Float(string='Discount Amount')
discount_type = fields.Selection(string='Discount Type',
selection=[
('percentage', 'Percentage'),
diff --git a/indoteknik_custom/models/website_user_cart.py b/indoteknik_custom/models/website_user_cart.py
index 47a695fe..bbc14c88 100644
--- a/indoteknik_custom/models/website_user_cart.py
+++ b/indoteknik_custom/models/website_user_cart.py
@@ -55,11 +55,15 @@ class WebsiteUserCart(models.Model):
def get_product_by_user(self, user_id, selected=False, source=False):
user_id = int(user_id)
- source = source if source else 'add_to_cart'
+
+ if source == 'buy':
+ source = ['buy']
+ else:
+ source = ['add_to_cart', 'buy']
parameters = [
('user_id', '=', user_id),
- ('source', '=', source)
+ ('source', 'in', source)
]
if selected:
@@ -91,6 +95,7 @@ class WebsiteUserCart(models.Model):
tax = round(subtotal * 0.11)
grand_total = subtotal + tax
total_weight = sum(x['weight'] * x['quantity'] for x in products)
+ total_weight = round(total_weight, 2)
result = {
'total_purchase': total_purchase,
'total_discount': total_discount,
diff --git a/indoteknik_custom/models/x_manufactures.py b/indoteknik_custom/models/x_manufactures.py
index e48a5367..abedf0cf 100755
--- a/indoteknik_custom/models/x_manufactures.py
+++ b/indoteknik_custom/models/x_manufactures.py
@@ -47,6 +47,8 @@ class XManufactures(models.Model):
parent_id = fields.Many2one('x_manufactures', string='Parent', help='Parent Brand tersebut')
category_ids = fields.Many2many('product.public.category', string='Category', help='Brand tsb memiliki Category apa saja')
vendor_ids = fields.Many2many('res.partner', string='Vendor', compute='_compute_vendor_ids')
+ # user_id = fields.Many2one('res.users', string='Responsible', domain="['|'('id', '=', 19), ('id', '=', 6)]", help="Siapa yang bertanggung jawab")
+ user_id = fields.Many2one('res.users', string='Responsible', help="Siapa yang bertanggung jawab")
def _compute_vendor_ids(self):
for manufacture in self:
diff --git a/indoteknik_custom/security/ir.model.access.csv b/indoteknik_custom/security/ir.model.access.csv
index e362e546..ff467204 100755
--- a/indoteknik_custom/security/ir.model.access.csv
+++ b/indoteknik_custom/security/ir.model.access.csv
@@ -77,4 +77,8 @@ access_cost_centre,access.cost.centre,model_cost_centre,,1,1,1,1
access_stock_scheduler_compute,access.stock.scheduler.compute,model_stock_scheduler_compute,,1,1,1,1
access_sale_order_promotion,access.sale.order.promotion,model_sale_order_promotion,,1,1,1,1
access_sale_orders_multi_update,access.sale.orders.multi_update,model_sale_orders_multi_update,,1,1,1,1
-access_quotation_so_multi_update,access.quotation.so.multi_update,model_quotation_so_multi_update,,1,1,1,1 \ No newline at end of file
+access_quotation_so_multi_update,access.quotation.so.multi_update,model_quotation_so_multi_update,,1,1,1,1
+access_product_monitoring,access.product.monitoring,model_product_monitoring,,1,1,1,1
+access_customer_commision,access.customer.commision,model_customer_commision,,1,1,1,1
+access_customer_commision_line,access.customer.commision.line,model_customer_commision_line,,1,1,1,1
+access_customer_rebate,access.customer.rebate,model_customer_rebate,,1,1,1,1 \ No newline at end of file
diff --git a/indoteknik_custom/views/account_bank_statement.xml b/indoteknik_custom/views/account_bank_statement.xml
new file mode 100644
index 00000000..db380f37
--- /dev/null
+++ b/indoteknik_custom/views/account_bank_statement.xml
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<odoo>
+ <data>
+ <record id="account_bank_statement_tree_inherit" model="ir.ui.view">
+ <field name="name">account.bank.statement.tree</field>
+ <field name="model">account.bank.statement</field>
+ <field name="inherit_id" ref="account.view_bank_statement_tree"/>
+ <field name="arch" type="xml">
+ <field name="state" position="after">
+ <field name="is_edit"/>
+ </field>
+ </field>
+ </record>
+
+ <record id="account_bank_statement_form_inherit" model="ir.ui.view">
+ <field name="name">account.bank.statement.form</field>
+ <field name="model">account.bank.statement</field>
+ <field name="inherit_id" ref="account.view_bank_statement_form"/>
+ <field name="arch" type="xml">
+ <button name="button_reprocess" position="after">
+ <button string="Unlock" class="oe_highlight" name="is_edited" type="object" attrs="{'invisible':['|', '|', ('is_edit', '=', True), ('line_ids','=',[]), ('state', '!=', 'confirm')]}"/>
+
+ <button string="Lock" class="oe_highlight" name="not_edited" type="object" attrs="{'invisible':['|', '|', ('is_edit', '=', False), ('line_ids','=',[]), ('state', '!=', 'confirm')]}"/>
+ </button>
+ <field name="date" position="after">
+ <field name="is_edit" invisible="1"/>
+ </field>
+ </field>
+ </record>
+ </data>
+</odoo> \ No newline at end of file
diff --git a/indoteknik_custom/views/account_move.xml b/indoteknik_custom/views/account_move.xml
index c45dab25..1721abb6 100644
--- a/indoteknik_custom/views/account_move.xml
+++ b/indoteknik_custom/views/account_move.xml
@@ -13,6 +13,9 @@
<field name="invoice_date" position="after">
<field name="payment_schedule" attrs="{'invisible': [('move_type', '!=', 'in_invoice')]}"/>
</field>
+ <field name="payment_reference" position="after">
+ <field name="date_completed" readonly="1" attrs="{'invisible': [('move_type', '!=', 'out_invoice')]}"/>
+ </field>
<field name="efaktur_document" position="before">
<field name="no_faktur_pajak" readonly="1"/>
</field>
@@ -28,7 +31,7 @@
<field name="counter"/>
</field>
<notebook position="inside">
- <page string="Due Extension">
+ <page string="Due Extension" attrs="{'invisible': [('move_type', '!=', 'out_invoice')]}">
<field name="due_line">
<tree>
<field name="due_id"/>
@@ -70,8 +73,12 @@
<field name="model">account.move</field>
<field name="inherit_id" ref="account.view_in_invoice_tree"/>
<field name="arch" type="xml">
- <field name="payment_state" position="after">
- <field name="payment_schedule" optional="hide"/>
+ <field name="invoice_date_due" position="after">
+ <field name="bill_day_to_due" string="Due Date" widget="remaining_days"/>
+ </field>
+
+ <field name="invoice_date_due" position="attributes">
+ <attribute name="invisible">1</attribute>
</field>
</field>
</record>
diff --git a/indoteknik_custom/views/automatic_purchase.xml b/indoteknik_custom/views/automatic_purchase.xml
index 49751f4e..0478304e 100644
--- a/indoteknik_custom/views/automatic_purchase.xml
+++ b/indoteknik_custom/views/automatic_purchase.xml
@@ -10,6 +10,7 @@
<field name="description"/>
<field name="notification" readonly="1"/>
<field name="is_po" readonly="1"/>
+ <field name="responsible_id"/>
</tree>
</field>
</record>
@@ -57,6 +58,7 @@
<group>
<field name="date_doc"/>
<field name="vendor_id"/>
+ <field name="responsible_id"/>
<field name="description"/>
<field name="notification" readonly="1"/>
</group>
diff --git a/indoteknik_custom/views/customer_commision.xml b/indoteknik_custom/views/customer_commision.xml
new file mode 100644
index 00000000..008c79f8
--- /dev/null
+++ b/indoteknik_custom/views/customer_commision.xml
@@ -0,0 +1,189 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<odoo>
+ <record id="customer_commision_tree" model="ir.ui.view">
+ <field name="name">customer.commision.tree</field>
+ <field name="model">customer.commision</field>
+ <field name="arch" type="xml">
+ <tree>
+ <field name="number"/>
+ <field name="date_from"/>
+ <field name="date_to"/>
+ <field name="partner_id"/>
+ <field name="description"/>
+ <field name="notification" readonly="1"/>
+ <field name="status" readonly="1"/>
+ </tree>
+ </field>
+ </record>
+
+ <record id="customer_commision_line_tree" model="ir.ui.view">
+ <field name="name">customer.commision.line.tree</field>
+ <field name="model">customer.commision.line</field>
+ <field name="arch" type="xml">
+ <tree editable="top" create="false">
+ <field name="partner_id" readonly="1"/>
+ <field name="invoice_id" readonly="1"/>
+ <field name="state" readonly="1"/>
+ <field name="product_id" readonly="1" optional="hide"/>
+ <field name="dpp" readonly="1"/>
+ <field name="tax" readonly="1" optional="hide"/>
+ <field name="total" readonly="1" optional="hide"/>
+ </tree>
+ </field>
+ </record>
+
+ <record id="customer_commision_form" model="ir.ui.view">
+ <field name="name">customer_commision_form</field>
+ <field name="model">customer.commision</field>
+ <field name="arch" type="xml">
+ <form>
+ <header>
+ <button name="action_confirm_customer_commision"
+ string="Confirm" type="object"
+ options="{}"/>
+ </header>
+ <sheet string="Customer Commision">
+ <div class="oe_button_box" name="button_box"/>
+ <group>
+ <group>
+ <field name="number"/>
+ <field name="date_from"/>
+ <field name="partner_id"/>
+ <field name="description"/>
+ <field name="commision_percent"/>
+ <field name="commision_amt"/>
+ </group>
+ <group>
+ <div>
+ <button name="generate_customer_commision"
+ string="Generate Line"
+ type="object"
+ class="mr-2 oe_highlight"
+ />
+ </div>
+ <field name="date_to"/>
+ <field name="commision_type"/>
+ <field name="notification" readonly="1"/>
+ <field name="status" readonly="1"/>
+ <field name="total_dpp"/>
+ </group>
+ </group>
+ <notebook>
+ <page string="Lines">
+ <field name="commision_lines"/>
+ </page>
+ </notebook>
+ </sheet>
+ <div class="oe_chatter">
+ <field name="message_follower_ids" widget="mail_followers"/>
+ <field name="message_ids" widget="mail_thread"/>
+ </div>
+ </form>
+ </field>
+ </record>
+
+ <record id="customer_commision_action" model="ir.actions.act_window">
+ <field name="name">Customer Commision</field>
+ <field name="type">ir.actions.act_window</field>
+ <field name="res_model">customer.commision</field>
+ <field name="view_mode">tree,form</field>
+ </record>
+
+ <menuitem id="menu_customer_commision_acct"
+ name="Customer Commision"
+ action="customer_commision_action"
+ parent="account.menu_finance_entries"
+ sequence="113"
+ />
+
+ <menuitem id="menu_customer_commision_sales"
+ name="Customer Commision"
+ action="customer_commision_action"
+ parent="sale.product_menu_catalog"
+ sequence="101"
+ />
+
+ <record id="customer_rebate_tree" model="ir.ui.view">
+ <field name="name">customer.rebate.tree</field>
+ <field name="model">customer.rebate</field>
+ <field name="arch" type="xml">
+ <tree>
+ <field name="partner_id"/>
+ <field name="date_from"/>
+ <field name="date_to"/>
+ <field name="description"/>
+ <field name="target_1st"/>
+ <field name="target_2nd"/>
+ <field name="achieve_1"/>
+ <field name="achieve_2"/>
+ <field name="dpp_q1" optional="hide"/>
+ <field name="dpp_q2" optional="hide"/>
+ <field name="dpp_q3" optional="hide"/>
+ <field name="dpp_q4" optional="hide"/>
+ <field name="status_q1" optional="hide"/>
+ <field name="status_q2" optional="hide"/>
+ <field name="status_q3" optional="hide"/>
+ <field name="status_q4" optional="hide"/>
+ </tree>
+ </field>
+ </record>
+
+ <record id="customer_rebate_form" model="ir.ui.view">
+ <field name="name">customer_rebate_form</field>
+ <field name="model">customer.rebate</field>
+ <field name="arch" type="xml">
+ <form>
+ <sheet string="Customer Rebate">
+ <div class="oe_button_box" name="button_box"/>
+ <group>
+ <group>
+ <field name="date_from"/>
+ <field name="partner_id"/>
+ <field name="target_1st"/>
+ <field name="target_2nd"/>
+ <field name="dpp_q1"/>
+ <field name="dpp_q2"/>
+ <field name="dpp_q3"/>
+ <field name="dpp_q4"/>
+ </group>
+ <group>
+ <field name="date_to"/>
+ <field name="description"/>
+ <field name="achieve_1"/>
+ <field name="achieve_2"/>
+ <field name="status_q1"/>
+ <field name="status_q2"/>
+ <field name="status_q3"/>
+ <field name="status_q4"/>
+ </group>
+ </group>
+ </sheet>
+ <div class="oe_chatter">
+ <field name="message_follower_ids" widget="mail_followers"/>
+ <field name="message_ids" widget="mail_thread"/>
+ </div>
+ </form>
+ </field>
+ </record>
+
+ <record id="customer_rebate_action" model="ir.actions.act_window">
+ <field name="name">Customer Rebate</field>
+ <field name="type">ir.actions.act_window</field>
+ <field name="res_model">customer.rebate</field>
+ <field name="view_mode">tree,form</field>
+ </record>
+
+ <menuitem id="menu_customer_rebate_acct"
+ name="Customer Rebate"
+ action="customer_rebate_action"
+ parent="account.menu_finance_entries"
+ sequence="114"
+ />
+
+ <menuitem id="menu_customer_rebate_sales"
+ name="Customer Rebate"
+ action="customer_rebate_action"
+ parent="sale.product_menu_catalog"
+ sequence="102"
+ />
+</odoo> \ No newline at end of file
diff --git a/indoteknik_custom/views/ir_sequence.xml b/indoteknik_custom/views/ir_sequence.xml
index 6798e5b4..86259b12 100644
--- a/indoteknik_custom/views/ir_sequence.xml
+++ b/indoteknik_custom/views/ir_sequence.xml
@@ -60,5 +60,15 @@
<field name="number_next">1</field>
<field name="number_increment">1</field>
</record>
+
+ <record id="sequence_commision_customer" model="ir.sequence">
+ <field name="name">Customer Commision</field>
+ <field name="code">customer.commision</field>
+ <field name="active">TRUE</field>
+ <field name="prefix">CC/%(year)s/</field>
+ <field name="padding">5</field>
+ <field name="number_next">1</field>
+ <field name="number_increment">1</field>
+ </record>
</data>
</odoo> \ No newline at end of file
diff --git a/indoteknik_custom/views/product_monitoring.xml b/indoteknik_custom/views/product_monitoring.xml
new file mode 100644
index 00000000..779a7dd7
--- /dev/null
+++ b/indoteknik_custom/views/product_monitoring.xml
@@ -0,0 +1,55 @@
+<?xml version="1.0" encoding="utf-8" ?>
+<odoo>
+ <record id="product_monitoring_tree" model="ir.ui.view">
+ <field name="name">product.monitoring.tree</field>
+ <field name="model">product.monitoring</field>
+ <field name="arch" type="xml">
+ <tree create="false" multi_edit="1">
+ <field name="product_id"/>
+ <field name="outgoing_qty"/>
+ <field name="incoming_qty"/>
+ <field name="qty_available"/>
+ <field name="qty_upcoming"/>
+ <field name="status_stock"
+ widget="badge"
+ decoration-danger="status_stock == 'outgoing_gt_stock'"
+ decoration-success="status_stock == 'outgoing_lt_stock'"
+ />
+ </tree>
+ </field>
+ </record>
+
+ <record id="product_monitoring_form" model="ir.ui.view">
+ <field name="name">product.monitoring.form</field>
+ <field name="model">product.monitoring</field>
+ <field name="arch" type="xml">
+ <form create="false" edit="false">
+ <sheet>
+ <group>
+ <group>
+ <field name="product_id"/>
+ <field name="outgoing_qty"/>
+ <field name="incoming_qty"/>
+ <field name="qty_available"/>
+ </group>
+ </group>
+ </sheet>
+ </form>
+ </field>
+ </record>
+
+ <record id="product_monitoring_action" model="ir.actions.act_window">
+ <field name="name">Product Monitoring</field>
+ <field name="type">ir.actions.act_window</field>
+ <field name="res_model">product.monitoring</field>
+ <field name="view_mode">tree,form</field>
+ </record>
+
+ <menuitem
+ id="menu_product_monitoring_in_purchase"
+ name="Product Monitoring"
+ parent="menu_monitoring_in_purchase"
+ sequence="1"
+ action="product_monitoring_action"
+ />
+</odoo> \ No newline at end of file
diff --git a/indoteknik_custom/views/product_template.xml b/indoteknik_custom/views/product_template.xml
index a3a23101..92d2191e 100755
--- a/indoteknik_custom/views/product_template.xml
+++ b/indoteknik_custom/views/product_template.xml
@@ -10,9 +10,11 @@
<field name="web_tax_id"/>
<field name="x_manufacture"/>
<field name="x_model_product"/>
+ <field name="kind_of"/>
<field name="x_studio_field_tGhJR" widget="many2many_tags"/>
</field>
<field name="uom_po_id" position="after">
+ <field name="unpublished" />
<field name="desc_update_solr" readonly="1" />
<field name="last_update_solr" readonly="1" />
</field>
diff --git a/indoteknik_custom/views/purchase_order.xml b/indoteknik_custom/views/purchase_order.xml
index e0ec86f9..bc84bcd1 100755
--- a/indoteknik_custom/views/purchase_order.xml
+++ b/indoteknik_custom/views/purchase_order.xml
@@ -37,7 +37,7 @@
<field name="currency_id" position="after">
<field name="summary_qty_po"/>
<field name="count_line_product"/>
- <field name="payment_term_id"/>
+ <field name="payment_term_id" required="1"/>
</field>
<field name="amount_total" position="after">
<field name="total_margin"/>
@@ -65,6 +65,7 @@
</field>
<field name="price_subtotal" position="after">
<field name="so_line_id" attrs="{'readonly': 1}" optional="hide"/>
+ <field name="indent" optional="hide"/>
</field>
<page name="purchase_delivery_invoice" position="after">
<page name="purchase_vendor_bills" string="Vendor Bills" groups="indoteknik_custom.technical_administrator">
@@ -75,8 +76,10 @@
</page>
<field name="fiscal_position_id" position="after">
<field name="note_description"/>
+ <field name="description"/>
<field name="total_so_percent_margin"/>
<field name="has_active_invoice" invisible="1" />
+ <field name="responsible_ids" widget="many2many_tags"/>
</field>
<field name="order_line" position="attributes">
@@ -94,6 +97,12 @@
<xpath expr="//form/sheet/notebook/page/field[@name='order_line']/tree/field[@name='product_qty']" position="attributes">
<attribute name="attrs">{'readonly': [], 'required': True}</attribute>
</xpath>
+
+ <xpath expr="//form/sheet/notebook/page[@name='purchase_delivery_invoice']" position="before">
+ <page string="Indent" name="purchase_order_lines_indent">
+ <field name="purchase_order_lines"/>
+ </page>
+ </xpath>
</field>
</record>
</data>
@@ -106,6 +115,7 @@
<field name="arch" type="xml">
<field name="create_date" position="after">
<field name="approval_status" />
+ <field name="responsible_ids" widget="many2many_tags" optional="hide"/>
</field>
</field>
</record>
@@ -121,6 +131,7 @@
<field name="po_status"/>
<field name="note_description" optional="hide"/>
<field name="sale_order_id" optional="hide"/>
+ <field name="responsible_ids" widget="many2many_tags" optional="hide"/>
</field>
</field>
</record>
@@ -138,7 +149,7 @@
</record>
</data>
<data>
- <record id="purchase_order_search_inherit" model="ir.ui.view">
+ <record id="rfq_order_search_inherit" model="ir.ui.view">
<field name="name">purchase.order.select.inherit</field>
<field name="model">purchase.order</field>
<field name="inherit_id" ref="purchase.view_purchase_order_filter"/>
@@ -149,4 +160,30 @@
</field>
</record>
</data>
+ <data>
+ <record id="cron_stock_scheduler_compute" model="ir.cron">
+ <field name="name">Run Scheduler Reserve Stock</field>
+ <field name="interval_number">1</field>
+ <field name="interval_type">hours</field>
+ <field name="numbercall">-1</field>
+ <field name="doall" eval="False"/>
+ <field name="model_id" ref="model_stock_scheduler_compute"/>
+ <field name="code">model.procure_calculation()</field>
+ <field name="state">code</field>
+ <field name="priority">75</field>
+ <field name="active">True</field>
+ </record>
+ </data>
+ <data>
+ <record id="purchase_order_line_indent_tree" model="ir.ui.view">
+ <field name="name">purchase.order.line.indent.tree</field>
+ <field name="model">purchase.order.line</field>
+ <field name="arch" type="xml">
+ <tree editable="top" create="false" delete="false">
+ <field name="product_id" readonly="1"/>
+ <field name="indent"/>
+ </tree>
+ </field>
+ </record>
+ </data>
</odoo> \ No newline at end of file
diff --git a/indoteknik_custom/views/purchase_pricelist.xml b/indoteknik_custom/views/purchase_pricelist.xml
index f9fd52ba..f4cd4e78 100755
--- a/indoteknik_custom/views/purchase_pricelist.xml
+++ b/indoteknik_custom/views/purchase_pricelist.xml
@@ -11,6 +11,8 @@
<field name="system_price"/>
<field name="human_last_update"/>
<field name="system_last_update"/>
+ <field name="count_trx_po"/>
+ <field name="count_trx_po_vendor"/>
</tree>
</field>
</record>
@@ -27,6 +29,10 @@
<field name="vendor_id" context="{'res_partner_search_mode': 'supplier'}"/>
<field name="product_price"/>
<field name="system_price"/>
+ <field name="human_last_update"/>
+ <field name="system_last_update"/>
+ <field name="count_trx_po"/>
+ <field name="count_trx_po_vendor"/>
</group>
</group>
</sheet>
diff --git a/indoteknik_custom/views/requisition.xml b/indoteknik_custom/views/requisition.xml
index e7335a57..e9c3b4e0 100644
--- a/indoteknik_custom/views/requisition.xml
+++ b/indoteknik_custom/views/requisition.xml
@@ -62,16 +62,6 @@
</group>
<group>
<div>
- <button name="create_requisition_from_sales"
- string="Create Line"
- type="object"
- class="mr-2 oe_highlight"
- />
- <button name="create_requisition_from_sales_with_price"
- string="Create Line with Price"
- type="object"
- class="mr-2 oe_highlight"
- />
<button name="create_po_from_requisition"
string="Create PO"
type="object"
@@ -82,13 +72,26 @@
</group>
<notebook>
<page string="Lines">
- <field name="requisition_lines"/>
+ <field name="requisition_lines">
+ <tree editable="line">
+ <field name="product_id"/>
+ <field name="partner_id"/>
+ <field name="qty_purchase"/>
+ <field name="price_unit"/>
+ <field name="subtotal"/>
+ <field name="brand_id"/>
+ </tree>
+ </field>
</page>
<page string="Matches">
<field name="requisition_match"/>
</page>
</notebook>
</sheet>
+ <div class="oe_chatter">
+ <field name="message_follower_ids" widget="mail_followers"/>
+ <field name="message_ids" widget="mail_thread"/>
+ </div>
</form>
</field>
</record>
diff --git a/indoteknik_custom/views/res_partner.xml b/indoteknik_custom/views/res_partner.xml
index d609fdd5..c1ae3ed3 100644
--- a/indoteknik_custom/views/res_partner.xml
+++ b/indoteknik_custom/views/res_partner.xml
@@ -14,6 +14,8 @@
<field name="industry_id" position="after">
<field name="company_type_id"/>
<field name="group_partner_id"/>
+ <field name="is_potential"/>
+ <field name="digital_invoice_tax"/>
</field>
<field name="npwp" position="before">
<field name="customer_type"/>
diff --git a/indoteknik_custom/views/sale_monitoring.xml b/indoteknik_custom/views/sale_monitoring.xml
index 641eb8fb..207277af 100755
--- a/indoteknik_custom/views/sale_monitoring.xml
+++ b/indoteknik_custom/views/sale_monitoring.xml
@@ -4,7 +4,7 @@
<field name="name">sale.monitoring.tree</field>
<field name="model">sale.monitoring</field>
<field name="arch" type="xml">
- <tree create="false" multi_edit="1">
+ <tree create="false" multi_edit="1" default_order="date_order asc">
<header>
<button name="action_refresh" string="Refresh" class="oe_highlight" type="object" />
</header>
@@ -18,6 +18,7 @@
<field name="qty_po_received"/>
<field name="qty_so_delivered"/>
<field name="qty_so_invoiced"/>
+ <field name="purchase_representative_id"/>
<field name="status"
widget="badge"
decoration-danger="status == 'Belum/Kurang PO'"
@@ -25,7 +26,8 @@
decoration-success="status == 'Siap kirim'"
decoration-info="status == 'Delivered' or status == 'Invoiced'"
/>
- <field name="note"/>
+ <field name="note_so_line"/>
+ <field name="note" optional="hide"/>
</tree>
</field>
</record>
@@ -49,7 +51,8 @@
decoration-info="status == 'Delivered' or status == 'Invoiced'"
/>
<field name="po_number"/>
- <field name="note"/>
+ <field name="note_so_line"/>
+ <field name="note" optional="hide"/>
</group>
<group>
<field name="qty_so"/>
@@ -58,6 +61,7 @@
<field name="qty_po_received"/>
<field name="qty_so_delivered"/>
<field name="qty_so_invoiced"/>
+ <field name="purchase_representative_id"/>
</group>
</group>
</sheet>
diff --git a/indoteknik_custom/views/sale_order.xml b/indoteknik_custom/views/sale_order.xml
index e0e9ac54..125296e3 100755
--- a/indoteknik_custom/views/sale_order.xml
+++ b/indoteknik_custom/views/sale_order.xml
@@ -45,12 +45,12 @@
<field name="helper_by_id" readonly="1"/>
</field>
<field name="analytic_account_id" position="after">
- <field name="customer_type" attrs="{'required': ['|', ('create_date', '&gt;', '2023-06-28'), ('create_date', '=', False)]}"/>
- <field name="npwp" placeholder='99.999.999.9-999.999' attrs="{'required': ['|', ('create_date', '&gt;', '2023-06-28'), ('create_date', '=', False)]}"/>
- <field name="sppkp" attrs="{'invisible': [('customer_type','!=','pkp')], 'required': [('customer_type', '=', 'pkp')]}"/>
+ <field name="customer_type" required="1"/>
+ <field name="npwp" placeholder='99.999.999.9-999.999' required="1"/>
+ <field name="sppkp" attrs="{'required': [('customer_type', '=', 'pkp')]}"/>
<field name="email" required="1"/>
<field name="due_id" readonly="1"/>
- <field name="source_id" domain="[('id', 'in', [32, 59, 60, 61])]" attrs="{'required':[('create_date', '&gt;', '2023-09-10')]}"/>
+ <field name="source_id" domain="[('id', 'in', [32, 59, 60, 61])]" required="1"/>
</field>
<field name="partner_shipping_id" position="after">
<field name="real_shipping_id"/>
@@ -92,6 +92,7 @@
"/>
<field name="purchase_tax_id" attrs="{'readonly': [('parent.approval_status', '!=', False)]}" domain="[('type_tax_use','=','purchase')]"/>
<field name="item_percent_margin"/>
+ <field name="note" optional="hide"/>
<field name="note_procurement" optional="hide"/>
<field name="vendor_subtotal" optional="hide"/>
<field name="amount_voucher_disc" string="Voucher" readonly="1" optional="hide"/>
diff --git a/indoteknik_custom/views/stock_picking.xml b/indoteknik_custom/views/stock_picking.xml
index 9f03235d..b0932d5a 100644
--- a/indoteknik_custom/views/stock_picking.xml
+++ b/indoteknik_custom/views/stock_picking.xml
@@ -15,6 +15,7 @@
<field name="driver_departure_date" optional="hide"/>
<field name="driver_arrival_date" optional="hide"/>
<field name="note_logistic" optional="hide"/>
+ <field name="note" optional="hide"/>
</field>
<field name="partner_id" position="after">
<field name="purchase_representative_id"/>
@@ -71,6 +72,7 @@
/>
</field>
<field name="group_id" position="before">
+ <field name="date_reserved"/>
<field name="is_internal_use"
string="Internal Use"
type="object"
diff --git a/indoteknik_custom/views/stock_warehouse_orderpoint.xml b/indoteknik_custom/views/stock_warehouse_orderpoint.xml
new file mode 100644
index 00000000..038b09cc
--- /dev/null
+++ b/indoteknik_custom/views/stock_warehouse_orderpoint.xml
@@ -0,0 +1,15 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<odoo>
+ <data>
+ <record id="stock_warehouse_orderpoint_inherit" model="ir.ui.view">
+ <field name="name">stock.warehouse.orderpoint.tree</field>
+ <field name="model">stock.warehouse.orderpoint</field>
+ <field name="inherit_id" ref="stock.view_warehouse_orderpoint_tree_editable_config"/>
+ <field name="arch" type="xml">
+ <field name="product_uom_name" position="after">
+ <field name="responsible_id" optional="hide"/>
+ </field>
+ </field>
+ </record>
+ </data>
+</odoo> \ No newline at end of file
diff --git a/indoteknik_custom/views/users.xml b/indoteknik_custom/views/users.xml
index d67b4474..020d8ddc 100644
--- a/indoteknik_custom/views/users.xml
+++ b/indoteknik_custom/views/users.xml
@@ -13,6 +13,7 @@
<field name="is_leader"/>
<field name="is_logistic_approver"/>
<field name="is_editor_product"/>
+ <field name="is_admin_reconcile"/>
</field>
</field>
</record>
diff --git a/indoteknik_custom/views/x_manufactures.xml b/indoteknik_custom/views/x_manufactures.xml
index f68a0e00..d413be12 100755
--- a/indoteknik_custom/views/x_manufactures.xml
+++ b/indoteknik_custom/views/x_manufactures.xml
@@ -24,6 +24,7 @@
<field name="x_manufacture_service_center"/>
<field name="cache_reset_status"/>
<field name="parent_id"/>
+ <field name="user_id" optional="hide"/>
</tree>
</field>
</record>
@@ -46,6 +47,7 @@
<field name="cache_reset_status"/>
<field name="parent_id"/>
<field name="category_ids" widget="many2many_tags"/>
+ <field name="user_id"/>
</group>
<group>
<field name="x_logo_manufacture" widget="image"/>