# Author Mufti Muntasir Ahmed 20-06-2021

from odoo import api, fields, models, _
import datetime
import json
from datetime import date, datetime
from odoo.osv import osv
import requests


class ManifestWithFullReturn(models.Model):
    _name = "manifest.with.full.return"
    _description = "Manifest with full return"

    invoice_id = fields.Integer('Invoice ID')
    manifest_line_id = fields.Integer('Manifest Line ID')
    order_no = fields.Char('Order No')
    return_reason = fields.Selection([
        ('cash_problems', 'Cash Problems'),
        ('customer_did_not_ordered', 'Customer Did Not Ordered'),
        ('customer_not_interested', 'Customer Not Interested'),
        ('customer_not_reachable', 'Customer Not Reachable'),
        ('customer_wants_full_delivery', 'Customer Wants Full Delivery'),
        ('customer_wants_high_quality', 'Customer Wants High Quality'),
        ('customer_wants_low_quality', 'Customer Wants Low Quality'),
        ('fake_order', 'Fake Order'),
        ('late_delivery', 'Late Delivery'),
        ('less_qty_required', 'Less Qty Required'),
        ('more_qty_required', 'More Qty Required'),
        ('office_closed', 'Office Closed'),
        ('pack_size_issue', 'Pack Size Issue'),
        ('price_issue', 'Price Issue'),
        ('product_damaged', 'Product Damaged'),
        ('product_mismatch', 'Product Mismatch'),
        ('returned_due_to_other_products', 'Returned Due to Other Products'),
        ('wrong_address', 'Wrong Address'),
        ('wrong_order_placed', 'Wrong Order Placed'),
        ('wrongly_packed', 'Wrongly Packed'),
    ], 'Return Reason', index=True),
    delivery_line = fields.One2many('manifest.with.full.return.line', 'deliver_line_id', 'Delivery Line', required=True)

    @api.model
    def default_get(self, fields):

        res = super(ManifestWithFullReturn, self).default_get(fields)
        man_line_obj = self.env["manifest.process.line"]
        man_line = man_line_obj.browse(self.env.context['active_id'])
        res['invoice_id'] = man_line.invoice_id.id
        res['order_no'] = man_line.order_no
        res['manifest_line_id'] = man_line.id

        return res

    def create_deliver_with_full_return(self):
        ### Update manifest line amount

        return_amount = 0
        inv_data = self.env['account.move'].search([('id', '=', self.invoice_id)], limit=1)
        for inv_item in inv_data:
            return_amount = inv_item.amount_residual

        today_date = fields.date.today()


        self._cr.execute("update account_move set full_return='True' where id in %s", (tuple([self.invoice_id]),))
        self._cr.execute(
            "update manifest_process_line set manifest_out_status ='assigned',full_return=True, return_amount=%s where id=%s",
            ([return_amount, self.manifest_line_id]))
        self._cr.commit()

        ### Ends Here Delivery Amount Update


        return True


class ManifestWithFullReturnLine(models.Model):
    _name = "manifest.with.full.return.line"
    _description = "Manifest with full return line"

    product_id = fields.Integer('Product ID')
    description = fields.Char('Description')
    quantity = fields.Float('Quantity')
    delivered = fields.Float('Delivered')
    return_manifest = fields.Float('Return')
    amount = fields.Float('Amount')
    return_reason = fields.Selection([
        ('cash_problems', 'Cash Problems'),
        ('customer_did_not_ordered', 'Customer Did Not Ordered'),
        ('customer_not_interested', 'Customer Not Interested'),
        ('customer_not_reachable', 'Customer Not Reachable'),
        ('customer_wants_full_delivery', 'Customer Wants Full Delivery'),
        ('customer_wants_high_quality', 'Customer Wants High Quality'),
        ('customer_wants_low_quality', 'Customer Wants Low Quality'),
        ('fake_order', 'Fake Order'),
        ('late_delivery', 'Late Delivery'),
        ('less_qty_required', 'Less Qty Required'),
        ('more_qty_required', 'More Qty Required'),
        ('office_closed', 'Office Closed'),
        ('pack_size_issue', 'Pack Size Issue'),
        ('price_issue', 'Price Issue'),
        ('product_damaged', 'Product Damaged'),
        ('product_mismatch', 'Product Mismatch'),
        ('returned_due_to_other_products', 'Returned Due to Other Products'),
        ('wrong_address', 'Wrong Address'),
        ('wrong_order_placed', 'Wrong Order Placed'),
        ('wrongly_packed', 'Wrongly Packed'),
    ], 'Return Reason', index=True)
    deliver_line_id = fields.Many2one('manifest.with.full.return', 'Delivery Line', required=True,
                                      ondelete='cascade', index=True, readonly=True)


