From ad1f21b27dff6eca4eb90d2a4496cd9ff80701c4 Mon Sep 17 00:00:00 2001 From: Azka Nathan Date: Sat, 12 Jul 2025 10:40:06 +0700 Subject: purchasing job, requisition, reordering v2 --- fixco_custom/models/automatic_purchase.py | 106 ++++++++++++++++++++++++++++-- 1 file changed, 99 insertions(+), 7 deletions(-) (limited to 'fixco_custom/models/automatic_purchase.py') diff --git a/fixco_custom/models/automatic_purchase.py b/fixco_custom/models/automatic_purchase.py index 7612f4a..f3f650d 100644 --- a/fixco_custom/models/automatic_purchase.py +++ b/fixco_custom/models/automatic_purchase.py @@ -19,8 +19,9 @@ class AutomaticPurchase(models.Model): is_po = fields.Boolean(string='Is PO', tracking=True) responsible_id = fields.Many2one('res.users', string='Responsible', tracking=True, default=lambda self: self.env.user) apo_type = fields.Selection([ - ('regular', 'Regular Fulfill SO'), + ('purchasing_job', 'Purchasing Job'), ('reordering', 'Reordering Rule'), + ('requisition', 'Requisition'), ], string='Type', tracking=True) purchase_order_ids = fields.One2many( 'purchase.order', @@ -31,6 +32,55 @@ class AutomaticPurchase(models.Model): string='Purchase Orders', compute='_compute_purchase_order_count' ) + sale_order_id = fields.Many2one('sale.order', string='Sales Order') + + def action_generate_lines_from_so(self): + self.ensure_one() + + self.automatic_purchase_lines.unlink() + + if not self.sale_order_id: + raise UserError("Please select a Sales Order first.") + + lines = [] + + for line in self.sale_order_id.order_line: + product = line.product_id + + manage_stock = self.env['manage.stock'].search([ + ('product_id', '=', product.id) + ], limit=1) + + qty_min = manage_stock.min_stock if manage_stock else 0.0 + qty_buffer = manage_stock.buffer_stock if manage_stock else 0.0 + + quant = self.env['stock.quant'].search([ + ('product_id', '=', product.id) + ], limit=1) + qty_available = quant.available_quantity if quant else 0.0 + + pricelist = self.env['purchase.pricelist'].search([ + ('product_id', '=', product.id) + ], limit=1) + + vendor = pricelist.vendor_id if pricelist else False + price = pricelist.price if pricelist else 0.0 + subtotal = price * line.product_uom_qty + + lines.append({ + 'automatic_purchase_id': self.id, + 'product_id': product.id, + 'qty_purchase': line.product_uom_qty, + 'qty_min': qty_min, + 'qty_buffer': qty_buffer, + 'qty_available': qty_available, + 'partner_id': vendor.id if vendor else False, + 'taxes_id': vendor.tax_id.id if vendor else False, + 'price': price, + 'subtotal': subtotal, + }) + + self.env['automatic.purchase.line'].create(lines) def action_view_related_po(self): self.ensure_one() @@ -77,7 +127,7 @@ class AutomaticPurchase(models.Model): for vendor_id, lines in vendor_lines.items(): vendor = self.env['res.partner'].browse(vendor_id) - chunk_size = 20 + chunk_size = 10 line_chunks = [lines[i:i + chunk_size] for i in range(0, len(lines), chunk_size)] for index, chunk in enumerate(line_chunks): @@ -105,7 +155,7 @@ class AutomaticPurchase(models.Model): 'company_id': self.env.company.id, 'currency_id': vendor.property_purchase_currency_id.id or self.env.company.currency_id.id, 'automatic_purchase_id': self.id, - 'source': 'reordering', + 'source': self.apo_type, }) def _create_purchase_order_line(self, order, line): @@ -141,7 +191,7 @@ class AutomaticPurchase(models.Model): ]) # Hitung total qty_available (quantity - reserved_quantity) untuk lokasi tersebut - total_available = quant_records.available_quantity or 0.0 + total_available = quant_records.quantity or 0.0 # Log nilai untuk debugging _logger.info( @@ -195,7 +245,6 @@ class AutomaticPurchase(models.Model): 'qty_purchase': qty_purchase, 'qty_min': stock.min_stock, 'qty_buffer': stock.buffer_stock, - 'qty_available': total_available, 'partner_id': stock.vendor_id.id, 'taxes_id': stock.vendor_id.tax_id.id, 'price': price, @@ -235,7 +284,10 @@ class AutomaticPurchaseLine(models.Model): qty_purchase = fields.Float(string='Qty Purchase') qty_min = fields.Float(string='Qty Min') qty_buffer = fields.Float(string='Qty Buffer') - qty_available = fields.Float(string='Qty Available') + qty_available = fields.Float(string='Qty Available', compute='compute_qty_available') + qty_onhand = fields.Float(string='Qty On Hand', compute='compute_qty_onhand') + qty_incoming = fields.Float(string='Qty Incoming', compute='compute_qty_incoming') + qty_outgoing = fields.Float(string='Qty Outgoing', compute='compute_qty_outgoing') partner_id = fields.Many2one('res.partner', string='Vendor') price = fields.Float(string='Price') subtotal = fields.Float(string='Subtotal') @@ -244,4 +296,44 @@ class AutomaticPurchaseLine(models.Model): is_po = fields.Boolean(String='Is PO') current_po_id = fields.Many2one('purchase.order', string='Current') current_po_line_id = fields.Many2one('purchase.order.line', string='Current Line') - taxes_id = fields.Many2one('account.tax', string='Taxes') \ No newline at end of file + taxes_id = fields.Many2one('account.tax', string='Taxes') + + def compute_qty_available(self): + for line in self: + if line.product_id: + stock_quant = self.env['stock.quant'].search([ + ('product_id', '=', line.product_id.id), + ('location_id', '=', 55) + ], limit=1) + line.qty_available = stock_quant.available_quantity if stock_quant else 0.0 + + def compute_qty_onhand(self): + for line in self: + if line.product_id: + stock_quant = self.env['stock.quant'].search([ + ('product_id', '=', line.product_id.id), + ('location_id', '=', 55) + ], limit=1) + line.qty_onhand = stock_quant.quantity if stock_quant else 0.0 + + def compute_qty_incoming(self): + for line in self: + if line.product_id: + stock_move = self.env['stock.move'].search([ + ('product_id', '=', line.product_id.id), + ('location_dest_id', '=', 55), + ('location_id', '=', 4), + ('state', 'in', ['waiting', 'confirmed', 'assigned', 'partially_available']) + ]) + line.qty_incoming = sum(move.product_uom_qty for move in stock_move) + + def compute_qty_outgoing(self): + for line in self: + if line.product_id: + stock_move = self.env['stock.move'].search([ + ('product_id', '=', line.product_id.id), + ('location_dest_id', '=', 5), + ('location_id', '=', 55), + ('state', 'in', ['waiting', 'confirmed', 'assigned', 'partially_available']) + ], limit=1) + line.qty_outgoing = sum(move.product_uom_qty for move in stock_move) \ No newline at end of file -- cgit v1.2.3