Exemple #1
0
class HrPayslipLine(models.Model):
    _name = 'hr.payslip.line'
    _inherit = 'hr.salary.rule'
    _description = 'Payslip Line'
    _order = 'contract_id, sequence'

    slip_id = fields.Many2one('hr.payslip', string='Pay Slip', required=True, ondelete='cascade')
    salary_rule_id = fields.Many2one('hr.salary.rule', string='Rule', required=True)
    employee_id = fields.Many2one('hr.employee', string='Employee', required=True)
    contract_id = fields.Many2one('hr.contract', string='Contract', required=True, index=True)
    rate = fields.Float(string='Rate (%)', digits=dp.get_precision('Payroll Rate'), default=100.0)
    amount = fields.Float(digits=dp.get_precision('Payroll'))
    quantity = fields.Float(digits=dp.get_precision('Payroll'), default=1.0)
    total = fields.Monetary(compute='_compute_total', string='Total',
                            digits=dp.get_precision('Payroll'), store=True,
                            currency_field='company_currency_id')
    company_currency_id = fields.Many2one(
        'res.currency', related='employee_id.company_id.currency_id',
        string="Company Currency", readonly=True)

    @api.depends('quantity', 'amount', 'rate')
    def _compute_total(self):
        for line in self:
            line.total = float(line.quantity) * line.amount * line.rate / 100

    @api.model
    def create(self, values):
        if 'employee_id' not in values or 'contract_id' not in values:
            payslip = self.env['hr.payslip'].browse(values.get('slip_id'))
            values['employee_id'] = values.get('employee_id') or payslip.employee_id.id
            values['contract_id'] = values.get('contract_id') or payslip.contract_id and payslip.contract_id.id
            if not values['contract_id']:
                raise UserError(_('You must set a contract to create a payslip line.'))
        return super(HrPayslipLine, self).create(values)
Exemple #2
0
class report_account_analytic_line_to_invoice(models.Model):
    _name = "report.account.analytic.line.to.invoice"
    _description = "Analytic lines to invoice report"
    _order = 'name desc, product_id asc, account_id asc'
    _auto = False

    name = fields.Char(string='Year', readonly=True)
    product_id = fields.Many2one('product.product',
                                 string='Product',
                                 readonly=True)
    account_id = fields.Many2one('account.analytic.account',
                                 string='Analytic account',
                                 readonly=True)
    product_uom_id = fields.Many2one('product.uom',
                                     string='Unit of Measure',
                                     readonly=True)
    unit_amount = fields.Float(string='Units', readonly=True)
    sale_price = fields.Float(string='Sale price',
                              readonly=True,
                              digits=dp.get_precision('Product Price'))
    amount = fields.Float(string='Amount',
                          readonly=True,
                          digits=dp.get_precision('Account'))
    month = fields.Selection([('01', 'January'), ('02', 'February'),
                              ('03', 'March'), ('04', 'April'), ('05', 'May'),
                              ('06', 'June'), ('07', 'July'), ('08', 'August'),
                              ('09', 'September'), ('10', 'October'),
                              ('11', 'November'), ('12', 'December')],
                             string='Month',
                             readonly=True)

    @api.model_cr
    def init(self):
        cr = self._cr
        drop_view_if_exists(cr, 'report_account_analytic_line_to_invoice')
        cr.execute("""
            CREATE OR REPLACE VIEW report_account_analytic_line_to_invoice AS (
                SELECT
                    DISTINCT(to_char(l.date,'MM')) as month,
                    to_char(l.date, 'YYYY') as name,
                    MIN(l.id) AS id,
                    l.product_id,
                    l.account_id,
                    SUM(l.amount) AS amount,
                    SUM(l.unit_amount * t.list_price) AS sale_price,
                    SUM(l.unit_amount) AS unit_amount,
                    l.product_uom_id
                FROM
                    account_analytic_line l
                left join
                    product_product p on (l.product_id=p.id)
                left join
                    product_template t on (p.product_tmpl_id=t.id)
                WHERE
                    (invoice_id IS NULL) and (to_invoice IS NOT NULL)
                GROUP BY
                    to_char(l.date, 'YYYY'), to_char(l.date,'MM'),
                    l.product_id, l.product_uom_id, l.account_id
            )
        """)
Exemple #3
0
class PriceRule(models.Model):
    _name = "delivery.price.rule"
    _description = "Delivery Price Rules"
    _order = 'sequence, list_price, id'

    @api.depends('variable', 'operator', 'max_value', 'list_base_price', 'list_price', 'variable_factor')
    def _compute_name(self):
        for rule in self:
            name = 'if %s %s %s then' % (rule.variable, rule.operator, rule.max_value)
            if rule.list_base_price and not rule.list_price:
                name = '%s fixed price %s' % (name, rule.list_base_price)
            elif rule.list_price and not rule.list_base_price:
                name = '%s %s times %s' % (name, rule.list_price, rule.variable_factor)
            else:
                name = '%s fixed price %s plus %s times %s' % (name, rule.list_base_price, rule.list_price, rule.variable_factor)
            rule.name = name

    name = fields.Char(compute='_compute_name')
    sequence = fields.Integer(required=True, default=10)
    carrier_id = fields.Many2one('delivery.carrier', 'Carrier', required=True, ondelete='cascade')

    variable = fields.Selection([('weight', 'Weight'), ('volume', 'Volume'), ('wv', 'Weight * Volume'), ('price', 'Price'), ('quantity', 'Quantity')], required=True, default='weight')
    operator = fields.Selection([('==', '='), ('<=', '<='), ('<', '<'), ('>=', '>='), ('>', '>')], required=True, default='<=')
    max_value = fields.Float('Maximum Value', required=True)
    list_base_price = fields.Float(string='Sale Base Price', digits=dp.get_precision('Product Price'), required=True, default=0.0)
    list_price = fields.Float('Sale Price', digits=dp.get_precision('Product Price'), required=True, default=0.0)
    variable_factor = fields.Selection([('weight', 'Weight'), ('volume', 'Volume'), ('wv', 'Weight * Volume'), ('price', 'Price'), ('quantity', 'Quantity')], 'Variable Factor', required=True, default='weight')
