From 4aa0f2612225de32d361547f39283c1529fe955b Mon Sep 17 00:00:00 2001 From: it-fixcomart Date: Wed, 28 Aug 2024 14:09:05 +0700 Subject: update address fakture --- indoteknik_custom/models/res_partner.py | 40 +++++++++++++++++++++++++++++++++ 1 file changed, 40 insertions(+) (limited to 'indoteknik_custom/models') diff --git a/indoteknik_custom/models/res_partner.py b/indoteknik_custom/models/res_partner.py index ac126337..6a1257f8 100644 --- a/indoteknik_custom/models/res_partner.py +++ b/indoteknik_custom/models/res_partner.py @@ -58,6 +58,46 @@ class ResPartner(models.Model): default=_default_payment_term ) + @api.depends("street", "street2", "city", "state_id", "country_id", "blok", "nomor", "rt", "rw", "kelurahan_id", + "kecamatan_id") + def _alamat_lengkap(self): + for partner in self: + lengkap = partner.street or "" + lengkap += " " + (partner.street2 or '') + + if partner.blok: + lengkap += " Blok: " + partner.blok + ", " + if partner.nomor: + lengkap += " Nomor: " + partner.nomor + ", " + + if partner.rt: + lengkap += " RT: " + partner.rt + if partner.rw: + lengkap += " RW: " + partner.rw + + if partner.kelurahan_id: + lengkap += " Kel: " + partner.kelurahan_id.name + "," + + if partner.kecamatan_id: + lengkap += " Kec: " + partner.kecamatan_id.name + + if partner.kota_id: + lengkap += """ + """ + partner.kota_id.name + "," + + if partner.state_id: + lengkap += " " + partner.state_id.name + + partner.alamat_lengkap = lengkap.upper() + + if partner.company_type == 'person' and not partner.parent_id: + partner.alamat_lengkap_text = partner.street + else: + partner.alamat_lengkap_text = partner.alamat_lengkap + + alamat_lengkap = fields.Char(string="Alamat Lengkap", required=False, compute="_alamat_lengkap") + alamat_lengkap_text = fields.Text(string="Alamat Lengkap", required=False) + def write(self, vals): res = super(ResPartner, self).write(vals) -- cgit v1.2.3 From cf31bebc38f23450b7c429bb4b3a567515071a40 Mon Sep 17 00:00:00 2001 From: it-fixcomart Date: Wed, 28 Aug 2024 15:30:24 +0700 Subject: update to handle user company request --- indoteknik_custom/models/user_company_request.py | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'indoteknik_custom/models') diff --git a/indoteknik_custom/models/user_company_request.py b/indoteknik_custom/models/user_company_request.py index 2467261a..7d28d7ed 100644 --- a/indoteknik_custom/models/user_company_request.py +++ b/indoteknik_custom/models/user_company_request.py @@ -22,6 +22,11 @@ class UserCompanyRequest(models.Model): if not self.is_approve and is_approve: if is_approve == 'approved': self.user_id.parent_id = self.user_company_id.id + self.user_id.customer_type = self.user_company_id.customer_type + self.user_id.npwp = self.user_company_id.npwp + self.user_id.sppkp = self.user_company_id.sppkp + self.user_id.nama_wajib_pajak = self.user_company_id.nama_wajib_pajak + self.user_id.alamat_lengkap_text = self.user_company_id.alamat_lengkap_text else: new_company = self.env['res.partner'].create({ 'name': self.user_input -- cgit v1.2.3 From edafc890045d833289ad3b53ce3375625f18e54c Mon Sep 17 00:00:00 2001 From: it-fixcomart Date: Fri, 30 Aug 2024 14:59:50 +0700 Subject: update jika sppkp diganti di order, parent sppkp juga terganti --- indoteknik_custom/models/sale_order.py | 35 ++++++++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) (limited to 'indoteknik_custom/models') diff --git a/indoteknik_custom/models/sale_order.py b/indoteknik_custom/models/sale_order.py index 710e99de..16a1f415 100755 --- a/indoteknik_custom/models/sale_order.py +++ b/indoteknik_custom/models/sale_order.py @@ -942,3 +942,38 @@ class SaleOrder(models.Model): order_line.tax_id = tax_id order_line.discount = discount order_line.order_id.use_button = True + + @api.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() + return order + + def write(self, vals): + # Call the super method to handle the write operation + 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() + + return res + + def _update_partner_details(self): + for order in self: + partner = order.partner_id.parent_id or order.partner_id + if partner: + # Update partner details + partner.sppkp = order.sppkp + partner.npwp = order.npwp + partner.email = order.email + partner.customer_type = order.customer_type + + # Save changes to the partner record + partner.write({ + 'sppkp': partner.sppkp, + 'npwp': partner.npwp, + 'email': partner.email, + 'customer_type': partner.customer_type, + }) \ No newline at end of file -- cgit v1.2.3 From 0801de741384b29a01f5570f420da10953834e22 Mon Sep 17 00:00:00 2001 From: it-fixcomart Date: Fri, 30 Aug 2024 16:13:46 +0700 Subject: update automatic data new register --- indoteknik_custom/models/user_company_request.py | 3 +++ 1 file changed, 3 insertions(+) (limited to 'indoteknik_custom/models') diff --git a/indoteknik_custom/models/user_company_request.py b/indoteknik_custom/models/user_company_request.py index 7d28d7ed..69067e9c 100644 --- a/indoteknik_custom/models/user_company_request.py +++ b/indoteknik_custom/models/user_company_request.py @@ -27,6 +27,9 @@ class UserCompanyRequest(models.Model): self.user_id.sppkp = self.user_company_id.sppkp self.user_id.nama_wajib_pajak = self.user_company_id.nama_wajib_pajak self.user_id.alamat_lengkap_text = self.user_company_id.alamat_lengkap_text + self.user_id.user_id = self.user_company_id.user_id + self.user_id.property_account_receivable_id = self.user_company_id.property_account_receivable_id + self.user_id.property_account_payable_id = self.user_company_id.property_account_payable_id else: new_company = self.env['res.partner'].create({ 'name': self.user_input -- cgit v1.2.3 From 9ee856d603530e8cc3494a2bccb8fdfaa328da6a Mon Sep 17 00:00:00 2001 From: Azka Nathan Date: Tue, 3 Sep 2024 14:14:09 +0700 Subject: push --- indoteknik_custom/models/sale_order.py | 9 +++++++++ indoteknik_custom/models/stock_picking.py | 19 +++++++++++++++++-- 2 files changed, 26 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 710e99de..2769d408 100755 --- a/indoteknik_custom/models/sale_order.py +++ b/indoteknik_custom/models/sale_order.py @@ -109,6 +109,15 @@ class SaleOrder(models.Model): date_driver_departure = fields.Datetime(string='Departure Date', compute='_compute_date_kirim', copy=False) note_website = fields.Char(string="Note Website") use_button = fields.Boolean(string='Using Calculate Selling Price', copy=False) + unreserve_id = fields.Many2one('stock.picking', 'Unreserve Picking') + + def do_unreserve(self): + user_id = self.env.user.id + if user_id != self.user_id.id: + raise UserError(_("Only the user who created the picking can unreserve it.")) + + self.unreserve_id.do_unreserve() + def _compute_date_kirim(self): for rec in self: diff --git a/indoteknik_custom/models/stock_picking.py b/indoteknik_custom/models/stock_picking.py index d16d508e..474c7526 100644 --- a/indoteknik_custom/models/stock_picking.py +++ b/indoteknik_custom/models/stock_picking.py @@ -125,12 +125,27 @@ class StockPicking(models.Model): raise UserError('Hanya Logistic yang bisa mengubah shipping method') def do_unreserve(self): + if self.sale_id.unreserve_id.id != self.id: + self.sale_id.unreserve_id = self.id + return self._create_approval_notification('Logistic') + res = super(StockPicking, self).do_unreserve() - if not self.env.user.is_purchasing_manager: - raise UserError('Hanya Purchasing Manager yang bisa Unreserve') current_time = datetime.datetime.utcnow() self.date_unreserve = current_time + return res + + def _create_approval_notification(self, approval_role): + title = 'Warning' + message = f'Butuh approval sales untuk unreserved' + return self._create_notification_action(title, message) + + def _create_notification_action(self, title, message): + return { + 'type': 'ir.actions.client', + 'tag': 'display_notification', + 'params': { 'title': title, 'message': message, 'next': {'type': 'ir.actions.act_window_close'} }, + } def _compute_shipping_status(self): for rec in self: -- cgit v1.2.3 From eced81efba75d710d164f1baa2d2e50b4d2d3c18 Mon Sep 17 00:00:00 2001 From: Azka Nathan Date: Tue, 3 Sep 2024 14:14:40 +0700 Subject: fix bug --- indoteknik_custom/models/sale_order.py | 1 + 1 file changed, 1 insertion(+) (limited to 'indoteknik_custom/models') diff --git a/indoteknik_custom/models/sale_order.py b/indoteknik_custom/models/sale_order.py index 710e99de..348ea4d3 100755 --- a/indoteknik_custom/models/sale_order.py +++ b/indoteknik_custom/models/sale_order.py @@ -109,6 +109,7 @@ class SaleOrder(models.Model): date_driver_departure = fields.Datetime(string='Departure Date', compute='_compute_date_kirim', copy=False) note_website = fields.Char(string="Note Website") use_button = fields.Boolean(string='Using Calculate Selling Price', copy=False) + voucher_shipping_id = fields.Many2one(comodel_name='voucher', string='Voucher', copy=False) def _compute_date_kirim(self): for rec in self: -- cgit v1.2.3 From 8edde46e16d4d977e84a3681c03d1bfab8591a71 Mon Sep 17 00:00:00 2001 From: Azka Nathan Date: Tue, 3 Sep 2024 15:20:06 +0700 Subject: cr unreserved --- indoteknik_custom/models/sale_order.py | 3 +-- indoteknik_custom/models/stock_picking.py | 2 +- 2 files changed, 2 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 2769d408..d389f6ae 100755 --- a/indoteknik_custom/models/sale_order.py +++ b/indoteknik_custom/models/sale_order.py @@ -116,9 +116,8 @@ class SaleOrder(models.Model): if user_id != self.user_id.id: raise UserError(_("Only the user who created the picking can unreserve it.")) - self.unreserve_id.do_unreserve() + self.unreserve_id.with_context({'darimana': 'sale.order'}).do_unreserve() - def _compute_date_kirim(self): for rec in self: picking = self.env['stock.picking'].search([('sale_id', '=', rec.id), ('state', 'not in', ['cancel'])], order='date_doc_kirim desc', limit=1) diff --git a/indoteknik_custom/models/stock_picking.py b/indoteknik_custom/models/stock_picking.py index 474c7526..de45af2e 100644 --- a/indoteknik_custom/models/stock_picking.py +++ b/indoteknik_custom/models/stock_picking.py @@ -125,7 +125,7 @@ class StockPicking(models.Model): raise UserError('Hanya Logistic yang bisa mengubah shipping method') def do_unreserve(self): - if self.sale_id.unreserve_id.id != self.id: + if not self._context.get('darimana') == 'sale.order': self.sale_id.unreserve_id = self.id return self._create_approval_notification('Logistic') -- cgit v1.2.3 From 1da66aee1b99ce8fc10b7a4f1c2437dfce7c9ee4 Mon Sep 17 00:00:00 2001 From: Azka Nathan Date: Tue, 3 Sep 2024 15:41:30 +0700 Subject: cr register --- indoteknik_custom/models/user_company_request.py | 1 + 1 file changed, 1 insertion(+) (limited to 'indoteknik_custom/models') diff --git a/indoteknik_custom/models/user_company_request.py b/indoteknik_custom/models/user_company_request.py index 69067e9c..d6134650 100644 --- a/indoteknik_custom/models/user_company_request.py +++ b/indoteknik_custom/models/user_company_request.py @@ -30,6 +30,7 @@ class UserCompanyRequest(models.Model): self.user_id.user_id = self.user_company_id.user_id self.user_id.property_account_receivable_id = self.user_company_id.property_account_receivable_id self.user_id.property_account_payable_id = self.user_company_id.property_account_payable_id + self.user_company_id.active = True else: new_company = self.env['res.partner'].create({ 'name': self.user_input -- cgit v1.2.3 From ca5c12f1ee40ea3c34cafcc9fe73d3d79a6a5b98 Mon Sep 17 00:00:00 2001 From: stephanchrst Date: Wed, 4 Sep 2024 15:53:40 +0700 Subject: fix margin with fee third party --- 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 348ea4d3..81c3f5ed 100755 --- a/indoteknik_custom/models/sale_order.py +++ b/indoteknik_custom/models/sale_order.py @@ -744,7 +744,7 @@ class SaleOrder(models.Model): delivery_amt = order.delivery_amt else: delivery_amt = 0 - order.total_percent_margin = round((order.total_margin / (order.amount_untaxed-delivery_amt)) * 100, 2) + order.total_percent_margin = round((order.total_margin / (order.amount_untaxed-delivery_amt-order.fee_third_party)) * 100, 2) # order.total_percent_margin = round((order.total_margin / (order.amount_untaxed)) * 100, 2) @api.onchange('sales_tax_id') -- cgit v1.2.3 From 1bb074bb8f63072fb990c57c18986c50981f1402 Mon Sep 17 00:00:00 2001 From: Azka Nathan Date: Wed, 4 Sep 2024 17:12:38 +0700 Subject: fix voucher shipping --- indoteknik_custom/models/sale_order.py | 54 ++++++++++++++++++++++++++- indoteknik_custom/models/website_user_cart.py | 3 +- 2 files changed, 54 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 348ea4d3..0268f27b 100755 --- a/indoteknik_custom/models/sale_order.py +++ b/indoteknik_custom/models/sale_order.py @@ -88,6 +88,8 @@ class SaleOrder(models.Model): voucher_id = fields.Many2one(comodel_name='voucher', string='Voucher', copy=False) applied_voucher_id = fields.Many2one(comodel_name='voucher', string='Applied Voucher', copy=False) amount_voucher_disc = fields.Float(string='Voucher Discount') + applied_voucher_shipping_id = fields.Many2one(comodel_name='voucher', string='Applied Voucher', copy=False) + amount_voucher_shipping_disc = fields.Float(string='Voucher Discount') source_id = fields.Many2one('utm.source', 'Source', domain="[('id', 'in', [32, 59, 60, 61])]", required=True) estimated_arrival_days = fields.Integer('Estimated Arrival Days', default=0) email = fields.Char(string='Email') @@ -109,7 +111,7 @@ class SaleOrder(models.Model): date_driver_departure = fields.Datetime(string='Departure Date', compute='_compute_date_kirim', copy=False) note_website = fields.Char(string="Note Website") use_button = fields.Boolean(string='Using Calculate Selling Price', copy=False) - voucher_shipping_id = fields.Many2one(comodel_name='voucher', string='Voucher', copy=False) + voucher_shipping_id = fields.Many2one(comodel_name='voucher', string='Voucher Shipping', copy=False) def _compute_date_kirim(self): for rec in self: @@ -781,6 +783,28 @@ class SaleOrder(models.Model): self.apply_voucher() + def action_apply_voucher_shipping(self): + for line in self.order_line: + if line.order_promotion_id: + raise UserError('Voucher tidak dapat digabung dengan promotion program') + + voucher = self.voucher_shipping_id + if voucher.limit > 0 and voucher.count_order >= voucher.limit: + raise UserError('Voucher tidak dapat digunakan karena sudah habis digunakan') + + partner_voucher_orders = [] + for order in voucher.order_ids: + if order.partner_id.id == self.partner_id.id: + partner_voucher_orders.append(order) + + if voucher.limit_user > 0 and len(partner_voucher_orders) >= voucher.limit_user: + raise UserError('Voucher tidak dapat digunakan karena Customer ini sudah menghabiskan kuota voucher') + + if self.pricelist_id.id in [x.id for x in voucher.excl_pricelist_ids]: + raise UserError('Voucher tidak dapat digunakan karena pricelist ini tidak berlaku pada voucher') + + self.apply_voucher_shipping() + def apply_voucher(self): order_line = [] for line in self.order_line: @@ -822,6 +846,29 @@ class SaleOrder(models.Model): self.amount_voucher_disc = voucher['discount']['all'] self.applied_voucher_id = self.voucher_id + def apply_voucher_shipping(self): + for order in self: + delivery_amt = order.delivery_amt + voucher = order.voucher_shipping_id + + if voucher: + max_discount_amount = voucher.discount_amount + voucher_type = voucher.discount_type + + if voucher_type == 'fixed_price': + discount = max_discount_amount + elif voucher_type == 'percentage': + discount = delivery_amt * (max_discount_amount / 100) + + delivery_amt -= discount + + delivery_amt = max(delivery_amt, 0) + + order.delivery_amt = delivery_amt + + order.amount_voucher_shipping_disc = discount + order.applied_voucher_shipping_id = order.voucher_id.id + def cancel_voucher(self): self.applied_voucher_id = False self.amount_voucher_disc = 0 @@ -830,6 +877,11 @@ class SaleOrder(models.Model): line.discount = line.initial_discount line.initial_discount = False + def cancel_voucher_shipping(self): + self.delivery_amt + self.amount_voucher_shipping_disc + self.applied_voucher_shipping_id = False + self.amount_voucher_shipping_disc = 0 + def action_web_approve(self): if self.env.uid != self.partner_id.user_id.id: raise UserError('You are not authorized to approve this order. Only %s can approve this order.' % self.partner_id.user_id.name) diff --git a/indoteknik_custom/models/website_user_cart.py b/indoteknik_custom/models/website_user_cart.py index 0af22d47..b0cf47f7 100644 --- a/indoteknik_custom/models/website_user_cart.py +++ b/indoteknik_custom/models/website_user_cart.py @@ -130,8 +130,7 @@ class WebsiteUserCart(models.Model): if voucher_shipping: voucher_shipping_info = voucher_shipping.apply(order_line) - discount_voucher_shipping = voucher_shipping_info['discount']['all'] - subtotal -= discount_voucher_shipping + discount_voucher_shipping = voucher_shipping_info['discount']['all'] tax = round(subtotal * 0.11) grand_total = subtotal + tax -- cgit v1.2.3 From 4643df754b03eb3f8ae9567bc5b5327934b6cc83 Mon Sep 17 00:00:00 2001 From: it-fixcomart Date: Wed, 4 Sep 2024 17:15:20 +0700 Subject: update new register --- indoteknik_custom/models/res_partner.py | 46 ++++++++++++++++++++++++++------- 1 file changed, 36 insertions(+), 10 deletions(-) (limited to 'indoteknik_custom/models') diff --git a/indoteknik_custom/models/res_partner.py b/indoteknik_custom/models/res_partner.py index 6a1257f8..9f2c82e2 100644 --- a/indoteknik_custom/models/res_partner.py +++ b/indoteknik_custom/models/res_partner.py @@ -98,20 +98,46 @@ class ResPartner(models.Model): alamat_lengkap = fields.Char(string="Alamat Lengkap", required=False, compute="_alamat_lengkap") alamat_lengkap_text = fields.Text(string="Alamat Lengkap", required=False) - def write(self, vals): - res = super(ResPartner, self).write(vals) - - # if 'property_payment_term_id' in vals: - # if not self.env.user.is_accounting and vals['property_payment_term_id'] != 26: - # raise UserError('Hanya Finance Accounting yang dapat merubah payment term') + # def write(self, vals): + # res = super(ResPartner, self).write(vals) + # + # # if 'property_payment_term_id' in vals: + # # if not self.env.user.is_accounting and vals['property_payment_term_id'] != 26: + # # raise UserError('Hanya Finance Accounting yang dapat merubah payment term') + # + # # group_id = self.env.ref('indoteknik_custom.group_role_merchandiser').id + # # users_in_group = self.env['res.users'].search([('groups_id', 'in', [group_id])]) + # # if self.env.user.id not in users_in_group.mapped('id'): + # # raise UserError('You name it') + # + # return res - # group_id = self.env.ref('indoteknik_custom.group_role_merchandiser').id - # users_in_group = self.env['res.users'].search([('groups_id', 'in', [group_id])]) - # if self.env.user.id not in users_in_group.mapped('id'): - # raise UserError('You name it') + def write(self, vals): + if self.company_type == 'person': + if self.parent_id: + parent = self.parent_id + vals['customer_type'] = parent.customer_type + vals['nama_wajib_pajak'] = parent.nama_wajib_pajak + vals['npwp'] = parent.npwp + vals['sppkp'] = parent.sppkp + vals['alamat_lengkap_text'] = parent.alamat_lengkap_text + vals['industry_id'] = parent.industry_id.id + vals['company_type_id'] = parent.company_type_id.id + res = super(ResPartner, self).write(vals) return res + @api.onchange('company_type') + def _onchange_company_type(self): + if self.company_type == 'person' and self.parent_id: + self.customer_type = self.parent_id.customer_type + self.npwp = self.parent_id.npwp + self.sppkp = self.parent_id.sppkp + self.nama_wajib_pajak = self.parent_id.nama_wajib_pajak + self.alamat_lengkap_text = self.parent_id.alamat_lengkap_text + self.industry_id = self.parent_id.industry_id.id + self.company_type_id = self.parent_id.company_type_id.id + @api.constrains('property_payment_term_id') def updated_by_payment_term(self): for rec in self: -- cgit v1.2.3 From 013a3e4d73327c138ede6f224b32969dc8f85c1f Mon Sep 17 00:00:00 2001 From: Azka Nathan Date: Wed, 4 Sep 2024 17:18:02 +0700 Subject: solr category management --- indoteknik_custom/models/solr/__init__.py | 3 +- .../models/solr/website_categories_management.py | 108 +++++++++++++++++++++ 2 files changed, 110 insertions(+), 1 deletion(-) create mode 100644 indoteknik_custom/models/solr/website_categories_management.py (limited to 'indoteknik_custom/models') diff --git a/indoteknik_custom/models/solr/__init__.py b/indoteknik_custom/models/solr/__init__.py index 606c0035..dafd5a1e 100644 --- a/indoteknik_custom/models/solr/__init__.py +++ b/indoteknik_custom/models/solr/__init__.py @@ -10,4 +10,5 @@ from . import x_banner_banner from . import product_public_category from . import x_banner_category from . import promotion_program -from . import promotion_program_line \ No newline at end of file +from . import promotion_program_line +from . import website_categories_management \ No newline at end of file diff --git a/indoteknik_custom/models/solr/website_categories_management.py b/indoteknik_custom/models/solr/website_categories_management.py new file mode 100644 index 00000000..c3851f4b --- /dev/null +++ b/indoteknik_custom/models/solr/website_categories_management.py @@ -0,0 +1,108 @@ +from odoo import models, fields, api +from datetime import datetime +import json + + +class WebsiteCategoriesHomepage(models.Model): + _inherit = 'website.categories.management' + + last_update_solr = fields.Datetime('Last Update Solr') + + def solr(self): + return self.env['apache.solr'].connect('category_management') + + def update_last_update_solr(self): + self.last_update_solr = datetime.utcnow() + + def _create_solr_queue(self, function_name): + for rec in self: + self.env['apache.solr.queue'].create_unique({ + 'res_model': self._name, + 'res_id': rec.id, + 'function_name': function_name + }) + + @api.constrains('status') + def _create_solr_queue_sync_status(self): + self._create_solr_queue('_sync_status_category_homepage_solr') + + @api.constrains('category_id', 'category_id2', 'sequence') + def _create_solr_queue_sync_category_homepage(self): + self._create_solr_queue('_sync_category_management_to_solr') + + def action_sync_to_solr(self): + category_ids = self.env.context.get('active_ids', []) + categories = self.search([('id', 'in', category_ids)]) + categories._create_solr_queue('_sync_category_management_to_solr') + + def unlink(self): + res = super(WebsiteCategoriesHomepage, self).unlink() + for rec in self: + self.solr().delete(rec.id) + self.solr().optimize() + self.solr().commit() + return res + + def _sync_status_category_homepage_solr(self): + for rec in self: + if rec.status == 'tayang': + rec._sync_category_management_to_solr() + else: + rec.unlink() + + def _sync_category_management_to_solr(self): + solr_model = self.env['apache.solr'] + + for category in self: + if category.status != 'tayang': + continue + + # Level 1 Document + document = solr_model.get_doc('category_management', category.id) + document.update({ + 'id': category.id, + 'category_id_i': category.category_id.id, + 'name_s': category.category_id.name, + 'image_s': self.env['ir.attachment'].api_image('product.public.category', 'image_1920', category.category_id.id), + 'sequence_i': category.sequence or '', + 'numFound_i': len(category.category_id.product_tmpl_ids.ids), + }) + + # Level 2 and Level 3 Documents + level_2_docs = [] + for x in category.category_id2: + level_2_doc = { + 'id_level_2': x.id, + 'name_level_2': x.name, + 'numFound_level_2': len(x.product_tmpl_ids.ids), + 'image_level_2': self.env['ir.attachment'].api_image('product.public.category', 'image_1920', x.id), + 'categories_level_3': [] + } + + # Level 3 Data + for child in x.child_frontend_id2: + level_3_doc = { + 'id_level_3': child.id, + 'name_level_3': child.name, + 'numFound_level_3': len(child.product_tmpl_ids.ids), + 'image_level_3': self.env['ir.attachment'].api_image('product.public.category', 'image_1920', child.id), + } + level_2_doc['categories_level_3'].append(level_3_doc) + + level_2_docs.append(level_2_doc) + + # Add level 2 documents to level 1 document + document['categories_level_2'] = level_2_docs + + # Add document to Solr + self.solr().add([document]) + category.update_last_update_solr() + + self.solr().commit() + + + # def _sync_delete_solr(self): + # for rec in self: + # self.solr().delete(rec.id) + # self.solr().optimize() + # self.solr().commit() \ No newline at end of file -- cgit v1.2.3 From 95d7027481595aa83d75570044391e68c11e9ce1 Mon Sep 17 00:00:00 2001 From: it-fixcomart Date: Thu, 5 Sep 2024 09:41:47 +0700 Subject: update new register --- indoteknik_custom/models/res_partner.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'indoteknik_custom/models') diff --git a/indoteknik_custom/models/res_partner.py b/indoteknik_custom/models/res_partner.py index 9f2c82e2..3cc1b1aa 100644 --- a/indoteknik_custom/models/res_partner.py +++ b/indoteknik_custom/models/res_partner.py @@ -92,8 +92,8 @@ class ResPartner(models.Model): if partner.company_type == 'person' and not partner.parent_id: partner.alamat_lengkap_text = partner.street - else: - partner.alamat_lengkap_text = partner.alamat_lengkap + if partner.company_type == 'person' and partner.parent_id: + partner.alamat_lengkap_text = partner.parent_id.alamat_lengkap_text alamat_lengkap = fields.Char(string="Alamat Lengkap", required=False, compute="_alamat_lengkap") alamat_lengkap_text = fields.Text(string="Alamat Lengkap", required=False) -- cgit v1.2.3 From 4252e1b1b58499443a29c4a9fcf7d8ea8c2d2d31 Mon Sep 17 00:00:00 2001 From: it-fixcomart Date: Thu, 5 Sep 2024 16:43:11 +0700 Subject: update category management slinder --- indoteknik_custom/models/__init__.py | 1 + .../models/website_categories_management.py | 36 +++++++++++++--------- .../models/website_categories_management_line.py | 22 +++++++++++++ 3 files changed, 44 insertions(+), 15 deletions(-) create mode 100644 indoteknik_custom/models/website_categories_management_line.py (limited to 'indoteknik_custom/models') diff --git a/indoteknik_custom/models/__init__.py b/indoteknik_custom/models/__init__.py index e9ce587c..ad7b1d09 100755 --- a/indoteknik_custom/models/__init__.py +++ b/indoteknik_custom/models/__init__.py @@ -39,6 +39,7 @@ from . import website_brand_homepage from . import website_categories_homepage from . import website_categories_lob from . import website_categories_management +from . import website_categories_management_line from . import website_content from . import website_page_content from . import website_user_cart diff --git a/indoteknik_custom/models/website_categories_management.py b/indoteknik_custom/models/website_categories_management.py index 208b07a2..e430ef5f 100644 --- a/indoteknik_custom/models/website_categories_management.py +++ b/indoteknik_custom/models/website_categories_management.py @@ -6,8 +6,8 @@ class WebsiteCategoriesManagement(models.Model): _rec_name = 'category_id' category_id = fields.Many2one('product.public.category', string='Category Level 1', help='table ecommerce category', domain=lambda self: self._get_default_category_domain()) - category_id2 = fields.Many2many(comodel_name='product.public.category', relation='website_categories_category_id2_rel',column1='website_categories_homepage_id', column2='product_public_category_id', string='Category Level 2', copy=False) sequence = fields.Integer(string='Sequence') + line_ids = fields.One2many('website.categories.management.line', 'management_id', string='Category Level 2 Lines', auto_join=True) status = fields.Selection([ ('tayang', 'Tayang'), ('tidak_tayang', 'Tidak Tayang') @@ -17,11 +17,11 @@ class WebsiteCategoriesManagement(models.Model): def _onchange_category_id(self): domain = {} if self.category_id != self._origin.category_id: # Check if the category_id has changed - self.category_id2 = [(5, 0, 0)] # Clear the category_id2 field if category_id has changed + self.line_ids = [(5, 0, 0)] # Clear the lines if category_id has changed if self.category_id: - domain['category_id2'] = [('parent_frontend_id', '=', self.category_id.id)] + domain['line_ids'] = [('parent_frontend_id', '=', self.category_id.id)] else: - domain['category_id2'] = [] + domain['line_ids'] = [] return {'domain': domain} @@ -42,24 +42,30 @@ class WebsiteCategoriesManagement(models.Model): def _check_category_consistency(self): for record in self: - category_ids = record.category_id2.ids - for category in record.category_id2: - for child_category in category.child_frontend_id2: - if child_category.parent_frontend_id.id not in category_ids: + category_level2_ids = record.line_ids.mapped('category_id2.id') # Get all Category Level 2 IDs + for line in record.line_ids: + for category_level3 in line.category_id3_ids: # Loop through selected Category Level 3 + if category_level3.parent_frontend_id.id not in category_level2_ids: raise ValidationError( - f"Category Level 3 {child_category.name} bukan bagian dari category Level 2 {category.name}") + f"Category Level 3 '{category_level3.name}' bukan bagian dari Category Level 2 '{line.category_id2.name}'") def unlink(self): - for record in self.category_id2: - if record.id: + for record in self.line_ids: + if record.category_id2: related_categories = self.env['product.public.category'].search([ - ('id', 'in', record.ids) + ('id', '=', record.category_id2.id) ]) for category in related_categories: - for category3 in record.child_frontend_id2.ids: - if category3 in category.child_frontend_id2.ids: + # Iterate through the Category Level 3 related to the current Category Level 2 + for category3 in record.category_id3_ids: + # If Category Level 3 is linked to Category Level 2, remove the link + if category3.id in category.child_frontend_id2.ids: category.write({ - 'child_frontend_id2': [(3, category3)] + 'child_frontend_id2': [(3, category3.id)] + # Remove the link between Category Level 2 and Category Level 3 }) + return super(WebsiteCategoriesManagement, self).unlink() + + diff --git a/indoteknik_custom/models/website_categories_management_line.py b/indoteknik_custom/models/website_categories_management_line.py new file mode 100644 index 00000000..2f97ddfa --- /dev/null +++ b/indoteknik_custom/models/website_categories_management_line.py @@ -0,0 +1,22 @@ +from odoo import fields, models, api +from odoo.exceptions import ValidationError + +class WebsiteCategoriesManagementLine(models.Model): + _name = 'website.categories.management.line' + _order = 'sequence' + + sequence = fields.Integer(string='Sequence') + management_id = fields.Many2one('website.categories.management', string='Management Reference', required=True, ondelete='cascade') + category_id2 = fields.Many2one('product.public.category', string='Category Level 2', required=True,) + category_id3_ids = fields.Many2many('product.public.category', string='Category Level 3') + + @api.onchange('category_id2') + def _onchange_category_id2(self): + """ Update domain for category_id3_ids based on category_id2 """ + if self.category_id2: + domain_category_id3_ids = [('parent_frontend_id', '=', self.category_id2.id)] + else: + domain_category_id3_ids = [] + + return {'domain': {'category_id3_ids': domain_category_id3_ids}} + -- cgit v1.2.3 From 1b55d65464b9789164ba45bdef03c56428e026f2 Mon Sep 17 00:00:00 2001 From: it-fixcomart Date: Thu, 5 Sep 2024 17:49:30 +0700 Subject: update category management --- .../models/solr/website_categories_management.py | 54 +++++++++++----------- 1 file changed, 28 insertions(+), 26 deletions(-) (limited to 'indoteknik_custom/models') diff --git a/indoteknik_custom/models/solr/website_categories_management.py b/indoteknik_custom/models/solr/website_categories_management.py index c3851f4b..fe85f8e7 100644 --- a/indoteknik_custom/models/solr/website_categories_management.py +++ b/indoteknik_custom/models/solr/website_categories_management.py @@ -2,19 +2,21 @@ from odoo import models, fields, api from datetime import datetime import json - class WebsiteCategoriesHomepage(models.Model): _inherit = 'website.categories.management' last_update_solr = fields.Datetime('Last Update Solr') def solr(self): + """Returns the Solr connection object.""" return self.env['apache.solr'].connect('category_management') def update_last_update_solr(self): + """Updates the last sync time for the record.""" self.last_update_solr = datetime.utcnow() def _create_solr_queue(self, function_name): + """Creates unique Solr queue for each record.""" for rec in self: self.env['apache.solr.queue'].create_unique({ 'res_model': self._name, @@ -24,26 +26,30 @@ class WebsiteCategoriesHomepage(models.Model): @api.constrains('status') def _create_solr_queue_sync_status(self): + """Triggers Solr sync when the status changes.""" self._create_solr_queue('_sync_status_category_homepage_solr') @api.constrains('category_id', 'category_id2', 'sequence') def _create_solr_queue_sync_category_homepage(self): + """Triggers Solr sync when categories or sequence change.""" self._create_solr_queue('_sync_category_management_to_solr') def action_sync_to_solr(self): + """Manual action to sync selected categories to Solr.""" category_ids = self.env.context.get('active_ids', []) categories = self.search([('id', 'in', category_ids)]) categories._create_solr_queue('_sync_category_management_to_solr') def unlink(self): - res = super(WebsiteCategoriesHomepage, self).unlink() + """Overrides unlink method to remove records from Solr.""" for rec in self: self.solr().delete(rec.id) self.solr().optimize() self.solr().commit() - return res + return super(WebsiteCategoriesHomepage, self).unlink() def _sync_status_category_homepage_solr(self): + """Syncs status to Solr or deletes if not active.""" for rec in self: if rec.status == 'tayang': rec._sync_category_management_to_solr() @@ -51,13 +57,14 @@ class WebsiteCategoriesHomepage(models.Model): rec.unlink() def _sync_category_management_to_solr(self): + """Syncs categories (Level 1, 2, and 3) to Solr.""" solr_model = self.env['apache.solr'] for category in self: if category.status != 'tayang': continue - # Level 1 Document + # Prepare Level 1 document document = solr_model.get_doc('category_management', category.id) document.update({ 'id': category.id, @@ -65,44 +72,39 @@ class WebsiteCategoriesHomepage(models.Model): 'name_s': category.category_id.name, 'image_s': self.env['ir.attachment'].api_image('product.public.category', 'image_1920', category.category_id.id), 'sequence_i': category.sequence or '', - 'numFound_i': len(category.category_id.product_tmpl_ids.ids), + 'numFound_i': len(category.category_id.product_tmpl_ids), }) - # Level 2 and Level 3 Documents + # Prepare Level 2 documents level_2_docs = [] - for x in category.category_id2: + for category_level_2 in category.line_ids.mapped('category_id2'): level_2_doc = { - 'id_level_2': x.id, - 'name_level_2': x.name, - 'numFound_level_2': len(x.product_tmpl_ids.ids), - 'image_level_2': self.env['ir.attachment'].api_image('product.public.category', 'image_1920', x.id), + 'id_level_2': category_level_2.id, + 'name_level_2': category_level_2.name, + 'numFound_level_2': len(category_level_2.product_tmpl_ids), + 'image_level_2': self.env['ir.attachment'].api_image('product.public.category', 'image_1920', category_level_2.id), 'categories_level_3': [] } - # Level 3 Data - for child in x.child_frontend_id2: + # Prepare Level 3 documents + for category_level_3 in category_level_2.child_frontend_id2: level_3_doc = { - 'id_level_3': child.id, - 'name_level_3': child.name, - 'numFound_level_3': len(child.product_tmpl_ids.ids), - 'image_level_3': self.env['ir.attachment'].api_image('product.public.category', 'image_1920', child.id), + 'id_level_3': category_level_3.id, + 'name_level_3': category_level_3.name, + 'numFound_level_3': len(category_level_3.product_tmpl_ids), + 'image_level_3': self.env['ir.attachment'].api_image('product.public.category', 'image_1920', category_level_3.id), } level_2_doc['categories_level_3'].append(level_3_doc) level_2_docs.append(level_2_doc) - # Add level 2 documents to level 1 document + # Add Level 2 documents to Level 1 document document['categories_level_2'] = level_2_docs - # Add document to Solr + # Sync document with Solr self.solr().add([document]) category.update_last_update_solr() + # Commit and optimize Solr changes self.solr().commit() - - - # def _sync_delete_solr(self): - # for rec in self: - # self.solr().delete(rec.id) - # self.solr().optimize() - # self.solr().commit() \ No newline at end of file + self.solr().optimize() -- cgit v1.2.3 From 94be2756aa2ab4c5a403877e9085eab344468f1a Mon Sep 17 00:00:00 2001 From: it-fixcomart Date: Fri, 6 Sep 2024 09:31:28 +0700 Subject: update category management --- .../models/solr/website_categories_management.py | 44 ++++++++++++---------- .../models/website_categories_management.py | 4 ++ 2 files changed, 28 insertions(+), 20 deletions(-) (limited to 'indoteknik_custom/models') diff --git a/indoteknik_custom/models/solr/website_categories_management.py b/indoteknik_custom/models/solr/website_categories_management.py index fe85f8e7..1f4caac3 100644 --- a/indoteknik_custom/models/solr/website_categories_management.py +++ b/indoteknik_custom/models/solr/website_categories_management.py @@ -65,41 +65,44 @@ class WebsiteCategoriesHomepage(models.Model): continue # Prepare Level 1 document - document = solr_model.get_doc('category_management', category.id) - document.update({ + document = { 'id': category.id, + 'sequence': category.sequence or '', 'category_id_i': category.category_id.id, - 'name_s': category.category_id.name, - 'image_s': self.env['ir.attachment'].api_image('product.public.category', 'image_1920', category.category_id.id), - 'sequence_i': category.sequence or '', - 'numFound_i': len(category.category_id.product_tmpl_ids), - }) + 'name': category.category_id.name, + 'numFound': len(category.category_id.product_tmpl_ids), + 'image': self.env['ir.attachment'].api_image( + 'product.public.category', 'image_1920', category.category_id.id + ), + 'categories': [] + } # Prepare Level 2 documents - level_2_docs = [] for category_level_2 in category.line_ids.mapped('category_id2'): level_2_doc = { 'id_level_2': category_level_2.id, - 'name_level_2': category_level_2.name, - 'numFound_level_2': len(category_level_2.product_tmpl_ids), - 'image_level_2': self.env['ir.attachment'].api_image('product.public.category', 'image_1920', category_level_2.id), - 'categories_level_3': [] + 'name': category_level_2.name, + 'numFound': len(category_level_2.product_tmpl_ids), + 'image': self.env['ir.attachment'].api_image( + 'product.public.category', 'image_1920', category_level_2.id + ), + 'child_frontend_id_i': [] } # Prepare Level 3 documents for category_level_3 in category_level_2.child_frontend_id2: level_3_doc = { 'id_level_3': category_level_3.id, - 'name_level_3': category_level_3.name, - 'numFound_level_3': len(category_level_3.product_tmpl_ids), - 'image_level_3': self.env['ir.attachment'].api_image('product.public.category', 'image_1920', category_level_3.id), + 'name': category_level_3.name, + 'numFound': len(category_level_3.product_tmpl_ids), + 'image': self.env['ir.attachment'].api_image( + 'product.public.category', 'image_1920', category_level_3.id + ), } - level_2_doc['categories_level_3'].append(level_3_doc) - - level_2_docs.append(level_2_doc) + level_2_doc['child_frontend_id_i'].append(level_3_doc) - # Add Level 2 documents to Level 1 document - document['categories_level_2'] = level_2_docs + # Add Level 2 document to Level 1 + document['categories'].append(level_2_doc) # Sync document with Solr self.solr().add([document]) @@ -108,3 +111,4 @@ class WebsiteCategoriesHomepage(models.Model): # Commit and optimize Solr changes self.solr().commit() self.solr().optimize() + diff --git a/indoteknik_custom/models/website_categories_management.py b/indoteknik_custom/models/website_categories_management.py index e430ef5f..3b1db7dd 100644 --- a/indoteknik_custom/models/website_categories_management.py +++ b/indoteknik_custom/models/website_categories_management.py @@ -7,6 +7,10 @@ class WebsiteCategoriesManagement(models.Model): category_id = fields.Many2one('product.public.category', string='Category Level 1', help='table ecommerce category', domain=lambda self: self._get_default_category_domain()) sequence = fields.Integer(string='Sequence') + category_id2 = fields.Many2many(comodel_name='product.public.category', + relation='website_categories_category_id2_rel', + column1='website_categories_homepage_id', column2='product_public_category_id', + string='Category Level 2', copy=False) line_ids = fields.One2many('website.categories.management.line', 'management_id', string='Category Level 2 Lines', auto_join=True) status = fields.Selection([ ('tayang', 'Tayang'), -- cgit v1.2.3 From f6a26ebaa1b960b0ad5de8f6f28238c1e31cd621 Mon Sep 17 00:00:00 2001 From: it-fixcomart Date: Fri, 6 Sep 2024 14:32:39 +0700 Subject: upadate category management sync to solr --- .../models/solr/website_categories_management.py | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'indoteknik_custom/models') diff --git a/indoteknik_custom/models/solr/website_categories_management.py b/indoteknik_custom/models/solr/website_categories_management.py index 1f4caac3..0a40a356 100644 --- a/indoteknik_custom/models/solr/website_categories_management.py +++ b/indoteknik_custom/models/solr/website_categories_management.py @@ -67,11 +67,11 @@ class WebsiteCategoriesHomepage(models.Model): # Prepare Level 1 document document = { 'id': category.id, - 'sequence': category.sequence or '', + 'sequence_i': category.sequence or '', 'category_id_i': category.category_id.id, - 'name': category.category_id.name, - 'numFound': len(category.category_id.product_tmpl_ids), - 'image': self.env['ir.attachment'].api_image( + 'name_s': category.category_id.name, + 'numFound_i': len(category.category_id.product_tmpl_ids), + 'image_s': self.env['ir.attachment'].api_image( 'product.public.category', 'image_1920', category.category_id.id ), 'categories': [] @@ -99,10 +99,10 @@ class WebsiteCategoriesHomepage(models.Model): 'product.public.category', 'image_1920', category_level_3.id ), } - level_2_doc['child_frontend_id_i'].append(level_3_doc) + level_2_doc['child_frontend_id_i'].append(json.dumps(level_3_doc)) # Add Level 2 document to Level 1 - document['categories'].append(level_2_doc) + document['categories'].append(json.dumps(level_2_doc)) # Sync document with Solr self.solr().add([document]) -- cgit v1.2.3 From 84cb69b4ce0a793768fbeca4367d37f21e896615 Mon Sep 17 00:00:00 2001 From: it-fixcomart Date: Fri, 6 Sep 2024 16:20:11 +0700 Subject: update new register --- indoteknik_custom/models/res_partner.py | 62 ++++++++++++------------ indoteknik_custom/models/user_company_request.py | 2 + 2 files changed, 34 insertions(+), 30 deletions(-) (limited to 'indoteknik_custom/models') diff --git a/indoteknik_custom/models/res_partner.py b/indoteknik_custom/models/res_partner.py index 3cc1b1aa..b8a6502c 100644 --- a/indoteknik_custom/models/res_partner.py +++ b/indoteknik_custom/models/res_partner.py @@ -92,14 +92,15 @@ class ResPartner(models.Model): if partner.company_type == 'person' and not partner.parent_id: partner.alamat_lengkap_text = partner.street - if partner.company_type == 'person' and partner.parent_id: - partner.alamat_lengkap_text = partner.parent_id.alamat_lengkap_text + # if partner.company_type == 'person' and partner.parent_id: + # partner.alamat_lengkap_text = partner.parent_id.alamat_lengkap_text + alamat_lengkap = fields.Char(string="Alamat Lengkap", required=False, compute="_alamat_lengkap") - alamat_lengkap_text = fields.Text(string="Alamat Lengkap", required=False) + alamat_lengkap_text = fields.Text(string="Alamat Lengkap", required=False , tracking=3) - # def write(self, vals): - # res = super(ResPartner, self).write(vals) + def write(self, vals): + res = super(ResPartner, self).write(vals) # # # if 'property_payment_term_id' in vals: # # if not self.env.user.is_accounting and vals['property_payment_term_id'] != 26: @@ -110,33 +111,34 @@ class ResPartner(models.Model): # # if self.env.user.id not in users_in_group.mapped('id'): # # raise UserError('You name it') # - # return res - - def write(self, vals): - if self.company_type == 'person': - if self.parent_id: - parent = self.parent_id - vals['customer_type'] = parent.customer_type - vals['nama_wajib_pajak'] = parent.nama_wajib_pajak - vals['npwp'] = parent.npwp - vals['sppkp'] = parent.sppkp - vals['alamat_lengkap_text'] = parent.alamat_lengkap_text - vals['industry_id'] = parent.industry_id.id - vals['company_type_id'] = parent.company_type_id.id - - res = super(ResPartner, self).write(vals) return res - @api.onchange('company_type') - def _onchange_company_type(self): - if self.company_type == 'person' and self.parent_id: - self.customer_type = self.parent_id.customer_type - self.npwp = self.parent_id.npwp - self.sppkp = self.parent_id.sppkp - self.nama_wajib_pajak = self.parent_id.nama_wajib_pajak - self.alamat_lengkap_text = self.parent_id.alamat_lengkap_text - self.industry_id = self.parent_id.industry_id.id - self.company_type_id = self.parent_id.company_type_id.id + # def write(self, vals): + # if self.company_type == 'person': + # if self.parent_id: + # parent = self.parent_id + # vals['customer_type'] = parent.customer_type + # vals['nama_wajib_pajak'] = parent.nama_wajib_pajak + # vals['npwp'] = parent.npwp + # vals['sppkp'] = parent.sppkp + # vals['alamat_lengkap_text'] = parent.alamat_lengkap_text + # vals['industry_id'] = parent.industry_id.id + # vals['company_type_id'] = parent.company_type_id.id + # + # res = super(ResPartner, self).write(vals) + # return res + + @api.depends('company_type', 'parent_id', 'npwp', 'sppkp', 'nama_wajib_pajak','alamat_lengkap_text', 'industry_id', 'company_type_id') + def _related_fields(self): + for partner in self: + if partner.company_type == 'person' and partner.parent_id: + partner.customer_type = partner.parent_id.customer_type + partner.npwp = partner.parent_id.npwp + partner.sppkp = partner.parent_id.sppkp + partner.nama_wajib_pajak = partner.parent_id.nama_wajib_pajak + partner.alamat_lengkap_text = partner.parent_id.alamat_lengkap_text + partner.industry_id = partner.parent_id.industry_id.id + partner.company_type_id = partner.parent_id.company_type_id.id @api.constrains('property_payment_term_id') def updated_by_payment_term(self): diff --git a/indoteknik_custom/models/user_company_request.py b/indoteknik_custom/models/user_company_request.py index d6134650..56bb8d5d 100644 --- a/indoteknik_custom/models/user_company_request.py +++ b/indoteknik_custom/models/user_company_request.py @@ -27,6 +27,8 @@ class UserCompanyRequest(models.Model): self.user_id.sppkp = self.user_company_id.sppkp self.user_id.nama_wajib_pajak = self.user_company_id.nama_wajib_pajak self.user_id.alamat_lengkap_text = self.user_company_id.alamat_lengkap_text + self.user_id.industry_id = self.user_company_id.industry_id.id + self.user_id.company_type_id = self.user_company_id.company_type_id.id self.user_id.user_id = self.user_company_id.user_id self.user_id.property_account_receivable_id = self.user_company_id.property_account_receivable_id self.user_id.property_account_payable_id = self.user_company_id.property_account_payable_id -- cgit v1.2.3 From 494acce1cb7490ab27ad06d2bb9f36d98fbb2256 Mon Sep 17 00:00:00 2001 From: Azka Nathan Date: Sat, 7 Sep 2024 09:34:40 +0700 Subject: fix bug commision --- indoteknik_custom/models/commision.py | 1 + 1 file changed, 1 insertion(+) (limited to 'indoteknik_custom/models') diff --git a/indoteknik_custom/models/commision.py b/indoteknik_custom/models/commision.py index c5809005..48f1c7f6 100644 --- a/indoteknik_custom/models/commision.py +++ b/indoteknik_custom/models/commision.py @@ -261,6 +261,7 @@ class CustomerCommision(models.Model): ('move_id.invoice_date', '>=', self.date_from), ('move_id.invoice_date', '<=', self.date_to), ('product_id.x_manufacture', 'in', brand), + ('exclude_from_invoice_tab', '=', False), ] invoice_lines = self.env['account.move.line'].search(where, order='id') for invoice_line in invoice_lines: -- cgit v1.2.3 From 0aacd16c72067c0bb5c9c8ca24bb19a7995b132b Mon Sep 17 00:00:00 2001 From: it-fixcomart Date: Mon, 9 Sep 2024 10:34:58 +0700 Subject: delete not lines category management --- indoteknik_custom/models/website_categories_management.py | 4 ---- 1 file changed, 4 deletions(-) (limited to 'indoteknik_custom/models') diff --git a/indoteknik_custom/models/website_categories_management.py b/indoteknik_custom/models/website_categories_management.py index 3b1db7dd..e430ef5f 100644 --- a/indoteknik_custom/models/website_categories_management.py +++ b/indoteknik_custom/models/website_categories_management.py @@ -7,10 +7,6 @@ class WebsiteCategoriesManagement(models.Model): category_id = fields.Many2one('product.public.category', string='Category Level 1', help='table ecommerce category', domain=lambda self: self._get_default_category_domain()) sequence = fields.Integer(string='Sequence') - category_id2 = fields.Many2many(comodel_name='product.public.category', - relation='website_categories_category_id2_rel', - column1='website_categories_homepage_id', column2='product_public_category_id', - string='Category Level 2', copy=False) line_ids = fields.One2many('website.categories.management.line', 'management_id', string='Category Level 2 Lines', auto_join=True) status = fields.Selection([ ('tayang', 'Tayang'), -- cgit v1.2.3 From 894d4806067463fceaa2c6e6a67882e8f0bed974 Mon Sep 17 00:00:00 2001 From: stephanchrst Date: Mon, 9 Sep 2024 11:04:35 +0700 Subject: remove product sementara validation --- indoteknik_custom/models/product_template.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'indoteknik_custom/models') diff --git a/indoteknik_custom/models/product_template.py b/indoteknik_custom/models/product_template.py index e6778758..000ee3bf 100755 --- a/indoteknik_custom/models/product_template.py +++ b/indoteknik_custom/models/product_template.py @@ -338,9 +338,9 @@ class ProductTemplate(models.Model): return values def write(self, vals): - for rec in self: - if rec.id == 224484: - raise UserError('Tidak dapat mengubah produk sementara') + # for rec in self: + # if rec.id == 224484: + # raise UserError('Tidak dapat mengubah produk sementara') return super(ProductTemplate, self).write(vals) -- cgit v1.2.3 From ee22bb5c668c346c5f8ba2c4e148324dab0c6a3e Mon Sep 17 00:00:00 2001 From: Azka Nathan Date: Tue, 10 Sep 2024 10:27:15 +0700 Subject: bill dp --- indoteknik_custom/models/purchase_order.py | 47 ++++++++++++++++++++++++++++++ 1 file changed, 47 insertions(+) (limited to 'indoteknik_custom/models') diff --git a/indoteknik_custom/models/purchase_order.py b/indoteknik_custom/models/purchase_order.py index 8ec904a9..83e401b7 100755 --- a/indoteknik_custom/models/purchase_order.py +++ b/indoteknik_custom/models/purchase_order.py @@ -66,6 +66,53 @@ class PurchaseOrder(models.Model): ('printed', 'Printed') ], string='Printed?', copy=False, tracking=True) date_done_picking = fields.Datetime(string='Date Done Picking', compute='get_date_done') + bills_dp_id = fields.Many2one('account.move', string='Bills DP') + + def create_bill_dp(self): + if not self.env.user.is_accounting: + raise UserError('Hanya Accounting yang bisa bikin bill dp') + + current_date = datetime.utcnow() + data_bills = { + 'partner_id': self.partner_id.id, + 'partner_shipping_id': self.partner_id.id, + 'ref': self.name, + 'invoice_date': current_date, + 'date': current_date, + 'move_type': 'in_invoice' + + } + + bills = self.env['account.move'].create([data_bills]) + + product_dp = self.env['product.product'].browse(229625) + + data_line_bills = { + 'move_id': bills.id, + 'product_id': product_dp.id, #product down payment + 'account_id': 401, #Uang Muka persediaan barang dagang + 'quantity': 1, + 'product_uom_id': 1, + 'tax_ids': [line[0].taxes_id.id for line in self.order_line], + } + + + bills_line = self.env['account.move.line'].create([data_line_bills]) + + self.bills_dp_id = bills.id + + move_line = bills.line_ids + move_line.name = '[IT.121456] Down Payment' + move_line.partner_id = self.partner_id.id + + return { + 'name': _('Account Move'), + 'view_mode': 'tree,form', + 'res_model': 'account.move', + 'target': 'current', + 'type': 'ir.actions.act_window', + 'domain': [('id', '=', bills.id)] + } def get_date_done(self): picking = self.env['stock.picking'].search([ -- cgit v1.2.3 From b61d191e9d5663acb81338de133789fd0c43bdf0 Mon Sep 17 00:00:00 2001 From: Azka Nathan Date: Tue, 10 Sep 2024 16:10:15 +0700 Subject: add payment terms on users --- indoteknik_custom/models/res_users.py | 1 + 1 file changed, 1 insertion(+) (limited to 'indoteknik_custom/models') diff --git a/indoteknik_custom/models/res_users.py b/indoteknik_custom/models/res_users.py index 33f64ce3..70a7dc53 100755 --- a/indoteknik_custom/models/res_users.py +++ b/indoteknik_custom/models/res_users.py @@ -11,6 +11,7 @@ class ResUsers(models.Model): activation_token = fields.Char(string="Activation Token") otp_code = fields.Char(string='OTP Code') otp_create_date = fields.Datetime(string='OTP Create Date') + payment_terms_id = fields.Many2one('account.payment.term', related='partner_id.property_payment_term_id', string='Payment Terms') def _generate_otp(self): for user in self: -- cgit v1.2.3 From 1371df38b6818960e6e9520ae783f041694209d8 Mon Sep 17 00:00:00 2001 From: Azka Nathan Date: Wed, 11 Sep 2024 13:39:13 +0700 Subject: ongkos kirim po --- indoteknik_custom/models/purchase_order.py | 13 +++++++++++++ 1 file changed, 13 insertions(+) (limited to 'indoteknik_custom/models') diff --git a/indoteknik_custom/models/purchase_order.py b/indoteknik_custom/models/purchase_order.py index 83e401b7..edcbbb19 100755 --- a/indoteknik_custom/models/purchase_order.py +++ b/indoteknik_custom/models/purchase_order.py @@ -31,6 +31,7 @@ class PurchaseOrder(models.Model): ('approved', 'Approved'), ], string='Approval Status', readonly=True, copy=False, index=True, tracking=3) delivery_amount = fields.Float('Delivery Amount', compute='compute_delivery_amount') + delivery_amt = fields.Float('Delivery Amt') total_margin = fields.Float( 'Margin', compute='compute_total_margin', help="Total Margin in Sales Order Header") @@ -67,6 +68,14 @@ class PurchaseOrder(models.Model): ], string='Printed?', copy=False, tracking=True) date_done_picking = fields.Datetime(string='Date Done Picking', compute='get_date_done') bills_dp_id = fields.Many2one('account.move', string='Bills DP') + grand_total = fields.Monetary(string='Grand Total', help='Amount total + amount delivery', compute='_compute_grand_total') + + def _compute_grand_total(self): + for order in self: + if order.delivery_amt: + order.grand_total = order.delivery_amt + order.amount_total + else: + order.grand_total = order.amount_total def create_bill_dp(self): if not self.env.user.is_accounting: @@ -671,6 +680,8 @@ class PurchaseOrder(models.Model): purchase_price = line.price_subtotal if line.order_id.delivery_amount > 0: purchase_price += line.delivery_amt_line + if line.order_id.delivery_amt > 0: + purchase_price += line.order_id.delivery_amt real_item_margin = sales_price - purchase_price sum_margin += real_item_margin @@ -713,6 +724,8 @@ class PurchaseOrder(models.Model): purchase_price = po_line.price_subtotal / po_line.product_qty * line.qty_po if line.purchase_order_id.delivery_amount > 0: purchase_price += (po_line.delivery_amt_line / po_line.product_qty) * line.qty_po + if line.purchase_order_id.delivery_amt > 0: + purchase_price += line.purchase_order_id.delivery_amt real_item_margin = sales_price - purchase_price sum_margin += real_item_margin -- cgit v1.2.3 From d8e60a974097058482167eefe658f9b4e89c0dd2 Mon Sep 17 00:00:00 2001 From: stephanchrst Date: Wed, 11 Sep 2024 16:07:56 +0700 Subject: mandatory delivery date --- indoteknik_custom/models/sale_order.py | 3 +++ 1 file changed, 3 insertions(+) (limited to 'indoteknik_custom/models') diff --git a/indoteknik_custom/models/sale_order.py b/indoteknik_custom/models/sale_order.py index b6759306..5e792b05 100755 --- a/indoteknik_custom/models/sale_order.py +++ b/indoteknik_custom/models/sale_order.py @@ -633,6 +633,9 @@ class SaleOrder(models.Model): if not order.client_order_ref and order.create_date > datetime(2024, 6, 27): raise UserError("Customer Reference kosong, di isi dengan NO PO jika PO tidak ada mohon ditulis Tanpa PO") + + if not order.commitment_date and order.create_date > datetime(2024, 9, 10): + raise UserError("Expected Delivery Date kosong, wajib diisi") if order.validate_partner_invoice_due(): return self._create_notification_action('Notification', 'Terdapat invoice yang telah melewati batas waktu, mohon perbarui pada dokumen Due Extension') -- cgit v1.2.3 From a8e539c92236453ce7aad06d23cf117f4b7239fc Mon Sep 17 00:00:00 2001 From: stephanchrst Date: Wed, 11 Sep 2024 16:08:30 +0700 Subject: revise --- 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 5e792b05..9506aedb 100755 --- a/indoteknik_custom/models/sale_order.py +++ b/indoteknik_custom/models/sale_order.py @@ -634,7 +634,7 @@ class SaleOrder(models.Model): if not order.client_order_ref and order.create_date > datetime(2024, 6, 27): raise UserError("Customer Reference kosong, di isi dengan NO PO jika PO tidak ada mohon ditulis Tanpa PO") - if not order.commitment_date and order.create_date > datetime(2024, 9, 10): + if not order.commitment_date and order.create_date > datetime(2024, 9, 12): raise UserError("Expected Delivery Date kosong, wajib diisi") if order.validate_partner_invoice_due(): -- cgit v1.2.3 From 82f0467cd3f014761fd35bd04eecc485ed8addda Mon Sep 17 00:00:00 2001 From: Azka Nathan Date: Thu, 12 Sep 2024 09:46:14 +0700 Subject: push --- indoteknik_custom/models/sale_order.py | 7 +++++-- 1 file changed, 5 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 d389f6ae..abfbb799 100755 --- a/indoteknik_custom/models/sale_order.py +++ b/indoteknik_custom/models/sale_order.py @@ -113,10 +113,13 @@ class SaleOrder(models.Model): def do_unreserve(self): user_id = self.env.user.id - if user_id != self.user_id.id: + if user_id != self.user_id.id and user_id != self.helper_by_id.id: raise UserError(_("Only the user who created the picking can unreserve it.")) - self.unreserve_id.with_context({'darimana': 'sale.order'}).do_unreserve() + if self.unreserve_id and self.unreserve_id.state == 'assigned': + self.unreserve_id.with_context({'darimana': 'sale.order'}).do_unreserve() + else: + raise UserError(_("Picking not found.")) def _compute_date_kirim(self): for rec in self: -- cgit v1.2.3 From f03e6dc2ee2f3cd34eca15e81cd8964c07089ef4 Mon Sep 17 00:00:00 2001 From: Azka Nathan Date: Thu, 12 Sep 2024 10:26:48 +0700 Subject: new window --- indoteknik_custom/models/__init__.py | 1 + indoteknik_custom/models/approval_unreserve.py | 69 ++++++++++++++++++++++++++ 2 files changed, 70 insertions(+) create mode 100644 indoteknik_custom/models/approval_unreserve.py (limited to 'indoteknik_custom/models') diff --git a/indoteknik_custom/models/__init__.py b/indoteknik_custom/models/__init__.py index e9ce587c..fe3e02d4 100755 --- a/indoteknik_custom/models/__init__.py +++ b/indoteknik_custom/models/__init__.py @@ -125,3 +125,4 @@ from . import sale_order_multi_uangmuka_penjualan from . import shipment_group from . import sales_order_reject from . import approval_date_doc +from . import approval_unreserve diff --git a/indoteknik_custom/models/approval_unreserve.py b/indoteknik_custom/models/approval_unreserve.py new file mode 100644 index 00000000..4feb51fa --- /dev/null +++ b/indoteknik_custom/models/approval_unreserve.py @@ -0,0 +1,69 @@ +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 ApprovalUnreserve(models.Model): + _name = "approval.unreserve" + _description = "Approval Unreserve" + _inherit = ['mail.thread'] + _rec_name = 'number' + + number = fields.Char(string='Document No', index=True, copy=False, readonly=True, tracking=True, default='New') + approval_line = fields.One2many('approval.unreserve.line', 'approval_id', string='Approval Unreserve Lines', auto_join=True) + state = fields.Selection([ + ('draft', 'Draft'), + ('waiting_approval', 'Waiting for Approval'), + ('approved', 'Approved'), + ('rejected', 'Rejected') + ], string="Status", default='draft', tracking=True) + request_date = fields.Date(string="Request Date", default=fields.Date.today, tracking=True) + approved_by = fields.Many2one('res.users', string="Approved By", readonly=True, tracking=True) + rejection_reason = fields.Text(string="Rejection Reason", tracking=True) + + @api.model + def create(self, vals): + if vals.get('number', 'New') == 'New': + vals['number'] = self.env['ir.sequence'].next_by_code('approval.unreserve') or 'New' + return super(ApprovalUnreserve, self).create(vals) + + def action_submit_for_approval(self): + self.write({'state': 'waiting_approval'}) + + def action_approve(self): + if self.state != 'waiting_approval': + raise UserError("Approval can only be done in 'Waiting for Approval' state") + self.write({ + 'state': 'approved', + 'approved_by': self.env.user.id + }) + # Trigger the unreserve function + self._trigger_unreserve() + + def action_reject(self, reason): + if self.state != 'waiting_approval': + raise UserError("Rejection can only be done in 'Waiting for Approval' state") + self.write({ + 'state': 'rejected', + 'rejection_reason': reason + }) + + def _trigger_unreserve(self): + # Get the related stock moves and perform the unreserve for approved lines + stock_move_obj = self.env['stock.move'] + for line in self.approval_line: + move = stock_move_obj.browse(line.move_id.id) + # Use the custom _do_unreserve method you defined earlier + move._do_unreserve(product=line.product_id, quantity=line.unreserve_qty) + +class ApprovalUnreserveLine(models.Model): + _name = 'approval.unreserve.line' + _description = 'Approval Unreserve Line' + _order = 'approval_id, id' + + approval_id = fields.Many2one('approval.unreserve', string='Approval Reference', required=True, ondelete='cascade', index=True, copy=False) + move_id = fields.Many2one('stock.move', string="Stock Move", required=True) + product_id = fields.Many2one('product.product', string="Product", related='move_id.product_id', readonly=True) + unreserve_qty = fields.Float(string="Quantity to Unreserve", required=True) -- cgit v1.2.3 From fdd67910ef7d4dd66803d09a7c49b1c3faabdd18 Mon Sep 17 00:00:00 2001 From: Azka Nathan Date: Thu, 12 Sep 2024 10:53:10 +0700 Subject: deactivate function update_purchase_price_so_line --- indoteknik_custom/models/automatic_purchase.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'indoteknik_custom/models') diff --git a/indoteknik_custom/models/automatic_purchase.py b/indoteknik_custom/models/automatic_purchase.py index 1d1322fa..13c83b04 100644 --- a/indoteknik_custom/models/automatic_purchase.py +++ b/indoteknik_custom/models/automatic_purchase.py @@ -262,7 +262,7 @@ class AutomaticPurchase(models.Model): new_po_line = self.env['purchase.order.line'].create([param_line]) line.current_po_id = new_po.id line.current_po_line_id = new_po_line.id - self.update_purchase_price_so_line(line) + # self.update_purchase_price_so_line(line) self.create_purchase_order_sales_match(new_po) -- cgit v1.2.3 From 33d2a0583d74182709588313ad0eae70c8569f02 Mon Sep 17 00:00:00 2001 From: it-fixcomart Date: Thu, 12 Sep 2024 12:18:59 +0700 Subject: update new register --- indoteknik_custom/models/res_partner.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'indoteknik_custom/models') diff --git a/indoteknik_custom/models/res_partner.py b/indoteknik_custom/models/res_partner.py index b8a6502c..4c6621d4 100644 --- a/indoteknik_custom/models/res_partner.py +++ b/indoteknik_custom/models/res_partner.py @@ -88,7 +88,7 @@ class ResPartner(models.Model): if partner.state_id: lengkap += " " + partner.state_id.name - partner.alamat_lengkap = lengkap.upper() + # partner.alamat_lengkap = lengkap.upper() if partner.company_type == 'person' and not partner.parent_id: partner.alamat_lengkap_text = partner.street @@ -99,8 +99,8 @@ class ResPartner(models.Model): alamat_lengkap = fields.Char(string="Alamat Lengkap", required=False, compute="_alamat_lengkap") alamat_lengkap_text = fields.Text(string="Alamat Lengkap", required=False , tracking=3) - def write(self, vals): - res = super(ResPartner, self).write(vals) + # def write(self, vals): + # res = super(ResPartner, self).write(vals) # # # if 'property_payment_term_id' in vals: # # if not self.env.user.is_accounting and vals['property_payment_term_id'] != 26: @@ -111,7 +111,7 @@ class ResPartner(models.Model): # # if self.env.user.id not in users_in_group.mapped('id'): # # raise UserError('You name it') # - return res + # return res # def write(self, vals): # if self.company_type == 'person': -- cgit v1.2.3 From 5c6098158ab0f82437aa24e947a66b78b21b6bd7 Mon Sep 17 00:00:00 2001 From: Azka Nathan Date: Thu, 12 Sep 2024 13:58:27 +0700 Subject: push --- indoteknik_custom/models/approval_unreserve.py | 19 ++++++++++- indoteknik_custom/models/stock_move.py | 44 +++++++++++++++++++++++++- 2 files changed, 61 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 4feb51fa..a8f9fd3b 100644 --- a/indoteknik_custom/models/approval_unreserve.py +++ b/indoteknik_custom/models/approval_unreserve.py @@ -21,8 +21,25 @@ class ApprovalUnreserve(models.Model): ], string="Status", default='draft', tracking=True) request_date = fields.Date(string="Request Date", default=fields.Date.today, tracking=True) approved_by = fields.Many2one('res.users', string="Approved By", readonly=True, tracking=True) + picking_id = fields.Many2one('stock.picking', string="Picking", tracking=True) rejection_reason = fields.Text(string="Rejection Reason", tracking=True) + @api.constrains('picking_id') + def create_move_id_line(self): + if not self.picking_id: + raise ValidationError("Picking is required") + + stock_move = self.env['stock.move'].search([('picking_id', '=', self.picking_id.id)]) + + if not stock_move: + raise ValidationError("Picking is not found") + + for move in stock_move: + self.approval_line.create({ + 'approval_id': self.id, + 'move_id': move.id + }) + @api.model def create(self, vals): if vals.get('number', 'New') == 'New': @@ -66,4 +83,4 @@ class ApprovalUnreserveLine(models.Model): approval_id = fields.Many2one('approval.unreserve', string='Approval Reference', required=True, ondelete='cascade', index=True, copy=False) move_id = fields.Many2one('stock.move', string="Stock Move", required=True) product_id = fields.Many2one('product.product', string="Product", related='move_id.product_id', readonly=True) - unreserve_qty = fields.Float(string="Quantity to Unreserve", required=True) + unreserve_qty = fields.Float(string="Quantity to Unreserve") diff --git a/indoteknik_custom/models/stock_move.py b/indoteknik_custom/models/stock_move.py index fe46bf65..6c44f8a6 100644 --- a/indoteknik_custom/models/stock_move.py +++ b/indoteknik_custom/models/stock_move.py @@ -1,5 +1,6 @@ from odoo import fields, models, api - +from odoo.tools.misc import format_date, OrderedSet +from odoo.exceptions import UserError class StockMove(models.Model): _inherit = 'stock.move' @@ -7,6 +8,47 @@ class StockMove(models.Model): line_no = fields.Integer('No', default=0) sale_id = fields.Many2one('sale.order', string='SO') + def _do_unreserve(self, product=None, quantity=None): + moves_to_unreserve = OrderedSet() + for move in self: + if move.state == 'cancel' or (move.state == 'done' and move.scrapped): + continue + elif move.state == 'done': + raise UserError(_("You cannot unreserve a stock move that has been set to 'Done'.")) + + if product and move.product_id != product: + continue # Skip moves that don't match the specified product + moves_to_unreserve.add(move.id) + + moves_to_unreserve = self.env['stock.move'].browse(moves_to_unreserve) + + ml_to_update, ml_to_unlink = OrderedSet(), OrderedSet() + moves_not_to_recompute = OrderedSet() + + for ml in moves_to_unreserve.move_line_ids: + if product and ml.product_id != product: + continue # Only affect the specified product + + if quantity > 0: + # Only reduce by the specified quantity if it is greater than zero + ml_to_update.add(ml.id) + remaining_qty = ml.product_uom_qty - quantity + ml.write({'product_uom_qty': remaining_qty if remaining_qty > 0 else 0}) + quantity = 0 # Set to zero to prevent further unreserving in the same loop + elif ml.qty_done: + ml_to_update.add(ml.id) + else: + ml_to_unlink.add(ml.id) + moves_not_to_recompute.add(ml.move_id.id) + + ml_to_update, ml_to_unlink = self.env['stock.move.line'].browse(ml_to_update), self.env['stock.move.line'].browse(ml_to_unlink) + moves_not_to_recompute = self.env['stock.move'].browse(moves_not_to_recompute) + + ml_to_unlink.unlink() + (moves_to_unreserve - moves_not_to_recompute)._recompute_state() + return True + + def _prepare_account_move_line_from_mr(self, po_line, qty, move=False): po_line.ensure_one() aml_currency = move and move.currency_id or po_line.currency_id -- cgit v1.2.3 From a37bc839612b5162b4446182ac23c1dfd1c3253e Mon Sep 17 00:00:00 2001 From: stephanchrst Date: Thu, 12 Sep 2024 14:17:36 +0700 Subject: calculate margin after purchase delivery deduction --- indoteknik_custom/models/automatic_purchase.py | 6 ++++- indoteknik_custom/models/purchase_order.py | 11 +++++++++ .../models/purchase_order_sales_match.py | 12 +++++++++- indoteknik_custom/models/sale_order.py | 26 ++++++++++++++++++++++ 4 files changed, 53 insertions(+), 2 deletions(-) (limited to 'indoteknik_custom/models') diff --git a/indoteknik_custom/models/automatic_purchase.py b/indoteknik_custom/models/automatic_purchase.py index 1d1322fa..4531cff9 100644 --- a/indoteknik_custom/models/automatic_purchase.py +++ b/indoteknik_custom/models/automatic_purchase.py @@ -293,6 +293,9 @@ class AutomaticPurchase(models.Model): sale_ids_set.add(sale_id_with_salesperson) sale_ids_name.add(sale_order.sale_id.name) + margin_item = sale_order.sale_line_id.item_margin / sale_order.qty_so if sale_order.qty_so else 0 + margin_item = margin_item * sale_order.qty_po + matches_so_line = { 'purchase_order_id': purchase_order.id, 'sale_id': sale_order.sale_id.id, @@ -305,7 +308,8 @@ class AutomaticPurchase(models.Model): 'product_id': sale_order.product_id.id, 'qty_so': sale_order.qty_so, 'qty_po': sale_order.qty_po, - 'margin_so': sale_order.sale_line_id.item_percent_margin + 'margin_so': sale_order.sale_line_id.item_percent_margin, + 'margin_item': margin_item } po_matches_so_line = self.env['purchase.order.sales.match'].create([matches_so_line]) diff --git a/indoteknik_custom/models/purchase_order.py b/indoteknik_custom/models/purchase_order.py index edcbbb19..afa67cf2 100755 --- a/indoteknik_custom/models/purchase_order.py +++ b/indoteknik_custom/models/purchase_order.py @@ -69,6 +69,17 @@ class PurchaseOrder(models.Model): date_done_picking = fields.Datetime(string='Date Done Picking', compute='get_date_done') 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') + + def _compute_total_margin_match(self): + for purchase in self: + match = self.env['purchase.order.sales.match'] + result = match.read_group( + [('purchase_order_id.id', '=', purchase.id)], + ['margin_item'], + [] + ) + purchase.total_margin_match = result[0].get('margin_item', 0.0) def _compute_grand_total(self): for order in self: diff --git a/indoteknik_custom/models/purchase_order_sales_match.py b/indoteknik_custom/models/purchase_order_sales_match.py index 78581409..d1d929d3 100644 --- a/indoteknik_custom/models/purchase_order_sales_match.py +++ b/indoteknik_custom/models/purchase_order_sales_match.py @@ -20,7 +20,17 @@ class PurchaseOrderSalesMatch(models.Model): product_id = fields.Many2one('product.product', string='Product') qty_so = fields.Float(string='Qty SO') qty_po = fields.Float(string='Qty PO') - margin_so = fields.Float(string='Margin SO') + margin_so = fields.Float(string='Margin SO') + margin_item = fields.Float(string='Margin') + delivery_amt = fields.Float(string='Delivery Amount', compute='_compute_delivery_amt') + margin_deduct = fields.Float(string='After Deduct', compute='_compute_delivery_amt') + + def _compute_delivery_amt(self): + for line in self: + percent_margin = line.margin_item / line.purchase_order_id.total_margin_match \ + if line.purchase_order_id.total_margin_match else 0 + line.delivery_amt = line.purchase_order_id.delivery_amt * percent_margin + line.margin_deduct = line.margin_item - line.delivery_amt @api.onchange('sale_id') def onchange_sale_id(self): diff --git a/indoteknik_custom/models/sale_order.py b/indoteknik_custom/models/sale_order.py index 9506aedb..9a6dbd9e 100755 --- a/indoteknik_custom/models/sale_order.py +++ b/indoteknik_custom/models/sale_order.py @@ -112,6 +112,32 @@ class SaleOrder(models.Model): note_website = fields.Char(string="Note Website") use_button = fields.Boolean(string='Using Calculate Selling Price', copy=False) voucher_shipping_id = fields.Many2one(comodel_name='voucher', string='Voucher Shipping', copy=False) + margin_after_delivery_purchase = fields.Float(string='Margin After Delivery Purchase', compute='_compute_margin_after_delivery_purchase') + percent_margin_after_delivery_purchase = fields.Float(string='% Margin After Delivery Purchase', compute='_compute_margin_after_delivery_purchase') + purchase_delivery_amt = fields.Float(string='Purchase Delivery Amount', compute='_compute_purchase_delivery_amount') + + def _compute_purchase_delivery_amount(self): + for order in self: + match = self.env['purchase.order.sales.match'] + result2 = match.search([ + ('sale_id.id', '=', order.id) + ]) + delivery_amt = 0 + for res in result2: + delivery_amt = res.delivery_amt + order.purchase_delivery_amt = delivery_amt + + def _compute_margin_after_delivery_purchase(self): + for order in self: + order.margin_after_delivery_purchase = order.total_margin - order.purchase_delivery_amt + if order.amount_untaxed == 0: + order.total_percent_margin = 0 + continue + if order.shipping_cost_covered == 'indoteknik': + delivery_amt = order.delivery_amt + else: + delivery_amt = 0 + order.percent_margin_after_delivery_purchase = round((order.margin_after_delivery_purchase / (order.amount_untaxed-delivery_amt-order.fee_third_party)) * 100, 2) def _compute_date_kirim(self): for rec in self: -- cgit v1.2.3 From c36fb56b19bbd33e0f6a3d6f16a939f7fb6a0ead Mon Sep 17 00:00:00 2001 From: it-fixcomart Date: Thu, 12 Sep 2024 15:24:17 +0700 Subject: update new register --- indoteknik_custom/models/res_partner.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'indoteknik_custom/models') diff --git a/indoteknik_custom/models/res_partner.py b/indoteknik_custom/models/res_partner.py index 4c6621d4..5e1eba09 100644 --- a/indoteknik_custom/models/res_partner.py +++ b/indoteknik_custom/models/res_partner.py @@ -88,7 +88,7 @@ class ResPartner(models.Model): if partner.state_id: lengkap += " " + partner.state_id.name - # partner.alamat_lengkap = lengkap.upper() + partner.alamat_lengkap = lengkap.upper() if partner.company_type == 'person' and not partner.parent_id: partner.alamat_lengkap_text = partner.street -- cgit v1.2.3 From b473179e5adde097bc9ec43ee4566b850937f1ed Mon Sep 17 00:00:00 2001 From: Azka Nathan Date: Fri, 13 Sep 2024 10:25:03 +0700 Subject: unreserve --- indoteknik_custom/models/approval_unreserve.py | 9 +++++++++ indoteknik_custom/models/sale_order.py | 10 ---------- indoteknik_custom/models/sale_order_line.py | 2 +- indoteknik_custom/models/stock_move.py | 2 +- 4 files changed, 11 insertions(+), 12 deletions(-) (limited to 'indoteknik_custom/models') diff --git a/indoteknik_custom/models/approval_unreserve.py b/indoteknik_custom/models/approval_unreserve.py index a8f9fd3b..8c232d9c 100644 --- a/indoteknik_custom/models/approval_unreserve.py +++ b/indoteknik_custom/models/approval_unreserve.py @@ -22,6 +22,7 @@ class ApprovalUnreserve(models.Model): request_date = fields.Date(string="Request Date", default=fields.Date.today, tracking=True) approved_by = fields.Many2one('res.users', string="Approved By", readonly=True, tracking=True) picking_id = fields.Many2one('stock.picking', string="Picking", tracking=True) + user_id = fields.Many2one('res.users', string="User", readonly=True, tracking=True) rejection_reason = fields.Text(string="Rejection Reason", tracking=True) @api.constrains('picking_id') @@ -40,6 +41,8 @@ class ApprovalUnreserve(models.Model): 'move_id': move.id }) + self.user_id = self.picking_id.sale_id.user_id.id + @api.model def create(self, vals): if vals.get('number', 'New') == 'New': @@ -50,6 +53,9 @@ class ApprovalUnreserve(models.Model): self.write({'state': 'waiting_approval'}) def action_approve(self): + if self.env.user.id != self.user_id.id: + raise UserError("Hanya Sales nya yang bisa approve.") + if self.state != 'waiting_approval': raise UserError("Approval can only be done in 'Waiting for Approval' state") self.write({ @@ -60,6 +66,9 @@ class ApprovalUnreserve(models.Model): self._trigger_unreserve() def action_reject(self, reason): + if self.env.user.id != self.user_id.id: + raise UserError("Hanya Sales nya yang bisa reject.") + if self.state != 'waiting_approval': raise UserError("Rejection can only be done in 'Waiting for Approval' state") self.write({ diff --git a/indoteknik_custom/models/sale_order.py b/indoteknik_custom/models/sale_order.py index 023cc5e6..0690ffa2 100755 --- a/indoteknik_custom/models/sale_order.py +++ b/indoteknik_custom/models/sale_order.py @@ -113,16 +113,6 @@ class SaleOrder(models.Model): use_button = fields.Boolean(string='Using Calculate Selling Price', copy=False) unreserve_id = fields.Many2one('stock.picking', 'Unreserve Picking') voucher_shipping_id = fields.Many2one(comodel_name='voucher', string='Voucher Shipping', copy=False) - - def do_unreserve(self): - user_id = self.env.user.id - if user_id != self.user_id.id and user_id != self.helper_by_id.id: - raise UserError(_("Only the user who created the picking can unreserve it.")) - - if self.unreserve_id and self.unreserve_id.state == 'assigned': - self.unreserve_id.with_context({'darimana': 'sale.order'}).do_unreserve() - else: - raise UserError(_("Picking not found.")) def _compute_date_kirim(self): for rec in self: diff --git a/indoteknik_custom/models/sale_order_line.py b/indoteknik_custom/models/sale_order_line.py index a64a744c..50438dbe 100644 --- a/indoteknik_custom/models/sale_order_line.py +++ b/indoteknik_custom/models/sale_order_line.py @@ -348,7 +348,7 @@ class SaleOrderLine(models.Model): def validate_line(self): for line in self: - if line.product_id.id in [385544, 224484]: + if line.product_id.id in [385544, 224484, 417724]: raise UserError('Produk Sementara Tidak Bisa Di Confirm atau Ask Approval') if not line.product_id or line.product_id.type == 'service': continue diff --git a/indoteknik_custom/models/stock_move.py b/indoteknik_custom/models/stock_move.py index 6c44f8a6..cd061946 100644 --- a/indoteknik_custom/models/stock_move.py +++ b/indoteknik_custom/models/stock_move.py @@ -14,7 +14,7 @@ class StockMove(models.Model): if move.state == 'cancel' or (move.state == 'done' and move.scrapped): continue elif move.state == 'done': - raise UserError(_("You cannot unreserve a stock move that has been set to 'Done'.")) + raise UserError("You cannot unreserve a stock move that has been set to 'Done'.") if product and move.product_id != product: continue # Skip moves that don't match the specified product -- cgit v1.2.3 From c81f7b9f21d5ae9c77758a67bbf961fb42697dd8 Mon Sep 17 00:00:00 2001 From: Azka Nathan Date: Fri, 13 Sep 2024 10:30:15 +0700 Subject: validation product sementara --- 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 a64a744c..50438dbe 100644 --- a/indoteknik_custom/models/sale_order_line.py +++ b/indoteknik_custom/models/sale_order_line.py @@ -348,7 +348,7 @@ class SaleOrderLine(models.Model): def validate_line(self): for line in self: - if line.product_id.id in [385544, 224484]: + if line.product_id.id in [385544, 224484, 417724]: raise UserError('Produk Sementara Tidak Bisa Di Confirm atau Ask Approval') if not line.product_id or line.product_id.type == 'service': continue -- cgit v1.2.3 From f44dc785ffcce7738c284fd40d79dbece7b2e5cb Mon Sep 17 00:00:00 2001 From: Azka Nathan Date: Fri, 13 Sep 2024 14:22:19 +0700 Subject: add validation on stock picking gudang selisih --- indoteknik_custom/models/stock_picking.py | 3 +++ 1 file changed, 3 insertions(+) (limited to 'indoteknik_custom/models') diff --git a/indoteknik_custom/models/stock_picking.py b/indoteknik_custom/models/stock_picking.py index d16d508e..3dd960e2 100644 --- a/indoteknik_custom/models/stock_picking.py +++ b/indoteknik_custom/models/stock_picking.py @@ -373,6 +373,9 @@ class StockPicking(models.Model): if self.picking_type_id.id == 28 and not self.env.user.is_logistic_approver: raise UserError("Harus di Approve oleh Logistik") + + if self.location_dest_id.id == 47 and not self.env.user.is_purchasing_manager: + raise UserError("Transfer ke gudang selisih harus di approve Rafly Hanggara") if self.group_id.sale_id: if self.group_id.sale_id.payment_link_midtrans: -- cgit v1.2.3 From 649a8f0d51b8fa7dc90dfbd0967e94dd586cd0aa Mon Sep 17 00:00:00 2001 From: stephanchrst Date: Fri, 13 Sep 2024 16:21:50 +0700 Subject: bug fix sales order with amount equal zero --- 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 9a6dbd9e..6348328e 100755 --- a/indoteknik_custom/models/sale_order.py +++ b/indoteknik_custom/models/sale_order.py @@ -131,7 +131,7 @@ class SaleOrder(models.Model): for order in self: order.margin_after_delivery_purchase = order.total_margin - order.purchase_delivery_amt if order.amount_untaxed == 0: - order.total_percent_margin = 0 + order.percent_margin_after_delivery_purchase = 0 continue if order.shipping_cost_covered == 'indoteknik': delivery_amt = order.delivery_amt -- cgit v1.2.3 From 2e9f95e8201692317d1ce23f6992fdb0e37dc95c Mon Sep 17 00:00:00 2001 From: Azka Nathan Date: Fri, 13 Sep 2024 16:51:28 +0700 Subject: cr archive product --- indoteknik_custom/models/product_template.py | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) (limited to 'indoteknik_custom/models') diff --git a/indoteknik_custom/models/product_template.py b/indoteknik_custom/models/product_template.py index 000ee3bf..031d1b5b 100755 --- a/indoteknik_custom/models/product_template.py +++ b/indoteknik_custom/models/product_template.py @@ -388,8 +388,16 @@ class ProductProduct(models.Model): if product_template.active and product.active: if not product.active and len(variants) == 1: product_template.with_context(skip_active_constraint=True).active = False + product_template.unpublished = True elif not product.active and len(variants) > 1: - continue + all_inactive = all(not variant.active for variant in variants) + if all_inactive: + product_template.with_context(skip_active_constraint=True).active = False + product_template.unpublished = True + else: + continue + if any(variant.active for variant in variants): + product_template.unpublished = False def update_internal_reference_variants(self, limit=100): variants = self.env['product.product'].search([ -- cgit v1.2.3 From 98bdb05daa79c46b0a1f4284d19e65ed3a7d2f48 Mon Sep 17 00:00:00 2001 From: stephanchrst Date: Sat, 14 Sep 2024 13:30:14 +0700 Subject: bug fix delete purchase order line cause of calculate margin match --- 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 afa67cf2..8a47482a 100755 --- a/indoteknik_custom/models/purchase_order.py +++ b/indoteknik_custom/models/purchase_order.py @@ -75,7 +75,7 @@ class PurchaseOrder(models.Model): for purchase in self: match = self.env['purchase.order.sales.match'] result = match.read_group( - [('purchase_order_id.id', '=', purchase.id)], + [('purchase_order_id', '=', purchase.id)], ['margin_item'], [] ) -- cgit v1.2.3 From b14ec46d5c0d8e75558cff9cf38cb2372b82af3b Mon Sep 17 00:00:00 2001 From: it-fixcomart Date: Tue, 17 Sep 2024 14:04:33 +0700 Subject: update new register --- indoteknik_custom/models/res_partner.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'indoteknik_custom/models') diff --git a/indoteknik_custom/models/res_partner.py b/indoteknik_custom/models/res_partner.py index 5e1eba09..b8a6502c 100644 --- a/indoteknik_custom/models/res_partner.py +++ b/indoteknik_custom/models/res_partner.py @@ -99,8 +99,8 @@ class ResPartner(models.Model): alamat_lengkap = fields.Char(string="Alamat Lengkap", required=False, compute="_alamat_lengkap") alamat_lengkap_text = fields.Text(string="Alamat Lengkap", required=False , tracking=3) - # def write(self, vals): - # res = super(ResPartner, self).write(vals) + def write(self, vals): + res = super(ResPartner, self).write(vals) # # # if 'property_payment_term_id' in vals: # # if not self.env.user.is_accounting and vals['property_payment_term_id'] != 26: @@ -111,7 +111,7 @@ class ResPartner(models.Model): # # if self.env.user.id not in users_in_group.mapped('id'): # # raise UserError('You name it') # - # return res + return res # def write(self, vals): # if self.company_type == 'person': -- cgit v1.2.3 From f0aaf4476c8b92cb68503e9760216ca20fe4e34d Mon Sep 17 00:00:00 2001 From: Azka Nathan Date: Tue, 17 Sep 2024 14:05:31 +0700 Subject: api check_tempo and add type promotion on sale order --- indoteknik_custom/models/sale_order.py | 11 +++++++++++ 1 file changed, 11 insertions(+) (limited to 'indoteknik_custom/models') diff --git a/indoteknik_custom/models/sale_order.py b/indoteknik_custom/models/sale_order.py index 6348328e..43ee3ef9 100755 --- a/indoteknik_custom/models/sale_order.py +++ b/indoteknik_custom/models/sale_order.py @@ -115,6 +115,17 @@ class SaleOrder(models.Model): margin_after_delivery_purchase = fields.Float(string='Margin After Delivery Purchase', compute='_compute_margin_after_delivery_purchase') percent_margin_after_delivery_purchase = fields.Float(string='% Margin After Delivery Purchase', compute='_compute_margin_after_delivery_purchase') purchase_delivery_amt = fields.Float(string='Purchase Delivery Amount', compute='_compute_purchase_delivery_amount') + type_promotion = fields.Char(string='Type Promotion', compute='_compute_type_promotion') + + def _compute_type_promotion(self): + for rec in self: + promotion_types = [] + for promotion in rec.order_promotion_ids: + for line_program in promotion.program_line_id: + if line_program.promotion_type: + promotion_types.append(dict(line_program._fields['promotion_type'].selection).get(line_program.promotion_type)) + + rec.type_promotion = ', '.join(promotion_types) def _compute_purchase_delivery_amount(self): for order in self: -- cgit v1.2.3 From 1698ec300f2e7c363e41cb51ce94a39f66d6088b Mon Sep 17 00:00:00 2001 From: Azka Nathan Date: Tue, 17 Sep 2024 14:43:22 +0700 Subject: cr type promotion --- indoteknik_custom/models/sale_order.py | 4 +++- 1 file changed, 3 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 43ee3ef9..65b92601 100755 --- a/indoteknik_custom/models/sale_order.py +++ b/indoteknik_custom/models/sale_order.py @@ -125,7 +125,9 @@ class SaleOrder(models.Model): if line_program.promotion_type: promotion_types.append(dict(line_program._fields['promotion_type'].selection).get(line_program.promotion_type)) - rec.type_promotion = ', '.join(promotion_types) + # Removing duplicates by converting to a set, then back to a list + rec.type_promotion = ', '.join(sorted(set(promotion_types))) + def _compute_purchase_delivery_amount(self): for order in self: -- cgit v1.2.3 From fd66c221b48c28a3aaf45500572821aaae84c0de Mon Sep 17 00:00:00 2001 From: Azka Nathan Date: Tue, 17 Sep 2024 15:38:00 +0700 Subject: add is_efaktur_exported to tree invoices --- indoteknik_custom/models/sale_order.py | 1 - 1 file changed, 1 deletion(-) (limited to 'indoteknik_custom/models') diff --git a/indoteknik_custom/models/sale_order.py b/indoteknik_custom/models/sale_order.py index 65b92601..bd0fb75e 100755 --- a/indoteknik_custom/models/sale_order.py +++ b/indoteknik_custom/models/sale_order.py @@ -128,7 +128,6 @@ class SaleOrder(models.Model): # Removing duplicates by converting to a set, then back to a list rec.type_promotion = ', '.join(sorted(set(promotion_types))) - def _compute_purchase_delivery_amount(self): for order in self: match = self.env['purchase.order.sales.match'] -- cgit v1.2.3 From 314125a03d680cd2da6e413200abd8eefec2b1ec Mon Sep 17 00:00:00 2001 From: it-fixcomart Date: Tue, 17 Sep 2024 17:22:50 +0700 Subject: uppdate new register --- indoteknik_custom/models/res_partner.py | 31 +------------------------------ 1 file changed, 1 insertion(+), 30 deletions(-) (limited to 'indoteknik_custom/models') diff --git a/indoteknik_custom/models/res_partner.py b/indoteknik_custom/models/res_partner.py index b8a6502c..7392b10d 100644 --- a/indoteknik_custom/models/res_partner.py +++ b/indoteknik_custom/models/res_partner.py @@ -60,43 +60,14 @@ class ResPartner(models.Model): @api.depends("street", "street2", "city", "state_id", "country_id", "blok", "nomor", "rt", "rw", "kelurahan_id", "kecamatan_id") - def _alamat_lengkap(self): + def _alamat_lengkap_text(self): for partner in self: - lengkap = partner.street or "" - lengkap += " " + (partner.street2 or '') - - if partner.blok: - lengkap += " Blok: " + partner.blok + ", " - if partner.nomor: - lengkap += " Nomor: " + partner.nomor + ", " - - if partner.rt: - lengkap += " RT: " + partner.rt - if partner.rw: - lengkap += " RW: " + partner.rw - - if partner.kelurahan_id: - lengkap += " Kel: " + partner.kelurahan_id.name + "," - - if partner.kecamatan_id: - lengkap += " Kec: " + partner.kecamatan_id.name - - if partner.kota_id: - lengkap += """ - """ + partner.kota_id.name + "," - - if partner.state_id: - lengkap += " " + partner.state_id.name - - partner.alamat_lengkap = lengkap.upper() - if partner.company_type == 'person' and not partner.parent_id: partner.alamat_lengkap_text = partner.street # if partner.company_type == 'person' and partner.parent_id: # partner.alamat_lengkap_text = partner.parent_id.alamat_lengkap_text - alamat_lengkap = fields.Char(string="Alamat Lengkap", required=False, compute="_alamat_lengkap") alamat_lengkap_text = fields.Text(string="Alamat Lengkap", required=False , tracking=3) def write(self, vals): -- cgit v1.2.3 From b34c5cc5d6cc3dc1e9ccf43cecc14a5a7a427992 Mon Sep 17 00:00:00 2001 From: Azka Nathan Date: Wed, 18 Sep 2024 11:02:51 +0700 Subject: change condition --- indoteknik_custom/models/account_move.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'indoteknik_custom/models') diff --git a/indoteknik_custom/models/account_move.py b/indoteknik_custom/models/account_move.py index a7010bbe..725b3c2d 100644 --- a/indoteknik_custom/models/account_move.py +++ b/indoteknik_custom/models/account_move.py @@ -174,7 +174,7 @@ class AccountMove(models.Model): def _compute_mark_upload_efaktur(self): for move in self: - if move.date_efaktur_exported or move.is_efaktur_exported or move.efaktur_document: + if move.efaktur_document: move.mark_upload_efaktur = 'sudah_upload' else: move.mark_upload_efaktur = 'belum_upload' -- cgit v1.2.3 From 95a65f3a543ca628b16acd5bc5e28d50e7cbe24c Mon Sep 17 00:00:00 2001 From: Azka Nathan Date: Thu, 19 Sep 2024 09:16:11 +0700 Subject: push --- indoteknik_custom/models/sale_order.py | 21 +++++++++++++++++---- 1 file changed, 17 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 bd0fb75e..1e9d3992 100755 --- a/indoteknik_custom/models/sale_order.py +++ b/indoteknik_custom/models/sale_order.py @@ -430,10 +430,22 @@ class SaleOrder(models.Model): # return [('id', 'not in', order_ids)] # return ['&', ('order_line.invoice_lines.move_id.move_type', 'in', ('out_invoice', 'out_refund')), ('order_line.invoice_lines.move_id', operator, value)] - @api.onchange('partner_shipping_id') - def onchange_partner_shipping(self): - self.real_shipping_id = self.partner_shipping_id - self.real_invoice_id = self.partner_invoice_id + + 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') @api.onchange('partner_id') def onchange_partner_contact(self): @@ -658,6 +670,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 c1d1b273e2eeb3c4713fe174846ec7687ec2026b Mon Sep 17 00:00:00 2001 From: it-fixcomart Date: Thu, 19 Sep 2024 09:57:39 +0700 Subject: update new register --- indoteknik_custom/models/res_partner.py | 3 ++- indoteknik_custom/models/user_company_request.py | 2 ++ 2 files changed, 4 insertions(+), 1 deletion(-) (limited to 'indoteknik_custom/models') diff --git a/indoteknik_custom/models/res_partner.py b/indoteknik_custom/models/res_partner.py index 7392b10d..ef857c55 100644 --- a/indoteknik_custom/models/res_partner.py +++ b/indoteknik_custom/models/res_partner.py @@ -18,7 +18,8 @@ class ResPartner(models.Model): ('pkp', 'PKP'), ('nonpkp', 'Non PKP') ]) - sppkp = fields.Char(string="SPPKP") + sppkp = fields.Char(string="SPPKP", tracking=3) + npwp = fields.Char(string="NPWP", tracking=3) 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/user_company_request.py b/indoteknik_custom/models/user_company_request.py index 56bb8d5d..40ac4446 100644 --- a/indoteknik_custom/models/user_company_request.py +++ b/indoteknik_custom/models/user_company_request.py @@ -33,10 +33,12 @@ class UserCompanyRequest(models.Model): self.user_id.property_account_receivable_id = self.user_company_id.property_account_receivable_id self.user_id.property_account_payable_id = self.user_company_id.property_account_payable_id self.user_company_id.active = True + # tambahkan send email kalau bisnis berhsil di buat else: new_company = self.env['res.partner'].create({ 'name': self.user_input }) self.user_id.parent_id = new_company.id + # tambahkan send email kalau bisnis ditolak di buat return super(UserCompanyRequest, self).write(vals) \ No newline at end of file -- cgit v1.2.3 From eb7661705303a64c97e84061b53d48d5c46f6293 Mon Sep 17 00:00:00 2001 From: it-fixcomart Date: Thu, 19 Sep 2024 15:08:15 +0700 Subject: add email user company request status --- indoteknik_custom/models/res_users.py | 19 ++++++++++++++++++- indoteknik_custom/models/user_company_request.py | 13 +++++++++++-- 2 files changed, 29 insertions(+), 3 deletions(-) (limited to 'indoteknik_custom/models') diff --git a/indoteknik_custom/models/res_users.py b/indoteknik_custom/models/res_users.py index 33f64ce3..cedf19bd 100755 --- a/indoteknik_custom/models/res_users.py +++ b/indoteknik_custom/models/res_users.py @@ -11,6 +11,8 @@ class ResUsers(models.Model): activation_token = fields.Char(string="Activation Token") otp_code = fields.Char(string='OTP Code') otp_create_date = fields.Datetime(string='OTP Create Date') + user_company_name = fields.Char(string="User Company Name") + def _generate_otp(self): for user in self: @@ -28,7 +30,22 @@ class ResUsers(models.Model): user._generate_otp() user._generate_activation_token() template.send_mail(user.id, force_send=True) - + + def send_company_request_mail(self): + template = self.env.ref('indoteknik_custom.mail_template_res_user_company_request') + for user in self: + template.send_mail(user.id, force_send=True) + + def send_company_request_approve_mail(self): + template = self.env.ref('indoteknik_custom.mail_template_res_user_company_request_approve') + for user in self: + template.send_mail(user.id, force_send=True) + + def send_company_request_reject_mail(self): + template = self.env.ref('indoteknik_custom.mail_template_res_user_company_request_reject') + for user in self: + template.send_mail(user.id, force_send=True) + def get_activation_token_url(self): base_url = self.env['ir.config_parameter'].get_param('site.base.url') return f'{base_url}/register?activation=token&token={self.activation_token}' diff --git a/indoteknik_custom/models/user_company_request.py b/indoteknik_custom/models/user_company_request.py index 40ac4446..8122c6a0 100644 --- a/indoteknik_custom/models/user_company_request.py +++ b/indoteknik_custom/models/user_company_request.py @@ -1,6 +1,6 @@ from odoo import models, fields from odoo.exceptions import UserError - +from odoo.http import request class UserCompanyRequest(models.Model): _name = 'user.company.request' @@ -15,6 +15,8 @@ class UserCompanyRequest(models.Model): ], string='Approval') def write(self, vals): + user = self.get_user_by_email(self.user_id.email) + user.user_company_name = self.user_input is_approve = vals.get('is_approve') if self.is_approve and is_approve: raise UserError('Tidak dapat mengubah approval yang sudah diisi') @@ -34,11 +36,18 @@ class UserCompanyRequest(models.Model): self.user_id.property_account_payable_id = self.user_company_id.property_account_payable_id self.user_company_id.active = True # tambahkan send email kalau bisnis berhsil di buat + user.send_company_request_approve_mail() else: new_company = self.env['res.partner'].create({ 'name': self.user_input }) self.user_id.parent_id = new_company.id # tambahkan send email kalau bisnis ditolak di buat + user.send_company_request_reject_mail() return super(UserCompanyRequest, self).write(vals) - \ No newline at end of file + + def get_user_by_email(self, email): + return request.env['res.users'].search([ + ('login', '=', email), + ('active', 'in', [True, False]) + ]) \ No newline at end of file -- cgit v1.2.3 From d2bb21ae878db2a3b77dbb3341046c9d12ba1de5 Mon Sep 17 00:00:00 2001 From: Azka Nathan Date: Fri, 20 Sep 2024 14:12:00 +0700 Subject: add grand total on dunning run and bill receipt --- indoteknik_custom/models/bill_receipt.py | 10 +++++++++- indoteknik_custom/models/dunning_run.py | 9 ++++++++- 2 files changed, 17 insertions(+), 2 deletions(-) (limited to 'indoteknik_custom/models') diff --git a/indoteknik_custom/models/bill_receipt.py b/indoteknik_custom/models/bill_receipt.py index 76449c1f..7d38d5ad 100644 --- a/indoteknik_custom/models/bill_receipt.py +++ b/indoteknik_custom/models/bill_receipt.py @@ -22,8 +22,16 @@ class BillReceipt(models.Model): resi_tukar_faktur = fields.Char(string='Resi Faktur') date_terima_tukar_faktur = fields.Date(string='Terima Faktur') shipper_faktur_id = fields.Many2one('delivery.carrier', string='Shipper Faktur') - is_validated = fields.Boolean(string='Validated') + is_validated = fields.Boolean(string='Validated') notification = fields.Char(string='Notification') + grand_total = fields.Float(string='Grand Total', compute="_compute_grand_total") + + def _compute_grand_total(self): + for record in self: + grand_total = 0 + for line in record.bill_line: + grand_total += line.total_amt + record.grand_total = grand_total def copy_date_faktur(self): if not self.is_validated: diff --git a/indoteknik_custom/models/dunning_run.py b/indoteknik_custom/models/dunning_run.py index 90159cd0..c167aab7 100644 --- a/indoteknik_custom/models/dunning_run.py +++ b/indoteknik_custom/models/dunning_run.py @@ -30,7 +30,14 @@ class DunningRun(models.Model): is_paid = fields.Boolean(string='Paid') description = fields.Char(string='Description') comment = fields.Char(string='Comment') - + grand_total = fields.Float(string='Grand Total', compute="_compute_grand_total") + + def _compute_grand_total(self): + for record in self: + grand_total = 0 + for line in record.dunning_line: + grand_total += line.total_amt + record.grand_total = grand_total def copy_date_faktur(self): if not self.is_validated: -- cgit v1.2.3 From a31294c9d1b66f3b63275c1ef20e0a068d6a1af0 Mon Sep 17 00:00:00 2001 From: it-fixcomart Date: Fri, 20 Sep 2024 15:33:51 +0700 Subject: update --- indoteknik_custom/models/res_users.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'indoteknik_custom/models') diff --git a/indoteknik_custom/models/res_users.py b/indoteknik_custom/models/res_users.py index d8eb348a..e339049d 100755 --- a/indoteknik_custom/models/res_users.py +++ b/indoteknik_custom/models/res_users.py @@ -12,7 +12,7 @@ class ResUsers(models.Model): otp_code = fields.Char(string='OTP Code') otp_create_date = fields.Datetime(string='OTP Create Date') payment_terms_id = fields.Many2one('account.payment.term', related='partner_id.property_payment_term_id', string='Payment Terms') - user_company_name = fields.Char(string="User Company Name") + user_company_name = fields.Char(string="User Company Name ") def _generate_otp(self): -- cgit v1.2.3 From cabac3c1d89beb6a86e58be820a06d85607c8313 Mon Sep 17 00:00:00 2001 From: it-fixcomart Date: Fri, 20 Sep 2024 15:42:00 +0700 Subject: update new register --- indoteknik_custom/models/res_users.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'indoteknik_custom/models') diff --git a/indoteknik_custom/models/res_users.py b/indoteknik_custom/models/res_users.py index e339049d..d8eb348a 100755 --- a/indoteknik_custom/models/res_users.py +++ b/indoteknik_custom/models/res_users.py @@ -12,7 +12,7 @@ class ResUsers(models.Model): otp_code = fields.Char(string='OTP Code') otp_create_date = fields.Datetime(string='OTP Create Date') payment_terms_id = fields.Many2one('account.payment.term', related='partner_id.property_payment_term_id', string='Payment Terms') - user_company_name = fields.Char(string="User Company Name ") + user_company_name = fields.Char(string="User Company Name") def _generate_otp(self): -- cgit v1.2.3 From 3f8fd250ee63ad4db48d45284f055bda641fec08 Mon Sep 17 00:00:00 2001 From: it-fixcomart Date: Fri, 20 Sep 2024 16:40:24 +0700 Subject: update new register user company namer --- indoteknik_custom/models/res_users.py | 1 - indoteknik_custom/models/users.py | 1 + 2 files changed, 1 insertion(+), 1 deletion(-) (limited to 'indoteknik_custom/models') diff --git a/indoteknik_custom/models/res_users.py b/indoteknik_custom/models/res_users.py index d8eb348a..5e16aad1 100755 --- a/indoteknik_custom/models/res_users.py +++ b/indoteknik_custom/models/res_users.py @@ -12,7 +12,6 @@ class ResUsers(models.Model): otp_code = fields.Char(string='OTP Code') otp_create_date = fields.Datetime(string='OTP Create Date') payment_terms_id = fields.Many2one('account.payment.term', related='partner_id.property_payment_term_id', string='Payment Terms') - user_company_name = fields.Char(string="User Company Name") def _generate_otp(self): diff --git a/indoteknik_custom/models/users.py b/indoteknik_custom/models/users.py index d95b56e7..981d787f 100644 --- a/indoteknik_custom/models/users.py +++ b/indoteknik_custom/models/users.py @@ -14,6 +14,7 @@ class Users(models.Model): is_admin_reconcile = fields.Boolean(string='Admin Reconcile', help='Berhak Mengedit Journal Reconcile') is_inbound = fields.Boolean(string='Operator Inbound') is_outbound = fields.Boolean(string='Operator Outbound') + user_company_name = fields.Char(string="User Company Name") def notify_internal_users(self, message, title): users = self.search([('share', '=', False)]) -- cgit v1.2.3 From 6c5d45e9062c6d5b2c3c3070a3d4eaead923c101 Mon Sep 17 00:00:00 2001 From: it-fixcomart Date: Fri, 20 Sep 2024 16:47:24 +0700 Subject: delete user company name --- indoteknik_custom/models/users.py | 1 - 1 file changed, 1 deletion(-) (limited to 'indoteknik_custom/models') diff --git a/indoteknik_custom/models/users.py b/indoteknik_custom/models/users.py index 981d787f..d95b56e7 100644 --- a/indoteknik_custom/models/users.py +++ b/indoteknik_custom/models/users.py @@ -14,7 +14,6 @@ class Users(models.Model): is_admin_reconcile = fields.Boolean(string='Admin Reconcile', help='Berhak Mengedit Journal Reconcile') is_inbound = fields.Boolean(string='Operator Inbound') is_outbound = fields.Boolean(string='Operator Outbound') - user_company_name = fields.Char(string="User Company Name") def notify_internal_users(self, message, title): users = self.search([('share', '=', False)]) -- cgit v1.2.3 From 3bb987d6dad51fb2b40d0ebec42c1143e8ee36ad Mon Sep 17 00:00:00 2001 From: it-fixcomart Date: Mon, 23 Sep 2024 09:28:45 +0700 Subject: update bug --- indoteknik_custom/models/user_company_request.py | 2 +- 1 file changed, 1 insertion(+), 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 8122c6a0..b02830bd 100644 --- a/indoteknik_custom/models/user_company_request.py +++ b/indoteknik_custom/models/user_company_request.py @@ -16,7 +16,7 @@ class UserCompanyRequest(models.Model): def write(self, vals): user = self.get_user_by_email(self.user_id.email) - user.user_company_name = self.user_input + user.parent_name = self.user_input is_approve = vals.get('is_approve') if self.is_approve and is_approve: raise UserError('Tidak dapat mengubah approval yang sudah diisi') -- cgit v1.2.3 From 5065ffb7c1dc7113e3d951c0f5a59f2268a88375 Mon Sep 17 00:00:00 2001 From: Azka Nathan Date: Mon, 23 Sep 2024 09:38:08 +0700 Subject: update code --- indoteknik_custom/models/approval_unreserve.py | 27 +++++++++++++++++++++++--- 1 file changed, 24 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 8c232d9c..51bd52d0 100644 --- a/indoteknik_custom/models/approval_unreserve.py +++ b/indoteknik_custom/models/approval_unreserve.py @@ -30,7 +30,7 @@ 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)]) + stock_move = self.env['stock.move'].search([('picking_id', '=', self.picking_id.id), ('state', '=', 'assigned')]) if not stock_move: raise ValidationError("Picking is not found") @@ -58,6 +58,8 @@ class ApprovalUnreserve(models.Model): if self.state != 'waiting_approval': raise UserError("Approval can only be done in 'Waiting for Approval' state") + + self.write({ 'state': 'approved', 'approved_by': self.env.user.id @@ -77,13 +79,31 @@ class ApprovalUnreserve(models.Model): }) def _trigger_unreserve(self): - # Get the related stock moves and perform the unreserve for approved lines stock_move_obj = self.env['stock.move'] + for line in self.approval_line: move = stock_move_obj.browse(line.move_id.id) - # Use the custom _do_unreserve method you defined earlier + + # Step 1: Unreserve the product from the current picking move._do_unreserve(product=line.product_id, quantity=line.unreserve_qty) + # Step 2: Reserve the product in the destination picking (dest_picking_id) + if line.dest_picking_id: + # Find or create the stock move for the destination picking + dest_move = stock_move_obj.create({ + 'product_id': line.product_id.id, + 'product_uom_qty': line.unreserve_qty, + 'picking_id': line.dest_picking_id.id, + 'name': line.product_id.name, + 'location_id': move.location_dest_id.id, # From the unreserved location + 'location_dest_id': line.dest_picking_id.location_id.id, # To the destination picking's location + 'state': 'draft' # Initial state, to be confirmed later + }) + + # Confirm and reserve the product in the new move + dest_move._action_confirm() # Confirm the move + dest_move._action_assign() # Reserve the product + class ApprovalUnreserveLine(models.Model): _name = 'approval.unreserve.line' _description = 'Approval Unreserve Line' @@ -93,3 +113,4 @@ class ApprovalUnreserveLine(models.Model): move_id = fields.Many2one('stock.move', string="Stock Move", required=True) product_id = fields.Many2one('product.product', string="Product", related='move_id.product_id', readonly=True) unreserve_qty = fields.Float(string="Quantity to Unreserve") + dest_picking_id = fields.Many2one('stock.picking', string="Destination Picking", tracking=True) -- cgit v1.2.3 From 5abf0ad2fb38fc2777fe04ab35bde1e81e0c6d38 Mon Sep 17 00:00:00 2001 From: it-fixcomart Date: Mon, 23 Sep 2024 10:10:57 +0700 Subject: update contact to not connect to child --- indoteknik_custom/models/user_company_request.py | 4 +--- 1 file changed, 1 insertion(+), 3 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 b02830bd..d540b0f6 100644 --- a/indoteknik_custom/models/user_company_request.py +++ b/indoteknik_custom/models/user_company_request.py @@ -35,14 +35,12 @@ class UserCompanyRequest(models.Model): self.user_id.property_account_receivable_id = self.user_company_id.property_account_receivable_id self.user_id.property_account_payable_id = self.user_company_id.property_account_payable_id self.user_company_id.active = True - # tambahkan send email kalau bisnis berhsil di buat user.send_company_request_approve_mail() else: new_company = self.env['res.partner'].create({ 'name': self.user_input }) - self.user_id.parent_id = new_company.id - # tambahkan send email kalau bisnis ditolak di buat + # self.user_id.parent_id = new_company.id user.send_company_request_reject_mail() return super(UserCompanyRequest, self).write(vals) -- cgit v1.2.3 From 1a50d80c1070f009d93d58f2ff469fbc3daa5623 Mon Sep 17 00:00:00 2001 From: Azka Nathan Date: Mon, 23 Sep 2024 10:27:11 +0700 Subject: push --- indoteknik_custom/models/approval_unreserve.py | 39 +++++++++++++++----------- 1 file changed, 22 insertions(+), 17 deletions(-) (limited to 'indoteknik_custom/models') diff --git a/indoteknik_custom/models/approval_unreserve.py b/indoteknik_custom/models/approval_unreserve.py index 51bd52d0..72e3ff51 100644 --- a/indoteknik_custom/models/approval_unreserve.py +++ b/indoteknik_custom/models/approval_unreserve.py @@ -82,27 +82,32 @@ class ApprovalUnreserve(models.Model): stock_move_obj = self.env['stock.move'] for line in self.approval_line: - move = stock_move_obj.browse(line.move_id.id) - # Step 1: Unreserve the product from the current picking + move = stock_move_obj.browse(line.move_id.id) move._do_unreserve(product=line.product_id, quantity=line.unreserve_qty) - # Step 2: Reserve the product in the destination picking (dest_picking_id) + # Step 2: Update existing stock move in dest_picking_id if line.dest_picking_id: - # Find or create the stock move for the destination picking - dest_move = stock_move_obj.create({ - 'product_id': line.product_id.id, - 'product_uom_qty': line.unreserve_qty, - 'picking_id': line.dest_picking_id.id, - 'name': line.product_id.name, - 'location_id': move.location_dest_id.id, # From the unreserved location - 'location_dest_id': line.dest_picking_id.location_id.id, # To the destination picking's location - 'state': 'draft' # Initial state, to be confirmed later - }) - - # Confirm and reserve the product in the new move - dest_move._action_confirm() # Confirm the move - dest_move._action_assign() # Reserve the product + dest_move = stock_move_obj.search([ + ('picking_id', '=', line.dest_picking_id.id), + ('product_id', '=', line.product_id.id), + ('state', 'not in', ['cancel', 'done']) # Only draft or assigned moves can be updated + ], limit=1) + + if dest_move: + # Add the unreserved quantity to the existing stock move + dest_move.write({ + 'product_uom_qty': dest_move.product_uom_qty + line.unreserve_qty + }) + + # If the move is in draft state, confirm it and reserve the product + if dest_move.state == 'draft': + dest_move._action_confirm() + dest_move._action_assign() # Reserve the product + + else: + # If no move is found, raise an error or handle accordingly + raise UserError(f"No stock move found for product {line.product_id.display_name} in the destination picking.") class ApprovalUnreserveLine(models.Model): _name = 'approval.unreserve.line' -- cgit v1.2.3 From b2f9da06ff526a005f7e71c85a4c626971b5c06b Mon Sep 17 00:00:00 2001 From: Azka Nathan Date: Mon, 23 Sep 2024 11:40:58 +0700 Subject: push --- indoteknik_custom/models/approval_unreserve.py | 42 ++++++++++++++------------ indoteknik_custom/models/stock_move.py | 9 +++--- 2 files changed, 27 insertions(+), 24 deletions(-) (limited to 'indoteknik_custom/models') diff --git a/indoteknik_custom/models/approval_unreserve.py b/indoteknik_custom/models/approval_unreserve.py index 72e3ff51..00fd1555 100644 --- a/indoteknik_custom/models/approval_unreserve.py +++ b/indoteknik_custom/models/approval_unreserve.py @@ -86,28 +86,30 @@ class ApprovalUnreserve(models.Model): move = stock_move_obj.browse(line.move_id.id) move._do_unreserve(product=line.product_id, quantity=line.unreserve_qty) + line.dest_picking_id.action_assign() + # Step 2: Update existing stock move in dest_picking_id - if line.dest_picking_id: - dest_move = stock_move_obj.search([ - ('picking_id', '=', line.dest_picking_id.id), - ('product_id', '=', line.product_id.id), - ('state', 'not in', ['cancel', 'done']) # Only draft or assigned moves can be updated - ], limit=1) - - if dest_move: - # Add the unreserved quantity to the existing stock move - dest_move.write({ - 'product_uom_qty': dest_move.product_uom_qty + line.unreserve_qty - }) + # if line.dest_picking_id: + # dest_move = stock_move_obj.search([ + # ('picking_id', '=', line.dest_picking_id.id), + # ('product_id', '=', line.product_id.id), + # ('state', 'not in', ['cancel', 'done']) # Only draft or assigned moves can be updated + # ], limit=1) + + # if dest_move: + # # Add the unreserved quantity to the existing stock move + # dest_move.write({ + # 'product_uom_qty': dest_move.product_uom_qty + line.unreserve_qty + # }) - # If the move is in draft state, confirm it and reserve the product - if dest_move.state == 'draft': - dest_move._action_confirm() - dest_move._action_assign() # Reserve the product - - else: - # If no move is found, raise an error or handle accordingly - raise UserError(f"No stock move found for product {line.product_id.display_name} in the destination picking.") + # # If the move is in draft state, confirm it and reserve the product + # if dest_move.state == 'draft': + # dest_move._action_confirm() + # dest_move._action_assign() # Reserve the product + + # else: + # # If no move is found, raise an error or handle accordingly + # raise UserError(f"No stock move found for product {line.product_id.display_name} in the destination picking.") class ApprovalUnreserveLine(models.Model): _name = 'approval.unreserve.line' diff --git a/indoteknik_custom/models/stock_move.py b/indoteknik_custom/models/stock_move.py index cd061946..32ef312f 100644 --- a/indoteknik_custom/models/stock_move.py +++ b/indoteknik_custom/models/stock_move.py @@ -19,17 +19,17 @@ class StockMove(models.Model): if product and move.product_id != product: continue # Skip moves that don't match the specified product moves_to_unreserve.add(move.id) - + moves_to_unreserve = self.env['stock.move'].browse(moves_to_unreserve) ml_to_update, ml_to_unlink = OrderedSet(), OrderedSet() moves_not_to_recompute = OrderedSet() - + for ml in moves_to_unreserve.move_line_ids: if product and ml.product_id != product: continue # Only affect the specified product - if quantity > 0: + if quantity is not None and quantity > 0: # Only reduce by the specified quantity if it is greater than zero ml_to_update.add(ml.id) remaining_qty = ml.product_uom_qty - quantity @@ -40,7 +40,7 @@ class StockMove(models.Model): else: ml_to_unlink.add(ml.id) moves_not_to_recompute.add(ml.move_id.id) - + ml_to_update, ml_to_unlink = self.env['stock.move.line'].browse(ml_to_update), self.env['stock.move.line'].browse(ml_to_unlink) moves_not_to_recompute = self.env['stock.move'].browse(moves_not_to_recompute) @@ -49,6 +49,7 @@ class StockMove(models.Model): return True + def _prepare_account_move_line_from_mr(self, po_line, qty, move=False): po_line.ensure_one() aml_currency = move and move.currency_id or po_line.currency_id -- cgit v1.2.3 From 1f9d0136758531831ea6c7a90556c9a472ed8d40 Mon Sep 17 00:00:00 2001 From: Azka Nathan Date: Mon, 23 Sep 2024 13:20:39 +0700 Subject: push --- indoteknik_custom/models/stock_move.py | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) (limited to 'indoteknik_custom/models') diff --git a/indoteknik_custom/models/stock_move.py b/indoteknik_custom/models/stock_move.py index 32ef312f..ac2e3cc0 100644 --- a/indoteknik_custom/models/stock_move.py +++ b/indoteknik_custom/models/stock_move.py @@ -8,7 +8,7 @@ class StockMove(models.Model): line_no = fields.Integer('No', default=0) sale_id = fields.Many2one('sale.order', string='SO') - def _do_unreserve(self, product=None, quantity=None): + def _do_unreserve(self, product=None, quantity=False): moves_to_unreserve = OrderedSet() for move in self: if move.state == 'cancel' or (move.state == 'done' and move.scrapped): @@ -19,17 +19,17 @@ class StockMove(models.Model): if product and move.product_id != product: continue # Skip moves that don't match the specified product moves_to_unreserve.add(move.id) - + moves_to_unreserve = self.env['stock.move'].browse(moves_to_unreserve) ml_to_update, ml_to_unlink = OrderedSet(), OrderedSet() moves_not_to_recompute = OrderedSet() - + for ml in moves_to_unreserve.move_line_ids: if product and ml.product_id != product: continue # Only affect the specified product - if quantity is not None and quantity > 0: + if quantity and quantity > 0: # Only reduce by the specified quantity if it is greater than zero ml_to_update.add(ml.id) remaining_qty = ml.product_uom_qty - quantity @@ -40,7 +40,7 @@ class StockMove(models.Model): else: ml_to_unlink.add(ml.id) moves_not_to_recompute.add(ml.move_id.id) - + ml_to_update, ml_to_unlink = self.env['stock.move.line'].browse(ml_to_update), self.env['stock.move.line'].browse(ml_to_unlink) moves_not_to_recompute = self.env['stock.move'].browse(moves_not_to_recompute) @@ -49,7 +49,6 @@ class StockMove(models.Model): return True - def _prepare_account_move_line_from_mr(self, po_line, qty, move=False): po_line.ensure_one() aml_currency = move and move.currency_id or po_line.currency_id -- cgit v1.2.3 From fb3ed255759edcbe8dfbdcedf0fb1f803aae2e4f Mon Sep 17 00:00:00 2001 From: Azka Nathan Date: Mon, 23 Sep 2024 15:31:38 +0700 Subject: cr sale order --- indoteknik_custom/models/sale_order.py | 1 - 1 file changed, 1 deletion(-) (limited to 'indoteknik_custom/models') diff --git a/indoteknik_custom/models/sale_order.py b/indoteknik_custom/models/sale_order.py index 86b3d50d..610d5126 100755 --- a/indoteknik_custom/models/sale_order.py +++ b/indoteknik_custom/models/sale_order.py @@ -670,7 +670,6 @@ 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 649f3037e4357dab42d1a8d799e5f2a2f1fd2e52 Mon Sep 17 00:00:00 2001 From: Azka Nathan Date: Mon, 23 Sep 2024 16:03:38 +0700 Subject: add tracking --- indoteknik_custom/models/sale_order.py | 24 +++++++++++++++++++++--- 1 file changed, 21 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 610d5126..3a28bc54 100755 --- a/indoteknik_custom/models/sale_order.py +++ b/indoteknik_custom/models/sale_order.py @@ -38,14 +38,14 @@ class SaleOrder(models.Model): have_outstanding_po = fields.Boolean('Have Outstanding PO', compute='_have_outstanding_po') purchase_ids = fields.Many2many('purchase.order', string='Purchases', compute='_get_purchases') real_shipping_id = fields.Many2one( - 'res.partner', string='Real Delivery Address', readonly=True, required=True, + 'res.partner', string='Real Delivery Address', readonly=True, states={'draft': [('readonly', False)], 'sent': [('readonly', False)], 'sale': [('readonly', False)]}, domain="['|', ('company_id', '=', False), ('company_id', '=', company_id)]", - help="Dipakai untuk alamat tempel") + help="Dipakai untuk alamat tempel", tracking=True) real_invoice_id = fields.Many2one( 'res.partner', string='Delivery Invoice Address', required=True, domain="['|', ('company_id', '=', False), ('company_id', '=', company_id)]", - help="Dipakai untuk alamat tempel") + help="Dipakai untuk alamat tempel", tracking=True) fee_third_party = fields.Float('Fee Pihak Ketiga') so_status = fields.Selection([ ('terproses', 'Terproses'), @@ -116,6 +116,21 @@ class SaleOrder(models.Model): percent_margin_after_delivery_purchase = fields.Float(string='% Margin After Delivery Purchase', compute='_compute_margin_after_delivery_purchase') purchase_delivery_amt = fields.Float(string='Purchase Delivery Amount', compute='_compute_purchase_delivery_amount') type_promotion = fields.Char(string='Type Promotion', compute='_compute_type_promotion') + partner_invoice_id = fields.Many2one( + 'res.partner', string='Invoice Address', + readonly=True, required=True, + states={'draft': [('readonly', False)], 'sent': [('readonly', False)], 'sale': [('readonly', False)]}, + domain="['|', ('company_id', '=', False), ('company_id', '=', company_id)]", + tracking=True, # Menambahkan tracking=True + ) + partner_shipping_id = fields.Many2one( + 'res.partner', string='Delivery Address', readonly=True, required=True, + states={'draft': [('readonly', False)], 'sent': [('readonly', False)], 'sale': [('readonly', False)]}, + domain="['|', ('company_id', '=', False), ('company_id', '=', company_id)]", tracking=True) + + payment_term_id = fields.Many2one( + 'account.payment.term', string='Payment Terms', check_company=True, # Unrequired company + domain="['|', ('company_id', '=', False), ('company_id', '=', company_id)]", tracking=True) def _compute_type_promotion(self): for rec in self: @@ -687,6 +702,9 @@ class SaleOrder(models.Model): if not order.commitment_date and order.create_date > datetime(2024, 9, 12): raise UserError("Expected Delivery Date kosong, wajib diisi") + if not order.real_shipping_id: + UserError('Real Delivery Address harus di isi') + if order.validate_partner_invoice_due(): return self._create_notification_action('Notification', 'Terdapat invoice yang telah melewati batas waktu, mohon perbarui pada dokumen Due Extension') -- cgit v1.2.3 From be5ae68ee9c9d55611cfbb8243feeee886bc95fd Mon Sep 17 00:00:00 2001 From: Azka Nathan Date: Tue, 24 Sep 2024 15:47:47 +0700 Subject: push --- indoteknik_custom/models/approval_unreserve.py | 24 ++++++++++++++++++++++-- 1 file changed, 22 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 00fd1555..e617e11a 100644 --- a/indoteknik_custom/models/approval_unreserve.py +++ b/indoteknik_custom/models/approval_unreserve.py @@ -50,8 +50,28 @@ class ApprovalUnreserve(models.Model): return super(ApprovalUnreserve, self).create(vals) def action_submit_for_approval(self): + self._check_product_and_qty() self.write({'state': 'waiting_approval'}) + + def _check_product_and_qty(self): + stock_move = self.env['stock.move'] + for line in self.approval_line: + if line.dest_picking_id: + move = stock_move.search([ + ('picking_id', '=', line.dest_picking_id.id), + ('product_id', '=', line.product_id.id), + ('state', 'not in', ['done', 'cancel']) + ]) + + if not move: + raise UserError("Product tidak ada di destination picking") + + qty_unreserve = line.unreserve_qty + move.forecast_availability + + if move.product_uom_qty < qty_unreserve: + raise UserError("Quantity yang di unreserve melebihi quantity yang ada") + def action_approve(self): if self.env.user.id != self.user_id.id: raise UserError("Hanya Sales nya yang bisa approve.") @@ -59,7 +79,6 @@ class ApprovalUnreserve(models.Model): if self.state != 'waiting_approval': raise UserError("Approval can only be done in 'Waiting for Approval' state") - self.write({ 'state': 'approved', 'approved_by': self.env.user.id @@ -86,7 +105,8 @@ class ApprovalUnreserve(models.Model): move = stock_move_obj.browse(line.move_id.id) move._do_unreserve(product=line.product_id, quantity=line.unreserve_qty) - line.dest_picking_id.action_assign() + if line.dest_picking_id: + line.dest_picking_id.action_assign() # Step 2: Update existing stock move in dest_picking_id # if line.dest_picking_id: -- cgit v1.2.3 From 733b749bb4979e0488b02da48b4116774945d6b5 Mon Sep 17 00:00:00 2001 From: Azka Nathan Date: Tue, 24 Sep 2024 15:54:12 +0700 Subject: add validation while create tax --- indoteknik_custom/models/__init__.py | 1 + indoteknik_custom/models/account_tax.py | 14 ++++++++++++++ 2 files changed, 15 insertions(+) create mode 100644 indoteknik_custom/models/account_tax.py (limited to 'indoteknik_custom/models') diff --git a/indoteknik_custom/models/__init__.py b/indoteknik_custom/models/__init__.py index ad7b1d09..4619147a 100755 --- a/indoteknik_custom/models/__init__.py +++ b/indoteknik_custom/models/__init__.py @@ -126,3 +126,4 @@ from . import sale_order_multi_uangmuka_penjualan from . import shipment_group from . import sales_order_reject from . import approval_date_doc +from . import account_tax diff --git a/indoteknik_custom/models/account_tax.py b/indoteknik_custom/models/account_tax.py new file mode 100644 index 00000000..e698d5ec --- /dev/null +++ b/indoteknik_custom/models/account_tax.py @@ -0,0 +1,14 @@ +from odoo import fields, models, api, _ +from odoo.exceptions import AccessError, UserError, ValidationError + +class AccountTax(models.Model): + _inherit = 'account.tax' + + @api.model + def create(self, vals): + 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 self.env.user.id not in users_in_group.mapped('id'): + raise UserError('Hanya IT yang bisa membuat tax') + result = super(AccountTax, self).create(vals) + return result \ No newline at end of file -- cgit v1.2.3 From 6cfbf125b6154a2dc0fe3aec6f433b94584c91fe Mon Sep 17 00:00:00 2001 From: Azka Nathan Date: Tue, 24 Sep 2024 16:47:43 +0700 Subject: cr account tax --- indoteknik_custom/models/account_tax.py | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'indoteknik_custom/models') diff --git a/indoteknik_custom/models/account_tax.py b/indoteknik_custom/models/account_tax.py index e698d5ec..e39546f2 100644 --- a/indoteknik_custom/models/account_tax.py +++ b/indoteknik_custom/models/account_tax.py @@ -11,4 +11,12 @@ class AccountTax(models.Model): if self.env.user.id not in users_in_group.mapped('id'): raise UserError('Hanya IT yang bisa membuat tax') result = super(AccountTax, self).create(vals) + return result + + def write(self, values): + 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 self.env.user.id not in users_in_group.mapped('id'): + raise UserError('Hanya IT yang bisa mengedit tax') + result = super(AccountTax, self).write(values) return result \ No newline at end of file -- cgit v1.2.3 From 8793cf3b8dea2c87024b4c9f49077cc8c6b982d8 Mon Sep 17 00:00:00 2001 From: Azka Nathan Date: Wed, 25 Sep 2024 10:08:00 +0700 Subject: cr stock_total_f --- indoteknik_custom/models/solr/apache_solr.py | 6 +++--- indoteknik_custom/models/solr/product_product.py | 2 +- indoteknik_custom/models/solr/product_template.py | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) (limited to 'indoteknik_custom/models') diff --git a/indoteknik_custom/models/solr/apache_solr.py b/indoteknik_custom/models/solr/apache_solr.py index 6560c9b5..f6b29cd8 100644 --- a/indoteknik_custom/models/solr/apache_solr.py +++ b/indoteknik_custom/models/solr/apache_solr.py @@ -70,7 +70,7 @@ class ApacheSolr(models.Model): stocks = self.env['stock.vendor'].search(query, limit=limit) documents = [] for stock in stocks: - stock_total = int(stock.product_variant_id.product_tmpl_id.qty_stock_vendor) + stock_total = int(stock.product_variant_id.product_tmpl_id.qty_available_bandengan) # dict_stock = dict({"set": stock_total}) document = { "id": int(stock.product_variant_id.product_tmpl_id.id), @@ -178,7 +178,7 @@ class ApacheSolr(models.Model): 'price_discount_f': price_excl_after_disc, 'tax_f': tax, 'variant_total_i': template.product_variant_count, - 'stock_total_f': template.qty_stock_vendor, + 'stock_total_f': template.qty_available_bandengan, 'weight_f': template.weight, 'manufacture_id_i': template.x_manufacture.id or 0, 'manufacture_name_s': template.x_manufacture.x_name or '', @@ -264,7 +264,7 @@ class ApacheSolr(models.Model): 'discount_f': discount, 'price_discount_f': price_excl_after_disc, 'tax_f': tax, - 'stock_total_f': variant.qty_stock_vendor, + 'stock_total_f': variant.qty_available_bandengan, 'weight_f': variant.product_tmpl_id.weight, 'manufacture_id_i': variant.product_tmpl_id.x_manufacture.id or 0, 'manufacture_name_s': variant.product_tmpl_id.x_manufacture.x_name or '', diff --git a/indoteknik_custom/models/solr/product_product.py b/indoteknik_custom/models/solr/product_product.py index 35e3a4b3..6864041e 100644 --- a/indoteknik_custom/models/solr/product_product.py +++ b/indoteknik_custom/models/solr/product_product.py @@ -58,7 +58,7 @@ class ProductProduct(models.Model): 'product_id_i': variant.id, 'template_id_i': variant.product_tmpl_id.id, 'image_s': ir_attachment.api_image('product.template', 'image_512', variant.product_tmpl_id.id), - 'stock_total_f': variant.qty_stock_vendor, + 'stock_total_f': variant.qty_available_bandengan, 'weight_f': variant.weight, 'manufacture_id_i': variant.product_tmpl_id.x_manufacture.id or 0, 'manufacture_name_s': variant.product_tmpl_id.x_manufacture.x_name or '', diff --git a/indoteknik_custom/models/solr/product_template.py b/indoteknik_custom/models/solr/product_template.py index d8dec47c..9cb27c5b 100644 --- a/indoteknik_custom/models/solr/product_template.py +++ b/indoteknik_custom/models/solr/product_template.py @@ -92,7 +92,7 @@ class ProductTemplate(models.Model): "product_id_i": template.id, "image_s": self.env['ir.attachment'].api_image('product.template', 'image_512', template.id), "variant_total_i": template.product_variant_count, - "stock_total_f": template.qty_stock_vendor, + "stock_total_f": template.qty_available_bandengan, "weight_f": template.weight, "manufacture_id_i": template.x_manufacture.id or 0, "manufacture_name_s": template.x_manufacture.x_name or '', -- cgit v1.2.3 From 41b8281f9e01d675d0078bbe131e41acc9a8c15a Mon Sep 17 00:00:00 2001 From: Azka Nathan Date: Wed, 25 Sep 2024 10:36:21 +0700 Subject: fix error --- indoteknik_custom/models/solr/apache_solr.py | 4 ++-- indoteknik_custom/models/solr/product_template.py | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) (limited to 'indoteknik_custom/models') diff --git a/indoteknik_custom/models/solr/apache_solr.py b/indoteknik_custom/models/solr/apache_solr.py index f6b29cd8..f04b5e84 100644 --- a/indoteknik_custom/models/solr/apache_solr.py +++ b/indoteknik_custom/models/solr/apache_solr.py @@ -70,7 +70,7 @@ class ApacheSolr(models.Model): stocks = self.env['stock.vendor'].search(query, limit=limit) documents = [] for stock in stocks: - stock_total = int(stock.product_variant_id.product_tmpl_id.qty_available_bandengan) + stock_total = int(stock.product_variant_id.product_tmpl_id.qty_stock_vendor) # dict_stock = dict({"set": stock_total}) document = { "id": int(stock.product_variant_id.product_tmpl_id.id), @@ -178,7 +178,7 @@ class ApacheSolr(models.Model): 'price_discount_f': price_excl_after_disc, 'tax_f': tax, 'variant_total_i': template.product_variant_count, - 'stock_total_f': template.qty_available_bandengan, + 'stock_total_f': template.qty_stock_vendor, 'weight_f': template.weight, 'manufacture_id_i': template.x_manufacture.id or 0, 'manufacture_name_s': template.x_manufacture.x_name or '', diff --git a/indoteknik_custom/models/solr/product_template.py b/indoteknik_custom/models/solr/product_template.py index 9cb27c5b..d8dec47c 100644 --- a/indoteknik_custom/models/solr/product_template.py +++ b/indoteknik_custom/models/solr/product_template.py @@ -92,7 +92,7 @@ class ProductTemplate(models.Model): "product_id_i": template.id, "image_s": self.env['ir.attachment'].api_image('product.template', 'image_512', template.id), "variant_total_i": template.product_variant_count, - "stock_total_f": template.qty_available_bandengan, + "stock_total_f": template.qty_stock_vendor, "weight_f": template.weight, "manufacture_id_i": template.x_manufacture.id or 0, "manufacture_name_s": template.x_manufacture.x_name or '', -- cgit v1.2.3 From 30efa28bf211ffefc181551df026047143939b4f Mon Sep 17 00:00:00 2001 From: Azka Nathan Date: Wed, 25 Sep 2024 11:32:20 +0700 Subject: solr fix --- indoteknik_custom/models/solr/apache_solr.py | 2 +- indoteknik_custom/models/solr/product_product.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'indoteknik_custom/models') diff --git a/indoteknik_custom/models/solr/apache_solr.py b/indoteknik_custom/models/solr/apache_solr.py index f04b5e84..6560c9b5 100644 --- a/indoteknik_custom/models/solr/apache_solr.py +++ b/indoteknik_custom/models/solr/apache_solr.py @@ -264,7 +264,7 @@ class ApacheSolr(models.Model): 'discount_f': discount, 'price_discount_f': price_excl_after_disc, 'tax_f': tax, - 'stock_total_f': variant.qty_available_bandengan, + 'stock_total_f': variant.qty_stock_vendor, 'weight_f': variant.product_tmpl_id.weight, 'manufacture_id_i': variant.product_tmpl_id.x_manufacture.id or 0, 'manufacture_name_s': variant.product_tmpl_id.x_manufacture.x_name or '', diff --git a/indoteknik_custom/models/solr/product_product.py b/indoteknik_custom/models/solr/product_product.py index 6864041e..35e3a4b3 100644 --- a/indoteknik_custom/models/solr/product_product.py +++ b/indoteknik_custom/models/solr/product_product.py @@ -58,7 +58,7 @@ class ProductProduct(models.Model): 'product_id_i': variant.id, 'template_id_i': variant.product_tmpl_id.id, 'image_s': ir_attachment.api_image('product.template', 'image_512', variant.product_tmpl_id.id), - 'stock_total_f': variant.qty_available_bandengan, + 'stock_total_f': variant.qty_stock_vendor, 'weight_f': variant.weight, 'manufacture_id_i': variant.product_tmpl_id.x_manufacture.id or 0, 'manufacture_name_s': variant.product_tmpl_id.x_manufacture.x_name or '', -- cgit v1.2.3 From 6c7c80b9cf3f4146af1fcfc4c9b24881a7b29b3c Mon Sep 17 00:00:00 2001 From: Azka Nathan Date: Wed, 25 Sep 2024 14:39:16 +0700 Subject: add price_tier to program line --- .../models/promotion/promotion_program_line.py | 22 ++++++++++++++++++++++ indoteknik_custom/models/purchase_pricelist.py | 8 ++++++++ indoteknik_custom/models/solr/product_template.py | 4 ++-- .../models/solr/promotion_program_line.py | 5 +++++ 4 files changed, 37 insertions(+), 2 deletions(-) (limited to 'indoteknik_custom/models') diff --git a/indoteknik_custom/models/promotion/promotion_program_line.py b/indoteknik_custom/models/promotion/promotion_program_line.py index a57f1f2c..903e95cf 100644 --- a/indoteknik_custom/models/promotion/promotion_program_line.py +++ b/indoteknik_custom/models/promotion/promotion_program_line.py @@ -34,6 +34,28 @@ class PromotionProgramLine(models.Model): active = fields.Boolean(string="Active", default=True) solr_flag = fields.Integer(string="Solr Flag", default=1) description = fields.Char('Description') + price_tier_1 = fields.Float('Price Tier 1') + price_tier_2 = fields.Float('Price Tier 2') + price_tier_3 = fields.Float('Price Tier 3') + price_tier_4 = fields.Float('Price Tier 4') + price_tier_5 = fields.Float('Price Tier 5') + + def get_price_tier(self, product_id, qty): + product = self.env['product.product'].browse(product_id.id) # Get the product record + + tiers = ['1_v2', '2_v2', '3_v2', '4_v2', '5_v2'] + + for index, tier in enumerate(tiers, start=1): # Automatically count from 1 to 5 + # Call the function _get_pricelist_tier from product.product model + price_tier_data = product._get_pricelist_tier(tier) + + # Use the index as the tier number (1, 2, 3, etc.) + price_field = f'price_tier_{index}' # 'price_tier_1', 'price_tier_2', etc. + + # Update the corresponding price_tier_X field + if price_field in self._fields: # Ensure the field exists in the model + price = price_tier_data.get(f'price_tier{tier}', 0) * qty # Multiply by qty + self[price_field] = price def get_active_promotions(self, product_id): current_time = datetime.now().strftime('%Y-%m-%d %H:%M:%S') diff --git a/indoteknik_custom/models/purchase_pricelist.py b/indoteknik_custom/models/purchase_pricelist.py index 68fb796e..b5f719cb 100755 --- a/indoteknik_custom/models/purchase_pricelist.py +++ b/indoteknik_custom/models/purchase_pricelist.py @@ -23,6 +23,14 @@ class PurchasePricelist(models.Model): brand_id = fields.Many2one('x_manufactures', string='Brand') count_brand_vendor = fields.Integer(string='Count Brand Vendor') is_winner = fields.Boolean(string='Winner', default=False, help='Pemenang yang direkomendasikan oleh Merchandise') + + @api.constrains('include_price') + def sync_pricelist_tier(self): + for rec in self: + promotion_product = self.env['promotion.product'].search([('product_id', '=', rec.product_id.id)]) + + for promotion in promotion_product: + promotion.program_line_id.get_price_tier(promotion.product_id, promotion.qty) @api.depends('product_id', 'vendor_id') def _compute_name(self): diff --git a/indoteknik_custom/models/solr/product_template.py b/indoteknik_custom/models/solr/product_template.py index d8dec47c..1eb6f31b 100644 --- a/indoteknik_custom/models/solr/product_template.py +++ b/indoteknik_custom/models/solr/product_template.py @@ -112,8 +112,8 @@ class ProductTemplate(models.Model): "description_clean_t": cleaned_desc or '', 'has_product_info_b': True, 'publish_b': not template.unpublished, - 'sni_b': template.unpublished, - 'tkdn_b': template.unpublished, + 'sni_b': template.sni, + 'tkdn_b': template.tkdn, "qty_sold_f": template.qty_sold, "is_in_bu_b": is_in_bu, "voucher_min_purchase_f" : voucher.min_purchase_amount or 0, diff --git a/indoteknik_custom/models/solr/promotion_program_line.py b/indoteknik_custom/models/solr/promotion_program_line.py index 3e3a2a28..64ad4209 100644 --- a/indoteknik_custom/models/solr/promotion_program_line.py +++ b/indoteknik_custom/models/solr/promotion_program_line.py @@ -53,6 +53,11 @@ class PromotionProgramLine(models.Model): 'package_limit_user_i': rec.package_limit_user, 'package_limit_trx_i': rec.package_limit_trx, 'price_f': rec.price, + 'price_tier_1_f': rec.price_tier_1, + 'price_tier_2_f': rec.price_tier_2, + 'price_tier_3_f': rec.price_tier_3, + 'price_tier_4_f': rec.price_tier_4, + 'price_tier_5_f': rec.price_tier_5, 'sequence_i': sequence_value, 'product_ids': [x.product_id.id for x in rec.product_ids], 'products_s': json.dumps(products), -- cgit v1.2.3 From ce4715289f52a5a1b39fdecc8bda40fbf88308a9 Mon Sep 17 00:00:00 2001 From: Azka Nathan Date: Wed, 25 Sep 2024 16:14:58 +0700 Subject: program line cr --- .../models/promotion/promotion_program_line.py | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) (limited to 'indoteknik_custom/models') diff --git a/indoteknik_custom/models/promotion/promotion_program_line.py b/indoteknik_custom/models/promotion/promotion_program_line.py index 903e95cf..7a15ad11 100644 --- a/indoteknik_custom/models/promotion/promotion_program_line.py +++ b/indoteknik_custom/models/promotion/promotion_program_line.py @@ -41,22 +41,23 @@ class PromotionProgramLine(models.Model): price_tier_5 = fields.Float('Price Tier 5') def get_price_tier(self, product_id, qty): - product = self.env['product.product'].browse(product_id.id) # Get the product record + product = self.env['product.product'].browse(product_id.id) tiers = ['1_v2', '2_v2', '3_v2', '4_v2', '5_v2'] - for index, tier in enumerate(tiers, start=1): # Automatically count from 1 to 5 - # Call the function _get_pricelist_tier from product.product model + for index, tier in enumerate(tiers, start=1): + price_tier_data = product._get_pricelist_tier(tier) - # Use the index as the tier number (1, 2, 3, etc.) - price_field = f'price_tier_{index}' # 'price_tier_1', 'price_tier_2', etc. + price_field = f'price_tier_{index}' - # Update the corresponding price_tier_X field - if price_field in self._fields: # Ensure the field exists in the model - price = price_tier_data.get(f'price_tier{tier}', 0) * qty # Multiply by qty + if price_field in self._fields: + price = price_tier_data.get(f'price_tier{tier}', 0) * qty self[price_field] = price + if index == 1: + self.price = price + def get_active_promotions(self, product_id): current_time = datetime.now().strftime('%Y-%m-%d %H:%M:%S') return self.search([ -- cgit v1.2.3 From 2638a9fbfe29520e5be0b88810208f5232aaac7b Mon Sep 17 00:00:00 2001 From: Azka Nathan Date: Thu, 26 Sep 2024 10:10:25 +0700 Subject: cr purchase pricelist --- indoteknik_custom/models/purchase_pricelist.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'indoteknik_custom/models') diff --git a/indoteknik_custom/models/purchase_pricelist.py b/indoteknik_custom/models/purchase_pricelist.py index b5f719cb..e5b35d7f 100755 --- a/indoteknik_custom/models/purchase_pricelist.py +++ b/indoteknik_custom/models/purchase_pricelist.py @@ -24,7 +24,6 @@ class PurchasePricelist(models.Model): count_brand_vendor = fields.Integer(string='Count Brand Vendor') is_winner = fields.Boolean(string='Winner', default=False, help='Pemenang yang direkomendasikan oleh Merchandise') - @api.constrains('include_price') def sync_pricelist_tier(self): for rec in self: promotion_product = self.env['promotion.product'].search([('product_id', '=', rec.product_id.id)]) @@ -119,5 +118,6 @@ class PurchasePricelist(models.Model): tier_prod_pricelist = self.env['product.pricelist.item'].search(product_domain + [('pricelist_id', '=', tier_pricelist.id)], limit=1) tier_prod_pricelist.price_discount = tier_perc + rec.sync_pricelist_tier() rec.product_id.product_tmpl_id._create_solr_queue('_sync_price_to_solr') \ No newline at end of file -- cgit v1.2.3 From 5e1a6dc4d2bb04a36fcaef023fb9894336ebd4f6 Mon Sep 17 00:00:00 2001 From: Azka Nathan Date: Thu, 26 Sep 2024 15:05:22 +0700 Subject: cr unreserve --- indoteknik_custom/models/approval_unreserve.py | 53 ++++++++++++++------------ 1 file changed, 28 insertions(+), 25 deletions(-) (limited to 'indoteknik_custom/models') diff --git a/indoteknik_custom/models/approval_unreserve.py b/indoteknik_custom/models/approval_unreserve.py index e617e11a..88409c37 100644 --- a/indoteknik_custom/models/approval_unreserve.py +++ b/indoteknik_custom/models/approval_unreserve.py @@ -24,6 +24,7 @@ class ApprovalUnreserve(models.Model): picking_id = fields.Many2one('stock.picking', string="Picking", tracking=True) user_id = fields.Many2one('res.users', string="User", readonly=True, tracking=True) rejection_reason = fields.Text(string="Rejection Reason", tracking=True) + reason = fields.Text(string="Reason", tracking=True) @api.constrains('picking_id') def create_move_id_line(self): @@ -99,38 +100,33 @@ class ApprovalUnreserve(models.Model): def _trigger_unreserve(self): stock_move_obj = self.env['stock.move'] - + for line in self.approval_line: - # Step 1: Unreserve the product from the current picking move = stock_move_obj.browse(line.move_id.id) move._do_unreserve(product=line.product_id, quantity=line.unreserve_qty) + original_sale_id = move.picking_id.sale_id + + product_name = line.product_id.display_name + unreserved_qty = line.unreserve_qty + if line.dest_picking_id: + dest_sale_id = line.dest_picking_id.sale_id line.dest_picking_id.action_assign() - # Step 2: Update existing stock move in dest_picking_id - # if line.dest_picking_id: - # dest_move = stock_move_obj.search([ - # ('picking_id', '=', line.dest_picking_id.id), - # ('product_id', '=', line.product_id.id), - # ('state', 'not in', ['cancel', 'done']) # Only draft or assigned moves can be updated - # ], limit=1) - - # if dest_move: - # # Add the unreserved quantity to the existing stock move - # dest_move.write({ - # 'product_uom_qty': dest_move.product_uom_qty + line.unreserve_qty - # }) - - # # If the move is in draft state, confirm it and reserve the product - # if dest_move.state == 'draft': - # dest_move._action_confirm() - # dest_move._action_assign() # Reserve the product - - # else: - # # If no move is found, raise an error or handle accordingly - # raise UserError(f"No stock move found for product {line.product_id.display_name} in the destination picking.") - + if original_sale_id: + message = ( + f"Barang {product_name} sebanyak {unreserved_qty} dipindahkan ke SO {dest_sale_id.name}" + if dest_sale_id else + f"Barang {product_name} sebanyak {unreserved_qty} dipindahkan ke picking tujuan." + ) + original_sale_id.message_post(body=message) + else: + if original_sale_id: + message = f"Barang {product_name} sebanyak {unreserved_qty} ter unreserve." + original_sale_id.message_post(body=message) + + class ApprovalUnreserveLine(models.Model): _name = 'approval.unreserve.line' _description = 'Approval Unreserve Line' @@ -139,5 +135,12 @@ class ApprovalUnreserveLine(models.Model): approval_id = fields.Many2one('approval.unreserve', string='Approval Reference', required=True, ondelete='cascade', index=True, copy=False) move_id = fields.Many2one('stock.move', string="Stock Move", required=True) product_id = fields.Many2one('product.product', string="Product", related='move_id.product_id', readonly=True) + sales_id = fields.Many2one('res.users', string="Sales", readonly=True, tracking=True) unreserve_qty = fields.Float(string="Quantity to Unreserve") dest_picking_id = fields.Many2one('stock.picking', string="Destination Picking", tracking=True) + + + @api.onchange('dest_picking_id') + def onchange_dest_picking_id(self): + if self.dest_picking_id: + self.sales_id = self.dest_picking_id.sale_id.user_id.id -- cgit v1.2.3 From e48193b793216a4ab82d88753ae144c08c3ddfaf Mon Sep 17 00:00:00 2001 From: Azka Nathan Date: Mon, 30 Sep 2024 14:04:23 +0700 Subject: estimated shipping price --- indoteknik_custom/models/sale_order.py | 48 +++++++++++++++++++++++++++++ indoteknik_custom/models/sale_order_line.py | 2 ++ 2 files changed, 50 insertions(+) (limited to 'indoteknik_custom/models') diff --git a/indoteknik_custom/models/sale_order.py b/indoteknik_custom/models/sale_order.py index 3a28bc54..798b9109 100755 --- a/indoteknik_custom/models/sale_order.py +++ b/indoteknik_custom/models/sale_order.py @@ -131,6 +131,54 @@ class SaleOrder(models.Model): payment_term_id = fields.Many2one( 'account.payment.term', string='Payment Terms', check_company=True, # Unrequired company domain="['|', ('company_id', '=', False), ('company_id', '=', company_id)]", tracking=True) + + def action_estimate_shipping(self): + total_weight = 0 + missing_weight_products = [] + + # Menghitung total berat dari Sale Order Line + 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) + + # Menampilkan pesan jika ada produk tanpa berat + if missing_weight_products: + self.message_post(body="Warning: Beberapa produk tidak memiliki berat: %s" % ', '.join(missing_weight_products)) + + if total_weight == 0: + raise UserError("Tidak dapat mengestimasi ongkir tanpa berat yang valid.") + + # Panggil API Raja Ongkir untuk mendapatkan estimasi ongkir + result = self._call_rajaongkir_api(total_weight) + if result: + estimated_cost = result['rajaongkir']['results'][0]['costs'][0]['cost'][0]['value'] + # Memasukkan hasil estimasi ke field delivery_amt + self.delivery_amt = estimated_cost + self.message_post(body=f"Estimasi Ongkos Kirim: {estimated_cost}") + else: + raise UserError("Gagal mendapatkan estimasi ongkir.") + + def _call_rajaongkir_api(self, total_weight): + url = 'https://pro.rajaongkir.com/api/cost' + headers = { + 'key': '7ac9883688da043b50cc32f0e3070bb6', + } + courier = self.carrier_id.name.lower() + origin = self.partner_shipping_id.city_id.state_id.code + destination = self.partner_shipping_id.city_id.state_id.code + data = { + 'origin': origin, # Contoh ID kota asal (Yogyakarta) + 'destination': destination, # Contoh ID kota tujuan (Jakarta) + 'weight': int(total_weight * 1000), # Menggunakan berat dalam gram + 'courier': courier, + } + response = requests.post(url, headers=headers, data=data) + if response.status_code == 200: + return response.json() + return None def _compute_type_promotion(self): for rec in self: diff --git a/indoteknik_custom/models/sale_order_line.py b/indoteknik_custom/models/sale_order_line.py index 50438dbe..0ea6a2cc 100644 --- a/indoteknik_custom/models/sale_order_line.py +++ b/indoteknik_custom/models/sale_order_line.py @@ -31,6 +31,7 @@ class SaleOrderLine(models.Model): qty_reserved = fields.Float(string='Qty Reserved', compute='_compute_qty_reserved') 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') @api.constrains('note_procurement') def note_procurement_to_apo(self): @@ -244,6 +245,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.weight = line.product_id.weight 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 ce74fd588cb8bf7cca770e0ac9717321e6b70ebe Mon Sep 17 00:00:00 2001 From: Azka Nathan Date: Mon, 30 Sep 2024 17:06:18 +0700 Subject: estimated price shipping --- indoteknik_custom/models/sale_order.py | 84 +++++++++++++++++++++++------ indoteknik_custom/models/sale_order_line.py | 2 +- 2 files changed, 68 insertions(+), 18 deletions(-) (limited to 'indoteknik_custom/models') diff --git a/indoteknik_custom/models/sale_order.py b/indoteknik_custom/models/sale_order.py index d0a34007..8f48e898 100755 --- a/indoteknik_custom/models/sale_order.py +++ b/indoteknik_custom/models/sale_order.py @@ -137,49 +137,100 @@ class SaleOrder(models.Model): total_weight = 0 missing_weight_products = [] - # Menghitung total berat dari Sale Order Line for line in self.order_line: if line.weight: - total_weight += line.weight * line.product_uom_qty - line.product_id.weight = line.weight + total_weight += line.weight else: missing_weight_products.append(line.product_id.name) - # Menampilkan pesan jika ada produk tanpa berat - if missing_weight_products: - self.message_post(body="Warning: Beberapa produk tidak memiliki berat: %s" % ', '.join(missing_weight_products)) - if total_weight == 0: raise UserError("Tidak dapat mengestimasi ongkir tanpa berat yang valid.") - # Panggil API Raja Ongkir untuk mendapatkan estimasi ongkir - result = self._call_rajaongkir_api(total_weight) + # 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) + + if not origin_city_id or not destination_city_id: + raise UserError("Gagal mendapatkan ID kota asal atau tujuan.") + + result = self._call_rajaongkir_api(total_weight, origin_city_id, destination_city_id) if result: estimated_cost = result['rajaongkir']['results'][0]['costs'][0]['cost'][0]['value'] - # Memasukkan hasil estimasi ke field delivery_amt self.delivery_amt = estimated_cost self.message_post(body=f"Estimasi Ongkos Kirim: {estimated_cost}") else: raise UserError("Gagal mendapatkan estimasi ongkir.") - def _call_rajaongkir_api(self, total_weight): + def _call_rajaongkir_api(self, total_weight, origin_city_id, destination_city_id): url = 'https://pro.rajaongkir.com/api/cost' headers = { 'key': '7ac9883688da043b50cc32f0e3070bb6', } courier = self.carrier_id.name.lower() - origin = self.partner_shipping_id.city_id.state_id.code - destination = self.partner_shipping_id.city_id.state_id.code + data = { - 'origin': origin, # Contoh ID kota asal (Yogyakarta) - 'destination': destination, # Contoh ID kota tujuan (Jakarta) - 'weight': int(total_weight * 1000), # Menggunakan berat dalam gram + 'origin': int(origin_city_id), + 'originType': 'city', + 'destination': int(destination_city_id), + 'destinationType': 'city', + 'weight': int(total_weight * 1000), 'courier': courier, } + response = requests.post(url, headers=headers, data=data) if response.status_code == 200: return response.json() 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 + + def _get_city_id_by_name(self, city_name): + url = 'https://pro.rajaongkir.com/api/city' + headers = { + 'key': '7ac9883688da043b50cc32f0e3070bb6', + } + + # Normalisasi nama kota sebelum melakukan pencarian + normalized_city_name = self._normalize_city_name(city_name) + + response = requests.get(url, headers=headers) + if response.status_code == 200: + city_data = response.json() + for city in city_data['rajaongkir']['results']: + if city['city_name'].lower() == normalized_city_name: + return city['city_id'] + return None + + 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', + } + + 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(): + return subdistrict['subdistrict_id'] + return None + def _compute_type_promotion(self): for rec in self: @@ -189,7 +240,6 @@ class SaleOrder(models.Model): if line_program.promotion_type: promotion_types.append(dict(line_program._fields['promotion_type'].selection).get(line_program.promotion_type)) - # Removing duplicates by converting to a set, then back to a list rec.type_promotion = ', '.join(sorted(set(promotion_types))) def _compute_purchase_delivery_amount(self): diff --git a/indoteknik_custom/models/sale_order_line.py b/indoteknik_custom/models/sale_order_line.py index 0ea6a2cc..d1dcd0af 100644 --- a/indoteknik_custom/models/sale_order_line.py +++ b/indoteknik_custom/models/sale_order_line.py @@ -245,7 +245,6 @@ 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.weight = line.product_id.weight line.tax_id = line.order_id.sales_tax_id # price, taxes = line._get_valid_purchase_price(purchase_price) line.purchase_price = price @@ -259,6 +258,7 @@ class SaleOrderLine(models.Model): ('(' + attribute_values_str + ')' if attribute_values_str else '') + ' ' + \ (line.product_id.short_spesification if line.product_id.short_spesification else '') line.name = line_name + line.weight = line.product_id.weight def compute_delivery_amt_line(self): for line in self: -- cgit v1.2.3 From eeea51a3ba88623437774b3c568d78c487f7ca5d Mon Sep 17 00:00:00 2001 From: Azka Nathan Date: Tue, 1 Oct 2024 11:36:09 +0700 Subject: cr website user cart add price, phone and promotion product --- indoteknik_custom/models/website_user_cart.py | 22 +++++++++++++++++++++- 1 file changed, 21 insertions(+), 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 b0cf47f7..0e245748 100644 --- a/indoteknik_custom/models/website_user_cart.py +++ b/indoteknik_custom/models/website_user_cart.py @@ -1,4 +1,4 @@ -from odoo import fields, models +from odoo import fields, models, api from datetime import datetime, timedelta class WebsiteUserCart(models.Model): @@ -16,6 +16,26 @@ class WebsiteUserCart(models.Model): ], 'Source', default='add_to_cart') user_other_carts = fields.One2many('website.user.cart', 'id', 'Other Products', compute='_compute_user_other_carts') is_reminder = fields.Boolean(string='Reminder?') + phone_user = fields.Char(string='Phone', related='user_id.mobile') + price = fields.Float(string='Price', compute='_compute_price') + program_product_id = fields.Many2one('product.product', string='Program Products', compute='_compute_program_product_ids') + + @api.depends('program_line_id') + def _compute_program_product_ids(self): + for record in self: + if record.program_line_id and record.program_line_id.product_ids: + product = record.program_line_id.product_ids[0] + record.program_product_id = product.product_id + record.product_id = product.product_id + else: + # Handle case where there are no product_ids + record.program_product_id = False + + def _compute_price(self): + for record in self: + record.price = record.product_id.v2_api_single_response(record.product_id)['price']['price_discount'] + if record.program_line_id: + record.price = record.get_price_coret(record.program_line_id.id) def _compute_user_other_carts(self): for record in self: -- cgit v1.2.3 From 9da8f3d5b2bd966bf873d8d760b179ba41f26542 Mon Sep 17 00:00:00 2001 From: Azka Nathan Date: Tue, 1 Oct 2024 14:59:28 +0700 Subject: fix bug 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 0e245748..169f4a6b 100644 --- a/indoteknik_custom/models/website_user_cart.py +++ b/indoteknik_custom/models/website_user_cart.py @@ -33,7 +33,7 @@ class WebsiteUserCart(models.Model): def _compute_price(self): for record in self: - record.price = record.product_id.v2_api_single_response(record.product_id)['price']['price_discount'] + record.price = record.get_price_website(record.product_id.id)['price'] if record.program_line_id: record.price = record.get_price_coret(record.program_line_id.id) -- cgit v1.2.3 From 14fe99d8cfa175cf959d0ec35660b47493955228 Mon Sep 17 00:00:00 2001 From: Azka Nathan Date: Tue, 1 Oct 2024 15:36:03 +0700 Subject: cr due extension --- indoteknik_custom/models/account_move_due_extension.py | 2 ++ 1 file changed, 2 insertions(+) (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 0399c6a2..23f8888c 100644 --- a/indoteknik_custom/models/account_move_due_extension.py +++ b/indoteknik_custom/models/account_move_due_extension.py @@ -96,6 +96,8 @@ class DueExtension(models.Model): sales.action_confirm() self.order_id.due_id = self.id + template = self.env.ref('indoteknik_custom.mail_template_due_extension_approve') + template.send_mail(self.id, force_send=True) def generate_due_line(self): partners = self.partner_id.get_child_ids() -- cgit v1.2.3 From e909d345ecd58d933e7236d45b6994512c601748 Mon Sep 17 00:00:00 2001 From: it-fixcomart Date: Tue, 1 Oct 2024 17:07:00 +0700 Subject: update jika efaktur BP nya diubah maka child efakturnya juga berubah --- indoteknik_custom/models/res_partner.py | 53 ++++++++++++++++++++++++++++----- 1 file changed, 46 insertions(+), 7 deletions(-) (limited to 'indoteknik_custom/models') diff --git a/indoteknik_custom/models/res_partner.py b/indoteknik_custom/models/res_partner.py index ef857c55..2846c14b 100644 --- a/indoteknik_custom/models/res_partner.py +++ b/indoteknik_custom/models/res_partner.py @@ -85,15 +85,54 @@ class ResPartner(models.Model): # return res - # def write(self, vals): - # if self.company_type == 'person': + def write(self, vals): + # Fungsi rekursif untuk meng-update semua child, termasuk child dari child + def update_children_recursively(partner, vals_for_child): + # Lakukan update pada partner saat ini hanya dengan field yang diizinkan + partner.write(vals_for_child) + + # Untuk setiap child dari partner ini, update juga child-nya + for child in partner.child_ids: + update_children_recursively(child, vals_for_child) + + # Jika self tidak memiliki parent_id, artinya self adalah parent + if not self.parent_id: + # Ambil semua child dari parent ini + children = self.child_ids + + # Perbarui vals dengan nilai dari parent jika tidak ada dalam vals + vals['customer_type'] = vals.get('customer_type', self.customer_type) + vals['nama_wajib_pajak'] = vals.get('nama_wajib_pajak', self.nama_wajib_pajak) + vals['npwp'] = vals.get('npwp', self.npwp) + vals['sppkp'] = vals.get('sppkp', self.sppkp) + vals['alamat_lengkap_text'] = vals.get('alamat_lengkap_text', self.alamat_lengkap_text) + vals['industry_id'] = vals.get('industry_id', self.industry_id.id if self.industry_id else None) + vals['company_type_id'] = vals.get('company_type_id', + self.company_type_id.id if self.company_type_id else None) + + # Simpan hanya field yang perlu di-update pada child + vals_for_child = { + 'customer_type': vals.get('customer_type'), + 'nama_wajib_pajak': vals.get('nama_wajib_pajak'), + 'npwp': vals.get('npwp'), + 'sppkp': vals.get('sppkp'), + 'alamat_lengkap_text': vals.get('alamat_lengkap_text'), + 'industry_id': vals.get('industry_id'), + 'company_type_id': vals.get('company_type_id') + } + + # Lakukan update pada semua child secara rekursif + for child in children: + update_children_recursively(child, vals_for_child) + + # Lakukan write untuk parent dengan vals asli + res = super(ResPartner, self).write(vals) + + return res + + # if self.company_type == 'person' and not partner.parent_id: # if self.parent_id: # parent = self.parent_id - # vals['customer_type'] = parent.customer_type - # vals['nama_wajib_pajak'] = parent.nama_wajib_pajak - # vals['npwp'] = parent.npwp - # vals['sppkp'] = parent.sppkp - # vals['alamat_lengkap_text'] = parent.alamat_lengkap_text # vals['industry_id'] = parent.industry_id.id # vals['company_type_id'] = parent.company_type_id.id # -- cgit v1.2.3