class ManifestWithReturn(models.Model):
    _name = "manifest.with.return"
    _description = "Manifest with return"

    invoice_id = fields.Integer('Invoice ID')
    order_no = fields.Char('Order No')
    delivery_date = fields.Date('Delivery Date')
    delivery_line = fields.One2many('manifest.with.return.line', 'deliver_line_id', 'Delivery Line',
                                    required=True)
    delivery_time = fields.Selection([
        ('07 AM - 08 AM', '07 AM - 08 AM'),
        ('08 AM - 09 AM', '08 AM - 09 AM'),
        ('09 AM - 10 AM', '09 AM - 10 AM'),
        ('10 AM - 11 AM', '10 AM - 11 AM'),
        ('11 AM - 12 PM', '11 AM - 12 PM'),
        ('12 PM - 01 PM', '12 PM - 01 PM'),
        ('01 PM - 02 PM', '01 PM - 02 PM'),
        ('02 PM - 03 PM', '02 PM - 03 PM'),
        ('03 PM - 04 PM', '03 PM - 04 PM'),
        ('04 PM - 05 PM', '04 PM - 05 PM'),
        ('05 PM - 06 PM', '05 PM - 06 PM'),
        ('06 PM - 07 PM', '06 PM - 07 PM'),
        ('07 PM - 08 PM', '07 PM - 08 PM'),
        ('08 PM - 09 PM', '08 PM - 09 PM'),
        ('09 PM - 10 PM', '09 PM - 10 PM'),
    ], 'Deliver Time', index=True)

    @api.model
    def default_get(self, fields):
        res = super(ManifestWithReturn, self).default_get(fields)

        man_line_obj = self.env["manifest.process.line"]
        man_line = man_line_obj.browse(self.env.context['active_id'])

        res['invoice_id'] = man_line.invoice_id.id
        res['order_no'] = man_line.magento_no
        res['delivery_date'] = date.today().strftime("%Y-%m-%d")


        return res

    def create_deliver_with_return(self):
        return_amount = 0

        inv_data = self.env['account.move'].search([('id', '=', self.invoice_id)], limit=1)
        for inv_item in inv_data:
            return_amount = inv_item.amount_residual

        self._cr.execute("update account_move set full_return='True' where id=%s", ([self.invoice_id,]))
        self._cr.execute(
            "update manifest_process_line set manifest_out_status ='assigned',full_return='True', return_amount=%s where id=%s",
            ([return_amount, self.manifest_line_id]))
        self._cr.commit()

        return True

    def create_deliver_with_return_old(self):
        context = None
        delivery_return = self.browse()
        context['source'] = self.env.context.get('source') if context.get('source') else 'Web'

        for line in delivery_return.delivery_line:
            if line.delivered < 0 or line.delivered > line.quantity:
                raise osv.except_osv(_('Warning!'), _('Delivered quantity should be within ordered quantity!!!'))

        man_line_obj = self.env['manifest.process.line']
        man_line_list = man_line_obj.search([('invoice_id', '=', delivery_return.invoice_id),
                                             ('reschedule', '=', False)])
        man_line = man_line_obj.browse(man_line_list)


        out_data = {
            'name': delivery_return.order_no,
            'man_name': str(man_line.wms_manifest_id.name),
            'delivery_date': delivery_return.delivery_date,
            'delivery_time': delivery_return.delivery_time,
            'source': context.get('source') if context.get('source') else 'Web',
            'delivery_done_by': self.env.uid,
            'delivery_done_datetime': datetime.datetime.today(),

        }

        outbound_line_list = list()

        for line in delivery_return.delivery_line:
            if not line.return_reason and (float(line.quantity) - float(line.delivered)) > 0:
                raise osv.except_osv(_('Warning!'), _('Reason can not be blank!!!'))

            if float(line.quantity) > 0.00:
                outbound_line_list.append([0, False, {
                    'invoice_id': delivery_return.invoice_id,
                    'magento_no': delivery_return.order_no,
                    'description': str(line.description),
                    'product_id': line.product_id,
                    'amount': float(line.amount),
                    'quantity': float(line.quantity),
                    'delivered': float(line.delivered),
                    'return_reason': str(line.return_reason),
                }])

        out_data['outbound_line'] = outbound_line_list

        context['manifest_line_id'] = man_line.id

        wms_man_out = self.env["wms.manifest.outbound"]
        man_out_id = wms_man_out.create(out_data)

        returned_qty = 0
        man_out = wms_man_out.browse([man_out_id])
        for line_return in man_out.outbound_line:
            if line_return.return_qty > 0:
                returned_qty += line_return.return_qty

        source = context['source']
        delivery_done_by = self.env.uid
        delivery_done_datetime = datetime.datetime.today()
        if man_out_id and returned_qty > 0:
            wms_man_out.receipt_return([man_out_id])

            man_line_obj.write(man_line_list, {'manifest_out_status': 'assigned', 'partial_delivered': True,
                                               'source': source,
                                               'delivery_done_by': delivery_done_by,
                                               'delivery_done_datetime': delivery_done_datetime
                                               })
        else:
            man_line_obj.write(man_line_list,
                               {'manifest_out_status': 'assigned', 'full_delivered': True, 'source': source,
                                'delivery_done_by': delivery_done_by, 'delivery_done_datetime': delivery_done_datetime})

        # --------------------------------------------------
        data = dict()
        data['name'] = str(man_line.magento_no)
        data['invoice_id'] = delivery_return.invoice_id
        data['delivery_date'] = delivery_return.delivery_date
        data['delivery_time'] = delivery_return.delivery_time
        self.env['manifest.process'].process_confirm(data)
        # --------------------------------------------------

        return True