Exemple #4
0
class HrContract(models.Model):
    """
    Employee contract allows to add different values in fields.
    Fields are used in salary rule computation.
    """
    _inherit = 'hr.contract'

    tds = fields.Float(string='TDS',
                       digits=dp.get_precision('Payroll'),
                       help='Amount for Tax Deduction at Source')
    driver_salay = fields.Boolean(
        string='Driver Salary',
        help='Check this box if you provide allowance for driver')
    medical_insurance = fields.Float(
        string='Medical Insurance',
        digits=dp.get_precision('Payroll'),
        help='Deduction towards company provided medical insurance')
    voluntary_provident_fund = fields.Float(
        string='Voluntary Provident Fund (%)',
        digits=dp.get_precision('Payroll'),
        help=
        'VPF is a safe option wherein you can contribute more than the PF ceiling of 12% that has been mandated by the government and VPF computed as percentage(%)'
    )
    house_rent_allowance_metro_nonmetro = fields.Float(
        string='House Rent Allowance (%)',
        digits=dp.get_precision('Payroll'),
        help=
        'HRA is an allowance given by the employer to the employee for taking care of his rental or accommodation expenses for metro city it is 50% and for non metro 40%. \nHRA computed as percentage(%)'
    )
    supplementary_allowance = fields.Float(string='Supplementary Allowance',
                                           digits=dp.get_precision('Payroll'))
Exemple #5
0
class Product(models.Model):
    _inherit = "product.product"

    def _get_default_website_ids(self):
        default_website_id = self.env.ref('website.default_website')
        return [default_website_id.id] if default_website_id else None

    website_ids = fields.Many2many('website',
                                   string="Publish Product On Website",
                                   default=_get_default_website_ids)
    website_price = fields.Float('Website price',
                                 compute='_website_price',
                                 digits=dp.get_precision('Product Price'))
    website_public_price = fields.Float(
        'Website public price',
        compute='_website_price',
        digits=dp.get_precision('Product Price'))
    website_price_difference = fields.Boolean('Website price difference',
                                              compute='_website_price')

    def _website_price(self):
        qty = self._context.get('quantity', 1.0)
        partner = self.env.user.partner_id
        current_website = self.env['website'].get_current_website()
        pricelist = current_website.get_current_pricelist()
        company_id = current_website.company_id

        context = dict(self._context, pricelist=pricelist.id, partner=partner)
        self2 = self.with_context(
            context) if self._context != context else self

        ret = self.env.user.has_group(
            'sale.group_show_price_subtotal'
        ) and 'total_excluded' or 'total_included'

        for p, p2 in pycompat.izip(self, self2):
            taxes = partner.property_account_position_id.map_tax(
                p.sudo().taxes_id.filtered(
                    lambda x: x.company_id == company_id))
            p.website_price = taxes.compute_all(p2.price,
                                                pricelist.currency_id,
                                                quantity=qty,
                                                product=p2,
                                                partner=partner)[ret]
            price_without_pricelist = taxes.compute_all(
                p.list_price, pricelist.currency_id)[ret]
            p.website_price_difference = False if float_is_zero(
                price_without_pricelist - p.website_price,
                precision_rounding=pricelist.currency_id.rounding) else True
            p.website_public_price = taxes.compute_all(p2.lst_price,
                                                       quantity=qty,
                                                       product=p2,
                                                       partner=partner)[ret]

    @api.multi
    def website_publish_button(self):
        self.ensure_one()
        return self.product_tmpl_id.website_publish_button()
Exemple #6
0
class SaleQuoteOption(models.Model):
    _name = "sale.quote.option"
    _description = "Quotation Option"

    template_id = fields.Many2one('sale.quote.template',
                                  'Quotation Template Reference',
                                  ondelete='cascade',
                                  index=True,
                                  required=True)
    name = fields.Text('Description', required=True, translate=True)
    product_id = fields.Many2one('product.product',
                                 'Product',
                                 domain=[('sale_ok', '=', True)],
                                 required=True)
    layout_category_id = fields.Many2one('sale.layout_category',
                                         string='Section')
    website_description = fields.Html('Option Description',
                                      translate=html_translate,
                                      sanitize_attributes=False)
    price_unit = fields.Float('Unit Price',
                              required=True,
                              digits=dp.get_precision('Product Price'))
    discount = fields.Float('Discount (%)',
                            digits=dp.get_precision('Discount'))
    uom_id = fields.Many2one('product.uom', 'Unit of Measure ', required=True)
    quantity = fields.Float('Quantity',
                            required=True,
                            digits=dp.get_precision('Product UoS'),
                            default=1)

    @api.onchange('product_id')
    def _onchange_product_id(self):
        if not self.product_id:
            return
        product = self.product_id
        self.price_unit = product.list_price
        self.website_description = product.product_tmpl_id.quote_description
        name = product.name
        if self.product_id.description_sale:
            name += '\n' + self.product_id.description_sale
        self.name = name
        self.uom_id = product.uom_id
        domain = {
            'uom_id':
            [('category_id', '=', self.product_id.uom_id.category_id.id)]
        }
        return {'domain': domain}

    @api.onchange('uom_id')
    def _onchange_product_uom(self):
        if not self.product_id:
            return
        if not self.uom_id:
            self.price_unit = 0.0
            return
        if self.uom_id.id != self.product_id.uom_id.id:
            self.price_unit = self.product_id.uom_id._compute_price(
                self.price_unit, self.uom_id)
