2017-10-16 4 views
1

Ich möchte meinen erstellten Datensatz zu one2many Feld hinzufügen. Es ergibt sich jedoch ValueError: Erwartetes Singleton: product.job_line (762, 763).Odoo Wie existierender Datensatz zum Feld one2many hinzugefügt wird?

Ich weiß nicht, warum es nicht in zwei Objekte trennt, aber es in ein Objekt zusammenführen, wenn JobContainer die Methode write aufrufen. Danach ergibt sich der Fehler wie zuvor.

Wie löst man das?

Hier ist mein Code von SaleOrder:

# -*- coding: utf-8 -*- 
import logging 
from odoo import models, fields, api 

_logger = logging.getLogger(__name__) 

class SaleOrder(models.Model): 
    _inherit = 'sale.order' 

    job_container = fields.One2many('job.container', 'order') 
    discount = fields.Float() 
    state = fields.Selection(
     [ 
      ('draft', 'Quotation'), 
      ('sent', 'Quotation Sent'), 
      ('pending', 'Pending Approval'), 
      ('sale', 'Sales Order'), 
      ('done', 'Locked'), 
      ('cancel', 'Cancelled'), 
     ], 
     string='Status', readonly=True, copy=False, index=True, 
     track_visibility='onchange', default='draft' 
    ) 

    @api.onchange('discount') 
    def _amount_all(self): 
     super(SaleOrder, self)._amount_all() 
     for order in self: 
      total = order.amount_total 
      if order.discount > 1: 
       total -= order.discount 
      else: 
       total -= total * order.discount 
      order.update({ 
       'amount_total': total 
      }) 

    @api.multi 
    def action_confirm(self): 
     if self.state != 'pending' and self.get_full_price() != self.amount_total: 
      self.state = 'pending' 
     elif self.job_container: 
      self.state = 'sale' 
      self.confirmation_date = fields.Datetime.now() 
      self.job_container.confirmation_date = self.confirmation_date 
     else: 
      self.create_job_container() 
      self.delegate_job_values() 
      super(SaleOrder, self).action_confirm() 

    def delegate_job_values(self): 
     total_price = self.amount_total 
     price_list = [] 
     for line in self.order_line: 
      qty = line.product_uom_qty 
      product = line.product_id.product_tmpl_id 
      price = line.price_total*self.get_discount_percent()/qty 
      if price == 0: 
       price = line.price_total/qty 
      for _ in range(0, int(qty)): 
       price_list += product.create_price_list(price) 
     for index in range(0, len(self.job_container.job_lines)): 
      total_price -= price_list[index] 
      if index == len(self.job_container.job_lines)-1: 
      self.job_container.job_lines[index].update({ 
        'cost': price_list[index] + total_price, 
        'order':self.id, 
       }) 
      else: 
       self.job_container.job_lines[index].update({ 
        'cost': price_list[index], 
        'order': self.id, 
       }) 

    def get_full_price(self): 
     total_price = 0 
     for line in self.order_line: 
      total_price += line.product_id.product_tmpl_id.list_price*line.product_uom_qty 
     return total_price 

    def create_job_container(self): 
     container = self.env['job.container'].create({ 
      'order': self.id, 
      'partner': self.partner_id.id, 
      'confirmation_date': fields.Datetime.now() 
     }) 
     for line in self.order_line: 
      qty = line.product_uom_qty 
      product = line.product_id.product_tmpl_id 
      job_lines = [] 
      for _ in range(0, int(qty)): 
       for job_line in product.create_job_lines(): 
        _logger.info("JL : "+str(job_line)) 
        job_lines.append(job_line.id) 
        # container.add_job_line(job_line) 
        # container.update({ 
        #  'job_lines': [(1,job_line.id,job_line)] 
        # }) 
       container.job_lines += job_line 
     _logger.info('Job Line '+str(job_lines)) 
     # container.job_lines = job_lines 
     container.update_job_lines_left() 

    @api.one 
    def action_approve(self): 
     self.action_confirm() 

    def write(self, val): 
     old_state = self.state 
     _logger.info('Value : '+str(val)) 
     _logger.info('Old State '+old_state) 
     super(SaleOrder, self).write(val) 
     if old_state == 'sale' and 'confirmation_date' not in val: 
      self.state = 'pending' 
     return True 

    def get_discount_percent(self): 
     if self.discount < 1: 
      return self.discount 
     else: 
      return self.discount/(self.amount_total+self.discount) 

    def update_invoice_order(self): 
     for invoice in self.invoice_ids: 
      invoice.update({'order':self.id}) 

    @api.multi 
    def action_invoice_create(self, grouped=False, final=False): 
     super(SaleOrder, self).action_invoice_create(grouped, final) 
     self.update_invoice_order() 

    @api.one 
    def pending(self): 
     self.state = 'pending' 
     self.job_container.unpending() 

Hier ist mein Code Hiobs Container:

# -*- coding: utf-8 -*- 
from odoo import models, fields, api 
import logging 
_logger = logging.getLogger(__name__) 

class JobContainer(models.Model): 
    _name = 'job.container' 
    _order = 'jobs_left' 
    _inherit = ['mail.thread'] 

    order = fields.Many2one('sale.order', readonly=True) 
    partner = fields.Many2one('res.partner', readonly=True) 
    confirmation_date = fields.Datetime(readonly=True, track_visibility='onchange') 
    job_lines = fields.One2many('product.job_line', 'container') 
    jobs_left = fields.Integer(compute='update_job_lines_left') 
    to_pending = fields.Boolean() 

    def pending(self): 
     self.order.pending() 

    def unpending(self): 
     self.to_pending = False 
     for line in self.job_lines: 
      line.to_pending = False 

    @api.one 
    def update_job_lines_left(self): 
     left = 0 
     for job_line in self.job_lines: 
      if not job_line.is_finish and not job_line.state=='cancel': 
       left += 1 
     self.jobs_left = left 

    def adjust_cost(self,cost): 
     sum = 0 
     for line in self.job_lines: 
      if line.state=='active' and not line.is_finish: 
       line.cost+=round(cost/len(self.job_lines),2) 
       sum += line.cost 
     left = self.order.amount_total-sum 
     for line in self.job_lines: 
      if line.state=='active' and not line.is_finish: 
       line.cost+=left 
       break 

    @api.onchange('job_lines') 
    def notify_pending(self): 
     _logger.info("IN") 
     self.to_pending = True 

    @api.multi 
    def write(self,val): 
     _logger.info(val) 
     super(JobContainer,self).write(val) 
     _logger.info(str(val)) 
     if self.to_pending: 
      _logger.info("INNNN") 
      self.pending() 
     return True 

Antwort

1

einen Blick auf diese Antwort nehmen: https://stackoverflow.com/a/26012940/7990703

(0, 0, { values }) link to a new record that needs to be created with the given values dictionary 
(1, ID, { values }) update the linked record with id = ID (write *values* on it) 
(2, ID)    remove and delete the linked record with id = ID (calls unlink on ID, that will delete the object completely, and the link to it as well) 

Example: 
[(0, 0, {'field_name':field_value_record1, ...}), (0, 0, {'field_name':field_value_record2, ...})] 
Verwandte Themen