From f6afdd8f02676e9f0f16e2363f0065982e1e0c54 Mon Sep 17 00:00:00 2001 From: it-fixcomart Date: Thu, 7 Nov 2024 16:43:33 +0700 Subject: update code quotation status --- indoteknik_custom/models/sale_order.py | 1 + 1 file changed, 1 insertion(+) (limited to 'indoteknik_custom/models') diff --git a/indoteknik_custom/models/sale_order.py b/indoteknik_custom/models/sale_order.py index 8e170b1c..ed397301 100755 --- a/indoteknik_custom/models/sale_order.py +++ b/indoteknik_custom/models/sale_order.py @@ -98,6 +98,7 @@ class SaleOrder(models.Model): helper_by_id = fields.Many2one('res.users', 'Helper By') eta_date = fields.Datetime(string='ETA Date', copy=False, compute='_compute_eta_date') flash_sale = fields.Boolean(string='Flash Sale', help='Data dari web') + is_continue_transaction = fields.Boolean(string='Button Transaction', help='Data dari web') web_approval = fields.Selection([ ('company', 'Company'), ('cust_manager', 'Customer Manager'), -- cgit v1.2.3 From 1cf2ec912af62cca22de4c529d1bec154ca33bac Mon Sep 17 00:00:00 2001 From: it-fixcomart Date: Fri, 8 Nov 2024 13:56:37 +0700 Subject: update quotation website --- indoteknik_custom/models/res_partner.py | 13 +++++++++++-- indoteknik_custom/models/sale_order.py | 8 +++++++- indoteknik_custom/models/user_company_request.py | 2 +- 3 files changed, 19 insertions(+), 4 deletions(-) (limited to 'indoteknik_custom/models') diff --git a/indoteknik_custom/models/res_partner.py b/indoteknik_custom/models/res_partner.py index b01c7984..76fa06cd 100644 --- a/indoteknik_custom/models/res_partner.py +++ b/indoteknik_custom/models/res_partner.py @@ -1,7 +1,7 @@ from odoo import models, fields, api from odoo.exceptions import UserError, ValidationError from datetime import datetime - +from odoo.http import request class GroupPartner(models.Model): _name = 'group.partner' @@ -224,6 +224,15 @@ class ResPartner(models.Model): def _onchange_customer_type(self): if self.customer_type == 'nonpkp': self.npwp = '00.000.000.0-000.000' - + def get_check_tempo_partner(self): + self.ensure_one() + + partner = self.parent_id or self + + if not partner.property_payment_term_id or 'Tempo' not in partner.property_payment_term_id.name: + return False + + else: + return True diff --git a/indoteknik_custom/models/sale_order.py b/indoteknik_custom/models/sale_order.py index ed397301..36e60cfb 100755 --- a/indoteknik_custom/models/sale_order.py +++ b/indoteknik_custom/models/sale_order.py @@ -98,7 +98,7 @@ class SaleOrder(models.Model): helper_by_id = fields.Many2one('res.users', 'Helper By') eta_date = fields.Datetime(string='ETA Date', copy=False, compute='_compute_eta_date') flash_sale = fields.Boolean(string='Flash Sale', help='Data dari web') - is_continue_transaction = fields.Boolean(string='Button Transaction', help='Data dari web') + is_continue_transaction = fields.Boolean(string='Button Transaction', help='Data dari web', compute='_is_continue_transaction') web_approval = fields.Selection([ ('company', 'Company'), ('cust_manager', 'Customer Manager'), @@ -144,6 +144,12 @@ class SaleOrder(models.Model): ('NP', 'Non Pareto') ]) + def _is_continue_transaction(self): + if self.payment_status == 'settlement': + self.is_continue_transaction = True + else: + self.is_continue_transaction = False + def _compute_total_weight(self): total_weight = 0 missing_weight_products = [] diff --git a/indoteknik_custom/models/user_company_request.py b/indoteknik_custom/models/user_company_request.py index 86e66934..64e11700 100644 --- a/indoteknik_custom/models/user_company_request.py +++ b/indoteknik_custom/models/user_company_request.py @@ -74,7 +74,7 @@ class UserCompanyRequest(models.Model): if not self.is_approve and is_approve: if is_approve == 'approved': - self.user_id.parent_id = self.user_company_id.id + self.user_id.parent_id = self.user_company_id.id if self.user_company_id.id else vals.get('user_company_id') self.user_id.customer_type = self.user_company_id.customer_type self.user_id.npwp = self.user_company_id.npwp self.user_id.sppkp = self.user_company_id.sppkp -- cgit v1.2.3 From d0bd4a82c923789a931f9433085f4219c6d7346a Mon Sep 17 00:00:00 2001 From: it-fixcomart Date: Fri, 8 Nov 2024 14:14:54 +0700 Subject: update user tempo make quotation --- indoteknik_custom/models/res_partner.py | 1 - indoteknik_custom/models/sale_order.py | 12 +++++++----- 2 files changed, 7 insertions(+), 6 deletions(-) (limited to 'indoteknik_custom/models') diff --git a/indoteknik_custom/models/res_partner.py b/indoteknik_custom/models/res_partner.py index 76fa06cd..b6427745 100644 --- a/indoteknik_custom/models/res_partner.py +++ b/indoteknik_custom/models/res_partner.py @@ -232,7 +232,6 @@ class ResPartner(models.Model): if not partner.property_payment_term_id or 'Tempo' not in partner.property_payment_term_id.name: return False - else: return True diff --git a/indoteknik_custom/models/sale_order.py b/indoteknik_custom/models/sale_order.py index 36e60cfb..c00b2f4e 100755 --- a/indoteknik_custom/models/sale_order.py +++ b/indoteknik_custom/models/sale_order.py @@ -98,7 +98,7 @@ class SaleOrder(models.Model): helper_by_id = fields.Many2one('res.users', 'Helper By') eta_date = fields.Datetime(string='ETA Date', copy=False, compute='_compute_eta_date') flash_sale = fields.Boolean(string='Flash Sale', help='Data dari web') - is_continue_transaction = fields.Boolean(string='Button Transaction', help='Data dari web', compute='_is_continue_transaction') + is_continue_transaction = fields.Boolean(string='Button Transaction', help='Data dari web') web_approval = fields.Selection([ ('company', 'Company'), ('cust_manager', 'Customer Manager'), @@ -144,11 +144,13 @@ class SaleOrder(models.Model): ('NP', 'Non Pareto') ]) + @api.onchange('payment_status') def _is_continue_transaction(self): - if self.payment_status == 'settlement': - self.is_continue_transaction = True - else: - self.is_continue_transaction = False + if not self.is_continue_transaction: + if self.payment_status == 'settlement': + self.is_continue_transaction = True + else: + self.is_continue_transaction = False def _compute_total_weight(self): total_weight = 0 -- cgit v1.2.3 From 862e7b97028104e69ab500bf354a7c1b85854e4a Mon Sep 17 00:00:00 2001 From: it-fixcomart Date: Mon, 18 Nov 2024 15:41:41 +0700 Subject: update code avoid error --- indoteknik_custom/models/website_user_cart.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'indoteknik_custom/models') diff --git a/indoteknik_custom/models/website_user_cart.py b/indoteknik_custom/models/website_user_cart.py index 494f32f3..44393cf1 100644 --- a/indoteknik_custom/models/website_user_cart.py +++ b/indoteknik_custom/models/website_user_cart.py @@ -65,7 +65,7 @@ class WebsiteUserCart(models.Model): if stock_quant: res['is_in_bu'] = True res['on_hand_qty'] = sum(stock_quant.mapped('quantity')) - res['available_quantity'] = stock_quant.available_quantity + res['available_quantity'] = sum(stock_quant.mapped('available_quantity')) else: res['is_in_bu'] = False res['on_hand_qty'] = 0 -- cgit v1.2.3 From c4d1b5f203e0e860ed6ddcb3f33880476f0fa43c Mon Sep 17 00:00:00 2001 From: Azka Nathan Date: Tue, 19 Nov 2024 11:42:54 +0700 Subject: add field to responsive view and change field potential to is not potential --- indoteknik_custom/models/res_partner.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'indoteknik_custom/models') diff --git a/indoteknik_custom/models/res_partner.py b/indoteknik_custom/models/res_partner.py index 2f0baab0..4297012c 100644 --- a/indoteknik_custom/models/res_partner.py +++ b/indoteknik_custom/models/res_partner.py @@ -33,7 +33,7 @@ class ResPartner(models.Model): counter = fields.Integer(string="Counter", default=0) leadtime = fields.Integer(string="Leadtime", default=0) digital_invoice_tax = fields.Boolean(string="Digital Invoice & Faktur Pajak") - is_potential = fields.Boolean(string='Potential') + is_not_potential = fields.Boolean(string='Not Potential') pakta_integritas = fields.Boolean(string='Pakta Integritas') use_so_approval = fields.Boolean(string='Use SO Approval') -- cgit v1.2.3 From 9ec43ae9c1ba7bdc61388c3b9236bfb4434588e0 Mon Sep 17 00:00:00 2001 From: Azka Nathan Date: Tue, 19 Nov 2024 15:22:16 +0700 Subject: cr so --- indoteknik_custom/models/sale_order.py | 3 +++ 1 file changed, 3 insertions(+) (limited to 'indoteknik_custom/models') diff --git a/indoteknik_custom/models/sale_order.py b/indoteknik_custom/models/sale_order.py index 3d91ba91..7649ef12 100755 --- a/indoteknik_custom/models/sale_order.py +++ b/indoteknik_custom/models/sale_order.py @@ -636,6 +636,7 @@ class SaleOrder(models.Model): self.customer_type = parent_id.customer_type self.email = parent_id.email self.pareto_status = parent_id.pareto_status + self.user_id = parent_id.user_id @api.onchange('partner_id') def onchange_partner_id(self): @@ -1059,6 +1060,8 @@ class SaleOrder(models.Model): partner.email = self.email if not partner.customer_type: partner.customer_type = self.customer_type + if not partner.user_id: + partner.user_id = self.user_id # if not partner.sppkp or not partner.npwp or not partner.email or partner.customer_type: # partner.customer_type = self.customer_type -- cgit v1.2.3 From cc3b79a25e277bd360fdcf34eed1f26bdc44204e Mon Sep 17 00:00:00 2001 From: Azka Nathan Date: Tue, 19 Nov 2024 15:58:45 +0700 Subject: remove readonly driver_arrival_date --- indoteknik_custom/models/stock_picking.py | 1 - 1 file changed, 1 deletion(-) (limited to 'indoteknik_custom/models') diff --git a/indoteknik_custom/models/stock_picking.py b/indoteknik_custom/models/stock_picking.py index 430c54f3..464e728a 100644 --- a/indoteknik_custom/models/stock_picking.py +++ b/indoteknik_custom/models/stock_picking.py @@ -34,7 +34,6 @@ class StockPicking(models.Model): ) driver_arrival_date = fields.Datetime( string='Delivery Arrival Date', - readonly=True, copy=False ) delivery_tracking_no = fields.Char( -- cgit v1.2.3 From d64eccc538c5eb130efddb4d1b6c5bfc441957e8 Mon Sep 17 00:00:00 2001 From: it-fixcomart Date: Tue, 19 Nov 2024 17:29:27 +0700 Subject: shipment --- indoteknik_custom/models/stock_picking.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'indoteknik_custom/models') diff --git a/indoteknik_custom/models/stock_picking.py b/indoteknik_custom/models/stock_picking.py index 430c54f3..0bcb591e 100644 --- a/indoteknik_custom/models/stock_picking.py +++ b/indoteknik_custom/models/stock_picking.py @@ -281,9 +281,9 @@ class StockPicking(models.Model): def _compute_shipping_status(self): for rec in self: status = 'pending' - if rec.driver_departure_date and not rec.driver_arrival_date: + if rec.driver_departure_date and not (rec.sj_return_date or rec.driver_arrival_date): status = 'shipment' - elif rec.driver_departure_date and rec.driver_arrival_date: + elif rec.driver_departure_date and (rec.sj_return_date or rec.driver_arrival_date): status = 'completed' rec.shipping_status = status @@ -657,13 +657,13 @@ class StockPicking(models.Model): manifest_datas = [] departure_date = self.driver_departure_date - arrival_date = self.driver_arrival_date + arrival_date = self.sj_return_date if self.sj_return_date else self.driver_arrival_date status = status_mapping.get(status_key) if not status: return manifest_datas - if arrival_date: + if arrival_date or self.sj_return_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)) @@ -690,7 +690,7 @@ class StockPicking(models.Model): } if not self.waybill_id or len(self.waybill_id.manifest_ids) == 0: - response['delivered'] = self.driver_arrival_date != False + response['delivered'] = self.sj_return_date != False or self.driver_arrival_date != False return response response['delivery_order']['receiver_name'] = self.waybill_id.receiver_name -- cgit v1.2.3 From 1c8ecb8d4532e73e3cf5e5ea74e0a2ff1ca95939 Mon Sep 17 00:00:00 2001 From: Azka Nathan Date: Wed, 20 Nov 2024 11:39:53 +0700 Subject: add validation if qty_done > qty_onhand --- indoteknik_custom/models/sale_order.py | 2 +- indoteknik_custom/models/stock_picking.py | 19 +++++++++++++++++++ 2 files changed, 20 insertions(+), 1 deletion(-) (limited to 'indoteknik_custom/models') diff --git a/indoteknik_custom/models/sale_order.py b/indoteknik_custom/models/sale_order.py index 7649ef12..5e868edd 100755 --- a/indoteknik_custom/models/sale_order.py +++ b/indoteknik_custom/models/sale_order.py @@ -1061,7 +1061,7 @@ class SaleOrder(models.Model): if not partner.customer_type: partner.customer_type = self.customer_type if not partner.user_id: - partner.user_id = self.user_id + partner.user_id = self.user_id.id # if not partner.sppkp or not partner.npwp or not partner.email or partner.customer_type: # partner.customer_type = self.customer_type diff --git a/indoteknik_custom/models/stock_picking.py b/indoteknik_custom/models/stock_picking.py index 464e728a..52e70367 100644 --- a/indoteknik_custom/models/stock_picking.py +++ b/indoteknik_custom/models/stock_picking.py @@ -522,12 +522,31 @@ class StockPicking(models.Model): and quant.inventory_quantity < line.product_uom_qty ): raise UserError('Quantity reserved lebih besar dari quantity onhand di product') + + def check_qty_done_stock(self): + for line in self.move_line_ids_without_package: + def check_qty_per_inventory(self, product, location): + quant = self.env['stock.quant'].search([ + ('product_id', '=', product.id), + ('location_id', '=', location.id), + ]) + if quant: + return quant.quantity + + return 0 + + qty_onhand = check_qty_per_inventory(self, line.product_id, line.location_id) + if line.qty_done > qty_onhand: + raise UserError('Quantity Done melebihi Quantity Onhand') def button_validate(self): if not self.env.user.is_logistic_approver and self.env.context.get('active_model') == 'stock.picking': if self.origin and 'Return of' in self.origin: raise UserError("Button ini hanya untuk Logistik") + + if self.picking_type_code == 'internal': + self.check_qty_done_stock() if self._name != 'stock.picking': return super(StockPicking, self).button_validate() -- cgit v1.2.3 From 5a71f4543a265562abc36630d16059f9db92d056 Mon Sep 17 00:00:00 2001 From: Azka Nathan Date: Thu, 21 Nov 2024 09:24:56 +0700 Subject: cr stock_picking --- indoteknik_custom/models/stock_picking.py | 48 ++++++++++++++++--------------- 1 file changed, 25 insertions(+), 23 deletions(-) (limited to 'indoteknik_custom/models') diff --git a/indoteknik_custom/models/stock_picking.py b/indoteknik_custom/models/stock_picking.py index 071e3dfe..f17e12b7 100644 --- a/indoteknik_custom/models/stock_picking.py +++ b/indoteknik_custom/models/stock_picking.py @@ -442,29 +442,31 @@ class StockPicking(models.Model): for pick in self: if self.env.user.is_accounting: pick.approval_return_status = 'approved' - else: - if self.picking_type_code == 'outgoing': - if self.env.user.id in [3988, 3401, 20]: - action = self.env['ir.actions.act_window']._for_xml_id('indoteknik_custom.action_stock_return_note_wizard') - action['context'] = { - 'picking_ids': [x.id for x in self] - } - return action - elif not self.env.user.id in [3988, 3401, 20] and 'Return of' in self.origin: - raise UserError('Harus Purchasing yang Ask Return') - else: - raise UserError('Harus Sales Admin yang Ask Return') - elif self.picking_type_code == 'incoming': - if self.env.user.has_group('indoteknik_custom.group_role_purchasing'): - action = self.env['ir.actions.act_window']._for_xml_id('indoteknik_custom.action_stock_return_note_wizard') - action['context'] = { - 'picking_ids': [x.id for x in self] - } - return action - elif not self.env.user.has_group('indoteknik_custom.group_role_purchasing') and 'Return of' in self.origin: - raise UserError('Harus Sales Admin yang Ask Return') - else: - raise UserError('Harus Purchasing yang Ask Return') + continue + + action_context = { + 'picking_ids': [x.id for x in self] + } + + if self.picking_type_code == 'outgoing': + if self.env.user.id in [3988, 3401, 20] or ( + self.env.user.has_group('indoteknik_custom.group_role_purchasing') and 'Return of' in self.origin + ): + return self.env['ir.actions.act_window']._for_xml_id('indoteknik_custom.action_stock_return_note_wizard', context=action_context) + elif not self.env.user.has_group('indoteknik_custom.group_role_purchasing') and 'Return of' in self.origin: + raise UserError('Harus Purchasing yang Ask Return') + else: + raise UserError('Harus Sales Admin yang Ask Return') + + elif self.picking_type_code == 'incoming': + if self.env.user.has_group('indoteknik_custom.group_role_purchasing') or ( + self.env.user.id in [3988, 3401, 20] and 'Return of' in self.origin + ): + return self.env['ir.actions.act_window']._for_xml_id('indoteknik_custom.action_stock_return_note_wizard', context=action_context) + elif not self.env.user.id in [3988, 3401, 20] and 'Return of' in self.origin: + raise UserError('Harus Sales Admin yang Ask Return') + else: + raise UserError('Harus Purchasing yang Ask Return') def calculate_line_no(self): -- cgit v1.2.3 From ffa3c65f93c3b042fb2cb813c17483e7b8ccc4cf Mon Sep 17 00:00:00 2001 From: Azka Nathan Date: Thu, 21 Nov 2024 09:46:54 +0700 Subject: cr stock picking --- indoteknik_custom/models/stock_picking.py | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) (limited to 'indoteknik_custom/models') diff --git a/indoteknik_custom/models/stock_picking.py b/indoteknik_custom/models/stock_picking.py index f17e12b7..16805197 100644 --- a/indoteknik_custom/models/stock_picking.py +++ b/indoteknik_custom/models/stock_picking.py @@ -444,15 +444,15 @@ class StockPicking(models.Model): pick.approval_return_status = 'approved' continue - action_context = { - 'picking_ids': [x.id for x in self] - } - if self.picking_type_code == 'outgoing': if self.env.user.id in [3988, 3401, 20] or ( self.env.user.has_group('indoteknik_custom.group_role_purchasing') and 'Return of' in self.origin ): - return self.env['ir.actions.act_window']._for_xml_id('indoteknik_custom.action_stock_return_note_wizard', context=action_context) + action = self.env['ir.actions.act_window']._for_xml_id('indoteknik_custom.action_stock_return_note_wizard') + action['context'] = { + 'picking_ids': [x.id for x in self] + } + return action elif not self.env.user.has_group('indoteknik_custom.group_role_purchasing') and 'Return of' in self.origin: raise UserError('Harus Purchasing yang Ask Return') else: @@ -462,7 +462,11 @@ class StockPicking(models.Model): if self.env.user.has_group('indoteknik_custom.group_role_purchasing') or ( self.env.user.id in [3988, 3401, 20] and 'Return of' in self.origin ): - return self.env['ir.actions.act_window']._for_xml_id('indoteknik_custom.action_stock_return_note_wizard', context=action_context) + action = self.env['ir.actions.act_window']._for_xml_id('indoteknik_custom.action_stock_return_note_wizard') + action['context'] = { + 'picking_ids': [x.id for x in self] + } + return action elif not self.env.user.id in [3988, 3401, 20] and 'Return of' in self.origin: raise UserError('Harus Sales Admin yang Ask Return') else: -- cgit v1.2.3 From b9bdfb05f96affaeec8e197b6585df140d4cd11c Mon Sep 17 00:00:00 2001 From: Azka Nathan Date: Thu, 21 Nov 2024 09:48:11 +0700 Subject: cr stock_picking --- indoteknik_custom/models/stock_picking.py | 13 ++++--------- 1 file changed, 4 insertions(+), 9 deletions(-) (limited to 'indoteknik_custom/models') diff --git a/indoteknik_custom/models/stock_picking.py b/indoteknik_custom/models/stock_picking.py index 16805197..10b26711 100644 --- a/indoteknik_custom/models/stock_picking.py +++ b/indoteknik_custom/models/stock_picking.py @@ -444,14 +444,13 @@ class StockPicking(models.Model): pick.approval_return_status = 'approved' continue + action = self.env['ir.actions.act_window']._for_xml_id('indoteknik_custom.action_stock_return_note_wizard') + if self.picking_type_code == 'outgoing': if self.env.user.id in [3988, 3401, 20] or ( self.env.user.has_group('indoteknik_custom.group_role_purchasing') and 'Return of' in self.origin ): - action = self.env['ir.actions.act_window']._for_xml_id('indoteknik_custom.action_stock_return_note_wizard') - action['context'] = { - 'picking_ids': [x.id for x in self] - } + action['context'] = {'picking_ids': [x.id for x in self]} return action elif not self.env.user.has_group('indoteknik_custom.group_role_purchasing') and 'Return of' in self.origin: raise UserError('Harus Purchasing yang Ask Return') @@ -462,17 +461,13 @@ class StockPicking(models.Model): if self.env.user.has_group('indoteknik_custom.group_role_purchasing') or ( self.env.user.id in [3988, 3401, 20] and 'Return of' in self.origin ): - action = self.env['ir.actions.act_window']._for_xml_id('indoteknik_custom.action_stock_return_note_wizard') - action['context'] = { - 'picking_ids': [x.id for x in self] - } + action['context'] = {'picking_ids': [x.id for x in self]} return action elif not self.env.user.id in [3988, 3401, 20] and 'Return of' in self.origin: raise UserError('Harus Sales Admin yang Ask Return') else: raise UserError('Harus Purchasing yang Ask Return') - def calculate_line_no(self): for picking in self: -- cgit v1.2.3 From 130390b0c4c8c37f5a69d3833f5f1ad9e60e787d Mon Sep 17 00:00:00 2001 From: Azka Nathan Date: Thu, 21 Nov 2024 14:01:16 +0700 Subject: push --- indoteknik_custom/models/__init__.py | 2 + indoteknik_custom/models/sale_order.py | 47 +++++++------- indoteknik_custom/models/va_multi_approve.py | 22 +++++++ indoteknik_custom/models/va_multi_reject.py | 22 +++++++ indoteknik_custom/models/vendor_approval.py | 94 +++++++++++++++++----------- 5 files changed, 128 insertions(+), 59 deletions(-) create mode 100644 indoteknik_custom/models/va_multi_approve.py create mode 100644 indoteknik_custom/models/va_multi_reject.py (limited to 'indoteknik_custom/models') diff --git a/indoteknik_custom/models/__init__.py b/indoteknik_custom/models/__init__.py index 4983cc17..ad6d75dd 100755 --- a/indoteknik_custom/models/__init__.py +++ b/indoteknik_custom/models/__init__.py @@ -132,3 +132,5 @@ from . import vendor_approval from . import partner from . import find_page from . import approval_retur_picking +from . import va_multi_approve +from . import va_multi_reject diff --git a/indoteknik_custom/models/sale_order.py b/indoteknik_custom/models/sale_order.py index 5e868edd..6475f29f 100755 --- a/indoteknik_custom/models/sale_order.py +++ b/indoteknik_custom/models/sale_order.py @@ -79,7 +79,7 @@ class SaleOrder(models.Model): payment_link_midtrans = fields.Char(string='Payment Link', help='Url payment yg digenerate oleh midtrans, harap diserahkan ke customer agar dapat dilakukan pembayaran secara mandiri') payment_qr_code = fields.Binary("Payment QR Code") due_id = fields.Many2one('due.extension', string="Due Extension", readonly=True, tracking=True) - vendor_approval_id = fields.Many2one('vendor.approval', string="Vendor Approval", readonly=True, tracking=True, copy=False) + vendor_approval_id = fields.Many2many('vendor.approval', string="Vendor Approval", readonly=True, tracking=True, copy=False) customer_type = fields.Selection([ ('pkp', 'PKP'), ('nonpkp', 'Non PKP') @@ -882,29 +882,26 @@ class SaleOrder(models.Model): }).send() def validate_different_vendor(self): - if self.vendor_approval_id and self.vendor_approval_id.state == 'draft': - raise UserError('SO ini sedang dalam review Vendor Approval') - - if self.vendor_approval_id and self.vendor_approval_id.state == 'cancel': - raise UserError('Vendor Approval SO ini Di Reject') - - if self.vendor_approval_id and self.vendor_approval_id.state == 'done': + if self.vendor_approval_id.filtered(lambda v: v.state == 'draft'): + draft_names = ", ".join(self.vendor_approval_id.filtered(lambda v: v.state == 'draft').mapped('name')) + raise UserError(f"SO ini sedang dalam review Vendor Approval: {draft_names}") + + if self.vendor_approval_id and all(v.state != 'draft' for v in self.vendor_approval_id): return False - different_vendor = self.order_line.filtered(lambda l: l.vendor_id and l.vendor_md_id and l.vendor_id.id != l.vendor_md_id.id) + different_vendor = self.order_line.filtered( + lambda l: l.vendor_id and l.vendor_md_id and l.vendor_id.id != l.vendor_md_id.id + ) + if different_vendor: - vendor_approval = self.env['vendor.approval'].create({ - 'order_id': self.id, - 'create_date_so': self.create_date, - 'partner_id': self.partner_id.id, - 'state': 'draft', - }) - - self.vendor_approval_id = vendor_approval.id - + vendor_approvals = [] for line in different_vendor: - self.env['vendor.approval.line'].create({ - 'vendor_approval_id': vendor_approval.id, + vendor_approval = self.env['vendor.approval'].create({ + 'order_id': self.id, + 'order_line_id': line.id, + 'create_date_so': self.create_date, + 'partner_id': self.partner_id.id, + 'state': 'draft', 'product_id': line.product_id.id, 'product_uom_qty': line.product_uom_qty, 'vendor_id': line.vendor_id.id, @@ -916,9 +913,15 @@ class SaleOrder(models.Model): 'margin_after': line.item_percent_margin, 'purchase_tax_id': line.purchase_tax_id.id, 'sales_tax_id': line.tax_id[0].id if line.tax_id else False, - 'percent_margin_difference': (line.price_unit - line.purchase_price_md) / line.purchase_price_md if line.purchase_price_md else False, + 'percent_margin_difference': ( + (line.price_unit - line.purchase_price_md) / line.purchase_price_md + if line.purchase_price_md else False + ), }) - + + vendor_approvals.append(vendor_approval.id) + + self.vendor_approval_id = [(4, vid) for vid in vendor_approvals] return True else: return False diff --git a/indoteknik_custom/models/va_multi_approve.py b/indoteknik_custom/models/va_multi_approve.py new file mode 100644 index 00000000..028358c2 --- /dev/null +++ b/indoteknik_custom/models/va_multi_approve.py @@ -0,0 +1,22 @@ +from odoo import models, fields +import logging + +_logger = logging.getLogger(__name__) + + +class VaMultiApprove(models.TransientModel): + _name = 'va.multi.approve' + + def save_multi_approve_va(self): + va_ids = self._context['va_ids'] + vendor_approval = self.env['vendor.approval'].browse(va_ids) + vendor_approval.action_approve() + return { + 'type': 'ir.actions.client', + 'tag': 'display_notification', + 'params': { + 'title': 'Notification', + 'message': 'Berhasil Di Approve', + 'next': {'type': 'ir.actions.act_window_close'}, + } + } \ No newline at end of file diff --git a/indoteknik_custom/models/va_multi_reject.py b/indoteknik_custom/models/va_multi_reject.py new file mode 100644 index 00000000..c05581bf --- /dev/null +++ b/indoteknik_custom/models/va_multi_reject.py @@ -0,0 +1,22 @@ +from odoo import models, fields +import logging + +_logger = logging.getLogger(__name__) + + +class VaMultiReject(models.TransientModel): + _name = 'va.multi.reject' + + def save_multi_reject_va(self): + va_ids = self._context['va_ids'] + vendor_approval = self.env['vendor.approval'].browse(va_ids) + vendor_approval.action_reject() + return { + 'type': 'ir.actions.client', + 'tag': 'display_notification', + 'params': { + 'title': 'Notification', + 'message': 'Berhasil Di Reject', + 'next': {'type': 'ir.actions.act_window_close'}, + } + } \ No newline at end of file diff --git a/indoteknik_custom/models/vendor_approval.py b/indoteknik_custom/models/vendor_approval.py index 56b81a37..ad323c29 100644 --- a/indoteknik_custom/models/vendor_approval.py +++ b/indoteknik_custom/models/vendor_approval.py @@ -13,10 +13,22 @@ class VendorApproval(models.Model): number = fields.Char(string='Document No', index=True, copy=False, readonly=True, tracking=True) partner_id = fields.Many2one('res.partner', string="Customer", readonly=True) + order_line_id = fields.Many2one('sale.order.line', string="SO Line", readonly=True) order_id = fields.Many2one('sale.order', string="SO", readonly=True) - vendor_approval_line = fields.One2many('vendor.approval.line', 'vendor_approval_id', string='Vendor Approval Lines', auto_join=True) state = fields.Selection([('draft', 'Draft'), ('done', 'Done'), ('cancel', 'Reject')], string='State', tracking=True) create_date_so = fields.Datetime(string='Create Date SO', readonly=True) + product_id = fields.Many2one('product.product', string='Product') + product_uom_qty = fields.Float(string='Quantity') + vendor_id = fields.Many2one('res.partner', string='Vendor') + vendor_md_id = fields.Many2one('res.partner', string='Vendor MD') + sales_price = fields.Float(string='Sales Price') + margin_before = fields.Float(string='Margin Before') + margin_after = fields.Float(string='Margin After') + purchase_price = fields.Float(string='Purchase Price') + purchase_price_md= fields.Float(string='Purchase Price MD') + purchase_tax_id = fields.Many2one('account.tax', string='Purchase Tax', domain=['|', ('active', '=', False), ('active', '=', True)]) + sales_tax_id = fields.Many2one('account.tax', string='Sales Tax', domain=['|', ('active', '=', False), ('active', '=', True)]) + percent_margin_difference = fields.Float(string='Percent Margin Difference') @api.model def create(self, vals): @@ -25,49 +37,57 @@ class VendorApproval(models.Model): return result def action_approve(self): - if not self.env.user.has_group('indoteknik_custom.group_role_merchandiser'): - raise UserError('Hanya Merchandiser yang bisa approve') - - self.state = 'done' - self.order_id.vendor_approval = True - message = "Vendor Approval approved by %s" % (self.env.user.name) - self.order_id.message_post(body=message) - if not self.order_id.due_id and self.order_id.state == 'draft': - self.order_id.action_confirm() + for rec in self: + if not self.env.user.has_group('indoteknik_custom.group_role_merchandiser'): + raise UserError('Hanya Merchandiser yang bisa approve') + + # Set state menjadi 'done' + rec.state = 'done' + rec.order_id.vendor_approval = True + message = f"Vendor Approval approved by {self.env.user.name}" + rec.order_id.message_post(body=message) + + # Cek semua vendor.approval dengan order_id yang sama + related_approvals = self.env['vendor.approval'].search([('order_id', '=', rec.order_id.id)]) + if all(approval.state != 'draft' for approval in related_approvals): + # Jalankan action_confirm hanya jika semua state bukan draft + if not rec.order_id.due_id and rec.order_id.state == 'draft': + rec.order_id.action_confirm() + def action_reject(self): - if not self.env.user.has_group('indoteknik_custom.group_role_merchandiser'): - raise UserError('Hanya Merchandiser yang bisa cancel') - - self.state = 'cancel' + for rec in self: + if not self.env.user.has_group('indoteknik_custom.group_role_merchandiser'): + raise UserError('Hanya Merchandiser yang bisa cancel') + + rec.state = 'cancel' + + rec.order_line_id.vendor_id = rec.vendor_md_id.id + + message = "Vendor Approval rejected by %s" % (self.env.user.name) + self.order_id.message_post(body=message) - message = "Vendor Approval rejected by %s" % (self.env.user.name) - self.order_id.message_post(body=message) + related_approvals = self.env['vendor.approval'].search([('order_id', '=', rec.order_id.id)]) + if all(approval.state != 'draft' for approval in related_approvals): + # Jalankan action_confirm hanya jika semua state bukan draft + if not rec.order_id.due_id and rec.order_id.state == 'draft': + rec.order_id.action_confirm() def unlink(self): res = super(VendorApproval, self).unlink() if not self._name == 'vendor.approval': raise UserError('Vendor Approval tidak bisa didelete') return res - -class VendorApprovalLine(models.Model): - _name = 'vendor.approval.line' - _description = 'Vendor Approval Line' - _order = 'vendor_approval_id, id' - - vendor_approval_id = fields.Many2one('vendor.approval', string='Vendor Approval Ref', required=True, ondelete='cascade', index=True, copy=False) - product_id = fields.Many2one('product.product', string='Product') - product_uom_qty = fields.Float(string='Quantity') - vendor_id = fields.Many2one('res.partner', string='Vendor') - vendor_md_id = fields.Many2one('res.partner', string='Vendor MD') - sales_price = fields.Float(string='Sales Price') - margin_before = fields.Float(string='Margin Before') - margin_after = fields.Float(string='Margin After') - purchase_price = fields.Float(string='Purchase Price') - purchase_price_md= fields.Float(string='Purchase Price MD') - purchase_tax_id = fields.Many2one('account.tax', string='Purchase Tax', domain=['|', ('active', '=', False), ('active', '=', True)]) - sales_tax_id = fields.Many2one('account.tax', string='Sales Tax', domain=['|', ('active', '=', False), ('active', '=', True)]) - percent_margin_difference = fields.Float(string='Percent Margin Difference') - - + def open_form_multi_approve(self): + action = self.env['ir.actions.act_window']._for_xml_id('indoteknik_custom.action_va_multi_approve') + action['context'] = { + 'va_ids': [x.id for x in self] + } + return action + def open_form_multi_reject(self): + action = self.env['ir.actions.act_window']._for_xml_id('indoteknik_custom.action_va_multi_reject') + action['context'] = { + 'va_ids': [x.id for x in self] + } + return action \ No newline at end of file -- cgit v1.2.3 From 4e84a3c939f50315c5eba4a9ae350f17383b5543 Mon Sep 17 00:00:00 2001 From: it-fixcomart Date: Thu, 21 Nov 2024 16:29:05 +0700 Subject: perbaiki code is_in_bu logic --- indoteknik_custom/models/solr/product_product.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'indoteknik_custom/models') diff --git a/indoteknik_custom/models/solr/product_product.py b/indoteknik_custom/models/solr/product_product.py index dd1d40f6..667511b2 100644 --- a/indoteknik_custom/models/solr/product_product.py +++ b/indoteknik_custom/models/solr/product_product.py @@ -54,7 +54,7 @@ class ProductProduct(models.Model): ('location_id', 'in', target_locations), ]) - is_in_bu = any(quant.available_quantity > 0 for quant in stock_quant) + is_in_bu = True if variant.qty_free_bandengan > 0 else False document = solr_model.get_doc('variants', variant.id) -- cgit v1.2.3 From 447c98f3079af31a850dd3898190da1063f45cf0 Mon Sep 17 00:00:00 2001 From: Azka Nathan Date: Mon, 25 Nov 2024 09:07:05 +0700 Subject: cr validation link midtrans do --- indoteknik_custom/models/stock_picking.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'indoteknik_custom/models') diff --git a/indoteknik_custom/models/stock_picking.py b/indoteknik_custom/models/stock_picking.py index 10b26711..17dd5766 100644 --- a/indoteknik_custom/models/stock_picking.py +++ b/indoteknik_custom/models/stock_picking.py @@ -570,10 +570,10 @@ class StockPicking(models.Model): if self.location_dest_id.id == 47 and not self.env.user.is_purchasing_manager: raise UserError("Transfer ke gudang selisih harus di approve Rafly Hanggara") - if self.group_id.sale_id: - if self.group_id.sale_id.payment_link_midtrans: - if self.group_id.sale_id.payment_status != 'settlement': - raise UserError('Uang belum masuk (settlement), mohon konfirmasi ke sales atau finance') + # if self.group_id.sale_id: + # if self.group_id.sale_id.payment_link_midtrans: + # if self.group_id.sale_id.payment_status != 'settlement' and self.group_id.sale_id.state == 'draft': + # raise UserError('Uang belum masuk (settlement), mohon konfirmasi ke sales atau finance') if self.is_internal_use: self.approval_status = 'approved' -- cgit v1.2.3 From 3f3fd6fcaa74cf3e3dd6e73d7ddb95ff537742b8 Mon Sep 17 00:00:00 2001 From: Azka Nathan Date: Tue, 26 Nov 2024 13:44:33 +0700 Subject: push --- indoteknik_custom/models/purchase_order.py | 34 +++++++++++++++++++++++++---- indoteknik_custom/models/sale_order.py | 2 +- indoteknik_custom/models/vendor_approval.py | 9 ++++++++ 3 files changed, 40 insertions(+), 5 deletions(-) (limited to 'indoteknik_custom/models') diff --git a/indoteknik_custom/models/purchase_order.py b/indoteknik_custom/models/purchase_order.py index 3397616d..26dc5102 100755 --- a/indoteknik_custom/models/purchase_order.py +++ b/indoteknik_custom/models/purchase_order.py @@ -595,10 +595,19 @@ class PurchaseOrder(models.Model): if line.product_uom_qty > line.product_id.plafon_qty + line.product_uom_qty and not self.env.user.has_group('indoteknik_custom.group_role_merchandiser'): raise UserError('Product '+line.product_id.name+' melebihi plafon, harus Approval MD') + def check_different_vendor_so_po(self): + vendor_po = self.partner_id.id + for line in self.order_line: + if not line.so_line_id: + continue + if line.so_line_id.vendor_id.id != vendor_po: + raise UserError("Produk "+line.product_id.name+" memiliki vendor berbeda dengan SO (Vendor PO: "+str(self.partner_id.name)+", Vendor SO: "+str(line.so_line_id.vendor_id.name)+")") + def button_confirm(self): res = super(PurchaseOrder, self).button_confirm() current_time = datetime.now() self.check_ppn_mix() + self.check_different_vendor_so_po() # self.check_data_vendor() if self.amount_untaxed >= 50000000 and not self.env.user.has_group('indoteknik_custom.group_role_merchandiser'): @@ -736,12 +745,12 @@ class PurchaseOrder(models.Model): template.send_mail(self.id, force_send=True) def po_approve(self): - # if self.amount_untaxed >= 50000000 and not self.env.user.has_group('indoteknik_custom.group_role_merchandiser'): - # raise UserError("Hanya Merchandiser yang bisa approve") greater_than_plafon, message = self._get_msg_plafon_qty() + different_vendor_message = self.check_different_vendor_so() # Panggil fungsi check_different_vendor_so + if self.env.user.is_leader or self.env.user.has_group('indoteknik_custom.group_role_merchandiser'): raise UserError("Bisa langsung Confirm") - elif self.total_percent_margin == self.total_so_percent_margin and self.matches_so and not greater_than_plafon: + elif self.total_percent_margin == self.total_so_percent_margin and self.matches_so and not greater_than_plafon and not different_vendor_message: raise UserError("Bisa langsung Confirm") else: reason = '' @@ -757,13 +766,30 @@ class PurchaseOrder(models.Model): # Check Plafon Qty and Get Message every Line Product if greater_than_plafon: reason += message + # Check for Different Vendor Message + if different_vendor_message: + reason += different_vendor_message + # Post a highlighted message to lognote self.message_post( body=f"
" - f"Note (Pinned):
{reason}
", + f"Note (Pinned):
{reason}", subtype_id=self.env.ref("mail.mt_note").id ) + + def check_different_vendor_so(self): + vendor_po = self.partner_id.id + message = '' + for line in self.order_line: + if not line.so_line_id: + continue + if line.so_line_id.vendor_id.id != vendor_po: + product_code = line.product_id.display_name or 'Unknown' + message += (f"Produk {product_code} memiliki vendor berbeda dengan SO " + f"(Vendor PO: {self.partner_id.name}, Vendor SO: {line.so_line_id.vendor_id.name}), ") + return message if message else None + def _get_msg_plafon_qty(self): message = '' greater_than_plafon = False diff --git a/indoteknik_custom/models/sale_order.py b/indoteknik_custom/models/sale_order.py index 6475f29f..315a338a 100755 --- a/indoteknik_custom/models/sale_order.py +++ b/indoteknik_custom/models/sale_order.py @@ -883,7 +883,7 @@ class SaleOrder(models.Model): def validate_different_vendor(self): if self.vendor_approval_id.filtered(lambda v: v.state == 'draft'): - draft_names = ", ".join(self.vendor_approval_id.filtered(lambda v: v.state == 'draft').mapped('name')) + draft_names = ", ".join(self.vendor_approval_id.filtered(lambda v: v.state == 'draft').mapped('number')) raise UserError(f"SO ini sedang dalam review Vendor Approval: {draft_names}") if self.vendor_approval_id and all(v.state != 'draft' for v in self.vendor_approval_id): diff --git a/indoteknik_custom/models/vendor_approval.py b/indoteknik_custom/models/vendor_approval.py index ad323c29..01d2e6a2 100644 --- a/indoteknik_custom/models/vendor_approval.py +++ b/indoteknik_custom/models/vendor_approval.py @@ -35,9 +35,16 @@ class VendorApproval(models.Model): vals['number'] = self.env['ir.sequence'].next_by_code('vendor.approval') or '0' result = super(VendorApproval, self).create(vals) return result + + def check_state_so(self): + for rec in self: + if rec.order_id.state != 'draft': + raise UserError(f"SO {rec.order_id.name} sudah tidak bisa diubah") + def action_approve(self): for rec in self: + self.check_state_so() if not self.env.user.has_group('indoteknik_custom.group_role_merchandiser'): raise UserError('Hanya Merchandiser yang bisa approve') @@ -57,12 +64,14 @@ class VendorApproval(models.Model): def action_reject(self): for rec in self: + self.check_state_so() if not self.env.user.has_group('indoteknik_custom.group_role_merchandiser'): raise UserError('Hanya Merchandiser yang bisa cancel') rec.state = 'cancel' rec.order_line_id.vendor_id = rec.vendor_md_id.id + rec.order_line_id.purchase_price = rec.purchase_price_md message = "Vendor Approval rejected by %s" % (self.env.user.name) self.order_id.message_post(body=message) -- cgit v1.2.3 From a5894d7d55b48e15a2c61759d6ffc04f8ba17c79 Mon Sep 17 00:00:00 2001 From: Azka Nathan Date: Tue, 26 Nov 2024 14:20:30 +0700 Subject: cr purchasing job --- indoteknik_custom/models/purchasing_job.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'indoteknik_custom/models') diff --git a/indoteknik_custom/models/purchasing_job.py b/indoteknik_custom/models/purchasing_job.py index bf5ed8c4..4efb0cd4 100644 --- a/indoteknik_custom/models/purchasing_job.py +++ b/indoteknik_custom/models/purchasing_job.py @@ -57,7 +57,7 @@ class PurchasingJob(models.Model): max(pjs.status_apo::text) AS status_apo, max(pjs.note::text) AS note, CASE - WHEN sub.vendor_id = 5571 THEN 27 + WHEN pmp.brand IN ('Tekiro', 'RYU', 'Rexco') THEN 27 WHEN sub.vendor_id = 9688 THEN 397 WHEN sub.vendor_id = 35475 THEN 397 WHEN sub.vendor_id = 29712 THEN 397 -- cgit v1.2.3 From 58bec36c52b223c12fd15511a56ab417ebbd7257 Mon Sep 17 00:00:00 2001 From: Azka Nathan Date: Tue, 26 Nov 2024 16:06:50 +0700 Subject: fix bug po --- indoteknik_custom/models/purchase_order.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'indoteknik_custom/models') diff --git a/indoteknik_custom/models/purchase_order.py b/indoteknik_custom/models/purchase_order.py index 26dc5102..9388ae4c 100755 --- a/indoteknik_custom/models/purchase_order.py +++ b/indoteknik_custom/models/purchase_order.py @@ -600,7 +600,7 @@ class PurchaseOrder(models.Model): for line in self.order_line: if not line.so_line_id: continue - if line.so_line_id.vendor_id.id != vendor_po: + if line.so_line_id.vendor_id.id != vendor_po and not self.env.user.has_group('indoteknik_custom.group_role_merchandiser'): raise UserError("Produk "+line.product_id.name+" memiliki vendor berbeda dengan SO (Vendor PO: "+str(self.partner_id.name)+", Vendor SO: "+str(line.so_line_id.vendor_id.name)+")") def button_confirm(self): -- cgit v1.2.3 From 0080b6b1da5f181cee32fae7bb5166ce65165374 Mon Sep 17 00:00:00 2001 From: Azka Nathan Date: Fri, 29 Nov 2024 09:53:07 +0700 Subject: cr note product promotion --- indoteknik_custom/models/product_template.py | 2 ++ indoteknik_custom/models/promotion/sale_order.py | 11 ++++++----- 2 files changed, 8 insertions(+), 5 deletions(-) (limited to 'indoteknik_custom/models') diff --git a/indoteknik_custom/models/product_template.py b/indoteknik_custom/models/product_template.py index 25473ab8..2e80beec 100755 --- a/indoteknik_custom/models/product_template.py +++ b/indoteknik_custom/models/product_template.py @@ -61,6 +61,7 @@ class ProductTemplate(models.Model): sni = fields.Boolean(string='SNI') tkdn = fields.Boolean(string='TKDN') short_spesification = fields.Char(string='Short Spesification') + merchandise_ok = fields.Boolean(string='Product Promotion') @api.constrains('name', 'internal_reference', 'x_manufacture') def required_public_categ_ids(self): @@ -377,6 +378,7 @@ class ProductProduct(models.Model): max_qty_reorder = fields.Float(string='Max Qty Reorder', compute='_get_max_qty_reordering_rule') qty_rpo = fields.Float(string='Qty RPO', compute='_get_qty_rpo') plafon_qty = fields.Float(string='Max Plafon', compute='_get_plafon_qty_product') + merchandise_ok = fields.Boolean(string='Product Promotion') def _get_clean_website_description(self): for rec in self: diff --git a/indoteknik_custom/models/promotion/sale_order.py b/indoteknik_custom/models/promotion/sale_order.py index be820c6f..1c31d060 100644 --- a/indoteknik_custom/models/promotion/sale_order.py +++ b/indoteknik_custom/models/promotion/sale_order.py @@ -10,11 +10,12 @@ class SaleOrder(models.Model): for promotion in promotions: program_line = self.env['promotion.program.line'].browse(promotion['program_line_id']) for free_product in program_line.free_product_ids: - self.env['sale.order.line'].create({ - 'order_id': self.id, - 'name': "Free Product " + free_product.product_id.display_name, - 'display_type': 'line_note' - }) + if free_product.product_id.merchandise_ok: + self.env['sale.order.line'].create({ + 'order_id': self.id, + 'name': f"Free Product {free_product.product_id.display_name} Quantity ({free_product.qty})", + 'display_type': 'line_note' + }) def apply_promotion_program(self): userdata = { -- cgit v1.2.3