Exemple #7
0
class SaleQuoteLine(models.Model):
    _name = "sale.quote.line"
    _description = "Quotation Template Lines"
    _order = 'sequence, id'

    sequence = fields.Integer('Sequence', help="Gives the sequence order when displaying a list of sale quote lines.",
        default=10)
    quote_id = fields.Many2one('sale.quote.template', 'Quotation Template Reference', required=True,
        ondelete='cascade', index=True)
    name = fields.Text('Description', required=True, translate=True)
    product_id = fields.Many2one('product.product', 'Product', domain=[('sale_ok', '=', True)], required=True)
    layout_category_id = fields.Many2one('sale.layout_category', string='Section')
    website_description = fields.Html('Line Description', related='product_id.product_tmpl_id.quote_description',
        translate=html_translate)
    price_unit = fields.Float('Unit Price', required=True, digits=dp.get_precision('Product Price'))
    discount = fields.Float('Discount (%)', digits=dp.get_precision('Discount'), default=0.0)
    product_uom_qty = fields.Float('Quantity', required=True, digits=dp.get_precision('Product UoS'), default=1)
    product_uom_id = fields.Many2one('product.uom', 'Unit of Measure ', required=True)

    @api.onchange('product_id')
    def _onchange_product_id(self):
        self.ensure_one()
        if self.product_id:
            name = self.product_id.name_get()[0][1]
            if self.product_id.description_sale:
                name += '\n' + self.product_id.description_sale
            self.name = name
            self.price_unit = self.product_id.lst_price
            self.product_uom_id = self.product_id.uom_id.id
            self.website_description = self.product_id.quote_description or self.product_id.website_description or ''
            domain = {'product_uom_id': [('category_id', '=', self.product_id.uom_id.category_id.id)]}
            return {'domain': domain}

    @api.onchange('product_uom_id')
    def _onchange_product_uom(self):
        if self.product_id and self.product_uom_id:
            self.price_unit = self.product_id.uom_id._compute_price(self.product_id.lst_price, self.product_uom_id)

    @api.model
    def create(self, values):
        values = self._inject_quote_description(values)
        return super(SaleQuoteLine, self).create(values)

    @api.multi
    def write(self, values):
        values = self._inject_quote_description(values)
        return super(SaleQuoteLine, self).write(values)

    def _inject_quote_description(self, values):
        values = dict(values or {})
        if not values.get('website_description') and values.get('product_id'):
            product = self.env['product.product'].browse(values['product_id'])
            values['website_description'] = product.quote_description or product.website_description or ''
        return values
class PurchaseRequisitionLine(models.Model):
    _name = "purchase.requisition.line"
    _description = "Purchase Requisition Line"
    _rec_name = 'product_id'

    product_id = fields.Many2one('product.product', string='Product', domain=[('purchase_ok', '=', True)], required=True)
    product_uom_id = fields.Many2one('product.uom', string='Product Unit of Measure')
    product_qty = fields.Float(string='Quantity', digits=dp.get_precision('Product Unit of Measure'))
    price_unit = fields.Float(string='Unit Price', digits=dp.get_precision('Product Price'))
    qty_ordered = fields.Float(compute='_compute_ordered_qty', string='Ordered Quantities')
    requisition_id = fields.Many2one('purchase.requisition', string='Purchase Agreement', ondelete='cascade')
    company_id = fields.Many2one('res.company', related='requisition_id.company_id', string='Company', store=True, readonly=True, default= lambda self: self.env['res.company']._company_default_get('purchase.requisition.line'))
    account_analytic_id = fields.Many2one('account.analytic.account', string='Analytic Account')
    schedule_date = fields.Date(string='Scheduled Date')
    move_dest_id = fields.Many2one('stock.move', 'Downstream Move')

    @api.multi
    @api.depends('requisition_id.purchase_ids.state')
    def _compute_ordered_qty(self):
        for line in self:
            total = 0.0
            for po in line.requisition_id.purchase_ids.filtered(lambda purchase_order: purchase_order.state in ['purchase', 'done']):
                for po_line in po.order_line.filtered(lambda order_line: order_line.product_id == line.product_id):
                    if po_line.product_uom != line.product_uom_id:
                        total += po_line.product_uom._compute_quantity(po_line.product_qty, line.product_uom_id)
                    else:
                        total += po_line.product_qty
            line.qty_ordered = total

    @api.onchange('product_id')
    def _onchange_product_id(self):
        if self.product_id:
            self.product_uom_id = self.product_id.uom_id
            self.product_qty = 1.0
        if not self.account_analytic_id:
            self.account_analytic_id = self.requisition_id.account_analytic_id
        if not self.schedule_date:
            self.schedule_date = self.requisition_id.schedule_date

    @api.multi
    def _prepare_purchase_order_line(self, name, product_qty=0.0, price_unit=0.0, taxes_ids=False):
        self.ensure_one()
        requisition = self.requisition_id
        return {
            'name': name,
            'product_id': self.product_id.id,
            'product_uom': self.product_id.uom_po_id.id,
            'product_qty': product_qty,
            'price_unit': price_unit,
            'taxes_id': [(6, 0, taxes_ids)],
            'date_planned': requisition.schedule_date or fields.Date.today(),
            'account_analytic_id': self.account_analytic_id.id,
            'move_dest_ids': self.move_dest_id and [(4, self.move_dest_id.id)] or []
        }
Exemple #9
0
class PurchaseOrderLine(models.Model):
    _inherit = "purchase.order.line"

    @api.depends('discount2', 'discount3')
    def _compute_amount(self):
        super(PurchaseOrderLine, self)._compute_amount()

    discount2 = fields.Float(
        'Disc. 2 (%)',
        digits=dp.get_precision('Discount'),
    )

    discount3 = fields.Float(
        'Disc. 3 (%)',
        digits=dp.get_precision('Discount'),
    )

    _sql_constraints = [
        ('discount2_limit', 'CHECK (discount2 <= 100.0)',
         'Discount 2 must be lower than 100%.'),
        ('discount3_limit', 'CHECK (discount3 <= 100.0)',
         'Discount 3 must be lower than 100%.'),
    ]

    def _get_discounted_price_unit(self):
        price_unit = super(PurchaseOrderLine,
                           self)._get_discounted_price_unit()
        if self.discount2:
            price_unit *= (1 - self.discount2 / 100.0)
        if self.discount3:
            price_unit *= (1 - self.discount3 / 100.0)
        return price_unit

    @api.onchange('product_qty', 'product_uom')
    def _onchange_quantity(self):
        """
        Check if a discount is defined into the supplier info and if so then
        apply it to the current purchase order line
        """
        res = super(PurchaseOrderLine, self)._onchange_quantity()
        if self.product_id:
            date = None
            if self.order_id.date_order:
                date = fields.Date.to_string(
                    fields.Date.from_string(self.order_id.date_order))
            product_supplierinfo = self.product_id._select_seller(
                partner_id=self.partner_id,
                quantity=self.product_qty,
                date=date,
                uom_id=self.product_uom)
            if product_supplierinfo:
                self.discount2 = product_supplierinfo.discount2
                self.discount3 = product_supplierinfo.discount3
        return res
