diff options
| author | Azka Nathan <darizkyfaz@gmail.com> | 2024-03-25 13:07:44 +0700 |
|---|---|---|
| committer | Azka Nathan <darizkyfaz@gmail.com> | 2024-03-25 13:07:44 +0700 |
| commit | b2377426bec8aa334277aac48b0b25f0dfac420f (patch) | |
| tree | 49c6a042e0fe29295231b1d409d705a92ddbfc03 | |
| parent | a05da3fad1855cbf2ce4cc7645f1fda79cae037c (diff) | |
purchasing job feedback
| -rwxr-xr-x | indoteknik_custom/models/__init__.py | 1 | ||||
| -rw-r--r-- | indoteknik_custom/models/automatic_purchase.py | 13 | ||||
| -rwxr-xr-x | indoteknik_custom/models/purchase_order.py | 58 | ||||
| -rw-r--r-- | indoteknik_custom/models/purchasing_job.py | 46 | ||||
| -rw-r--r-- | indoteknik_custom/models/purchasing_job_multi_update.py | 29 | ||||
| -rw-r--r-- | indoteknik_custom/models/purchasing_job_state.py | 17 | ||||
| -rw-r--r-- | indoteknik_custom/models/sale_order_line.py | 2 | ||||
| -rw-r--r-- | indoteknik_custom/models/sales_order_fullfillment.py | 13 | ||||
| -rwxr-xr-x | indoteknik_custom/security/ir.model.access.csv | 3 | ||||
| -rw-r--r-- | indoteknik_custom/views/purchasing_job.xml | 2 | ||||
| -rwxr-xr-x | indoteknik_custom/views/sale_order.xml | 3 |
11 files changed, 162 insertions, 25 deletions
diff --git a/indoteknik_custom/models/__init__.py b/indoteknik_custom/models/__init__.py index 5af30414..a7ab1089 100755 --- a/indoteknik_custom/models/__init__.py +++ b/indoteknik_custom/models/__init__.py @@ -94,6 +94,7 @@ from . import account_bank_statement from . import stock_warehouse_orderpoint from . import commision from . import sale_advance_payment_inv +from . import purchasing_job_state from . import purchasing_job from . import purchasing_job_multi_update from . import purchase_order_sales_match diff --git a/indoteknik_custom/models/automatic_purchase.py b/indoteknik_custom/models/automatic_purchase.py index da845645..3e2d31e7 100644 --- a/indoteknik_custom/models/automatic_purchase.py +++ b/indoteknik_custom/models/automatic_purchase.py @@ -164,6 +164,7 @@ class AutomaticPurchase(models.Model): 'company_id': 1, # indoteknik dotcom gemilang 'picking_type_id': 28, # indoteknik bandengan receipts 'date_order': current_time, + 'from_apo': True, 'note_description': 'Automatic PO' } @@ -192,8 +193,19 @@ class AutomaticPurchase(models.Model): limit=PRODUCT_PER_PO ) + lines = auto_purchase_line.search( + domain, + offset=i * PRODUCT_PER_PO, + limit=PRODUCT_PER_PO + ) + + for line in lines: product = line.product_id + sales_match = self.env['automatic.purchase.sales.match'].search([ + ('automatic_purchase_id', '=', self.id), + ('product_id', '=', product.id), + ]) param_line = { 'order_id': new_po.id, 'product_id': product.id, @@ -202,6 +214,7 @@ class AutomaticPurchase(models.Model): 'suggest': product._get_po_suggest(line.qty_purchase), 'product_uom_qty': line.qty_purchase, 'price_unit': line.last_price, + # 'so_line_id': [sales.sale_line_id.id for sales in sales_match], } new_po_line = self.env['purchase.order.line'].create([param_line]) line.current_po_id = new_po.id diff --git a/indoteknik_custom/models/purchase_order.py b/indoteknik_custom/models/purchase_order.py index 99d79072..1cdf5094 100755 --- a/indoteknik_custom/models/purchase_order.py +++ b/indoteknik_custom/models/purchase_order.py @@ -53,6 +53,7 @@ class PurchaseOrder(models.Model): responsible_ids = fields.Many2many('res.users', string='Responsibles', compute='_compute_responsibles') status_paid_cbd = fields.Boolean(string='Paid Status', tracking=3, help='Field ini diisi secara manual oleh Finance AP dan hanya untuk status PO CBD') revisi_po = fields.Boolean(string='Revisi', tracking=3) + from_apo = fields.Boolean(string='From APO') @api.model def action_multi_cancel(self): @@ -442,6 +443,10 @@ class PurchaseOrder(models.Model): return res def compute_total_margin(self): + if self.from_apo: + self.compute_total_margin_from_apo() + return + sum_so_margin = sum_sales_price = sum_margin = 0 for line in self.order_line: sale_order_line = line.so_line_id @@ -475,6 +480,59 @@ class PurchaseOrder(models.Model): self.total_so_margin = 0 self.total_so_percent_margin = 0 + def compute_total_margin_from_apo(self): + purchase_price_dict = {} + + for lines in self.order_line: + product_id = lines.product_id.id + + if product_id not in purchase_price_dict: + purchase_price_dict[product_id] = lines.price_subtotal + + sum_so_margin = sum_sales_price = sum_margin = 0 + for line in self.order_sales_match_line: + sale_order_line = line.sale_line_id + + if not sale_order_line: + sale_order_line = self.env['sale.order.line'].search([ + ('product_id', '=', line.product_id.id), + ('order_id', '=', line.sale_id.id) + ], limit=1, order='price_reduce_taxexcl') + + sum_so_margin += sale_order_line.item_margin + + sales_price = sale_order_line.price_reduce_taxexcl * sale_order_line.product_uom_qty + + if sale_order_line.order_id.shipping_cost_covered == 'indoteknik': + sales_price -= sale_order_line.delivery_amt_line + + if sale_order_line.order_id.fee_third_party > 0: + sales_price -= sale_order_line.fee_third_party_line + + sum_sales_price += sales_price + + product_id = sale_order_line.product_id.id + + purchase_price = purchase_price_dict.get(product_id, 0) + + if line.purchase_order_id.delivery_amount > 0: + purchase_price += line.delivery_amt_line + + real_item_margin = sales_price - purchase_price + sum_margin += real_item_margin + + + if sum_so_margin != 0 and sum_sales_price != 0 and sum_margin != 0: + self.total_so_margin = sum_so_margin + self.total_so_percent_margin = round((sum_so_margin / sum_sales_price), 2) * 100 + self.total_margin = sum_margin + self.total_percent_margin = round((sum_margin / sum_sales_price), 2) * 100 + else: + self.total_margin = 0 + self.total_percent_margin = 0 + self.total_so_margin = 0 + self.total_so_percent_margin = 0 + def compute_amt_total_without_service(self): for order in self: sum_price_total = 0 diff --git a/indoteknik_custom/models/purchasing_job.py b/indoteknik_custom/models/purchasing_job.py index b3c25256..1c74f0e9 100644 --- a/indoteknik_custom/models/purchasing_job.py +++ b/indoteknik_custom/models/purchasing_job.py @@ -12,6 +12,7 @@ class PurchasingJob(models.Model): id = fields.Integer() product_id = fields.Many2one('product.product', string="Product") + vendor_id = fields.Many2one('res.partner', string="Vendor", compute='compute_vendor_id') brand = fields.Char(string='Brand') item_code = fields.Char(string='Item Code') product = fields.Char(string='Product Name') @@ -19,17 +20,47 @@ class PurchasingJob(models.Model): incoming = fields.Float(string="Incoming") outgoing = fields.Float(string="Outgoing") action = fields.Char(string="Status") + status_apo = fields.Selection([ + ('not_apo', 'Belum APO'), + ('apo', 'APO') + ], string='APO?') + + def compute_vendor_id(self): + for sale in self: + domain = [ + ('product_id', '=', sale.product_id.id) + ] + sales = self.env['v.sales.outstanding'].search(domain) + + vendor_id = False + + if sales: + vendor_id = sales[0].sale_line_id.vendor_id.id + + sale.vendor_id = vendor_id def init(self): tools.drop_view_if_exists(self.env.cr, self._table) self.env.cr.execute(""" CREATE OR REPLACE VIEW %s AS ( - select product_id as id, product_id, brand, item_code, product, onhand, incoming, outgoing, action - from v_procurement_monitoring_by_product - where action = 'kurang' + SELECT + pmp.product_id as id, + pmp.product_id, + pmp.brand, + pmp.item_code, + pmp.product, + pmp.onhand, + pmp.incoming, + pmp.outgoing, + pmp.action, + pjs.status_apo AS status_apo + FROM v_procurement_monitoring_by_product pmp + LEFT JOIN purchasing_job_state pjs ON pjs.purchasing_job_id = pmp.product_id + WHERE pmp.action = 'kurang' ) """ % self._table) + def open_form_multi_generate_request_po(self): action = self.env['ir.actions.act_window']._for_xml_id('indoteknik_custom.action_purchasing_job_multi_update') action['context'] = { @@ -80,14 +111,7 @@ class PurchasingJob(models.Model): automatic_purchase._create_sync_purchasing_job(job) count += 1 _logger.info('Create Automatic Purchase Line %s' % job.product_id.name) - return { - 'name': _('Automatic Purchase'), - 'view_mode': 'tree,form', - 'res_model': 'automatic.purchase', - 'target': 'current', - 'type': 'ir.actions.act_window', - 'domain': [('id', '=', automatic_purchase.id)], - } + return automatic_purchase.id class OutstandingSales(models.Model): _name = 'v.sales.outstanding' diff --git a/indoteknik_custom/models/purchasing_job_multi_update.py b/indoteknik_custom/models/purchasing_job_multi_update.py index a1b79907..e7f19e50 100644 --- a/indoteknik_custom/models/purchasing_job_multi_update.py +++ b/indoteknik_custom/models/purchasing_job_multi_update.py @@ -1,5 +1,6 @@ -from odoo import models, fields +from odoo import models, fields, _ import logging +from odoo.exceptions import AccessError, UserError, ValidationError _logger = logging.getLogger(__name__) @@ -9,14 +10,22 @@ class PurchasingJobMultiUpdate(models.TransientModel): def save_multi_update_purchasing_job(self): product_ids = self._context['product_ids'] - product = self.env['v.purchasing.job'].browse(product_ids) - product.generate_request_po() + products = self.env['v.purchasing.job'].browse(product_ids) + for product in products: + if product.status_apo == 'apo': + raise UserError('Ada Purchase Order yang statusnya APO, proses dulu') + + purchasing_job_state = self.env['purchasing.job.state'] + purchasing_job_state.create({ + 'purchasing_job_id': product.id, + 'status_apo': 'apo', + }) + apo = products.generate_request_po() return { - 'type': 'ir.actions.client', - 'tag': 'display_notification', - 'params': { - 'title': 'Notification', - 'message': 'Berhasil membuat Automatic Purchase', - 'next': {'type': 'ir.actions.act_window_close'}, - } + 'name': _('Automatic Purchase'), + 'view_mode': 'tree,form', + 'res_model': 'automatic.purchase', + 'target': 'current', + 'type': 'ir.actions.act_window', + 'domain': [('id', '=', apo)], }
\ No newline at end of file diff --git a/indoteknik_custom/models/purchasing_job_state.py b/indoteknik_custom/models/purchasing_job_state.py new file mode 100644 index 00000000..57fd3db2 --- /dev/null +++ b/indoteknik_custom/models/purchasing_job_state.py @@ -0,0 +1,17 @@ +from odoo import fields, models, api, tools, _ +import logging +from datetime import datetime + +_logger = logging.getLogger(__name__) + + +class PurchasingJobState(models.Model): + _name = 'purchasing.job.state' + _rec_name = 'purchasing_job_id' + + purchasing_job_id = fields.Many2one('purchasing.job', string='Ref') + status_apo = fields.Selection([ + ('not_apo', 'Belum APO'), + ('apo', 'APO') + ], string='APO?', copy=False) + diff --git a/indoteknik_custom/models/sale_order_line.py b/indoteknik_custom/models/sale_order_line.py index 5b5b35d6..39366028 100644 --- a/indoteknik_custom/models/sale_order_line.py +++ b/indoteknik_custom/models/sale_order_line.py @@ -13,7 +13,7 @@ class SaleOrderLine(models.Model): change_default=True, index=True, tracking=1, states={'draft': [('readonly', False)], 'sent': [('readonly', False)]}, domain="['|', ('company_id', '=', False), ('company_id', '=', company_id)]" - ) + ) purchase_price = fields.Float('Purchase', required=True, digits='Product Price', default=0.0) purchase_tax_id = fields.Many2one('account.tax', string='Tax', domain=['|', ('active', '=', False), ('active', '=', True)]) delivery_amt_line = fields.Float('DeliveryAmtLine', compute='compute_delivery_amt_line') diff --git a/indoteknik_custom/models/sales_order_fullfillment.py b/indoteknik_custom/models/sales_order_fullfillment.py index 97e6d5c2..ab416e8d 100644 --- a/indoteknik_custom/models/sales_order_fullfillment.py +++ b/indoteknik_custom/models/sales_order_fullfillment.py @@ -12,4 +12,15 @@ class SalesOrderFullfillment(models.Model): sales_order_id = fields.Many2one('sale.order', string='Sale Order') product_id = fields.Many2one('product.product', string='Product') reserved_from = fields.Char(string='Reserved From', copy=False) - qty_fullfillment = fields.Float(string='Qty')
\ No newline at end of file + qty_fullfillment = fields.Float(string='Qty') + user_id = fields.Many2one('res.users', string='Responsible', compute='get_user_id') + + def get_user_id(self): + for rec in self: + po = self.env['purchase.order'].search([('name', '=', rec.reserved_from)], limit=1) + + if po: + rec.user_id = po.user_id.id + else: + rec.user_id = False + diff --git a/indoteknik_custom/security/ir.model.access.csv b/indoteknik_custom/security/ir.model.access.csv index 7de5d909..784c52af 100755 --- a/indoteknik_custom/security/ir.model.access.csv +++ b/indoteknik_custom/security/ir.model.access.csv @@ -107,4 +107,5 @@ access_report_logbook_sj_line,access.report.logbook.sj.line,model_report_logbook 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 -access_sales_order_fullfillment,access.sales.order.fullfillment,model_sales_order_fullfillment,,1,1,1,1
\ No newline at end of file +access_sales_order_fullfillment,access.sales.order.fullfillment,model_sales_order_fullfillment,,1,1,1,1 +access_purchasing_job_state,access.purchasing.job.state,model_purchasing_job_state,,1,1,1,1
\ No newline at end of file diff --git a/indoteknik_custom/views/purchasing_job.xml b/indoteknik_custom/views/purchasing_job.xml index 42dfd359..c439dc8f 100644 --- a/indoteknik_custom/views/purchasing_job.xml +++ b/indoteknik_custom/views/purchasing_job.xml @@ -6,12 +6,14 @@ <field name="arch" type="xml"> <tree create="false" multi_edit="1"> <field name="product_id"/> + <field name="vendor_id"/> <field name="brand"/> <field name="item_code"/> <field name="product"/> <field name="onhand"/> <field name="incoming"/> <field name="outgoing"/> + <field name="status_apo"/> <field name="action"/> </tree> </field> diff --git a/indoteknik_custom/views/sale_order.xml b/indoteknik_custom/views/sale_order.xml index 7d1d4c4a..d77ecac0 100755 --- a/indoteknik_custom/views/sale_order.xml +++ b/indoteknik_custom/views/sale_order.xml @@ -171,7 +171,7 @@ </form> </field> </page> - <page string="Matches PO" name="page_matches_po"> + <page string="Matches PO" name="page_matches_po" invisible="1"> <field name="order_sales_match_line" readonly="1"/> </page> <page string="Fullfillment" name="page_sale_order_fullfillment"> @@ -254,6 +254,7 @@ <field name="product_id" readonly="1"/> <field name="reserved_from" readonly="1"/> <field name="qty_fullfillment" readonly="1"/> + <field name="user_id" readonly="1"/> </tree> </field> </record> |
