From afda28eb5bcda235c3c0b9479884894f9cd88c8c Mon Sep 17 00:00:00 2001 From: it-fixcomart Date: Tue, 1 Oct 2024 17:30:48 +0700 Subject: add inrernal input --- indoteknik_custom/models/user_company_request.py | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) (limited to 'indoteknik_custom/models') diff --git a/indoteknik_custom/models/user_company_request.py b/indoteknik_custom/models/user_company_request.py index d540b0f6..f86f3872 100644 --- a/indoteknik_custom/models/user_company_request.py +++ b/indoteknik_custom/models/user_company_request.py @@ -1,4 +1,4 @@ -from odoo import models, fields +from odoo import models, fields, api from odoo.exceptions import UserError from odoo.http import request @@ -13,14 +13,32 @@ class UserCompanyRequest(models.Model): ('approved', 'Approve'), ('rejected', 'Reject'), ], string='Approval') + internal_input = fields.Char(string='Internal Input') + company_type = fields.Char(string='Company Type', compute='_compute_company_type') + + @api.depends('user_company_id.customer_type') + def _compute_company_type(self): + for record in self: + if record.user_company_id.customer_type == 'nonpkp': + record.company_type = 'Non PKP' + elif record.user_company_id.customer_type == 'pkp': + record.company_type = 'PKP' + else: + record.company_type = 'company type belum di set' def write(self, vals): user = self.get_user_by_email(self.user_id.email) user.parent_name = self.user_input is_approve = vals.get('is_approve') + is_internal_input = vals.get('internal_input') if self.is_approve and is_approve: raise UserError('Tidak dapat mengubah approval yang sudah diisi') + if is_internal_input: + if self.user_company_id.nama_wajib_pajak == self.user_company_id.name: + self.user_company_id.nama_wajib_pajak = is_internal_input + self.user_company_id.name = is_internal_input + if not self.is_approve and is_approve: if is_approve == 'approved': self.user_id.parent_id = self.user_company_id.id -- cgit v1.2.3 From a2d93b35cc849d742e851f5d876557ac18c1a9e1 Mon Sep 17 00:00:00 2001 From: Azka Nathan Date: Wed, 2 Oct 2024 10:41:13 +0700 Subject: cr function get id partner --- indoteknik_custom/models/sale_order.py | 26 ++++++++++++++++---------- 1 file changed, 16 insertions(+), 10 deletions(-) (limited to 'indoteknik_custom/models') diff --git a/indoteknik_custom/models/sale_order.py b/indoteknik_custom/models/sale_order.py index 8f48e898..8c506c47 100755 --- a/indoteknik_custom/models/sale_order.py +++ b/indoteknik_custom/models/sale_order.py @@ -140,18 +140,27 @@ class SaleOrder(models.Model): for line in self.order_line: if line.weight: total_weight += line.weight + line.product_id.weight = line.weight else: missing_weight_products.append(line.product_id.name) + if missing_weight_products: + product_names = ', '.join(missing_weight_products) + self.message_post(body=f"Produk berikut tidak memiliki berat: {product_names}") + if total_weight == 0: raise UserError("Tidak dapat mengestimasi ongkir tanpa berat yang valid.") # Mendapatkan city_id berdasarkan nama kota origin_city_name = self.warehouse_id.partner_id.kota_id.name destination_city_name = self.real_shipping_id.kota_id.name - - origin_city_id = self._get_city_id_by_name(origin_city_name) - destination_city_id = self._get_city_id_by_name(destination_city_name) + origin_subdistrict_name = self.warehouse_id.partner_id.kecamatan_id.name + destination_subdistrict_name = self.real_shipping_id.kecamatan_id.name + + origin_id_city = self._get_city_id_by_name(origin_city_name) + destination_id_city = self._get_city_id_by_name(destination_city_name) + origin_city_id = self._get_subdistrict_id_by_name(origin_id_city, origin_subdistrict_name) + destination_city_id = self._get_subdistrict_id_by_name(destination_id_city, destination_subdistrict_name) if not origin_city_id or not destination_city_id: raise UserError("Gagal mendapatkan ID kota asal atau tujuan.") @@ -160,7 +169,8 @@ class SaleOrder(models.Model): if result: estimated_cost = result['rajaongkir']['results'][0]['costs'][0]['cost'][0]['value'] self.delivery_amt = estimated_cost - self.message_post(body=f"Estimasi Ongkos Kirim: {estimated_cost}") + self.message_post(body=f"Estimasi Ongkos Kirim: {self.delivery_amt}") + else: raise UserError("Gagal mendapatkan estimasi ongkir.") @@ -173,9 +183,9 @@ class SaleOrder(models.Model): data = { 'origin': int(origin_city_id), - 'originType': 'city', + 'originType': 'subdistrict', 'destination': int(destination_city_id), - 'destinationType': 'city', + 'destinationType': 'subdistrict', 'weight': int(total_weight * 1000), 'courier': courier, } @@ -186,16 +196,13 @@ class SaleOrder(models.Model): return None def _normalize_city_name(self, city_name): - # Ubah nama kota menjadi huruf kecil city_name = city_name.lower() - # Hilangkan prefiks "kabupaten" atau "kota" jika ada if city_name.startswith('kabupaten'): city_name = city_name.replace('kabupaten', '').strip() elif city_name.startswith('kota'): city_name = city_name.replace('kota', '').strip() - # Hilangkan spasi yang berlebihan city_name = " ".join(city_name.split()) return city_name @@ -206,7 +213,6 @@ class SaleOrder(models.Model): 'key': '7ac9883688da043b50cc32f0e3070bb6', } - # Normalisasi nama kota sebelum melakukan pencarian normalized_city_name = self._normalize_city_name(city_name) response = requests.get(url, headers=headers) -- cgit v1.2.3 From 27a603a8bc4750dcacd295e07144c5ce2621783c Mon Sep 17 00:00:00 2001 From: Azka Nathan Date: Wed, 2 Oct 2024 15:10:46 +0700 Subject: cr estimated shipping price + cr user company request --- indoteknik_custom/models/res_partner.py | 4 +-- indoteknik_custom/models/sale_order.py | 5 ++-- indoteknik_custom/models/user_company_request.py | 34 +++++++++++++++++++++++- 3 files changed, 38 insertions(+), 5 deletions(-) (limited to 'indoteknik_custom/models') diff --git a/indoteknik_custom/models/res_partner.py b/indoteknik_custom/models/res_partner.py index 2846c14b..25db16d0 100644 --- a/indoteknik_custom/models/res_partner.py +++ b/indoteknik_custom/models/res_partner.py @@ -18,8 +18,8 @@ class ResPartner(models.Model): ('pkp', 'PKP'), ('nonpkp', 'Non PKP') ]) - sppkp = fields.Char(string="SPPKP", tracking=3) - npwp = fields.Char(string="NPWP", tracking=3) + sppkp = fields.Char(string="SPPKP", tracking=True) + npwp = fields.Char(string="NPWP", tracking=True) counter = fields.Integer(string="Counter", default=0) leadtime = fields.Integer(string="Leadtime", default=0) digital_invoice_tax = fields.Boolean(string="Digital Invoice & Faktur Pajak") diff --git a/indoteknik_custom/models/sale_order.py b/indoteknik_custom/models/sale_order.py index 8c506c47..2b20a533 100755 --- a/indoteknik_custom/models/sale_order.py +++ b/indoteknik_custom/models/sale_order.py @@ -145,8 +145,9 @@ class SaleOrder(models.Model): missing_weight_products.append(line.product_id.name) if missing_weight_products: - product_names = ', '.join(missing_weight_products) - self.message_post(body=f"Produk berikut tidak memiliki berat: {product_names}") + product_names = '\n'.join(missing_weight_products) + self.message_post(body=f"Produk berikut tidak memiliki berat: \n{product_names}") + if total_weight == 0: raise UserError("Tidak dapat mengestimasi ongkir tanpa berat yang valid.") diff --git a/indoteknik_custom/models/user_company_request.py b/indoteknik_custom/models/user_company_request.py index d540b0f6..1b3434b1 100644 --- a/indoteknik_custom/models/user_company_request.py +++ b/indoteknik_custom/models/user_company_request.py @@ -1,4 +1,4 @@ -from odoo import models, fields +from odoo import models, fields, api from odoo.exceptions import UserError from odoo.http import request @@ -13,6 +13,38 @@ class UserCompanyRequest(models.Model): ('approved', 'Approve'), ('rejected', 'Reject'), ], string='Approval') + similar_company_ids = fields.Many2many('res.partner', compute="_compute_similar_companies", string="Similar Companies") + + @api.depends('user_input') + def _compute_similar_companies(self): + for record in self: + if record.user_input: + record.similar_company_ids = [(6, 0, self.get_similar_companies(record.user_input))] + 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 name ILIKE %s OR levenshtein(name::text, %s) < 3 + ORDER BY levenshtein(name::text, %s) ASC + """ + # Using '%' to match the partial company name + 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 + def write(self, vals): user = self.get_user_by_email(self.user_id.email) -- cgit v1.2.3 From 8b63d79efe0137ce6af535847f33868e73ce8d3c Mon Sep 17 00:00:00 2001 From: Azka Nathan Date: Wed, 2 Oct 2024 15:31:02 +0700 Subject: add validation data realshippingaddress --- indoteknik_custom/models/sale_order.py | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) (limited to 'indoteknik_custom/models') diff --git a/indoteknik_custom/models/sale_order.py b/indoteknik_custom/models/sale_order.py index 2b20a533..f8127d8c 100755 --- a/indoteknik_custom/models/sale_order.py +++ b/indoteknik_custom/models/sale_order.py @@ -419,6 +419,22 @@ class SaleOrder(models.Model): for line in order.order_line: total += line.vendor_subtotal order.purchase_total = total + + 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') + 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 @@ -565,8 +581,6 @@ 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') @api.onchange('partner_id') def onchange_partner_contact(self): @@ -791,6 +805,7 @@ class SaleOrder(models.Model): def action_confirm(self): for order in self: + order.check_data_real_delivery_address() order.sale_order_check_approve() order._validate_order() order.order_line.validate_line() -- cgit v1.2.3 From 16ddcb43b85c1deeda29bf6bb5db4ef73b8d20d2 Mon Sep 17 00:00:00 2001 From: stephanchrst Date: Wed, 2 Oct 2024 16:21:55 +0700 Subject: add suggested vendor by md, use later --- indoteknik_custom/models/sale_order_line.py | 2 ++ 1 file changed, 2 insertions(+) (limited to 'indoteknik_custom/models') diff --git a/indoteknik_custom/models/sale_order_line.py b/indoteknik_custom/models/sale_order_line.py index d1dcd0af..14bb8c99 100644 --- a/indoteknik_custom/models/sale_order_line.py +++ b/indoteknik_custom/models/sale_order_line.py @@ -32,6 +32,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) @api.constrains('note_procurement') def note_procurement_to_apo(self): @@ -245,6 +246,7 @@ class SaleOrderLine(models.Model): # 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_id = vendor_id + line.md_vendor_id = vendor_id line.tax_id = line.order_id.sales_tax_id # price, taxes = line._get_valid_purchase_price(purchase_price) line.purchase_price = price -- cgit v1.2.3 From 799c216979fb4216422c2a584a763b286713b8d2 Mon Sep 17 00:00:00 2001 From: it-fixcomart Date: Thu, 3 Oct 2024 10:04:18 +0700 Subject: add is in bu ke variant product solr --- indoteknik_custom/models/solr/product_product.py | 13 ++++++++++++- indoteknik_custom/models/solr/product_template.py | 3 ++- 2 files changed, 14 insertions(+), 2 deletions(-) (limited to 'indoteknik_custom/models') diff --git a/indoteknik_custom/models/solr/product_product.py b/indoteknik_custom/models/solr/product_product.py index 35e3a4b3..df20cc4b 100644 --- a/indoteknik_custom/models/solr/product_product.py +++ b/indoteknik_custom/models/solr/product_product.py @@ -47,6 +47,16 @@ class ProductProduct(models.Model): category_id = category.id category_name = category.name + # Check if the product's inventory location is in ID 57 or 83 + target_locations = [57, 83] + 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) + document = solr_model.get_doc('variants', variant.id) document.update({ @@ -76,7 +86,8 @@ class ProductProduct(models.Model): 'publish_b': not variant.unpublished, 'sni_b': variant.sni, 'tkdn_b': variant.tkdn, - 'qty_sold_f': variant.qty_sold + 'qty_sold_f': variant.qty_sold, + "is_in_bu_b": is_in_bu, }) self.solr().add(docs=[document], softCommit=True) diff --git a/indoteknik_custom/models/solr/product_template.py b/indoteknik_custom/models/solr/product_template.py index 1eb6f31b..70246ba3 100644 --- a/indoteknik_custom/models/solr/product_template.py +++ b/indoteknik_custom/models/solr/product_template.py @@ -74,7 +74,8 @@ class ProductTemplate(models.Model): target_locations = [57, 83] stock_quant = self.env['stock.quant'].search([ ('product_id', 'in', template.product_variant_ids.ids), - ('location_id', 'in', target_locations) + ('location_id', 'in', target_locations), + ('quantity', '>', 0) ]) is_in_bu = bool(stock_quant) -- cgit v1.2.3 From 4a69c71eab2d4ea3504a0cf6e3a9ca241be48594 Mon Sep 17 00:00:00 2001 From: Azka Nathan Date: Thu, 3 Oct 2024 10:12:24 +0700 Subject: push --- indoteknik_custom/models/sale_order.py | 32 ++++++++++++++++++++--- indoteknik_custom/models/sale_order_line.py | 7 ++++++ indoteknik_custom/models/vendor_approval.py | 39 +++++++++++++++++++++++++++++ 3 files changed, 75 insertions(+), 3 deletions(-) create mode 100644 indoteknik_custom/models/vendor_approval.py (limited to 'indoteknik_custom/models') diff --git a/indoteknik_custom/models/sale_order.py b/indoteknik_custom/models/sale_order.py index f8127d8c..538e0209 100755 --- a/indoteknik_custom/models/sale_order.py +++ b/indoteknik_custom/models/sale_order.py @@ -145,9 +145,8 @@ class SaleOrder(models.Model): missing_weight_products.append(line.product_id.name) if missing_weight_products: - product_names = '\n'.join(missing_weight_products) - self.message_post(body=f"Produk berikut tidak memiliki berat: \n{product_names}") - + product_names = '
'.join(missing_weight_products) + self.message_post(body=f"Produk berikut tidak memiliki berat:
{product_names}") if total_weight == 0: raise UserError("Tidak dapat mengestimasi ongkir tanpa berat yang valid.") @@ -802,9 +801,36 @@ class SaleOrder(models.Model): 'body_html': email_body, 'email_to': salesperson_email, }).send() + + def validate_different_vendor(self): + different_vendor = self.order_line.filtered(lambda l: l.vendor_id.id != l.vendor_md_id.id) + if different_vendor: + vendor_approval = self.env['vendor.approval'].create({ + 'order_id': self.id, + 'state': 'draft', + }) + for line in self.line: + self.env['vendor.approval.line'].create({ + 'vendor_approval_id': vendor_approval.id, + 'product_id': line.product_id.id, + 'product_uom_qty': line.product_uom_qty, + 'vendor_id': line.vendor_id.id, + 'vendor_md_id': line.vendor_md_id.id, + 'purchase_price': line.purchase_price, + 'purchase_price_md': line.purchase_price_md, + }) + + return True + else: + return False + + def action_confirm(self): for order in self: + if order.validate_partner_invoice_due(): + return self._create_notification_action('Notification', 'Terdapat Vendor yang berbeda dengan MD Vendor') + order.check_data_real_delivery_address() order.sale_order_check_approve() order._validate_order() diff --git a/indoteknik_custom/models/sale_order_line.py b/indoteknik_custom/models/sale_order_line.py index d1dcd0af..dca8534c 100644 --- a/indoteknik_custom/models/sale_order_line.py +++ b/indoteknik_custom/models/sale_order_line.py @@ -14,7 +14,12 @@ class SaleOrderLine(models.Model): states={'draft': [('readonly', False)], 'sent': [('readonly', False)]}, domain="['|', ('company_id', '=', False), ('company_id', '=', company_id)]" ) + vendor_md_id = fields.Many2one( + 'res.partner', string='MD Vendor', readonly=True, + change_default=True, index=True, tracking=1 + ) purchase_price = fields.Float('Purchase', required=True, digits='Product Price', default=0.0) + purchase_price_md = fields.Float('MD Purchase', required=True, digits='Product Price', default=0.0) purchase_tax_id = fields.Many2one('account.tax', string='Tax', domain=['|', ('active', '=', False), ('active', '=', True)]) delivery_amt_line = fields.Float('DeliveryAmtLine', compute='compute_delivery_amt_line') fee_third_party_line = fields.Float('FeeThirdPartyLine', compute='compute_fee_third_party_line', default=0) @@ -245,9 +250,11 @@ class SaleOrderLine(models.Model): # 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_id = vendor_id + line.vendor_md_id = vendor_id line.tax_id = line.order_id.sales_tax_id # price, taxes = line._get_valid_purchase_price(purchase_price) line.purchase_price = price + line.purchase_price_md = price line.purchase_tax_id = taxes attribute_values = line.product_id.product_template_attribute_value_ids.mapped('name') diff --git a/indoteknik_custom/models/vendor_approval.py b/indoteknik_custom/models/vendor_approval.py new file mode 100644 index 00000000..4369a193 --- /dev/null +++ b/indoteknik_custom/models/vendor_approval.py @@ -0,0 +1,39 @@ +from odoo import models, api, fields +from odoo.exceptions import AccessError, UserError, ValidationError +from datetime import timedelta, date +import logging + +_logger = logging.getLogger(__name__) + +class VendorApproval(models.Model): + _name = "vendor.approval" + _description = "Vendor Approval" + _inherit = ['mail.thread'] + _rec_name = 'number' + + 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_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) + + 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') + purchase_price = fields.Many2one(string='Purchase Price') + purchase_price_md= fields.Many2one(string='Purchase Price MD') + + -- cgit v1.2.3 From 7059f095dd09649f7c12f74ff29200f644bbc854 Mon Sep 17 00:00:00 2001 From: Azka Nathan Date: Thu, 3 Oct 2024 11:55:16 +0700 Subject: push --- indoteknik_custom/models/__init__.py | 1 + indoteknik_custom/models/sale_order.py | 12 ++++++++---- indoteknik_custom/models/sale_order_line.py | 10 +++++----- indoteknik_custom/models/vendor_approval.py | 14 ++++++++++++++ 4 files changed, 28 insertions(+), 9 deletions(-) (limited to 'indoteknik_custom/models') diff --git a/indoteknik_custom/models/__init__.py b/indoteknik_custom/models/__init__.py index 3d700ce0..a0064c06 100755 --- a/indoteknik_custom/models/__init__.py +++ b/indoteknik_custom/models/__init__.py @@ -128,3 +128,4 @@ from . import sales_order_reject from . import approval_date_doc from . import account_tax from . import approval_unreserve +from . import vendor_approval diff --git a/indoteknik_custom/models/sale_order.py b/indoteknik_custom/models/sale_order.py index 538e0209..a6ea6c81 100755 --- a/indoteknik_custom/models/sale_order.py +++ b/indoteknik_custom/models/sale_order.py @@ -78,6 +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) customer_type = fields.Selection([ ('pkp', 'PKP'), ('nonpkp', 'Non PKP') @@ -104,6 +105,7 @@ class SaleOrder(models.Model): ('cust_procurement', 'Customer Procurement') ], string='Web Approval', copy=False) compute_fullfillment = fields.Boolean(string='Compute Fullfillment', compute="_compute_fullfillment") + vendor_approval = fields.Boolean(string='Vendor Approval') note_ekspedisi = fields.Char(string="Note Ekspedisi") date_kirim_ril = fields.Datetime(string='Tanggal Kirim SJ', compute='_compute_date_kirim', copy=False) date_status_done = fields.Datetime(string='Date Done DO', compute='_compute_date_kirim', copy=False) @@ -703,6 +705,8 @@ class SaleOrder(models.Model): self._validate_order() for order in self: order.order_line.validate_line() + if order.validate_different_vendor() and not self.vendor_approval: + return self._create_notification_action('Notification', 'Terdapat Vendor yang berbeda dengan MD Vendor') partner = order.partner_id.parent_id or order.partner_id if not partner.property_payment_term_id: @@ -803,12 +807,14 @@ class SaleOrder(models.Model): }).send() def validate_different_vendor(self): - different_vendor = self.order_line.filtered(lambda l: 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, 'state': 'draft', }) + + self.vendor_approval_id = vendor_approval.id for line in self.line: self.env['vendor.approval.line'].create({ 'vendor_approval_id': vendor_approval.id, @@ -823,12 +829,10 @@ class SaleOrder(models.Model): return True else: return False - - def action_confirm(self): for order in self: - if order.validate_partner_invoice_due(): + if order.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() diff --git a/indoteknik_custom/models/sale_order_line.py b/indoteknik_custom/models/sale_order_line.py index dca8534c..06b0f53d 100644 --- a/indoteknik_custom/models/sale_order_line.py +++ b/indoteknik_custom/models/sale_order_line.py @@ -14,12 +14,9 @@ class SaleOrderLine(models.Model): states={'draft': [('readonly', False)], 'sent': [('readonly', False)]}, domain="['|', ('company_id', '=', False), ('company_id', '=', company_id)]" ) - vendor_md_id = fields.Many2one( - 'res.partner', string='MD Vendor', readonly=True, - change_default=True, index=True, tracking=1 - ) + vendor_md_id = fields.Many2one('res.partner', string='MD Vendor') purchase_price = fields.Float('Purchase', required=True, digits='Product Price', default=0.0) - purchase_price_md = fields.Float('MD Purchase', required=True, digits='Product Price', default=0.0) + purchase_price_md = fields.Float('MD Purchase') purchase_tax_id = fields.Many2one('account.tax', string='Tax', domain=['|', ('active', '=', False), ('active', '=', True)]) delivery_amt_line = fields.Float('DeliveryAmtLine', compute='compute_delivery_amt_line') fee_third_party_line = fields.Float('FeeThirdPartyLine', compute='compute_fee_third_party_line', default=0) @@ -138,6 +135,7 @@ class SaleOrderLine(models.Model): elif self.product_id.categ_id.id == 34: # finish good / manufacturing only cost = self.product_id.standard_price self.purchase_price = cost + self.purchase_price_md = cost elif self.product_id.x_manufacture.override_vendor_id: # purchase_price = self.env['purchase.pricelist'].search( # [('vendor_id', '=', self.product_id.x_manufacture.override_vendor_id.id), @@ -145,6 +143,8 @@ class SaleOrderLine(models.Model): # limit=1, order='count_trx_po desc, count_trx_po_vendor desc') price, taxes, vendor_id = self._get_purchase_price_by_vendor(self.product_id, self.vendor_id) self.purchase_price = price + self.purchase_price_md = price + self.vendor_md_id = self.vendor_id self.purchase_tax_id = taxes # else: # purchase_price = self.env['purchase.pricelist'].search( diff --git a/indoteknik_custom/models/vendor_approval.py b/indoteknik_custom/models/vendor_approval.py index 4369a193..442aec7a 100644 --- a/indoteknik_custom/models/vendor_approval.py +++ b/indoteknik_custom/models/vendor_approval.py @@ -15,7 +15,21 @@ class VendorApproval(models.Model): partner_id = fields.Many2one('res.partner', string="Customer", 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', 'Cancel')], string='State', tracking=True) + + 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.update({'vendor_approval': True}) + self.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' + def unlink(self): res = super(VendorApproval, self).unlink() if not self._name == 'vendor.approval': -- cgit v1.2.3 From 48c220d1c38f435962b8b630c5209ba781ca30df Mon Sep 17 00:00:00 2001 From: Azka Nathan Date: Fri, 4 Oct 2024 14:23:59 +0700 Subject: push --- indoteknik_custom/models/sale_order.py | 71 ++++++++++++++++++++------- indoteknik_custom/models/sale_order_line.py | 8 +-- indoteknik_custom/models/vendor_approval.py | 28 +++++++++-- indoteknik_custom/models/website_user_cart.py | 2 +- 4 files changed, 82 insertions(+), 27 deletions(-) (limited to 'indoteknik_custom/models') diff --git a/indoteknik_custom/models/sale_order.py b/indoteknik_custom/models/sale_order.py index a6ea6c81..0f22a7d4 100755 --- a/indoteknik_custom/models/sale_order.py +++ b/indoteknik_custom/models/sale_order.py @@ -135,6 +135,12 @@ class SaleOrder(models.Model): 'account.payment.term', string='Payment Terms', check_company=True, # Unrequired company domain="['|', ('company_id', '=', False), ('company_id', '=', company_id)]", tracking=True) + total_weight = fields.Float(string='Total Weight', compute='_compute_total_weight') + + def _compute_total_weight(self): + for order in self: + order.total_weight = sum(line.weight for line in order.order_line) + def action_estimate_shipping(self): total_weight = 0 missing_weight_products = [] @@ -155,38 +161,45 @@ class SaleOrder(models.Model): # Mendapatkan city_id berdasarkan nama kota origin_city_name = self.warehouse_id.partner_id.kota_id.name - destination_city_name = self.real_shipping_id.kota_id.name - origin_subdistrict_name = self.warehouse_id.partner_id.kecamatan_id.name - destination_subdistrict_name = self.real_shipping_id.kecamatan_id.name + destination_subsdistrict_id = self.real_shipping_id.kecamatan_id.rajaongkir_id - origin_id_city = self._get_city_id_by_name(origin_city_name) - destination_id_city = self._get_city_id_by_name(destination_city_name) - origin_city_id = self._get_subdistrict_id_by_name(origin_id_city, origin_subdistrict_name) - destination_city_id = self._get_subdistrict_id_by_name(destination_id_city, destination_subdistrict_name) - - if not origin_city_id or not destination_city_id: + if not destination_subsdistrict_id: raise UserError("Gagal mendapatkan ID kota asal atau tujuan.") - result = self._call_rajaongkir_api(total_weight, origin_city_id, destination_city_id) + result = self._call_rajaongkir_api(total_weight, destination_subsdistrict_id) if result: estimated_cost = result['rajaongkir']['results'][0]['costs'][0]['cost'][0]['value'] self.delivery_amt = estimated_cost - self.message_post(body=f"Estimasi Ongkos Kirim: {self.delivery_amt}") + shipping_info = [] + for courier in result['rajaongkir']['results']: + for cost_detail in courier['costs']: + service = cost_detail['service'] + description = cost_detail['description'] + etd = cost_detail['cost'][0]['etd'] + value = cost_detail['cost'][0]['value'] + shipping_info.append(f"Service: {service}, Description: {description}, ETD: {etd} hari, Cost: Rp {value}") + + log_message = "
".join(shipping_info) + + description_ongkir = result['rajaongkir']['results'][0]['costs'][0]['description'] + etd_ongkir = result['rajaongkir']['results'][0]['costs'][0]['cost'][0]['etd'] + service_ongkir = result['rajaongkir']['results'][0]['costs'][0]['service'] + self.message_post(body=f"Estimasi Ongkos Kirim: Rp{self.delivery_amt}
Service: {service_ongkir}
Description: {description_ongkir}
ETD: {etd_ongkir}
Detail Lain:
{log_message}") else: raise UserError("Gagal mendapatkan estimasi ongkir.") - def _call_rajaongkir_api(self, total_weight, origin_city_id, destination_city_id): + def _call_rajaongkir_api(self, total_weight, destination_subsdistrict_id): url = 'https://pro.rajaongkir.com/api/cost' headers = { - 'key': '7ac9883688da043b50cc32f0e3070bb6', + 'key': '9b1310f644056d84d60b0af6bb21611a', } courier = self.carrier_id.name.lower() data = { - 'origin': int(origin_city_id), + 'origin': 2127, 'originType': 'subdistrict', - 'destination': int(destination_city_id), + 'destination': int(destination_subsdistrict_id), 'destinationType': 'subdistrict', 'weight': int(total_weight * 1000), 'courier': courier, @@ -212,7 +225,7 @@ class SaleOrder(models.Model): def _get_city_id_by_name(self, city_name): url = 'https://pro.rajaongkir.com/api/city' headers = { - 'key': '7ac9883688da043b50cc32f0e3070bb6', + 'key': '9b1310f644056d84d60b0af6bb21611a', } normalized_city_name = self._normalize_city_name(city_name) @@ -228,14 +241,17 @@ class SaleOrder(models.Model): def _get_subdistrict_id_by_name(self, city_id, subdistrict_name): url = f'https://pro.rajaongkir.com/api/subdistrict?city={city_id}' headers = { - 'key': '7ac9883688da043b50cc32f0e3070bb6', + 'key': '9b1310f644056d84d60b0af6bb21611a', } response = requests.get(url, headers=headers) if response.status_code == 200: subdistrict_data = response.json() for subdistrict in subdistrict_data['rajaongkir']['results']: - if subdistrict['subdistrict_name'].lower() == subdistrict_name.lower(): + subsdistrict_1 = subdistrict['subdistrict_name'].lower() + subsdistrict_2 = subdistrict_name.lower() + + if subsdistrict_1 == subsdistrict_2: return subdistrict['subdistrict_id'] return None @@ -808,14 +824,24 @@ class SaleOrder(models.Model): def validate_different_vendor(self): 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 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 - for line in self.line: + + for line in different_vendor: self.env['vendor.approval.line'].create({ 'vendor_approval_id': vendor_approval.id, 'product_id': line.product_id.id, @@ -824,11 +850,18 @@ class SaleOrder(models.Model): 'vendor_md_id': line.vendor_md_id.id, 'purchase_price': line.purchase_price, 'purchase_price_md': line.purchase_price_md, + 'sales_price': line.price_unit, + 'margin_before': line.margin_md, + '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, }) return True else: return False + def action_confirm(self): for order in self: diff --git a/indoteknik_custom/models/sale_order_line.py b/indoteknik_custom/models/sale_order_line.py index 06b0f53d..98a6c759 100644 --- a/indoteknik_custom/models/sale_order_line.py +++ b/indoteknik_custom/models/sale_order_line.py @@ -34,6 +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') + margin_md = fields.Float(string='Margin MD') @api.constrains('note_procurement') def note_procurement_to_apo(self): @@ -127,6 +128,9 @@ class SaleOrderLine(models.Model): else: line.item_percent_margin = 0 + if not line.margin_md: + line.margin_md = line.item_percent_margin + @api.onchange('vendor_id') def onchange_vendor_id(self): # TODO : need to change this logic @stephan @@ -135,7 +139,6 @@ class SaleOrderLine(models.Model): elif self.product_id.categ_id.id == 34: # finish good / manufacturing only cost = self.product_id.standard_price self.purchase_price = cost - self.purchase_price_md = cost elif self.product_id.x_manufacture.override_vendor_id: # purchase_price = self.env['purchase.pricelist'].search( # [('vendor_id', '=', self.product_id.x_manufacture.override_vendor_id.id), @@ -143,8 +146,6 @@ class SaleOrderLine(models.Model): # limit=1, order='count_trx_po desc, count_trx_po_vendor desc') price, taxes, vendor_id = self._get_purchase_price_by_vendor(self.product_id, self.vendor_id) self.purchase_price = price - self.purchase_price_md = price - self.vendor_md_id = self.vendor_id self.purchase_tax_id = taxes # else: # purchase_price = self.env['purchase.pricelist'].search( @@ -251,6 +252,7 @@ class SaleOrderLine(models.Model): price, taxes, vendor_id = self._get_purchase_price(line.product_id) line.vendor_id = vendor_id line.vendor_md_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 = price diff --git a/indoteknik_custom/models/vendor_approval.py b/indoteknik_custom/models/vendor_approval.py index 442aec7a..e540b8fc 100644 --- a/indoteknik_custom/models/vendor_approval.py +++ b/indoteknik_custom/models/vendor_approval.py @@ -15,21 +15,35 @@ class VendorApproval(models.Model): partner_id = fields.Many2one('res.partner', string="Customer", 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', 'Cancel')], string='State', tracking=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) + + @api.model + def create(self, vals): + vals['number'] = self.env['ir.sequence'].next_by_code('vendor.approval') or '0' + result = super(VendorApproval, self).create(vals) + 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.update({'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) + - 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' + message = "Vendor Approval rejected by %s" % (self.env.user.name) + self.order_id.message_post(body=message) + def unlink(self): res = super(VendorApproval, self).unlink() if not self._name == 'vendor.approval': @@ -47,7 +61,13 @@ class VendorApprovalLine(models.Model): 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') - purchase_price = fields.Many2one(string='Purchase Price') - purchase_price_md= fields.Many2one(string='Purchase Price 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') diff --git a/indoteknik_custom/models/website_user_cart.py b/indoteknik_custom/models/website_user_cart.py index 169f4a6b..8a321187 100644 --- a/indoteknik_custom/models/website_user_cart.py +++ b/indoteknik_custom/models/website_user_cart.py @@ -173,7 +173,7 @@ class WebsiteUserCart(models.Model): } return result - def action_mail_reminder_to_checkout(self, limit=10): + def action_mail_reminder_to_checkout(self, limit=250): user_ids = self.search([]).mapped('user_id')[:limit] for user in user_ids: -- cgit v1.2.3 From 7fe263e557a13a8d3dbed4703e43c90706149f17 Mon Sep 17 00:00:00 2001 From: Azka Nathan Date: Fri, 4 Oct 2024 14:32:48 +0700 Subject: cr limit user send email reminder user cart --- indoteknik_custom/models/website_user_cart.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'indoteknik_custom/models') diff --git a/indoteknik_custom/models/website_user_cart.py b/indoteknik_custom/models/website_user_cart.py index 169f4a6b..8a321187 100644 --- a/indoteknik_custom/models/website_user_cart.py +++ b/indoteknik_custom/models/website_user_cart.py @@ -173,7 +173,7 @@ class WebsiteUserCart(models.Model): } return result - def action_mail_reminder_to_checkout(self, limit=10): + def action_mail_reminder_to_checkout(self, limit=250): user_ids = self.search([]).mapped('user_id')[:limit] for user in user_ids: -- cgit v1.2.3 From 112a7305891e64049b0626907a8db551236318cb Mon Sep 17 00:00:00 2001 From: Azka Nathan Date: Sat, 5 Oct 2024 09:18:03 +0700 Subject: test code email user cart --- indoteknik_custom/models/website_user_cart.py | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) (limited to 'indoteknik_custom/models') diff --git a/indoteknik_custom/models/website_user_cart.py b/indoteknik_custom/models/website_user_cart.py index 8a321187..61051e07 100644 --- a/indoteknik_custom/models/website_user_cart.py +++ b/indoteknik_custom/models/website_user_cart.py @@ -173,14 +173,14 @@ class WebsiteUserCart(models.Model): } return result - def action_mail_reminder_to_checkout(self, limit=250): + def action_mail_reminder_to_checkout(self, limit=150): user_ids = self.search([]).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', 'in', [user.id]), ('is_reminder', '=', False)], order='create_date desc', limit=1) # Proses semua keranjang untuk user tersebut - carts_to_remind = self.search([('user_id', '=', user.id)]) + carts_to_remind = self.search([('user_id', 'in', [user.id])]) if latest_cart and not latest_cart.is_reminder: for cart in carts_to_remind: @@ -195,7 +195,6 @@ class WebsiteUserCart(models.Model): template = self.env.ref('indoteknik_custom.mail_template_user_cart_reminder_to_checkout') template.send_mail(latest_cart.id, force_send=True) - def calculate_discount(self, user_id): carts = self.search([('user_id', '=', user_id)]) voucher = self.env['voucher'].browse(146) -- cgit v1.2.3 From 22b9a0839ff35e2ed5b326e6f28abbfd451feeab Mon Sep 17 00:00:00 2001 From: Azka Nathan Date: Sat, 5 Oct 2024 09:50:49 +0700 Subject: fix bug user cart --- indoteknik_custom/models/website_user_cart.py | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) (limited to 'indoteknik_custom/models') diff --git a/indoteknik_custom/models/website_user_cart.py b/indoteknik_custom/models/website_user_cart.py index 61051e07..76b192c5 100644 --- a/indoteknik_custom/models/website_user_cart.py +++ b/indoteknik_custom/models/website_user_cart.py @@ -173,14 +173,13 @@ class WebsiteUserCart(models.Model): } return result - def action_mail_reminder_to_checkout(self, limit=150): - user_ids = self.search([]).mapped('user_id')[:limit] + def action_mail_reminder_to_checkout(self, limit=250): + user_ids = self.search([('is_reminder', '=', False)]).mapped('user_id')[:limit] for user in user_ids: - latest_cart = self.search([('user_id', 'in', [user.id]), ('is_reminder', '=', False)], order='create_date desc', limit=1) + latest_cart = self.search([('user_id', '=', user.id), ('is_reminder', '=', False)], order='create_date desc', limit=1) - # Proses semua keranjang untuk user tersebut - carts_to_remind = self.search([('user_id', 'in', [user.id])]) + carts_to_remind = self.search([('user_id', '=', user.id)]) if latest_cart and not latest_cart.is_reminder: for cart in carts_to_remind: @@ -191,7 +190,6 @@ class WebsiteUserCart(models.Model): cart.is_selected = False cart.is_reminder = True - # Mengirim email pengingat untuk keranjang terbaru template = self.env.ref('indoteknik_custom.mail_template_user_cart_reminder_to_checkout') template.send_mail(latest_cart.id, force_send=True) -- cgit v1.2.3 From fe6b304a65fd7e576382d871558b3c404b9dd40a Mon Sep 17 00:00:00 2001 From: Azka Nathan Date: Mon, 7 Oct 2024 10:06:40 +0700 Subject: push --- indoteknik_custom/models/__init__.py | 1 + indoteknik_custom/models/partner.py | 7 +++++++ 2 files changed, 8 insertions(+) create mode 100644 indoteknik_custom/models/partner.py (limited to 'indoteknik_custom/models') diff --git a/indoteknik_custom/models/__init__.py b/indoteknik_custom/models/__init__.py index a0064c06..7b41a5fe 100755 --- a/indoteknik_custom/models/__init__.py +++ b/indoteknik_custom/models/__init__.py @@ -129,3 +129,4 @@ from . import approval_date_doc from . import account_tax from . import approval_unreserve from . import vendor_approval +from . import partner diff --git a/indoteknik_custom/models/partner.py b/indoteknik_custom/models/partner.py new file mode 100644 index 00000000..46dc751a --- /dev/null +++ b/indoteknik_custom/models/partner.py @@ -0,0 +1,7 @@ +from odoo import fields, models, api, _ +from odoo.exceptions import AccessError, UserError, ValidationError + +class kota(models.Model): + _inherit = 'vit.kota' + + is_jabodetabek = fields.Boolean(string='Jabodetabek', default=False) \ No newline at end of file -- cgit v1.2.3 From 04709ff9faa72f0c9d6ca4a51f203859e79596de Mon Sep 17 00:00:00 2001 From: Azka Nathan Date: Mon, 7 Oct 2024 10:35:40 +0700 Subject: cr vendor approval --- indoteknik_custom/models/sale_order.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'indoteknik_custom/models') diff --git a/indoteknik_custom/models/sale_order.py b/indoteknik_custom/models/sale_order.py index 0f22a7d4..f24a4bf3 100755 --- a/indoteknik_custom/models/sale_order.py +++ b/indoteknik_custom/models/sale_order.py @@ -716,13 +716,13 @@ 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: + return self._create_notification_action('Notification', 'Terdapat Vendor yang berbeda dengan MD Vendor') self.check_due() self._validate_order() for order in self: order.order_line.validate_line() - if order.validate_different_vendor() and not self.vendor_approval: - return self._create_notification_action('Notification', 'Terdapat Vendor yang berbeda dengan MD Vendor') partner = order.partner_id.parent_id or order.partner_id if not partner.property_payment_term_id: @@ -865,7 +865,7 @@ class SaleOrder(models.Model): def action_confirm(self): for order in self: - if order.validate_different_vendor() and not self.vendor_approval: + if self.validate_different_vendor() and not self.vendor_approval and not self.vendor_approval_id: return self._create_notification_action('Notification', 'Terdapat Vendor yang berbeda dengan MD Vendor') order.check_data_real_delivery_address() -- cgit v1.2.3 From 6b6a7d9f271106325133f1ec84c66717d2eec711 Mon Sep 17 00:00:00 2001 From: Azka Nathan Date: Mon, 7 Oct 2024 11:12:30 +0700 Subject: cr credit limit validation --- indoteknik_custom/models/sale_order.py | 4 ++-- indoteknik_custom/models/stock_picking.py | 4 +++- 2 files changed, 5 insertions(+), 3 deletions(-) (limited to 'indoteknik_custom/models') diff --git a/indoteknik_custom/models/sale_order.py b/indoteknik_custom/models/sale_order.py index f24a4bf3..265ffb9e 100755 --- a/indoteknik_custom/models/sale_order.py +++ b/indoteknik_custom/models/sale_order.py @@ -702,7 +702,7 @@ class SaleOrder(models.Model): partner = order.partner_id.parent_id or order.partner_id if not partner.property_payment_term_id: raise UserError("Payment Term pada Master Data Customer harus diisi") - if not partner.active_limit: + if not partner.active_limit and order.payment_term_id.id not in [27, 26]: raise UserError("Credit Limit pada Master Data Customer harus diisi") if order.payment_term_id != partner.property_payment_term_id: raise UserError("Payment Term berbeda pada Master Data Customer") @@ -727,7 +727,7 @@ class SaleOrder(models.Model): partner = order.partner_id.parent_id or order.partner_id if not partner.property_payment_term_id: raise UserError("Payment Term pada Master Data Customer harus diisi") - if not partner.active_limit: + if not partner.active_limit and order.payment_term_id.id not in [27, 26]: raise UserError("Credit Limit pada Master Data Customer harus diisi") if order.payment_term_id != partner.property_payment_term_id: raise UserError("Payment Term berbeda pada Master Data Customer") diff --git a/indoteknik_custom/models/stock_picking.py b/indoteknik_custom/models/stock_picking.py index 6f038386..14190474 100644 --- a/indoteknik_custom/models/stock_picking.py +++ b/indoteknik_custom/models/stock_picking.py @@ -125,7 +125,9 @@ class StockPicking(models.Model): raise UserError('Hanya Logistic yang bisa mengubah shipping method') def do_unreserve(self): - if not self._context.get('darimana') == 'sale.order': + group_id = self.env.ref('indoteknik_custom.group_role_it').id + users_in_group = self.env['res.users'].search([('groups_id', 'in', [group_id])]) + if not self._context.get('darimana') == 'sale.order' and self.env.user.id not in users_in_group.mapped('id'): self.sale_id.unreserve_id = self.id return self._create_approval_notification('Logistic') -- cgit v1.2.3 From 55a7bd6000c93b19f70489e5393102854cceaa4b Mon Sep 17 00:00:00 2001 From: Azka Nathan Date: Mon, 7 Oct 2024 14:05:09 +0700 Subject: cr estimate shipping price envio --- indoteknik_custom/models/sale_order.py | 30 +++++++++++++++++++++++++++++- 1 file changed, 29 insertions(+), 1 deletion(-) (limited to 'indoteknik_custom/models') diff --git a/indoteknik_custom/models/sale_order.py b/indoteknik_custom/models/sale_order.py index 265ffb9e..2cef531e 100755 --- a/indoteknik_custom/models/sale_order.py +++ b/indoteknik_custom/models/sale_order.py @@ -140,14 +140,42 @@ class SaleOrder(models.Model): def _compute_total_weight(self): for order in self: order.total_weight = sum(line.weight for line in order.order_line) + + def action_indoteknik_estimate_shipping(self): + if not self.real_shipping_id.kota_id.is_jabodetabek: + raise UserError('Estimasi ongkir hanya bisa dilakukan di kota Jabodetabek') + + total_weight = 0 + missing_weight_products = [] + + for line in self.order_line: + if line.weight: + total_weight += line.weight * line.product_uom_qty + line.product_id.weight = line.weight + else: + missing_weight_products.append(line.product_id.name) + + if missing_weight_products: + product_names = '
'.join(missing_weight_products) + self.message_post(body=f"Produk berikut tidak memiliki berat:
{product_names}") + + if total_weight == 0: + raise UserError("Tidak dapat mengestimasi ongkir tanpa berat yang valid.") + + if total_weight < 10: + total_weight = 10 + self.delivery_amt = total_weight * 3000 def action_estimate_shipping(self): + if self.carrier_id.id in [1, 151]: + self.action_indoteknik_estimate_shipping() + return total_weight = 0 missing_weight_products = [] for line in self.order_line: if line.weight: - total_weight += line.weight + total_weight += line.weight * line.product_uom_qty line.product_id.weight = line.weight else: missing_weight_products.append(line.product_id.name) -- cgit v1.2.3 From c67ec730efe048bce9872930841765d919956e15 Mon Sep 17 00:00:00 2001 From: Azka Nathan Date: Mon, 7 Oct 2024 14:20:00 +0700 Subject: cr confirm po --- indoteknik_custom/models/purchase_order.py | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'indoteknik_custom/models') diff --git a/indoteknik_custom/models/purchase_order.py b/indoteknik_custom/models/purchase_order.py index 8a47482a..ef2fdb5b 100755 --- a/indoteknik_custom/models/purchase_order.py +++ b/indoteknik_custom/models/purchase_order.py @@ -503,6 +503,9 @@ class PurchaseOrder(models.Model): current_time = datetime.now() self.check_ppn_mix() # self.check_data_vendor() + + if self.amount_untaxed >= 10000000 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: raise UserError("Beda Margin dengan Sales, harus approval Manager") @@ -634,6 +637,8 @@ class PurchaseOrder(models.Model): template.send_mail(self.id, force_send=True) def po_approve(self): + if self.amount_untaxed >= 10000000 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: raise UserError("Bisa langsung Confirm") elif self.total_percent_margin == self.total_so_percent_margin and self.sale_order_id: -- cgit v1.2.3 From 53cb341f8184c3d74434f2b2d18d1bd984b57118 Mon Sep 17 00:00:00 2001 From: Azka Nathan Date: Tue, 8 Oct 2024 09:06:49 +0700 Subject: cr po and validasi so --- indoteknik_custom/models/purchase_order.py | 4 ++-- indoteknik_custom/models/sale_order.py | 13 +++++++++++-- 2 files changed, 13 insertions(+), 4 deletions(-) (limited to 'indoteknik_custom/models') diff --git a/indoteknik_custom/models/purchase_order.py b/indoteknik_custom/models/purchase_order.py index ef2fdb5b..08408506 100755 --- a/indoteknik_custom/models/purchase_order.py +++ b/indoteknik_custom/models/purchase_order.py @@ -504,7 +504,7 @@ class PurchaseOrder(models.Model): self.check_ppn_mix() # self.check_data_vendor() - if self.amount_untaxed >= 10000000 and not self.env.user.has_group('indoteknik_custom.group_role_merchandiser'): + 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: @@ -637,7 +637,7 @@ class PurchaseOrder(models.Model): template.send_mail(self.id, force_send=True) def po_approve(self): - if self.amount_untaxed >= 10000000 and not self.env.user.has_group('indoteknik_custom.group_role_merchandiser'): + 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: raise UserError("Bisa langsung Confirm") diff --git a/indoteknik_custom/models/sale_order.py b/indoteknik_custom/models/sale_order.py index 2cef531e..d56a7946 100755 --- a/indoteknik_custom/models/sale_order.py +++ b/indoteknik_custom/models/sale_order.py @@ -727,10 +727,14 @@ class SaleOrder(models.Model): for order in self: order.order_line.validate_line() + term_days = 0 + for term_line in order.payment_term_id.line_ids: + term_days += term_line.days + partner = order.partner_id.parent_id or order.partner_id if not partner.property_payment_term_id: raise UserError("Payment Term pada Master Data Customer harus diisi") - if not partner.active_limit and order.payment_term_id.id not in [27, 26]: + if not partner.active_limit and term_days > 0: raise UserError("Credit Limit pada Master Data Customer harus diisi") if order.payment_term_id != partner.property_payment_term_id: raise UserError("Payment Term berbeda pada Master Data Customer") @@ -752,10 +756,15 @@ class SaleOrder(models.Model): for order in self: order.order_line.validate_line() + + term_days = 0 + for term_line in order.payment_term_id.line_ids: + term_days += term_line.days + partner = order.partner_id.parent_id or order.partner_id if not partner.property_payment_term_id: raise UserError("Payment Term pada Master Data Customer harus diisi") - if not partner.active_limit and order.payment_term_id.id not in [27, 26]: + if not partner.active_limit and term_days > 0: raise UserError("Credit Limit pada Master Data Customer harus diisi") if order.payment_term_id != partner.property_payment_term_id: raise UserError("Payment Term berbeda pada Master Data Customer") -- cgit v1.2.3 From 8512e5777d0fbe84f73ec061ac2afb90e7a474e6 Mon Sep 17 00:00:00 2001 From: Azka Nathan Date: Tue, 8 Oct 2024 13:20:16 +0700 Subject: cr total weight --- indoteknik_custom/models/sale_order.py | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) (limited to 'indoteknik_custom/models') diff --git a/indoteknik_custom/models/sale_order.py b/indoteknik_custom/models/sale_order.py index d56a7946..c1c2c267 100755 --- a/indoteknik_custom/models/sale_order.py +++ b/indoteknik_custom/models/sale_order.py @@ -138,8 +138,14 @@ class SaleOrder(models.Model): total_weight = fields.Float(string='Total Weight', compute='_compute_total_weight') def _compute_total_weight(self): - for order in self: - order.total_weight = sum(line.weight for line in order.order_line) + total_weight = 0 + missing_weight_products = [] + + for line in self.order_line: + if line.weight: + total_weight += line.weight * line.product_uom_qty + + self.total_weight = total_weight def action_indoteknik_estimate_shipping(self): if not self.real_shipping_id.kota_id.is_jabodetabek: -- cgit v1.2.3 From ce1c714c95f68b07f9b891600ba1e3b88288652c Mon Sep 17 00:00:00 2001 From: Azka Nathan Date: Tue, 8 Oct 2024 15:17:53 +0700 Subject: fix bug --- indoteknik_custom/models/sale_order_line.py | 1 + 1 file changed, 1 insertion(+) (limited to 'indoteknik_custom/models') diff --git a/indoteknik_custom/models/sale_order_line.py b/indoteknik_custom/models/sale_order_line.py index 6aaa4d53..59ac1ad4 100644 --- a/indoteknik_custom/models/sale_order_line.py +++ b/indoteknik_custom/models/sale_order_line.py @@ -257,6 +257,7 @@ class SaleOrderLine(models.Model): 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 attribute_values = line.product_id.product_template_attribute_value_ids.mapped('name') -- cgit v1.2.3 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 + 1 file changed, 1 insertion(+) (limited to 'indoteknik_custom/models') 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') -- 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(-) (limited to 'indoteknik_custom/models') 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 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 ++ 1 file changed, 2 insertions(+) (limited to 'indoteknik_custom/models') 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 -- 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(-) (limited to 'indoteknik_custom/models') 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(+) (limited to 'indoteknik_custom/models') 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 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 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) (limited to 'indoteknik_custom/models') 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) -- 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(-) (limited to 'indoteknik_custom/models') 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(-) (limited to 'indoteknik_custom/models') 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(-) (limited to 'indoteknik_custom/models') 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(-) (limited to 'indoteknik_custom/models') 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(-) (limited to 'indoteknik_custom/models') 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(-) (limited to 'indoteknik_custom/models') 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 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 +++++++++++++++++++++++++++++++++++ 2 files changed, 45 insertions(+) create mode 100644 indoteknik_custom/models/find_page.py (limited to 'indoteknik_custom/models') 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) -- 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(-) (limited to 'indoteknik_custom/models') 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(-) (limited to 'indoteknik_custom/models') 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(-) (limited to 'indoteknik_custom/models') 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 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(-) (limited to 'indoteknik_custom/models') 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 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(+) (limited to 'indoteknik_custom/models') 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(-) (limited to 'indoteknik_custom/models') 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 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'indoteknik_custom/models') 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') -- 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(-) (limited to 'indoteknik_custom/models') 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 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 ++++++++++++++++++ 2 files changed, 21 insertions(+), 2 deletions(-) (limited to 'indoteknik_custom/models') 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 -- 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(-) (limited to 'indoteknik_custom/models') 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 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 +++++++ 1 file changed, 7 insertions(+) (limited to 'indoteknik_custom/models') 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): -- 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(-) (limited to 'indoteknik_custom/models') 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(-) (limited to 'indoteknik_custom/models') 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(-) (limited to 'indoteknik_custom/models') 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 ++ 1 file changed, 2 insertions(+) (limited to 'indoteknik_custom/models') 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'), -- cgit v1.2.3 From 245f5c63c40527b94cf45e20e4c8dd15f5b51e98 Mon Sep 17 00:00:00 2001 From: it-fixcomart 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(-) (limited to 'indoteknik_custom/models') 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(-) (limited to 'indoteknik_custom/models') 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 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(-) (limited to 'indoteknik_custom/models') 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 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(-) (limited to 'indoteknik_custom/models') 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(+) (limited to 'indoteknik_custom/models') 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(-) (limited to 'indoteknik_custom/models') 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 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(-) (limited to 'indoteknik_custom/models') 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 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 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) (limited to 'indoteknik_custom/models') 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) -- 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/models/find_page.py | 56 ++++++++++++++++++++++++++++------- 1 file changed, 45 insertions(+), 11 deletions(-) (limited to 'indoteknik_custom/models') 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 -- 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(+) (limited to 'indoteknik_custom/models') 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(+) (limited to 'indoteknik_custom/models') 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 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(-) (limited to 'indoteknik_custom/models') 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