class ResCompany(models.Model):
    _inherit = 'res.company'

    plafond_secu = fields.Float(string='Plafond de la Securite Sociale',
                                digits=dp.get_precision('Payroll'))
    nombre_employes = fields.Integer(string='Nombre d\'employes')
    cotisation_prevoyance = fields.Float(
        string='Cotisation Patronale Prevoyance',
        digits=dp.get_precision('Payroll'))
    org_ss = fields.Char(string='Organisme de securite sociale')
    conv_coll = fields.Char(string='Convention collective')
Exemple #11
0
class WizIndentLine(models.TransientModel):
    _name = 'wiz.indent.line'
    _description = "Wizard Indent Line"

    @api.depends('purchase_indent_line_id',
                 'purchase_indent_line_id.product_qty',
                 'purchase_indent_line_id.requisition_qty')
    @api.multi
    def _compute_get_rem_qty(self):
        for line_id in self:
            remaining_qty = 0.0
            if line_id.purchase_indent_line_id:
                remaining_qty = \
                    line_id.purchase_indent_line_id.product_qty - \
                    line_id.purchase_indent_line_id.requisition_qty
            line_id.remaining_qty = remaining_qty

    purchase_indent_ids = fields.Many2many(
        'purchase.indent', string='Purchase Indent')
    name = fields.Text(string='Description', required=True)
    sequence = fields.Integer(string='Sequence', default=10)
    product_qty = fields.Float(
        string='Quantity', digits=dp.get_precision('Discount'))
    expected_date = fields.Datetime(string='Expected Date', index=True)
    product_uom = fields.Many2one(
        'product.uom', string='Product Unit of Measure')
    product_id = fields.Many2one(
        'product.product', string='Product',
        domain=[('purchase_ok', '=', True)],
        change_default=True, required=True)
    requisition_qty = fields.Float(
        string="Requisition Quantity",
        digits=dp.get_precision('Discount'))
    wizard_indent_id = fields.Many2one(
        'wiz.requisition.request', 'Wiz Requisition Request')

    partner_id = fields.Many2one('res.partner', string='Partner')
    price_unit = fields.Float(
        string='Unit Price', digits=dp.get_precision('Product Price'))
    taxes_id = fields.Many2many(
        'account.tax', string='Taxes',
        domain=['|', ('active', '=', False), ('active', '=', True)])
    purchase_indent_line_id = fields.Many2one(
        'purchase.indent.line', string="Indent Line Ref")
    remaining_qty = fields.Float(
        compute='_compute_get_rem_qty', string='Remaining Quantity',
        store=True)
    order_type = fields.Selection(
        related='wizard_indent_id.order_type', string='Order Type')
Exemple #12
0
class ResPartner(models.Model):
    _inherit = "res.partner"

    default_supplierinfo_discount2 = fields.Float(
        string='Default Supplier Discount 2 (%)',
        digits=dp.get_precision('Discount'),
        help="This value will be used as the default one, for each new "
        "supplierinfo line depending on that supplier.",
    )
    default_supplierinfo_discount3 = fields.Float(
        string='Default Supplier Discount 3 (%)',
        digits=dp.get_precision('Discount'),
        help="This value will be used as the default one, for each new "
        "supplierinfo line depending on that supplier.",
    )
class PurchaseCostDistributionLineExpense(models.Model):
    _name = "purchase.cost.distribution.line.expense"
    _description = "Purchase cost distribution line expense"

    distribution_line = fields.Many2one(
        comodel_name='purchase.cost.distribution.line',
        string='Cost distribution line', ondelete="cascade",
    )
    picking_id = fields.Many2one(
        comodel_name="stock.picking", store=True, readonly=True,
        related="distribution_line.picking_id",
    )
    picking_date_done = fields.Datetime(
        related="picking_id.date_done", store=True, readonly=True,
    )
    distribution_expense = fields.Many2one(
        comodel_name='purchase.cost.distribution.expense',
        string='Distribution expense', ondelete="cascade",
    )
    type = fields.Many2one(
        'purchase.expense.type', string='Expense type', readonly=True,
        related='distribution_expense.type', store=True,
    )
    expense_amount = fields.Float(
        string='Expense amount', digits=dp.get_precision('Account'),
    )
    cost_ratio = fields.Float('Unit cost')
    company_id = fields.Many2one(
        comodel_name="res.company", related="distribution_line.company_id",
        store=True, readonly=True,
    )
class MembershipInvoice(models.TransientModel):
    _name = "membership.invoice"
    _description = "Membership Invoice"

    product_id = fields.Many2one('product.product', string='Membership', required=True)
    member_price = fields.Float(string='Member Price', digits= dp.get_precision('Product Price'), required=True)

    @api.onchange('product_id')
    def onchange_product(self):
        """This function returns value of  product's member price based on product id.
        """
        price_dict = self.product_id.price_compute('list_price')
        self.member_price = price_dict.get(self.product_id.id) or False

    @api.multi
    def membership_invoice(self):
        if self:
            datas = {
                'membership_product_id': self.product_id.id,
                'amount': self.member_price
            }
        invoice_list = self.env['res.partner'].browse(self._context.get('active_ids')).create_membership_invoice(datas=datas)

        search_view_ref = self.env.ref('account.view_account_invoice_filter', False)
        form_view_ref = self.env.ref('account.invoice_form', False)
        tree_view_ref = self.env.ref('account.invoice_tree', False)

        return  {
            'domain': [('id', 'in', invoice_list)],
            'name': 'Membership Invoices',
            'res_model': 'account.invoice',
            'type': 'ir.actions.act_window',
            'views': [(tree_view_ref.id, 'tree'), (form_view_ref.id, 'form')],
            'search_view_id': search_view_ref and search_view_ref.id,
        }
