from odoo import models, fields, api from odoo.exceptions import UserError from datetime import datetime import logging _logger = logging.getLogger(__name__) class Requisition(models.Model): _name = 'requisition' _order = 'id desc' 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_requisition_from_sales_with_price(self): if self.requisition_lines: raise UserError('Sudah digenerate sebelumnya, hapus line terlebih dahulu') if not self.sale_order_id: raise UserError('Sale Order harus diisi') if self.is_po: raise UserError('Sudah jadi PO, tidak bisa di create ulang PO nya') count = 0 for order_line in self.sale_order_id.order_line: # get purchase price altama, if nothing, then get other cheaper, if nothing then last po purchase_price = order_line.purchase_price vendor_id = order_line.vendor_id.id # get qty available bandengan qty_available = order_line.product_id.qty_onhand_bandengan + order_line.product_id.qty_incoming_bandengan - order_line.product_id.outgoing_qty suggest = 'harus beli' if qty_available > order_line.product_qty: suggest = 'masih cukup' self.env['requisition.line'].create([{ 'requisition_id': self.id, 'partner_id': vendor_id, 'brand_id': order_line.product_id.product_tmpl_id.x_manufacture.id, 'product_id': order_line.product_id.id, 'qty_purchase': order_line.product_uom_qty, 'tax_id': order_line.purchase_tax_id.id, 'price_unit': purchase_price, 'subtotal': purchase_price * order_line.product_uom_qty, 'source': 'sales', 'qty_available_store': qty_available, 'suggest': suggest, }]) count+=1 _logger.info('Create Requisition %s' % order_line.product_id.name) self.notification = "Requisition Created %s lines" % count def create_requisition_from_sales(self): if self.requisition_lines: raise UserError('Sudah digenerate sebelumnya, hapus line terlebih dahulu') if not self.sale_order_id: raise UserError('Sale Order harus diisi') if self.is_po: raise UserError('Sudah jadi PO, tidak bisa di create ulang PO nya') # old_requisition = self.env['requisition'].search([('sale_order_id', '=', self.sale_order_id.id)], limit=1) # if old_requisition: # raise UserError('Sudah pernah jadi Requisition') count = 0 for order_line in self.sale_order_id.order_line: # get purchase price altama, if nothing, then get other cheaper, if nothing then last po purchase_price = 0 vendor_id = 0 # get qty available bandengan qty_available = order_line.product_id.qty_onhand_bandengan + order_line.product_id.qty_incoming_bandengan - order_line.product_id.outgoing_qty suggest = 'harus beli' if qty_available > order_line.product_qty: suggest = 'masih cukup' purchase_pricelist = self.env['purchase.pricelist'].search([ ('product_id.id', '=', order_line.product_id.id), ('vendor_id.id', '=', 5571) ], order='product_price asc', limit=1) purchase_price = purchase_pricelist.product_price vendor_id = purchase_pricelist.vendor_id.id source = 'PriceList' if not purchase_price or purchase_price <= 0: purchase_pricelist = self.env['purchase.pricelist'].search([('product_id', '=', order_line.product_id.id)], order='product_price asc', limit=1) purchase_price = purchase_pricelist.product_price vendor_id = purchase_pricelist.vendor_id.id source = 'PriceList' if not purchase_price or purchase_price <= 0: last_po_line = self.env['purchase.order.line'].search([('product_id', '=', order_line.product_id.id), ('order_id.state', '=', 'done')], order='id desc', limit=1) purchase_price = last_po_line.price_unit vendor_id = last_po_line.order_id.partner_id.id source = 'LastPO' if not purchase_price or purchase_price <= 0: purchase_price = 0 vendor_id = 5571 source = 'Nothing' self.env['requisition.line'].create([{ 'requisition_id': self.id, 'partner_id': vendor_id, 'brand_id': order_line.product_id.product_tmpl_id.x_manufacture.id, 'product_id': order_line.product_id.id, 'qty_purchase': order_line.product_uom_qty, 'tax_id': order_line.purchase_tax_id.id, 'price_unit': purchase_price, 'subtotal': purchase_price * order_line.product_uom_qty, 'source': source, 'qty_available_store': qty_available, 'suggest': suggest, }]) count+=1 _logger.info('Create Requisition %s' % order_line.product_id.name) self.notification = "Requisition Created %s lines" % count 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 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 } # new_po = self.env['purchase.order'].create([param_header]) products_vendors = self.env['requisition.line'].search([ ('requisition_id', '=', self.id), ('partner_id', '=', vendor['partner_id'][0]), ('qty_purchase', '>', 0) ], order='brand_id') count = brand_id = 0 new_po = '' for product in products_vendors: if not new_po or ((count == 200 or brand_id != product.brand_id.id) and vendor['partner_id'][0] == 5571): 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 }]) 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' param_line = { 'order_id': new_po.id, 'sequence': count, 'product_id': product.product_id.id, 'product_qty': product.qty_purchase, 'product_uom_qty': product.qty_purchase, 'price_unit': product.last_price, 'taxes_id': product.tax_id, 'qty_available_store': qty_available, 'suggest': suggest, } new_line = self.env['purchase.order.line'].create([param_line]) 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 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): self.subtotal = self.price_unit * self.qty_purchase 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