# Copyright (C) 2015-2019 Akretion (http://www.akretion.com)
# @author Alexis de Lattre <alexis.delattre@akretion.com>
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).


from odoo import api, fields, models


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

    # Also defined in bi_sale_company_currency
    company_currency_id = fields.Many2one(
        related='order_id.company_id.currency_id',
        store=True, string='Company Currency')
    standard_price_company_currency = fields.Float(
        string='Cost Price in Company Currency', readonly=True,
        digits="Product Price",
        help="Cost price in company currency in the unit of measure "
        "of the sale order line")
    standard_price_sale_currency = fields.Float(
        string='Cost Price in Sale Currency',
        compute='_compute_margin', store=True,
        digits="Product Price",
        help="Cost price in sale currency in the unit of measure "
        "of the sale order line")
    margin_sale_currency = fields.Monetary(
        string='Margin in Sale Currency', store=True,
        compute='_compute_margin', currency_field='currency_id')
    margin_company_currency = fields.Monetary(
        string='Margin in Company Currency', store=True,
        compute='_compute_margin', currency_field='company_currency_id')
    margin_rate = fields.Float(
        string="Margin Rate", store=True,
        compute='_compute_margin',
        digits=(16, 2), help="Margin rate in percentage of the sale price")

    @api.depends(
        'standard_price_company_currency', 'order_id.pricelist_id.currency_id',
        'order_id.date_order', 'product_uom_qty', 'price_subtotal',
        'order_id.company_id')
    def _compute_margin(self):
        for line in self:
            standard_price_sale_cur = 0.0
            margin_sale_cur = 0.0
            margin_comp_cur = 0.0
            margin_rate = 0.0
            order_cur = line.order_id.pricelist_id.currency_id
            company = line.order_id.company_id
            company_cur = company.currency_id
            if order_cur and company_cur:
                date = line.order_id.date_order
                standard_price_sale_cur =\
                    company_cur._convert(
                        line.standard_price_company_currency, order_cur,
                        company, date)
                margin_sale_cur =\
                    line.price_subtotal\
                    - line.product_uom_qty * standard_price_sale_cur
                margin_comp_cur = order_cur._convert(
                    margin_sale_cur, company_cur, company, date)
                if line.price_subtotal:
                    margin_rate = 100 * margin_sale_cur / line.price_subtotal
            line.standard_price_sale_currency = standard_price_sale_cur
            line.margin_sale_currency = margin_sale_cur
            line.margin_company_currency = margin_comp_cur
            line.margin_rate = margin_rate

    # We want to copy standard_price on sale order line
    @api.model_create_multi
    def create(self, vals_list):
        for vals in vals_list:
            if vals.get('product_id'):
                pp = self.env['product.product'].browse(vals['product_id'])
                std_price = pp.standard_price
                sale_uom_id = vals.get('product_uom')
                if sale_uom_id and sale_uom_id != pp.uom_id.id:
                    sale_uom = self.env['uom.uom'].browse(sale_uom_id)
                    # convert from product UoM to sale UoM
                    std_price = pp.uom_id._compute_price(
                        pp.standard_price, sale_uom)
                vals['standard_price_company_currency'] = std_price
        return super().create(vals_list)

    def write(self, vals):
        if not vals:
            vals = {}
        if 'product_id' in vals or 'product_uom' in vals:
            for sol in self:
                # product_uom and product_id are required fields
                if 'product_id' in vals:
                    pp = self.env['product.product'].browse(vals['product_id'])
                else:
                    pp = sol.product_id
                if 'product_uom' in vals:
                    sale_uom = self.env['uom.uom'].browse(
                        vals['product_uom'])
                else:
                    sale_uom = sol.product_uom
                std_price = pp.standard_price
                if sale_uom != pp.uom_id:
                    std_price = pp.uom_id._compute_price(std_price, sale_uom)
                sol.write({'standard_price_company_currency': std_price})
        return super().write(vals)


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

    # Also defined in bi_sale_company_currency
    company_currency_id = fields.Many2one(
        related='company_id.currency_id', store=True,
        string="Company Currency")
    margin_sale_currency = fields.Monetary(
        string='Margin in Sale Currency',
        currency_field='currency_id',
        compute='_compute_margin', store=True)
    margin_company_currency = fields.Monetary(
        string='Margin in Company Currency',
        currency_field='company_currency_id',
        compute='_compute_margin', store=True)

    @api.depends(
        'order_line.margin_sale_currency',
        'order_line.margin_company_currency')
    def _compute_margin(self):
        rg_res = self.env['sale.order.line'].read_group(
            [('order_id', 'in', self.ids)],
            ['order_id', 'margin_sale_currency:sum', 'margin_company_currency:sum'],
            ['order_id'])
        mapped_data = dict([
            (x['order_id'][0], {
                'margin_sale_currency': x['margin_sale_currency'],
                'margin_company_currency': x['margin_company_currency'],
                }) for x in rg_res])
        for order in self:
            order.margin_sale_currency = mapped_data.get(
                order.id, {}).get('margin_sale_currency')
            order.margin_company_currency = mapped_data.get(
                order.id, {}).get('margin_company_currency')
