2018-01-24 07:12:32 +01:00
|
|
|
# Part of Flectra See LICENSE file for full copyright and licensing details.
|
|
|
|
|
|
|
|
from datetime import datetime
|
|
|
|
|
|
|
|
from flectra.exceptions import Warning
|
|
|
|
from flectra.tools.misc import formatLang
|
|
|
|
|
|
|
|
import flectra.addons.decimal_precision as dp
|
|
|
|
from flectra import api, fields, models, _
|
|
|
|
|
|
|
|
|
|
|
|
class WizRequisitionRequest(models.TransientModel):
|
|
|
|
_name = 'wiz.requisition.request'
|
|
|
|
|
|
|
|
purchase_indent_id = fields.Many2one('purchase.indent', 'Purchase Indent')
|
2018-01-29 12:35:08 +01:00
|
|
|
branch_id = fields.Many2one('res.branch', string='Branch')
|
2018-01-24 07:12:32 +01:00
|
|
|
partner_id = fields.Many2one(
|
|
|
|
'res.partner', 'Vendor', domain="[('supplier','=',True)]")
|
|
|
|
wiz_indent_line = fields.One2many(
|
|
|
|
'wiz.indent.line', 'wizard_indent_id', string='Indent Lines')
|
|
|
|
category_id = fields.Many2one(
|
|
|
|
'product.category', 'Category', readonly=True)
|
|
|
|
state = fields.Selection(
|
|
|
|
[('draft', 'Draft'), ('confirm', 'Confirm')], default='draft')
|
|
|
|
dummy_wiz_indent_line = fields.One2many(
|
|
|
|
'dummy.wiz.indent.line', 'wizard_indent_id', string='Indent Lines')
|
|
|
|
order_type = fields.Selection([
|
|
|
|
('po', 'Purchase Order'),
|
|
|
|
('pa', 'Purchase Agreement')], string='Order Type', default='po')
|
|
|
|
requisition_type_id = fields.Many2one(
|
|
|
|
'purchase.requisition.type', string="Agreement Type")
|
|
|
|
|
|
|
|
@api.onchange('partner_id')
|
|
|
|
def onchange_partner_id(self):
|
|
|
|
obj_pro_sup = self.env['product.supplierinfo']
|
|
|
|
for line in self.wiz_indent_line:
|
|
|
|
pro_supplier_info_ids = obj_pro_sup.search([
|
|
|
|
('product_tmpl_id', '=', line.product_id.product_tmpl_id.id),
|
|
|
|
('name', '=', self.partner_id.id)])
|
|
|
|
if pro_supplier_info_ids:
|
|
|
|
line.price_unit = \
|
|
|
|
max([pro_sup_id.price
|
|
|
|
for pro_sup_id in pro_supplier_info_ids])
|
|
|
|
|
|
|
|
@api.onchange('purchase_indent_id')
|
|
|
|
def onchange_purchase_indent_id(self):
|
|
|
|
if self.state == 'draft':
|
|
|
|
purchase_indent_ids = self.purchase_indent_id.search([
|
|
|
|
('category_id', '=', self.purchase_indent_id.category_id.id),
|
|
|
|
('state', 'in', ['confirm', 'requisition']),
|
2018-01-29 12:35:08 +01:00
|
|
|
('branch_id', '=', self.purchase_indent_id.branch_id.id),
|
2018-01-24 07:12:32 +01:00
|
|
|
('company_id', '=', self.purchase_indent_id.company_id.id)])
|
|
|
|
list_data = []
|
|
|
|
value = {}
|
|
|
|
for purchase_indent_id in purchase_indent_ids:
|
|
|
|
for indent_line_id in purchase_indent_id.indent_line:
|
|
|
|
if not indent_line_id.product_qty == \
|
|
|
|
indent_line_id.requisition_qty:
|
|
|
|
list_data.append(
|
|
|
|
(0, 0, {
|
|
|
|
'partner_id': purchase_indent_id.partner_id.id,
|
|
|
|
'name': indent_line_id.name,
|
|
|
|
'product_id': indent_line_id.product_id.id,
|
|
|
|
'product_qty': indent_line_id.product_qty,
|
|
|
|
'dummy_product_qty':
|
|
|
|
indent_line_id.product_qty,
|
|
|
|
'indent_requ_date':
|
|
|
|
purchase_indent_id.request_date,
|
|
|
|
'expected_date': indent_line_id.expected_date,
|
|
|
|
'product_uom': indent_line_id.product_uom.id,
|
|
|
|
'purchase_indent_id': purchase_indent_id.id,
|
|
|
|
'purchase_indent_line_id': indent_line_id.id,
|
|
|
|
'wizard_indent_id': self.id
|
|
|
|
}))
|
|
|
|
value['dummy_wiz_indent_line'] = list_data
|
|
|
|
self.update(value)
|
|
|
|
|
|
|
|
@api.onchange('order_type')
|
|
|
|
def onchange_order_type(self):
|
|
|
|
if self.order_type == 'po':
|
|
|
|
self.requisition_type_id = False
|
|
|
|
|
|
|
|
@api.multi
|
|
|
|
def act_next(self):
|
|
|
|
wiz_line_object = self.env['wiz.indent.line']
|
|
|
|
dummy_wiz_line_object = self.env['dummy.wiz.indent.line']
|
|
|
|
dup_product_list = []
|
|
|
|
list_data = []
|
|
|
|
unique_list = []
|
|
|
|
check_requisition_qty = False
|
|
|
|
|
|
|
|
for line in self.dummy_wiz_indent_line:
|
|
|
|
if line.requisition_qty:
|
|
|
|
check_requisition_qty = True
|
|
|
|
line.requisition_qty = line.requisition_qty
|
|
|
|
if line.product_id.id not in dup_product_list:
|
|
|
|
dup_product_list.append(line.product_id.id)
|
|
|
|
if not check_requisition_qty:
|
|
|
|
raise Warning(_("No Requisition Quantity were \
|
|
|
|
found for any line!"))
|
|
|
|
msg = 'Following Requisition Quantity is greater than Remaining ' \
|
|
|
|
'Quantity!\n'
|
|
|
|
check_warning = False
|
|
|
|
for line in self.dummy_wiz_indent_line:
|
|
|
|
if not line.requisition_qty:
|
|
|
|
continue
|
|
|
|
if line.requisition_qty > line.remaining_qty:
|
|
|
|
check_warning = True
|
|
|
|
msg += ("\n %s : Product (%s) => Requisition Quantity (%s) "
|
|
|
|
"and Remaining Quantity (%s)!") % (
|
|
|
|
line.purchase_indent_id.name, line.product_id.name,
|
|
|
|
formatLang(self.env, line.requisition_qty, digits=2),
|
|
|
|
formatLang(self.env, line.remaining_qty, digits=2))
|
|
|
|
if check_warning:
|
|
|
|
raise Warning(_(msg))
|
|
|
|
for line in self.dummy_wiz_indent_line:
|
|
|
|
if not line.requisition_qty:
|
|
|
|
continue
|
|
|
|
line_vals = {
|
|
|
|
'purchase_indent_ids':
|
|
|
|
[(4, line.purchase_indent_id.id)],
|
|
|
|
'partner_id': line.partner_id.id,
|
|
|
|
'name': line.name,
|
|
|
|
'product_id': line.product_id.id,
|
|
|
|
'product_qty': line.requisition_qty,
|
|
|
|
'product_uom': line.product_uom.id,
|
|
|
|
'purchase_indent_line_id':
|
|
|
|
line.purchase_indent_line_id.id,
|
|
|
|
'wizard_indent_id': self.id,
|
|
|
|
'expected_date': line.expected_date,
|
|
|
|
'taxes_id': [(6, 0, line.product_id.supplier_taxes_id.ids)],
|
|
|
|
}
|
|
|
|
if dup_product_list:
|
|
|
|
if line.product_id.id not in unique_list:
|
|
|
|
new_line_id = wiz_line_object.create(line_vals)
|
|
|
|
unique_list.append(line.product_id.id)
|
|
|
|
list_data.append(new_line_id.id)
|
|
|
|
else:
|
|
|
|
wiz_ids = dummy_wiz_line_object.search([
|
|
|
|
('wizard_indent_id', '=', line.wizard_indent_id.id),
|
|
|
|
('product_id', '=', line.product_id.id)])
|
|
|
|
wiz_indent_line_id = wiz_line_object.search([
|
|
|
|
('wizard_indent_id', '=', self.id),
|
|
|
|
('product_id', '=', line.product_id.id)])
|
|
|
|
indent_list = []
|
|
|
|
qty = 0.0
|
|
|
|
for wiz_id in wiz_ids:
|
|
|
|
indent_list.append(wiz_id.purchase_indent_id.id)
|
|
|
|
qty += wiz_id.requisition_qty
|
|
|
|
wiz_indent_line_id.write({
|
|
|
|
'product_qty': qty,
|
|
|
|
'purchase_indent_ids':
|
|
|
|
[(6, 0, list(set(indent_list)))]})
|
|
|
|
else:
|
|
|
|
new_line_id = wiz_line_object.create(line_vals)
|
|
|
|
list_data.append(new_line_id.id)
|
|
|
|
self.write(
|
|
|
|
{'state': 'confirm', 'wiz_indent_line': [(6, False, list_data)]})
|
|
|
|
view_id = \
|
|
|
|
self.env.ref('purchase_indent.view_requisition_request_wizard')
|
|
|
|
context = dict(self._context)
|
|
|
|
return {
|
|
|
|
'views': [(view_id.id, 'form')],
|
|
|
|
'view_id': view_id.id,
|
|
|
|
'type': 'ir.actions.act_window',
|
|
|
|
'view_type': 'form',
|
|
|
|
'view_mode': 'form',
|
|
|
|
'res_model': 'wiz.requisition.request',
|
|
|
|
'target': 'new',
|
|
|
|
'res_id': self.id,
|
|
|
|
'context': context,
|
|
|
|
}
|
|
|
|
|
|
|
|
@api.multi
|
|
|
|
def action_create(self):
|
|
|
|
list_data = []
|
|
|
|
purchase_order_id = purchase_requisition_id = False
|
|
|
|
obj_history_purchase_indent = self.env['purchase.indent.history']
|
|
|
|
|
|
|
|
if self.order_type == 'po':
|
|
|
|
vals = {
|
|
|
|
'partner_id': self.partner_id.id,
|
|
|
|
'state': 'draft',
|
2018-01-29 12:35:08 +01:00
|
|
|
'branch_id': self.branch_id.id,
|
2018-01-24 07:12:32 +01:00
|
|
|
'company_id': self.purchase_indent_id.company_id.id,
|
|
|
|
}
|
2018-01-29 12:35:08 +01:00
|
|
|
purchase_order_id = self.env['purchase.order'].with_context(
|
|
|
|
{'branch_id': self.branch_id.id}).create(vals)
|
2018-01-24 07:12:32 +01:00
|
|
|
else:
|
|
|
|
vals = {
|
|
|
|
'name': self.sudo().env['ir.sequence'].next_by_code(
|
|
|
|
'purchase.order.requisition') or 'New',
|
|
|
|
'type_id': self.requisition_type_id.id,
|
2018-01-29 12:35:08 +01:00
|
|
|
'branch_id': self.branch_id.id,
|
2018-01-24 07:12:32 +01:00
|
|
|
'state': 'draft',
|
|
|
|
'company_id': self.purchase_indent_id.company_id.id,
|
|
|
|
}
|
|
|
|
purchase_requisition_id = self.env[
|
|
|
|
'purchase.requisition'].create(vals)
|
|
|
|
indent_list = []
|
|
|
|
for current_line in self.sudo().wiz_indent_line:
|
|
|
|
current_line.purchase_indent_ids.write({'state': 'requisition'})
|
|
|
|
indent_list.extend(current_line.purchase_indent_ids.ids)
|
|
|
|
line_vals = {
|
|
|
|
'product_id': current_line.product_id.id,
|
|
|
|
'product_qty': current_line.product_qty,
|
2018-01-29 12:35:08 +01:00
|
|
|
'branch_id': self.branch_id.id,
|
2018-01-24 07:12:32 +01:00
|
|
|
'purchase_indent_ids':
|
|
|
|
[(6, 0, current_line.purchase_indent_ids.ids)],
|
|
|
|
'purchase_indent_line_id':
|
|
|
|
current_line.purchase_indent_line_id.id,
|
|
|
|
}
|
|
|
|
if self.order_type == 'po':
|
|
|
|
line_vals.update({
|
|
|
|
'name': current_line.name,
|
|
|
|
'date_planned': current_line.expected_date,
|
|
|
|
'partner_id': self.partner_id.id,
|
|
|
|
'price_unit': current_line.price_unit,
|
|
|
|
'taxes_id': [(6, 0, current_line.taxes_id.ids)],
|
|
|
|
'product_uom': current_line.product_uom.id,
|
|
|
|
})
|
|
|
|
else:
|
|
|
|
line_vals.update({
|
|
|
|
'product_uom_id': current_line.product_uom.id,
|
|
|
|
})
|
|
|
|
list_data.append((0, 0, line_vals))
|
|
|
|
if len(current_line.purchase_indent_ids.ids) > 1:
|
|
|
|
for data in self.sudo().dummy_wiz_indent_line:
|
|
|
|
if data.product_id.id == current_line.product_id.id:
|
|
|
|
product_qty = data.purchase_indent_line_id.product_qty
|
|
|
|
requisition_qty = \
|
|
|
|
data.purchase_indent_line_id.requisition_qty
|
|
|
|
before_qty = product_qty - requisition_qty
|
|
|
|
data.purchase_indent_line_id.requisition_qty +=\
|
|
|
|
data.requisition_qty
|
|
|
|
obj_history_purchase_indent.create({
|
|
|
|
'purchase_indent_id': data.purchase_indent_id.id,
|
|
|
|
'product_id': data.product_id.id,
|
|
|
|
'order_id':
|
|
|
|
purchase_order_id and purchase_order_id.id,
|
|
|
|
'purchase_requisition_id':
|
|
|
|
purchase_requisition_id and
|
|
|
|
purchase_requisition_id.id,
|
|
|
|
'date': datetime.now(),
|
|
|
|
'product_qty': before_qty,
|
|
|
|
'requisition_qty': data.requisition_qty
|
|
|
|
})
|
|
|
|
else:
|
|
|
|
product_qty = current_line.purchase_indent_line_id.product_qty
|
|
|
|
requisition_qty = \
|
|
|
|
current_line.purchase_indent_line_id.requisition_qty
|
|
|
|
before_qty = product_qty - requisition_qty
|
|
|
|
current_line.purchase_indent_line_id.requisition_qty +=\
|
|
|
|
current_line.product_qty
|
|
|
|
obj_history_purchase_indent.create({
|
|
|
|
'purchase_indent_id': current_line.purchase_indent_ids.id,
|
|
|
|
'product_id': current_line.product_id.id,
|
|
|
|
'order_id': purchase_order_id and purchase_order_id.id,
|
|
|
|
'purchase_requisition_id':
|
|
|
|
purchase_requisition_id and purchase_requisition_id.id,
|
|
|
|
'date': datetime.now(),
|
|
|
|
'product_qty': before_qty,
|
|
|
|
'requisition_qty': current_line.product_qty,
|
|
|
|
})
|
|
|
|
if purchase_order_id:
|
|
|
|
purchase_order_id.write({
|
|
|
|
'order_line': list_data,
|
|
|
|
'purchase_indent_ids': [(6, 0, indent_list)]})
|
|
|
|
elif purchase_requisition_id:
|
|
|
|
purchase_requisition_id.write({
|
|
|
|
'line_ids': list_data,
|
|
|
|
'purchase_indent_ids': [(6, 0, indent_list)]})
|
|
|
|
self.check_state()
|
|
|
|
|
|
|
|
@api.multi
|
|
|
|
def check_state(self):
|
|
|
|
purchase_indent_ids = self.purchase_indent_id.search([
|
|
|
|
('category_id', '=', self.purchase_indent_id.category_id.id),
|
|
|
|
('state', 'in', ['confirm', 'requisition']),
|
2018-01-29 12:35:08 +01:00
|
|
|
('branch_id', '=', self.purchase_indent_id.branch_id.id),
|
2018-01-24 07:12:32 +01:00
|
|
|
('company_id', '=', self.purchase_indent_id.company_id.id)])
|
|
|
|
for purchase_indent_id in purchase_indent_ids:
|
|
|
|
check = False
|
|
|
|
for line in purchase_indent_id.indent_line:
|
|
|
|
if line.product_qty != line.requisition_qty:
|
|
|
|
check = False
|
|
|
|
break
|
|
|
|
else:
|
|
|
|
check = True
|
|
|
|
if check:
|
|
|
|
purchase_indent_id.write({'state': 'done'})
|
|
|
|
|
|
|
|
|
|
|
|
class WizIndentLine(models.TransientModel):
|
|
|
|
_name = 'wiz.indent.line'
|
|
|
|
_description = "Wizard Indent Line"
|
|
|
|
|
|
|
|
@api.depends('purchase_indent_line_id',
|
|
|
|
'purchase_indent_line_id.product_qty',
|
|
|
|
'purchase_indent_line_id.requisition_qty')
|
|
|
|
@api.multi
|
|
|
|
def _compute_get_rem_qty(self):
|
|
|
|
for line_id in self:
|
|
|
|
remaining_qty = 0.0
|
|
|
|
if line_id.purchase_indent_line_id:
|
|
|
|
remaining_qty = \
|
|
|
|
line_id.purchase_indent_line_id.product_qty - \
|
|
|
|
line_id.purchase_indent_line_id.requisition_qty
|
|
|
|
line_id.remaining_qty = remaining_qty
|
|
|
|
|
|
|
|
purchase_indent_ids = fields.Many2many(
|
|
|
|
'purchase.indent', string='Purchase Indent')
|
|
|
|
name = fields.Text(string='Description', required=True)
|
|
|
|
sequence = fields.Integer(string='Sequence', default=10)
|
|
|
|
product_qty = fields.Float(
|
|
|
|
string='Quantity', digits=dp.get_precision('Discount'))
|
|
|
|
expected_date = fields.Datetime(string='Expected Date', index=True)
|
|
|
|
product_uom = fields.Many2one(
|
|
|
|
'product.uom', string='Product Unit of Measure')
|
|
|
|
product_id = fields.Many2one(
|
|
|
|
'product.product', string='Product',
|
|
|
|
domain=[('purchase_ok', '=', True)],
|
|
|
|
change_default=True, required=True)
|
|
|
|
requisition_qty = fields.Float(
|
|
|
|
string="Requisition Quantity",
|
|
|
|
digits=dp.get_precision('Discount'))
|
|
|
|
wizard_indent_id = fields.Many2one(
|
|
|
|
'wiz.requisition.request', 'Wiz Requisition Request')
|
|
|
|
|
|
|
|
partner_id = fields.Many2one('res.partner', string='Partner')
|
|
|
|
price_unit = fields.Float(
|
|
|
|
string='Unit Price', digits=dp.get_precision('Product Price'))
|
|
|
|
taxes_id = fields.Many2many(
|
|
|
|
'account.tax', string='Taxes',
|
|
|
|
domain=['|', ('active', '=', False), ('active', '=', True)])
|
|
|
|
purchase_indent_line_id = fields.Many2one(
|
|
|
|
'purchase.indent.line', string="Indent Line Ref")
|
|
|
|
remaining_qty = fields.Float(
|
|
|
|
compute='_compute_get_rem_qty', string='Remaining Quantity',
|
|
|
|
store=True)
|
|
|
|
order_type = fields.Selection(
|
|
|
|
related='wizard_indent_id.order_type', string='Order Type')
|
|
|
|
|
|
|
|
|
|
|
|
class DummyWizIndentLine(models.TransientModel):
|
|
|
|
_name = 'dummy.wiz.indent.line'
|
|
|
|
_description = "Dummy Wizard Indent Line"
|
|
|
|
|
|
|
|
@api.depends('purchase_indent_line_id',
|
|
|
|
'purchase_indent_line_id.product_qty',
|
|
|
|
'purchase_indent_line_id.requisition_qty')
|
|
|
|
@api.multi
|
|
|
|
def _compute_get_rem_qty(self):
|
|
|
|
for line_id in self:
|
|
|
|
remaining_qty = 0.0
|
|
|
|
if line_id.purchase_indent_line_id:
|
|
|
|
remaining_qty = \
|
|
|
|
line_id.purchase_indent_line_id.product_qty - \
|
|
|
|
line_id.purchase_indent_line_id.requisition_qty
|
|
|
|
line_id.remaining_qty = remaining_qty
|
|
|
|
|
|
|
|
purchase_indent_id = fields.Many2one(
|
|
|
|
'purchase.indent', 'Purchase Indent',
|
|
|
|
domain="[('id', '=', purchase_indent_id)]")
|
|
|
|
name = fields.Text(string='Description')
|
|
|
|
sequence = fields.Integer(string='Sequence', default=10)
|
|
|
|
product_qty = fields.Float(
|
|
|
|
string='Quantity', digits=dp.get_precision('Discount'))
|
|
|
|
dummy_product_qty = fields.Float(string='Quantity',
|
|
|
|
digits=dp.get_precision('Discount'))
|
|
|
|
expected_date = fields.Datetime(string='Expected Date', index=True)
|
|
|
|
product_uom = fields.Many2one(
|
|
|
|
'product.uom', string='Product Unit of Measure')
|
|
|
|
product_id = fields.Many2one(
|
|
|
|
'product.product', string='Product',
|
|
|
|
domain="[('purchase_ok', '=', True), ('id', '=', product_id)]",
|
|
|
|
change_default=True, required=True)
|
|
|
|
company_id = fields.Many2one(
|
|
|
|
'res.company', related='purchase_indent_id.company_id',
|
|
|
|
string='Company', store=True, readonly=True)
|
|
|
|
requisition_qty = fields.Float(
|
|
|
|
string="Requisition Quantity",
|
|
|
|
digits=dp.get_precision('Product Unit of Measure'))
|
|
|
|
wizard_indent_id = fields.Many2one(
|
|
|
|
'wiz.requisition.request', 'Wiz Requisition Request')
|
|
|
|
partner_id = fields.Many2one(
|
|
|
|
'res.partner', related='purchase_indent_id.partner_id',
|
|
|
|
string='Partner', readonly=True, store=True)
|
|
|
|
indent_requ_date = fields.Date(
|
|
|
|
related='purchase_indent_id.request_date',
|
|
|
|
string='Request Date', readonly=True, store=True)
|
|
|
|
purchase_indent_line_id = fields.Many2one(
|
|
|
|
'purchase.indent.line', string="Indent Line Ref")
|
|
|
|
remaining_qty = fields.Float(
|
|
|
|
compute='_compute_get_rem_qty', string='Remaining Quantity',
|
|
|
|
store=True)
|
|
|
|
|
|
|
|
@api.onchange('requisition_qty')
|
|
|
|
def onchange_requisition_qty(self):
|
|
|
|
warning = {}
|
|
|
|
if self.requisition_qty < 0:
|
|
|
|
warning.update({
|
|
|
|
'title': _("Warning"),
|
|
|
|
'message': _("Requisition Quantity (%s) can not be \
|
|
|
|
Negative!") % (
|
|
|
|
formatLang(self.env, self.requisition_qty, digits=2))
|
|
|
|
})
|
|
|
|
self.requisition_qty = False
|
|
|
|
return {'warning': warning}
|
|
|
|
|
|
|
|
@api.model
|
|
|
|
def create(self, values):
|
|
|
|
if values.get('dummy_product_qty', False):
|
|
|
|
values.update({'product_qty': values.get('dummy_product_qty')})
|
|
|
|
res = super(DummyWizIndentLine, self).create(values)
|
|
|
|
return res
|
|
|
|
|
|
|
|
@api.model
|
|
|
|
def write(self, values):
|
|
|
|
if values.get('dummy_product_qty', False):
|
|
|
|
values.update({'product_qty': values.get('dummy_product_qty')})
|
|
|
|
res = super(DummyWizIndentLine, self).write(values)
|
|
|
|
return res
|