from odoo import models, fields, api, _ from odoo.exceptions import UserError from datetime import datetime import math import logging _logger = logging.getLogger(__name__) class Requisition(models.Model): _name = 'requisition' _order = 'id desc' _inherit = ['mail.thread'] _rec_name = 'number' number = fields.Char(string='Document No', index=True, copy=False, readonly=True) date_doc = fields.Date(string='Date', help='isi tanggal hari ini') description = fields.Char(string='Description', help='bebas isinya apa aja') requisition_lines = fields.One2many('requisition.line', 'requisition_id', string='Lines', auto_join=True) notification = fields.Char(string='Notification') is_po = fields.Boolean(string='Is PO') requisition_match = fields.One2many('requisition.purchase.match', 'requisition_id', string='Matches', auto_join=True) sale_order_id = fields.Many2one('sale.order', string='SO', help='harus diisi nomor SO yang ingin digenerate', domain="[('state', '=', 'sale')]") @api.model def create(self, vals): vals['number'] = self.env['ir.sequence'].next_by_code('requisition') or '0' result = super(Requisition, self).create(vals) return result def create_po_from_requisition(self): if not self.requisition_lines: raise UserError('Tidak ada Lines, belum bisa create PO') if self.is_po: raise UserError('Sudah pernah di create PO') vendor_ids = self.env['requisition.line'].read_group([ ('requisition_id', '=', self.id), ('partner_id', '!=', False) ], fields=['partner_id'], groupby=['partner_id']) po_ids = [] for vendor in vendor_ids: result_po = self.create_po_by_vendor(vendor['partner_id'][0]) po_ids.append(result_po) return { 'name': _('Purchase Order'), 'view_mode': 'tree,form', 'res_model': 'purchase.order', 'target': 'current', 'type': 'ir.actions.act_window', 'domain': [('id', 'in', po_ids)], } def create_po_by_vendor(self, vendor_id): current_time = datetime.now() PRODUCT_PER_PO = 20 requisition_line = self.env['requisition.line'] param_header = { 'partner_id': vendor_id, # 'partner_ref': self.sale_order_id.name, 'currency_id': 12, 'user_id': self.env.user.id, 'company_id': 1, # indoteknik dotcom gemilang 'picking_type_id': 28, # indoteknik bandengan receipts 'date_order': current_time, 'sale_order_id': self.sale_order_id.id, 'note_description': 'from Purchase Requisition' } domain = [ ('requisition_id', '=', self.id), ('partner_id', '=', vendor_id), ('qty_purchase', '>', 0) ] products_len = requisition_line.search_count(domain) page = math.ceil(products_len / PRODUCT_PER_PO) po_ids = [] # i start from zero (0) for i in range(page): new_po = self.env['purchase.order'].create([param_header]) new_po.name = new_po.name + "/R/" + str(i + 1) po_ids.append(new_po.id) lines = requisition_line.search( domain, offset=i * PRODUCT_PER_PO, limit=PRODUCT_PER_PO ) tax = [22] for line in lines: product = line.product_id param_line = { 'product_id': product.product_id.id, 'product_qty': product.qty_purchase, 'product_uom_qty': product.qty_purchase, 'price_unit': product.price_unit, 'taxes_id': tax, } 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 return po_ids def create_po_from_requisition(self): if not self.requisition_lines: raise UserError('Tidak ada Lines, belum bisa create PO') if self.is_po: raise UserError('Sudah pernah di create PO') current_time = datetime.now() vendor_ids = self.env['requisition.line'].read_group([('requisition_id', '=', self.id), ('partner_id', '!=', False)], fields=['partner_id'], groupby=['partner_id']) counter_po_number = 0 po_ids = [] for vendor in vendor_ids: param_header = { 'partner_id': vendor['partner_id'][0], # 'partner_ref': self.sale_order_id.name, 'currency_id': 12, 'user_id': self.env.user.id, 'company_id': 1, # indoteknik dotcom gemilang 'picking_type_id': 28, # indoteknik bandengan receipts 'date_order': current_time, 'sale_order_id': self.sale_order_id.id, 'note_description': 'from Purchase Requisition' } param_requisition_line = [ ('requisition_id', '=', self.id), ('partner_id', '=', vendor['partner_id'][0]), ('qty_purchase', '>', 0) ] # new_po = self.env['purchase.order'].create([param_header]) products_vendors = self.env['requisition.line'].search(, order='brand_id') count = brand_id = 0 for product in products_vendors: if count > 200 or brand_id != product.brand_id.id: continue count = 0 counter_po_number += 1 new_po = self.env['purchase.order'].create([param_header]) new_po.name = new_po.name + "/R/"+str(counter_po_number) self.env['requisition.purchase.match'].create([{ 'requisition_id': self.id, 'order_id': new_po.id }]) po_ids.append(new_po.id) self.env.cr.commit() # else: # new_po = self.env['purchase.order'].create([param_header]) brand_id = product.brand_id.id count += 10 # qty_available = product.product_id.qty_onhand_bandengan + product.product_id.qty_incoming_bandengan - product.product_id.outgoing_qty # suggest = 'harus beli' # if qty_available > product.qty_purchase: # suggest = 'masih cukup' tax = [22] param_line = { 'sequence': count, 'product_id': product.product_id.id, 'product_qty': product.qty_purchase, 'product_uom_qty': product.qty_purchase, 'price_unit': product.price_unit, 'taxes_id': tax, # 'qty_available_store': qty_available, # 'suggest': suggest, } new_line = self.env['purchase.order.line'].create([param_line]) if new_po: new_line.write({ 'order_id': new_po.id, }) product.current_po_id = new_po.id product.current_po_line_id = new_line.id _logger.info('Create PO Line %s' % product.product_id.name) # self.notification = self.notification + ' %s' % new_po.name self.is_po = True if po_ids: return { 'name': _('Purchase Order'), 'view_mode': 'tree,form', 'res_model': 'purchase.order', 'target': 'current', 'type': 'ir.actions.act_window', 'domain': [('id', 'in', po_ids)], } class RequisitionLine(models.Model): _name = 'requisition.line' _description = 'Requisition Line' _order = 'requisition_id, id' requisition_id = fields.Many2one('requisition', string='Ref', required=True, ondelete='cascade', index=True, copy=False) brand_id = fields.Many2one('x_manufactures', string='Brand') product_id = fields.Many2one('product.product', string='Product') partner_id = fields.Many2one('res.partner', string='Vendor') qty_purchase = fields.Float(string='Qty Purchase') price_unit = fields.Float(string='Price') tax_id = fields.Many2one('account.tax', help='isi tax pembelian include atau exclude', domain="[('type_tax_use', '=', 'purchase')]") subtotal = fields.Float(string='Subtotal') last_price = fields.Float(string='Last Price') last_order_id = fields.Many2one('purchase.order', string='Last Order') last_orderline_id = fields.Many2one('purchase.order.line', string='Last Order Line') 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') source = fields.Char(string='Source', help='data harga diambil darimana') qty_available_store = fields.Float(string='Available') suggest = fields.Char(string='Suggest') @api.onchange('price_unit') def _onchange_price_unit(self): for line in self: line.subtotal = line.price_unit * line.qty_purchase @api.onchange('product_id') def _onchange_product(self): for line in self: line.brand_id = line.product_id.product_tmpl_id.x_manufacture.id class RequisitionPurchaseMatch(models.Model): _name = 'requisition.purchase.match' _order = 'requisition_id, id' requisition_id = fields.Many2one('requisition', string='Ref', required=True, ondelete='cascade', index=True, copy=False) order_id = fields.Many2one('purchase.order', string='Purchase Order') vendor = fields.Char(string='Vendor', compute='_compute_info_po') total = fields.Float(string='Total', compute='_compute_info_po') def _compute_info_po(self): for match in self: match.vendor = match.order_id.partner_id.name match.total = match.order_id.amount_total