Exemple #15
0
class LandedCostLine(models.Model):
    _name = 'stock.landed.cost.lines'
    _description = 'Stock Landed Cost Lines'

    name = fields.Char('Description')
    cost_id = fields.Many2one('stock.landed.cost',
                              'Landed Cost',
                              required=True,
                              ondelete='cascade')
    product_id = fields.Many2one('product.product', 'Product', required=True)
    price_unit = fields.Float('Cost',
                              digits=dp.get_precision('Product Price'),
                              required=True)
    split_method = fields.Selection(product.SPLIT_METHOD,
                                    string='Split Method',
                                    required=True)
    account_id = fields.Many2one('account.account',
                                 'Account',
                                 domain=[('deprecated', '=', False)])

    @api.onchange('product_id')
    def onchange_product_id(self):
        if not self.product_id:
            self.quantity = 0.0
        self.name = self.product_id.name or ''
        self.split_method = self.product_id.split_method or 'equal'
        self.price_unit = self.product_id.standard_price or 0.0
        self.account_id = self.product_id.property_account_expense_id.id or self.product_id.categ_id.property_account_expense_categ_id.id
Exemple #16
0
class HrPayrollAdviceLine(models.Model):
    '''
    Bank Advice Lines
    '''
    _name = 'hr.payroll.advice.line'
    _description = 'Bank Advice Lines'

    advice_id = fields.Many2one('hr.payroll.advice', string='Bank Advice')
    name = fields.Char('Bank Account No.', required=True)
    ifsc_code = fields.Char(string='IFSC Code')
    employee_id = fields.Many2one('hr.employee',
                                  string='Employee',
                                  required=True)
    bysal = fields.Float(string='By Salary',
                         digits=dp.get_precision('Payroll'))
    debit_credit = fields.Char(string='C/D', default='C')
    company_id = fields.Many2one('res.company',
                                 related='advice_id.company_id',
                                 string='Company',
                                 store=True)
    ifsc = fields.Boolean(related='advice_id.neft', string='IFSC')

    @api.onchange('employee_id')
    def onchange_employee_id(self):
        self.name = self.employee_id.bank_account_id.acc_number
        self.ifsc_code = self.employee_id.bank_account_id.bank_bic or ''
Exemple #17
0
class StockMove(models.Model):
    _inherit = 'stock.move'

    def _default_uom(self):
        uom_categ_id = self.env.ref('product.product_uom_categ_kgm').id
        return self.env['product.uom'].search(
            [('category_id', '=', uom_categ_id), ('factor', '=', 1)], limit=1)

    weight = fields.Float(compute='_cal_move_weight',
                          digits=dp.get_precision('Stock Weight'),
                          store=True)
    weight_uom_id = fields.Many2one(
        'product.uom',
        string='Weight Unit of Measure',
        required=True,
        readonly=True,
        help=
        "Unit of Measure (Unit of Measure) is the unit of measurement for Weight",
        default=_default_uom)

    @api.depends('product_id', 'product_uom_qty', 'product_uom')
    def _cal_move_weight(self):
        for move in self.filtered(
                lambda moves: moves.product_id.weight > 0.00):
            move.weight = (move.product_qty * move.product_id.weight)

    def _get_new_picking_values(self):
        vals = super(StockMove, self)._get_new_picking_values()
        vals['carrier_id'] = self.sale_line_id.order_id.carrier_id.id
        return vals
Exemple #18
0
class MrpSubProduct(models.Model):
    _name = 'mrp.subproduct'
    _description = 'Byproduct'

    product_id = fields.Many2one('product.product', 'Product', required=True)
    product_qty = fields.Float(
        'Product Qty',
        default=1.0, digits=dp.get_precision('Product Unit of Measure'), required=True)
    product_uom_id = fields.Many2one('product.uom', 'Unit of Measure', required=True)
    bom_id = fields.Many2one('mrp.bom', 'BoM', ondelete='cascade')
    operation_id = fields.Many2one('mrp.routing.workcenter', 'Produced at Operation')

    @api.onchange('product_id')
    def onchange_product_id(self):
        """ Changes UoM if product_id changes. """
        if self.product_id:
            self.product_uom_id = self.product_id.uom_id.id

    @api.onchange('product_uom_id')
    def onchange_uom(self):
        res = {}
        if self.product_uom_id and self.product_id and self.product_uom_id.category_id != self.product_id.uom_id.category_id:
            res['warning'] = {
                'title': _('Warning'),
                'message': _('The Product Unit of Measure you chose has a different category than in the product form.')
            }
            self.product_uom_id = self.product_id.uom_id.id
        return res
Exemple #19
0
class PurchaseOrderRecommendationLine(models.TransientModel):
    _inherit = 'purchase.order.recommendation.line'

    secondary_uom_id = fields.Many2one(
        comodel_name='product.secondary.unit',
        related='product_id.purchase_secondary_uom_id',
        readonly=True,
    )
    secondary_uom_qty = fields.Float(
        string='Secondary Qty',
        digits=dp.get_precision('Product Unit of Measure'),
    )

    @api.onchange('secondary_uom_id', 'secondary_uom_qty')
    def _onchange_secondary_uom(self):
        if not self.secondary_uom_id:
            return
        factor = self.secondary_uom_id.factor * self.product_id.uom_id.factor
        qty = float_round(self.secondary_uom_qty * factor,
                          precision_rounding=self.product_id.uom_id.rounding)
        if float_compare(
                self.units_included,
                qty,
                precision_rounding=self.product_id.uom_id.rounding) != 0:
            self.units_included = qty

    @api.onchange('units_included')
    def _onchange_units_included_purchase_order_secondary_unit(self):
        if not self.secondary_uom_id:
            return
        factor = self.secondary_uom_id.factor * self.product_id.uom_id.factor
        qty = float_round(
            self.units_included / (factor or 1.0),
            precision_rounding=self.secondary_uom_id.uom_id.rounding)
        if float_compare(
                self.secondary_uom_qty,
                qty,
                precision_rounding=self.secondary_uom_id.uom_id.rounding) != 0:
            self.secondary_uom_qty = qty

    @api.multi
    def _prepare_update_po_line(self):
        res = super()._prepare_update_po_line()
        if self.secondary_uom_id and self.secondary_uom_qty:
            res.update({
                'secondary_uom_id': self.secondary_uom_id.id,
                'secondary_uom_qty': self.secondary_uom_qty,
            })
        return res

    @api.multi
    def _prepare_new_po_line(self, sequence):
        res = super()._prepare_new_po_line(sequence)
        if self.secondary_uom_id and self.secondary_uom_qty:
            res.update({
                'secondary_uom_id': self.secondary_uom_id.id,
                'secondary_uom_qty': self.secondary_uom_qty,
            })
        return res
