## Author Mufti Muntasir Ahmed 20-06-2021

from odoo import api, fields, tools, models, _
from odoo.exceptions import UserError, ValidationError
from datetime import timedelta

class LoadingMaster(models.Model):
    _name = 'loading.master'
    _description = 'Loading Master'
    _order = 'id desc'

    READONLY_STATES = {
        'purchase': [('readonly', True)],
        'done': [('readonly', True)],
        'cancel': [('readonly', True)],
    }

    name = fields.Char('Loading Number')
    partner_id = fields.Many2one('res.partner', string='Courier')
    scan = fields.Char('Scan Your Invoice')
    vehicle_number = fields.Char('Vehicle Number')
    assign_name = fields.Char('Assign To')
    loading_date = fields.Datetime("Loading Date", required=False, readonly=True, index=True, copy=False,
                                   default=fields.Datetime.now)
    remarks = fields.Text('Any Remarks')
    loading_amount = fields.Float(string='Loading Price')
    warehouse_id = fields.Many2one('stock.warehouse', string='Warehouse')
    loading_master_line_ids = fields.One2many('loading.master.line', 'loading_master_id', string='Loading Master lines')
    state = fields.Selection([
        ('pending', 'Pending'),
        ('confirm', 'Confirm'),
        ('cancel', 'Cancelled'),
    ], string='Status', readonly=True, copy=False, index=True, tracking=3, default='pending')

    @api.model
    def create(self, vals):
        res = super(LoadingMaster, self).create(vals)
        pick_number = "LOAD0" + str(res.id)
        res.name = pick_number
        return res

    def confirm_loading(self):
        inv_lists = []
        for rec in self:

            if rec.state == 'pending':

                manifest_vals={
                    'name':'',
                    'vehicle_number':rec.vehicle_number,
                    'assign_name':rec.assign_name,
                    'manifest_date':rec.loading_date,
                    'remarks':rec.remarks,
                    'manifest_amount':rec.loading_amount,
                    'warehouse_id':rec.warehouse_id.id
                }
                mianfest_lines=[]
                for load_itm in rec.loading_master_line_ids:
                    if load_itm.invoice_id.loaded == True:
                        raise ValidationError(_('You can not confirm. Invoices have been assigned to other load master'))
                    inv_lists.append(load_itm.invoice_id.id)
                    mianfest_lines.append([0, False, {
                        'order_no': load_itm.order_no,
                        'invoice_id': load_itm.invoice_id.id,
                        'customer_id': load_itm.customer_id.id,
                        'phone_no': load_itm.phone_no,
                        'address_line': load_itm.address_line,
                        'payment_type': load_itm.payment_type,
                        'amount': load_itm.amount,
                        'area': load_itm.area,
                        'status': load_itm.status

                    }])

                manifest_vals['manifest_process_line_ids'] = mianfest_lines

                packing_ids = self.env['manifest.process'].create(manifest_vals)
                if len(inv_lists) >0:

                    self._cr.execute("update account_move set loaded='True' where id in %s",
                                     (tuple(inv_lists),))
                    self._cr.commit()


                rec.write({'state': 'confirm'})


        return True

    def cancel_loading(self):
        for rec in self:
            inv_lists = []
            if rec.state == 'pending':
                for load_itm in rec.loading_master_line_ids:
                    inv_lists.append(load_itm.invoice_id.id)

                if len(inv_lists) >0:

                    self._cr.execute("update account_move set loaded='False' where id in %s",
                                     (tuple(inv_lists),))
                    self._cr.commit()

                rec.write({'state': 'cancel'})
            else:
                raise ValidationError(_('You can not cancel at this state'))
        return True

    @api.onchange('scan')
    def po_irn_barcode_onchange(self):

        try:

            inv_id = str(self.scan)
            inv_env = self.env['account.move']
            inv_obj = inv_env.search([('id', '=', inv_id)])


            po_line_list = list()

            for inv_line in inv_obj:
                item = {

                    'order_no': inv_line.invoice_origin,
                    'invoice_id': inv_line.id,
                    'customer_id': inv_line.partner_id.id,
                    'phone_no': inv_line.partner_shipping_id.mobile,
                    'address_line': inv_line.partner_shipping_id.id,
                    'payment_type': inv_line.narration,
                    'amount': inv_line.amount_residual,
                    'area': inv_line.partner_shipping_id.city,

                }
                po_line_list.append((0, 0, item))

                self.loading_amount += inv_line.amount_residual


            self.loading_master_line_ids = po_line_list

            self.scan = ""

        except:

            self.scan = ""

class LoadingMasterLine(models.Model):
    _name = 'loading.master.line'
    _description = 'Loading Master Line'

    loading_master_id = fields.Many2one('loading.master', string='Product Picking Entry', index=True, required=True,
                                         readonly=True, auto_join=True, ondelete="cascade")
    order_no = fields.Char('Order No')
    invoice_id = fields.Many2one('account.move', string='Invoice ID')
    customer_id = fields.Many2one('res.partner', string='Customer')
    phone_no = fields.Char('Phone No')
    address_line = fields.Char('Address')
    payment_type = fields.Char('Payment Type')
    amount = fields.Float('Amount')
    area = fields.Char('Area')
    status = fields.Char('Status')








