From 8d45e6557063f708e824b2700331c67168dde6c9 Mon Sep 17 00:00:00 2001 From: Rafi Zadanly Date: Tue, 22 Aug 2023 15:56:45 +0700 Subject: Add get stock picking and get stock picking detail tracking API --- indoteknik_api/controllers/api_v1/__init__.py | 3 +- indoteknik_api/controllers/api_v1/stock_picking.py | 77 ++++++++++++++++++++++ indoteknik_custom/models/stock_picking.py | 59 +++++++++++++++++ 3 files changed, 138 insertions(+), 1 deletion(-) create mode 100644 indoteknik_api/controllers/api_v1/stock_picking.py diff --git a/indoteknik_api/controllers/api_v1/__init__.py b/indoteknik_api/controllers/api_v1/__init__.py index 65bcf926..36fcbd53 100644 --- a/indoteknik_api/controllers/api_v1/__init__.py +++ b/indoteknik_api/controllers/api_v1/__init__.py @@ -25,4 +25,5 @@ from . import content from . import midtrans from . import wati from . import courier -from . import voucher \ No newline at end of file +from . import voucher +from . import stock_picking \ No newline at end of file diff --git a/indoteknik_api/controllers/api_v1/stock_picking.py b/indoteknik_api/controllers/api_v1/stock_picking.py new file mode 100644 index 00000000..0ffce16b --- /dev/null +++ b/indoteknik_api/controllers/api_v1/stock_picking.py @@ -0,0 +1,77 @@ +from .. import controller +from odoo import http +from odoo.http import request + + +class StockPicking(controller.Controller): + prefix = '/api/v1/' + PREFIX_PARTNER = prefix + 'partner//' + + @http.route(PREFIX_PARTNER + 'stock-picking', auth='public', method=['GET', 'OPTIONS']) + @controller.Controller.must_authorized(private=True, private_key='partner_id') + def get_partner_stock_picking(self, **kw): + get_params = self.get_request_params(kw, { + 'partner_id': ['number'], + 'q': [], + 'limit': ['default:0', 'number'], + 'offset': ['default:0', 'number'] + }) + + if not get_params['valid']: + return self.response(code=400, description=get_params) + + params = get_params['value'] + partner_id = params['partner_id'] + limit = params['limit'] + offset = params['offset'] + + child_ids = request.env['res.partner'].browse(partner_id).get_child_ids() + + picking_model = request.env['stock.picking'] + default_domain = [('partner_id', 'in', child_ids), ('sale_id', '!=', False)] + + domain = default_domain + if params['q']: + query_like = '%' + params['q'].replace(' ', '%') + '%' + domain += ['|', '|', ('name', 'ilike', query_like), ('sale_id.client_order_ref', 'ilike', query_like), ('delivery_tracking_no', 'ilike', query_like)] + + stock_pickings = picking_model.search(domain, offset=offset, limit=limit) + res_pickings = [] + for picking in stock_pickings: + res_pickings.append({ + 'id': picking.id, + 'name': picking.name, + 'date': self.time_to_str(picking.create_date, '%d/%m/%Y'), + 'tracking_number': picking.delivery_tracking_no or '', + 'sale_order': { + 'id': picking.sale_id.id, + 'name': picking.sale_id.name, + 'client_order_ref': picking.sale_id.client_order_ref or '' + }, + 'carrier_name': picking.carrier_id.name or '' + }) + + pending_count = picking_model.search_count(default_domain + [('driver_departure_date', '=', False), ('driver_arrival_date', '=', False)]) + shipment_count = picking_model.search_count(default_domain + [('driver_departure_date', '!=', False), ('driver_arrival_date', '=', False)]) + completed_count = picking_model.search_count(default_domain + [('driver_departure_date', '!=', False), ('driver_arrival_date', '!=', False)]) + + return self.response({ + 'summary': { + 'pending_count': pending_count, + 'shipment_count': shipment_count, + 'completed_count': completed_count + }, + 'pickings': res_pickings + }) + + @http.route(PREFIX_PARTNER + 'stock-picking//tracking', auth='public', method=['GET', 'OPTIONS']) + @controller.Controller.must_authorized(private=True, private_key='partner_id') + def get_partner_stock_picking_detail_tracking(self, **kw): + id = int(kw.get('id', 0)) + picking_model = request.env['stock.picking'] + + picking = picking_model.browse(id) + if not picking: + return self.response(None) + + return self.response(picking.get_tracking_detail()) diff --git a/indoteknik_custom/models/stock_picking.py b/indoteknik_custom/models/stock_picking.py index 4d1df7ee..f9b077ba 100644 --- a/indoteknik_custom/models/stock_picking.py +++ b/indoteknik_custom/models/stock_picking.py @@ -2,6 +2,7 @@ from odoo import fields, models, api, _ from odoo.exceptions import AccessError, UserError, ValidationError from odoo.tools.float_utils import float_is_zero from itertools import groupby +import pytz, datetime class StockPicking(models.Model): @@ -351,3 +352,61 @@ class StockPicking(models.Model): picking.delivery_status = "Diterima Ekspedisi" else: picking.delivery_status = "Diterima Konsumen" + + def create_manifest_data(self, description, object): + datetime_str = '' + if isinstance(object, datetime.datetime): + jakarta_timezone = pytz.timezone('Asia/Jakarta') + datetime_str = object.replace(tzinfo=pytz.utc).astimezone(jakarta_timezone).strftime('%Y-%m-%d %H:%M:%S') + return { + 'description': description, + 'datetime': datetime_str + } + + def get_manifests(self): + manifest_datas = [] + + departure_date = self.driver_departure_date + arrival_date = self.driver_arrival_date + + if self.carrier_id.id == 32: # Pickup Bandengan + manifest_datas.append(self.create_manifest_data('Sedang disiapkan', self.create_date)) + if departure_date: + manifest_datas.append(self.create_manifest_data('Siap diambil', departure_date)) + if arrival_date: + manifest_datas.append(self.create_manifest_data('Sudah diambil', arrival_date)) + else: + manifest_datas.append(self.create_manifest_data('Menunggu pickup', self.create_date)) + if departure_date: + manifest_datas.append(self.create_manifest_data('Sedang dikirim', departure_date)) + if arrival_date: + manifest_datas.append(self.create_manifest_data('Sudah sampai', arrival_date)) + + return manifest_datas + + def get_tracking_detail(self): + self.ensure_one() + + response = { + 'delivery_order': { + 'name': self.name, + 'carrier': self.carrier_id.name or '', + 'receiver_name': '', + 'receiver_city': '' + }, + 'delivered': False, + 'waybill_number': self.delivery_tracking_no or '', + 'delivery_status': None + } + + if not self.waybill_id or len(self.waybill_id.manifest_ids) == 0: + response['delivered'] = self.driver_arrival_date != False + response['manifests'] = self.get_manifests() + return response + + response['delivery_order']['receiver_name'] = self.waybill_id.receiver_name, + response['delivery_order']['receiver_city'] = self.waybill_id.receiver_city, + response['delivery_status'] = self.waybill_id._get_history('delivery_status') + response['manifests'] = [self.create_manifest_data(x.description, x.datetime) for x in self.waybill_id.manifest_ids] + + return response -- cgit v1.2.3 From d1e92dcd8ee34d2140edfc2fe440cc53e89eec79 Mon Sep 17 00:00:00 2001 From: Rafi Zadanly Date: Wed, 23 Aug 2023 13:28:56 +0700 Subject: Add stock picking api response --- indoteknik_api/controllers/api_v1/stock_picking.py | 3 ++- indoteknik_custom/models/stock_picking.py | 1 + 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/indoteknik_api/controllers/api_v1/stock_picking.py b/indoteknik_api/controllers/api_v1/stock_picking.py index 0ffce16b..7d397b4d 100644 --- a/indoteknik_api/controllers/api_v1/stock_picking.py +++ b/indoteknik_api/controllers/api_v1/stock_picking.py @@ -28,7 +28,7 @@ class StockPicking(controller.Controller): child_ids = request.env['res.partner'].browse(partner_id).get_child_ids() picking_model = request.env['stock.picking'] - default_domain = [('partner_id', 'in', child_ids), ('sale_id', '!=', False)] + default_domain = [('partner_id', 'in', child_ids), ('sale_id', '!=', False), ('origin', 'ilike', 'SO%')] domain = default_domain if params['q']: @@ -48,6 +48,7 @@ class StockPicking(controller.Controller): 'name': picking.sale_id.name, 'client_order_ref': picking.sale_id.client_order_ref or '' }, + 'delivered': picking.waybill_id.delivered or picking.driver_arrival_date != False, 'carrier_name': picking.carrier_id.name or '' }) diff --git a/indoteknik_custom/models/stock_picking.py b/indoteknik_custom/models/stock_picking.py index f9b077ba..8d1a85ea 100644 --- a/indoteknik_custom/models/stock_picking.py +++ b/indoteknik_custom/models/stock_picking.py @@ -407,6 +407,7 @@ class StockPicking(models.Model): response['delivery_order']['receiver_name'] = self.waybill_id.receiver_name, response['delivery_order']['receiver_city'] = self.waybill_id.receiver_city, response['delivery_status'] = self.waybill_id._get_history('delivery_status') + response['delivered'] = self.waybill_id.delivered response['manifests'] = [self.create_manifest_data(x.description, x.datetime) for x in self.waybill_id.manifest_ids] return response -- cgit v1.2.3 From 9e4511c8d27665a53d296ee648150121a7f6cf84 Mon Sep 17 00:00:00 2001 From: Rafi Zadanly Date: Wed, 23 Aug 2023 13:29:13 +0700 Subject: Add sale order api response --- indoteknik_api/controllers/api_v1/sale_order.py | 8 ++------ indoteknik_api/models/sale_order.py | 8 ++++++++ 2 files changed, 10 insertions(+), 6 deletions(-) diff --git a/indoteknik_api/controllers/api_v1/sale_order.py b/indoteknik_api/controllers/api_v1/sale_order.py index ecc6c771..36803466 100644 --- a/indoteknik_api/controllers/api_v1/sale_order.py +++ b/indoteknik_api/controllers/api_v1/sale_order.py @@ -97,12 +97,8 @@ class SaleOrder(controller.Controller): if not params['valid']: return self.response(code=400, description=params) - partner_child_ids = self.get_partner_child_ids( - params['value']['partner_id']) - domain = [ - ('id', '=', params['value']['id']), - ('partner_id', 'in', partner_child_ids) - ] + partner_child_ids = self.get_partner_child_ids(params['value']['partner_id']) + domain = [('id', '=', params['value']['id']), ('partner_id', 'in', partner_child_ids)] data = {} sale_order = request.env['sale.order'].search(domain) if sale_order: diff --git a/indoteknik_api/models/sale_order.py b/indoteknik_api/models/sale_order.py index 9661a0ba..85bf5015 100644 --- a/indoteknik_api/models/sale_order.py +++ b/indoteknik_api/models/sale_order.py @@ -18,7 +18,15 @@ class SaleOrder(models.Model): 'invoice_count': sale_order.invoice_count, 'status': 'draft', 'date_order': self.env['rest.api'].datetime_to_str(sale_order.date_order, '%d/%m/%Y %H:%M:%S'), + 'pickings': [] } + for picking in sale_order.picking_ids: + data['pickings'].append({ + 'id': picking.id, + 'name': picking.name, + 'tracking_number': picking.delivery_tracking_no or '', + 'delivered': picking.waybill_id.delivered or picking.driver_arrival_date != False, + }) if sale_order.state == 'cancel': data['status'] = 'cancel' if sale_order.state in ['draft', 'sent']: -- cgit v1.2.3 From c420bd4e418b2f646e1b3116bdb31e4ff07bf448 Mon Sep 17 00:00:00 2001 From: Rafi Zadanly Date: Thu, 24 Aug 2023 11:28:05 +0700 Subject: Add estimated arrival days field and estimated time arrival API response --- indoteknik_api/controllers/api_v1/sale_order.py | 4 ++- indoteknik_api/controllers/api_v1/stock_picking.py | 2 +- indoteknik_custom/models/sale_order.py | 1 + indoteknik_custom/models/stock_picking.py | 29 +++++++++++++++++++++- indoteknik_custom/views/sale_order.xml | 1 + 5 files changed, 34 insertions(+), 3 deletions(-) diff --git a/indoteknik_api/controllers/api_v1/sale_order.py b/indoteknik_api/controllers/api_v1/sale_order.py index 36803466..4f6393a6 100644 --- a/indoteknik_api/controllers/api_v1/sale_order.py +++ b/indoteknik_api/controllers/api_v1/sale_order.py @@ -258,7 +258,8 @@ class SaleOrder(controller.Controller): 'carrier_id': [], 'delivery_service_type': [], 'voucher': [], - 'source': [] + 'source': [], + 'estimated_arrival_days': ['number', 'default:0'] }) if not params['valid']: @@ -283,6 +284,7 @@ class SaleOrder(controller.Controller): 'partner_purchase_order_name': params['value']['po_number'], 'partner_purchase_order_file': params['value']['po_file'], 'delivery_amt': params['value']['delivery_amount'], + 'estimated_arrival_days': params['value']['estimated_arrival_days'], 'shipping_cost_covered': 'customer', 'shipping_paid_by': 'customer', 'carrier_id': params['value']['carrier_id'], diff --git a/indoteknik_api/controllers/api_v1/stock_picking.py b/indoteknik_api/controllers/api_v1/stock_picking.py index 7d397b4d..304bc806 100644 --- a/indoteknik_api/controllers/api_v1/stock_picking.py +++ b/indoteknik_api/controllers/api_v1/stock_picking.py @@ -28,7 +28,7 @@ class StockPicking(controller.Controller): child_ids = request.env['res.partner'].browse(partner_id).get_child_ids() picking_model = request.env['stock.picking'] - default_domain = [('partner_id', 'in', child_ids), ('sale_id', '!=', False), ('origin', 'ilike', 'SO%')] + default_domain = [('partner_id', 'in', child_ids), ('sale_id', '!=', False), ('origin', 'ilike', 'SO%'), ('state', '!=', 'cancel')] domain = default_domain if params['q']: diff --git a/indoteknik_custom/models/sale_order.py b/indoteknik_custom/models/sale_order.py index ca98cde4..d0817ad5 100755 --- a/indoteknik_custom/models/sale_order.py +++ b/indoteknik_custom/models/sale_order.py @@ -76,6 +76,7 @@ class SaleOrder(models.Model): voucher_id = fields.Many2one(comodel_name='voucher', string='Voucher') amount_voucher_disc = fields.Float(string='Voucher Discount') source_id = fields.Many2one('utm.source', 'Source', domain="[('id', 'in', [32, 59, 60, 61])]") + estimated_arrival_days = fields.Integer('Estimated Arrival Days', default=0) def _compute_purchase_total(self): for order in self: diff --git a/indoteknik_custom/models/stock_picking.py b/indoteknik_custom/models/stock_picking.py index 8d1a85ea..c094b74d 100644 --- a/indoteknik_custom/models/stock_picking.py +++ b/indoteknik_custom/models/stock_picking.py @@ -396,7 +396,8 @@ class StockPicking(models.Model): }, 'delivered': False, 'waybill_number': self.delivery_tracking_no or '', - 'delivery_status': None + 'delivery_status': None, + 'eta': self.generate_eta_delivery() } if not self.waybill_id or len(self.waybill_id.manifest_ids) == 0: @@ -411,3 +412,29 @@ class StockPicking(models.Model): response['manifests'] = [self.create_manifest_data(x.description, x.datetime) for x in self.waybill_id.manifest_ids] return response + + def generate_eta_delivery(self): + current_date = datetime.datetime.now() + prepare_days = 3 + start_date = self.driver_departure_date or self.create_date + + ead = self.sale_id.estimated_arrival_days or 0 + if not self.driver_departure_date: + ead += prepare_days + + ead_datetime = datetime.timedelta(days=ead) + fastest_eta = start_date + ead_datetime + if not self.driver_departure_date and fastest_eta < current_date: + fastest_eta = current_date + ead_datetime + + longest_days = 3 + longest_eta = fastest_eta + datetime.timedelta(days=longest_days) + + if fastest_eta.year == longest_eta.year: + formatted_fastest_eta = fastest_eta.strftime('%d %b') + formatted_longest_eta = longest_eta.strftime('%d %b %Y') + else: + formatted_fastest_eta = fastest_eta.strftime('%d %b %Y') + formatted_longest_eta = longest_eta.strftime('%d %b %Y') + + return f'{formatted_fastest_eta} - {formatted_longest_eta}' diff --git a/indoteknik_custom/views/sale_order.xml b/indoteknik_custom/views/sale_order.xml index d2a59621..032156cf 100755 --- a/indoteknik_custom/views/sale_order.xml +++ b/indoteknik_custom/views/sale_order.xml @@ -93,6 +93,7 @@ + -- cgit v1.2.3 From 4d99d85f04f43b05eded0e25f49f1c3c75ba3314 Mon Sep 17 00:00:00 2001 From: Rafi Zadanly Date: Thu, 24 Aug 2023 11:36:25 +0700 Subject: Refactor format eta on generate_eta_delivery --- indoteknik_custom/models/stock_picking.py | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/indoteknik_custom/models/stock_picking.py b/indoteknik_custom/models/stock_picking.py index c094b74d..3c064f8f 100644 --- a/indoteknik_custom/models/stock_picking.py +++ b/indoteknik_custom/models/stock_picking.py @@ -430,11 +430,10 @@ class StockPicking(models.Model): longest_days = 3 longest_eta = fastest_eta + datetime.timedelta(days=longest_days) - if fastest_eta.year == longest_eta.year: - formatted_fastest_eta = fastest_eta.strftime('%d %b') - formatted_longest_eta = longest_eta.strftime('%d %b %Y') - else: - formatted_fastest_eta = fastest_eta.strftime('%d %b %Y') - formatted_longest_eta = longest_eta.strftime('%d %b %Y') + format_time = '%d %b %Y' + format_time_fastest = '%d %b' if fastest_eta.year == longest_eta.year else format_time + + formatted_fastest_eta = fastest_eta.strftime(format_time_fastest) + formatted_longest_eta = longest_eta.strftime(format_time) return f'{formatted_fastest_eta} - {formatted_longest_eta}' -- cgit v1.2.3 From 4c0552bec7c44eb680ae4c0e1e352e14bade9276 Mon Sep 17 00:00:00 2001 From: Rafi Zadanly Date: Thu, 24 Aug 2023 14:43:27 +0700 Subject: Update manifest stock picking order --- indoteknik_custom/models/stock_picking.py | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/indoteknik_custom/models/stock_picking.py b/indoteknik_custom/models/stock_picking.py index 3c064f8f..e4a3e09e 100644 --- a/indoteknik_custom/models/stock_picking.py +++ b/indoteknik_custom/models/stock_picking.py @@ -370,17 +370,17 @@ class StockPicking(models.Model): arrival_date = self.driver_arrival_date if self.carrier_id.id == 32: # Pickup Bandengan - manifest_datas.append(self.create_manifest_data('Sedang disiapkan', self.create_date)) - if departure_date: - manifest_datas.append(self.create_manifest_data('Siap diambil', departure_date)) if arrival_date: manifest_datas.append(self.create_manifest_data('Sudah diambil', arrival_date)) - else: - manifest_datas.append(self.create_manifest_data('Menunggu pickup', self.create_date)) if departure_date: - manifest_datas.append(self.create_manifest_data('Sedang dikirim', departure_date)) + manifest_datas.append(self.create_manifest_data('Siap diambil', departure_date)) + manifest_datas.append(self.create_manifest_data('Sedang disiapkan', self.create_date)) + else: if arrival_date: manifest_datas.append(self.create_manifest_data('Sudah sampai', arrival_date)) + if departure_date: + manifest_datas.append(self.create_manifest_data('Sedang dikirim', departure_date)) + manifest_datas.append(self.create_manifest_data('Menunggu pickup', self.create_date)) return manifest_datas -- cgit v1.2.3 From 3e37282f6ceb8ef17e3b9784bcacf80e13461fb6 Mon Sep 17 00:00:00 2001 From: Rafi Zadanly Date: Thu, 24 Aug 2023 14:48:39 +0700 Subject: Add sort on get stock picking API --- indoteknik_api/controllers/api_v1/stock_picking.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/indoteknik_api/controllers/api_v1/stock_picking.py b/indoteknik_api/controllers/api_v1/stock_picking.py index 304bc806..c489d04b 100644 --- a/indoteknik_api/controllers/api_v1/stock_picking.py +++ b/indoteknik_api/controllers/api_v1/stock_picking.py @@ -35,7 +35,7 @@ class StockPicking(controller.Controller): query_like = '%' + params['q'].replace(' ', '%') + '%' domain += ['|', '|', ('name', 'ilike', query_like), ('sale_id.client_order_ref', 'ilike', query_like), ('delivery_tracking_no', 'ilike', query_like)] - stock_pickings = picking_model.search(domain, offset=offset, limit=limit) + stock_pickings = picking_model.search(domain, offset=offset, limit=limit, order='create_date desc') res_pickings = [] for picking in stock_pickings: res_pickings.append({ -- cgit v1.2.3 From 3cf2809ab4cd0ca113318665997d58d0d758e495 Mon Sep 17 00:00:00 2001 From: Rafi Zadanly Date: Mon, 28 Aug 2023 09:47:48 +0700 Subject: Add picking total on get stock picking api --- indoteknik_api/controllers/api_v1/stock_picking.py | 1 + 1 file changed, 1 insertion(+) diff --git a/indoteknik_api/controllers/api_v1/stock_picking.py b/indoteknik_api/controllers/api_v1/stock_picking.py index c489d04b..9e92e5d0 100644 --- a/indoteknik_api/controllers/api_v1/stock_picking.py +++ b/indoteknik_api/controllers/api_v1/stock_picking.py @@ -62,6 +62,7 @@ class StockPicking(controller.Controller): 'shipment_count': shipment_count, 'completed_count': completed_count }, + 'picking_total': picking_model.search_count(default_domain), 'pickings': res_pickings }) -- cgit v1.2.3 From 3757621d0b0232603a3d578b27b845054cae5982 Mon Sep 17 00:00:00 2001 From: Rafi Zadanly Date: Mon, 28 Aug 2023 11:02:58 +0700 Subject: Refactor get manifest and add last manifest on get stock picking api --- indoteknik_api/controllers/api_v1/stock_picking.py | 4 +- indoteknik_custom/models/stock_picking.py | 51 ++++++++++++++-------- 2 files changed, 36 insertions(+), 19 deletions(-) diff --git a/indoteknik_api/controllers/api_v1/stock_picking.py b/indoteknik_api/controllers/api_v1/stock_picking.py index 9e92e5d0..e0a60c98 100644 --- a/indoteknik_api/controllers/api_v1/stock_picking.py +++ b/indoteknik_api/controllers/api_v1/stock_picking.py @@ -38,6 +38,7 @@ class StockPicking(controller.Controller): stock_pickings = picking_model.search(domain, offset=offset, limit=limit, order='create_date desc') res_pickings = [] for picking in stock_pickings: + manifests = picking.get_manifests() res_pickings.append({ 'id': picking.id, 'name': picking.name, @@ -49,7 +50,8 @@ class StockPicking(controller.Controller): 'client_order_ref': picking.sale_id.client_order_ref or '' }, 'delivered': picking.waybill_id.delivered or picking.driver_arrival_date != False, - 'carrier_name': picking.carrier_id.name or '' + 'carrier_name': picking.carrier_id.name or '', + 'last_manifest': next(iter(manifests), None) }) pending_count = picking_model.search_count(default_domain + [('driver_departure_date', '=', False), ('driver_arrival_date', '=', False)]) diff --git a/indoteknik_custom/models/stock_picking.py b/indoteknik_custom/models/stock_picking.py index e4a3e09e..bf321172 100644 --- a/indoteknik_custom/models/stock_picking.py +++ b/indoteknik_custom/models/stock_picking.py @@ -364,23 +364,39 @@ class StockPicking(models.Model): } def get_manifests(self): - manifest_datas = [] + if self.waybill_id and len(self.waybill_id.manifest_ids) > 0: + return [self.create_manifest_data(x.description, x.datetime) for x in self.waybill_id.manifest_ids] + + status_mapping = { + 'pickup': { + 'arrival': 'Sudah diambil', + 'departure': 'Siap diambil', + 'prepare': 'Sedang disiapkan' + }, + 'delivery': { + 'arrival': 'Sudah sampai', + 'departure': 'Sedang dikirim', + 'prepare': 'Menunggu pickup', + } + } + status_key = 'delivery' + if self.carrier_id.id == 32: + status_key = 'pickup' + + manifest_datas = [] departure_date = self.driver_departure_date arrival_date = self.driver_arrival_date + status = status_mapping.get(status_key) - if self.carrier_id.id == 32: # Pickup Bandengan - if arrival_date: - manifest_datas.append(self.create_manifest_data('Sudah diambil', arrival_date)) - if departure_date: - manifest_datas.append(self.create_manifest_data('Siap diambil', departure_date)) - manifest_datas.append(self.create_manifest_data('Sedang disiapkan', self.create_date)) - else: - if arrival_date: - manifest_datas.append(self.create_manifest_data('Sudah sampai', arrival_date)) - if departure_date: - manifest_datas.append(self.create_manifest_data('Sedang dikirim', departure_date)) - manifest_datas.append(self.create_manifest_data('Menunggu pickup', self.create_date)) + if not status: + return manifest_datas + + if arrival_date: + manifest_datas.append(self.create_manifest_data(status['arrival'], arrival_date)) + if departure_date: + manifest_datas.append(self.create_manifest_data(status['departure'], departure_date)) + manifest_datas.append(self.create_manifest_data(status['prepare'], self.create_date)) return manifest_datas @@ -397,19 +413,18 @@ class StockPicking(models.Model): 'delivered': False, 'waybill_number': self.delivery_tracking_no or '', 'delivery_status': None, - 'eta': self.generate_eta_delivery() + 'eta': self.generate_eta_delivery(), + 'manifests': self.get_manifests() } if not self.waybill_id or len(self.waybill_id.manifest_ids) == 0: response['delivered'] = self.driver_arrival_date != False - response['manifests'] = self.get_manifests() return response - response['delivery_order']['receiver_name'] = self.waybill_id.receiver_name, - response['delivery_order']['receiver_city'] = self.waybill_id.receiver_city, + response['delivery_order']['receiver_name'] = self.waybill_id.receiver_name + response['delivery_order']['receiver_city'] = self.waybill_id.receiver_city response['delivery_status'] = self.waybill_id._get_history('delivery_status') response['delivered'] = self.waybill_id.delivered - response['manifests'] = [self.create_manifest_data(x.description, x.datetime) for x in self.waybill_id.manifest_ids] return response -- cgit v1.2.3 From 61c89397e839f546c796a596a1fbbc840aa85311 Mon Sep 17 00:00:00 2001 From: Azka Nathan Date: Mon, 28 Aug 2023 15:04:51 +0700 Subject: Validate Data Product & Purchase Pricelist --- indoteknik_custom/models/product_template.py | 119 ++++++++++++++++++++++++- indoteknik_custom/models/purchase_pricelist.py | 23 +++++ indoteknik_custom/views/purchase_pricelist.xml | 2 +- 3 files changed, 142 insertions(+), 2 deletions(-) diff --git a/indoteknik_custom/models/product_template.py b/indoteknik_custom/models/product_template.py index 52f72729..3352c6b0 100755 --- a/indoteknik_custom/models/product_template.py +++ b/indoteknik_custom/models/product_template.py @@ -51,7 +51,67 @@ class ProductTemplate(models.Model): is_new_product = fields.Boolean(string='Produk Baru', help='Centang jika ingin ditammpilkan di website sebagai segment Produk Baru') seq_new_product = fields.Integer(string='Seq New Product', help='Urutan Sequence New Product') + is_edit = fields.Boolean(string="Update Counter", default=True) + # def write(self, vals): + # if not self.env.user.is_purchasing_manager: + # for product in self: + + # domain = [ + # ('id', '=', product.id), + # ('create_date', '<=', product.write_date), + # ('name', '=', product.name), + # ('default_code', '=', product.default_code) + # ] + + # existing_purchase = self.search(domain, limit=1) + # if existing_purchase: + # raise UserError("Hanya Pak Tyas yang bisa mengedit product") + # return super(ProductTemplate, self).write(vals) + + @api.constrains('name', + 'default_code', + 'sequence', + 'responsible_id', + 'list_price', + 'standard_price', + 'qty_available', + 'virtual_available', + 'uom_id', + 'activity_exception_decoration', + 'web_tax_id', + 'categ_id', + 'taxes_id', + 'barcode', + 'x_manufacture', + 'x_model_product', + 'x_studio_field_tGhJR', + 'attribute_line_ids',) + def _check_duplicate_product(self): + if not self.env.user.is_purchasing_manager: + for product in self: + if product.write_date == product.create_date: + domain = [ + ('default_code', '!=', False), + '|', + ('name', '=', product.name), + ('default_code', '=', product.default_code)] + + domain.append(('id', '!=', product.id)) + massage="SKU atau Name yang anda pakai sudah digunakan di product lain" + existing_purchase = self.search(domain, limit=1) + if existing_purchase: + raise UserError(massage) + else: + domain = [ + ('id', '=', product.id) + ] + massage="Hanya Pak Tyas Yang Dapat Merubah Data Product" + existing_purchase = self.search(domain, limit=1) + if existing_purchase: + raise UserError(massage) + + @api.constrains('name') def _validate_name(self): pattern = r'^[a-zA-Z0-9\[\]\(\)\.\s/%]+$' @@ -59,7 +119,7 @@ class ProductTemplate(models.Model): pattern_suggest = r'[a-zA-Z0-9\[\]\(\)\.\s/%]+' suggest = ''.join(re.findall(pattern_suggest, self.name)) raise UserError(f'Nama hanya bisa menggunakan angka, huruf kecil, huruf besar, titik, kurung lengkung, kurung siku, garis miring. Contoh: {suggest}') - + # def write(self, vals): # if 'solr_flag' not in vals and self.solr_flag == 1: # vals['solr_flag'] = 2 @@ -287,6 +347,63 @@ class ProductProduct(models.Model): 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') sla_version = fields.Integer(string="SLA Version", default=0) + is_edit = fields.Boolean(string="Update Counter", default=True) + + # def write(self, vals): + # if not self.env.user.is_purchasing_manager: + # for product in self: + # domain = [ + # ('id', '=', product.id), + # ('create_date', '<=', product.write_date), + # ('name', '=', product.name), + # ('default_code', '=', product.default_code) + # ] + + # existing_purchase = self.search(domain, limit=1) + # if existing_purchase: + # raise UserError("Hanya Pak Tyas yang bisa mengedit product") + # return super(ProductProduct, self).write(vals) + + @api.constrains('name', + 'default_code', + 'product_template_attribute_value_ids', + 'lst_price', + 'standard_price', + 'qty_available', + 'outgoing_qty', + 'incoming_qty', + 'virtual_available', + 'web_tax_id', + 'categ_id', + 'taxes_id', + 'barcode', + 'x_manufacture', + 'x_model_product', + 'x_studio_field_tGhJR', + ) + def _check_duplicate_product(self): + if not self.env.user.is_purchasing_manager: + for product in self: + if product.write_date == product.create_date: + domain = [ + ('default_code', '!=', False), + '|', + ('name', '=', product.name), + ('default_code', '=', product.default_code)] + + domain.append(('id', '!=', product.id)) + massage="SKU atau Name yang anda pakai sudah digunakan di product lain" + existing_purchase = self.search(domain, limit=1) + if existing_purchase: + raise UserError(massage) + else: + domain = [ + ('id', '=', product.id) + ] + massage="Hanya Pak Tyas Yang Dapat Merubah Data Product" + existing_purchase = self.search(domain, limit=1) + if existing_purchase: + raise UserError(massage) @api.constrains('name') def _validate_name(self): diff --git a/indoteknik_custom/models/purchase_pricelist.py b/indoteknik_custom/models/purchase_pricelist.py index 419ca8e0..5d077e04 100755 --- a/indoteknik_custom/models/purchase_pricelist.py +++ b/indoteknik_custom/models/purchase_pricelist.py @@ -27,3 +27,26 @@ class PurchasePricelist(models.Model): self.system_last_update = current_time else: self.human_last_update = current_time + + @api.constrains('vendor_id', 'product_id','human_last_update','write_date') + def _check_duplicate_purchase_pricelist(self): + for price in self: + if price.write_date == price.create_date: + domain = [ + ('product_id', '=', price.product_id.id), + ('vendor_id', '=', price.vendor_id.id) + ] + + domain.append(('id', '!=', price.id)) + massage="Product dan vendor yang anda gunakan sudah ada di purchase pricelist" + existing_purchase = self.search(domain, limit=1) + if existing_purchase: + raise UserError(massage) + else: + domain = [ + ('id', '=', price.id) + ] + massage="Tidak Dapat Merubah Product" + existing_purchase = self.search(domain, limit=1) + if existing_purchase: + raise UserError(massage) \ No newline at end of file diff --git a/indoteknik_custom/views/purchase_pricelist.xml b/indoteknik_custom/views/purchase_pricelist.xml index f9fd52ba..5c63676d 100755 --- a/indoteknik_custom/views/purchase_pricelist.xml +++ b/indoteknik_custom/views/purchase_pricelist.xml @@ -19,7 +19,7 @@ purchase.pricelist.form purchase.pricelist -
+ -- cgit v1.2.3 From 76e97903641e6dc35f4158f2a08cfa70bed50afe Mon Sep 17 00:00:00 2001 From: Azka Nathan Date: Wed, 30 Aug 2023 10:33:01 +0700 Subject: change constraint product template --- indoteknik_custom/models/product_template.py | 37 ++-------------------------- 1 file changed, 2 insertions(+), 35 deletions(-) diff --git a/indoteknik_custom/models/product_template.py b/indoteknik_custom/models/product_template.py index 3352c6b0..c2cf3bb9 100755 --- a/indoteknik_custom/models/product_template.py +++ b/indoteknik_custom/models/product_template.py @@ -69,24 +69,7 @@ class ProductTemplate(models.Model): # raise UserError("Hanya Pak Tyas yang bisa mengedit product") # return super(ProductTemplate, self).write(vals) - @api.constrains('name', - 'default_code', - 'sequence', - 'responsible_id', - 'list_price', - 'standard_price', - 'qty_available', - 'virtual_available', - 'uom_id', - 'activity_exception_decoration', - 'web_tax_id', - 'categ_id', - 'taxes_id', - 'barcode', - 'x_manufacture', - 'x_model_product', - 'x_studio_field_tGhJR', - 'attribute_line_ids',) + @api.constrains('name','default_code',) def _check_duplicate_product(self): if not self.env.user.is_purchasing_manager: for product in self: @@ -364,23 +347,7 @@ class ProductProduct(models.Model): # raise UserError("Hanya Pak Tyas yang bisa mengedit product") # return super(ProductProduct, self).write(vals) - @api.constrains('name', - 'default_code', - 'product_template_attribute_value_ids', - 'lst_price', - 'standard_price', - 'qty_available', - 'outgoing_qty', - 'incoming_qty', - 'virtual_available', - 'web_tax_id', - 'categ_id', - 'taxes_id', - 'barcode', - 'x_manufacture', - 'x_model_product', - 'x_studio_field_tGhJR', - ) + @api.constrains('name','default_code',) def _check_duplicate_product(self): if not self.env.user.is_purchasing_manager: for product in self: -- cgit v1.2.3 From b7dba2d8eed3c2af22dca53a916f12e9b842c2aa Mon Sep 17 00:00:00 2001 From: Azka Nathan Date: Thu, 31 Aug 2023 11:51:50 +0700 Subject: coa cost centre --- indoteknik_custom/__manifest__.py | 3 ++ indoteknik_custom/models/__init__.py | 3 ++ indoteknik_custom/models/account_account.py | 6 ++++ indoteknik_custom/models/account_move_line.py | 22 ++++++++++++ indoteknik_custom/models/cost_centre.py | 11 ++++++ indoteknik_custom/security/ir.model.access.csv | 1 + indoteknik_custom/views/account_account_views.xml | 15 +++++++++ indoteknik_custom/views/account_move_line.xml | 16 +++++++++ indoteknik_custom/views/cost_centre.xml | 41 +++++++++++++++++++++++ 9 files changed, 118 insertions(+) create mode 100644 indoteknik_custom/models/account_account.py create mode 100644 indoteknik_custom/models/account_move_line.py create mode 100644 indoteknik_custom/models/cost_centre.py create mode 100644 indoteknik_custom/views/account_account_views.xml create mode 100644 indoteknik_custom/views/account_move_line.xml create mode 100644 indoteknik_custom/views/cost_centre.xml diff --git a/indoteknik_custom/__manifest__.py b/indoteknik_custom/__manifest__.py index 0d38a7d7..e1be8910 100755 --- a/indoteknik_custom/__manifest__.py +++ b/indoteknik_custom/__manifest__.py @@ -93,6 +93,9 @@ 'views/price_group.xml', 'views/mrp_production.xml', 'views/apache_solr_queue.xml', + 'views/cost_centre.xml', + 'views/account_account_views.xml', + 'views/account_move_line.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 cf2597b0..b8be14ba 100755 --- a/indoteknik_custom/models/__init__.py +++ b/indoteknik_custom/models/__init__.py @@ -85,3 +85,6 @@ from . import base_import_import from . import product_attribute from . import mrp_production from . import solr +from . import cost_centre +from . import account_account +from . import account_move_line diff --git a/indoteknik_custom/models/account_account.py b/indoteknik_custom/models/account_account.py new file mode 100644 index 00000000..584c38f8 --- /dev/null +++ b/indoteknik_custom/models/account_account.py @@ -0,0 +1,6 @@ +from odoo import fields, models, api, _ + +class AccountAccount(models.Model): + _inherit = 'account.account' + + cost_centre_id = fields.Many2one('cost.centre', string='Cost Centre') \ No newline at end of file diff --git a/indoteknik_custom/models/account_move_line.py b/indoteknik_custom/models/account_move_line.py new file mode 100644 index 00000000..87e5a182 --- /dev/null +++ b/indoteknik_custom/models/account_move_line.py @@ -0,0 +1,22 @@ +from odoo import models, api, fields + + +class AccountMoveLine(models.Model): + _inherit = "account.move.line" + + cost_centre_id = fields.Many2one('cost.centre', string='Cost Centre') + is_required = fields.Boolean(string='Is Required', compute='_compute_is_required') + + @api.onchange('account_id') + def _compute_is_required(self): + for account in self: + if account.account_id.code and account.account_id.code[0] in ['6', '7']: + account.is_required = True + else: + account.is_required = False + + @api.onchange('account_id') + def _onchange_cost_centre_id(self): + for account in self: + cost_centre = account.account_id.cost_centre_id + account.cost_centre_id = cost_centre diff --git a/indoteknik_custom/models/cost_centre.py b/indoteknik_custom/models/cost_centre.py new file mode 100644 index 00000000..eaf518d5 --- /dev/null +++ b/indoteknik_custom/models/cost_centre.py @@ -0,0 +1,11 @@ +from odoo import fields, models, api +from datetime import datetime, timedelta +import logging + +_logger = logging.getLogger(__name__) + + +class CostCentre(models.Model): + _name = 'cost.centre' + name = fields.Char(string="Name") + description = fields.Text(string="Description") diff --git a/indoteknik_custom/security/ir.model.access.csv b/indoteknik_custom/security/ir.model.access.csv index c41587c0..e1480dd3 100755 --- a/indoteknik_custom/security/ir.model.access.csv +++ b/indoteknik_custom/security/ir.model.access.csv @@ -71,3 +71,4 @@ access_po_sync_price,access.po.sync.price,model_po_sync_price,,1,1,1,1 access_product_attribute_value,access.product.attribute.value,model_product_attribute_value,,1,1,1,1 access_mrp_production,access.mrp.production,model_mrp_production,,1,1,1,1 access_apache_solr_queue,access.apache.solr.queue,model_apache_solr_queue,,1,1,1,1 +access_cost_centre,access.cost.centre,model_cost_centre,,1,1,1,1 diff --git a/indoteknik_custom/views/account_account_views.xml b/indoteknik_custom/views/account_account_views.xml new file mode 100644 index 00000000..45d8a19c --- /dev/null +++ b/indoteknik_custom/views/account_account_views.xml @@ -0,0 +1,15 @@ + + + + + account.account.list + account.account + + + + + + + + + \ No newline at end of file diff --git a/indoteknik_custom/views/account_move_line.xml b/indoteknik_custom/views/account_move_line.xml new file mode 100644 index 00000000..f4db8d86 --- /dev/null +++ b/indoteknik_custom/views/account_move_line.xml @@ -0,0 +1,16 @@ + + + + + account.move.form.inherit + account.move + + + + + + + + + + diff --git a/indoteknik_custom/views/cost_centre.xml b/indoteknik_custom/views/cost_centre.xml new file mode 100644 index 00000000..665b0025 --- /dev/null +++ b/indoteknik_custom/views/cost_centre.xml @@ -0,0 +1,41 @@ + + + + cost.centre.tree + cost.centre + + + + + + + + + + cost.centre.form + cost.centre + + + + + + + + + + + + + + + + Cost Centre + ir.actions.act_window + cost.centre + tree,form + + + + \ No newline at end of file -- cgit v1.2.3 From 5e85d3f86366018546dab425a8c41eb8a4f3056e Mon Sep 17 00:00:00 2001 From: Azka Nathan Date: Thu, 31 Aug 2023 13:06:56 +0700 Subject: fix error --- indoteknik_custom/models/account_move.py | 1 + 1 file changed, 1 insertion(+) diff --git a/indoteknik_custom/models/account_move.py b/indoteknik_custom/models/account_move.py index 9e7266b1..b2d1df39 100644 --- a/indoteknik_custom/models/account_move.py +++ b/indoteknik_custom/models/account_move.py @@ -20,6 +20,7 @@ class AccountMove(models.Model): due_extension = fields.Integer(string='Due Extension', default=0) new_due_date = fields.Date(string='New Due') counter = fields.Integer(string="Counter", default=0) + cost_centre_id = fields.Many2one('cost.centre', string='Cost Centre') due_line = fields.One2many('due.extension.line', 'invoice_id', compute='_compute_due_line', string='Due Extension Lines') def _compute_due_line(self): -- cgit v1.2.3 From 3f9ee6e5297afbd7aad670eb061c069621af888e Mon Sep 17 00:00:00 2001 From: Azka Nathan Date: Thu, 31 Aug 2023 13:40:38 +0700 Subject: refactor validate product --- indoteknik_custom/models/product_template.py | 6 ++---- indoteknik_custom/views/cost_centre.xml | 2 +- 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/indoteknik_custom/models/product_template.py b/indoteknik_custom/models/product_template.py index 707a8381..e9d57dc3 100755 --- a/indoteknik_custom/models/product_template.py +++ b/indoteknik_custom/models/product_template.py @@ -51,7 +51,6 @@ class ProductTemplate(models.Model): is_new_product = fields.Boolean(string='Produk Baru', help='Centang jika ingin ditammpilkan di website sebagai segment Produk Baru') seq_new_product = fields.Integer(string='Seq New Product', help='Urutan Sequence New Product') - is_edit = fields.Boolean(string="Update Counter", default=True) # def write(self, vals): # if not self.env.user.is_purchasing_manager: @@ -69,7 +68,7 @@ class ProductTemplate(models.Model): # raise UserError("Hanya Pak Tyas yang bisa mengedit product") # return super(ProductTemplate, self).write(vals) - @api.constrains('name','default_code',) + @api.constrains('name','default_code') def _check_duplicate_product(self): if not self.env.user.is_purchasing_manager: for product in self: @@ -332,7 +331,6 @@ class ProductProduct(models.Model): 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') sla_version = fields.Integer(string="SLA Version", default=0) - is_edit = fields.Boolean(string="Update Counter", default=True) # def write(self, vals): # if not self.env.user.is_purchasing_manager: @@ -349,7 +347,7 @@ class ProductProduct(models.Model): # raise UserError("Hanya Pak Tyas yang bisa mengedit product") # return super(ProductProduct, self).write(vals) - @api.constrains('name','default_code',) + @api.constrains('name','default_code') def _check_duplicate_product(self): if not self.env.user.is_purchasing_manager: for product in self: diff --git a/indoteknik_custom/views/cost_centre.xml b/indoteknik_custom/views/cost_centre.xml index 665b0025..3e4d2736 100644 --- a/indoteknik_custom/views/cost_centre.xml +++ b/indoteknik_custom/views/cost_centre.xml @@ -19,7 +19,7 @@ - + -- cgit v1.2.3 From 215fde914a2eae20928b9e40a9a5dd1ac179c4e1 Mon Sep 17 00:00:00 2001 From: Azka Nathan Date: Thu, 31 Aug 2023 14:06:21 +0700 Subject: fix error solr --- .../models/solr/product_pricelist_item.py | 24 ++-------------------- indoteknik_custom/models/solr/product_template.py | 1 + 2 files changed, 3 insertions(+), 22 deletions(-) diff --git a/indoteknik_custom/models/solr/product_pricelist_item.py b/indoteknik_custom/models/solr/product_pricelist_item.py index 6ab2f588..fa042480 100644 --- a/indoteknik_custom/models/solr/product_pricelist_item.py +++ b/indoteknik_custom/models/solr/product_pricelist_item.py @@ -6,25 +6,5 @@ class ProductPricelistItem(models.Model): @api.constrains('applied_on', 'product_id', 'base', 'base_pricelist_id', 'price_discount') def _constrains_related_solr_field(self): - self.update_template_solr() - self.update_variant_solr() - - def update_template_solr(self): - updated_template_ids = [] - for rec in self: - template = rec.product_id.product_tmpl_id - if template.id in updated_template_ids: - continue - - template._sync_price_to_solr() - updated_template_ids.append(template.id) - - def update_variant_solr(self): - updated_product_ids = [] - for rec in self: - product = rec.product_id - if product.id in updated_product_ids: - continue - - product._sync_price_to_solr() - updated_product_ids.append(product.id) \ No newline at end of file + for rec in self: + rec.product_id.product_tmpl_id._create_solr_queue('_sync_price_to_solr') \ 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 6ae0bec2..692eaa94 100644 --- a/indoteknik_custom/models/solr/product_template.py +++ b/indoteknik_custom/models/solr/product_template.py @@ -151,6 +151,7 @@ class ProductTemplate(models.Model): 'has_price_info_b': True }) self.solr().add([document]) + template.product_variant_ids._sync_price_to_solr() template.change_solr_data('Ada perubahan pada harga product') if not document.get('has_product_info_b'): -- cgit v1.2.3 From eff76a5d9671ba8a39b58166e3df9428a1f10e0c Mon Sep 17 00:00:00 2001 From: Azka Nathan Date: Thu, 31 Aug 2023 14:14:43 +0700 Subject: move code to folder solr --- indoteknik_custom/models/product_pricelist.py | 10 +--------- indoteknik_custom/models/solr/product_pricelist_item.py | 12 +++++++++++- 2 files changed, 12 insertions(+), 10 deletions(-) diff --git a/indoteknik_custom/models/product_pricelist.py b/indoteknik_custom/models/product_pricelist.py index b0adcef7..026977f8 100644 --- a/indoteknik_custom/models/product_pricelist.py +++ b/indoteknik_custom/models/product_pricelist.py @@ -41,12 +41,4 @@ class ProductPricelistItem(models.Model): manufacture_id = fields.Many2one('x_manufactures', string='Manufacture') - def action_sync_to_solr(self): - active_ids = self.env.context.get('active_ids', []) - - for pricelist_item_id in active_ids: - pricelist = self.env['product.pricelist.item'].browse(pricelist_item_id) - - templates = self.env['product.template'].search([('id', 'in', [pricelist.product_id.product_tmpl_id.id])]) - - templates._create_solr_queue('_sync_product_template_to_solr') + \ No newline at end of file diff --git a/indoteknik_custom/models/solr/product_pricelist_item.py b/indoteknik_custom/models/solr/product_pricelist_item.py index fa042480..3be8c4c0 100644 --- a/indoteknik_custom/models/solr/product_pricelist_item.py +++ b/indoteknik_custom/models/solr/product_pricelist_item.py @@ -7,4 +7,14 @@ class ProductPricelistItem(models.Model): @api.constrains('applied_on', 'product_id', 'base', 'base_pricelist_id', 'price_discount') def _constrains_related_solr_field(self): for rec in self: - rec.product_id.product_tmpl_id._create_solr_queue('_sync_price_to_solr') \ No newline at end of file + rec.product_id.product_tmpl_id._create_solr_queue('_sync_price_to_solr') + + def action_sync_to_solr(self): + active_ids = self.env.context.get('active_ids', []) + + for pricelist_item_id in active_ids: + pricelist = self.env['product.pricelist.item'].browse(pricelist_item_id) + + templates = self.env['product.template'].search([('id', 'in', [pricelist.product_id.product_tmpl_id.id])]) + + templates._create_solr_queue('_sync_price_to_solr') -- cgit v1.2.3 From fb2ee6f00d4b8caf351b05db92af7bf0e4774ec8 Mon Sep 17 00:00:00 2001 From: Azka Nathan Date: Fri, 1 Sep 2023 08:39:17 +0700 Subject: fix product template variants --- indoteknik_custom/models/product_template.py | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/indoteknik_custom/models/product_template.py b/indoteknik_custom/models/product_template.py index e9d57dc3..b44f585e 100755 --- a/indoteknik_custom/models/product_template.py +++ b/indoteknik_custom/models/product_template.py @@ -51,6 +51,7 @@ class ProductTemplate(models.Model): is_new_product = fields.Boolean(string='Produk Baru', help='Centang jika ingin ditammpilkan di website sebagai segment Produk Baru') seq_new_product = fields.Integer(string='Seq New Product', help='Urutan Sequence New Product') + is_edited = fields.Boolean(string='Is Edited') # def write(self, vals): # if not self.env.user.is_purchasing_manager: @@ -331,6 +332,7 @@ class ProductProduct(models.Model): 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') sla_version = fields.Integer(string="SLA Version", default=0) + is_edited = fields.Boolean(string='Is Edited') # def write(self, vals): # if not self.env.user.is_purchasing_manager: @@ -365,12 +367,15 @@ class ProductProduct(models.Model): raise UserError(massage) else: domain = [ - ('id', '=', product.id) + ('id', '=', product.id), + ('is_edited', '=', True), ] - massage="Hanya Pak Tyas Yang Dapat Merubah Data Product" - existing_purchase = self.search(domain, limit=1) + existing_purchase = self.search(domain) if existing_purchase: - raise UserError(massage) + raise UserError('Hanya Pak Tyas Yang Dapat Merubah Data Product') + if not existing_purchase: + true = True + self.is_edited = true @api.constrains('name') def _validate_name(self): -- cgit v1.2.3 From 41e76bb5b668473c8086ba82ea8f405315b8e5ae Mon Sep 17 00:00:00 2001 From: Azka Nathan Date: Fri, 1 Sep 2023 10:31:23 +0700 Subject: change cost_centre to analytic_account --- indoteknik_custom/models/account_account.py | 3 ++- indoteknik_custom/models/account_move_line.py | 14 ++++++++------ indoteknik_custom/views/account_account_views.xml | 3 ++- indoteknik_custom/views/account_move_line.xml | 6 +++++- 4 files changed, 17 insertions(+), 9 deletions(-) diff --git a/indoteknik_custom/models/account_account.py b/indoteknik_custom/models/account_account.py index 584c38f8..e2988625 100644 --- a/indoteknik_custom/models/account_account.py +++ b/indoteknik_custom/models/account_account.py @@ -3,4 +3,5 @@ from odoo import fields, models, api, _ class AccountAccount(models.Model): _inherit = 'account.account' - cost_centre_id = fields.Many2one('cost.centre', string='Cost Centre') \ No newline at end of file + cost_centre_id = fields.Many2one('cost.centre', string='Cost Centre') + analytic_account_ids = fields.Many2many('account.analytic.account', string='Analytic Account') \ No newline at end of file diff --git a/indoteknik_custom/models/account_move_line.py b/indoteknik_custom/models/account_move_line.py index 87e5a182..cb969855 100644 --- a/indoteknik_custom/models/account_move_line.py +++ b/indoteknik_custom/models/account_move_line.py @@ -6,6 +6,13 @@ class AccountMoveLine(models.Model): cost_centre_id = fields.Many2one('cost.centre', string='Cost Centre') is_required = fields.Boolean(string='Is Required', compute='_compute_is_required') + analytic_account_ids = fields.Many2many('account.analytic.account', string='Analytic Account') + + @api.onchange('account_id') + def _onchange_analytic_account_ids(self): + for account in self: + analytic_account = account.account_id.analytic_account_ids + account.analytic_account_ids = analytic_account @api.onchange('account_id') def _compute_is_required(self): @@ -14,9 +21,4 @@ class AccountMoveLine(models.Model): account.is_required = True else: account.is_required = False - - @api.onchange('account_id') - def _onchange_cost_centre_id(self): - for account in self: - cost_centre = account.account_id.cost_centre_id - account.cost_centre_id = cost_centre + diff --git a/indoteknik_custom/views/account_account_views.xml b/indoteknik_custom/views/account_account_views.xml index 45d8a19c..20886787 100644 --- a/indoteknik_custom/views/account_account_views.xml +++ b/indoteknik_custom/views/account_account_views.xml @@ -7,7 +7,8 @@ - + + diff --git a/indoteknik_custom/views/account_move_line.xml b/indoteknik_custom/views/account_move_line.xml index f4db8d86..f8d5db05 100644 --- a/indoteknik_custom/views/account_move_line.xml +++ b/indoteknik_custom/views/account_move_line.xml @@ -8,7 +8,11 @@ - + + + + + 1 -- cgit v1.2.3 From a08e9a90e24159b8d3a22844dac4416809c5ddff Mon Sep 17 00:00:00 2001 From: Azka Nathan Date: Fri, 1 Sep 2023 14:19:16 +0700 Subject: Fix solr product template --- indoteknik_custom/models/solr/product_template.py | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/indoteknik_custom/models/solr/product_template.py b/indoteknik_custom/models/solr/product_template.py index 692eaa94..63daeb46 100644 --- a/indoteknik_custom/models/solr/product_template.py +++ b/indoteknik_custom/models/solr/product_template.py @@ -106,14 +106,17 @@ class ProductTemplate(models.Model): for template in self: price_excl_after_disc = price_excl = discount = tax = 0 flashsale_data = tier1 = tier2 = tier3 = {} - + for variant in template.product_variant_ids: if price_excl_after_disc == 0 or variant._get_website_price_after_disc_and_tax() < price_excl_after_disc: + variant_flashsale = variant._get_flashsale_price() + flashsale_price = flashsale_data.get('flashsale_price') + if not flashsale_price or variant_flashsale['flashsale_price'] < flashsale_data.get('flashsale_price', 0): + 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() - flashsale_data = variant._get_flashsale_price() # add price tiering for base price, discount, and price after discount (tier 1 - 3) tier1 = variant._get_pricelist_tier1() tier2 = variant._get_pricelist_tier2() -- cgit v1.2.3 From a1137c5bb22734eff9585b7b95607983f23d2de9 Mon Sep 17 00:00:00 2001 From: Azka Nathan Date: Fri, 1 Sep 2023 14:27:47 +0700 Subject: fix jurnal entries line --- indoteknik_custom/views/account_move_line.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/indoteknik_custom/views/account_move_line.xml b/indoteknik_custom/views/account_move_line.xml index f8d5db05..99122de3 100644 --- a/indoteknik_custom/views/account_move_line.xml +++ b/indoteknik_custom/views/account_move_line.xml @@ -9,7 +9,7 @@ - + 1 -- cgit v1.2.3 From 513bce9e13dee0453ce24b41a54d3b408e58c7f0 Mon Sep 17 00:00:00 2001 From: Azka Nathan Date: Tue, 5 Sep 2023 14:45:18 +0700 Subject: Fix bug solr product variants, add analytic tags to jurnal entries line, remove validation edit di purchase pricelist --- indoteknik_custom/models/account_account.py | 3 +- indoteknik_custom/models/account_move_line.py | 5 +- indoteknik_custom/models/product_template.py | 85 ++++++++--------------- indoteknik_custom/models/purchase_pricelist.py | 5 -- indoteknik_custom/models/solr/product_template.py | 42 +++++------ indoteknik_custom/views/account_account_views.xml | 3 +- indoteknik_custom/views/account_move_line.xml | 6 +- 7 files changed, 53 insertions(+), 96 deletions(-) diff --git a/indoteknik_custom/models/account_account.py b/indoteknik_custom/models/account_account.py index e2988625..d8ac3204 100644 --- a/indoteknik_custom/models/account_account.py +++ b/indoteknik_custom/models/account_account.py @@ -4,4 +4,5 @@ class AccountAccount(models.Model): _inherit = 'account.account' cost_centre_id = fields.Many2one('cost.centre', string='Cost Centre') - analytic_account_ids = fields.Many2many('account.analytic.account', string='Analytic Account') \ No newline at end of file + analytic_tag_ids = fields.Many2many("account.analytic.tag", + string="Analytic Tags") \ No newline at end of file diff --git a/indoteknik_custom/models/account_move_line.py b/indoteknik_custom/models/account_move_line.py index cb969855..c230b956 100644 --- a/indoteknik_custom/models/account_move_line.py +++ b/indoteknik_custom/models/account_move_line.py @@ -6,13 +6,12 @@ class AccountMoveLine(models.Model): cost_centre_id = fields.Many2one('cost.centre', string='Cost Centre') is_required = fields.Boolean(string='Is Required', compute='_compute_is_required') - analytic_account_ids = fields.Many2many('account.analytic.account', string='Analytic Account') @api.onchange('account_id') def _onchange_analytic_account_ids(self): for account in self: - analytic_account = account.account_id.analytic_account_ids - account.analytic_account_ids = analytic_account + analytic_account = account.account_id.analytic_tag_ids + account.analytic_tag_ids = analytic_account @api.onchange('account_id') def _compute_is_required(self): diff --git a/indoteknik_custom/models/product_template.py b/indoteknik_custom/models/product_template.py index b44f585e..8daa0b7a 100755 --- a/indoteknik_custom/models/product_template.py +++ b/indoteknik_custom/models/product_template.py @@ -53,47 +53,37 @@ class ProductTemplate(models.Model): seq_new_product = fields.Integer(string='Seq New Product', help='Urutan Sequence New Product') is_edited = fields.Boolean(string='Is Edited') - # def write(self, vals): - # if not self.env.user.is_purchasing_manager: - # for product in self: - - # domain = [ - # ('id', '=', product.id), - # ('create_date', '<=', product.write_date), - # ('name', '=', product.name), - # ('default_code', '=', product.default_code) - # ] - - # existing_purchase = self.search(domain, limit=1) - # if existing_purchase: - # raise UserError("Hanya Pak Tyas yang bisa mengedit product") - # return super(ProductTemplate, self).write(vals) - - @api.constrains('name','default_code') + @api.constrains('name', 'default_code') def _check_duplicate_product(self): - if not self.env.user.is_purchasing_manager: - for product in self: - if product.write_date == product.create_date: - domain = [ - ('default_code', '!=', False), + for product in self: + if not self.env.user.is_purchasing_manager: + domain = [('default_code', '!=', False)] + + if product.product_variant_ids: + domain.extend([ '|', - ('name', '=', product.name), - ('default_code', '=', product.default_code)] - - domain.append(('id', '!=', product.id)) - massage="SKU atau Name yang anda pakai sudah digunakan di product lain" - existing_purchase = self.search(domain, limit=1) - if existing_purchase: - raise UserError(massage) + ('name', 'in', [variants.name for variants in product.product_variant_ids]), + ('default_code', 'in', [variants.default_code for variants in product.product_variant_ids]) + ]) else: - domain = [ - ('id', '=', product.id) - ] - massage="Hanya Pak Tyas Yang Dapat Merubah Data Product" - existing_purchase = self.search(domain, limit=1) - if existing_purchase: - raise UserError(massage) - + domain.extend([ + '|', + ('name', 'in', [product.name]), + ('default_code', 'in', [product.default_code]) + ]) + + domain.append(('id', '!=', product.id)) + + if product.write_date == product.create_date: + message = "SKU atau Name yang Anda gunakan sudah digunakan di produk lain" + else: + domain = [('id', '=', product.id)] + message = "Hanya Pak Tyas yang dapat merubah data produk" + + existing_purchase = self.search(domain, limit=1) + + if existing_purchase: + raise UserError(message) @api.constrains('name') def _validate_name(self): @@ -334,21 +324,6 @@ class ProductProduct(models.Model): sla_version = fields.Integer(string="SLA Version", default=0) is_edited = fields.Boolean(string='Is Edited') - # def write(self, vals): - # if not self.env.user.is_purchasing_manager: - # for product in self: - # domain = [ - # ('id', '=', product.id), - # ('create_date', '<=', product.write_date), - # ('name', '=', product.name), - # ('default_code', '=', product.default_code) - # ] - - # existing_purchase = self.search(domain, limit=1) - # if existing_purchase: - # raise UserError("Hanya Pak Tyas yang bisa mengedit product") - # return super(ProductProduct, self).write(vals) - @api.constrains('name','default_code') def _check_duplicate_product(self): if not self.env.user.is_purchasing_manager: @@ -357,8 +332,8 @@ class ProductProduct(models.Model): domain = [ ('default_code', '!=', False), '|', - ('name', '=', product.name), - ('default_code', '=', product.default_code)] + ('name', 'in', [template.name for template in product.product_tmpl_id] or [product.name]), + ('default_code', 'in', [template.default_code for template in product.product_tmpl_id] or [product.default_code])] domain.append(('id', '!=', product.id)) massage="SKU atau Name yang anda pakai sudah digunakan di product lain" diff --git a/indoteknik_custom/models/purchase_pricelist.py b/indoteknik_custom/models/purchase_pricelist.py index 5d077e04..86a5544d 100755 --- a/indoteknik_custom/models/purchase_pricelist.py +++ b/indoteknik_custom/models/purchase_pricelist.py @@ -42,11 +42,6 @@ class PurchasePricelist(models.Model): existing_purchase = self.search(domain, limit=1) if existing_purchase: raise UserError(massage) - else: - domain = [ - ('id', '=', price.id) - ] - massage="Tidak Dapat Merubah Product" existing_purchase = self.search(domain, limit=1) if existing_purchase: raise UserError(massage) \ 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 63daeb46..9950c93a 100644 --- a/indoteknik_custom/models/solr/product_template.py +++ b/indoteknik_custom/models/solr/product_template.py @@ -104,35 +104,25 @@ class ProductTemplate(models.Model): solr = self.solr() for template in self: - price_excl_after_disc = price_excl = discount = tax = 0 - flashsale_data = tier1 = tier2 = tier3 = {} + document = solr_model.get_doc('product', template.id) + flashsale_data = {} for variant in template.product_variant_ids: - if price_excl_after_disc == 0 or variant._get_website_price_after_disc_and_tax() < price_excl_after_disc: - variant_flashsale = variant._get_flashsale_price() - flashsale_price = flashsale_data.get('flashsale_price') - if not flashsale_price or variant_flashsale['flashsale_price'] < flashsale_data.get('flashsale_price', 0): - 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() - # add price tiering for base price, discount, and price after discount (tier 1 - 3) - tier1 = variant._get_pricelist_tier1() - tier2 = variant._get_pricelist_tier2() - tier3 = variant._get_pricelist_tier3() - - if template.product_variant_count == 1: - price_excl = template.product_variant_id._get_website_price_exclude_tax() - discount = template.product_variant_id._get_website_disc(0) - price_excl_after_disc = template.product_variant_id._get_website_price_after_disc_and_tax() - tax = template.product_variant_id._get_website_tax() - flashsale_data = template.product_variant_id._get_flashsale_price() - tier1 = template.product_variant_id._get_pricelist_tier1() - tier2 = template.product_variant_id._get_pricelist_tier2() - tier3 = template.product_variant_id._get_pricelist_tier3() + variant_flashsale = variant._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() + tier1 = variant._get_pricelist_tier1() + tier2 = variant._get_pricelist_tier2() + tier3 = variant._get_pricelist_tier3() - document = solr_model.get_doc('product', template.id) document.update({ 'id': template.id, 'flashsale_id_i': flashsale_data.get('flashsale_id', 0), diff --git a/indoteknik_custom/views/account_account_views.xml b/indoteknik_custom/views/account_account_views.xml index 20886787..875d5a6b 100644 --- a/indoteknik_custom/views/account_account_views.xml +++ b/indoteknik_custom/views/account_account_views.xml @@ -7,8 +7,7 @@ - - + diff --git a/indoteknik_custom/views/account_move_line.xml b/indoteknik_custom/views/account_move_line.xml index 99122de3..5b5f73cd 100644 --- a/indoteknik_custom/views/account_move_line.xml +++ b/indoteknik_custom/views/account_move_line.xml @@ -8,11 +8,9 @@ - - - - 1 + + -- cgit v1.2.3 From c4bf293cd29fab412d38e7590acdc99f2456c0d8 Mon Sep 17 00:00:00 2001 From: Azka Nathan Date: Tue, 5 Sep 2023 15:05:06 +0700 Subject: fix purchase pricelist --- indoteknik_custom/models/purchase_pricelist.py | 25 +++++++++++-------------- indoteknik_custom/views/purchase_pricelist.xml | 2 +- 2 files changed, 12 insertions(+), 15 deletions(-) diff --git a/indoteknik_custom/models/purchase_pricelist.py b/indoteknik_custom/models/purchase_pricelist.py index 86a5544d..6a8a4650 100755 --- a/indoteknik_custom/models/purchase_pricelist.py +++ b/indoteknik_custom/models/purchase_pricelist.py @@ -31,17 +31,14 @@ class PurchasePricelist(models.Model): @api.constrains('vendor_id', 'product_id','human_last_update','write_date') def _check_duplicate_purchase_pricelist(self): for price in self: - if price.write_date == price.create_date: - domain = [ - ('product_id', '=', price.product_id.id), - ('vendor_id', '=', price.vendor_id.id) - ] - - domain.append(('id', '!=', price.id)) - massage="Product dan vendor yang anda gunakan sudah ada di purchase pricelist" - existing_purchase = self.search(domain, limit=1) - if existing_purchase: - raise UserError(massage) - existing_purchase = self.search(domain, limit=1) - if existing_purchase: - raise UserError(massage) \ No newline at end of file + domain = [ + ('product_id', '=', price.product_id.id), + ('vendor_id', '=', price.vendor_id.id) + ] + + domain.append(('id', '!=', price.id)) + massage="Product dan vendor yang anda gunakan sudah ada di purchase pricelist" + existing_purchase = self.search(domain, limit=1) + if existing_purchase: + raise UserError(massage) + \ No newline at end of file diff --git a/indoteknik_custom/views/purchase_pricelist.xml b/indoteknik_custom/views/purchase_pricelist.xml index 5c63676d..f9fd52ba 100755 --- a/indoteknik_custom/views/purchase_pricelist.xml +++ b/indoteknik_custom/views/purchase_pricelist.xml @@ -19,7 +19,7 @@ purchase.pricelist.form purchase.pricelist -
+ -- cgit v1.2.3 From e07379886024a313695a56ebdd072bfd87b6626a Mon Sep 17 00:00:00 2001 From: Azka Nathan Date: Tue, 5 Sep 2023 16:19:20 +0700 Subject: try to fix bug on odoo --- indoteknik_custom/models/account_move.py | 1 + indoteknik_custom/models/account_move_line.py | 3 ++- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/indoteknik_custom/models/account_move.py b/indoteknik_custom/models/account_move.py index b2d1df39..18025b32 100644 --- a/indoteknik_custom/models/account_move.py +++ b/indoteknik_custom/models/account_move.py @@ -21,6 +21,7 @@ class AccountMove(models.Model): new_due_date = fields.Date(string='New Due') counter = fields.Integer(string="Counter", default=0) cost_centre_id = fields.Many2one('cost.centre', string='Cost Centre') + 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') def _compute_due_line(self): diff --git a/indoteknik_custom/models/account_move_line.py b/indoteknik_custom/models/account_move_line.py index c230b956..a4b25109 100644 --- a/indoteknik_custom/models/account_move_line.py +++ b/indoteknik_custom/models/account_move_line.py @@ -6,9 +6,10 @@ class AccountMoveLine(models.Model): cost_centre_id = fields.Many2one('cost.centre', string='Cost Centre') is_required = fields.Boolean(string='Is Required', compute='_compute_is_required') + analytic_account_ids = fields.Many2many('account.analytic.account', string='Analytic Account') @api.onchange('account_id') - def _onchange_analytic_account_ids(self): + def _onchange_account_id(self): for account in self: analytic_account = account.account_id.analytic_tag_ids account.analytic_tag_ids = analytic_account -- cgit v1.2.3