class ProductAttributevalue(models.Model):
    _name = "product.attribute.value"
    _order = 'sequence, attribute_id, id'

    name = fields.Char('Value', required=True, translate=True)
    sequence = fields.Integer('Sequence', help="Determine the display order")
    attribute_id = fields.Many2one('product.attribute', 'Attribute', ondelete='cascade', required=True)
    product_ids = fields.Many2many('product.product', string='Variants', readonly=True)
    price_extra = fields.Float(
        'Attribute Price Extra', compute='_compute_price_extra', inverse='_set_price_extra',
        default=0.0, digits=dp.get_precision('Product Price'),
        help="Price Extra: Extra price for the variant with this attribute value on sale price. eg. 200 price extra, 1000 + 200 = 1200.")
    price_ids = fields.One2many('product.attribute.price', 'value_id', 'Attribute Prices', readonly=True)

    _sql_constraints = [
        ('value_company_uniq', 'unique (name,attribute_id)', 'This attribute value already exists !')
    ]

    @api.one
    def _compute_price_extra(self):
        if self._context.get('active_id'):
            price = self.price_ids.filtered(lambda price: price.product_tmpl_id.id == self._context['active_id'])
            self.price_extra = price.price_extra
        else:
            self.price_extra = 0.0

    def _set_price_extra(self):
        if not self._context.get('active_id'):
            return

        AttributePrice = self.env['product.attribute.price']
        prices = AttributePrice.search([('value_id', 'in', self.ids), ('product_tmpl_id', '=', self._context['active_id'])])
        updated = prices.mapped('value_id')
        if prices:
            prices.write({'price_extra': self.price_extra})
        else:
            for value in self - updated:
                AttributePrice.create({
                    'product_tmpl_id': self._context['active_id'],
                    'value_id': value.id,
                    'price_extra': self.price_extra,
                })

    @api.multi
    def name_get(self):
        if not self._context.get('show_attribute', True):  # TDE FIXME: not used
            return super(ProductAttributevalue, self).name_get()
        return [(value.id, "%s: %s" % (value.attribute_id.name, value.name)) for value in self]

    @api.multi
    def unlink(self):
        linked_products = self.env['product.product'].with_context(active_test=False).search([('attribute_value_ids', 'in', self.ids)])
        if linked_products:
            raise UserError(_('The operation cannot be completed:\nYou are trying to delete an attribute value with a reference on a product variant.'))
        return super(ProductAttributevalue, self).unlink()

    @api.multi
    def _variant_name(self, variable_attributes):
        return ", ".join([v.name for v in self if v.attribute_id in variable_attributes])
Exemple #21
0
class PurchaseOrderLine(models.Model):
    _inherit = 'purchase.order.line'

    @api.depends('product_qty', 'qty_invoiced',
                 'invoice_lines.invoice_id.state', 'order_id.state',
                 'order_id.invoice_status', 'move_ids.state', 'qty_received')
    def _compute_qty_to_invoice(self):
        for line in self:
            # If the invoice status has been forced to invoiced,
            # then respect it. See module purchase_force_invoiced.
            if getattr(line.order_id, 'force_invoiced', None):
                line.qty_to_invoice = 0.0
            elif line.product_id.purchase_method == 'receive':
                qty = line.qty_received - line.qty_invoiced
                if qty >= 0.0:
                    line.qty_to_invoice = qty
                else:
                    line.qty_to_invoice = 0.0
            else:
                line.qty_to_invoice = line.product_qty - line.qty_invoiced

    @api.depends('order_id.state', 'move_ids.state', 'product_qty')
    def _compute_qty_to_receive(self):
        for line in self:
            total = 0.0
            for move in line.move_ids.filtered(lambda m: m.state not in
                                               ('cancel', 'done')):
                if move.product_uom != line.product_uom:
                    total += move.product_uom._compute_quantity(
                        move.product_uom_qty, line.product_uom)
                else:
                    total += move.product_uom_qty
            line.qty_to_receive = total

    qty_to_invoice = fields.Float(
        compute='_compute_qty_to_invoice',
        digits=dp.get_precision('Product Unit of Measure'),
        copy=False,
        string="Qty to Bill",
        store=True)
    qty_to_receive = fields.Float(
        compute='_compute_qty_to_receive',
        digits=dp.get_precision('Product Unit of Measure'),
        copy=False,
        string="Qty to Receive",
        store=True)
Exemple #22
0
class ResPartner(models.Model):
    _inherit = 'res.partner'

    purchase_general_discount = fields.Float(
        digits=dp.get_precision('Discount'),
        string='Purchase General Discount (%)',
        company_dependent=True,
    )
