0

I have inherited account.move model and added job_card_id field(many2one) in it, as shown as below :

Image

Below given is Image of Selected Job Card :

Image

Below given is code of my model and I also tried creating function below fields :

    class JobCard(models.Model):
    _name = "job.card"
    _inherit = ['mail.thread', 'mail.activity.mixin']
    _description = "Job Card Master"
    _rec_name = 'job_card_number'

    job_card_number = fields.Char(string='Job Card No.', readonly=True)
    customer_id = fields.Many2one('res.partner', string="Customer Name", tracking=True)
    vehicle_id = fields.Many2one('res.partner.line', string="Vehicle", tracking=True,
                                 domain="[('x_customer_id','=',customer_id)]")
    date_time_of_invoice = fields.Datetime(string='Date & Time of Invoice', tracking=True, default=fields.Datetime.now)
    start_date_time = fields.Datetime(string='Start Date & Time', tracking=True)
    end_date_time = fields.Datetime(string='End Date & Time', tracking=True)
    priority = fields.Selection([
        ('0', 'Normal'),
        ('1', 'Low'),
        ('2', 'High'),
        ('3', 'Very High')], string="Priority")  # priority widget
    state = fields.Selection([
        ('draft', 'Draft'),
        ('in_progress', 'In Progress'),
        ('done', 'Done'),
        ('cancel', 'Cancelled')], string="Status", default='draft', required=True)  # status bar

    active = fields.Boolean(string="Active", default=True, tracking=True)

    x_product_ids = fields.Many2many('job.card.line', 'product_id', string="Job Card Details")
    x_quantity_ids = fields.One2many('job.card.line', 'quantity', string="Job Card Details")
    x_price_ids = fields.One2many('job.card.line', 'price', string="Job Card Details")
    x_total_ids = fields.One2many('job.card.line', 'total', string="Job Card Details")
    x_employee_ids = fields.One2many('job.card.line', 'employee_id', string="Job Card Details")
    x_job_card_ids = fields.One2many('job.card.line', 'job_card_id', string="Job Card Details")

    job_card_count = fields.Integer(compute='compute_job_card_count', string='Job Card Count')

    def get_invoice_line_vals(self):
        vals_list = []
        for job_card_line in self.x_product_ids:
            vals_list.append({
                ' price_unit': job_card_line.price_unit,
                'quantity': job_card_line.quantity
            })
        return vals_list

Below given is code of inherited model and also added onchange function :

class CustomInvoice(models.Model):
_inherit = "account.move"

job_card_id = fields.Many2one('job.card', string="Job Card", domain="[('customer_id','=',partner_id)]",
                              tracking=True)

@api.onchange('job_card_id')
def _onchange_job_card_id(self):
    # creates your invoice lines vals according to your values
    invoice_lines_vals = self.job_card_id.get_invoice_line_vals()
    self.update({'invoice_line_ids': [(5, 0)] + [(0, 0, vals) for vals in invoice_lines_vals]})

Below given is code of my job card line :

class JobCardLine(models.Model):
_name = "job.card.line"

job_card_id = fields.Many2one('job.card', string="Job Card Id", tracking=True)
product_id = fields.Many2one('product.template', string="Product", tracking=True)
quantity = fields.Integer(string="Quantity", tracking=True)
# price = fields.Char(string="Price")
price = fields.Float(string="Price")
total = fields.Integer(string='Total', compute='_compute_total', tracking=True,
                       help="This field will be calculated from quantity and price !")
employee_id = fields.Many2one('hr.employee', string="Employee", tracking=True)

x_job_card_id = fields.Many2one('res.partner', string="Vehicle Details")

@api.onchange('product_id')
def _on_change_product_id(self):
    self.price = self.product_id.list_price

@api.depends('quantity', 'price')
def _compute_total(self):
    print("self........", self)
    for rec in self:
        rec.total = rec.quantity * rec.price

Actually I wanted to add product line of selected job card into Invoice product line automatically when I select the job card.

But I am getting error as shown below :

Error

mr.robot
  • 1
  • 1
  • You got that error because you have no field named `line_ids` in `job.card` model. Maybe you need to change it to `x_product_ids`. – Kenly Jun 19 '22 at 10:52
  • @Kenly I tried that it is giving error : `TypeError: 'int' object is not iterable` – mr.robot Jun 20 '22 at 05:20
  • I wanted to add product line of selected job card into Invoice product line automatically when I select the job card. Am I going in right way ?? – mr.robot Jun 20 '22 at 05:29
  • If you clear the invoice lines each time the job card changes, Odoo will remove the manually entered lines – Kenly Jun 20 '22 at 11:12

1 Answers1

0

You got that error because you have no field named line_ids in job.card model. Maybe you need to change it to x_product_ids.

The TyprError (int object is not iterable) is caused by the first tuple passed to the write method :

(6, 0, 0)

Odoo expects the third parameter to be iterable. If you need to clear the list, use (5,0)

Avoid calling the write method inside an onchange function. You can read the following danger notice in the official onchange documentation:

Danger

Since @onchange returns a recordset of pseudo-records, calling any one of the
CRUD methods (create(), read(), write(), unlink()) on the
aforementioned recordset is undefined behaviour, as they potentially do not exist
in the database yet.

Instead, simply set the record’s field like shown in the example above or call the
update() method.

Edit:

You have two errors in get_invoice_line_vals function

1/ ValueError:

Invalid field ' price_unit' on model 'account.move.line'

You need to remove the space at the beginning.

2/ AttributeError:

'job.card.line' object has no attribute 'price_unit'.

Use the price field instead.

Kenly
  • 24,317
  • 7
  • 44
  • 60
  • I used `(5,0)` in write method , it is not giving any error but when I select job_card it is not setting the product line of invoice. How can I use that `update()` method ?? – mr.robot Jun 20 '22 at 12:00
  • You can call `update` method like you call the write method `self.update({'invoice_line_ids': [(5, 0)] + [(0, 0, vals) for vals in invoice_lines_vals]})`. You will need to provide all the required fields. – Kenly Jun 20 '22 at 13:17
  • Tried doing with update method as you suggested but not getting job card's product line in invoice line. – mr.robot Jun 21 '22 at 05:07
  • I tried your example above, and a line is added to the invoices lines (only the price and quantity) when we select the job card. The problem is that you can't save the invoice because some required fields are not set – Kenly Jun 21 '22 at 08:05
  • Please, update the question with your code – Kenly Jun 21 '22 at 08:25
  • Updated question please check and revert. – mr.robot Jun 21 '22 at 09:59
  • I tested your code after correcting the two errors, and it worked as expected – Kenly Jun 21 '22 at 10:39