class ManifestWithReturnLine(models.Model):
    _name = "manifest.with.return.line"
    _description = "Manifest with return line"

    product_id = fields.Integer('Product ID')
    description = fields.Char('Description')
    quantity = fields.Float('Quantity')
    delivered = fields.Float('Delivered')
    returned_qty = fields.Float('Return')
    return_manifest = fields.Float('Return')
    amount = fields.Float('Amount')
    return_reason = fields.Selection([
        ('sku_full_received', 'SKU Full Received'),
        ('cash_problems', 'Cash Problems'),
        ('customer_did_not_ordered', 'Customer Did Not Ordered'),
        ('customer_not_interested', 'Customer Not Interested'),
        ('customer_not_reachable', 'Customer Not Reachable'),
        ('customer_wants_full_delivery', 'Customer Wants Full Delivery'),
        ('customer_wants_high_quality', 'Customer Wants High Quality'),
        ('customer_wants_low_quality', 'Customer Wants Low Quality'),
        ('fake_order', 'Fake Order'),
        ('late_delivery', 'Late Delivery'),
        ('less_qty_required', 'Less Qty Required'),
        ('more_qty_required', 'More Qty Required'),
        ('office_closed', 'Office Closed'),
        ('pack_size_issue', 'Pack Size Issue'),
        ('price_issue', 'Price Issue'),
        ('product_damaged', 'Product Damaged'),
        ('product_mismatch', 'Product Mismatch'),
        ('returned_due_to_other_products', 'Returned Due to Other Products'),
        ('wrong_address', 'Wrong Address'),
        ('wrong_order_placed', 'Wrong Order Placed'),
        ('wrongly_packed', 'Wrongly Packed'),
    ], 'Return Reason', index=True)
    deliver_line_id = fields.Many2one('manifest.with.return', 'Delivery Line', required=True, ondelete='cascade',
                                      index=True, readonly=True)



    @api.onchange('delivered')
    def _onchange_return_qty(self):
        self.returned_qty = self.quantity - self.delivered if self.quantity - self.delivered > 0 else 0