Exemple #23
0
class PurchaseOrderLine(models.Model):
    _inherit = 'purchase.order.line'

    secondary_uom_qty = fields.Float(
        string='Secondary Qty',
        digits=dp.get_precision('Product Unit of Measure'),
    )
    secondary_uom_id = fields.Many2one(
        comodel_name='product.secondary.unit',
        string='Secondary uom',
        ondelete='restrict',
    )

    @api.onchange('secondary_uom_id', 'secondary_uom_qty')
    def _onchange_secondary_uom(self):
        if not self.secondary_uom_id:
            return
        factor = self.secondary_uom_id.factor * self.product_uom.factor
        qty = float_round(
            self.secondary_uom_qty * factor,
            precision_rounding=self.product_uom.rounding
        )
        if float_compare(
                self.product_qty, qty,
                precision_rounding=self.product_uom.rounding) != 0:
            self.product_qty = qty

    @api.onchange('product_qty')
    def _onchange_product_qty_purchase_order_secondary_unit(self):
        if not self.secondary_uom_id:
            return
        factor = self.secondary_uom_id.factor * self.product_uom.factor
        qty = float_round(
            self.product_qty / (factor or 1.0),
            precision_rounding=self.secondary_uom_id.uom_id.rounding
        )
        if float_compare(
                self.secondary_uom_qty, qty,
                precision_rounding=self.secondary_uom_id.uom_id.rounding) != 0:
            self.secondary_uom_qty = qty

    @api.onchange('product_uom')
    def _onchange_product_uom_purchase_order_secondary_unit(self):
        if not self.secondary_uom_id:
            return
        factor = self.product_uom.factor * self.secondary_uom_id.factor
        qty = float_round(
            self.product_qty / (factor or 1.0),
            precision_rounding=self.product_uom.rounding
        )
        if float_compare(
                self.secondary_uom_qty, qty,
                precision_rounding=self.product_uom.rounding) != 0:
            self.secondary_uom_qty = qty

    @api.onchange('product_id')
    def _onchange_product_id_purchase_order_secondary_unit(self):
        self.secondary_uom_id = self.product_id.purchase_secondary_uom_id
Exemple #24
0
class MRPSimpleLine(models.TransientModel):
    _name = 'mrp.simple.line'

    mrp_simple_id = fields.Many2one('mrp.simple')
    product_id = fields.Many2one('product.product')
    quantity = fields.Float(string="Quantity",
                            digits=dp.get_precision('Product Unit of Measure'),
                            default=1)
    price_unit = fields.Float('Unit Price',
                              digits=dp.get_precision('Product Price'))
    uom_id = fields.Many2one('product.uom', 'Unit of Measure')
    type = fields.Selection([('consumption', 'Consumption in production'),
                             ('receipt', 'Receipt from production')],
                            string='Type')

    @api.onchange('product_id')
    def onchange_product_id(self):
        self.uom_id = self.product_id.uom_id
Exemple #25
0
class QcTestQuestion(models.Model):
    """Each test line is a question with its valid value(s)."""
    _name = 'qc.test.question'
    _description = 'Quality control question'
    _order = 'sequence, id'

    @api.constrains('ql_values')
    def _check_valid_answers(self):
        for tc in self:
            if (tc.type == 'qualitative' and tc.ql_values
                    and not tc.ql_values.filtered('ok')):
                raise exceptions.ValidationError(
                    _("Question '%s' is not valid: "
                      "you have to mark at least one value as OK.") %
                    tc.name_get()[0][1])

    @api.constrains('min_value', 'max_value')
    def _check_valid_range(self):
        for tc in self:
            if tc.type == 'quantitative' and tc.min_value > tc.max_value:
                raise exceptions.ValidationError(
                    _("Question '%s' is not valid: "
                      "minimum value can't be higher than maximum value.") %
                    tc.name_get()[0][1])

    sequence = fields.Integer(string='Sequence', required=True, default="10")
    test = fields.Many2one(comodel_name='qc.test', string='Test')
    name = fields.Char(string='Name', required=True, translate=True)
    type = fields.Selection([('qualitative', 'Qualitative'),
                             ('quantitative', 'Quantitative')],
                            string='Type',
                            required=True)
    ql_values = fields.One2many(comodel_name='qc.test.question.value',
                                inverse_name="test_line",
                                string='Qualitative values',
                                copy=True)
    notes = fields.Text(string='Notes')
    min_value = fields.Float(string='Min',
                             digits=dp.get_precision('Quality Control'))
    max_value = fields.Float(
        string='Max',
        digits=dp.get_precision('Quality Control'),
    )
    uom_id = fields.Many2one(comodel_name='product.uom', string='Uom')
class MrpProductProduceLine(models.TransientModel):
    _name = "mrp.product.produce.line"
    _description = "Record Production Line"

    product_produce_id = fields.Many2one('mrp.product.produce')
    product_id = fields.Many2one('product.product', 'Product')
    lot_id = fields.Many2one('stock.production.lot', 'Lot')
    qty_to_consume = fields.Float(
        'To Consume', digits=dp.get_precision('Product Unit of Measure'))
    product_uom_id = fields.Many2one('product.uom', 'Unit of Measure')
    qty_done = fields.Float('Done',
                            digits=dp.get_precision('Product Unit of Measure'))
    move_id = fields.Many2one('stock.move')

    @api.onchange('lot_id')
    def _onchange_lot_id(self):
        """ When the user is encoding a produce line for a tracked product, we apply some logic to
        help him. This onchange will automatically switch `qty_done` to 1.0.
        """
        res = {}
        if self.product_id.tracking == 'serial':
            self.qty_done = 1
        return res

    @api.onchange('qty_done')
    def _onchange_qty_done(self):
        """ When the user is encoding a produce line for a tracked product, we apply some logic to
        help him. This onchange will warn him if he set `qty_done` to a non-supported value.
        """
        res = {}
        if self.product_id.tracking == 'serial':
            if float_compare(self.qty_done,
                             1.0,
                             precision_rounding=self.move_id.product_id.uom_id.
                             rounding) != 0:
                message = _(
                    'You can only process 1.0 %s for products with unique serial number.'
                ) % self.product_id.uom_id.name
                res['warning'] = {'title': _('Warning'), 'message': message}
        return res

    @api.onchange('product_id')
    def _onchange_product_id(self):
        self.product_uom_id = self.product_id.uom_id.id
