From 475b927a543890639cfef7731ba8617449a423ec Mon Sep 17 00:00:00 2001 From: Azka Nathan Date: Wed, 9 Oct 2024 15:01:30 +0700 Subject: add image small --- indoteknik_custom/models/purchase_order_line.py | 1 + indoteknik_custom/views/purchase_order.xml | 3 +++ 2 files changed, 4 insertions(+) diff --git a/indoteknik_custom/models/purchase_order_line.py b/indoteknik_custom/models/purchase_order_line.py index 7af84b48..fa300c67 100755 --- a/indoteknik_custom/models/purchase_order_line.py +++ b/indoteknik_custom/models/purchase_order_line.py @@ -37,6 +37,7 @@ class PurchaseOrderLine(models.Model): is_ltc = fields.Boolean(string='Sudah di LTC', default=False, help='centang ini jika barang sudah di LTC') note = fields.Char(string='Note') sale_automatic_id = fields.Many2one('sale.order', string='SO') + image_small = fields.Binary("Product Image", related="product_id.image_1920") qty_reserved = fields.Float(string='Qty Reserved', compute='_compute_qty_reserved') delete_line = fields.Boolean(string='Delete', default=False, help='centang ini jika anda ingin menghapus line ini') diff --git a/indoteknik_custom/views/purchase_order.xml b/indoteknik_custom/views/purchase_order.xml index f6e5a1a4..0db378f0 100755 --- a/indoteknik_custom/views/purchase_order.xml +++ b/indoteknik_custom/views/purchase_order.xml @@ -69,6 +69,9 @@ + + + -- cgit v1.2.3 From 48a3d602e65f4aac6a23b356aa89ce8e37a591ff Mon Sep 17 00:00:00 2001 From: Azka Nathan Date: Wed, 9 Oct 2024 17:13:07 +0700 Subject: cr po --- indoteknik_custom/views/purchase_order.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/indoteknik_custom/views/purchase_order.xml b/indoteknik_custom/views/purchase_order.xml index 0db378f0..4ca3cd84 100755 --- a/indoteknik_custom/views/purchase_order.xml +++ b/indoteknik_custom/views/purchase_order.xml @@ -45,7 +45,7 @@ - + @@ -67,7 +67,7 @@ - + -- cgit v1.2.3 From bf80d91dd74549db76edc0c3df3221bb7afc7564 Mon Sep 17 00:00:00 2001 From: Azka Nathan Date: Thu, 10 Oct 2024 09:19:21 +0700 Subject: cr image small po --- indoteknik_custom/views/purchase_order.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/indoteknik_custom/views/purchase_order.xml b/indoteknik_custom/views/purchase_order.xml index 4ca3cd84..f2aec143 100755 --- a/indoteknik_custom/views/purchase_order.xml +++ b/indoteknik_custom/views/purchase_order.xml @@ -70,7 +70,7 @@ - + -- cgit v1.2.3 From 698cb0618c8bc90a02aeaa5ceb35818b26c71324 Mon Sep 17 00:00:00 2001 From: it-fixcomart Date: Thu, 10 Oct 2024 09:20:09 +0700 Subject: update ready stock --- indoteknik_custom/models/solr/product_product.py | 3 +-- indoteknik_custom/models/solr/product_template.py | 3 +-- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/indoteknik_custom/models/solr/product_product.py b/indoteknik_custom/models/solr/product_product.py index df20cc4b..7c10a910 100644 --- a/indoteknik_custom/models/solr/product_product.py +++ b/indoteknik_custom/models/solr/product_product.py @@ -52,10 +52,9 @@ class ProductProduct(models.Model): stock_quant = self.env['stock.quant'].search([ ('product_id', 'in', variant.product_variant_ids.ids), ('location_id', 'in', target_locations), - ('quantity', '>', 0) ]) - is_in_bu = bool(stock_quant) + is_in_bu = any(quant.available_quantity > 0 for quant in stock_quant) document = solr_model.get_doc('variants', variant.id) diff --git a/indoteknik_custom/models/solr/product_template.py b/indoteknik_custom/models/solr/product_template.py index 70246ba3..029e0956 100644 --- a/indoteknik_custom/models/solr/product_template.py +++ b/indoteknik_custom/models/solr/product_template.py @@ -75,10 +75,9 @@ class ProductTemplate(models.Model): stock_quant = self.env['stock.quant'].search([ ('product_id', 'in', template.product_variant_ids.ids), ('location_id', 'in', target_locations), - ('quantity', '>', 0) ]) - is_in_bu = bool(stock_quant) + is_in_bu = any(quant.available_quantity > 0 for quant in stock_quant) cleaned_desc = BeautifulSoup(template.website_description or '', "html.parser").get_text() website_description = template.website_description if cleaned_desc else '' -- cgit v1.2.3 From cfe3ab19b4c578ceda20f55e86bc901bbd383da5 Mon Sep 17 00:00:00 2001 From: Azka Nathan Date: Thu, 10 Oct 2024 09:33:35 +0700 Subject: cr image small po --- indoteknik_custom/views/purchase_order.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/indoteknik_custom/views/purchase_order.xml b/indoteknik_custom/views/purchase_order.xml index f2aec143..346100ae 100755 --- a/indoteknik_custom/views/purchase_order.xml +++ b/indoteknik_custom/views/purchase_order.xml @@ -70,7 +70,7 @@ - + -- cgit v1.2.3 From 7153f047a6c9e98a1a016a6e08379f495071c9a1 Mon Sep 17 00:00:00 2001 From: Azka Nathan Date: Thu, 10 Oct 2024 09:45:23 +0700 Subject: add approve_by po --- indoteknik_custom/models/purchase_order.py | 2 ++ indoteknik_custom/views/purchase_order.xml | 1 + 2 files changed, 3 insertions(+) diff --git a/indoteknik_custom/models/purchase_order.py b/indoteknik_custom/models/purchase_order.py index 08408506..12eeb5c4 100755 --- a/indoteknik_custom/models/purchase_order.py +++ b/indoteknik_custom/models/purchase_order.py @@ -70,6 +70,7 @@ class PurchaseOrder(models.Model): bills_dp_id = fields.Many2one('account.move', string='Bills DP') grand_total = fields.Monetary(string='Grand Total', help='Amount total + amount delivery', compute='_compute_grand_total') total_margin_match = fields.Float(string='Total Margin Match', compute='_compute_total_margin_match') + approve_by = fields.Many2one('res.users', string='Approve By') def _compute_total_margin_match(self): for purchase in self: @@ -541,6 +542,7 @@ class PurchaseOrder(models.Model): self.po_status = 'menunggu' self.calculate_line_no() + self.approve_by = self.env.user.id # override date planned added with two days leadtime = self.partner_id.leadtime diff --git a/indoteknik_custom/views/purchase_order.xml b/indoteknik_custom/views/purchase_order.xml index 346100ae..1702db5d 100755 --- a/indoteknik_custom/views/purchase_order.xml +++ b/indoteknik_custom/views/purchase_order.xml @@ -41,6 +41,7 @@ + -- cgit v1.2.3 From 6b2cb9b1078b48aa97f8f06613eca9dc121a431e Mon Sep 17 00:00:00 2001 From: it-fixcomart Date: Thu, 10 Oct 2024 09:47:39 +0700 Subject: ubah code untuk handle jika tidak ada category id --- indoteknik_custom/models/solr/product_template.py | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/indoteknik_custom/models/solr/product_template.py b/indoteknik_custom/models/solr/product_template.py index 029e0956..1d54cc9b 100644 --- a/indoteknik_custom/models/solr/product_template.py +++ b/indoteknik_custom/models/solr/product_template.py @@ -158,10 +158,14 @@ class ProductTemplate(models.Model): traverse_category(category.parent_id.id) # Start traversal from the initial category - traverse_category(category_id) - - # Reverse the list to get the hierarchy from top level to the current level - return list(reversed(category_ids)) + if category_id: # Check if category_id is not an empty value + traverse_category(category_id) + + # Reverse the list to get the hierarchy from top level to the current level + return list(reversed(category_ids)) + else: + # If category_id is empty, return an empty list + return [] def _sync_price_to_solr(self): solr_model = self.env['apache.solr'] -- cgit v1.2.3 From 26c0d5bef2a175764a6df6eac9a92d89f99d57d7 Mon Sep 17 00:00:00 2001 From: Azka Nathan Date: Thu, 10 Oct 2024 10:39:19 +0700 Subject: add clean description --- indoteknik_custom/models/product_template.py | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/indoteknik_custom/models/product_template.py b/indoteknik_custom/models/product_template.py index 031d1b5b..af7f98cd 100755 --- a/indoteknik_custom/models/product_template.py +++ b/indoteknik_custom/models/product_template.py @@ -5,6 +5,7 @@ import logging import requests import json import re +from bs4 import BeautifulSoup _logger = logging.getLogger(__name__) @@ -363,6 +364,7 @@ class ProductProduct(models.Model): specification = fields.Char(string='Specification') material = fields.Char(string='Material') qty_onhand_bandengan = fields.Float(string='Onhand BU', compute='_get_qty_onhand_bandengan') + clean_website_description = fields.Char(string='Clean Website Description', compute='_get_clean_website_description') qty_incoming_bandengan = fields.Float(string='Incoming BU', compute='_get_qty_incoming_bandengan') qty_outgoing_bandengan = fields.Float(string='Outgoing BU', compute='_get_qty_outgoing_bandengan') qty_available_bandengan = fields.Float(string='Available BU', compute='_get_qty_available_bandengan') @@ -373,6 +375,11 @@ class ProductProduct(models.Model): qty_sold = fields.Float(string='Sold Quantity', compute='_get_qty_sold') short_spesification = fields.Char(string='Short Spesification') + def _get_clean_website_description(self): + for rec in self: + cleaned_desc = BeautifulSoup(self.website_description or '', "html.parser").get_text() + rec.clean_website_description = cleaned_desc + @api.constrains('name', 'internal_reference', 'x_manufacture') def required_public_categ_ids(self): for rec in self: -- cgit v1.2.3 From 884c8725dc941fc5e74d57959c9d486395bffebc Mon Sep 17 00:00:00 2001 From: Azka Nathan Date: Thu, 10 Oct 2024 10:44:50 +0700 Subject: cr po --- indoteknik_custom/views/product_template.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/indoteknik_custom/views/product_template.xml b/indoteknik_custom/views/product_template.xml index a77b99de..8fae5038 100755 --- a/indoteknik_custom/views/product_template.xml +++ b/indoteknik_custom/views/product_template.xml @@ -20,6 +20,7 @@ + 0 -- cgit v1.2.3 From 3990589120359d4407c65924485098e9c1516acc Mon Sep 17 00:00:00 2001 From: Azka Nathan Date: Thu, 10 Oct 2024 10:46:14 +0700 Subject: fix bug --- indoteknik_custom/views/product_template.xml | 1 - 1 file changed, 1 deletion(-) diff --git a/indoteknik_custom/views/product_template.xml b/indoteknik_custom/views/product_template.xml index 8fae5038..a77b99de 100755 --- a/indoteknik_custom/views/product_template.xml +++ b/indoteknik_custom/views/product_template.xml @@ -20,7 +20,6 @@ - 0 -- cgit v1.2.3 From 811d37923e235e12b2032e2acf93fc69c2a350a7 Mon Sep 17 00:00:00 2001 From: Azka Nathan Date: Thu, 10 Oct 2024 10:58:46 +0700 Subject: cr product variant --- indoteknik_custom/views/product_template.xml | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/indoteknik_custom/views/product_template.xml b/indoteknik_custom/views/product_template.xml index a77b99de..5a509ebd 100755 --- a/indoteknik_custom/views/product_template.xml +++ b/indoteknik_custom/views/product_template.xml @@ -39,12 +39,23 @@ - + - + + + Product Template + product.product + + + + + + + + product.template.search.inherit product.template -- cgit v1.2.3 From ed9c28ad7062704cb9f124c7ba7b78eebe2695dc Mon Sep 17 00:00:00 2001 From: Azka Nathan Date: Thu, 10 Oct 2024 11:24:01 +0700 Subject: cr line po --- indoteknik_custom/models/purchase_order_line.py | 9 ++++++++- indoteknik_custom/views/purchase_order.xml | 1 + 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/indoteknik_custom/models/purchase_order_line.py b/indoteknik_custom/models/purchase_order_line.py index fa300c67..9e7d7e81 100755 --- a/indoteknik_custom/models/purchase_order_line.py +++ b/indoteknik_custom/models/purchase_order_line.py @@ -3,6 +3,7 @@ from odoo.exceptions import AccessError, UserError, ValidationError from odoo.tools import DEFAULT_SERVER_DATETIME_FORMAT import logging from dateutil.relativedelta import relativedelta +from bs4 import BeautifulSoup from datetime import datetime _logger = logging.getLogger(__name__) @@ -38,11 +39,17 @@ class PurchaseOrderLine(models.Model): note = fields.Char(string='Note') sale_automatic_id = fields.Many2one('sale.order', string='SO') image_small = fields.Binary("Product Image", related="product_id.image_1920") - + clean_website_description_product = fields.Char(string='Clean Website Description Product', compute='_get_clean_website_description_product') qty_reserved = fields.Float(string='Qty Reserved', compute='_compute_qty_reserved') delete_line = fields.Boolean(string='Delete', default=False, help='centang ini jika anda ingin menghapus line ini') is_edit_product_qty = fields.Boolean(string='Is Edit Product Qty', compute='_compute_is_edit_product_qty') + def _get_clean_website_description_product(self): + for line in self: + description = line.product_id.website_description + description_clean = BeautifulSoup(description or '', "html.parser").get_text() + line.clean_website_description_product = description_clean + def _prepare_stock_move_vals(self, picking, price_unit, product_uom_qty, product_uom): self.ensure_one() product = self.product_id.with_context(lang=self.order_id.dest_address_id.lang or self.env.user.lang) diff --git a/indoteknik_custom/views/purchase_order.xml b/indoteknik_custom/views/purchase_order.xml index 1702db5d..3e609f15 100755 --- a/indoteknik_custom/views/purchase_order.xml +++ b/indoteknik_custom/views/purchase_order.xml @@ -65,6 +65,7 @@ + -- cgit v1.2.3 From 1cdb32893afe7b8360f488f58d46f71745bf7691 Mon Sep 17 00:00:00 2001 From: Azka Nathan Date: Thu, 10 Oct 2024 15:47:23 +0700 Subject: fix purchasing job --- indoteknik_custom/models/purchasing_job.py | 87 +++++++++--------------------- 1 file changed, 25 insertions(+), 62 deletions(-) diff --git a/indoteknik_custom/models/purchasing_job.py b/indoteknik_custom/models/purchasing_job.py index 6e4f239d..0c34fc3c 100644 --- a/indoteknik_custom/models/purchasing_job.py +++ b/indoteknik_custom/models/purchasing_job.py @@ -43,73 +43,36 @@ class PurchasingJob(models.Model): def init(self): tools.drop_view_if_exists(self.env.cr, self._table) self.env.cr.execute(""" - CREATE OR REPLACE VIEW %s AS ( - WITH latest_purchase_orders AS ( - SELECT - pol.product_id, - po.user_id, - ROW_NUMBER() OVER (PARTITION BY po.partner_id ORDER BY po.create_date DESC) AS order_rank - FROM purchase_order po - RIGHT JOIN purchase_order_line pol ON pol.order_id = po.id - LEFT JOIN res_partner rp ON rp.id = po.partner_id - ), - random_user_ids AS ( - SELECT DISTINCT - CASE - WHEN vendor_id = 5571 THEN 27 - WHEN vendor_id = 9688 THEN 397 - WHEN vendor_id = 35475 THEN 397 - WHEN vendor_id = 29712 THEN 397 - ELSE (CASE WHEN random() < 0.5 THEN 397 ELSE 1036 END) - END AS user_id, - vendor_id - FROM ( - SELECT - sol.vendor_id - FROM v_sales_outstanding vso - LEFT JOIN sale_order_line sol ON sol.id = vso.sale_line_id - ) AS sub - WHERE sub.vendor_id IS NOT NULL - ) - SELECT - pmp.product_id AS id, - pmp.product_id, - sub.vendor_id, - pmp.brand, - pmp.item_code, - pmp.product, - MAX(pmp.onhand) AS onhand, - MAX(pmp.incoming) AS incoming, - MAX(pmp.outgoing) AS outgoing, - pmp.action, - MAX(pjs.status_apo) AS status_apo, - MAX(pjs.note) AS note, - ru.user_id AS purchase_representative_id - FROM v_procurement_monitoring_by_product pmp + CREATE OR REPLACE VIEW %s + AS SELECT pmp.product_id AS id, + pmp.product_id, + sub.vendor_id, + pmp.brand, + pmp.item_code, + pmp.product, + max(pmp.onhand) AS onhand, + max(pmp.incoming) AS incoming, + max(pmp.outgoing) AS outgoing, + pmp.action, + max(pjs.status_apo::text) AS status_apo, + max(pjs.note::text) AS note, + CASE + WHEN sub.vendor_id = 5571 THEN 27 + WHEN sub.vendor_id = 9688 THEN 397 + WHEN sub.vendor_id = 35475 THEN 397 + WHEN sub.vendor_id = 29712 THEN 397 + ELSE 1036 + END AS purchase_representative_id + FROM v_procurement_monitoring_by_product pmp LEFT JOIN purchasing_job_state pjs ON pjs.purchasing_job_id = pmp.product_id - LEFT JOIN ( - SELECT - vso.product_id, + LEFT JOIN ( SELECT vso.product_id, sol.vendor_id FROM v_sales_outstanding vso - LEFT JOIN sale_order_line sol ON sol.id = vso.sale_line_id - ) AS sub ON sub.product_id = pmp.product_id - LEFT JOIN latest_purchase_orders po ON po.product_id = pmp.product_id - LEFT JOIN random_user_ids ru ON ru.vendor_id = sub.vendor_id OR (ru.vendor_id IS NULL AND sub.vendor_id != 9688) - WHERE pmp.action = 'kurang' - AND sub.vendor_id IS NOT NULL - GROUP BY - pmp.product_id, - pmp.brand, - pmp.item_code, - pmp.product, - pmp.action, - sub.vendor_id, - ru.user_id - ) + LEFT JOIN sale_order_line sol ON sol.id = vso.sale_line_id) sub ON sub.product_id = pmp.product_id + WHERE pmp.action = 'kurang'::text AND sub.vendor_id IS NOT NULL + GROUP BY pmp.product_id, pmp.brand, pmp.item_code, pmp.product, pmp.action, sub.vendor_id; """ % self._table) - def open_form_multi_generate_request_po(self): action = self.env['ir.actions.act_window']._for_xml_id('indoteknik_custom.action_purchasing_job_multi_update') action['context'] = { -- cgit v1.2.3 From c795b3508756c625a545e35c7329ff705a3c3c9d Mon Sep 17 00:00:00 2001 From: stephanchrst Date: Fri, 11 Oct 2024 09:02:17 +0700 Subject: add distinct in purchasing job while join sale order --- indoteknik_custom/models/purchasing_job.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/indoteknik_custom/models/purchasing_job.py b/indoteknik_custom/models/purchasing_job.py index 0c34fc3c..756b1079 100644 --- a/indoteknik_custom/models/purchasing_job.py +++ b/indoteknik_custom/models/purchasing_job.py @@ -65,7 +65,7 @@ class PurchasingJob(models.Model): END AS purchase_representative_id FROM v_procurement_monitoring_by_product pmp LEFT JOIN purchasing_job_state pjs ON pjs.purchasing_job_id = pmp.product_id - LEFT JOIN ( SELECT vso.product_id, + LEFT JOIN ( SELECT distinct vso.product_id, sol.vendor_id FROM v_sales_outstanding vso LEFT JOIN sale_order_line sol ON sol.id = vso.sale_line_id) sub ON sub.product_id = pmp.product_id -- cgit v1.2.3 From b8edd5b930595fdc415d94c0f0d09fa5ecbe43ba Mon Sep 17 00:00:00 2001 From: stephanchrst Date: Fri, 11 Oct 2024 09:05:53 +0700 Subject: add max and group in purchasing job --- indoteknik_custom/models/purchasing_job.py | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/indoteknik_custom/models/purchasing_job.py b/indoteknik_custom/models/purchasing_job.py index 756b1079..bf5ed8c4 100644 --- a/indoteknik_custom/models/purchasing_job.py +++ b/indoteknik_custom/models/purchasing_job.py @@ -65,10 +65,13 @@ class PurchasingJob(models.Model): END AS purchase_representative_id FROM v_procurement_monitoring_by_product pmp LEFT JOIN purchasing_job_state pjs ON pjs.purchasing_job_id = pmp.product_id - LEFT JOIN ( SELECT distinct vso.product_id, - sol.vendor_id + LEFT JOIN ( + SELECT vso.product_id, + max(sol.vendor_id) as vendor_id FROM v_sales_outstanding vso - LEFT JOIN sale_order_line sol ON sol.id = vso.sale_line_id) sub ON sub.product_id = pmp.product_id + LEFT JOIN sale_order_line sol ON sol.id = vso.sale_line_id + group by vso.product_id + ) sub ON sub.product_id = pmp.product_id WHERE pmp.action = 'kurang'::text AND sub.vendor_id IS NOT NULL GROUP BY pmp.product_id, pmp.brand, pmp.item_code, pmp.product, pmp.action, sub.vendor_id; """ % self._table) -- cgit v1.2.3 From 58892a2e250d317e03ceddfb9517988525fc1f64 Mon Sep 17 00:00:00 2001 From: Azka Nathan Date: Fri, 11 Oct 2024 10:52:56 +0700 Subject: fix bug md vendor --- indoteknik_custom/models/sale_order_line.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/indoteknik_custom/models/sale_order_line.py b/indoteknik_custom/models/sale_order_line.py index 59ac1ad4..5e01067a 100644 --- a/indoteknik_custom/models/sale_order_line.py +++ b/indoteknik_custom/models/sale_order_line.py @@ -251,14 +251,14 @@ class SaleOrderLine(models.Model): # purchase_price = self.env['purchase.pricelist'].search( # query, limit=1, order='count_trx_po desc, count_trx_po_vendor desc') price, taxes, vendor_id = self._get_purchase_price(line.product_id) + line.vendor_md_id = vendor_id line.vendor_id = vendor_id - line.md_vendor_id = vendor_id line.margin_md = line.item_percent_margin line.tax_id = line.order_id.sales_tax_id # price, taxes = line._get_valid_purchase_price(purchase_price) line.purchase_price_md = price line.purchase_price = price - line.purchase_tax_id = taxes + line.purchase_tax_id = taxes attribute_values = line.product_id.product_template_attribute_value_ids.mapped('name') attribute_values_str = ', '.join(attribute_values) if attribute_values else '' -- cgit v1.2.3 From d4e9baf79312142aa19ac7c159052ada8bc215d7 Mon Sep 17 00:00:00 2001 From: Azka Nathan Date: Fri, 11 Oct 2024 11:16:33 +0700 Subject: test user cart --- indoteknik_custom/models/website_user_cart.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/indoteknik_custom/models/website_user_cart.py b/indoteknik_custom/models/website_user_cart.py index 76b192c5..26e217cb 100644 --- a/indoteknik_custom/models/website_user_cart.py +++ b/indoteknik_custom/models/website_user_cart.py @@ -173,11 +173,11 @@ class WebsiteUserCart(models.Model): } return result - def action_mail_reminder_to_checkout(self, limit=250): + def action_mail_reminder_to_checkout(self, limit=200): user_ids = self.search([('is_reminder', '=', False)]).mapped('user_id')[:limit] for user in user_ids: - latest_cart = self.search([('user_id', '=', user.id), ('is_reminder', '=', False)], order='create_date desc', limit=1) + latest_cart = self.search([('user_id', '=', user.id)], order='create_date desc', limit=1) carts_to_remind = self.search([('user_id', '=', user.id)]) -- cgit v1.2.3 From 24b4e09c5f77d0f6d2f179693b90d924e2107ee6 Mon Sep 17 00:00:00 2001 From: Azka Nathan Date: Fri, 11 Oct 2024 11:20:14 +0700 Subject: crr revisi po --- indoteknik_custom/models/purchase_order.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/indoteknik_custom/models/purchase_order.py b/indoteknik_custom/models/purchase_order.py index 12eeb5c4..340df49e 100755 --- a/indoteknik_custom/models/purchase_order.py +++ b/indoteknik_custom/models/purchase_order.py @@ -534,7 +534,7 @@ class PurchaseOrder(models.Model): self._send_mail() if self.revisi_po: - delta_time = current_time - timedelta(days=2) + delta_time = current_time - timedelta(days=1) delta_time = delta_time.strftime('%Y-%m-%d %H:%M:%S') self.date_approve = delta_time -- cgit v1.2.3 From 49b8f17c48a04b28a54608cf45367266f35cf420 Mon Sep 17 00:00:00 2001 From: it-fixcomart Date: Fri, 11 Oct 2024 11:21:52 +0700 Subject: add dokumentasi driver --- indoteknik_api/controllers/api_v1/stock_picking.py | 23 +++++++++++++++++++++- indoteknik_custom/models/stock_picking.py | 2 ++ indoteknik_custom/views/stock_picking.xml | 2 ++ 3 files changed, 26 insertions(+), 1 deletion(-) diff --git a/indoteknik_api/controllers/api_v1/stock_picking.py b/indoteknik_api/controllers/api_v1/stock_picking.py index 8b941c16..c8bc9a7e 100644 --- a/indoteknik_api/controllers/api_v1/stock_picking.py +++ b/indoteknik_api/controllers/api_v1/stock_picking.py @@ -110,4 +110,25 @@ class StockPicking(controller.Controller): if not picking: return self.response(None) - return self.response(picking.get_tracking_detail()) \ No newline at end of file + return self.response(picking.get_tracking_detail()) + + @http.route(prefix + 'stock-picking//documentation', auth='public', methods=['PUT', 'OPTIONS'], csrf=False) + @controller.Controller.must_authorized() + def write_partner_stock_picking_documentation(self, **kw): + picking_code = int(kw.get('picking_code', 0)) + sj_document = kw.get('sj_document', False) + paket_document = kw.get('paket_document', False) + + params = {'sj_documentation': sj_document, + 'paket_documentation': paket_document + } + + picking_data = request.env['stock.picking'].search([('picking_code', '=', picking_code)], limit=1) + + if not picking_data: + return self.response(code=404, description='picking not found') + picking_data.write(params) + + return self.response({ + 'name': picking_data.name + }) \ No newline at end of file diff --git a/indoteknik_custom/models/stock_picking.py b/indoteknik_custom/models/stock_picking.py index 14190474..066ce238 100644 --- a/indoteknik_custom/models/stock_picking.py +++ b/indoteknik_custom/models/stock_picking.py @@ -53,6 +53,8 @@ class StockPicking(models.Model): readonly=True, copy=False ) + sj_documentation = fields.Binary(string="Dokumentasi Surat Jalan", ) + paket_documentation = fields.Binary(string="Dokumentasi Paket", ) approval_status = fields.Selection([ ('pengajuan1', 'Approval Accounting'), diff --git a/indoteknik_custom/views/stock_picking.xml b/indoteknik_custom/views/stock_picking.xml index 899d29eb..d47c1051 100644 --- a/indoteknik_custom/views/stock_picking.xml +++ b/indoteknik_custom/views/stock_picking.xml @@ -129,6 +129,8 @@ + + -- cgit v1.2.3 From d7f4569c5d2dcda1316ca4ef37fed53f467df9df Mon Sep 17 00:00:00 2001 From: stephanchrst Date: Tue, 15 Oct 2024 09:10:06 +0700 Subject: initial commit generate url --- indoteknik_custom/models/__init__.py | 1 + indoteknik_custom/models/find_page.py | 44 ++++++++++++++++++++++++++ indoteknik_custom/security/ir.model.access.csv | 2 ++ 3 files changed, 47 insertions(+) create mode 100644 indoteknik_custom/models/find_page.py diff --git a/indoteknik_custom/models/__init__.py b/indoteknik_custom/models/__init__.py index 7b41a5fe..e62fbb4a 100755 --- a/indoteknik_custom/models/__init__.py +++ b/indoteknik_custom/models/__init__.py @@ -130,3 +130,4 @@ from . import account_tax from . import approval_unreserve from . import vendor_approval from . import partner +from . import find_page diff --git a/indoteknik_custom/models/find_page.py b/indoteknik_custom/models/find_page.py new file mode 100644 index 00000000..b81b3845 --- /dev/null +++ b/indoteknik_custom/models/find_page.py @@ -0,0 +1,44 @@ +from odoo import fields, models, api, tools, _ +import logging + +_logger = logging.getLogger(__name__) + + +class BrandProductCategory(models.Model): + _name = 'v.brand.product.category' + _auto = False + _rec_name = 'brand_id' + brand_id = fields.Many2one('x_manufactures', string='Brand') + category_id = fields.Many2one('product.public.category', string='Category') + + def init(self): + tools.drop_view_if_exists(self.env.cr, self._table) + self.env.cr.execute(""" + CREATE OR REPLACE VIEW %s + AS select row_number() over(order by pt.x_manufacture) as id, + pt.x_manufacture as brand_id, + ppcptr.product_public_category_id as category_id + from product_template pt + join product_public_category_product_template_rel ppcptr on ppcptr.product_template_id = pt.id + join x_manufactures xm on xm.id = pt.x_manufacture + group by x_manufacture, ppcptr.product_public_category_id + """ % self._table) + + +class FindPage(models.Model): + _name = 'web.find.page' + + brand_id = fields.Many2one('x_manufactures', string='Brand') + category_id = fields.Many2one('product.public.category', string='Category', help='Bisa semua level Category') + url = fields.Char(string='Url') + + def _generate_url(self): + categories = self.env['v.brand.product.category'].search([]) + count = 0 + for category in categories: + print(category.brand_id.x_name+' '+category.category_id.name) + count += 1 + print(count) + + def _generate_url_parent(self): + print(1) diff --git a/indoteknik_custom/security/ir.model.access.csv b/indoteknik_custom/security/ir.model.access.csv index 408aae55..553047e6 100755 --- a/indoteknik_custom/security/ir.model.access.csv +++ b/indoteknik_custom/security/ir.model.access.csv @@ -141,3 +141,5 @@ access_approval_unreserve_line,access.approval.unreserve.line,model_approval_unr access_vendor_approval,access.vendor.approval,model_vendor_approval,,1,1,1,1 access_vendor_approval_line,access.vendor.approval.line,model_vendor_approval_line,,1,1,1,1 access_vit_kota,access.vit.kota,model_vit_kota,,1,1,1,1 +access_v_brand_product_category,access.v.brand.product.category,model_v_brand_product_category,,1,1,1,1 +access_web_find_page,access.web.find.page,model_web_find_page,,1,1,1,1 -- cgit v1.2.3 From 80433401aeba163a03f0f30902332331338b005f Mon Sep 17 00:00:00 2001 From: stephanchrst Date: Tue, 15 Oct 2024 09:12:20 +0700 Subject: remove set npwp and sppkp while confirm sales order for disruption --- indoteknik_custom/models/sale_order.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/indoteknik_custom/models/sale_order.py b/indoteknik_custom/models/sale_order.py index c1c2c267..2e0b5775 100755 --- a/indoteknik_custom/models/sale_order.py +++ b/indoteknik_custom/models/sale_order.py @@ -943,7 +943,7 @@ class SaleOrder(models.Model): return self._create_approval_notification('Sales Manager') order.approval_status = 'approved' - order._set_sppkp_npwp_contact() + # order._set_sppkp_npwp_contact() order.calculate_line_no() order.send_notif_to_salesperson() # order.order_line.get_reserved_from() -- cgit v1.2.3 From 1833d42fe880ca3c63630c46d1b2e4f19e89c9ab Mon Sep 17 00:00:00 2001 From: stephanchrst Date: Tue, 15 Oct 2024 09:20:19 +0700 Subject: disable update if not null in npwp sppkp contact while confirm so --- indoteknik_custom/models/sale_order.py | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/indoteknik_custom/models/sale_order.py b/indoteknik_custom/models/sale_order.py index 2e0b5775..e6382cd9 100755 --- a/indoteknik_custom/models/sale_order.py +++ b/indoteknik_custom/models/sale_order.py @@ -943,7 +943,7 @@ class SaleOrder(models.Model): return self._create_approval_notification('Sales Manager') order.approval_status = 'approved' - # order._set_sppkp_npwp_contact() + order._set_sppkp_npwp_contact() order.calculate_line_no() order.send_notif_to_salesperson() # order.order_line.get_reserved_from() @@ -1024,11 +1024,20 @@ class SaleOrder(models.Model): def _set_sppkp_npwp_contact(self): partner = self.partner_id.parent_id or self.partner_id - if not partner.sppkp or not partner.npwp or not partner.email or partner.customer_type: - partner.customer_type = self.customer_type - partner.npwp = self.npwp + if not partner.sppkp: partner.sppkp = self.sppkp + if not partner.npwp: + partner.npwp = self.npwp + if not partner.email: partner.email = self.email + if not partner.customer_type: + partner.customer_type = self.customer_type + + # if not partner.sppkp or not partner.npwp or not partner.email or partner.customer_type: + # partner.customer_type = self.customer_type + # partner.npwp = self.npwp + # partner.sppkp = self.sppkp + # partner.email = self.email def _compute_total_margin(self): for order in self: -- cgit v1.2.3 From 387fe06b8d8d212172a1ef0a61ad2657f618ec1b Mon Sep 17 00:00:00 2001 From: stephanchrst Date: Tue, 15 Oct 2024 11:33:36 +0700 Subject: scheduled action for pipeline --- indoteknik_custom/models/crm_lead.py | 71 +++++++++++++++++++++++++++++++++++- 1 file changed, 70 insertions(+), 1 deletion(-) diff --git a/indoteknik_custom/models/crm_lead.py b/indoteknik_custom/models/crm_lead.py index 9ffd607c..b0d3430c 100755 --- a/indoteknik_custom/models/crm_lead.py +++ b/indoteknik_custom/models/crm_lead.py @@ -2,6 +2,7 @@ from odoo import fields, models, api import logging import random from odoo.exceptions import AccessError, UserError, ValidationError +from datetime import datetime, timedelta _logger = logging.getLogger(__name__) @@ -97,4 +98,72 @@ class CrmLead(models.Model): lead.user_id = salesperson_id - + def _cancel_pipeline(self, delta=48): + # Get the current time + current_time = datetime.now() + + # Calculate the time 24 hours ago + time_48_hours_ago = current_time - timedelta(hours=delta) + + # Define the allowed states + allowed_states = ['cancel'] + + # Search for sale orders with date_order greater than 24 hours ago and opportunity_id is null + orders = self.env['sale.order'].search([ + ('write_date', '>=', time_48_hours_ago), + ('opportunity_id', '!=', False), + ('state', 'in', allowed_states) + ]) + for order in orders: + order.opportunity_id.stage_id = 7 + _logger.info('cancel order stage pipeline %s' % order.id) + + def _convert_to_pipeline(self, delta=48): + # Get the current time + current_time = datetime.now() + + # Calculate the time 24 hours ago + time_48_hours_ago = current_time - timedelta(hours=delta) + + # Define the allowed states + allowed_states = ['draft', 'done', 'sale', 'sent', 'cancel'] + + # Search for sale orders with date_order greater than 24 hours ago and opportunity_id is null + orders = self.env['sale.order'].search([ + ('write_date', '>=', time_48_hours_ago), + ('opportunity_id', '=', False), + ('state', 'in', allowed_states) + ]) + # stage + # 1 potensi baru, 2 proses quotation, 3 proses lain visit, 4 proses berhasil, 5 proses negosiasi, 7 tidak terpakai / gagal + for order in orders: + # stage_id = 2 + if order.state == 'sale' or order.state == 'done': + stage_id = 4 + elif order.state == 'sent': + stage_id = 5 + elif order.state == 'cancel': + stage_id = 7 + else: + stage_id = 2 + crm_lead = self.env['crm.lead'].create([{ + 'email_normalized': order.email, + 'name': order.name, + 'user_id': order.user_id.id, + 'company_id': 1, + 'type': 'opportunity', + 'priority': 0, + 'team_id': order.team_id.id, + 'stage_id': stage_id, + 'expected_revenue': order.amount_untaxed, + 'partner_id': order.partner_id.parent_id.id or order.partner_id.id, + 'contact_name': order.partner_id.name, + 'partner_name': order.partner_id.parent_id.name or order.partner_id.name, + 'phone': order.partner_id.mobile, + 'street': order.partner_id.street, + 'street2': order.partner_id.street2, + 'zip': order.partner_id.zip, + 'order_id': order.id + }]) + order.opportunity_id = crm_lead.id + _logger.info('convert order to opportunity %s' % crm_lead.id) -- cgit v1.2.3 From 0b5623adc1c6d6f5ef7a4d68f42bcf2f524107c1 Mon Sep 17 00:00:00 2001 From: it-fixcomart Date: Tue, 15 Oct 2024 12:05:53 +0700 Subject: update code ambil data stock mandatory ke stock awailable --- indoteknik_api/controllers/api_v1/product.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/indoteknik_api/controllers/api_v1/product.py b/indoteknik_api/controllers/api_v1/product.py index e779e623..8fe48932 100644 --- a/indoteknik_api/controllers/api_v1/product.py +++ b/indoteknik_api/controllers/api_v1/product.py @@ -73,7 +73,10 @@ class Product(controller.Controller): total_adem = qty_altama if qty_available > 0: - qty = qty_available + total_adem + total_excell + qty = qty_available + sla_date = '1 Hari' + elif qty_available > 0 and qty_altama > 0: + qty = qty_available sla_date = '1 Hari' elif qty_altama > 0 or qty_vendor > 0: qty = total_adem if qty_altama > 0 else total_excell -- cgit v1.2.3 From 6ae562de235d0a150db594d93522e2ad3b395aa8 Mon Sep 17 00:00:00 2001 From: stephanchrst Date: Tue, 15 Oct 2024 14:32:30 +0700 Subject: add limit to pipeline --- indoteknik_custom/models/crm_lead.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/indoteknik_custom/models/crm_lead.py b/indoteknik_custom/models/crm_lead.py index b0d3430c..eac75cb0 100755 --- a/indoteknik_custom/models/crm_lead.py +++ b/indoteknik_custom/models/crm_lead.py @@ -98,7 +98,7 @@ class CrmLead(models.Model): lead.user_id = salesperson_id - def _cancel_pipeline(self, delta=48): + def _cancel_pipeline(self, delta=48, limit=100): # Get the current time current_time = datetime.now() @@ -113,12 +113,12 @@ class CrmLead(models.Model): ('write_date', '>=', time_48_hours_ago), ('opportunity_id', '!=', False), ('state', 'in', allowed_states) - ]) + ], limit=limit) for order in orders: order.opportunity_id.stage_id = 7 _logger.info('cancel order stage pipeline %s' % order.id) - def _convert_to_pipeline(self, delta=48): + def _convert_to_pipeline(self, delta=48, limit=100): # Get the current time current_time = datetime.now() @@ -133,7 +133,7 @@ class CrmLead(models.Model): ('write_date', '>=', time_48_hours_ago), ('opportunity_id', '=', False), ('state', 'in', allowed_states) - ]) + ], limit=limit) # stage # 1 potensi baru, 2 proses quotation, 3 proses lain visit, 4 proses berhasil, 5 proses negosiasi, 7 tidak terpakai / gagal for order in orders: -- cgit v1.2.3 From 02499d14bb9e6cd5063df0ef3ad00e362a99fbde Mon Sep 17 00:00:00 2001 From: it-fixcomart Date: Tue, 15 Oct 2024 14:46:26 +0700 Subject: add 1 nol agar npwp jadi 16 angka --- indoteknik_api/controllers/api_v1/user.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/indoteknik_api/controllers/api_v1/user.py b/indoteknik_api/controllers/api_v1/user.py index c7bfe91a..e4f8b97f 100644 --- a/indoteknik_api/controllers/api_v1/user.py +++ b/indoteknik_api/controllers/api_v1/user.py @@ -248,7 +248,7 @@ class User(controller.Controller): if type_acc == 'individu': user.partner_id.customer_type = 'nonpkp' - user.partner_id.npwp = '0.000.000.0-000.000' + user.partner_id.npwp = '00.000.000.0-000.000' user.partner_id.sppkp = '-' user.partner_id.nama_wajib_pajak = name user.partner_id.user_id = 3222 -- cgit v1.2.3 From 65436a03d40cd31e0111727fe6c84380eba005d5 Mon Sep 17 00:00:00 2001 From: stephanchrst Date: Tue, 15 Oct 2024 15:34:36 +0700 Subject: update pipeline --- indoteknik_custom/models/crm_lead.py | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/indoteknik_custom/models/crm_lead.py b/indoteknik_custom/models/crm_lead.py index eac75cb0..de2bdb12 100755 --- a/indoteknik_custom/models/crm_lead.py +++ b/indoteknik_custom/models/crm_lead.py @@ -98,6 +98,26 @@ class CrmLead(models.Model): lead.user_id = salesperson_id + def _update_pipeline(self, delta=48, limit=100): + # Get the current time + current_time = datetime.now() + + # Calculate the time 24 hours ago + time_48_hours_ago = current_time - timedelta(hours=delta) + + # Define the allowed states + allowed_states = ['sale', 'done'] + + # Search for sale orders with date_order greater than 24 hours ago and opportunity_id is null + orders = self.env['sale.order'].search([ + ('write_date', '>=', time_48_hours_ago), + ('opportunity_id', '!=', False), + ('state', 'in', allowed_states) + ], limit=limit) + for order in orders: + order.opportunity_id.stage_id = 4 + _logger.info('finish order stage pipeline %s' % order.id) + def _cancel_pipeline(self, delta=48, limit=100): # Get the current time current_time = datetime.now() -- cgit v1.2.3 From 29e6aa1d25a7484736399ddbf21dd180ffb2f025 Mon Sep 17 00:00:00 2001 From: Azka Nathan Date: Tue, 15 Oct 2024 15:55:02 +0700 Subject: change permission po form purchasing manager to merchandise --- indoteknik_custom/models/purchase_order.py | 6 +++--- indoteknik_custom/models/report_stock_forecasted.py | 1 - 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/indoteknik_custom/models/purchase_order.py b/indoteknik_custom/models/purchase_order.py index 340df49e..21f3265e 100755 --- a/indoteknik_custom/models/purchase_order.py +++ b/indoteknik_custom/models/purchase_order.py @@ -508,10 +508,10 @@ class PurchaseOrder(models.Model): if self.amount_untaxed >= 50000000 and not self.env.user.has_group('indoteknik_custom.group_role_merchandiser'): raise UserError("Hanya Merchandiser yang bisa approve") - if self.total_percent_margin < self.total_so_percent_margin and not self.env.user.is_purchasing_manager and not self.env.user.is_leader: + if self.total_percent_margin < self.total_so_percent_margin and not self.env.user.has_group('indoteknik_custom.group_role_merchandiser') and not self.env.user.is_leader: raise UserError("Beda Margin dengan Sales, harus approval Manager") if not self.from_apo: - if not self.sale_order_id and not self.env.user.is_purchasing_manager and not self.env.user.is_leader: + if not self.sale_order_id and self.env.user.has_group('indoteknik_custom.group_role_merchandiser') and not self.env.user.is_leader: raise UserError("Tidak ada link dengan SO, harus approval Manager") send_email = False @@ -641,7 +641,7 @@ class PurchaseOrder(models.Model): 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") - if self.env.user.is_leader or self.env.user.is_purchasing_manager: + 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.sale_order_id: raise UserError("Bisa langsung Confirm") diff --git a/indoteknik_custom/models/report_stock_forecasted.py b/indoteknik_custom/models/report_stock_forecasted.py index 5f9427f8..ebdc7d4a 100644 --- a/indoteknik_custom/models/report_stock_forecasted.py +++ b/indoteknik_custom/models/report_stock_forecasted.py @@ -33,7 +33,6 @@ class ReplenishmentReport(models.AbstractModel): 'reserved_from': result, 'qty_fullfillment': quantity, }) - return lines def _calculate_result(self, line): -- cgit v1.2.3 From a3667d8e42b891192a3e86a00ebc3cd07da8877d Mon Sep 17 00:00:00 2001 From: Azka Nathan Date: Wed, 16 Oct 2024 09:33:42 +0700 Subject: remove field md_vendor_id --- indoteknik_custom/models/sale_order_line.py | 2 +- indoteknik_custom/views/sale_order.xml | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/indoteknik_custom/models/sale_order_line.py b/indoteknik_custom/models/sale_order_line.py index 5e01067a..1b7b3ef2 100644 --- a/indoteknik_custom/models/sale_order_line.py +++ b/indoteknik_custom/models/sale_order_line.py @@ -34,7 +34,7 @@ class SaleOrderLine(models.Model): reserved_from = fields.Char(string='Reserved From', copy=False) item_percent_margin_without_deduction = fields.Float('%Margin', compute='_compute_item_margin_without_deduction') weight = fields.Float(string='Weight') - md_vendor_id = fields.Many2one('res.partner', string='MD Vendor', readonly=True) + # md_vendor_id = fields.Many2one('res.partner', string='MD Vendor', readonly=True) margin_md = fields.Float(string='Margin MD') @api.constrains('note_procurement') diff --git a/indoteknik_custom/views/sale_order.xml b/indoteknik_custom/views/sale_order.xml index 895b242c..9a637441 100755 --- a/indoteknik_custom/views/sale_order.xml +++ b/indoteknik_custom/views/sale_order.xml @@ -140,7 +140,6 @@ - -- cgit v1.2.3 From 53e39ccf1780beda4f27ae2e67566d57ac915654 Mon Sep 17 00:00:00 2001 From: Azka Nathan Date: Wed, 16 Oct 2024 09:39:32 +0700 Subject: fix error --- indoteknik_custom/models/sale_order_line.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/indoteknik_custom/models/sale_order_line.py b/indoteknik_custom/models/sale_order_line.py index 1b7b3ef2..5e01067a 100644 --- a/indoteknik_custom/models/sale_order_line.py +++ b/indoteknik_custom/models/sale_order_line.py @@ -34,7 +34,7 @@ class SaleOrderLine(models.Model): reserved_from = fields.Char(string='Reserved From', copy=False) item_percent_margin_without_deduction = fields.Float('%Margin', compute='_compute_item_margin_without_deduction') weight = fields.Float(string='Weight') - # md_vendor_id = fields.Many2one('res.partner', string='MD Vendor', readonly=True) + md_vendor_id = fields.Many2one('res.partner', string='MD Vendor', readonly=True) margin_md = fields.Float(string='Margin MD') @api.constrains('note_procurement') -- cgit v1.2.3 From 0e00a82659579fa0fdfe1f51687b3568cd62a955 Mon Sep 17 00:00:00 2001 From: it-fixcomart Date: Wed, 16 Oct 2024 09:56:18 +0700 Subject: back to original code --- indoteknik_api/controllers/api_v1/product.py | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/indoteknik_api/controllers/api_v1/product.py b/indoteknik_api/controllers/api_v1/product.py index 8fe48932..9673b3ef 100644 --- a/indoteknik_api/controllers/api_v1/product.py +++ b/indoteknik_api/controllers/api_v1/product.py @@ -73,11 +73,7 @@ class Product(controller.Controller): total_adem = qty_altama if qty_available > 0: - qty = qty_available - sla_date = '1 Hari' - elif qty_available > 0 and qty_altama > 0: - qty = qty_available - sla_date = '1 Hari' + qty = qty_available + total_adem + total_excell elif qty_altama > 0 or qty_vendor > 0: qty = total_adem if qty_altama > 0 else total_excell sla_date = '2-4 Hari' -- cgit v1.2.3 From 0f11923903736a7ccbfc6df815103f890d55d7e9 Mon Sep 17 00:00:00 2001 From: Azka Nathan Date: Wed, 16 Oct 2024 10:29:16 +0700 Subject: add state reserve on stock.picking --- indoteknik_custom/models/approval_unreserve.py | 5 +++-- indoteknik_custom/models/stock_picking.py | 18 ++++++++++++++++++ indoteknik_custom/views/stock_picking.xml | 1 + 3 files changed, 22 insertions(+), 2 deletions(-) diff --git a/indoteknik_custom/models/approval_unreserve.py b/indoteknik_custom/models/approval_unreserve.py index 88409c37..85dfffff 100644 --- a/indoteknik_custom/models/approval_unreserve.py +++ b/indoteknik_custom/models/approval_unreserve.py @@ -31,12 +31,12 @@ class ApprovalUnreserve(models.Model): if not self.picking_id: raise ValidationError("Picking is required") - stock_move = self.env['stock.move'].search([('picking_id', '=', self.picking_id.id), ('state', '=', 'assigned')]) + stock_move = self.env['stock.move'].search([('picking_id', '=', self.picking_id.id), ('state', 'in', ['assigned', 'partially_available'])]) if not stock_move: raise ValidationError("Picking is not found") - for move in stock_move: + for move in stock_move: self.approval_line.create({ 'approval_id': self.id, 'move_id': move.id @@ -86,6 +86,7 @@ class ApprovalUnreserve(models.Model): }) # Trigger the unreserve function self._trigger_unreserve() + self.picking_id.check_state_reserve() def action_reject(self, reason): if self.env.user.id != self.user_id.id: diff --git a/indoteknik_custom/models/stock_picking.py b/indoteknik_custom/models/stock_picking.py index 14190474..33e577bc 100644 --- a/indoteknik_custom/models/stock_picking.py +++ b/indoteknik_custom/models/stock_picking.py @@ -101,6 +101,13 @@ class StockPicking(models.Model): ('no', 'Nothing to Invoice') ], string='Invoice Status', related="sale_id.invoice_status") + state_reserve = fields.Selection([ + ('waiting', 'Waiting For Fullfilment'), + ('ready', 'Ready to Ship'), + ('done', 'Done'), + ('cancel', 'Cancelled'), + ], string='Status Reserve', readonly=True, tracking=True, help="The current state of the stock picking.") + @api.constrains('driver_departure_date') def constrains_driver_departure_date(self): self.date_doc_kirim = self.driver_departure_date @@ -134,9 +141,18 @@ class StockPicking(models.Model): res = super(StockPicking, self).do_unreserve() current_time = datetime.datetime.utcnow() self.date_unreserve = current_time + self.check_state_reserve() return res + def check_state_reserve(self): + self.state_reserve = 'ready' + + for line in self.move_ids_without_package: + if line.product_uom_qty > line.reserved_availability: + self.state_reserve = 'waiting' + break + def _create_approval_notification(self, approval_role): title = 'Warning' message = f'Butuh approval sales untuk unreserved' @@ -275,6 +291,7 @@ class StockPicking(models.Model): current_time = datetime.datetime.utcnow() self.real_shipping_id = self.sale_id.real_shipping_id self.date_availability = current_time + self.check_state_reserve() return res def ask_approval(self): @@ -421,6 +438,7 @@ class StockPicking(models.Model): res = super(StockPicking, self).button_validate() self.calculate_line_no() self.date_done = datetime.datetime.utcnow() + self.state_reserve = 'done' return res @api.model diff --git a/indoteknik_custom/views/stock_picking.xml b/indoteknik_custom/views/stock_picking.xml index 899d29eb..af1af563 100644 --- a/indoteknik_custom/views/stock_picking.xml +++ b/indoteknik_custom/views/stock_picking.xml @@ -16,6 +16,7 @@ + -- cgit v1.2.3 From ec04fe1b46e846633108b889f2a4d4cdbbb6ff1e Mon Sep 17 00:00:00 2001 From: Azka Nathan Date: Wed, 16 Oct 2024 11:55:56 +0700 Subject: cr state reserve --- indoteknik_custom/models/stock_picking.py | 22 ++++++++++++++-------- 1 file changed, 14 insertions(+), 8 deletions(-) diff --git a/indoteknik_custom/models/stock_picking.py b/indoteknik_custom/models/stock_picking.py index 33e577bc..1b2baea7 100644 --- a/indoteknik_custom/models/stock_picking.py +++ b/indoteknik_custom/models/stock_picking.py @@ -141,17 +141,23 @@ class StockPicking(models.Model): res = super(StockPicking, self).do_unreserve() current_time = datetime.datetime.utcnow() self.date_unreserve = current_time - self.check_state_reserve() + # self.check_state_reserve() return res def check_state_reserve(self): - self.state_reserve = 'ready' - - for line in self.move_ids_without_package: - if line.product_uom_qty > line.reserved_availability: - self.state_reserve = 'waiting' - break + do = self.search([ + ('state', 'not in', ['cancel', 'draft', 'done']), + ('picking_type_code', '=', 'outgoing') + ]) + + for rec in do: + rec.state_reserve = 'ready' + + for line in rec.move_ids_without_package: + if line.product_uom_qty > line.reserved_availability: + rec.state_reserve = 'waiting' + break def _create_approval_notification(self, approval_role): title = 'Warning' @@ -291,7 +297,7 @@ class StockPicking(models.Model): current_time = datetime.datetime.utcnow() self.real_shipping_id = self.sale_id.real_shipping_id self.date_availability = current_time - self.check_state_reserve() + # self.check_state_reserve() return res def ask_approval(self): -- cgit v1.2.3 From 4c2325d4a983ced3a25a9d53d7613a9186360b17 Mon Sep 17 00:00:00 2001 From: it-fixcomart Date: Wed, 16 Oct 2024 13:15:11 +0700 Subject: update ready stock picup quantity --- indoteknik_api/controllers/api_v1/product.py | 15 +++++++++++++++ indoteknik_api/controllers/api_v1/sale_order.py | 3 ++- indoteknik_api/models/sale_order.py | 1 + indoteknik_custom/models/sale_order_line.py | 1 + indoteknik_custom/models/website_user_cart.py | 2 ++ 5 files changed, 21 insertions(+), 1 deletion(-) diff --git a/indoteknik_api/controllers/api_v1/product.py b/indoteknik_api/controllers/api_v1/product.py index 9673b3ef..b68eb0f9 100644 --- a/indoteknik_api/controllers/api_v1/product.py +++ b/indoteknik_api/controllers/api_v1/product.py @@ -96,6 +96,21 @@ class Product(controller.Controller): return self.response(data, headers=[('Cache-Control', 'max-age=600, private')]) + @http.route(prefix + 'product_variant//qty_available', auth='public', methods=['GET', 'OPTIONS']) + @controller.Controller.must_authorized() + def get_product_variant_stock_available_by_id(self, **kw): + id = int(kw.get('id')) + product = request.env['product.product'].search( + [('id', '=', id)], limit=1) + + qty_available = product.free_qty + + data = { + 'qty': qty_available, + } + + return self.response(data, headers=[('Cache-Control', 'max-age=600, private')]) + @http.route(prefix + 'product/template/price/', auth='public', methods=['GET', 'OPTIONS']) def get_product_template_price_by_id(self, **kw): if not self.authenticate(): diff --git a/indoteknik_api/controllers/api_v1/sale_order.py b/indoteknik_api/controllers/api_v1/sale_order.py index e7664c79..905795b0 100644 --- a/indoteknik_api/controllers/api_v1/sale_order.py +++ b/indoteknik_api/controllers/api_v1/sale_order.py @@ -446,7 +446,8 @@ class SaleOrder(controller.Controller): 'company_id': 1, 'order_id': sale_order.id, 'product_id': cart['id'], - 'product_uom_qty': cart['quantity'] + 'product_uom_qty': cart['quantity'], + 'product_available_quantity': cart['available_quantity'] }) order_line.product_id_change() order_line.onchange_vendor_id() diff --git a/indoteknik_api/models/sale_order.py b/indoteknik_api/models/sale_order.py index 725dbb4b..8e0371a3 100644 --- a/indoteknik_api/models/sale_order.py +++ b/indoteknik_api/models/sale_order.py @@ -84,6 +84,7 @@ class SaleOrder(models.Model): 'subtotal': line.price_subtotal } product['quantity'] = line.product_uom_qty + product['available_quantity'] = line.product_available_quantity data_with_detail['products'].append(product) for invoice in sale_order.invoice_ids: if invoice.state == 'posted': diff --git a/indoteknik_custom/models/sale_order_line.py b/indoteknik_custom/models/sale_order_line.py index 5e01067a..964b3ff2 100644 --- a/indoteknik_custom/models/sale_order_line.py +++ b/indoteknik_custom/models/sale_order_line.py @@ -31,6 +31,7 @@ class SaleOrderLine(models.Model): vendor_subtotal = fields.Float(string='Vendor Subtotal', compute="_compute_vendor_subtotal") amount_voucher_disc = fields.Float(string='Voucher Discount') qty_reserved = fields.Float(string='Qty Reserved', compute='_compute_qty_reserved') + product_available_quantity = fields.Float(string='Qty pickup by user',) reserved_from = fields.Char(string='Reserved From', copy=False) item_percent_margin_without_deduction = fields.Float('%Margin', compute='_compute_item_margin_without_deduction') weight = fields.Float(string='Weight') diff --git a/indoteknik_custom/models/website_user_cart.py b/indoteknik_custom/models/website_user_cart.py index 26e217cb..9dadc40b 100644 --- a/indoteknik_custom/models/website_user_cart.py +++ b/indoteknik_custom/models/website_user_cart.py @@ -65,9 +65,11 @@ 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 else: res['is_in_bu'] = False res['on_hand_qty'] = 0 + res['available_quantity'] = 0 flashsales = self.product_id._get_active_flash_sale() res['has_flashsale'] = True if len(flashsales) > 0 else False -- cgit v1.2.3 From 39b3e85ebcef9a02b3d6cb881d071c37ef45ac4f Mon Sep 17 00:00:00 2001 From: stephanchrst Date: Wed, 16 Oct 2024 14:05:28 +0700 Subject: add field pareto_status --- indoteknik_custom/models/sale_order.py | 7 +++++++ indoteknik_custom/views/sale_order.xml | 3 +++ 2 files changed, 10 insertions(+) diff --git a/indoteknik_custom/models/sale_order.py b/indoteknik_custom/models/sale_order.py index e6382cd9..22130ac3 100755 --- a/indoteknik_custom/models/sale_order.py +++ b/indoteknik_custom/models/sale_order.py @@ -136,6 +136,12 @@ class SaleOrder(models.Model): domain="['|', ('company_id', '=', False), ('company_id', '=', company_id)]", tracking=True) total_weight = fields.Float(string='Total Weight', compute='_compute_total_weight') + pareto_status = fields.Selection([ + ('PR', 'Pareto Repeating'), + ('PPR', 'Potensi Pareto Repeating'), + ('PNR', 'Pareto Non Repeating'), + ('NP', 'Non Pareto') + ]) def _compute_total_weight(self): total_weight = 0 @@ -642,6 +648,7 @@ class SaleOrder(models.Model): self.sppkp = parent_id.sppkp self.customer_type = parent_id.customer_type self.email = parent_id.email + self.pareto_status = parent_id.pareto_status @api.onchange('partner_id') def onchange_partner_id(self): diff --git a/indoteknik_custom/views/sale_order.xml b/indoteknik_custom/views/sale_order.xml index 9a637441..98001589 100755 --- a/indoteknik_custom/views/sale_order.xml +++ b/indoteknik_custom/views/sale_order.xml @@ -73,6 +73,7 @@ + @@ -244,6 +245,7 @@ + @@ -262,6 +264,7 @@ + -- cgit v1.2.3 From e60bfff5a9ec49545370b1804b33535b5f373b60 Mon Sep 17 00:00:00 2001 From: Azka Nathan Date: Wed, 16 Oct 2024 14:56:12 +0700 Subject: cr approval unreserve --- indoteknik_custom/models/approval_unreserve.py | 2 +- indoteknik_custom/models/purchase_order.py | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/indoteknik_custom/models/approval_unreserve.py b/indoteknik_custom/models/approval_unreserve.py index 85dfffff..07ddda1f 100644 --- a/indoteknik_custom/models/approval_unreserve.py +++ b/indoteknik_custom/models/approval_unreserve.py @@ -68,7 +68,7 @@ class ApprovalUnreserve(models.Model): if not move: raise UserError("Product tidak ada di destination picking") - qty_unreserve = line.unreserve_qty + move.forecast_availability + qty_unreserve = line.unreserve_qty + move.reserved_availability if move.product_uom_qty < qty_unreserve: raise UserError("Quantity yang di unreserve melebihi quantity yang ada") diff --git a/indoteknik_custom/models/purchase_order.py b/indoteknik_custom/models/purchase_order.py index 21f3265e..f8af409f 100755 --- a/indoteknik_custom/models/purchase_order.py +++ b/indoteknik_custom/models/purchase_order.py @@ -509,10 +509,10 @@ class PurchaseOrder(models.Model): raise UserError("Hanya Merchandiser yang bisa approve") if self.total_percent_margin < self.total_so_percent_margin and not self.env.user.has_group('indoteknik_custom.group_role_merchandiser') and not self.env.user.is_leader: - raise UserError("Beda Margin dengan Sales, harus approval Manager") + raise UserError("Beda Margin dengan Sales, harus approval Merchandise") if not self.from_apo: if not self.sale_order_id and self.env.user.has_group('indoteknik_custom.group_role_merchandiser') and not self.env.user.is_leader: - raise UserError("Tidak ada link dengan SO, harus approval Manager") + raise UserError("Tidak ada link dengan SO, harus approval Merchandise") send_email = False self.add_product_to_pricelist() -- cgit v1.2.3 From d67a78aa3532ebdb5b369ccd0b6f7a3ad6aa2b15 Mon Sep 17 00:00:00 2001 From: Azka Nathan Date: Wed, 16 Oct 2024 17:03:30 +0700 Subject: remove note logistic selection --- indoteknik_custom/models/stock_picking.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/indoteknik_custom/models/stock_picking.py b/indoteknik_custom/models/stock_picking.py index 1b2baea7..a9eb3943 100644 --- a/indoteknik_custom/models/stock_picking.py +++ b/indoteknik_custom/models/stock_picking.py @@ -73,10 +73,8 @@ class StockPicking(models.Model): ('hold', 'Hold by Sales'), ('not_paid', 'Customer belum bayar'), ('partial', 'Kirim Parsial'), - ('not_complete', 'Belum Lengkap'), ('indent', 'Indent'), ('self_pickup', 'Barang belum di pickup Customer'), - ('delivery_route', 'Belum masuk rute pengiriman'), ('expedition_closed', 'Eskpedisi belum buka') ], string='Note Logistic', help='jika field ini diisi maka tidak akan dihitung ke lead time') waybill_id = fields.One2many(comodel_name='airway.bill', inverse_name='do_id', string='Airway Bill') -- cgit v1.2.3 From 29ba7afb88c676623a24b8b45503df5fd8e5c3ad Mon Sep 17 00:00:00 2001 From: Azka Nathan Date: Thu, 17 Oct 2024 10:01:28 +0700 Subject: cr approve po --- indoteknik_custom/models/purchase_order.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/indoteknik_custom/models/purchase_order.py b/indoteknik_custom/models/purchase_order.py index f8af409f..f924174a 100755 --- a/indoteknik_custom/models/purchase_order.py +++ b/indoteknik_custom/models/purchase_order.py @@ -511,7 +511,7 @@ class PurchaseOrder(models.Model): if self.total_percent_margin < self.total_so_percent_margin and not self.env.user.has_group('indoteknik_custom.group_role_merchandiser') and not self.env.user.is_leader: raise UserError("Beda Margin dengan Sales, harus approval Merchandise") if not self.from_apo: - if not self.sale_order_id and self.env.user.has_group('indoteknik_custom.group_role_merchandiser') and not self.env.user.is_leader: + if not self.sale_order_id and not self.env.user.has_group('indoteknik_custom.group_role_merchandiser') and not self.env.user.is_leader: raise UserError("Tidak ada link dengan SO, harus approval Merchandise") send_email = False -- cgit v1.2.3 From dd53080cb1bd9a1e6236a72dc4df09df9cda82a8 Mon Sep 17 00:00:00 2001 From: Azka Nathan Date: Thu, 17 Oct 2024 14:18:03 +0700 Subject: add printed sj retur --- indoteknik_custom/models/stock_picking.py | 2 ++ indoteknik_custom/views/stock_picking.xml | 2 ++ 2 files changed, 4 insertions(+) diff --git a/indoteknik_custom/models/stock_picking.py b/indoteknik_custom/models/stock_picking.py index a9eb3943..a5482f9d 100644 --- a/indoteknik_custom/models/stock_picking.py +++ b/indoteknik_custom/models/stock_picking.py @@ -92,6 +92,8 @@ class StockPicking(models.Model): date_availability = fields.Datetime(string="Date Availability", copy=False, tracking=True) sale_order = fields.Char(string='Matches SO', copy=False) printed_sj = fields.Boolean('Printed Surat Jalan', help='flag which is internal use or not') + printed_sj_retur = fields.Boolean('Printed Surat Jalan Retur', help='flag which is internal use or not') + date_printed_sj_retur = fields.Datetime(string='Status Printed Surat Jalan Retur', copy=False, tracking=True) invoice_status = fields.Selection([ ('upselling', 'Upselling Opportunity'), ('invoiced', 'Fully Invoiced'), diff --git a/indoteknik_custom/views/stock_picking.xml b/indoteknik_custom/views/stock_picking.xml index af1af563..e435fa71 100644 --- a/indoteknik_custom/views/stock_picking.xml +++ b/indoteknik_custom/views/stock_picking.xml @@ -92,6 +92,8 @@ + + Date: Thu, 17 Oct 2024 17:08:06 +0700 Subject: update menampilkan category dan brand, sebelum ditampilkan cek dulu apakah brand termasuk kedalam category --- indoteknik_custom/models/find_page.py | 32 ++++++++++++++++++++++++++++++-- 1 file changed, 30 insertions(+), 2 deletions(-) diff --git a/indoteknik_custom/models/find_page.py b/indoteknik_custom/models/find_page.py index b81b3845..463092ce 100644 --- a/indoteknik_custom/models/find_page.py +++ b/indoteknik_custom/models/find_page.py @@ -32,13 +32,41 @@ class FindPage(models.Model): category_id = fields.Many2one('product.public.category', string='Category', help='Bisa semua level Category') url = fields.Char(string='Url') + def _get_category_hierarchy(self, category): + categories = [] + current_category = category + while current_category: + categories.insert(0, current_category) + current_category = current_category.parent_id + return categories + def _generate_url(self): categories = self.env['v.brand.product.category'].search([]) count = 0 for category in categories: - print(category.brand_id.x_name+' '+category.category_id.name) + category_hierarchy = self._get_category_hierarchy(category.category_id) + + for level, cat in enumerate(category_hierarchy, start=1): + products = self.env['product.product'].search([ + ('public_categ_ids', '=', cat.id), + ('x_manufacture', '=', category.brand_id.id) + ]) + + if products: + print(f"Level {level} : {cat.name} {category.brand_id.x_name}") + count += 1 - print(count) + # if count == 5: + # break + print(f"Total categories processed: {count}") + + # def _generate_url(self): + # categories = self.env['v.brand.product.category'].search([]) + # count = 0 + # for category in categories: + # print(category.brand_id.x_name+' '+category.category_id.name) + # count += 1 + # print(count) def _generate_url_parent(self): print(1) -- cgit v1.2.3 From d0af9ab71c65f6e7e1280b2978ebac2d0d514a45 Mon Sep 17 00:00:00 2001 From: it-fixcomart Date: Fri, 18 Oct 2024 09:09:07 +0700 Subject: update generate tanpa chek product --- indoteknik_custom/models/find_page.py | 12 ++---------- 1 file changed, 2 insertions(+), 10 deletions(-) diff --git a/indoteknik_custom/models/find_page.py b/indoteknik_custom/models/find_page.py index 463092ce..b7ad7f49 100644 --- a/indoteknik_custom/models/find_page.py +++ b/indoteknik_custom/models/find_page.py @@ -46,18 +46,10 @@ class FindPage(models.Model): for category in categories: category_hierarchy = self._get_category_hierarchy(category.category_id) - for level, cat in enumerate(category_hierarchy, start=1): - products = self.env['product.product'].search([ - ('public_categ_ids', '=', cat.id), - ('x_manufacture', '=', category.brand_id.id) - ]) - - if products: - print(f"Level {level} : {cat.name} {category.brand_id.x_name}") + for level, cat in enumerate(reversed(category_hierarchy), start=1): + print(f"Level {level}: {cat.name} {category.brand_id.x_name}") count += 1 - # if count == 5: - # break print(f"Total categories processed: {count}") # def _generate_url(self): -- cgit v1.2.3 From f82f8840c8addc1a4e244e6ad7d60ffe66b178c1 Mon Sep 17 00:00:00 2001 From: it-fixcomart Date: Fri, 18 Oct 2024 13:55:42 +0700 Subject: nambahin 1 nol jadi pkp 15 --- indoteknik_api/controllers/api_v1/user.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/indoteknik_api/controllers/api_v1/user.py b/indoteknik_api/controllers/api_v1/user.py index e4f8b97f..3be874fa 100644 --- a/indoteknik_api/controllers/api_v1/user.py +++ b/indoteknik_api/controllers/api_v1/user.py @@ -95,7 +95,7 @@ class User(controller.Controller): user = request.env['res.users'].create(user_data) user.partner_id.email = email user.partner_id.customer_type = 'nonpkp' - user.partner_id.npwp = '0.000.000.0-000.000' + user.partner_id.npwp = '00.000.000.0-000.000' user.partner_id.sppkp = '-' user.partner_id.nama_wajib_pajak = user.name user.partner_id.user_id = 3222 -- cgit v1.2.3 From 330dc374a9a15e4ad41b6829ad87a2a1d8264fff Mon Sep 17 00:00:00 2001 From: stephanchrst Date: Fri, 18 Oct 2024 14:10:45 +0700 Subject: temporary comment update contact in sales order --- indoteknik_custom/models/sale_order.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/indoteknik_custom/models/sale_order.py b/indoteknik_custom/models/sale_order.py index 22130ac3..cb7d1782 100755 --- a/indoteknik_custom/models/sale_order.py +++ b/indoteknik_custom/models/sale_order.py @@ -1314,7 +1314,7 @@ class SaleOrder(models.Model): def create(self, vals): # Ensure partner details are updated when a sale order is created order = super(SaleOrder, self).create(vals) - order._update_partner_details() + # order._update_partner_details() return order def write(self, vals): @@ -1322,8 +1322,8 @@ class SaleOrder(models.Model): res = super(SaleOrder, self).write(vals) # Check if the update is coming from a save operation - if any(field in vals for field in ['sppkp', 'npwp', 'email', 'customer_type']): - self._update_partner_details() + # if any(field in vals for field in ['sppkp', 'npwp', 'email', 'customer_type']): + # self._update_partner_details() return res -- cgit v1.2.3 From f65c674b06d3fbe22829a599eec36b4b19c27dd2 Mon Sep 17 00:00:00 2001 From: Azka Nathan Date: Sat, 19 Oct 2024 09:38:37 +0700 Subject: push --- indoteknik_custom/views/res_partner.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/indoteknik_custom/views/res_partner.xml b/indoteknik_custom/views/res_partner.xml index 6d02a86b..b458c44c 100644 --- a/indoteknik_custom/views/res_partner.xml +++ b/indoteknik_custom/views/res_partner.xml @@ -65,9 +65,9 @@ - + 1 -- cgit v1.2.3 From 4146004dfa277d1e5f15ca7ed6af247f543b74bb Mon Sep 17 00:00:00 2001 From: Azka Nathan Date: Sat, 19 Oct 2024 09:41:42 +0700 Subject: push --- indoteknik_custom/views/res_partner.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/indoteknik_custom/views/res_partner.xml b/indoteknik_custom/views/res_partner.xml index b458c44c..6d02a86b 100644 --- a/indoteknik_custom/views/res_partner.xml +++ b/indoteknik_custom/views/res_partner.xml @@ -65,9 +65,9 @@ - + 1 -- cgit v1.2.3 From a4006a9c7f57bbc11ba0c519e69719ded8248ad3 Mon Sep 17 00:00:00 2001 From: Azka Nathan Date: Sat, 19 Oct 2024 11:25:53 +0700 Subject: add date_reserved on tree stock picking --- indoteknik_custom/views/stock_picking.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/indoteknik_custom/views/stock_picking.xml b/indoteknik_custom/views/stock_picking.xml index e435fa71..d713edbc 100644 --- a/indoteknik_custom/views/stock_picking.xml +++ b/indoteknik_custom/views/stock_picking.xml @@ -16,6 +16,7 @@ + -- cgit v1.2.3 From eadc70481dd65dd7483aa2ae5c9bcc68bb274f3e Mon Sep 17 00:00:00 2001 From: Azka Nathan Date: Mon, 21 Oct 2024 09:19:50 +0700 Subject: fix bug vendor approval --- indoteknik_custom/models/sale_order.py | 3 +++ indoteknik_custom/models/vendor_approval.py | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/indoteknik_custom/models/sale_order.py b/indoteknik_custom/models/sale_order.py index cb7d1782..891482cb 100755 --- a/indoteknik_custom/models/sale_order.py +++ b/indoteknik_custom/models/sale_order.py @@ -873,6 +873,9 @@ class SaleOrder(models.Model): }).send() def validate_different_vendor(self): + if self.vendor_approval_id and self.vendor_approval: + 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) if self.vendor_approval_id and self.vendor_approval_id.state == 'draft': diff --git a/indoteknik_custom/models/vendor_approval.py b/indoteknik_custom/models/vendor_approval.py index e540b8fc..b0d58b85 100644 --- a/indoteknik_custom/models/vendor_approval.py +++ b/indoteknik_custom/models/vendor_approval.py @@ -29,7 +29,7 @@ class VendorApproval(models.Model): raise UserError('Hanya Merchandiser yang bisa approve') self.state = 'done' - self.order_id.update({'vendor_approval': True}) + self.order_id.vendor_approval = True self.order_id.action_confirm() message = "Vendor Approval approved by %s" % (self.env.user.name) self.order_id.message_post(body=message) -- cgit v1.2.3 From 81d6d5550737af445900199afd6edf5824bd03e2 Mon Sep 17 00:00:00 2001 From: Azka Nathan Date: Mon, 21 Oct 2024 16:33:48 +0700 Subject: cr active product product --- indoteknik_custom/models/product_template.py | 1 + 1 file changed, 1 insertion(+) diff --git a/indoteknik_custom/models/product_template.py b/indoteknik_custom/models/product_template.py index af7f98cd..2ca4925b 100755 --- a/indoteknik_custom/models/product_template.py +++ b/indoteknik_custom/models/product_template.py @@ -405,6 +405,7 @@ class ProductProduct(models.Model): continue if any(variant.active for variant in variants): product_template.unpublished = False + variants.unpublished = False def update_internal_reference_variants(self, limit=100): variants = self.env['product.product'].search([ -- cgit v1.2.3 From c99e4d67c037a781b79e0ed198899d5f5c4a153b Mon Sep 17 00:00:00 2001 From: Azka Nathan Date: Tue, 22 Oct 2024 10:53:16 +0700 Subject: cr vendor approval --- indoteknik_custom/models/sale_order.py | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/indoteknik_custom/models/sale_order.py b/indoteknik_custom/models/sale_order.py index 891482cb..1ad08154 100755 --- a/indoteknik_custom/models/sale_order.py +++ b/indoteknik_custom/models/sale_order.py @@ -873,17 +873,16 @@ class SaleOrder(models.Model): }).send() def validate_different_vendor(self): - if self.vendor_approval_id and self.vendor_approval: - 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) - 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': + 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) if different_vendor: vendor_approval = self.env['vendor.approval'].create({ 'order_id': self.id, -- cgit v1.2.3 From adb901e780bd0f1e9abfefc9f403e335c155115c Mon Sep 17 00:00:00 2001 From: it-fixcomart Date: Tue, 22 Oct 2024 12:01:55 +0700 Subject: ubah state id dari null menjadi 0 --- indoteknik_api/models/res_users.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/indoteknik_api/models/res_users.py b/indoteknik_api/models/res_users.py index 534898e1..2751ca7a 100644 --- a/indoteknik_api/models/res_users.py +++ b/indoteknik_api/models/res_users.py @@ -48,7 +48,7 @@ class ResUsers(models.Model): 'street': user.street or '', 'street2': user.street2 or '', 'city': None, - 'state_id': None, + 'state_id': 0, 'district': None, 'sub_district': None, 'zip': user.zip or '', -- cgit v1.2.3 From ecc3621e449af1393836cf67ca34d91ed32eea5c Mon Sep 17 00:00:00 2001 From: Azka Nathan Date: Tue, 22 Oct 2024 15:26:24 +0700 Subject: cr status reserve --- indoteknik_custom/models/stock_picking.py | 82 ++++++++++++++++++++++++++++--- 1 file changed, 74 insertions(+), 8 deletions(-) diff --git a/indoteknik_custom/models/stock_picking.py b/indoteknik_custom/models/stock_picking.py index a5482f9d..2a73d631 100644 --- a/indoteknik_custom/models/stock_picking.py +++ b/indoteknik_custom/models/stock_picking.py @@ -3,7 +3,7 @@ from odoo.exceptions import AccessError, UserError, ValidationError from odoo.tools.float_utils import float_is_zero from datetime import datetime from itertools import groupby -import pytz, datetime +import pytz, datetime, requests, json class StockPicking(models.Model): @@ -107,6 +107,51 @@ class StockPicking(models.Model): ('done', 'Done'), ('cancel', 'Cancelled'), ], string='Status Reserve', readonly=True, tracking=True, help="The current state of the stock picking.") + + def action_send_to_biteship(self): + url = "https://api.biteship.com/v1/orders" + + api_key = "biteship_test.eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJuYW1lIjoiSW5kb3Rla25payIsInVzZXJJZCI6IjY3MTViYTJkYzVkMjdkMDAxMjRjODk2MiIsImlhdCI6MTcyOTQ5ODAwMX0.L6C73couP4-cgVEfhKI2g7eMCMo3YOFSRZhS-KSuHNA" + + items_data = [] + for item in self.items: + items_data.append({ + "name": item.name, + "description": item.description, + "category": item.category, + "value": item.value, + "quantity": item.quantity, + "weight": item.weight + }) + + payload = { + "shipper_contact_name": self.carrier_id.pic_name or '', + "shipper_contact_phone": self.carrier_id.pic_phone or '', + # "shipper_contact_email": "sales@indoteknik.co.id", + "shipper_organization": self.carrier_id.name, + "origin_contact_name": "PT. Indoteknik Dotcom Gemilang", + "origin_contact_phone": "081717181922", + "origin_address": "Jl. Bandengan Utara Komp A & BRT. Penjaringan, Kec. Penjaringan, Jakarta (BELAKANG INDOMARET) KOTA JAKARTA UTARA PENJARINGAN", + "origin_postal_code": "14440", + "destination_contact_name": self.real_shipping_id.name, + "destination_contact_phone": self.real_shipping_id.phone or self.real_shipping_id.mobile, + "destination_contact_email": self.real_shipping_id.email or '', + "destination_address": self.real_shipping_id.street, + "destination_postal_code": self.real_shipping_id.zip, + "items": items_data + } + + headers = { + "Authorization": f"Bearer {api_key}", + "Content-Type": "application/json" + } + + response = requests.post(url, headers=headers, data=json.dumps(payload)) + + if response.status_code == 201: + return response.json() + else: + raise UserError(f"Error saat mengirim ke Biteship: {response.content}") @api.constrains('driver_departure_date') def constrains_driver_departure_date(self): @@ -145,18 +190,39 @@ class StockPicking(models.Model): return res + # def check_state_reserve(self): + # do = self.search([ + # ('state', 'not in', ['cancel', 'draft', 'done']), + # ('picking_type_code', '=', 'outgoing') + # ]) + + # for rec in do: + # rec.state_reserve = 'ready' + # rec.date_reserved = datetime.datetime.utcnow() + + # for line in rec.move_ids_without_package: + # if line.product_uom_qty > line.reserved_availability: + # rec.state_reserve = 'waiting' + # rec.date_reserved = '' + # break + def check_state_reserve(self): - do = self.search([ + picking = self.search([ ('state', 'not in', ['cancel', 'draft', 'done']), ('picking_type_code', '=', 'outgoing') ]) + + for data in picking: + fullfilment = self.env['sales.order.fullfillment'].search([ + ('sales_order_id', '=', data.sale_id.id) + ]) - for rec in do: - rec.state_reserve = 'ready' - - for line in rec.move_ids_without_package: - if line.product_uom_qty > line.reserved_availability: - rec.state_reserve = 'waiting' + data.state_reserve = 'ready' + data.date_reserved = datetime.datetime.utcnow() + for rec in fullfilment: + if rec.reserved_from not in ['Inventory On Hand', 'Reserved from stock', 'Free Stock']: + data.state_reserve = 'waiting' + data.date_reserved = '' break def _create_approval_notification(self, approval_role): -- cgit v1.2.3 From d588e3c431f428e09f1efc1736a2ad947ca5b61e Mon Sep 17 00:00:00 2001 From: Azka Nathan Date: Tue, 22 Oct 2024 16:53:04 +0700 Subject: cr due extension and dunning run --- indoteknik_custom/views/account_move_views.xml | 1 + indoteknik_custom/views/dunning_run.xml | 1 + 2 files changed, 2 insertions(+) diff --git a/indoteknik_custom/views/account_move_views.xml b/indoteknik_custom/views/account_move_views.xml index 4acafb14..f4faf386 100644 --- a/indoteknik_custom/views/account_move_views.xml +++ b/indoteknik_custom/views/account_move_views.xml @@ -12,6 +12,7 @@ + diff --git a/indoteknik_custom/views/dunning_run.xml b/indoteknik_custom/views/dunning_run.xml index 522be8c9..2117a7bb 100644 --- a/indoteknik_custom/views/dunning_run.xml +++ b/indoteknik_custom/views/dunning_run.xml @@ -14,6 +14,7 @@ + -- cgit v1.2.3 From bd02dbfcfef14c016eec14811f9f257790e6e321 Mon Sep 17 00:00:00 2001 From: Azka Nathan Date: Tue, 22 Oct 2024 16:57:56 +0700 Subject: create_date on due extension --- indoteknik_custom/views/account_move_views.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/indoteknik_custom/views/account_move_views.xml b/indoteknik_custom/views/account_move_views.xml index f4faf386..f7b753bd 100644 --- a/indoteknik_custom/views/account_move_views.xml +++ b/indoteknik_custom/views/account_move_views.xml @@ -13,6 +13,7 @@ + -- cgit v1.2.3 From e8be87ce9143c92e2b1011649fa6b8280338fa69 Mon Sep 17 00:00:00 2001 From: trisusilo48 Date: Wed, 23 Oct 2024 09:12:35 +0700 Subject: fedback indoteknik delivery --- indoteknik_api/controllers/api_v1/stock_picking.py | 5 ++++- indoteknik_custom/models/stock_picking.py | 8 +++++--- indoteknik_custom/views/stock_picking.xml | 8 +++++--- 3 files changed, 14 insertions(+), 7 deletions(-) diff --git a/indoteknik_api/controllers/api_v1/stock_picking.py b/indoteknik_api/controllers/api_v1/stock_picking.py index c8bc9a7e..f0c7456d 100644 --- a/indoteknik_api/controllers/api_v1/stock_picking.py +++ b/indoteknik_api/controllers/api_v1/stock_picking.py @@ -1,6 +1,8 @@ from .. import controller from odoo import http from odoo.http import request +from pytz import timezone +from datetime import datetime class StockPicking(controller.Controller): @@ -120,7 +122,8 @@ class StockPicking(controller.Controller): paket_document = kw.get('paket_document', False) params = {'sj_documentation': sj_document, - 'paket_documentation': paket_document + 'paket_documentation': paket_document, + 'driver_arrival_date': self.time_to_str(datetime.utcnow(), '%Y-%m-%d %H:%M:%S'), } picking_data = request.env['stock.picking'].search([('picking_code', '=', picking_code)], limit=1) diff --git a/indoteknik_custom/models/stock_picking.py b/indoteknik_custom/models/stock_picking.py index 066ce238..9dede1af 100644 --- a/indoteknik_custom/models/stock_picking.py +++ b/indoteknik_custom/models/stock_picking.py @@ -25,7 +25,7 @@ class StockPicking(models.Model): # Delivery Order driver_departure_date = fields.Datetime( - string='Driver Departure Date', + string='Delivery Departure Date', copy=False ) arrival_time = fields.Datetime( @@ -33,7 +33,7 @@ class StockPicking(models.Model): copy=False ) driver_arrival_date = fields.Datetime( - string='Driver Arrival Date', + string='Delivery Arrival Date', readonly=True, copy=False ) @@ -55,6 +55,8 @@ class StockPicking(models.Model): ) sj_documentation = fields.Binary(string="Dokumentasi Surat Jalan", ) paket_documentation = fields.Binary(string="Dokumentasi Paket", ) + sj_return_date = fields.Datetime(string="SJ Return Date", ) + responsible = fields.Many2one('res.users', string='Responsible', tracking=True) approval_status = fields.Selection([ ('pengajuan1', 'Approval Accounting'), @@ -419,7 +421,7 @@ class StockPicking(models.Model): self.date_reserved = current_time self.validation_minus_onhand_quantity() - + self.responsible = self.env.user.id res = super(StockPicking, self).button_validate() self.calculate_line_no() self.date_done = datetime.datetime.utcnow() diff --git a/indoteknik_custom/views/stock_picking.xml b/indoteknik_custom/views/stock_picking.xml index d47c1051..37c622ec 100644 --- a/indoteknik_custom/views/stock_picking.xml +++ b/indoteknik_custom/views/stock_picking.xml @@ -122,13 +122,15 @@ + + + + - - - + -- cgit v1.2.3 From 25645d93db289ea4855486630dba8d578efb2851 Mon Sep 17 00:00:00 2001 From: Azka Nathan Date: Wed, 23 Oct 2024 09:13:53 +0700 Subject: cr due extension --- indoteknik_custom/models/account_move_due_extension.py | 7 +++++-- indoteknik_custom/views/account_move_views.xml | 6 +++++- 2 files changed, 10 insertions(+), 3 deletions(-) diff --git a/indoteknik_custom/models/account_move_due_extension.py b/indoteknik_custom/models/account_move_due_extension.py index 23f8888c..6fc58cdd 100644 --- a/indoteknik_custom/models/account_move_due_extension.py +++ b/indoteknik_custom/models/account_move_due_extension.py @@ -1,6 +1,6 @@ from odoo import models, api, fields from odoo.exceptions import AccessError, UserError, ValidationError -from datetime import timedelta, date +from datetime import timedelta, date, datetime import logging _logger = logging.getLogger(__name__) @@ -31,7 +31,8 @@ class DueExtension(models.Model): ('21', '21 Hari'), ], string='Day Extension', help='Menambah Due Date yang sudah limit dari hari ini', tracking=True) counter = fields.Integer(string="Counter", compute='_compute_counter') - + approve_by = fields.Many2one('res.users', string="Approve By", readonly=True) + date_approve = fields.Datetime(string="Date Approve", readonly=True) def _compute_counter(self): for due in self: due.counter = due.partner_id.counter @@ -96,6 +97,8 @@ class DueExtension(models.Model): sales.action_confirm() self.order_id.due_id = self.id + self.approve_by = self.env.user.id + self.date_approve = datetime.utcnow() template = self.env.ref('indoteknik_custom.mail_template_due_extension_approve') template.send_mail(self.id, force_send=True) diff --git a/indoteknik_custom/views/account_move_views.xml b/indoteknik_custom/views/account_move_views.xml index f7b753bd..da25636e 100644 --- a/indoteknik_custom/views/account_move_views.xml +++ b/indoteknik_custom/views/account_move_views.xml @@ -12,6 +12,8 @@ + + @@ -60,12 +62,14 @@ + - + + -- cgit v1.2.3 From 943ee3ca2e3b8469d1f3969fa6ea45710e532fc0 Mon Sep 17 00:00:00 2001 From: stephanchrst Date: Wed, 23 Oct 2024 10:21:27 +0700 Subject: fix web find page --- indoteknik_custom/__manifest__.py | 1 + indoteknik_custom/models/find_page.py | 56 ++++++++++++++++++++++------ indoteknik_custom/views/find_page.xml | 70 +++++++++++++++++++++++++++++++++++ 3 files changed, 116 insertions(+), 11 deletions(-) create mode 100644 indoteknik_custom/views/find_page.xml diff --git a/indoteknik_custom/__manifest__.py b/indoteknik_custom/__manifest__.py index 116c64ec..c8a658b5 100755 --- a/indoteknik_custom/__manifest__.py +++ b/indoteknik_custom/__manifest__.py @@ -144,6 +144,7 @@ 'views/vendor_payment_term.xml', 'views/approval_unreserve.xml', 'views/vendor_approval.xml', + 'views/find_page.xml', 'report/report.xml', 'report/report_banner_banner.xml', 'report/report_banner_banner2.xml', diff --git a/indoteknik_custom/models/find_page.py b/indoteknik_custom/models/find_page.py index b7ad7f49..697fd275 100644 --- a/indoteknik_custom/models/find_page.py +++ b/indoteknik_custom/models/find_page.py @@ -1,5 +1,6 @@ from odoo import fields, models, api, tools, _ import logging +import re _logger = logging.getLogger(__name__) @@ -27,6 +28,8 @@ class BrandProductCategory(models.Model): class FindPage(models.Model): _name = 'web.find.page' + _inherit = ['mail.thread'] + _rec_name = 'url' brand_id = fields.Many2one('x_manufactures', string='Brand') category_id = fields.Many2one('product.public.category', string='Category', help='Bisa semua level Category') @@ -42,23 +45,54 @@ class FindPage(models.Model): def _generate_url(self): categories = self.env['v.brand.product.category'].search([]) - count = 0 + + list_url = [] for category in categories: category_hierarchy = self._get_category_hierarchy(category.category_id) for level, cat in enumerate(reversed(category_hierarchy), start=1): - print(f"Level {level}: {cat.name} {category.brand_id.x_name}") + list_url.append(self._generate_mod_url(cat, category.brand_id)) + # print(f"Level {level}: {cat.name} {category.brand_id.x_name}") + unique_list = [] + for item in list_url: + if item not in unique_list: + unique_list.append(item) + count = 0 + for item in unique_list: + self._create_find_page(item['url'], item['category_id'], item['brand_id']) count += 1 print(f"Total categories processed: {count}") - # def _generate_url(self): - # categories = self.env['v.brand.product.category'].search([]) - # count = 0 - # for category in categories: - # print(category.brand_id.x_name+' '+category.category_id.name) - # count += 1 - # print(count) + def _create_find_page(self, url, category_id, brand_id): + param = { + 'url': url, + 'category_id': category_id, + 'brand_id': brand_id, + } + find_page = self.env['web.find.page'].create(param) + _logger.info('Created Web Find Page %s' % find_page.id) - def _generate_url_parent(self): - print(1) + def _generate_mod_url(self, category, brand): + # generate_url = 'https://indoteknik.com/shop/find/category-brand' example + cleaned_category = re.sub(r'[^\w\s]', '', category.name) + cleaned_brand = re.sub(r'[^\w\s]', '', brand.x_name) + cleaned_combined = cleaned_category+' '+cleaned_brand + cleaned_combined = cleaned_combined.replace(' ', '-') + cleaned_combined = cleaned_combined.replace('--', '-') + url = 'https://indoteknik.com/shop/find/'+cleaned_combined + url = url.lower() + result = { + 'url': url, + 'category_id': category.id, + 'brand_id': brand.id + } + # print(url) + # param = { + # 'brand_id': brand.id, + # 'category_id': category.id, + # 'url':'' + # } + # self.env['web.find.page'].create() + # print(1) + return result diff --git a/indoteknik_custom/views/find_page.xml b/indoteknik_custom/views/find_page.xml new file mode 100644 index 00000000..c752aa98 --- /dev/null +++ b/indoteknik_custom/views/find_page.xml @@ -0,0 +1,70 @@ + + + + web.find.page.tree + web.find.page + + + + + + + + + + + + + web.find.page.form + web.find.page + +
+ +
+ + + + + + + + + + + + +
+ + +
+ + + + + + web.find.page.list.select + web.find.page + + + + + + + + + + + + Web Find Page + ir.actions.act_window + web.find.page + + tree,form + + + + \ No newline at end of file -- cgit v1.2.3 From 3852cfd075fb3bebf189234db6fd9c52acf6d667 Mon Sep 17 00:00:00 2001 From: stephanchrst Date: Wed, 23 Oct 2024 11:35:46 +0700 Subject: sync to solr web find page --- indoteknik_custom/models/find_page.py | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/indoteknik_custom/models/find_page.py b/indoteknik_custom/models/find_page.py index 697fd275..467e30d1 100644 --- a/indoteknik_custom/models/find_page.py +++ b/indoteknik_custom/models/find_page.py @@ -1,8 +1,11 @@ from odoo import fields, models, api, tools, _ import logging import re +import pysolr _logger = logging.getLogger(__name__) +_cat_brand_solr = pysolr.Solr('http://10.148.0.5:8983/solr/url_category_brand/', always_commit=True, timeout=30) +# _cat_brand_solr_dev = pysolr.Solr('http://127.0.0.1:8983/solr/url_category_brand/', always_commit=True, timeout=30) class BrandProductCategory(models.Model): @@ -35,6 +38,26 @@ class FindPage(models.Model): category_id = fields.Many2one('product.public.category', string='Category', help='Bisa semua level Category') url = fields.Char(string='Url') + def _sync_to_solr(self, limit=10000): + urls = self.env['web.find.page'].search([]) + documents = [] + catch = {} + for url in urls: + try: + document = { + 'id': url.id, + 'category_id_i': url.category_id.id, + 'brand_id_i': url.brand_id.id, + 'url_s': url.url + } + documents.append(document) + catch = document + except Exception as e: + _logger.error('Failed to add document to Solr URL Category Brand: %s', e) + _logger.error('Document Data: %s', catch) + _cat_brand_solr.add(documents) + return True + def _get_category_hierarchy(self, category): categories = [] current_category = category -- cgit v1.2.3 From 3fa5e5bfe91969b4ab74a43a63ab673a76aff9da Mon Sep 17 00:00:00 2001 From: Azka Nathan Date: Wed, 23 Oct 2024 15:26:16 +0700 Subject: cr requisition --- indoteknik_custom/models/requisition.py | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/indoteknik_custom/models/requisition.py b/indoteknik_custom/models/requisition.py index 2b148c96..c4104ec5 100644 --- a/indoteknik_custom/models/requisition.py +++ b/indoteknik_custom/models/requisition.py @@ -214,6 +214,7 @@ class RequisitionLine(models.Model): last_price = fields.Float(string='Last Price') last_order_id = fields.Many2one('purchase.order', string='Last Order') last_orderline_id = fields.Many2one('purchase.order.line', string='Last Order Line') + taxes_id = fields.Many2one('account.tax', string='Tax') is_po = fields.Boolean(String='Is PO') current_po_id = fields.Many2one('purchase.order', string='Current') current_po_line_id = fields.Many2one('purchase.order.line', string='Current Line') @@ -221,6 +222,23 @@ class RequisitionLine(models.Model): qty_available_store = fields.Float(string='Available') suggest = fields.Char(string='Suggest') + def _get_valid_purchase_price(self, purchase_price): + price = 0 + taxes = '' + human_last_update = purchase_price.human_last_update or datetime.min + system_last_update = purchase_price.system_last_update or datetime.min + + if purchase_price.taxes_product_id.type_tax_use == 'purchase': + price = purchase_price.product_price + taxes = purchase_price.taxes_product_id.id + + if system_last_update > human_last_update: + if purchase_price.taxes_system_id.type_tax_use == 'purchase': + price = purchase_price.system_price + taxes = purchase_price.taxes_system_id.id + + return price, taxes + @api.onchange('price_unit') def _onchange_price_unit(self): for line in self: @@ -230,6 +248,15 @@ class RequisitionLine(models.Model): def _onchange_product(self): for line in self: line.brand_id = line.product_id.product_tmpl_id.x_manufacture.id + purchase_pricelist = self.env['purchase.pricelist'].search([ + ('product_id', '=', line.product_id.id) + ],order='count_trx_po desc, count_trx_po_vendor desc', limit=1) + + price, taxes = line._get_valid_purchase_price(purchase_pricelist) + line.price_unit = price + line.taxes_id = taxes + line.partner_id = purchase_pricelist.vendor_id.id + class RequisitionPurchaseMatch(models.Model): _name = 'requisition.purchase.match' -- cgit v1.2.3 From 0b740ccb154fc89e04b41f3b6a199dec4657b7de Mon Sep 17 00:00:00 2001 From: Azka Nathan Date: Wed, 23 Oct 2024 15:55:28 +0700 Subject: cr rpo --- indoteknik_custom/views/requisition.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/indoteknik_custom/views/requisition.xml b/indoteknik_custom/views/requisition.xml index 652d03d0..b704baaf 100644 --- a/indoteknik_custom/views/requisition.xml +++ b/indoteknik_custom/views/requisition.xml @@ -78,6 +78,7 @@ + -- cgit v1.2.3 From a7be93f4825967807f12e6bfbebcf090af8500fa Mon Sep 17 00:00:00 2001 From: Azka Nathan Date: Thu, 24 Oct 2024 11:02:01 +0700 Subject: cr user company request --- indoteknik_custom/models/user_company_request.py | 23 ++++++++++++----------- 1 file changed, 12 insertions(+), 11 deletions(-) diff --git a/indoteknik_custom/models/user_company_request.py b/indoteknik_custom/models/user_company_request.py index 6d809385..86e66934 100644 --- a/indoteknik_custom/models/user_company_request.py +++ b/indoteknik_custom/models/user_company_request.py @@ -23,24 +23,25 @@ class UserCompanyRequest(models.Model): else: record.similar_company_ids = [(6, 0, [])] - def get_similar_companies(self, user_input): - query = """ - SELECT id - FROM res_partner - WHERE levenshtein(name::text, %s) < 3 - ORDER BY levenshtein(name::text, %s) ASC - """ - self.env.cr.execute(query, (user_input, user_input)) - return [row[0] for row in self.env.cr.fetchall()] + # def get_similar_companies(self, user_input): + # query = """ + # SELECT id + # FROM res_partner + # WHERE levenshtein(name::text, %s) < 3 + # ORDER BY levenshtein(name::text, %s) ASC + # """ + # self.env.cr.execute(query, (user_input, user_input)) + # return [row[0] for row in self.env.cr.fetchall()] def get_similar_companies(self, user_input): query = """ SELECT id FROM res_partner - WHERE name ILIKE %s OR levenshtein(name::text, %s) < 3 + WHERE (name ILIKE %s OR levenshtein(name::text, %s) < 3) + AND active = TRUE AND is_company = TRUE ORDER BY levenshtein(name::text, %s) ASC """ - # Using '%' to match the partial company name + # Menggunakan '%' untuk mencocokkan nama perusahaan sebagian self.env.cr.execute(query, ('%' + user_input + '%', user_input, user_input)) company_ids = [row[0] for row in self.env.cr.fetchall()] return company_ids -- cgit v1.2.3 From af190fa1e5e9301d84307b39b1927f77d3f0ee21 Mon Sep 17 00:00:00 2001 From: Azka Nathan Date: Fri, 25 Oct 2024 09:03:36 +0700 Subject: fix bug date reserved --- indoteknik_custom/models/stock_picking.py | 73 +++++++++++++++++++++++-------- indoteknik_custom/views/stock_picking.xml | 4 ++ 2 files changed, 59 insertions(+), 18 deletions(-) diff --git a/indoteknik_custom/models/stock_picking.py b/indoteknik_custom/models/stock_picking.py index 2a73d631..df72dadf 100644 --- a/indoteknik_custom/models/stock_picking.py +++ b/indoteknik_custom/models/stock_picking.py @@ -110,43 +110,78 @@ class StockPicking(models.Model): def action_send_to_biteship(self): url = "https://api.biteship.com/v1/orders" - api_key = "biteship_test.eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJuYW1lIjoiSW5kb3Rla25payIsInVzZXJJZCI6IjY3MTViYTJkYzVkMjdkMDAxMjRjODk2MiIsImlhdCI6MTcyOTQ5ODAwMX0.L6C73couP4-cgVEfhKI2g7eMCMo3YOFSRZhS-KSuHNA" - items_data = [] - for item in self.items: - items_data.append({ - "name": item.name, - "description": item.description, - "category": item.category, - "value": item.value, - "quantity": item.quantity, - "weight": item.weight - }) - + # Mencari data sale.order.line berdasarkan sale_id + products = self.env['sale.order.line'].search([('order_id', '=', self.sale_id.id)]) + + # Fungsi untuk membangun items_data dari order lines + def build_items_data(lines): + return [{ + "name": line.product_id.name, + "description": line.name, + "value": line.price_unit, + "quantity": line.product_uom_qty, + "weight": line.weight + } for line in lines] + + # Items untuk pengiriman standard + items_data_standard = build_items_data(products) + + # Items untuk pengiriman instant, mengambil product_id dari move_line_ids_without_package + items_data_instant = [] + for move_line in self.move_line_ids_without_package: + # Mencari baris di sale.order.line berdasarkan product_id dari move_line + order_line = self.env['sale.order.line'].search([ + ('order_id', '=', self.sale_id.id), + ('product_id', '=', move_line.product_id.id) + ], limit=1) + + if order_line: + items_data_instant.append({ + "name": order_line.product_id.name, + "description": order_line.name, + "value": order_line.price_unit, + "quantity": move_line.qty_done, # Menggunakan qty_done dari move_line + "weight": order_line.weight + }) + payload = { "shipper_contact_name": self.carrier_id.pic_name or '', "shipper_contact_phone": self.carrier_id.pic_phone or '', - # "shipper_contact_email": "sales@indoteknik.co.id", "shipper_organization": self.carrier_id.name, "origin_contact_name": "PT. Indoteknik Dotcom Gemilang", "origin_contact_phone": "081717181922", "origin_address": "Jl. Bandengan Utara Komp A & BRT. Penjaringan, Kec. Penjaringan, Jakarta (BELAKANG INDOMARET) KOTA JAKARTA UTARA PENJARINGAN", - "origin_postal_code": "14440", + "origin_postal_code": 14440, "destination_contact_name": self.real_shipping_id.name, "destination_contact_phone": self.real_shipping_id.phone or self.real_shipping_id.mobile, - "destination_contact_email": self.real_shipping_id.email or '', "destination_address": self.real_shipping_id.street, "destination_postal_code": self.real_shipping_id.zip, - "items": items_data + "courier_type": "reg", + "courier_company": self.carrier_id.name.lower(), + "delivery_type": "now", + "destination_postal_code": self.real_shipping_id.zip, + "items": items_data_standard } + # Cek jika pengiriman instant atau same_day + if "instant" in self.sale_id.delivery_service_type or "same_day" in self.sale_id.delivery_service_type: + payload.update({ + "origin_note": "BELAKANG INDOMARET", + "courier_company": self.carrier_id.name.lower(), + "courier_type": self.sale_id.delivery_service_type, + "delivery_type": "now", + "items": items_data_instant # Gunakan items untuk instant + }) + headers = { "Authorization": f"Bearer {api_key}", "Content-Type": "application/json" } - response = requests.post(url, headers=headers, data=json.dumps(payload)) + # Kirim request ke Biteship + response = requests.post(url, headers=headers, json=payload) if response.status_code == 201: return response.json() @@ -218,7 +253,9 @@ class StockPicking(models.Model): ]) data.state_reserve = 'ready' - data.date_reserved = datetime.datetime.utcnow() + if not data.date_reserved: + data.date_reserved = datetime.datetime.utcnow() + for rec in fullfilment: if rec.reserved_from not in ['Inventory On Hand', 'Reserved from stock', 'Free Stock']: data.state_reserve = 'waiting' diff --git a/indoteknik_custom/views/stock_picking.xml b/indoteknik_custom/views/stock_picking.xml index d713edbc..b5087e35 100644 --- a/indoteknik_custom/views/stock_picking.xml +++ b/indoteknik_custom/views/stock_picking.xml @@ -52,6 +52,10 @@ type="object" attrs="{'invisible': ['|', ('state', '!=', 'done'), ('name', 'ilike', 'out')]}" /> + -- cgit v1.2.3 From bf6db57611262036be96e2f7cc93e315b208f174 Mon Sep 17 00:00:00 2001 From: Azka Nathan Date: Fri, 25 Oct 2024 14:00:02 +0700 Subject: bills pelunasan --- indoteknik_custom/models/purchase_order.py | 70 ++++++++++++++++++++++++++++++ indoteknik_custom/views/purchase_order.xml | 7 ++- 2 files changed, 76 insertions(+), 1 deletion(-) diff --git a/indoteknik_custom/models/purchase_order.py b/indoteknik_custom/models/purchase_order.py index f924174a..c24bdbb3 100755 --- a/indoteknik_custom/models/purchase_order.py +++ b/indoteknik_custom/models/purchase_order.py @@ -68,6 +68,7 @@ class PurchaseOrder(models.Model): ], string='Printed?', copy=False, tracking=True) date_done_picking = fields.Datetime(string='Date Done Picking', compute='get_date_done') bills_dp_id = fields.Many2one('account.move', string='Bills DP') + bills_pelunasan_id = fields.Many2one('account.move', string='Bills Pelunasan') grand_total = fields.Monetary(string='Grand Total', help='Amount total + amount delivery', compute='_compute_grand_total') total_margin_match = fields.Float(string='Total Margin Match', compute='_compute_total_margin_match') approve_by = fields.Many2one('res.users', string='Approve By') @@ -89,6 +90,75 @@ class PurchaseOrder(models.Model): else: order.grand_total = order.amount_total + def create_bill_pelunasan(self): + if not self.env.user.is_accounting: + raise UserError('Hanya Accounting yang bisa bikin bill dp') + + # Check for existing vendor bills with the same reference and partner + existing_bill = self.env['account.move'].search([ + ('ref', '=', self.name), + ('partner_id', '=', self.partner_id.id), + ('move_type', '=', 'in_invoice'), + ('state', 'not in', ['cancel', 'posted']) + ], limit=1) + + if existing_bill: + raise UserError(_('Duplicated vendor reference detected. You probably encoded twice the same vendor bill/credit note: %s') % existing_bill.name) + + current_date = datetime.utcnow() + data_bills = { + 'partner_id': self.partner_id.id, + 'partner_shipping_id': self.partner_id.id, + 'ref': self.name, + 'invoice_date': current_date, + 'date': current_date, + 'move_type': 'in_invoice' + } + + bills = self.env['account.move'].create([data_bills]) + + product_dp = self.env['product.product'].browse(229625) + + data_line_bills = [] + + data_line_bills.append({ + 'move_id': bills.id, + 'product_id': product_dp.id, # product down payment + 'name': '[IT.121456] Down Payment', # product down payment + 'account_id': 401, # Uang Muka persediaan barang dagang + 'quantity': -1, + 'product_uom_id': 1, + 'tax_ids': [(5, 0, 0)] + [(4, tax.id) for tax in product_dp.taxes_id], + }) + + for line in self.order_line: + if line.product_id: + data_line_bills.append({ + 'move_id': bills.id, + 'product_id': line.product_id.id, + 'name': self.name + ": " + line.product_id.display_name, + 'account_id': 439, # Uang Muka persediaan barang dagang + 'quantity': line.product_qty, + 'price_unit': line.price_unit, + 'product_uom_id': line.product_uom.id, + 'tax_ids': [(5, 0, 0)] + [(4, tax.id) for tax in line.taxes_id], + }) + + bills_line = self.env['account.move.line'].create(data_line_bills) + + self.bills_pelunasan_id = bills.id + + return { + 'name': _('Account Move'), + 'view_mode': 'tree,form', + 'res_model': 'account.move', + 'target': 'current', + 'type': 'ir.actions.act_window', + 'domain': [('id', '=', bills.id)] + } + + + def create_bill_dp(self): if not self.env.user.is_accounting: raise UserError('Hanya Accounting yang bisa bikin bill dp') diff --git a/indoteknik_custom/views/purchase_order.xml b/indoteknik_custom/views/purchase_order.xml index 3e609f15..06c76a82 100755 --- a/indoteknik_custom/views/purchase_order.xml +++ b/indoteknik_custom/views/purchase_order.xml @@ -27,7 +27,11 @@ + @@ -100,6 +104,7 @@ + -- cgit v1.2.3 From db612e07fdebc8c053e6708bf612f68324cf07bb Mon Sep 17 00:00:00 2001 From: Azka Nathan Date: Tue, 29 Oct 2024 13:56:50 +0700 Subject: cr crm lead and res partner --- indoteknik_api/models/res_users.py | 3 +++ indoteknik_custom/models/crm_lead.py | 2 ++ indoteknik_custom/models/res_partner.py | 6 ++++++ 3 files changed, 11 insertions(+) diff --git a/indoteknik_api/models/res_users.py b/indoteknik_api/models/res_users.py index 2751ca7a..230707cb 100644 --- a/indoteknik_api/models/res_users.py +++ b/indoteknik_api/models/res_users.py @@ -59,6 +59,9 @@ class ResUsers(models.Model): 'rajaongkir_city_id': user.kecamatan_id.rajaongkir_id or 0, 'alamat_wajib_pajak': user.alamat_lengkap_text or None, 'alamat_bisnis': user.street or None, + 'longtitude': user.longtitude or None, + 'latitude': user.latitude or None, + 'address_map': user.address_map or None, } if user.state_id: diff --git a/indoteknik_custom/models/crm_lead.py b/indoteknik_custom/models/crm_lead.py index de2bdb12..050168a5 100755 --- a/indoteknik_custom/models/crm_lead.py +++ b/indoteknik_custom/models/crm_lead.py @@ -31,6 +31,8 @@ class CrmLead(models.Model): if rec.email_from == 'api.noreply@altama.co.id' and rec.name.startswith('INDOTEKNIK|ODOO|'): rec.user_id = 20 # User ID: Nabila Rahmawati + if not rec.user_id: + rec.user_id = 20 # User ID: Nabila Rahmawati return rec @api.onchange('user_id') diff --git a/indoteknik_custom/models/res_partner.py b/indoteknik_custom/models/res_partner.py index 25db16d0..b01c7984 100644 --- a/indoteknik_custom/models/res_partner.py +++ b/indoteknik_custom/models/res_partner.py @@ -48,6 +48,12 @@ class ResPartner(models.Model): date_payment_terms_sales = fields.Datetime(string='Date Update Payment Terms') user_payment_terms_purchase = fields.Many2one('res.users', string='Users Update Payment Terms') date_payment_terms_purchase = fields.Datetime(string='Date Update Payment Terms') + longtitude = fields.Char(string='Longtitude') + latitude = fields.Char(string='Latitude') + address_map = fields.Char(string='Address Map') + company_type = fields.Selection(string='Company Type', + selection=[('person', 'Individual'), ('company', 'Company')], + compute='_compute_company_type', inverse='_write_company_type', tracking=3) @api.model def _default_payment_term(self): -- cgit v1.2.3 From 8710bda7da6915023f916d42df20a7b6df431b69 Mon Sep 17 00:00:00 2001 From: Azka Nathan Date: Tue, 29 Oct 2024 14:17:44 +0700 Subject: cr crm lead --- indoteknik_custom/models/crm_lead.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/indoteknik_custom/models/crm_lead.py b/indoteknik_custom/models/crm_lead.py index 050168a5..078d9810 100755 --- a/indoteknik_custom/models/crm_lead.py +++ b/indoteknik_custom/models/crm_lead.py @@ -32,7 +32,7 @@ class CrmLead(models.Model): rec.user_id = 20 # User ID: Nabila Rahmawati if not rec.user_id: - rec.user_id = 20 # User ID: Nabila Rahmawati + rec.user_id = 2 # User ID: Sales return rec @api.onchange('user_id') -- cgit v1.2.3 From 9206adc3ce8f5011b4b2e42c25a310419c1947d5 Mon Sep 17 00:00:00 2001 From: Azka Nathan Date: Wed, 30 Oct 2024 16:10:56 +0700 Subject: cr bill pelunasan --- indoteknik_custom/models/purchase_order.py | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/indoteknik_custom/models/purchase_order.py b/indoteknik_custom/models/purchase_order.py index c24bdbb3..393fc562 100755 --- a/indoteknik_custom/models/purchase_order.py +++ b/indoteknik_custom/models/purchase_order.py @@ -121,11 +121,23 @@ class PurchaseOrder(models.Model): data_line_bills = [] + move_line = self.env['account.move.line'].search([ + ('move_id', '=', self.bills_dp_id.id), + ('product_id', '=', product_dp.id), + ]) + + bills.message_post( + body=f"
" + f"DP :
{move_line.price_unit}
", + subtype_id=self.env.ref("mail.mt_note").id + ) + data_line_bills.append({ 'move_id': bills.id, 'product_id': product_dp.id, # product down payment 'name': '[IT.121456] Down Payment', # product down payment 'account_id': 401, # Uang Muka persediaan barang dagang + # 'price_unit': move_line.price_unit, 'quantity': -1, 'product_uom_id': 1, 'tax_ids': [(5, 0, 0)] + [(4, tax.id) for tax in product_dp.taxes_id], @@ -139,9 +151,11 @@ class PurchaseOrder(models.Model): 'name': self.name + ": " + line.product_id.display_name, 'account_id': 439, # Uang Muka persediaan barang dagang 'quantity': line.product_qty, - 'price_unit': line.price_unit, + # 'price_unit': line.price_subtotal, 'product_uom_id': line.product_uom.id, 'tax_ids': [(5, 0, 0)] + [(4, tax.id) for tax in line.taxes_id], + 'purchase_line_id': line.id, + 'purchase_order_id': line[0].order_id.id, }) bills_line = self.env['account.move.line'].create(data_line_bills) -- cgit v1.2.3 From 9b86d64f64e149d26b5e33254fefd5dfc15ce1c4 Mon Sep 17 00:00:00 2001 From: Azka Nathan Date: Thu, 31 Oct 2024 09:03:21 +0700 Subject: approval retur picking --- indoteknik_custom/__manifest__.py | 1 + indoteknik_custom/models/__init__.py | 1 + indoteknik_custom/models/approval_retur_picking.py | 38 ++++++++++++++++++++++ indoteknik_custom/models/stock_picking.py | 16 ++++++++- indoteknik_custom/security/ir.model.access.csv | 1 + indoteknik_custom/views/approval_retur_picking.xml | 27 +++++++++++++++ 6 files changed, 83 insertions(+), 1 deletion(-) create mode 100644 indoteknik_custom/models/approval_retur_picking.py create mode 100644 indoteknik_custom/views/approval_retur_picking.xml diff --git a/indoteknik_custom/__manifest__.py b/indoteknik_custom/__manifest__.py index c8a658b5..da44ebf3 100755 --- a/indoteknik_custom/__manifest__.py +++ b/indoteknik_custom/__manifest__.py @@ -145,6 +145,7 @@ 'views/approval_unreserve.xml', 'views/vendor_approval.xml', 'views/find_page.xml', + 'views/approval_retur_picking.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 e62fbb4a..4983cc17 100755 --- a/indoteknik_custom/models/__init__.py +++ b/indoteknik_custom/models/__init__.py @@ -131,3 +131,4 @@ from . import approval_unreserve from . import vendor_approval from . import partner from . import find_page +from . import approval_retur_picking diff --git a/indoteknik_custom/models/approval_retur_picking.py b/indoteknik_custom/models/approval_retur_picking.py new file mode 100644 index 00000000..63639782 --- /dev/null +++ b/indoteknik_custom/models/approval_retur_picking.py @@ -0,0 +1,38 @@ +from odoo import models, fields +import logging + +_logger = logging.getLogger(__name__) + + +class ApprovalReturPicking(models.TransientModel): + _name = 'approval.retur.picking' + _description = 'Wizard to add Note Return' + + note_return = fields.Text(string="Note Return", required=True) + + def action_confirm_note_return(self): + picking_ids = self._context.get('picking_ids') + picking = self.env['stock.picking'].browse(picking_ids) + + # Update the note_return field + picking.update({ + 'note_return': self.note_return + }) + + # Post a highlighted message to lognote + picking.message_post( + body=f"
" + f"Note Return (Pinned):
{self.note_return}
", + subtype_id=self.env.ref("mail.mt_note").id + ) + + return { + 'type': 'ir.actions.client', + 'tag': 'display_notification', + 'params': { + 'title': 'Notification', + 'message': 'Note berhasil ditambah', + 'next': {'type': 'ir.actions.act_window_close'}, + } + } + diff --git a/indoteknik_custom/models/stock_picking.py b/indoteknik_custom/models/stock_picking.py index 4c9d7658..107a6e72 100644 --- a/indoteknik_custom/models/stock_picking.py +++ b/indoteknik_custom/models/stock_picking.py @@ -104,6 +104,7 @@ class StockPicking(models.Model): ('to invoice', 'To Invoice'), ('no', 'Nothing to Invoice') ], string='Invoice Status', related="sale_id.invoice_status") + note_return = fields.Text(string="Note Return", help="Catatan untuk kirim barang kembali") state_reserve = fields.Selection([ ('waiting', 'Waiting For Fullfilment'), @@ -445,6 +446,11 @@ class StockPicking(models.Model): pick.approval_return_status = 'approved' else: pick.approval_return_status = 'pengajuan1' + 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 def calculate_line_no(self): for picking in self: @@ -503,6 +509,9 @@ class StockPicking(models.Model): def button_validate(self): + if not self.env.user.is_logistic_approver and 'Return of' in self.origin: + raise UserError("Button ini hanya untuk Logistik") + if self._name != 'stock.picking': return super(StockPicking, self).button_validate() @@ -553,6 +562,11 @@ class StockPicking(models.Model): self.date_done = datetime.datetime.utcnow() self.state_reserve = 'done' return res + def action_cancel(self): + if not self.env.user.is_logistic_approver and 'Return of' in self.origin: + raise UserError("Button ini hanya untuk Logistik") + res = super(StockPicking, self).action_cancel() + return res @api.model def create(self, vals): @@ -688,4 +702,4 @@ class StockPicking(models.Model): 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}' + return f'{formatted_fastest_eta} - {formatted_longest_eta}' \ No newline at end of file diff --git a/indoteknik_custom/security/ir.model.access.csv b/indoteknik_custom/security/ir.model.access.csv index 553047e6..06848ad7 100755 --- a/indoteknik_custom/security/ir.model.access.csv +++ b/indoteknik_custom/security/ir.model.access.csv @@ -143,3 +143,4 @@ access_vendor_approval_line,access.vendor.approval.line,model_vendor_approval_li access_vit_kota,access.vit.kota,model_vit_kota,,1,1,1,1 access_v_brand_product_category,access.v.brand.product.category,model_v_brand_product_category,,1,1,1,1 access_web_find_page,access.web.find.page,model_web_find_page,,1,1,1,1 +access_approval_retur_picking,access.approval.retur.picking,model_approval_retur_picking,,1,1,1,1 diff --git a/indoteknik_custom/views/approval_retur_picking.xml b/indoteknik_custom/views/approval_retur_picking.xml new file mode 100644 index 00000000..ebe038d1 --- /dev/null +++ b/indoteknik_custom/views/approval_retur_picking.xml @@ -0,0 +1,27 @@ + + + + approval.retur.picking.form + approval.retur.picking + +
+ + + +
+
+
+
+
+ + + + Add Return Note + approval.retur.picking + form + + new + +
-- cgit v1.2.3 From 57f30e319a3f3c6c6c87418ffb12e44ac6846fe2 Mon Sep 17 00:00:00 2001 From: Azka Nathan Date: Thu, 31 Oct 2024 11:47:44 +0700 Subject: cr contacts --- indoteknik_api/controllers/api_v1/partner.py | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/indoteknik_api/controllers/api_v1/partner.py b/indoteknik_api/controllers/api_v1/partner.py index a7925a02..bbca471b 100644 --- a/indoteknik_api/controllers/api_v1/partner.py +++ b/indoteknik_api/controllers/api_v1/partner.py @@ -74,6 +74,9 @@ class Partner(controller.Controller): 'district_id': ['number', 'alias:kecamatan_id'], 'sub_district_id': ['number', 'alias:kelurahan_id', 'exclude_if_null'], 'zip': ['required'], + 'longtitude': [], + 'latitude': [], + 'address_map': [], 'alamat_lengkap_text': [] }) @@ -105,6 +108,9 @@ class Partner(controller.Controller): 'city_id': ['required', 'number', 'alias:kota_id'], 'district_id': ['number', 'alias:kecamatan_id'], 'sub_district_id': ['number', 'alias:kelurahan_id', 'exclude_if_null'], + 'longtitude': [], + 'latitude': [], + 'address_map': [], 'zip': ['required'] }) -- cgit v1.2.3 From 926ab9c6d505eff4accbfd1e5472e0e63e900a30 Mon Sep 17 00:00:00 2001 From: Azka Nathan Date: Fri, 1 Nov 2024 10:50:52 +0700 Subject: cr approval unreserve --- indoteknik_custom/models/approval_unreserve.py | 2 +- indoteknik_custom/models/logbook_sj.py | 6 ++++-- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/indoteknik_custom/models/approval_unreserve.py b/indoteknik_custom/models/approval_unreserve.py index 07ddda1f..ba8b8da7 100644 --- a/indoteknik_custom/models/approval_unreserve.py +++ b/indoteknik_custom/models/approval_unreserve.py @@ -74,7 +74,7 @@ class ApprovalUnreserve(models.Model): raise UserError("Quantity yang di unreserve melebihi quantity yang ada") def action_approve(self): - if self.env.user.id != self.user_id.id: + if self.env.user.id != self.user_id.id and not self.env.user.has_group('indoteknik_custom.group_role_it'): raise UserError("Hanya Sales nya yang bisa approve.") if self.state != 'waiting_approval': diff --git a/indoteknik_custom/models/logbook_sj.py b/indoteknik_custom/models/logbook_sj.py index f84619ad..9f349882 100644 --- a/indoteknik_custom/models/logbook_sj.py +++ b/indoteknik_custom/models/logbook_sj.py @@ -101,14 +101,16 @@ class LogbookSJLine(models.TransientModel): delivery_type = self.get_delivery_type(picking.driver_departure_date, picking.driver_arrival_date) if delivery_type != 'departure': - self.departure_date = picking.driver_departure_date.astimezone(timezone('Asia/Jakarta')).strftime('%Y-%m-%d %H:%M:%S') + if picking.driver_departure_date: + self.departure_date = picking.driver_departure_date.astimezone(timezone('Asia/Jakarta')).strftime('%Y-%m-%d %H:%M:%S') if delivery_type == 'departure': self.departure_date = current_time elif delivery_type == 'arrival': self.arrival_date = current_time else: - self.arrival_date = picking.driver_arrival_date.astimezone(timezone('Asia/Jakarta')).strftime('%Y-%m-%d %H:%M:%S') + if picking.driver_arrival_date: + self.arrival_date = picking.driver_arrival_date.astimezone(timezone('Asia/Jakarta')).strftime('%Y-%m-%d %H:%M:%S') else: raise UserError('Nomor DO tidak ditemukan') -- cgit v1.2.3 From d55ed85f466cc437645a19756c8d13694b1f9305 Mon Sep 17 00:00:00 2001 From: Azka Nathan Date: Fri, 1 Nov 2024 11:15:41 +0700 Subject: cr delivery order sj retur date --- indoteknik_custom/models/delivery_order.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/indoteknik_custom/models/delivery_order.py b/indoteknik_custom/models/delivery_order.py index be5fd2e0..04b99711 100644 --- a/indoteknik_custom/models/delivery_order.py +++ b/indoteknik_custom/models/delivery_order.py @@ -37,7 +37,7 @@ class DeliveryOrder(models.TransientModel): if delivery_type == 'departure': picking.driver_departure_date = current_time elif delivery_type == 'arrival': - picking.driver_arrival_date = current_time + picking.sj_return_date = datetime.utcnow() sale_order = False if picking.origin: -- cgit v1.2.3 From 388942b58b47da9425c253db13036a80fbcf4ce4 Mon Sep 17 00:00:00 2001 From: Azka Nathan Date: Fri, 1 Nov 2024 14:33:53 +0700 Subject: fix bug purchasing job --- indoteknik_custom/models/delivery_order.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/indoteknik_custom/models/delivery_order.py b/indoteknik_custom/models/delivery_order.py index 04b99711..2ed49a54 100644 --- a/indoteknik_custom/models/delivery_order.py +++ b/indoteknik_custom/models/delivery_order.py @@ -103,14 +103,16 @@ class DeliveryOrderLine(models.TransientModel): delivery_type = self.get_delivery_type(picking.driver_departure_date, picking.driver_arrival_date) if delivery_type != 'departure': - self.departure_date = picking.driver_departure_date.astimezone(timezone('Asia/Jakarta')).strftime('%Y-%m-%d %H:%M:%S') + if picking.driver_departure_date: + self.departure_date = picking.driver_departure_date.astimezone(timezone('Asia/Jakarta')).strftime('%Y-%m-%d %H:%M:%S') if delivery_type == 'departure': self.departure_date = current_time elif delivery_type == 'arrival': self.arrival_date = current_time else: - self.arrival_date = picking.driver_arrival_date.astimezone(timezone('Asia/Jakarta')).strftime('%Y-%m-%d %H:%M:%S') + if picking.driver_arrival_date: + self.arrival_date = picking.driver_arrival_date.astimezone(timezone('Asia/Jakarta')).strftime('%Y-%m-%d %H:%M:%S') else: raise UserError('Nomor DO tidak ditemukan') -- cgit v1.2.3 From f59c345864c67fbcedb06a15f8a7cf44c9a37e05 Mon Sep 17 00:00:00 2001 From: Azka Nathan Date: Fri, 1 Nov 2024 16:18:43 +0700 Subject: cr stock picking --- indoteknik_custom/views/stock_picking.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/indoteknik_custom/views/stock_picking.xml b/indoteknik_custom/views/stock_picking.xml index c230bc7b..69b29f9b 100644 --- a/indoteknik_custom/views/stock_picking.xml +++ b/indoteknik_custom/views/stock_picking.xml @@ -134,7 +134,7 @@ - + -- cgit v1.2.3 From 100fa7ec1d9ccfc02712096dceca3decc2311abb Mon Sep 17 00:00:00 2001 From: Azka Nathan Date: Fri, 1 Nov 2024 16:42:46 +0700 Subject: cr view stock picking --- indoteknik_custom/views/stock_picking.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/indoteknik_custom/views/stock_picking.xml b/indoteknik_custom/views/stock_picking.xml index 69b29f9b..c230bc7b 100644 --- a/indoteknik_custom/views/stock_picking.xml +++ b/indoteknik_custom/views/stock_picking.xml @@ -134,7 +134,7 @@ - + -- cgit v1.2.3 From 7afd1ef51e18f9dcb1c0e71ea1e512b52284d3d1 Mon Sep 17 00:00:00 2001 From: stephanchrst Date: Tue, 5 Nov 2024 11:09:46 +0700 Subject: add sticky note while ask approval --- indoteknik_custom/models/purchase_order.py | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/indoteknik_custom/models/purchase_order.py b/indoteknik_custom/models/purchase_order.py index 393fc562..6fc0c497 100755 --- a/indoteknik_custom/models/purchase_order.py +++ b/indoteknik_custom/models/purchase_order.py @@ -730,7 +730,20 @@ class PurchaseOrder(models.Model): elif self.total_percent_margin == self.total_so_percent_margin and self.sale_order_id: raise UserError("Bisa langsung Confirm") else: + reason = '' self.approval_status = 'pengajuan1' + if self.amount_untaxed >= 50000000: + reason = 'above 50jt, ' + if self.total_percent_margin < self.total_so_percent_margin: + reason += 'diff margin, ' + if not self.from_apo and not self.sale_order_id: + reason += 'not link with sales, ' + # Post a highlighted message to lognote + self.message_post( + body=f"
" + f"Note Return (Pinned):
{reason}
", + subtype_id=self.env.ref("mail.mt_note").id + ) def re_calculate(self): if self.from_apo: -- cgit v1.2.3 From 772d42fba3fddccd3ca951bbedadeca4044593a9 Mon Sep 17 00:00:00 2001 From: it-fixcomart Date: Tue, 5 Nov 2024 12:04:45 +0700 Subject: add error handling ask aproval --- indoteknik_custom/models/sale_order.py | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/indoteknik_custom/models/sale_order.py b/indoteknik_custom/models/sale_order.py index 1ad08154..8e170b1c 100755 --- a/indoteknik_custom/models/sale_order.py +++ b/indoteknik_custom/models/sale_order.py @@ -768,7 +768,28 @@ class SaleOrder(models.Model): self._validate_order() for order in self: order.order_line.validate_line() + order.check_data_real_delivery_address() + order._validate_order() + order.sale_order_check_approve() + + main_parent = order.partner_id.get_main_parent() + SYSTEM_UID = 25 + FROM_WEBSITE = order.create_uid.id == SYSTEM_UID + if FROM_WEBSITE and main_parent.use_so_approval and order.web_approval not in ['cust_procurement','cust_director']: + raise UserError("This order not yet approved by customer procurement or director") + + if not order.client_order_ref and order.create_date > datetime(2024, 6, 27): + raise UserError("Customer Reference kosong, di isi dengan NO PO jika PO tidak ada mohon ditulis Tanpa PO") + + if not order.commitment_date and order.create_date > datetime(2024, 9, 12): + raise UserError("Expected Delivery Date kosong, wajib diisi") + + if not order.real_shipping_id: + UserError('Real Delivery Address harus di isi') + + if order.validate_partner_invoice_due(): + return self._create_notification_action('Notification','Terdapat invoice yang telah melewati batas waktu, mohon perbarui pada dokumen Due Extension') term_days = 0 for term_line in order.payment_term_id.line_ids: -- cgit v1.2.3 From 9602db0d08b64f50e02d3e25ab3846221bf2cb08 Mon Sep 17 00:00:00 2001 From: stephanchrst Date: Tue, 5 Nov 2024 13:22:35 +0700 Subject: temporary disable reserve stock --- indoteknik_custom/views/purchase_order.xml | 1 - 1 file changed, 1 deletion(-) diff --git a/indoteknik_custom/views/purchase_order.xml b/indoteknik_custom/views/purchase_order.xml index 06c76a82..0e6b6792 100755 --- a/indoteknik_custom/views/purchase_order.xml +++ b/indoteknik_custom/views/purchase_order.xml @@ -212,7 +212,6 @@ model.procure_calculation() code 75 - True -- cgit v1.2.3 From 4a3ff9e6fc85f534c106198c0ceee4e8c33eba5c Mon Sep 17 00:00:00 2001 From: it-fixcomart Date: Wed, 6 Nov 2024 09:50:38 +0700 Subject: update bug products_inactive on user carts --- indoteknik_api/controllers/api_v1/cart.py | 21 +++++++++++++++++++-- indoteknik_custom/models/website_user_cart.py | 24 +++++++++++++++++++++++- 2 files changed, 42 insertions(+), 3 deletions(-) diff --git a/indoteknik_api/controllers/api_v1/cart.py b/indoteknik_api/controllers/api_v1/cart.py index 2a24b205..7a40b1e2 100644 --- a/indoteknik_api/controllers/api_v1/cart.py +++ b/indoteknik_api/controllers/api_v1/cart.py @@ -46,8 +46,25 @@ class Cart(controller.Controller): def get_cart_count_by_user_id(self, user_id, **kw): user_id = int(user_id) query = [('user_id', '=', user_id)] - carts = request.env['website.user.cart'].search_count(query) - return self.response(carts) + carts = request.env['website.user.cart'].search(query) + products_active = [] + products_inactive = [] + for cart in carts: + if cart.product_id: + price = cart.product_id._v2_get_website_price_include_tax() + if cart.product_id.active and price > 0: + product = cart.with_context(price_for="web").get_products() + for product_active in product: + products_active.append(product_active) + else: + product_inactives = cart.with_context(price_for="web").get_products() + for inactives in product_inactives: + products_inactive.append(inactives) + else: + program = cart.with_context(price_for="web").get_products() + for programs in program: + products_active.append(programs) + return self.response(len(products_active)) @http.route(PREFIX_USER + 'cart/create-or-update', auth='public', methods=['POST', 'OPTIONS'], csrf=False) @controller.Controller.must_authorized(private=True, private_key='user_id') diff --git a/indoteknik_custom/models/website_user_cart.py b/indoteknik_custom/models/website_user_cart.py index 26e217cb..fbcb0aa4 100644 --- a/indoteknik_custom/models/website_user_cart.py +++ b/indoteknik_custom/models/website_user_cart.py @@ -108,8 +108,30 @@ class WebsiteUserCart(models.Model): parameters.append(('is_selected', '=', True)) carts = self.search(parameters) + products_active = [] + products_inactive = [] + for cart in carts: + if cart.product_id: + price = cart.product_id._v2_get_website_price_include_tax() + if cart.product_id.active and price > 0: + product = cart.with_context(price_for="web").get_products() + for product_active in product: + products_active.append(product_active) + else: + product_inactives = cart.with_context(price_for="web").get_products() + for inactives in product_inactives: + products_inactive.append(inactives) + else: + program = cart.with_context(price_for="web").get_products() + for programs in program: + products_active.append(programs) + data = { + 'product_total': self.search_count(parameters), + 'products': products_active, + 'products_inactive': products_inactive + } products = carts.get_products() - return products + return products_active def get_user_checkout(self, user_id, voucher=False, voucher_shipping=False, source=False): products = self.get_product_by_user(user_id=user_id, selected=True, source=source) -- cgit v1.2.3 From 7712141e5fa515eb6b966ae63956e7bbb3f384f3 Mon Sep 17 00:00:00 2001 From: Azka Nathan Date: Wed, 6 Nov 2024 11:19:34 +0700 Subject: fix bug wati --- indoteknik_custom/models/wati.py | 50 +++++++++++++++------------------------- 1 file changed, 18 insertions(+), 32 deletions(-) diff --git a/indoteknik_custom/models/wati.py b/indoteknik_custom/models/wati.py index d9fb7247..eed5413e 100644 --- a/indoteknik_custom/models/wati.py +++ b/indoteknik_custom/models/wati.py @@ -192,27 +192,6 @@ class WatiHistory(models.Model): is_get_attribute = fields.Boolean(string='Get Attribute', default=False) def _get_attribute_wati(self): - # url = 'https://live-server-2106.wati.io/api/v1/getContacts' - - # cookies = { - # 'affinity': '1701232090.884.1520.321410|ff187ffce9bc0bae13542bb446e41008', - # } - - # headers = { - # 'Authorization': 'Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJqdGkiOiI3MGM5ZmJhNy00MWRlLTRkMWEtYjY2NS1hM2Q5ODc2ZjhlZWIiLCJ1bmlxdWVfbmFtZSI6InR5YXNAaW5kb3Rla25pay5jb20iLCJuYW1laWQiOiJ0eWFzQGluZG90ZWtuaWsuY29tIiwiZW1haWwiOiJ0eWFzQGluZG90ZWtuaWsuY29tIiwiYXV0aF90aW1lIjoiMTEvMjkvMjAyMyAwNDoxNzo0NyIsImRiX25hbWUiOiIyMTA2IiwiaHR0cDovL3NjaGVtYXMubWljcm9zb2Z0LmNvbS93cy8yMDA4LzA2L2lkZW50aXR5L2NsYWltcy9yb2xlIjoiQURNSU5JU1RSQVRPUiIsImV4cCI6MjUzNDAyMzAwODAwLCJpc3MiOiJDbGFyZV9BSSIsImF1ZCI6IkNsYXJlX0FJIn0.--KHv4GCOG2MM3lNW9Nm-0-d8OAVpn5kbcSX4JKqATQ', - # # 'Cookie': 'affinity=1701232090.884.1520.321410|ff187ffce9bc0bae13542bb446e41008', - # } - - # files = { - # 'pageSize': (None, '1'), - # 'pageNumber': (None, '1'), - # 'name': (None, ''), - # 'attribute': (None, '[{name: "phone", operator: "contain", value: "6285751430014"}]'), - # 'createdDate': (None, ''), - # } - - # response = requests.get(url, cookies=cookies, headers=headers, files=files) - # print(response.json()) domain = [ '&', ('is_get_attribute', '=', False), @@ -226,29 +205,36 @@ class WatiHistory(models.Model): for wati_history in wati_histories: count += 1 _logger.info('[Parse Notification] Process: %s/%s' % (str(count), str(limit))) + wati_api = self.env['wati.api'] + + # Perbaikan pada params 'attribute' untuk menghindari masalah "type object is not subscriptable" params = { - 'pageSize':1, - 'pageNumber':1, - 'attribute':[{'name': "phone", 'operator': "contain", 'value': wati_history.wa_id}], + 'pageSize': 1, + 'pageNumber': 1, + 'attribute': json.dumps([{'name': "phone", 'operator': "contain", 'value': wati_history.wa_id}]), } + wati_contacts = wati_api.http_get('/api/v1/getContacts', params) - if wati_contacts['result'] != 'success': + + if wati_contacts.get('result') != 'success': return - json_dump = json.dumps(wati_contacts, indent=4, sort_keys=True) - contact_list = json.loads(json_dump)['contact_list'] + + contact_list = wati_contacts.get('contact_list', []) + perusahaan = email = '' for data in contact_list: - custom_params = data['customParams'] + custom_params = data.get('customParams', []) for custom_param in custom_params: - name = custom_param['name'] - value = custom_param['value'] + name = custom_param.get('name') + value = custom_param.get('value') if name == 'perusahaan': perusahaan = value elif name == 'email': email = value - # end for 2 - # end for 1 + # End inner loop + + # Update wati_history fields wati_history.perusahaan = perusahaan wati_history.email = email wati_history.is_get_attribute = True -- cgit v1.2.3 From a9afcfa5b6c6e071aefe708b865b37124ba54d1f Mon Sep 17 00:00:00 2001 From: Azka Nathan Date: Wed, 6 Nov 2024 14:11:52 +0700 Subject: add image mobile to solr --- indoteknik_custom/models/solr/product_product.py | 1 + 1 file changed, 1 insertion(+) diff --git a/indoteknik_custom/models/solr/product_product.py b/indoteknik_custom/models/solr/product_product.py index 7c10a910..dd1d40f6 100644 --- a/indoteknik_custom/models/solr/product_product.py +++ b/indoteknik_custom/models/solr/product_product.py @@ -67,6 +67,7 @@ class ProductProduct(models.Model): 'product_id_i': variant.id, 'template_id_i': variant.product_tmpl_id.id, 'image_s': ir_attachment.api_image('product.template', 'image_512', variant.product_tmpl_id.id), + 'image_mobile_s': ir_attachment.api_image('product.template', 'image_256', variant.product_tmpl_id.id), 'stock_total_f': variant.qty_stock_vendor, 'weight_f': variant.weight, 'manufacture_id_i': variant.product_tmpl_id.x_manufacture.id or 0, -- cgit v1.2.3 From 295088070b43c409c2114a0a98d898ff3ff4ae7b Mon Sep 17 00:00:00 2001 From: Azka Nathan Date: Wed, 6 Nov 2024 14:47:19 +0700 Subject: cr solr product --- indoteknik_custom/models/solr/product_template.py | 1 + 1 file changed, 1 insertion(+) diff --git a/indoteknik_custom/models/solr/product_template.py b/indoteknik_custom/models/solr/product_template.py index 1d54cc9b..87e8370f 100644 --- a/indoteknik_custom/models/solr/product_template.py +++ b/indoteknik_custom/models/solr/product_template.py @@ -91,6 +91,7 @@ class ProductTemplate(models.Model): "product_rating_f": template.virtual_rating, "product_id_i": template.id, "image_s": self.env['ir.attachment'].api_image('product.template', 'image_512', template.id), + 'image_mobile_s': self.env['ir.attachment'].api_image('product.template', 'image_256', template.id), "variant_total_i": template.product_variant_count, "stock_total_f": template.qty_stock_vendor, "weight_f": template.weight, -- cgit v1.2.3 From 3b1c519848d69709aa64ff6078c7d2d45dc356b1 Mon Sep 17 00:00:00 2001 From: trisusilo48 Date: Wed, 6 Nov 2024 16:46:40 +0700 Subject: bugfix date time --- 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 f0c7456d..ea8c6400 100644 --- a/indoteknik_api/controllers/api_v1/stock_picking.py +++ b/indoteknik_api/controllers/api_v1/stock_picking.py @@ -123,7 +123,7 @@ class StockPicking(controller.Controller): params = {'sj_documentation': sj_document, 'paket_documentation': paket_document, - 'driver_arrival_date': self.time_to_str(datetime.utcnow(), '%Y-%m-%d %H:%M:%S'), + 'driver_arrival_date': datetime.utcnow(), } picking_data = request.env['stock.picking'].search([('picking_code', '=', picking_code)], limit=1) -- cgit v1.2.3 From 8b54606ef925ff2e6feb2794aabaafa4864e6961 Mon Sep 17 00:00:00 2001 From: stephanchrst Date: Wed, 6 Nov 2024 17:00:48 +0700 Subject: initial commit max plafon qty order --- indoteknik_custom/models/product_template.py | 25 +++++++++++++++++++++++-- indoteknik_custom/models/purchase_order.py | 11 ++++++++++- 2 files changed, 33 insertions(+), 3 deletions(-) diff --git a/indoteknik_custom/models/product_template.py b/indoteknik_custom/models/product_template.py index 2ca4925b..35844c22 100755 --- a/indoteknik_custom/models/product_template.py +++ b/indoteknik_custom/models/product_template.py @@ -374,6 +374,8 @@ class ProductProduct(models.Model): is_edited = fields.Boolean(string='Is Edited') qty_sold = fields.Float(string='Sold Quantity', compute='_get_qty_sold') short_spesification = fields.Char(string='Short Spesification') + max_qty_reorder = fields.Float(string='Max Qty Reorder', compute='_get_max_qty_reordering_rule') + plafon_qty = fields.Float(string='Max Plafon', compute='_get_plafon_qty_product') def _get_clean_website_description(self): for rec in self: @@ -487,13 +489,32 @@ class ProductProduct(models.Model): def _get_qty_available_bandengan(self): for product in self: qty_available = product.qty_incoming_bandengan + product.qty_onhand_bandengan - product.qty_outgoing_bandengan - product.qty_available_bandengan = qty_available + product.qty_available_bandengan = qty_available or 0 def _get_qty_free_bandengan(self): for product in self: qty_free = product.qty_onhand_bandengan - product.qty_outgoing_bandengan product.qty_free_bandengan = qty_free - + + def _get_max_qty_reordering_rule(self): + for product in self: + reordering = self.env['stock.warehouse.orderpoint'].search([ + ('product_id', '=', product.id) + ], limit=1) + if not reordering: + product.max_qty_reorder = 0 + else: + product.max_qty_reorder = reordering.product_max_qty + test = reordering.product_max_qty + print(test) + + def _get_plafon_qty_product(self): + for product in self: + qty_available = product.qty_available_bandengan + max_qty = product.max_qty_reorder + product.plafon_qty = max_qty - qty_available + + # def write(self, vals): # if 'solr_flag' not in vals: # for variant in self: diff --git a/indoteknik_custom/models/purchase_order.py b/indoteknik_custom/models/purchase_order.py index 6fc0c497..510695a6 100755 --- a/indoteknik_custom/models/purchase_order.py +++ b/indoteknik_custom/models/purchase_order.py @@ -583,6 +583,14 @@ class PurchaseOrder(models.Model): picking.scheduled_date = self.date_planned picking.date_deadline = self.date_planned + def _check_qty_plafon_product(self): + for line in self.order_line: + if not line.product_id: + continue + test = line.product_id.plafon_qty + if line.product_uom_qty > line.product_id.plafon_qty: + raise UserError('Product '+line.product_id.name+' melebihi plafon') + def button_confirm(self): res = super(PurchaseOrder, self).button_confirm() current_time = datetime.now() @@ -635,7 +643,8 @@ class PurchaseOrder(models.Model): self.date_planned = delta_time self.date_deadline_ref_date_planned() self.unlink_purchasing_job_state() - + + self._check_qty_plafon_product() return res -- cgit v1.2.3 From ca625dc60de8bbf53e21326abc24c210ea0f8f71 Mon Sep 17 00:00:00 2001 From: Azka Nathan Date: Thu, 7 Nov 2024 11:51:13 +0700 Subject: cr archive and unpublished product variant --- indoteknik_custom/models/product_template.py | 49 ++++++++++++++++++++-------- 1 file changed, 36 insertions(+), 13 deletions(-) diff --git a/indoteknik_custom/models/product_template.py b/indoteknik_custom/models/product_template.py index 2ca4925b..e64b63d7 100755 --- a/indoteknik_custom/models/product_template.py +++ b/indoteknik_custom/models/product_template.py @@ -389,23 +389,46 @@ class ProductProduct(models.Model): @api.constrains('active') def archive_product(self): for product in self: + if self.env.context.get('skip_unpublished_constraint'): + continue # Mencegah looping saat dipanggil dari metode lain + product_template = product.product_tmpl_id variants = product_template.product_variant_ids - if product_template.active and product.active: - if not product.active and len(variants) == 1: - product_template.with_context(skip_active_constraint=True).active = False - product_template.unpublished = True - elif not product.active and len(variants) > 1: + if len(variants) == 1: + # Jika hanya ada satu varian, atur status `unpublished` berdasarkan `active` + product_template.with_context(skip_unpublished_constraint=True).unpublished = not product.active + product.with_context(skip_unpublished_constraint=True).unpublished = not product.active + else: + if product.active: + product.with_context(skip_unpublished_constraint=True).unpublished = False + product_template.with_context(skip_unpublished_constraint=True).unpublished = any(variant.active for variant in variants) + else: + product.with_context(skip_unpublished_constraint=True).unpublished = True all_inactive = all(not variant.active for variant in variants) - if all_inactive: - product_template.with_context(skip_active_constraint=True).active = False - product_template.unpublished = True - else: - continue - if any(variant.active for variant in variants): - product_template.unpublished = False - variants.unpublished = False + product_template.with_context(skip_unpublished_constraint=True).unpublished = all_inactive + + @api.constrains('unpublished') + def archive_product_unpublished(self): + for product in self: + if self.env.context.get('skip_active_constraint'): + continue # Mencegah looping saat dipanggil dari metode lain + + product_template = product.product_tmpl_id + variants = product_template.product_variant_ids + + if len(variants) == 1: + # Jika hanya ada satu varian, atur status `unpublished` pada template, tetapi biarkan `active` tetap True + product_template.with_context(skip_active_constraint=True).unpublished = product.unpublished + else: + if not product.unpublished: + # Jika `unpublished` adalah False, pastikan `active` tetap True + product.with_context(skip_active_constraint=True).active = True + product_template.with_context(skip_active_constraint=True).active = any(not variant.unpublished for variant in variants) + else: + # Jika `unpublished` adalah True, atur template hanya jika semua varian di-unpublished + all_unpublished = all(variant.unpublished for variant in variants) + product_template.with_context(skip_active_constraint=True).active = not all_unpublished def update_internal_reference_variants(self, limit=100): variants = self.env['product.product'].search([ -- cgit v1.2.3 From 0e87cd50902756c86c975505a7dde2239d94968c Mon Sep 17 00:00:00 2001 From: stephanchrst Date: Thu, 7 Nov 2024 13:47:35 +0700 Subject: bug fix wrong price in website user cart --- indoteknik_custom/models/website_user_cart.py | 41 +++++++++------------------ 1 file changed, 14 insertions(+), 27 deletions(-) diff --git a/indoteknik_custom/models/website_user_cart.py b/indoteknik_custom/models/website_user_cart.py index fbcb0aa4..2142dada 100644 --- a/indoteknik_custom/models/website_user_cart.py +++ b/indoteknik_custom/models/website_user_cart.py @@ -93,45 +93,32 @@ class WebsiteUserCart(models.Model): def get_product_by_user(self, user_id, selected=False, source=False): user_id = int(user_id) - + if source == 'buy': source = ['buy'] else: source = ['add_to_cart', 'buy'] parameters = [ - ('user_id', '=', user_id), + ('user_id', '=', user_id), ('source', 'in', source) ] - - if selected: - parameters.append(('is_selected', '=', True)) - carts = self.search(parameters) - products_active = [] - products_inactive = [] + for cart in carts: if cart.product_id: price = cart.product_id._v2_get_website_price_include_tax() - if cart.product_id.active and price > 0: - product = cart.with_context(price_for="web").get_products() - for product_active in product: - products_active.append(product_active) - else: - product_inactives = cart.with_context(price_for="web").get_products() - for inactives in product_inactives: - products_inactive.append(inactives) - else: - program = cart.with_context(price_for="web").get_products() - for programs in program: - products_active.append(programs) - data = { - 'product_total': self.search_count(parameters), - 'products': products_active, - 'products_inactive': products_inactive - } - products = carts.get_products() - return products_active + if not cart.product_id.active and price < 1: + cart.is_selected = False + + if selected: + parameters.append(('is_selected', '=', True)) + + products_active = self.search(parameters) + + products = products_active.get_products() + + return products def get_user_checkout(self, user_id, voucher=False, voucher_shipping=False, source=False): products = self.get_product_by_user(user_id=user_id, selected=True, source=source) -- cgit v1.2.3 From 779002da16637df255b7f8ead65ccb49078d6190 Mon Sep 17 00:00:00 2001 From: stephanchrst Date: Thu, 7 Nov 2024 13:57:38 +0700 Subject: bf --- indoteknik_custom/models/website_user_cart.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/indoteknik_custom/models/website_user_cart.py b/indoteknik_custom/models/website_user_cart.py index 2142dada..6cb282f8 100644 --- a/indoteknik_custom/models/website_user_cart.py +++ b/indoteknik_custom/models/website_user_cart.py @@ -108,7 +108,7 @@ class WebsiteUserCart(models.Model): for cart in carts: if cart.product_id: price = cart.product_id._v2_get_website_price_include_tax() - if not cart.product_id.active and price < 1: + if not cart.product_id.active or price < 1: cart.is_selected = False if selected: -- cgit v1.2.3 From f787f06a341f1775151d98be4490fe6126c511cd Mon Sep 17 00:00:00 2001 From: stephanchrst Date: Thu, 7 Nov 2024 15:59:57 +0700 Subject: excelude incoming --- indoteknik_custom/models/product_template.py | 12 ++++++++++-- indoteknik_custom/models/purchase_order.py | 2 ++ 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/indoteknik_custom/models/product_template.py b/indoteknik_custom/models/product_template.py index 35844c22..d3343e75 100755 --- a/indoteknik_custom/models/product_template.py +++ b/indoteknik_custom/models/product_template.py @@ -466,6 +466,16 @@ class ProductProduct(models.Model): qty = sum(qty_incoming.mapped('product_uom_qty')) product.qty_incoming_bandengan = qty + def _get_qty_incoming_bandengan_with_exclude(self): + for product in self: + qty_incoming = self.env['stock.move'].search([ + ('product_id', '=', product.id), + ('location_dest_id', 'in', [57, 83]), + ('state', 'not in', ['done', 'cancel']) + ]) + qty = sum(qty_incoming.mapped('product_uom_qty')) + product.qty_incoming_bandengan = qty + def _get_qty_outgoing_bandengan(self): for product in self: qty_incoming = self.env['stock.move'].search([ @@ -505,8 +515,6 @@ class ProductProduct(models.Model): product.max_qty_reorder = 0 else: product.max_qty_reorder = reordering.product_max_qty - test = reordering.product_max_qty - print(test) def _get_plafon_qty_product(self): for product in self: diff --git a/indoteknik_custom/models/purchase_order.py b/indoteknik_custom/models/purchase_order.py index 510695a6..231acb4c 100755 --- a/indoteknik_custom/models/purchase_order.py +++ b/indoteknik_custom/models/purchase_order.py @@ -72,6 +72,8 @@ class PurchaseOrder(models.Model): grand_total = fields.Monetary(string='Grand Total', help='Amount total + amount delivery', compute='_compute_grand_total') total_margin_match = fields.Float(string='Total Margin Match', compute='_compute_total_margin_match') approve_by = fields.Many2one('res.users', string='Approve By') + exclude_incoming = fields.Boolean(string='Exclude Incoming', default=False, + help='Centang jika tidak mau masuk perhitungan Incoming Qty') def _compute_total_margin_match(self): for purchase in self: -- cgit v1.2.3 From 9c54bae83c5fc50d2ca894a7e75d9beb156d3e9c Mon Sep 17 00:00:00 2001 From: stephanchrst Date: Thu, 7 Nov 2024 16:13:00 +0700 Subject: must link with matches so if want to skip approval --- indoteknik_custom/models/purchase_order.py | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/indoteknik_custom/models/purchase_order.py b/indoteknik_custom/models/purchase_order.py index 6fc0c497..ef86bc61 100755 --- a/indoteknik_custom/models/purchase_order.py +++ b/indoteknik_custom/models/purchase_order.py @@ -595,7 +595,7 @@ class PurchaseOrder(models.Model): if self.total_percent_margin < self.total_so_percent_margin and not self.env.user.has_group('indoteknik_custom.group_role_merchandiser') and not self.env.user.is_leader: raise UserError("Beda Margin dengan Sales, harus approval Merchandise") if not self.from_apo: - if not self.sale_order_id and not self.env.user.has_group('indoteknik_custom.group_role_merchandiser') and not self.env.user.is_leader: + if not self.matches_so and not self.env.user.has_group('indoteknik_custom.group_role_merchandiser') and not self.env.user.is_leader: raise UserError("Tidak ada link dengan SO, harus approval Merchandise") send_email = False @@ -727,7 +727,7 @@ class PurchaseOrder(models.Model): raise UserError("Hanya Merchandiser yang bisa approve") 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.sale_order_id: + elif self.total_percent_margin == self.total_so_percent_margin and self.matches_so: raise UserError("Bisa langsung Confirm") else: reason = '' @@ -736,12 +736,14 @@ class PurchaseOrder(models.Model): reason = 'above 50jt, ' if self.total_percent_margin < self.total_so_percent_margin: reason += 'diff margin, ' - if not self.from_apo and not self.sale_order_id: - reason += 'not link with sales, ' + if not self.from_apo and not self.matches_so: + reason += 'not link with pj and reorder, ' + if not self.matches_so: + reason += 'not link with so, ' # Post a highlighted message to lognote self.message_post( body=f"
" - f"Note Return (Pinned):
{reason}
", + f"Note (Pinned):
{reason}
", subtype_id=self.env.ref("mail.mt_note").id ) -- cgit v1.2.3 From 8d4ba8a22aa90a7c2dfad48c5de38ee17b68db60 Mon Sep 17 00:00:00 2001 From: Azka Nathan Date: Thu, 7 Nov 2024 16:21:20 +0700 Subject: deactivate function constrains driver departure date date doc kirim --- indoteknik_custom/models/stock_picking.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/indoteknik_custom/models/stock_picking.py b/indoteknik_custom/models/stock_picking.py index 4c9d7658..a4031d52 100644 --- a/indoteknik_custom/models/stock_picking.py +++ b/indoteknik_custom/models/stock_picking.py @@ -192,9 +192,9 @@ class StockPicking(models.Model): else: raise UserError(f"Error saat mengirim ke Biteship: {response.content}") - @api.constrains('driver_departure_date') - def constrains_driver_departure_date(self): - self.date_doc_kirim = self.driver_departure_date + # @api.constrains('driver_departure_date') + # def constrains_driver_departure_date(self): + # self.date_doc_kirim = self.driver_departure_date @api.constrains('arrival_time') def constrains_arrival_time(self): -- cgit v1.2.3 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_api/controllers/api_v1/sale_order.py | 6 +++++- indoteknik_api/models/sale_order.py | 2 ++ indoteknik_custom/models/sale_order.py | 1 + 3 files changed, 8 insertions(+), 1 deletion(-) diff --git a/indoteknik_api/controllers/api_v1/sale_order.py b/indoteknik_api/controllers/api_v1/sale_order.py index e7664c79..99ba2573 100644 --- a/indoteknik_api/controllers/api_v1/sale_order.py +++ b/indoteknik_api/controllers/api_v1/sale_order.py @@ -150,7 +150,8 @@ class SaleOrder(controller.Controller): def partner_checkout_sale_order_by_id(self, **kw): params = self.get_request_params(kw, { 'partner_id': ['number'], - 'id': ['number'] + 'id': ['number'], + 'status': ['boolean'] }) if not params['valid']: return self.response(code=400, description=params) @@ -163,6 +164,9 @@ class SaleOrder(controller.Controller): data = {} sale_order = request.env['sale.order'].search(domain) if sale_order: + if 'status' in params['value']: + sale_order.is_continue_transaction = params['value']['status'] + if sale_order._requires_approval_margin_leader(): sale_order.approval_status = 'pengajuan2' elif sale_order._requires_approval_margin_manager(): diff --git a/indoteknik_api/models/sale_order.py b/indoteknik_api/models/sale_order.py index 725dbb4b..3f9606a5 100644 --- a/indoteknik_api/models/sale_order.py +++ b/indoteknik_api/models/sale_order.py @@ -39,6 +39,8 @@ class SaleOrder(models.Model): data['status'] = 'cancel' if sale_order.state in ['draft', 'sent']: data['status'] = 'draft' + if sale_order.is_continue_transaction: + data['status'] = 'waiting' if sale_order.approval_status in ['pengajuan1', 'pengajuan2']: data['status'] = 'waiting' if sale_order.state == 'sale': 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 02e7b5f913c4f740124d28c078c4f6f1185d9b0f Mon Sep 17 00:00:00 2001 From: Azka Nathan Date: Fri, 8 Nov 2024 11:12:06 +0700 Subject: cr sj return date do --- indoteknik_custom/models/delivery_order.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/indoteknik_custom/models/delivery_order.py b/indoteknik_custom/models/delivery_order.py index 2ed49a54..3473197b 100644 --- a/indoteknik_custom/models/delivery_order.py +++ b/indoteknik_custom/models/delivery_order.py @@ -33,11 +33,13 @@ class DeliveryOrder(models.TransientModel): picking.driver_id = self.env.uid picking.delivery_tracking_no = line_tracking_no + if picking.driver_departure_date: + picking.sj_return_date = datetime.utcnow() + delivery_type = self.env['delivery.order.line'].get_delivery_type(picking.driver_departure_date, picking.driver_arrival_date) if delivery_type == 'departure': picking.driver_departure_date = current_time elif delivery_type == 'arrival': - picking.sj_return_date = datetime.utcnow() sale_order = False if picking.origin: -- 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_api/models/res_users.py | 6 +++++- indoteknik_custom/models/res_partner.py | 13 +++++++++++-- indoteknik_custom/models/sale_order.py | 8 +++++++- indoteknik_custom/models/user_company_request.py | 2 +- 4 files changed, 24 insertions(+), 5 deletions(-) diff --git a/indoteknik_api/models/res_users.py b/indoteknik_api/models/res_users.py index 230707cb..52a044dc 100644 --- a/indoteknik_api/models/res_users.py +++ b/indoteknik_api/models/res_users.py @@ -14,6 +14,9 @@ class ResUsers(models.Model): 'manager': 2, 'director': 3 } + partner_tempo = False + if main_partner: + partner_tempo = main_partner.get_check_tempo_partner() data = { 'id': res_user.id, @@ -32,7 +35,8 @@ class ResUsers(models.Model): 'feature': { 'so_approval': main_partner.use_so_approval, 'only_ready_stock': main_partner.use_only_ready_stock - } + }, + 'partner_tempo': partner_tempo } return data 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 1d7d90b35078c82ed1904bfb4486e172488bf747 Mon Sep 17 00:00:00 2001 From: Azka Nathan Date: Fri, 8 Nov 2024 14:08:10 +0700 Subject: cr function state reserve transfer --- indoteknik_custom/models/stock_picking.py | 27 ++++++++++++--------------- 1 file changed, 12 insertions(+), 15 deletions(-) diff --git a/indoteknik_custom/models/stock_picking.py b/indoteknik_custom/models/stock_picking.py index a4031d52..1906dae0 100644 --- a/indoteknik_custom/models/stock_picking.py +++ b/indoteknik_custom/models/stock_picking.py @@ -246,25 +246,22 @@ class StockPicking(models.Model): # break def check_state_reserve(self): - picking = self.search([ + pickings = self.search([ ('state', 'not in', ['cancel', 'draft', 'done']), ('picking_type_code', '=', 'outgoing') - ]) + ]) - for data in picking: - fullfilment = self.env['sales.order.fullfillment'].search([ - ('sales_order_id', '=', data.sale_id.id) + for picking in pickings: + fullfillments = self.env['sales.order.fullfillment'].search([ + ('sales_order_id', '=', picking.sale_id.id) ]) - - data.state_reserve = 'ready' - if not data.date_reserved: - data.date_reserved = datetime.datetime.utcnow() - - for rec in fullfilment: - if rec.reserved_from not in ['Inventory On Hand', 'Reserved from stock', 'Free Stock']: - data.state_reserve = 'waiting' - data.date_reserved = '' - break + + picking.state_reserve = 'ready' + picking.date_reserved = picking.date_reserved or datetime.datetime.utcnow() + + if any(rec.reserved_from not in ['Inventory On Hand', 'Reserved from stock', 'Free Stock'] for rec in fullfillments): + picking.state_reserve = 'waiting' + picking.date_reserved = '' def _create_approval_notification(self, approval_role): title = 'Warning' -- 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(-) 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 8423e5b2facd32aec17ac67d95ffc83e7bc311b7 Mon Sep 17 00:00:00 2001 From: Azka Nathan Date: Fri, 8 Nov 2024 15:39:37 +0700 Subject: cr vendor approval --- indoteknik_custom/models/sale_order.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/indoteknik_custom/models/sale_order.py b/indoteknik_custom/models/sale_order.py index 8e170b1c..5545e28c 100755 --- a/indoteknik_custom/models/sale_order.py +++ b/indoteknik_custom/models/sale_order.py @@ -78,7 +78,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) + vendor_approval_id = fields.Many2one('vendor.approval', string="Vendor Approval", readonly=True, tracking=True, copy=False) customer_type = fields.Selection([ ('pkp', 'PKP'), ('nonpkp', 'Non PKP') -- cgit v1.2.3 From 5a53288558a0adf7bff223f745be75cf48cb252f Mon Sep 17 00:00:00 2001 From: Azka Nathan Date: Fri, 8 Nov 2024 16:16:04 +0700 Subject: fix bug approval date doc --- indoteknik_custom/models/approval_date_doc.py | 1 + 1 file changed, 1 insertion(+) diff --git a/indoteknik_custom/models/approval_date_doc.py b/indoteknik_custom/models/approval_date_doc.py index 441ada3d..751bae82 100644 --- a/indoteknik_custom/models/approval_date_doc.py +++ b/indoteknik_custom/models/approval_date_doc.py @@ -40,6 +40,7 @@ class ApprovalDateDoc(models.Model): raise UserError("Hanya Accounting Yang Bisa Approve") self.check_invoice_so_picking self.picking_id.driver_departure_date = self.driver_departure_date + self.picking_id.date_doc_kirim = self.driver_departure_date self.state = 'done' self.approve_date = datetime.utcnow() self.approve_by = self.env.user.id -- cgit v1.2.3 From de1fa6223484ea424ae9b6bcf3f3fedf75ae6bb1 Mon Sep 17 00:00:00 2001 From: Azka Nathan Date: Mon, 11 Nov 2024 10:11:59 +0700 Subject: fix vendor approval bug --- indoteknik_custom/models/sale_order_line.py | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/indoteknik_custom/models/sale_order_line.py b/indoteknik_custom/models/sale_order_line.py index 5e01067a..f218757b 100644 --- a/indoteknik_custom/models/sale_order_line.py +++ b/indoteknik_custom/models/sale_order_line.py @@ -251,12 +251,9 @@ class SaleOrderLine(models.Model): # purchase_price = self.env['purchase.pricelist'].search( # query, limit=1, order='count_trx_po desc, count_trx_po_vendor desc') price, taxes, vendor_id = self._get_purchase_price(line.product_id) - line.vendor_md_id = vendor_id line.vendor_id = vendor_id - line.margin_md = line.item_percent_margin line.tax_id = line.order_id.sales_tax_id # price, taxes = line._get_valid_purchase_price(purchase_price) - line.purchase_price_md = price line.purchase_price = price line.purchase_tax_id = taxes @@ -270,6 +267,14 @@ class SaleOrderLine(models.Model): line.name = line_name line.weight = line.product_id.weight + @api.constrains('vendor_id') + def _check_vendor_id(self): + for line in self: + price, taxes, vendor_id = self._get_purchase_price(line.product_id) + line.vendor_md_id = vendor_id + line.margin_md = line.item_percent_margin + line.purchase_price_md = price + def compute_delivery_amt_line(self): for line in self: try: -- cgit v1.2.3 From 20060408d381fddf859d3e99ee9dcdd187ac1329 Mon Sep 17 00:00:00 2001 From: Azka Nathan Date: Mon, 11 Nov 2024 10:30:56 +0700 Subject: fix bug --- indoteknik_custom/models/sale_order_line.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/indoteknik_custom/models/sale_order_line.py b/indoteknik_custom/models/sale_order_line.py index f218757b..fe6d9b8c 100644 --- a/indoteknik_custom/models/sale_order_line.py +++ b/indoteknik_custom/models/sale_order_line.py @@ -271,7 +271,7 @@ class SaleOrderLine(models.Model): def _check_vendor_id(self): for line in self: price, taxes, vendor_id = self._get_purchase_price(line.product_id) - line.vendor_md_id = vendor_id + line.vendor_md_id = vendor_id if vendor_id else '' line.margin_md = line.item_percent_margin line.purchase_price_md = price -- cgit v1.2.3 From 3404e2526fd4d95fc93224fbcfb5ddbfd254dcb5 Mon Sep 17 00:00:00 2001 From: Azka Nathan Date: Mon, 11 Nov 2024 10:37:35 +0700 Subject: fix bug vendor md --- indoteknik_custom/models/sale_order_line.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/indoteknik_custom/models/sale_order_line.py b/indoteknik_custom/models/sale_order_line.py index fe6d9b8c..978b1f69 100644 --- a/indoteknik_custom/models/sale_order_line.py +++ b/indoteknik_custom/models/sale_order_line.py @@ -271,7 +271,7 @@ class SaleOrderLine(models.Model): def _check_vendor_id(self): for line in self: price, taxes, vendor_id = self._get_purchase_price(line.product_id) - line.vendor_md_id = vendor_id if vendor_id else '' + line.vendor_md_id = vendor_id if vendor_id else None line.margin_md = line.item_percent_margin line.purchase_price_md = price -- cgit v1.2.3 From 3c5b4bbecca6614c0b6f894e41e9551793957b00 Mon Sep 17 00:00:00 2001 From: stephanchrst Date: Mon, 11 Nov 2024 13:24:11 +0700 Subject: bug fix match requisition and purchase order --- indoteknik_custom/models/requisition.py | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/indoteknik_custom/models/requisition.py b/indoteknik_custom/models/requisition.py index c4104ec5..92b222a8 100644 --- a/indoteknik_custom/models/requisition.py +++ b/indoteknik_custom/models/requisition.py @@ -108,6 +108,13 @@ class Requisition(models.Model): new_po_line = self.env['purchase.order.line'].create([param_line]) line.current_po_id = new_po.id line.current_po_line_id = new_po_line.id + + self.env['requisition.purchase.match'].create([{ + 'requisition_id': self.id, + 'order_id': new_po.id + }]) + self.is_po = True + return po_ids # def create_po_from_requisition(self): -- cgit v1.2.3 From c8359019759d78dcddea6d419c4a8f8eebe23c69 Mon Sep 17 00:00:00 2001 From: stephanchrst Date: Mon, 11 Nov 2024 13:27:04 +0700 Subject: validasi SO harus diisi pada saat create PO di requisition --- indoteknik_custom/models/requisition.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/indoteknik_custom/models/requisition.py b/indoteknik_custom/models/requisition.py index 92b222a8..576857df 100644 --- a/indoteknik_custom/models/requisition.py +++ b/indoteknik_custom/models/requisition.py @@ -35,6 +35,8 @@ class Requisition(models.Model): raise UserError('Tidak ada Lines, belum bisa create PO') if self.is_po: raise UserError('Sudah pernah di create PO') + if self.sale_order_id: + raise UserError('Tidak ada link dengan Sales Order, tidak bisa dihitung sebagai Plafon Qty di PO') vendor_ids = self.env['requisition.line'].read_group([ ('requisition_id', '=', self.id), -- cgit v1.2.3 From 1bb2d9edb764ee3de50b0a005ff40aeef60bf5d6 Mon Sep 17 00:00:00 2001 From: Azka Nathan Date: Mon, 11 Nov 2024 13:38:49 +0700 Subject: add approval sales manager and marketing manager on rpo --- indoteknik_custom/models/requisition.py | 16 ++++++++++++++++ indoteknik_custom/views/requisition.xml | 7 +++++++ 2 files changed, 23 insertions(+) diff --git a/indoteknik_custom/models/requisition.py b/indoteknik_custom/models/requisition.py index c4104ec5..a90a5718 100644 --- a/indoteknik_custom/models/requisition.py +++ b/indoteknik_custom/models/requisition.py @@ -22,15 +22,31 @@ class Requisition(models.Model): requisition_match = fields.One2many('requisition.purchase.match', 'requisition_id', string='Matches', auto_join=True) sale_order_id = fields.Many2one('sale.order', string='SO', help='harus diisi nomor SO yang ingin digenerate', domain="[('state', '=', 'sale')]") + sales_approve = fields.Boolean(string='Sales Approve', tracking=3, copy=False) + merchandise_approve = fields.Boolean(string='Merchandise Approve', tracking=3, copy=False) @api.model def create(self, vals): vals['number'] = self.env['ir.sequence'].next_by_code('requisition') or '0' result = super(Requisition, self).create(vals) return result + + def button_approve(self): + if self.env.user.id not in [377, 19]: + raise UserError('Hanya Vita dan Darren Yang Bisa Approve') + if self.env.user.id == 377: + self.sales_approve = True + elif self.env.user.id == 19: + if not self.sales_approve: + raise UserError('Vita Belum Approve') + self.merchandise_approve = True def create_po_from_requisition(self): + if not self.sales_approve: + raise UserError('Harus Di Approve oleh Vita') + if not self.merchandise_approve: + raise UserError('Harus Di Approve oleh Darren') if not self.requisition_lines: raise UserError('Tidak ada Lines, belum bisa create PO') if self.is_po: diff --git a/indoteknik_custom/views/requisition.xml b/indoteknik_custom/views/requisition.xml index b704baaf..cc537eda 100644 --- a/indoteknik_custom/views/requisition.xml +++ b/indoteknik_custom/views/requisition.xml @@ -50,6 +50,13 @@ requisition
+
+
-- cgit v1.2.3 From beefbce9a41d0210582cf8ceb6e4e7a6a5bc8fef Mon Sep 17 00:00:00 2001 From: stephanchrst Date: Mon, 11 Nov 2024 13:41:46 +0700 Subject: add view of requisition match po --- indoteknik_custom/models/requisition.py | 26 +++++++++++++++++++++++++- 1 file changed, 25 insertions(+), 1 deletion(-) diff --git a/indoteknik_custom/models/requisition.py b/indoteknik_custom/models/requisition.py index 576857df..e5053d34 100644 --- a/indoteknik_custom/models/requisition.py +++ b/indoteknik_custom/models/requisition.py @@ -1,4 +1,4 @@ -from odoo import models, fields, api, _ +from odoo import models, fields, api, tools, _ from odoo.exceptions import UserError from datetime import datetime import math @@ -7,6 +7,30 @@ import logging _logger = logging.getLogger(__name__) +class RequisitionMatchPO(models.Model): + _name = 'v.requisition.match.po' + _auto = False + _rec_name = 'purchase_id' + + id = fields.Integer(string='ID') + requisition_id = fields.Many2one('requisition', string='Requisition') + line_id = fields.Many2one('requisition.line', string='Requisition Line') + product_id = fields.Many2one('product.product', string='Product') + partner_id = fields.Many2one('res.partner', string='Partner') + purchase_id = fields.Many2one('purchase.order', string='Purchase Order') + + def init(self): + tools.drop_view_if_exists(self.env.cr, self._table) + self.env.cr.execute(""" + create or replace view %s as + select rpm.id as id, r.id as requisition_id, rl.id as line_id, rl.product_id, rl.partner_id, + rpm.order_id as purchase_id + from requisition_line rl + join requisition r on r.id = rl.requisition_id + join requisition_purchase_match rpm on rpm.requisition_id = r.id + """ % self._table) + + class Requisition(models.Model): _name = 'requisition' _order = 'id desc' -- cgit v1.2.3 From 03e9f9e8997836e37a5ab38798edb310ce6a6c76 Mon Sep 17 00:00:00 2001 From: stephanchrst Date: Mon, 11 Nov 2024 13:43:48 +0700 Subject: add sale order --- indoteknik_custom/models/requisition.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/indoteknik_custom/models/requisition.py b/indoteknik_custom/models/requisition.py index e5053d34..68c57e4c 100644 --- a/indoteknik_custom/models/requisition.py +++ b/indoteknik_custom/models/requisition.py @@ -24,7 +24,7 @@ class RequisitionMatchPO(models.Model): self.env.cr.execute(""" create or replace view %s as select rpm.id as id, r.id as requisition_id, rl.id as line_id, rl.product_id, rl.partner_id, - rpm.order_id as purchase_id + rpm.order_id as purchase_id, r.sale_order_id as sale_id from requisition_line rl join requisition r on r.id = rl.requisition_id join requisition_purchase_match rpm on rpm.requisition_id = r.id -- cgit v1.2.3 From e40f5a21ec251363b3b71d81b7801a782716ca0a Mon Sep 17 00:00:00 2001 From: Azka Nathan Date: Mon, 11 Nov 2024 13:43:58 +0700 Subject: add approval sales manager and marketing manager on rpo --- indoteknik_custom/models/requisition.py | 17 ++++++++++++++++- indoteknik_custom/views/requisition.xml | 7 +++++++ 2 files changed, 23 insertions(+), 1 deletion(-) diff --git a/indoteknik_custom/models/requisition.py b/indoteknik_custom/models/requisition.py index c4104ec5..e09c9e41 100644 --- a/indoteknik_custom/models/requisition.py +++ b/indoteknik_custom/models/requisition.py @@ -22,15 +22,30 @@ class Requisition(models.Model): requisition_match = fields.One2many('requisition.purchase.match', 'requisition_id', string='Matches', auto_join=True) sale_order_id = fields.Many2one('sale.order', string='SO', help='harus diisi nomor SO yang ingin digenerate', domain="[('state', '=', 'sale')]") + sales_approve = fields.Boolean(string='Sales Approve', tracking=3, copy=False) + merchandise_approve = fields.Boolean(string='Merchandise Approve', tracking=3, copy=False) @api.model def create(self, vals): vals['number'] = self.env['ir.sequence'].next_by_code('requisition') or '0' result = super(Requisition, self).create(vals) return result - + + def button_approve(self): + if self.env.user.id not in [377, 19]: + raise UserError('Hanya Vita dan Darren Yang Bisa Approve') + if self.env.user.id == 377: + self.sales_approve = True + elif self.env.user.id == 19: + if not self.sales_approve: + raise UserError('Vita Belum Approve') + self.merchandise_approve = True def create_po_from_requisition(self): + if not self.sales_approve: + raise UserError('Harus di Approve Vita') + if not self.merchandise_approve: + raise UserError('Harus di Approve Darren') if not self.requisition_lines: raise UserError('Tidak ada Lines, belum bisa create PO') if self.is_po: diff --git a/indoteknik_custom/views/requisition.xml b/indoteknik_custom/views/requisition.xml index b704baaf..a866690d 100644 --- a/indoteknik_custom/views/requisition.xml +++ b/indoteknik_custom/views/requisition.xml @@ -50,6 +50,13 @@ requisition +
+
-- cgit v1.2.3 From e573a766b997e4dc60935f8cc87e887d09f64b7a Mon Sep 17 00:00:00 2001 From: stephanchrst Date: Mon, 11 Nov 2024 13:53:22 +0700 Subject: add sale order condition in match requisition --- indoteknik_custom/models/requisition.py | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/indoteknik_custom/models/requisition.py b/indoteknik_custom/models/requisition.py index 68c57e4c..583a25c4 100644 --- a/indoteknik_custom/models/requisition.py +++ b/indoteknik_custom/models/requisition.py @@ -28,6 +28,11 @@ class RequisitionMatchPO(models.Model): from requisition_line rl join requisition r on r.id = rl.requisition_id join requisition_purchase_match rpm on rpm.requisition_id = r.id + join purchase_order po on po.id = rpm.order_id + join sale_order so on so.id = r.sale_order_id + where r.date_doc >= '2024-11-11' + and po.state in ('done', 'purchase') + and so.state in ('draft', 'sent') """ % self._table) -- cgit v1.2.3 From 9a0fd25e54491bd14a5b29b62b31a440dfa1bebc Mon Sep 17 00:00:00 2001 From: stephanchrst Date: Mon, 11 Nov 2024 14:10:13 +0700 Subject: change view requisition match --- indoteknik_custom/models/requisition.py | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/indoteknik_custom/models/requisition.py b/indoteknik_custom/models/requisition.py index 0ab78530..704ae8c0 100644 --- a/indoteknik_custom/models/requisition.py +++ b/indoteknik_custom/models/requisition.py @@ -13,26 +13,24 @@ class RequisitionMatchPO(models.Model): _rec_name = 'purchase_id' id = fields.Integer(string='ID') - requisition_id = fields.Many2one('requisition', string='Requisition') - line_id = fields.Many2one('requisition.line', string='Requisition Line') product_id = fields.Many2one('product.product', string='Product') - partner_id = fields.Many2one('res.partner', string='Partner') - purchase_id = fields.Many2one('purchase.order', string='Purchase Order') + qty_rpo = fields.Float(string='Qty RPO', help='Qty RPO yang sudah di PO namun SO masih Draft') def init(self): tools.drop_view_if_exists(self.env.cr, self._table) self.env.cr.execute(""" create or replace view %s as - select rpm.id as id, r.id as requisition_id, rl.id as line_id, rl.product_id, rl.partner_id, - rpm.order_id as purchase_id, r.sale_order_id as sale_id + select rl.product_id as id, rl.product_id, sum(rl.qty_purchase) as qty_rpo from requisition_line rl join requisition r on r.id = rl.requisition_id join requisition_purchase_match rpm on rpm.requisition_id = r.id join purchase_order po on po.id = rpm.order_id join sale_order so on so.id = r.sale_order_id - where r.date_doc >= '2024-11-11' + where 1=1 + and r.date_doc >= '2024-11-11' and po.state in ('done', 'purchase') and so.state in ('draft', 'sent') + group by rl.product_id """ % self._table) -- cgit v1.2.3 From ad4c738cb9a03f96cd4d7035ec13cafe4763e233 Mon Sep 17 00:00:00 2001 From: stephanchrst Date: Mon, 11 Nov 2024 14:38:05 +0700 Subject: add qty rpo on plafon qty --- indoteknik_custom/models/product_template.py | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/indoteknik_custom/models/product_template.py b/indoteknik_custom/models/product_template.py index 3bb06eaf..25473ab8 100755 --- a/indoteknik_custom/models/product_template.py +++ b/indoteknik_custom/models/product_template.py @@ -375,6 +375,7 @@ class ProductProduct(models.Model): qty_sold = fields.Float(string='Sold Quantity', compute='_get_qty_sold') short_spesification = fields.Char(string='Short Spesification') 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') def _get_clean_website_description(self): @@ -539,11 +540,22 @@ class ProductProduct(models.Model): else: product.max_qty_reorder = reordering.product_max_qty + def _get_qty_rpo(self): + for product in self: + rpo = self.env['v.requisition.match.po'].search([ + ('product_id', '=', product.id) + ], limit=1) + if not rpo: + product.qty_rpo = 0 + else: + product.qty_rpo = rpo.qty_rpo + def _get_plafon_qty_product(self): for product in self: qty_available = product.qty_available_bandengan max_qty = product.max_qty_reorder - product.plafon_qty = max_qty - qty_available + qty_rpo = product.qty_rpo + product.plafon_qty = max_qty - qty_available + qty_rpo # def write(self, vals): -- cgit v1.2.3 From 17d46cf9f4eede8177b2373c03d5b36123f712c1 Mon Sep 17 00:00:00 2001 From: stephanchrst Date: Mon, 11 Nov 2024 14:39:26 +0700 Subject: change rec name view match requisition --- indoteknik_custom/models/requisition.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/indoteknik_custom/models/requisition.py b/indoteknik_custom/models/requisition.py index 704ae8c0..3d9ca876 100644 --- a/indoteknik_custom/models/requisition.py +++ b/indoteknik_custom/models/requisition.py @@ -10,7 +10,7 @@ _logger = logging.getLogger(__name__) class RequisitionMatchPO(models.Model): _name = 'v.requisition.match.po' _auto = False - _rec_name = 'purchase_id' + _rec_name = 'product_id' id = fields.Integer(string='ID') product_id = fields.Many2one('product.product', string='Product') -- cgit v1.2.3 From 8fd1bb1a05f0b98ca25750abb2f75c13e44b623e Mon Sep 17 00:00:00 2001 From: stephanchrst Date: Mon, 11 Nov 2024 15:24:05 +0700 Subject: add view xml product --- indoteknik_custom/security/ir.model.access.csv | 1 + indoteknik_custom/views/product_product.xml | 3 +++ 2 files changed, 4 insertions(+) diff --git a/indoteknik_custom/security/ir.model.access.csv b/indoteknik_custom/security/ir.model.access.csv index 553047e6..28794f41 100755 --- a/indoteknik_custom/security/ir.model.access.csv +++ b/indoteknik_custom/security/ir.model.access.csv @@ -143,3 +143,4 @@ access_vendor_approval_line,access.vendor.approval.line,model_vendor_approval_li access_vit_kota,access.vit.kota,model_vit_kota,,1,1,1,1 access_v_brand_product_category,access.v.brand.product.category,model_v_brand_product_category,,1,1,1,1 access_web_find_page,access.web.find.page,model_web_find_page,,1,1,1,1 +access_v_requisition_match_po,access.v.requisition.match.po,model_v_requisition_match_po,,1,1,1,1 diff --git a/indoteknik_custom/views/product_product.xml b/indoteknik_custom/views/product_product.xml index c06cc5f1..71748e44 100644 --- a/indoteknik_custom/views/product_product.xml +++ b/indoteknik_custom/views/product_product.xml @@ -11,11 +11,14 @@ + + + -- cgit v1.2.3 From 98c75272a5ee571de134b8e5746a026f1654ed80 Mon Sep 17 00:00:00 2001 From: stephanchrst Date: Mon, 11 Nov 2024 15:51:51 +0700 Subject: add message while check plafon qty --- indoteknik_custom/models/purchase_order.py | 21 +++++++++++++++++++-- 1 file changed, 19 insertions(+), 2 deletions(-) diff --git a/indoteknik_custom/models/purchase_order.py b/indoteknik_custom/models/purchase_order.py index f5b5979b..a8fd68e9 100755 --- a/indoteknik_custom/models/purchase_order.py +++ b/indoteknik_custom/models/purchase_order.py @@ -589,9 +589,8 @@ class PurchaseOrder(models.Model): for line in self.order_line: if not line.product_id: continue - test = line.product_id.plafon_qty if line.product_uom_qty > line.product_id.plafon_qty: - raise UserError('Product '+line.product_id.name+' melebihi plafon') + raise UserError('Product '+line.product_id.name+' melebihi plafon, harus Approval MD') def button_confirm(self): res = super(PurchaseOrder, self).button_confirm() @@ -751,6 +750,10 @@ class PurchaseOrder(models.Model): reason += 'not link with pj and reorder, ' if not self.matches_so: reason += 'not link with so, ' + # Check Plafon Qty and Get Message every Line Product + greater_than_plafon, message = self._get_msg_plafon_qty() + if greater_than_plafon: + reason += message # Post a highlighted message to lognote self.message_post( body=f"
" @@ -758,6 +761,20 @@ class PurchaseOrder(models.Model): subtype_id=self.env.ref("mail.mt_note").id ) + def _get_msg_plafon_qty(self): + message = '' + greater_than_plafon = False + for line in self.order_line: + if not line.product_id: + continue + if line.product_uom_qty > line.product_id.plafon_qty: + message = (message + line.product_id.default_code + 'melebihi plafon ' + + str(line.product_uom_qty) + ' vs ' + str(line.product_id.plafon_qty) + + ', ') + greater_than_plafon = True + print(1) + return greater_than_plafon, message + def re_calculate(self): if self.from_apo: self.re_calculate_from_apo() -- cgit v1.2.3 From 4be403f544f63a5161275f0d600c6f6950f3a30c Mon Sep 17 00:00:00 2001 From: Azka Nathan Date: Mon, 11 Nov 2024 16:13:27 +0700 Subject: push --- indoteknik_custom/models/approval_retur_picking.py | 16 ++++++------- indoteknik_custom/models/requisition.py | 2 +- indoteknik_custom/models/stock_picking.py | 26 +++++++++++++++++----- indoteknik_custom/views/approval_retur_picking.xml | 2 +- 4 files changed, 30 insertions(+), 16 deletions(-) diff --git a/indoteknik_custom/models/approval_retur_picking.py b/indoteknik_custom/models/approval_retur_picking.py index 63639782..34c449a8 100644 --- a/indoteknik_custom/models/approval_retur_picking.py +++ b/indoteknik_custom/models/approval_retur_picking.py @@ -8,7 +8,7 @@ class ApprovalReturPicking(models.TransientModel): _name = 'approval.retur.picking' _description = 'Wizard to add Note Return' - note_return = fields.Text(string="Note Return", required=True) + note_return = fields.Text(string="Note Return") def action_confirm_note_return(self): picking_ids = self._context.get('picking_ids') @@ -16,22 +16,22 @@ class ApprovalReturPicking(models.TransientModel): # Update the note_return field picking.update({ - 'note_return': self.note_return + 'approval_return_status': 'pengajuan1' }) # Post a highlighted message to lognote - picking.message_post( - body=f"
" - f"Note Return (Pinned):
{self.note_return}
", - subtype_id=self.env.ref("mail.mt_note").id - ) + # picking.message_post( + # body=f"
" + # f"Note Return (Pinned):
{self.note_return}
", + # subtype_id=self.env.ref("mail.mt_note").id + # ) return { 'type': 'ir.actions.client', 'tag': 'display_notification', 'params': { 'title': 'Notification', - 'message': 'Note berhasil ditambah', + 'message': 'Status pengajuan telah berubah', 'next': {'type': 'ir.actions.act_window_close'}, } } diff --git a/indoteknik_custom/models/requisition.py b/indoteknik_custom/models/requisition.py index a90a5718..89ed4a27 100644 --- a/indoteknik_custom/models/requisition.py +++ b/indoteknik_custom/models/requisition.py @@ -117,7 +117,7 @@ class Requisition(models.Model): 'product_id': product.id, 'product_qty': line.qty_purchase, 'product_uom_qty': line.qty_purchase, - 'name': product.name, + 'name': product.display_name, 'price_unit': line.price_unit, 'taxes_id': tax, } diff --git a/indoteknik_custom/models/stock_picking.py b/indoteknik_custom/models/stock_picking.py index 107a6e72..ad31a2ba 100644 --- a/indoteknik_custom/models/stock_picking.py +++ b/indoteknik_custom/models/stock_picking.py @@ -445,14 +445,28 @@ class StockPicking(models.Model): if self.env.user.is_accounting: pick.approval_return_status = 'approved' else: - pick.approval_return_status = 'pengajuan1' - 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 + 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 + 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 + else: + raise UserError('Harus Purchasing yang Ask Return') + def calculate_line_no(self): + for picking in self: name = picking.group_id.name for move in picking.move_ids_without_package: diff --git a/indoteknik_custom/views/approval_retur_picking.xml b/indoteknik_custom/views/approval_retur_picking.xml index ebe038d1..5ce28e20 100644 --- a/indoteknik_custom/views/approval_retur_picking.xml +++ b/indoteknik_custom/views/approval_retur_picking.xml @@ -6,7 +6,7 @@ - + Ask Approval Retur?
+
+
-- cgit v1.2.3 From 9f293c1270e29db78ac8542221a4bbe6d208ea8f Mon Sep 17 00:00:00 2001 From: stephanchrst Date: Tue, 12 Nov 2024 13:35:24 +0700 Subject: bf plafon --- indoteknik_custom/models/purchase_order.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/indoteknik_custom/models/purchase_order.py b/indoteknik_custom/models/purchase_order.py index 9faa6464..d65e1d66 100755 --- a/indoteknik_custom/models/purchase_order.py +++ b/indoteknik_custom/models/purchase_order.py @@ -589,7 +589,10 @@ class PurchaseOrder(models.Model): for line in self.order_line: if not line.product_id: continue - if line.product_uom_qty > line.product_id.plafon_qty and not self.env.user.has_group('indoteknik_custom.group_role_merchandiser'): + # test = line.product_uom_qty + # test2 = line.product_id.plafon_qty + # test3 = test2 + line.product_uom_qty + 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 button_confirm(self): @@ -772,7 +775,6 @@ class PurchaseOrder(models.Model): + str(line.product_id.plafon_qty) + ') vs Qty PO ('+str(line.product_uom_qty)+')' + ', ') greater_than_plafon = True - print(1) return greater_than_plafon, message def re_calculate(self): -- cgit v1.2.3 From 537e3afa70512c084516b7c11aef970252d83e58 Mon Sep 17 00:00:00 2001 From: stephanchrst Date: Tue, 12 Nov 2024 13:41:57 +0700 Subject: bf plafon in po --- indoteknik_custom/models/purchase_order.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/indoteknik_custom/models/purchase_order.py b/indoteknik_custom/models/purchase_order.py index d65e1d66..3397616d 100755 --- a/indoteknik_custom/models/purchase_order.py +++ b/indoteknik_custom/models/purchase_order.py @@ -738,9 +738,10 @@ class PurchaseOrder(models.Model): 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() 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: + elif self.total_percent_margin == self.total_so_percent_margin and self.matches_so and not greater_than_plafon: raise UserError("Bisa langsung Confirm") else: reason = '' @@ -754,7 +755,6 @@ class PurchaseOrder(models.Model): if not self.matches_so: reason += 'not link with so, ' # Check Plafon Qty and Get Message every Line Product - greater_than_plafon, message = self._get_msg_plafon_qty() if greater_than_plafon: reason += message # Post a highlighted message to lognote -- cgit v1.2.3 From a2211259c5bc20fe78b44ae7da60991038919a58 Mon Sep 17 00:00:00 2001 From: Azka Nathan Date: Tue, 12 Nov 2024 14:12:46 +0700 Subject: cr so --- indoteknik_custom/models/sale_order.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/indoteknik_custom/models/sale_order.py b/indoteknik_custom/models/sale_order.py index 5545e28c..694624cd 100755 --- a/indoteknik_custom/models/sale_order.py +++ b/indoteknik_custom/models/sale_order.py @@ -482,8 +482,8 @@ class SaleOrder(models.Model): if not real_delivery_address.state_id: raise UserError('State Real Delivery Address harus diisi') - if not real_delivery_address.zip: - raise UserError('Zip code Real Delivery Address harus diisi') + # if not real_delivery_address.zip: + # raise UserError('Zip code Real Delivery Address harus diisi') if not real_delivery_address.mobile: raise UserError('Mobile Real Delivery Address harus diisi') if not real_delivery_address.phone: -- cgit v1.2.3 From bd3826b66e647306b46052375620291e2962ae31 Mon Sep 17 00:00:00 2001 From: Azka Nathan Date: Tue, 12 Nov 2024 14:53:11 +0700 Subject: cr so --- indoteknik_custom/models/sale_order.py | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/indoteknik_custom/models/sale_order.py b/indoteknik_custom/models/sale_order.py index 694624cd..39243fc9 100755 --- a/indoteknik_custom/models/sale_order.py +++ b/indoteknik_custom/models/sale_order.py @@ -625,19 +625,19 @@ class SaleOrder(models.Model): # return ['&', ('order_line.invoice_lines.move_id.move_type', 'in', ('out_invoice', 'out_refund')), ('order_line.invoice_lines.move_id', operator, value)] - def check_data_real_delivery_address(self): - real_delivery_address = self.real_shipping_id - - if not real_delivery_address.state_id: - raise UserError('State Real Delivery Address harus diisi') - if not real_delivery_address.zip: - raise UserError('Zip code Real Delivery Address harus diisi') - if not real_delivery_address.mobile: - raise UserError('Mobile Real Delivery Address harus diisi') - if not real_delivery_address.phone: - raise UserError('Phone Real Delivery Address harus diisi') - if not real_delivery_address.kecamatan_id: - raise UserError('Kecamatan Real Delivery Address harus diisi') + # def check_data_real_delivery_address(self): + # real_delivery_address = self.real_shipping_id + + # if not real_delivery_address.state_id: + # raise UserError('State Real Delivery Address harus diisi') + # if not real_delivery_address.zip: + # raise UserError('Zip code Real Delivery Address harus diisi') + # if not real_delivery_address.mobile: + # raise UserError('Mobile Real Delivery Address harus diisi') + # if not real_delivery_address.phone: + # raise UserError('Phone Real Delivery Address harus diisi') + # if not real_delivery_address.kecamatan_id: + # raise UserError('Kecamatan Real Delivery Address harus diisi') @api.onchange('partner_id') def onchange_partner_contact(self): -- cgit v1.2.3 From a3c057d4ddf660ce1214b55c791fd436cc7a6100 Mon Sep 17 00:00:00 2001 From: stephanchrst Date: Tue, 12 Nov 2024 15:35:12 +0700 Subject: add new table of fulfillment v2 --- indoteknik_custom/models/sales_order_fullfillment.py | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/indoteknik_custom/models/sales_order_fullfillment.py b/indoteknik_custom/models/sales_order_fullfillment.py index ab416e8d..9e9457f1 100644 --- a/indoteknik_custom/models/sales_order_fullfillment.py +++ b/indoteknik_custom/models/sales_order_fullfillment.py @@ -6,6 +6,22 @@ import logging _logger = logging.getLogger(__name__) +class SalesOrderFullfillmentV2(models.Model): + _name = 'sales.order.fulfillment.v2' + + sale_order_id = fields.Many2one('sale.order', string='Sale Order') + sale_order_line_id = fields.Many2one('sale.order.line', string='Sale Order Line') + picking_id = fields.Many2one('stock.picking', string='Picking') + move_id = fields.Many2one('stock.move', string='Move') + move_line_id = fields.Many2one('stock.move.line', string='Move Line') + product_id = fields.Many2one('product.product', string='Product') + so_qty = fields.Float(string='SO Qty') + reserved_stock_qty = fields.Float(string='Reserved Stock Qty') + po_ids = fields.Many2many('purchase.order', string='Purchase Order') + po_qty = fields.Float(string='PO Qty', help='Totalan dari semua PO Outstanding') + received_qty = fields.Float(string='Received Qty', help='Totalan dari barang yang diterima dari PO tsb') + + class SalesOrderFullfillment(models.Model): _name = 'sales.order.fullfillment' -- cgit v1.2.3 From 08e490b3f6a1dc90ebe8fd39bd9cf5fe64cd64a3 Mon Sep 17 00:00:00 2001 From: Azka Nathan Date: Tue, 12 Nov 2024 16:11:25 +0700 Subject: add attrs to delivery amt sale order --- indoteknik_custom/views/sale_order.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/indoteknik_custom/views/sale_order.xml b/indoteknik_custom/views/sale_order.xml index 98001589..88fcd8a1 100755 --- a/indoteknik_custom/views/sale_order.xml +++ b/indoteknik_custom/views/sale_order.xml @@ -29,7 +29,7 @@ - + -- cgit v1.2.3 From ffec5d50ef5be0bea5dd9a658b54d053ed67344b Mon Sep 17 00:00:00 2001 From: Azka Nathan Date: Tue, 12 Nov 2024 17:15:28 +0700 Subject: cr kelurahan so --- indoteknik_custom/models/sale_order.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/indoteknik_custom/models/sale_order.py b/indoteknik_custom/models/sale_order.py index 39243fc9..e2399ecc 100755 --- a/indoteknik_custom/models/sale_order.py +++ b/indoteknik_custom/models/sale_order.py @@ -482,16 +482,16 @@ class SaleOrder(models.Model): if not real_delivery_address.state_id: raise UserError('State Real Delivery Address harus diisi') - # if not real_delivery_address.zip: - # raise UserError('Zip code Real Delivery Address harus diisi') + if not real_delivery_address.zip: + raise UserError('Zip code Real Delivery Address harus diisi') if not real_delivery_address.mobile: raise UserError('Mobile Real Delivery Address harus diisi') if not real_delivery_address.phone: raise UserError('Phone Real Delivery Address harus diisi') if not real_delivery_address.kecamatan_id: raise UserError('Kecamatan Real Delivery Address harus diisi') - if not real_delivery_address.kelurahan_id: - raise UserError('Kelurahan Real Delivery Address harus diisi') + # if not real_delivery_address.kelurahan_id: + # raise UserError('Kelurahan Real Delivery Address harus diisi') def generate_payment_link_midtrans_sales_order(self): # midtrans_url = 'https://app.sandbox.midtrans.com/snap/v1/transactions' # dev - sandbox -- cgit v1.2.3 From b44f26591a67b1a33132bcbcb9190920eb52e6f3 Mon Sep 17 00:00:00 2001 From: stephanchrst Date: Wed, 13 Nov 2024 09:04:27 +0700 Subject: view of fulfillment version 2 --- indoteknik_custom/models/sale_order.py | 9 +++++---- indoteknik_custom/models/sales_order_fullfillment.py | 5 +++-- indoteknik_custom/security/ir.model.access.csv | 1 + indoteknik_custom/views/sale_order.xml | 20 ++++++++++++++++++++ 4 files changed, 29 insertions(+), 6 deletions(-) diff --git a/indoteknik_custom/models/sale_order.py b/indoteknik_custom/models/sale_order.py index 5545e28c..31ea8902 100755 --- a/indoteknik_custom/models/sale_order.py +++ b/indoteknik_custom/models/sale_order.py @@ -11,6 +11,7 @@ _logger = logging.getLogger(__name__) class SaleOrder(models.Model): _inherit = "sale.order" + fulfillment_line_v2 = fields.One2many('sales.order.fulfillment.v2', 'sale_order_id', string='Fullfillment2') fullfillment_line = fields.One2many('sales.order.fullfillment', 'sales_order_id', string='Fullfillment') reject_line = fields.One2many('sales.order.reject', 'sale_order_id', string='Reject Lines') order_sales_match_line = fields.One2many('sales.order.purchase.match', 'sales_order_id', string='Purchase Match Lines', states={'cancel': [('readonly', True)], 'done': [('readonly', True)]}, copy=True) @@ -346,10 +347,10 @@ class SaleOrder(models.Model): def _compute_fullfillment(self): for rec in self: - rec.fullfillment_line.unlink() - - for line in rec.order_line: - line._compute_reserved_from() + # rec.fullfillment_line.unlink() + # + # for line in rec.order_line: + # line._compute_reserved_from() rec.compute_fullfillment = True diff --git a/indoteknik_custom/models/sales_order_fullfillment.py b/indoteknik_custom/models/sales_order_fullfillment.py index 9e9457f1..42544c15 100644 --- a/indoteknik_custom/models/sales_order_fullfillment.py +++ b/indoteknik_custom/models/sales_order_fullfillment.py @@ -16,8 +16,9 @@ class SalesOrderFullfillmentV2(models.Model): move_line_id = fields.Many2one('stock.move.line', string='Move Line') product_id = fields.Many2one('product.product', string='Product') so_qty = fields.Float(string='SO Qty') - reserved_stock_qty = fields.Float(string='Reserved Stock Qty') - po_ids = fields.Many2many('purchase.order', string='Purchase Order') + reserved_stock_qty = fields.Float(string='Reserved Stock Qty', help='Sudah ter-reserved oleh sistem') + delivered_qty = fields.Float(string='Delivered Qty', help='Yang sudah terkirim ke Customer') + po_ids = fields.Many2many('purchase.order', string='Purchase Order', help='PO yang dibuat, bisa lebih dari satu') po_qty = fields.Float(string='PO Qty', help='Totalan dari semua PO Outstanding') received_qty = fields.Float(string='Received Qty', help='Totalan dari barang yang diterima dari PO tsb') diff --git a/indoteknik_custom/security/ir.model.access.csv b/indoteknik_custom/security/ir.model.access.csv index 49b38e6a..e817a28d 100755 --- a/indoteknik_custom/security/ir.model.access.csv +++ b/indoteknik_custom/security/ir.model.access.csv @@ -145,3 +145,4 @@ access_v_brand_product_category,access.v.brand.product.category,model_v_brand_pr access_web_find_page,access.web.find.page,model_web_find_page,,1,1,1,1 access_v_requisition_match_po,access.v.requisition.match.po,model_v_requisition_match_po,,1,1,1,1 access_approval_retur_picking,access.approval.retur.picking,model_approval_retur_picking,,1,1,1,1 +access_sales_order_fulfillment_v2,access.sales.order.fulfillment.v2,model_sales_order_fulfillment_v2,,1,1,1,1 diff --git a/indoteknik_custom/views/sale_order.xml b/indoteknik_custom/views/sale_order.xml index 98001589..676a822d 100755 --- a/indoteknik_custom/views/sale_order.xml +++ b/indoteknik_custom/views/sale_order.xml @@ -227,6 +227,9 @@ + + + @@ -341,6 +344,23 @@ + + + + + sales.order.fulfillment.v2.tree + sales.order.fulfillment.v2 + + + + + + + + + + + sales.order.fullfillment.tree -- cgit v1.2.3 From d71a8ead26eaf1d44da38b94b1a114f97f407bd8 Mon Sep 17 00:00:00 2001 From: stephanchrst Date: Wed, 13 Nov 2024 09:50:19 +0700 Subject: add po ids in fulfillment v2 --- indoteknik_custom/views/sale_order.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/indoteknik_custom/views/sale_order.xml b/indoteknik_custom/views/sale_order.xml index 676a822d..02531966 100755 --- a/indoteknik_custom/views/sale_order.xml +++ b/indoteknik_custom/views/sale_order.xml @@ -356,6 +356,7 @@ + -- cgit v1.2.3 From 001002a2c56d241cf2340155683f43a8c62ac7b6 Mon Sep 17 00:00:00 2001 From: Azka Nathan Date: Wed, 13 Nov 2024 13:30:27 +0700 Subject: add free product to so line when promotion --- indoteknik_api/controllers/api_v1/sale_order.py | 1 + indoteknik_custom/models/promotion/sale_order.py | 10 ++++++++++ indoteknik_custom/models/sale_order.py | 6 +++--- 3 files changed, 14 insertions(+), 3 deletions(-) diff --git a/indoteknik_api/controllers/api_v1/sale_order.py b/indoteknik_api/controllers/api_v1/sale_order.py index 905795b0..3e182a2e 100644 --- a/indoteknik_api/controllers/api_v1/sale_order.py +++ b/indoteknik_api/controllers/api_v1/sale_order.py @@ -464,6 +464,7 @@ class SaleOrder(controller.Controller): if len(promotions) > 0: sale_order.apply_promotion_program() + sale_order.add_free_product(promotions) voucher_code = params['value']['voucher'] voucher = request.env['voucher'].search([('code', '=', voucher_code),('apply_type', 'in', ['all', 'brand'])], limit=1) diff --git a/indoteknik_custom/models/promotion/sale_order.py b/indoteknik_custom/models/promotion/sale_order.py index cb9a6f92..be820c6f 100644 --- a/indoteknik_custom/models/promotion/sale_order.py +++ b/indoteknik_custom/models/promotion/sale_order.py @@ -6,6 +6,16 @@ class SaleOrder(models.Model): order_promotion_ids = fields.One2many('sale.order.promotion', 'order_id', 'Promotions') + def add_free_product(self, promotions): + 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' + }) + def apply_promotion_program(self): userdata = { 'user_id': self.partner_id.user_id.id, diff --git a/indoteknik_custom/models/sale_order.py b/indoteknik_custom/models/sale_order.py index e2399ecc..a0d70059 100755 --- a/indoteknik_custom/models/sale_order.py +++ b/indoteknik_custom/models/sale_order.py @@ -148,7 +148,7 @@ class SaleOrder(models.Model): missing_weight_products = [] for line in self.order_line: - if line.weight: + if line.weight > 0: total_weight += line.weight * line.product_uom_qty self.total_weight = total_weight @@ -161,7 +161,7 @@ class SaleOrder(models.Model): missing_weight_products = [] for line in self.order_line: - if line.weight: + if line.weight > 0: total_weight += line.weight * line.product_uom_qty line.product_id.weight = line.weight else: @@ -186,7 +186,7 @@ class SaleOrder(models.Model): missing_weight_products = [] for line in self.order_line: - if line.weight: + if line.weight > 0: total_weight += line.weight * line.product_uom_qty line.product_id.weight = line.weight else: -- cgit v1.2.3 From 7dd310eed8f726982e3df3934d85e844b14526c3 Mon Sep 17 00:00:00 2001 From: it-fixcomart Date: Wed, 13 Nov 2024 13:35:16 +0700 Subject: update set parent berdasarkan vals company id --- indoteknik_custom/models/user_company_request.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/indoteknik_custom/models/user_company_request.py b/indoteknik_custom/models/user_company_request.py index 86e66934..dd9a35c1 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 = vals.get('user_company_id') if vals.get('user_company_id') else self.user_company_id.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 770c6506de7ba5b1a3430695298f1001f6e9d48e Mon Sep 17 00:00:00 2001 From: stephanchrst Date: Wed, 13 Nov 2024 14:20:07 +0700 Subject: add purchaser in fulfillment v2 --- indoteknik_custom/models/sales_order_fullfillment.py | 1 + indoteknik_custom/views/sale_order.xml | 11 ++++++----- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/indoteknik_custom/models/sales_order_fullfillment.py b/indoteknik_custom/models/sales_order_fullfillment.py index 42544c15..05a0641c 100644 --- a/indoteknik_custom/models/sales_order_fullfillment.py +++ b/indoteknik_custom/models/sales_order_fullfillment.py @@ -21,6 +21,7 @@ class SalesOrderFullfillmentV2(models.Model): po_ids = fields.Many2many('purchase.order', string='Purchase Order', help='PO yang dibuat, bisa lebih dari satu') po_qty = fields.Float(string='PO Qty', help='Totalan dari semua PO Outstanding') received_qty = fields.Float(string='Received Qty', help='Totalan dari barang yang diterima dari PO tsb') + purchaser = fields.Char(string='Purchaser') class SalesOrderFullfillment(models.Model): diff --git a/indoteknik_custom/views/sale_order.xml b/indoteknik_custom/views/sale_order.xml index ca27c2ed..7b8af971 100755 --- a/indoteknik_custom/views/sale_order.xml +++ b/indoteknik_custom/views/sale_order.xml @@ -353,12 +353,13 @@ - - + + - - - + + + + -- cgit v1.2.3 From 405da89e61fc9d1278d37fbd9793f5578992f1c1 Mon Sep 17 00:00:00 2001 From: Azka Nathan Date: Wed, 13 Nov 2024 15:10:28 +0700 Subject: delivery amt cr --- indoteknik_custom/views/sale_order.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/indoteknik_custom/views/sale_order.xml b/indoteknik_custom/views/sale_order.xml index ca27c2ed..02531966 100755 --- a/indoteknik_custom/views/sale_order.xml +++ b/indoteknik_custom/views/sale_order.xml @@ -29,7 +29,7 @@ - + -- cgit v1.2.3 From 68998f5a42a0740060d74107d108181b1dfcfb2d Mon Sep 17 00:00:00 2001 From: stephanchrst Date: Wed, 13 Nov 2024 15:34:00 +0700 Subject: comment fulfillment v1 --- .../models/report_stock_forecasted.py | 54 +++++++++++----------- 1 file changed, 27 insertions(+), 27 deletions(-) diff --git a/indoteknik_custom/models/report_stock_forecasted.py b/indoteknik_custom/models/report_stock_forecasted.py index ebdc7d4a..c9d54a15 100644 --- a/indoteknik_custom/models/report_stock_forecasted.py +++ b/indoteknik_custom/models/report_stock_forecasted.py @@ -6,33 +6,33 @@ class ReplenishmentReport(models.AbstractModel): @api.model def _get_report_lines(self, product_template_ids, product_variant_ids, wh_location_ids): lines = super(ReplenishmentReport, self)._get_report_lines(product_template_ids, product_variant_ids, wh_location_ids) - result_dict = {} - - for line in lines: - document_out = line.get('document_out') - - if document_out and "SO/" in document_out.name: - order_id = document_out.id - if document_out == False: - continue - product_id = line.get('product', {}).get('id') - query = [('product_id', '=', product_id)] - - if order_id: - result = self._calculate_result(line) - quantity = line.get('quantity', 0) - result_dict.setdefault(order_id, []).append((result, quantity)) - - for order_id, results in result_dict.items(): - sales_order = self.env['sale.order'].browse(order_id) - - for result, quantity in results: - self.env['sales.order.fullfillment'].create({ - 'sales_order_id': sales_order.id, - 'product_id': product_id, - 'reserved_from': result, - 'qty_fullfillment': quantity, - }) + # result_dict = {} + # + # for line in lines: + # document_out = line.get('document_out') + # + # if document_out and "SO/" in document_out.name: + # order_id = document_out.id + # if document_out == False: + # continue + # product_id = line.get('product', {}).get('id') + # query = [('product_id', '=', product_id)] + # + # if order_id: + # result = self._calculate_result(line) + # quantity = line.get('quantity', 0) + # result_dict.setdefault(order_id, []).append((result, quantity)) + # + # for order_id, results in result_dict.items(): + # sales_order = self.env['sale.order'].browse(order_id) + # + # for result, quantity in results: + # self.env['sales.order.fullfillment'].create({ + # 'sales_order_id': sales_order.id, + # 'product_id': product_id, + # 'reserved_from': result, + # 'qty_fullfillment': quantity, + # }) return lines def _calculate_result(self, line): -- cgit v1.2.3 From 9365e1bb72a34eb17cbb25536d9e2dbb843e7fe8 Mon Sep 17 00:00:00 2001 From: Azka Nathan Date: Thu, 14 Nov 2024 10:05:08 +0700 Subject: note so line on stock picking --- indoteknik_custom/models/sale_order.py | 28 ++++++++++++---------------- indoteknik_custom/models/sale_order_line.py | 2 +- indoteknik_custom/models/stock_picking.py | 1 + indoteknik_custom/views/stock_picking.xml | 1 + 4 files changed, 15 insertions(+), 17 deletions(-) diff --git a/indoteknik_custom/models/sale_order.py b/indoteknik_custom/models/sale_order.py index 75332996..e90ca995 100755 --- a/indoteknik_custom/models/sale_order.py +++ b/indoteknik_custom/models/sale_order.py @@ -491,8 +491,8 @@ class SaleOrder(models.Model): raise UserError('Phone Real Delivery Address harus diisi') if not real_delivery_address.kecamatan_id: raise UserError('Kecamatan Real Delivery Address harus diisi') - # if not real_delivery_address.kelurahan_id: - # raise UserError('Kelurahan Real Delivery Address harus diisi') + if not real_delivery_address.kelurahan_id: + raise UserError('Kelurahan Real Delivery Address harus diisi') def generate_payment_link_midtrans_sales_order(self): # midtrans_url = 'https://app.sandbox.midtrans.com/snap/v1/transactions' # dev - sandbox @@ -626,20 +626,6 @@ class SaleOrder(models.Model): # return ['&', ('order_line.invoice_lines.move_id.move_type', 'in', ('out_invoice', 'out_refund')), ('order_line.invoice_lines.move_id', operator, value)] - # def check_data_real_delivery_address(self): - # real_delivery_address = self.real_shipping_id - - # if not real_delivery_address.state_id: - # raise UserError('State Real Delivery Address harus diisi') - # if not real_delivery_address.zip: - # raise UserError('Zip code Real Delivery Address harus diisi') - # if not real_delivery_address.mobile: - # raise UserError('Mobile Real Delivery Address harus diisi') - # if not real_delivery_address.phone: - # raise UserError('Phone Real Delivery Address harus diisi') - # if not real_delivery_address.kecamatan_id: - # raise UserError('Kecamatan Real Delivery Address harus diisi') - @api.onchange('partner_id') def onchange_partner_contact(self): parent_id = self.partner_id.parent_id @@ -980,6 +966,16 @@ class SaleOrder(models.Model): # order.order_line.get_reserved_from() res = super(SaleOrder, self).action_confirm() + for order in self: + note = [] + for line in order.order_line: + if line.display_type == 'line_note': + note.append(line.name) + + if order.picking_ids: + # Sort picking_ids by date and get the most recent one + latest_picking = order.picking_ids.sorted(key=lambda p: p.scheduled_date, reverse=True)[0] + latest_picking.notee = '\n'.join(note) return res def action_cancel(self): diff --git a/indoteknik_custom/models/sale_order_line.py b/indoteknik_custom/models/sale_order_line.py index 5a6640ec..f4469117 100644 --- a/indoteknik_custom/models/sale_order_line.py +++ b/indoteknik_custom/models/sale_order_line.py @@ -372,5 +372,5 @@ class SaleOrderLine(models.Model): continue if not line.product_id.product_tmpl_id.sale_ok: raise UserError('Product %s belum bisa dijual, harap hubungi finance' % line.product_id.display_name) - if not line.vendor_id or not line.purchase_price: + if not line.vendor_id or not line.purchase_price and not line.display_type == 'line_note': raise UserError(_('Isi Vendor dan Harga Beli sebelum Request Approval')) \ No newline at end of file diff --git a/indoteknik_custom/models/stock_picking.py b/indoteknik_custom/models/stock_picking.py index 50e9304b..ee1dd68c 100644 --- a/indoteknik_custom/models/stock_picking.py +++ b/indoteknik_custom/models/stock_picking.py @@ -112,6 +112,7 @@ class StockPicking(models.Model): ('done', 'Done'), ('cancel', 'Cancelled'), ], string='Status Reserve', readonly=True, tracking=True, help="The current state of the stock picking.") + notee = fields.Text(string="Note") def action_send_to_biteship(self): url = "https://api.biteship.com/v1/orders" diff --git a/indoteknik_custom/views/stock_picking.xml b/indoteknik_custom/views/stock_picking.xml index c230bc7b..1893fcaf 100644 --- a/indoteknik_custom/views/stock_picking.xml +++ b/indoteknik_custom/views/stock_picking.xml @@ -129,6 +129,7 @@ + -- cgit v1.2.3 From f6df2ccfde5b45d018c8d7b11203429b5f39ebfc Mon Sep 17 00:00:00 2001 From: stephanchrst Date: Thu, 14 Nov 2024 10:39:36 +0700 Subject: make default AR AP in contact --- indoteknik_custom/models/res_partner.py | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/indoteknik_custom/models/res_partner.py b/indoteknik_custom/models/res_partner.py index b01c7984..9108707d 100644 --- a/indoteknik_custom/models/res_partner.py +++ b/indoteknik_custom/models/res_partner.py @@ -10,6 +10,16 @@ class GroupPartner(models.Model): class ResPartner(models.Model): _inherit = 'res.partner' + property_account_payable_id = fields.Many2one('account.account', company_dependent=True, + string="Account Payable", + domain="[('internal_type', '=', 'payable'), ('deprecated', '=', False), ('company_id', '=', current_company_id)]", + help="This account will be used instead of the default one as the payable account for the current partner", + default=438) + property_account_receivable_id = fields.Many2one('account.account', company_dependent=True, + string="Account Receivable", + domain="[('internal_type', '=', 'receivable'), ('deprecated', '=', False), ('company_id', '=', current_company_id)]", + help="This account will be used instead of the default one as the receivable account for the current partner", + default=395) reference_number = fields.Char(string="Reference Number") company_type_id = fields.Many2one('res.partner.company_type', string='Company Type') custom_pricelist_id = fields.Many2one('product.pricelist', string='Price Matrix') -- cgit v1.2.3 From 3f5eec5331b216911d911c230ea64538588b65c0 Mon Sep 17 00:00:00 2001 From: stephanchrst Date: Thu, 14 Nov 2024 11:16:07 +0700 Subject: add free bu --- indoteknik_custom/models/sale_order_line.py | 5 +++++ indoteknik_custom/views/sale_order.xml | 1 + 2 files changed, 6 insertions(+) diff --git a/indoteknik_custom/models/sale_order_line.py b/indoteknik_custom/models/sale_order_line.py index f4469117..04fafa69 100644 --- a/indoteknik_custom/models/sale_order_line.py +++ b/indoteknik_custom/models/sale_order_line.py @@ -37,6 +37,11 @@ class SaleOrderLine(models.Model): weight = fields.Float(string='Weight') md_vendor_id = fields.Many2one('res.partner', string='MD Vendor', readonly=True) margin_md = fields.Float(string='Margin MD') + qty_free_bu = fields.Float(string='Free BU', compute='_get_qty_free_bandengan') + + def _get_qty_free_bandengan(self): + for line in self: + line.qty_free_bu = line.product_id.qty_free_bandengan @api.constrains('note_procurement') def note_procurement_to_apo(self): diff --git a/indoteknik_custom/views/sale_order.xml b/indoteknik_custom/views/sale_order.xml index b8f2d08d..53dac424 100755 --- a/indoteknik_custom/views/sale_order.xml +++ b/indoteknik_custom/views/sale_order.xml @@ -119,6 +119,7 @@ + Date: Thu, 14 Nov 2024 13:19:42 +0700 Subject: readonly credit limit on contact --- indoteknik_custom/views/partner_payment_term.xml | 3 +++ indoteknik_custom/views/res_partner.xml | 9 +++++++++ 2 files changed, 12 insertions(+) diff --git a/indoteknik_custom/views/partner_payment_term.xml b/indoteknik_custom/views/partner_payment_term.xml index 433cac3e..e0f2fe39 100644 --- a/indoteknik_custom/views/partner_payment_term.xml +++ b/indoteknik_custom/views/partner_payment_term.xml @@ -24,6 +24,9 @@ + + + diff --git a/indoteknik_custom/views/res_partner.xml b/indoteknik_custom/views/res_partner.xml index 6d02a86b..e8d3bf1a 100644 --- a/indoteknik_custom/views/res_partner.xml +++ b/indoteknik_custom/views/res_partner.xml @@ -6,6 +6,15 @@ res.partner + + 1 + + + 1 + + + 1 + -- cgit v1.2.3 From 7b60204cb96af3d180fa21570c7540722184ab4e Mon Sep 17 00:00:00 2001 From: Azka Nathan Date: Thu, 14 Nov 2024 16:08:42 +0700 Subject: fix bug wati --- indoteknik_custom/models/sale_order.py | 4 +-- indoteknik_custom/models/wati.py | 57 +++++++++++++++++++++------------- 2 files changed, 38 insertions(+), 23 deletions(-) diff --git a/indoteknik_custom/models/sale_order.py b/indoteknik_custom/models/sale_order.py index e90ca995..80e111a8 100755 --- a/indoteknik_custom/models/sale_order.py +++ b/indoteknik_custom/models/sale_order.py @@ -973,8 +973,8 @@ class SaleOrder(models.Model): note.append(line.name) if order.picking_ids: - # Sort picking_ids by date and get the most recent one - latest_picking = order.picking_ids.sorted(key=lambda p: p.scheduled_date, reverse=True)[0] + # Sort picking_ids by creation date to get the most recent one + latest_picking = order.picking_ids.sorted(key=lambda p: p.create_date, reverse=True)[0] latest_picking.notee = '\n'.join(note) return res diff --git a/indoteknik_custom/models/wati.py b/indoteknik_custom/models/wati.py index eed5413e..f3632334 100644 --- a/indoteknik_custom/models/wati.py +++ b/indoteknik_custom/models/wati.py @@ -58,41 +58,56 @@ class WatiNotification(models.Model): return def _create_wati_history_header(self, ticket_id, sender_name, notification_json, date_wati): + # Helper function to remove NUL characters + def remove_null_characters(value): + if isinstance(value, str): + return value.replace('\0', '') + return value + + # Sanitize the input data param_header = { 'ticket_id': ticket_id, - 'conversation_id': notification_json['conversationId'], - 'sender_name': sender_name, - 'wa_id': notification_json['waId'], - 'text': notification_json['text'], - 'date_wati': date_wati or '', + 'conversation_id': remove_null_characters(notification_json.get('conversationId', '')), + 'sender_name': remove_null_characters(sender_name), + 'wa_id': remove_null_characters(notification_json.get('waId', '')), + 'text': remove_null_characters(notification_json.get('text', '')), + 'date_wati': remove_null_characters(date_wati or ''), } + + # Create the record new_header = self.env['wati.history'].create([param_header]) return new_header def _create_wati_history_line(self, new_header, ticket_id, sender_name, notification_json, date_wati): - text_body = notification_json['text'] or '' + # Helper function to remove NUL characters + def remove_null_characters(value): + if isinstance(value, str): + return value.replace('\0', '') + return value + + # Sanitize the input data param_line = { "wati_history_id": new_header.id, - "conversation_id": notification_json['conversationId'], - "data": notification_json['data'] or '', - "event_type": notification_json['eventType'] or '', - # "list_reply": notification_json['listReply'] or '', - # "message_contact": notification_json['messageContact'] or '', - "operator_email": notification_json['operatorEmail'] or '', - "operator_name": notification_json['operatorName'] or '', - "sender_name": sender_name or '', - # "source_url": notification_json['sourceUrl'] or '', - "status_string": notification_json['statusString'] or '', - "text": text_body, + "conversation_id": remove_null_characters(notification_json.get('conversationId', '')), + "data": remove_null_characters(notification_json.get('data', '')), + "event_type": remove_null_characters(notification_json.get('eventType', '')), + "operator_email": remove_null_characters(notification_json.get('operatorEmail', '')), + "operator_name": remove_null_characters(notification_json.get('operatorName', '')), + "sender_name": remove_null_characters(sender_name or ''), + "status_string": remove_null_characters(notification_json.get('statusString', '')), + "text": remove_null_characters(notification_json.get('text', '')), "ticket_id": ticket_id, - "type": notification_json['type'] or '', - "wa_id": notification_json['waId'] or '', - "date_wati": date_wati or '', + "type": remove_null_characters(notification_json.get('type', '')), + "wa_id": remove_null_characters(notification_json.get('waId', '')), + "date_wati": remove_null_characters(date_wati or ''), } + + # Create the record safely without NUL characters self.env['wati.history.line'].create([param_line]) - self._update_header_after_create_line(new_header, sender_name, date_wati, text_body) + self._update_header_after_create_line(new_header, sender_name, date_wati, param_line['text']) return + def _update_header_after_create_line(self, new_header, sender_name, date_wati, text_body): new_header.last_reply_by = sender_name new_header.last_reply_date = date_wati -- cgit v1.2.3 From 0c0cf00f50f78bc74aeedd8096eb161673a4ada7 Mon Sep 17 00:00:00 2001 From: stephanchrst Date: Fri, 15 Nov 2024 09:57:49 +0700 Subject: bf matches so in purchase order --- indoteknik_custom/models/automatic_purchase.py | 60 ++++++++++++++------------ 1 file changed, 32 insertions(+), 28 deletions(-) diff --git a/indoteknik_custom/models/automatic_purchase.py b/indoteknik_custom/models/automatic_purchase.py index 548115e6..46cc9fa5 100644 --- a/indoteknik_custom/models/automatic_purchase.py +++ b/indoteknik_custom/models/automatic_purchase.py @@ -401,36 +401,40 @@ class AutomaticPurchase(models.Model): domain = [ ('product_id', '=', line.product_id.id) ] - sale = self.env['v.sales.outstanding'].search(domain, order='sale_order_create_date desc', limit=1) - - existing_match = self.env['automatic.purchase.sales.match'].search([ - ('automatic_purchase_id', '=', self.id), - ('sale_id', '=', sale.sale_id.id), - ('product_id', '=', sale.product_id.id), - ]) + sales = self.env['v.sales.outstanding'].search(domain, order='sale_order_create_date desc') - price_so = self.env['sale.order.line'].search([ - ('id', '=', sale.sale_line_id.id), - ]) - - if existing_match: - continue + for sale in sales: + existing_match = self.env['automatic.purchase.sales.match'].search([ + ('automatic_purchase_id', '=', self.id), + ('sale_id', '=', sale.sale_id.id), + ('sale_line_id', '=', sale.sale_line_id.id), + ('product_id', '=', sale.product_id.id), + ]) - self.env['automatic.purchase.sales.match'].create([{ - 'automatic_purchase_id': self.id, - 'sale_id': sale.sale_id.id, - 'sale_line_id': sale.sale_line_id.id, - 'picking_id': sale.picking_id.id, - 'move_id': sale.move_id.id, - 'partner_id': sale.partner_id.id, - 'partner_invoice_id': sale.partner_invoice_id.id, - 'salesperson_id': sale.salesperson_id.id, - 'product_id': sale.product_id.id, - 'qty_so': sale.outgoing, - 'qty_po': line.qty_purchase, - 'purchase_price': price_so.purchase_price, - 'purchase_tax_id': price_so.purchase_tax_id.id if price_so.purchase_tax_id.id else None, - }]) + # price_so = self.env['sale.order.line'].search([ + # ('id', '=', sale.sale_line_id.id), + # ]) + + if existing_match: + continue + + self.env['automatic.purchase.sales.match'].create([{ + 'automatic_purchase_id': self.id, + 'sale_id': sale.sale_id.id, + 'sale_line_id': sale.sale_line_id.id, + 'picking_id': sale.picking_id.id, + 'move_id': sale.move_id.id, + 'partner_id': sale.partner_id.id, + 'partner_invoice_id': sale.partner_invoice_id.id, + 'salesperson_id': sale.salesperson_id.id, + 'product_id': sale.product_id.id, + 'qty_so': sale.outgoing, + 'qty_po': line.qty_purchase, + 'purchase_price': sale.sale_line_id.purchase_price, + 'purchase_tax_id': sale.sale_line_id.purchase_tax_id.id if sale.sale_line_id.purchase_tax_id.id else None, + # 'purchase_price': price_so.purchase_price, + # 'purchase_tax_id': price_so.purchase_tax_id.id if price_so.purchase_tax_id.id else None, + }]) def _create_sync_purchasing_job(self, jobs): date = datetime.utcnow() -- cgit v1.2.3 From 513e38bb38e712a37f2d2b8427212f4e83950f5a Mon Sep 17 00:00:00 2001 From: stephanchrst Date: Fri, 15 Nov 2024 10:11:55 +0700 Subject: cr qty available to available bandengan in generate reordering rule --- indoteknik_custom/models/automatic_purchase.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/indoteknik_custom/models/automatic_purchase.py b/indoteknik_custom/models/automatic_purchase.py index 46cc9fa5..4e96e6d4 100644 --- a/indoteknik_custom/models/automatic_purchase.py +++ b/indoteknik_custom/models/automatic_purchase.py @@ -466,9 +466,9 @@ class AutomaticPurchase(models.Model): count = 0 for point in orderpoints: # _logger.info('test %s' % point.product_id.name) - if point.product_id.virtual_available > point.product_min_qty: + if point.product_id.qty_available_bandengan > point.product_min_qty: continue - qty_purchase = point.product_max_qty - point.product_id.virtual_available + qty_purchase = point.product_max_qty - point.product_id.qty_available_bandengan po_line = self.env['purchase.order.line'].search([('product_id', '=', point.product_id.id), ('order_id.state', '=', 'done')], order='id desc', limit=1) if self.vendor_id: @@ -495,7 +495,7 @@ class AutomaticPurchase(models.Model): 'qty_purchase': qty_purchase, 'qty_min': point.product_min_qty, 'qty_max': point.product_max_qty, - 'qty_available': point.product_id.virtual_available, + 'qty_available': point.product_id.qty_available_bandengan, # 'partner_id': po_line.order_id.partner_id.id, # 'last_price': po_line.price_unit, 'partner_id': vendor_id, -- cgit v1.2.3 From afc8a108c9b1c52656bb3bbac9111dfa6e590bcb Mon Sep 17 00:00:00 2001 From: Azka Nathan Date: Fri, 15 Nov 2024 13:38:26 +0700 Subject: comment code check state reserve on approval unreserve --- indoteknik_custom/models/approval_unreserve.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/indoteknik_custom/models/approval_unreserve.py b/indoteknik_custom/models/approval_unreserve.py index ba8b8da7..d847ea37 100644 --- a/indoteknik_custom/models/approval_unreserve.py +++ b/indoteknik_custom/models/approval_unreserve.py @@ -86,7 +86,7 @@ class ApprovalUnreserve(models.Model): }) # Trigger the unreserve function self._trigger_unreserve() - self.picking_id.check_state_reserve() + # self.picking_id.check_state_reserve() def action_reject(self, reason): if self.env.user.id != self.user_id.id: -- cgit v1.2.3 From 0731e9433b959f3aee8bff0488272f54a32546fe Mon Sep 17 00:00:00 2001 From: Azka Nathan Date: Sat, 16 Nov 2024 09:16:25 +0700 Subject: deactivate kelurahan validation --- indoteknik_custom/models/sale_order.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/indoteknik_custom/models/sale_order.py b/indoteknik_custom/models/sale_order.py index 80e111a8..21f83521 100755 --- a/indoteknik_custom/models/sale_order.py +++ b/indoteknik_custom/models/sale_order.py @@ -491,8 +491,8 @@ class SaleOrder(models.Model): raise UserError('Phone Real Delivery Address harus diisi') if not real_delivery_address.kecamatan_id: raise UserError('Kecamatan Real Delivery Address harus diisi') - if not real_delivery_address.kelurahan_id: - raise UserError('Kelurahan Real Delivery Address harus diisi') + # if not real_delivery_address.kelurahan_id: + # raise UserError('Kelurahan Real Delivery Address harus diisi') def generate_payment_link_midtrans_sales_order(self): # midtrans_url = 'https://app.sandbox.midtrans.com/snap/v1/transactions' # dev - sandbox -- cgit v1.2.3 From 5fda2edbacb79e31f26e0ba332a76244354ec337 Mon Sep 17 00:00:00 2001 From: Azka Nathan Date: Sat, 16 Nov 2024 09:47:49 +0700 Subject: activate function constrains departure date --- indoteknik_custom/models/stock_picking.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/indoteknik_custom/models/stock_picking.py b/indoteknik_custom/models/stock_picking.py index ee1dd68c..68e94ef7 100644 --- a/indoteknik_custom/models/stock_picking.py +++ b/indoteknik_custom/models/stock_picking.py @@ -194,9 +194,9 @@ class StockPicking(models.Model): else: raise UserError(f"Error saat mengirim ke Biteship: {response.content}") - # @api.constrains('driver_departure_date') - # def constrains_driver_departure_date(self): - # self.date_doc_kirim = self.driver_departure_date + @api.constrains('driver_departure_date') + def constrains_driver_departure_date(self): + self.date_doc_kirim = self.driver_departure_date @api.constrains('arrival_time') def constrains_arrival_time(self): -- cgit v1.2.3 From b57a1313743121f4a6a089fd175bb1594e042afb Mon Sep 17 00:00:00 2001 From: Azka Nathan Date: Mon, 18 Nov 2024 09:58:20 +0700 Subject: cr stock_picking --- indoteknik_custom/models/stock_picking.py | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/indoteknik_custom/models/stock_picking.py b/indoteknik_custom/models/stock_picking.py index 68e94ef7..430c54f3 100644 --- a/indoteknik_custom/models/stock_picking.py +++ b/indoteknik_custom/models/stock_picking.py @@ -196,7 +196,8 @@ class StockPicking(models.Model): @api.constrains('driver_departure_date') def constrains_driver_departure_date(self): - self.date_doc_kirim = self.driver_departure_date + if not self.date_doc_kirim: + self.date_doc_kirim = self.driver_departure_date @api.constrains('arrival_time') def constrains_arrival_time(self): @@ -450,6 +451,8 @@ class StockPicking(models.Model): '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': @@ -459,6 +462,8 @@ class StockPicking(models.Model): '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') -- cgit v1.2.3 From d5cef4f36b8f6e74d536d26fa01a3b68b5e57ba8 Mon Sep 17 00:00:00 2001 From: Azka Nathan Date: Mon, 18 Nov 2024 10:05:29 +0700 Subject: fix bug vendor approval --- indoteknik_custom/models/vendor_approval.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/indoteknik_custom/models/vendor_approval.py b/indoteknik_custom/models/vendor_approval.py index bcc5d3ea..56b81a37 100644 --- a/indoteknik_custom/models/vendor_approval.py +++ b/indoteknik_custom/models/vendor_approval.py @@ -32,7 +32,7 @@ class VendorApproval(models.Model): 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: + if not self.order_id.due_id and self.order_id.state == 'draft': self.order_id.action_confirm() def action_reject(self): -- cgit v1.2.3 From c11d6c564db098b3553893406e9f59bbef029feb Mon Sep 17 00:00:00 2001 From: it-fixcomart Date: Mon, 18 Nov 2024 10:10:03 +0700 Subject: edit code --- indoteknik_api/models/sale_order.py | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/indoteknik_api/models/sale_order.py b/indoteknik_api/models/sale_order.py index 8e0371a3..16a17200 100644 --- a/indoteknik_api/models/sale_order.py +++ b/indoteknik_api/models/sale_order.py @@ -85,6 +85,11 @@ class SaleOrder(models.Model): } product['quantity'] = line.product_uom_qty product['available_quantity'] = line.product_available_quantity + for data_v2 in sale_order.fulfillment_line_v2: + product_v2 = self.env['product.product'].api_single_response(data_v2.product_id) + if product['id'] == product_v2['id']: + product['so_qty'] = data_v2.so_qty + product['reserved_stock_qty'] = data_v2.reserved_stock_qty data_with_detail['products'].append(product) for invoice in sale_order.invoice_ids: if invoice.state == 'posted': -- cgit v1.2.3 From 34c6611b059cf6ea79bb78e359b973719848f09b Mon Sep 17 00:00:00 2001 From: Azka Nathan Date: Mon, 18 Nov 2024 10:57:21 +0700 Subject: fix bug vendor approval --- indoteknik_custom/models/sale_order.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/indoteknik_custom/models/sale_order.py b/indoteknik_custom/models/sale_order.py index 21f83521..3d91ba91 100755 --- a/indoteknik_custom/models/sale_order.py +++ b/indoteknik_custom/models/sale_order.py @@ -748,7 +748,7 @@ class SaleOrder(models.Model): raise UserError("Salesperson sudah tidak aktif, mohon diisi yang benar pada data SO dan Contact") def sale_order_approve(self): - if self.validate_different_vendor() and not self.vendor_approval and not self.vendor_approval_id: + if self.validate_different_vendor() and not self.vendor_approval: return self._create_notification_action('Notification', 'Terdapat Vendor yang berbeda dengan MD Vendor') self.check_due() @@ -925,7 +925,7 @@ class SaleOrder(models.Model): def action_confirm(self): for order in self: - if self.validate_different_vendor() and not self.vendor_approval and not self.vendor_approval_id: + if self.validate_different_vendor() and not self.vendor_approval: return self._create_notification_action('Notification', 'Terdapat Vendor yang berbeda dengan MD Vendor') order.check_data_real_delivery_address() -- 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_api/models/product_product.py | 5 +++-- indoteknik_custom/models/website_user_cart.py | 2 +- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/indoteknik_api/models/product_product.py b/indoteknik_api/models/product_product.py index 386ddb6a..f8869c7d 100644 --- a/indoteknik_api/models/product_product.py +++ b/indoteknik_api/models/product_product.py @@ -61,8 +61,9 @@ class ProductProduct(models.Model): price_for = self.env.context.get('price_for', 'odoo') pricelist = pricelist or self.env.context.get('user_pricelist') default_price_tier = '1_v2' - - price_tier = pricelist.get_tier_level() + price_tier = [] + if pricelist: + price_tier = pricelist.get_tier_level() price_tier = price_tier if price_tier else default_price_tier pricelist = self._get_pricelist_tier(price_tier) 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 +- indoteknik_custom/views/res_partner.xml | 2 +- indoteknik_custom/views/sale_order.xml | 40 ++++++++++++++++++++++++++++++++- 3 files changed, 41 insertions(+), 3 deletions(-) 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') diff --git a/indoteknik_custom/views/res_partner.xml b/indoteknik_custom/views/res_partner.xml index e8d3bf1a..1b164161 100644 --- a/indoteknik_custom/views/res_partner.xml +++ b/indoteknik_custom/views/res_partner.xml @@ -31,7 +31,7 @@ - + diff --git a/indoteknik_custom/views/sale_order.xml b/indoteknik_custom/views/sale_order.xml index 53dac424..3a3b1c81 100755 --- a/indoteknik_custom/views/sale_order.xml +++ b/indoteknik_custom/views/sale_order.xml @@ -118,9 +118,47 @@ } +
+
+
+
+ +
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
- + 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(-) 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(-) 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(-) 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/__manifest__.py | 2 + 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 +++++++++++++--------- indoteknik_custom/security/ir.model.access.csv | 3 +- .../views/form_vendor_approval_multi_approve.xml | 31 +++++++ .../views/form_vendor_approval_multi_reject.xml | 31 +++++++ indoteknik_custom/views/sale_order.xml | 2 +- indoteknik_custom/views/vendor_approval.xml | 62 ++++++++------ 11 files changed, 233 insertions(+), 85 deletions(-) create mode 100644 indoteknik_custom/models/va_multi_approve.py create mode 100644 indoteknik_custom/models/va_multi_reject.py create mode 100644 indoteknik_custom/views/form_vendor_approval_multi_approve.xml create mode 100644 indoteknik_custom/views/form_vendor_approval_multi_reject.xml diff --git a/indoteknik_custom/__manifest__.py b/indoteknik_custom/__manifest__.py index da44ebf3..89f62524 100755 --- a/indoteknik_custom/__manifest__.py +++ b/indoteknik_custom/__manifest__.py @@ -146,6 +146,8 @@ 'views/vendor_approval.xml', 'views/find_page.xml', 'views/approval_retur_picking.xml', + 'views/form_vendor_approval_multi_approve.xml', + 'views/form_vendor_approval_multi_reject.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 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 diff --git a/indoteknik_custom/security/ir.model.access.csv b/indoteknik_custom/security/ir.model.access.csv index e817a28d..c2ff2a3b 100755 --- a/indoteknik_custom/security/ir.model.access.csv +++ b/indoteknik_custom/security/ir.model.access.csv @@ -139,10 +139,11 @@ access_account_tax,access.account.tax,model_account_tax,,1,1,1,1 access_approval_unreserve,access.approval.unreserve,model_approval_unreserve,,1,1,1,1 access_approval_unreserve_line,access.approval.unreserve.line,model_approval_unreserve_line,,1,1,1,1 access_vendor_approval,access.vendor.approval,model_vendor_approval,,1,1,1,1 -access_vendor_approval_line,access.vendor.approval.line,model_vendor_approval_line,,1,1,1,1 access_vit_kota,access.vit.kota,model_vit_kota,,1,1,1,1 access_v_brand_product_category,access.v.brand.product.category,model_v_brand_product_category,,1,1,1,1 access_web_find_page,access.web.find.page,model_web_find_page,,1,1,1,1 access_v_requisition_match_po,access.v.requisition.match.po,model_v_requisition_match_po,,1,1,1,1 access_approval_retur_picking,access.approval.retur.picking,model_approval_retur_picking,,1,1,1,1 access_sales_order_fulfillment_v2,access.sales.order.fulfillment.v2,model_sales_order_fulfillment_v2,,1,1,1,1 +access_va_multi_approve,access.va.multi.approve,model_va_multi_approve,,1,1,1,1 +access_va_multi_reject,access.va.multi.reject,model_va_multi_reject,,1,1,1,1 diff --git a/indoteknik_custom/views/form_vendor_approval_multi_approve.xml b/indoteknik_custom/views/form_vendor_approval_multi_approve.xml new file mode 100644 index 00000000..d9be107e --- /dev/null +++ b/indoteknik_custom/views/form_vendor_approval_multi_approve.xml @@ -0,0 +1,31 @@ + + + + + VA Multi Approve + va.multi.approve + + + + + Apakah Anda Yakin Ingin Approve Vendor Approval? + + +
+
+ +
+
+ + + VA Multi Approve + va.multi.approve + ir.actions.act_window + form + + new + +
+
\ No newline at end of file diff --git a/indoteknik_custom/views/form_vendor_approval_multi_reject.xml b/indoteknik_custom/views/form_vendor_approval_multi_reject.xml new file mode 100644 index 00000000..666de261 --- /dev/null +++ b/indoteknik_custom/views/form_vendor_approval_multi_reject.xml @@ -0,0 +1,31 @@ + + + + + VA Multi Reject + va.multi.reject + +
+ + + Apakah Anda Yakin Ingin Reject Vendor Approval? + + +
+
+
+
+
+ + + VA Multi Reject + va.multi.reject + ir.actions.act_window + form + + new + +
+
\ No newline at end of file diff --git a/indoteknik_custom/views/sale_order.xml b/indoteknik_custom/views/sale_order.xml index 3a3b1c81..e12130de 100755 --- a/indoteknik_custom/views/sale_order.xml +++ b/indoteknik_custom/views/sale_order.xml @@ -82,7 +82,7 @@ - +