From 6850fd6f86a0fbba3156e59f9ac5836052f019ce Mon Sep 17 00:00:00 2001 From: Azka Nathan Date: Thu, 22 Feb 2024 14:48:01 +0700 Subject: master data commision % and reserved from by forcasted --- indoteknik_custom/__manifest__.py | 1 + indoteknik_custom/models/__init__.py | 2 + indoteknik_custom/models/commision.py | 19 +++++++-- indoteknik_custom/models/cust_commision.py | 25 ++++++++++++ .../models/report_stock_forecasted.py | 45 ++++++++++++++++++++++ indoteknik_custom/models/sale_order.py | 1 + indoteknik_custom/models/sale_order_line.py | 36 +++++++++++++++++ indoteknik_custom/security/ir.model.access.csv | 2 + indoteknik_custom/views/cust_commision.xml | 44 +++++++++++++++++++++ indoteknik_custom/views/purchase_order.xml | 2 +- indoteknik_custom/views/sale_order.xml | 3 +- 11 files changed, 175 insertions(+), 5 deletions(-) create mode 100644 indoteknik_custom/models/cust_commision.py create mode 100644 indoteknik_custom/models/report_stock_forecasted.py create mode 100644 indoteknik_custom/views/cust_commision.xml diff --git a/indoteknik_custom/__manifest__.py b/indoteknik_custom/__manifest__.py index 9c505916..c2170579 100755 --- a/indoteknik_custom/__manifest__.py +++ b/indoteknik_custom/__manifest__.py @@ -112,6 +112,7 @@ 'views/report_logbook_sj.xml', 'views/role_permission/ir_model_access.xml', 'views/role_permission/res_groups.xml', + 'views/cust_commision.xml', 'report/report.xml', 'report/report_banner_banner.xml', 'report/report_banner_banner2.xml', diff --git a/indoteknik_custom/models/__init__.py b/indoteknik_custom/models/__init__.py index 327da2d5..f8ff34d9 100755 --- a/indoteknik_custom/models/__init__.py +++ b/indoteknik_custom/models/__init__.py @@ -102,3 +102,5 @@ from . import po_multi_cancel from . import logbook_sj from . import report_logbook_sj from . import role_permission +from . import cust_commision +from . import report_stock_forecasted diff --git a/indoteknik_custom/models/commision.py b/indoteknik_custom/models/commision.py index 955d1634..fe65de84 100644 --- a/indoteknik_custom/models/commision.py +++ b/indoteknik_custom/models/commision.py @@ -156,7 +156,17 @@ class CustomerCommision(models.Model): # add status for type of commision, fee, rebate / cashback # include child or not? - @api.constrains('commision_percent') + @api.constrains('partner_ids') + def _onchange_partner_ids(self): + commision = self.env['cust.commision'].search([ + ('partner_id', 'in', [rec.id for rec in self.partner_ids]), + ]) + + if commision: + max_commision = max(commision.mapped('commision_percent')) + self.commision_percent = max_commision + + # @api.constrains('commision_percent', 'partner_ids') def _onchange_commision_percent(self): print('masuk onchange commision percent') if self.commision_amt == 0: @@ -165,8 +175,8 @@ class CustomerCommision(models.Model): @api.constrains('commision_amt') def _onchange_commision_amt(self): print('masuk onchange commision amt') - if self.commision_percent == 0: - self.commision_percent = (self.commision_amt / self.total_dpp * 100) + if self.total_dpp > 0: + self.commision_percent = (self.commision_amt / self.total_dpp) * 100 def _compute_total_dpp(self): for data in self: @@ -208,6 +218,9 @@ class CustomerCommision(models.Model): else: self._generate_customer_commision_rebate() + self._onchange_commision_percent() + self._onchange_commision_amt() + def _generate_customer_commision_rebate(self): for rec in self: # partners = rec.partner_ids.child_ids + rec.partner_ids diff --git a/indoteknik_custom/models/cust_commision.py b/indoteknik_custom/models/cust_commision.py new file mode 100644 index 00000000..eeb255cd --- /dev/null +++ b/indoteknik_custom/models/cust_commision.py @@ -0,0 +1,25 @@ +from odoo import models, api, fields +from odoo.exceptions import UserError +from datetime import datetime +import logging + +_logger = logging.getLogger(__name__) + + +class CustCommision(models.Model): + _name = 'cust.commision' + _order = 'id desc' + + partner_id = fields.Many2one('res.partner', String='Customer', required=True) + commision_percent = fields.Float(string='Commision %', tracking=3) + + @api.constrains('partner_id') + def _check_partner_id(self): + for rec in self: + duplicate_partner = self.search([ + ('partner_id', '=', rec.partner_id.id), + ('id', '!=', rec.id) + ]) + if duplicate_partner: + raise UserError('Partner already exists') + \ No newline at end of file diff --git a/indoteknik_custom/models/report_stock_forecasted.py b/indoteknik_custom/models/report_stock_forecasted.py new file mode 100644 index 00000000..48a17095 --- /dev/null +++ b/indoteknik_custom/models/report_stock_forecasted.py @@ -0,0 +1,45 @@ +from odoo import api, models + +class ReplenishmentReport(models.AbstractModel): + _inherit = 'report.stock.report_product_product_replenishment' + + @api.model + def _get_report_lines(self, product_template_ids, product_variant_ids, wh_location_ids): + lines = super(ReplenishmentReport, self)._get_report_lines(product_template_ids, product_variant_ids, wh_location_ids) + + result_dict = {} + + for line in lines: + product_id = line.get('product', {}).get('id') + query = [('product_id', '=', product_id)] + document_out = line.get('document_out') + order_id = document_out.id if document_out else None + + if order_id: + result = self._calculate_result(line) + result_dict.setdefault(order_id, []).append(result) + + for order_id, results in result_dict.items(): + sale_order_lines = self.env['sale.order.line'].search([('order_id', '=', order_id)]) + + concatenated_result = ' ,'.join(results) + + for sale_order_line in sale_order_lines: + sale_order_line.reserved_from = concatenated_result + + return lines + + def _calculate_result(self, line): + if line['document_in']: + return str(line["document_in"].name) + elif line['reservation'] and not line['document_in']: + return 'Reserved from stock' + elif line['replenishment_filled']: + if line['document_out']: + return 'Inventory On Hand' + else: + return 'Free Stock' + else: + return 'Not Available' + + diff --git a/indoteknik_custom/models/sale_order.py b/indoteknik_custom/models/sale_order.py index 24c642d9..4176a464 100755 --- a/indoteknik_custom/models/sale_order.py +++ b/indoteknik_custom/models/sale_order.py @@ -451,6 +451,7 @@ class SaleOrder(models.Model): order.approval_status = 'approved' order._set_sppkp_npwp_contact() order.calculate_line_no() + # order.order_line.get_reserved_from() res = super(SaleOrder, self).action_confirm() return res diff --git a/indoteknik_custom/models/sale_order_line.py b/indoteknik_custom/models/sale_order_line.py index 62f4a6b4..a140468c 100644 --- a/indoteknik_custom/models/sale_order_line.py +++ b/indoteknik_custom/models/sale_order_line.py @@ -29,6 +29,32 @@ class SaleOrderLine(models.Model): vendor_subtotal = fields.Float(string='Vendor Subtotal', compute="_compute_vendor_subtotal") amount_voucher_disc = fields.Float(string='Voucher Discount') qty_reserved = fields.Float(string='Qty Reserved', compute='_compute_qty_reserved') + reserved_from = fields.Char(string='Reserved From', copy=False) + + # def get_reserved_from(self): + # for line in self: + # current_stock = self.env['stock.quant'].search([ + # ('product_id', '=', line.product_id.id), + # ('location_id', '=', line.order_id.warehouse_id.lot_stock_id.id) + # ]) + + # po_stock = self.env['purchase.order.line'].search([ + # ('product_id', '=', line.product_id.id), + # ('order_id.sale_order_id', '=', line.order_id.id), + # ('state', '=', 'done') + # ]) + + # available_quantity = current_stock.available_quantity if current_stock else 0 + # product_qty = po_stock.product_qty if po_stock else 0 + + # if available_quantity >= line.product_uom_qty: + # line.reserved_from = 'From Stock' + # elif product_qty >= line.product_uom_qty: + # line.reserved_from = 'From PO' + # elif (available_quantity + product_qty) >= line.product_uom_qty: + # line.reserved_from = 'From Stock and PO' + # else: + # line.reserved_from = None def _compute_qty_reserved(self): for line in self: @@ -41,6 +67,16 @@ class SaleOrderLine(models.Model): reserved_qty = sum(move.product_uom_qty for move in stock_moves) line.qty_reserved = reserved_qty + if reserved_qty > 0: + line._compute_reserved_from() + + + def _compute_reserved_from(self): + for line in self: + # continue + report_stock_forecasted = self.env['report.stock.report_product_product_replenishment'] + report_stock_forecasted._get_report_data(False, [line.product_id.id]) + def _compute_vendor_subtotal(self): for line in self: if line.purchase_price > 0 and line.product_uom_qty > 0: diff --git a/indoteknik_custom/security/ir.model.access.csv b/indoteknik_custom/security/ir.model.access.csv index 31503dbe..4f167b6d 100755 --- a/indoteknik_custom/security/ir.model.access.csv +++ b/indoteknik_custom/security/ir.model.access.csv @@ -94,3 +94,5 @@ access_logbook_sj,access.logbook.sj,model_logbook_sj,,1,1,1,1 access_logbook_sj_line,access.logbook.sj.line,model_logbook_sj_line,,1,1,1,1 access_report_logbook_sj,access.report.logbook.sj,model_report_logbook_sj,,1,1,1,1 access_report_logbook_sj_line,access.report.logbook.sj.line,model_report_logbook_sj_line,,1,1,1,1 +access_cust_commision,access.cust.commision,model_cust_commision,,1,1,1,1 +access_report_stock_report_product_product_replenishment,access.report.stock.report_product_product_replenishment,model_report_stock_report_product_product_replenishment,,1,1,1,1 diff --git a/indoteknik_custom/views/cust_commision.xml b/indoteknik_custom/views/cust_commision.xml new file mode 100644 index 00000000..dfa4adfb --- /dev/null +++ b/indoteknik_custom/views/cust_commision.xml @@ -0,0 +1,44 @@ + + + + cust.commision.tree + cust.commision + + + + + + + + + + cust.commision.form + cust.commision + +
+ + + + + + + + +
+
+
+ + + Commision + ir.actions.act_window + cust.commision + tree,form + + + +
\ No newline at end of file diff --git a/indoteknik_custom/views/purchase_order.xml b/indoteknik_custom/views/purchase_order.xml index a6f28ffa..c7fdfcc3 100755 --- a/indoteknik_custom/views/purchase_order.xml +++ b/indoteknik_custom/views/purchase_order.xml @@ -102,7 +102,7 @@ - {'readonly': [('is_edit_product_qty', '=', False)], 'required': True} + {'required': True} diff --git a/indoteknik_custom/views/sale_order.xml b/indoteknik_custom/views/sale_order.xml index 4c4ac281..bff2fe33 100755 --- a/indoteknik_custom/views/sale_order.xml +++ b/indoteknik_custom/views/sale_order.xml @@ -109,7 +109,8 @@ - + + {'no_create': True} -- cgit v1.2.3 From 6887a85d0e5aa30b6274360480eeac544a97248b Mon Sep 17 00:00:00 2001 From: Azka Nathan Date: Sat, 24 Feb 2024 11:22:46 +0700 Subject: fix add a note on so --- indoteknik_custom/views/sale_order.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/indoteknik_custom/views/sale_order.xml b/indoteknik_custom/views/sale_order.xml index bff2fe33..2f800e34 100755 --- a/indoteknik_custom/views/sale_order.xml +++ b/indoteknik_custom/views/sale_order.xml @@ -115,9 +115,9 @@ {'no_create': True} - +