Exemple #27
0
class RepairFee(models.Model):
    _name = 'mrp.repair.fee'
    _description = 'Repair Fees Line'

    repair_id = fields.Many2one(
        'mrp.repair', 'Repair Order Reference',
        index=True, ondelete='cascade', required=True)
    name = fields.Char('Description', index=True, required=True)
    product_id = fields.Many2one('product.product', 'Product')
    product_uom_qty = fields.Float('Quantity', digits=dp.get_precision('Product Unit of Measure'), required=True, default=1.0)
    price_unit = fields.Float('Unit Price', required=True)
    product_uom = fields.Many2one('product.uom', 'Product Unit of Measure', required=True)
    price_subtotal = fields.Float('Subtotal', compute='_compute_price_subtotal', digits=0)
    tax_id = fields.Many2many('account.tax', 'repair_fee_line_tax', 'repair_fee_line_id', 'tax_id', 'Taxes')
    invoice_line_id = fields.Many2one('account.invoice.line', 'Invoice Line', copy=False, readonly=True)
    invoiced = fields.Boolean('Invoiced', copy=False, readonly=True)

    @api.one
    @api.depends('price_unit', 'repair_id', 'product_uom_qty', 'product_id')
    def _compute_price_subtotal(self):
        taxes = self.tax_id.compute_all(self.price_unit, self.repair_id.pricelist_id.currency_id, self.product_uom_qty, self.product_id, self.repair_id.partner_id)
        self.price_subtotal = taxes['total_excluded']

    @api.onchange('repair_id', 'product_id', 'product_uom_qty')
    def onchange_product_id(self):
        """ On change of product it sets product quantity, tax account, name,
        uom of product, unit price and price subtotal. """
        if not self.product_id:
            return

        partner = self.repair_id.partner_id
        pricelist = self.repair_id.pricelist_id

        if partner and self.product_id:
            self.tax_id = partner.property_account_position_id.map_tax(self.product_id.taxes_id, self.product_id, partner).ids
        if self.product_id:
            self.name = self.product_id.display_name
            self.product_uom = self.product_id.uom_id.id

        warning = False
        if not pricelist:
            warning = {
                'title': _('No Pricelist!'),
                'message':
                    _('You have to select a pricelist in the Repair form !\n Please set one before choosing a product.')}
        else:
            price = pricelist.get_product_price(self.product_id, self.product_uom_qty, partner)
            if price is False:
                warning = {
                    'title': _('No valid pricelist line found !'),
                    'message':
                        _("Couldn't find a pricelist line matching this product and quantity.\nYou have to change either the product, the quantity or the pricelist.")}
            else:
                self.price_unit = price
        if warning:
            return {'warning': warning}
Exemple #28
0
class Product(models.Model):
    _inherit = "product.product"

    website_price = fields.Float('Website price',
                                 compute='_website_price',
                                 digits=dp.get_precision('Product Price'))
    website_public_price = fields.Float(
        'Website public price',
        compute='_website_price',
        digits=dp.get_precision('Product Price'))

    def _website_price(self):
        qty = self._context.get('quantity', 1.0)
        partner = self.env.user.partner_id
        current_website = self.env['website'].get_current_website()
        pricelist = current_website.get_current_pricelist()
        company_id = current_website.company_id

        context = dict(self._context, pricelist=pricelist.id, partner=partner)
        self2 = self.with_context(
            context) if self._context != context else self

        ret = self.env.user.has_group(
            'sale.group_show_price_subtotal'
        ) and 'total_excluded' or 'total_included'

        for p, p2 in pycompat.izip(self, self2):
            taxes = partner.property_account_position_id.map_tax(
                p.taxes_id.filtered(lambda x: x.company_id == company_id))
            p.website_price = taxes.compute_all(p2.price,
                                                pricelist.currency_id,
                                                quantity=qty,
                                                product=p2,
                                                partner=partner)[ret]
            p.website_public_price = taxes.compute_all(p2.lst_price,
                                                       quantity=qty,
                                                       product=p2,
                                                       partner=partner)[ret]

    @api.multi
    def website_publish_button(self):
        self.ensure_one()
        return self.product_tmpl_id.website_publish_button()
Exemple #29
0
class PurchaseOrderLine(models.Model):
    _inherit = "purchase.order.line"

    @api.depends('discount')
    def _compute_amount(self):
        for line in self:
            price_unit = False
            # This is always executed for allowing other modules to use this
            # with different conditions than discount != 0
            price = line._get_discounted_price_unit()
            if price != line.price_unit:
                # Only change value if it's different
                price_unit = line.price_unit
                line.price_unit = price
            super(PurchaseOrderLine, line)._compute_amount()
            if price_unit:
                line.price_unit = price_unit

    discount = fields.Float(
        string='Discount (%)', digits=dp.get_precision('Discount'),
    )

    _sql_constraints = [
        ('discount_limit', 'CHECK (discount <= 100.0)',
         'Discount must be lower than 100%.'),
    ]

    def _get_discounted_price_unit(self):
        """Inheritable method for getting the unit price after applying
        discount(s).

        :rtype: float
        :return: Unit price after discount(s).
        """
        self.ensure_one()
        if self.discount:
            return self.price_unit * (1 - self.discount / 100)
        return self.price_unit

    @api.multi
    def _get_stock_move_price_unit(self):
        """Get correct price with discount replacing current price_unit
        value before calling super and restoring it later for assuring
        maximum inheritability.
        """
        price_unit = False
        price = self._get_discounted_price_unit()
        if price != self.price_unit:
            # Only change value if it's different
            price_unit = self.price_unit
            self.price_unit = price
        price = super(PurchaseOrderLine, self)._get_stock_move_price_unit()
        if price_unit:
            self.price_unit = price_unit
        return price
Exemple #30
0
class LunchProduct(models.Model):
    """ Products available to order. A product is linked to a specific vendor. """
    _name = 'lunch.product'
    _description = 'lunch product'

    name = fields.Char('Product', required=True)
    category_id = fields.Many2one('lunch.product.category', 'Category', required=True)
    description = fields.Text('Description')
    price = fields.Float('Price', digits=dp.get_precision('Account'))
    supplier = fields.Many2one('res.partner', 'Vendor')
    active = fields.Boolean(default=True)