class ManifestWithFullDelivered(models.Model):
    _name = "manifest.with.full.delivered"
    _description = "Manifest with full Delivered"

    invoice_id = fields.Integer('Invoice ID')
    manifest_line_id = fields.Integer('Manifest Line ID')
    order_no = fields.Char('Order No')
    delivery_date = fields.Datetime('Delivery Date', default=lambda self: fields.Datetime.now())
    deliver_time = fields.Selection([
        ('07 AM - 08 AM', '07 AM - 08 AM'),
        ('08 AM - 09 AM', '08 AM - 09 AM'),
        ('09 AM - 10 AM', '09 AM - 10 AM'),
        ('10 AM - 11 AM', '10 AM - 11 AM'),
        ('11 AM - 12 PM', '11 AM - 12 PM'),
        ('12 PM - 01 PM', '12 PM - 01 PM'),
        ('01 PM - 02 PM', '01 PM - 02 PM'),
        ('02 PM - 03 PM', '02 PM - 03 PM'),
        ('03 PM - 04 PM', '03 PM - 04 PM'),
        ('04 PM - 05 PM', '04 PM - 05 PM'),
        ('05 PM - 06 PM', '05 PM - 06 PM'),
        ('06 PM - 07 PM', '06 PM - 07 PM'),
        ('07 PM - 08 PM', '07 PM - 08 PM'),
        ('08 PM - 09 PM', '08 PM - 09 PM'),
        ('09 PM - 10 PM', '09 PM - 10 PM'),
    ], 'Deliver Time', index=True)

    @api.model
    def default_get(self, fields):
        res = super(ManifestWithFullDelivered, self).default_get(fields)

        man_line_obj = self.env["manifest.process.line"]
        man_line = man_line_obj.browse(self.env.context['active_id'])

        res['invoice_id'] = man_line.invoice_id.id
        res['order_no'] = man_line.order_no
        res['manifest_line_id'] = man_line.id

        return res

    def create_full_delivery(self):


        ### Update manifest line amount

        delivered_amount = 0
        inv_data = self.env['account.move'].search([('id', '=', self.invoice_id)], limit=1)
        mobile_no=''
        order_no=' '
        for inv_item in inv_data:
            delivered_amount = inv_item.amount_residual
            mobile_no = inv_item.partner_shipping_id.phone if inv_item.partner_shipping_id.phone else inv_item.partner_shipping_id.mobile
            order_no = inv_item.invoice_origin

        today_date = fields.date.today()

        self._cr.execute("update account_move set delivered='True' where id in %s", (tuple([self.invoice_id]),))
        self._cr.execute("update manifest_process_line set manifest_out_status ='assigned',full_delivered='True', delivered_amount=%s,delivery_date=%s,deliver_time=%s where id=%s",
                         ([delivered_amount,self.delivery_date,self.deliver_time,self.manifest_line_id]))
        self._cr.commit()


        ### Ends Here Delivery Amount Update

        ## Send SMS Section

        mobile_no = str(mobile_no)
        if len(mobile_no)>10:
            sms_text = "Dear valued customer, your order %23" + str(
                order_no) + " has been delivered. Thank you for choosing Walcart."
            try:

                basic_urls = "https://api.mobireach.com.bd/SendTextMessage?Username=walton_api&Password=Walton20@19&From=walcart&To="
                params = mobile_no + "&Message=" + sms_text
                final_url = basic_urls + params

                r = requests.get(final_url)
            except:
                pass

        ## Ends here the SMS

        return True


class ManifestReschedule(models.Model):
    _name = "manifest.reschedule"
    _description = "Manifest Reschedule"

    invoice_id = fields.Integer('Invoice ID')
    manifest_line_id = fields.Integer('Manifest Line ID')
    ndr = fields.Selection([
        ('cash_problems', 'Cash Problems'),
        ('customer_did_not_ordered', 'Customer Did Not Ordered'),
        ('customer_not_interested', 'Customer Not Interested'),
        ('customer_not_reachable', 'Customer Not Reachable'),
        ('customer_wants_full_delivery', 'Customer Wants Full Delivery'),
        ('customer_wants_high_quality', 'Customer Wants High Quality'),
        ('customer_wants_low_quality', 'Customer Wants Low Quality'),
        ('fake_order', 'Fake Order'),
        ('late_delivery', 'Late Delivery'),
        ('less_qty_required', 'Less Qty Required'),
        ('more_qty_required', 'More Qty Required'),
        ('office_closed', 'Office Closed'),
        ('pack_size_issue', 'Pack Size Issue'),
        ('price_issue', 'Price Issue'),
        ('product_damaged', 'Product Damaged'),
        ('product_mismatch', 'Product Mismatch'),
        ('returned_due_to_other_products', 'Returned Due to Other Products'),
        ('wrong_address', 'Wrong Address'),
        ('wrong_order_placed', 'Wrong Order Placed'),
        ('wrongly_packed', 'Wrongly Packed'),
    ], 'Not Delivery Reason', index=True)


    @api.model
    def default_get(self, fields):


        context = None
        res = super(ManifestReschedule, self).default_get(fields)
        man_line_obj = self.env["manifest.process.line"]
        man_line = man_line_obj.browse(self.env.context['active_id'])

        res['invoice_id'] = man_line.invoice_id.id
        res['manifest_line_id'] = man_line.id


        return res

    def reschedule_invoice(self):
        context = None

        delivered_amount = 0
        ndr = 0

        inv_data = self.env['account.move'].search([('id', '=', self.invoice_id)], limit=1)
        for inv_item in inv_data:
            delivered_amount = inv_item.amount_residual
            ndr +=inv_item.ndr


        self._cr.execute("update account_move set ndr='True',total_ndr=%s where id=%s", ([ndr,self.invoice_id]))
        self._cr.execute(
            "update manifest_process_line set manifest_out_status ='assigned',reschedule='True', ndr_amount=%s where id=%s",
            ([delivered_amount, self.manifest_line_id]))
        self._cr.commit()

        return True
