示例#1
0
 def onchange_discount_per(self):
     values = self.get_maximum_per_amount()
     if self.discount_method == 'per' and (
             self.discount_per > 100 or self.discount_per < 0) \
             and values.get('check_group', False):
         raise Warning(_("Percentage should be between 0% to 100%"))
     if self.discount_per > values.get('max_percentage', False) \
             and values.get('check_group', False):
         raise Warning(_("You are not allowed to apply Discount Percentage "
                         "(%s) more than configured Discount Percentage "
                         "(%s) in configuration setting!") % (
             formatLang(self.env,  self.discount_per, digits=2),
             formatLang(self.env, values['max_percentage'], digits=2)))
     config_id = self.env[
         'res.config.settings'].search([], order='id desc', limit=1)
     if config_id and config_id.global_discount_invoice_apply:
         global_percentage = config_id.global_discount_percentage_invoice
         if global_percentage < self.discount_per:
             raise Warning(_("You are not allowed to apply Discount "
                             "Percentage(%s) more than configured Discount"
                             " Percentage (%s) in configuration setting!"
                             ) % (
                 formatLang(self.env, self.discount_per, digits=2),
                 formatLang(self.env,
                            config_id.global_discount_percentage_invoice,
                            digits=2)))
示例#2
0
 def _check_fix_amount_value(self):
     config_id = self.env['res.config.settings'].search(
         [], order='id desc', limit=1)
     if config_id and config_id.global_discount_apply \
             and config_id.global_discount_fix_amount < self.fix_amount:
         raise ValueError(
             _("Fix amount (%s) is greater than configuration Amount (%s)!"
               ) % (formatLang(
                 self.env, self.fix_amount, digits=2), formatLang(
                 self.env, config_id.global_discount_fix_amount, digits=2)))
示例#3
0
 def _check_percentage(self):
     if self.percentage < 0 or self.percentage > 100:
         raise ValueError(_("Percentage should be between 0% to 100%!"))
     config_id = self.env[
         'res.config.settings'].search([], order='id desc', limit=1)
     if config_id and config_id.global_discount_apply \
             and config_id.global_discount_percentage < self.percentage:
         raise ValueError(
             _("Percentage (%s) is greater than configuration Percentage "
               "(%s)!") % (formatLang(
                 self.env, self.percentage, digits=2),
                           formatLang(self.env,
                                      config_id.global_discount_percentage,
                                      digits=2)))
示例#4
0
    def action_confirm(self):
        if self._uid != self.create_uid.id:
            raise Warning(
                _("You can't confirm purchase indent which is \
            requested by %s!") % (self.create_uid.name))
        if not self.indent_line:
            raise Warning(_('No Product Line(s) were found!'))
        check_pro_qty = [
            line.id for line in self.indent_line if line.product_qty
        ]
        if not check_pro_qty:
            raise Warning(_("No Quantity were found for any line!"))
        self.check_duplicate_product()
        group_id = self.sudo().env.ref('purchase.group_purchase_manager')
        if not group_id.users:
            raise AccessError(
                _("Please contact your Administrator \n \
                  No user found under 'Purchase Manager'"))
        server_id = self.env['ir.mail_server'].search([])
        if not server_id:
            raise AccessError(_("Please configure outgoing mail server"))
        email_to = ",".join(
            [user.email for user in group_id.users if user.email])
        recipient_ids = [user.partner_id.id for user in group_id.users]
        if self.env.user.email:
            product_qty = '''
                    <table width=100%% border="0" style="font-family: 'Arial';
                    font-size: 12px;">
                    <tr>
                        <td><b>''' + _("Product Name") + '''</b></td>
                        <td><b>''' + _("Quantity") + '''</b></td>
                        <td><b>''' + _("Expected Date") + '''</b></td>
                    </tr>'''
            for line in self.indent_line:
                qty = (str(formatLang(self.env, line.product_qty, digits=2)))
                product_qty += '<tr>\
                                    <td>' + str(line.product_id.name) + '</td>\
                                    <td>' + qty + '</td>\
                                    <td>' + str(line.expected_date) + '</td>\
                                </tr>'

            msg1 = '<p>Purchase Indent "%s" Confirmed by "%s" for following \
            Products Details.</p>' % (self.name, self.env.user.name)
            msg1 += '<p> %s </p>' % (product_qty)
            create_values = {
                'body_html': msg1,
                'subject':
                'Purchase Indent Confirmed by %s' % (self.env.user.name),
                'email_from': self.env.user.email,
                'email_to': email_to,
                'model': 'purchase.indent',
                'res_id': self.id,
                'reply_to': '',
                'recipient_ids': [(6, 0, recipient_ids)],
            }
            email_id = self.env['mail.mail'].create(create_values)
            email_id.send()
        else:
            raise AccessError(_("Please configure your email"))
        self.state = 'confirm'
示例#5
0
 def set_qty_state_confirm(self,
                           purchase_order_id=False,
                           purchase_agreement_id=False):
     indent_line_obj = self.env['purchase.indent.line']
     indent_history_ids = []
     if purchase_order_id:
         indent_history_ids = self.env['purchase.indent.history'].search([
             ('order_id', '=', purchase_order_id.id),
             ('state', '=', 'Cancelled')
         ])
     elif purchase_agreement_id:
         indent_history_ids = self.env['purchase.indent.history'].search([
             ('purchase_requisition_id', '=', purchase_agreement_id.id),
             ('state', '=', 'Cancelled')
         ])
     for history_id in indent_history_ids:
         indent_line_id = indent_line_obj.sudo().search([
             ('product_id', '=', history_id.product_id.id),
             ('purchase_indent_id', '=', history_id.purchase_indent_id.id)
         ])
         if indent_line_id.requisition_qty + history_id.requisition_qty > \
                 indent_line_id.product_qty:
             remaining_qty = \
                 indent_line_id.product_qty - indent_line_id.requisition_qty
             raise Warning(
                 _("Requisition Quantity of ' %s ' is more than \
             Remaining Quantity (%s)!") %
                 (history_id.product_id.name,
                  formatLang(self.env, remaining_qty, digits=2)))
         requisition_qty = \
             indent_line_id.requisition_qty + history_id.requisition_qty
         indent_line_id.write({'requisition_qty': requisition_qty})
         history_id.purchase_indent_id.check_state()
         history_id.date = datetime.now()
示例#6
0
 def onchange_product_qty(self):
     warning = {}
     if self.product_qty < 0:
         warning.update({
             'title':
             _("Warning"),
             'message':
             _("Quantity (%s) can not be Negative!") %
             (formatLang(self.env, self.product_qty, digits=2))
         })
         self.product_qty = False
         return {'warning': warning}
示例#7
0
 def onchange_discount_amount(self):
     values = self.get_maximum_per_amount()
     if self.discount < 0:
         raise Warning(_("Discount should be less than Gross Amount"))
     discount = self.discount or self.discount_amount
     if discount > self.gross_amount:
         raise Warning(_("Discount (%s) should be less than "
                         "Gross Amount (%s).") % (
             formatLang(self.env, discount, digits=2),
             formatLang(self.env, self.gross_amount, digits=2)))
     if self.discount_amount > values.get('max_amount', False) \
             and values.get('check_group', False):
         raise Warning(_("You're not allowed to apply Discount Amount "
                         "(%s) more than configured amount (%s) in "
                         "configuration setting!") % (
             formatLang(self.env, self.discount_amount, digits=2),
             formatLang(self.env, values['max_amount'], digits=2)))
     config_id = self.env['res.config.settings'].search(
         [], order='id desc', limit=1)
     if config_id and config_id.global_discount_apply:
         if config_id.global_discount_fix_amount < self.discount_amount:
             raise Warning(_("You're not allowed to apply Discount "
                             "Amount (%s) more than configured amount "
                             "(%s) in configuration setting!") % (
                 formatLang(self.env, self.discount_amount, digits=2),
                 formatLang(self.env, config_id.global_discount_fix_amount,
                            digits=2)))
示例#8
0
 def onchange_discount_amount(self):
     values = self.get_maximum_per_amount()
     if self.discount < 0:
         raise Warning(_("Discount should be less than Gross Amount"))
     discount = self.discount or self.discount_amount
     if self.gross_amount and discount > self.gross_amount:
         raise Warning(_("Discount (%s) should be less than "
                         "Gross Amount (%s).") % (
             formatLang(self.env, discount, digits=2),
             formatLang(self.env, self.gross_amount, digits=2)))
     if self.discount > values.get('max_amount', False) \
             and values.get('check_group', False):
         raise Warning(_("You're not allowed to apply this amount of "
                         "discount as discount Amount (%s) is greater than"
                         " assign Fix Amount (%s).") % (
             formatLang(self.env, self.discount, digits=2),
             formatLang(self.env, values['max_amount'], digits=2)))
     config_id = self.env[
         'res.config.settings'].search([], order='id desc', limit=1)
     if config_id and config_id.global_discount_invoice_apply:
         fix_amount = config_id.global_discount_fix_invoice_amount
         if fix_amount < self.discount_amount:
             raise Warning(_("You're not allowed to apply this amount of"
                             " discount as discount Amount (%s) is greater"
                             " than Configuration Amount (%s).") % (
                 formatLang(self.env, self.discount, digits=2),
                 formatLang(self.env,
                            config_id.global_discount_fix_invoice_amount,
                            digits=2)))
示例#9
0
 def _check_Constraints(self):
     self.get_values()
     order_line = self.order_line
     if not self.have_coupon_code:
         raise UserError(_("Please enter the Coupon code!"))
     if not order_line:
         raise UserError(_("There is no sale order line!"))
     if self.pricelist_id.pricelist_type != 'advance' or not \
             self.pricelist_id.apply_coupon_code:
         raise UserError(_("Coupon code does not apply to "
                           "sale order pricelist!"))
     coupon_obj = self.env['coupon.code']
     coupon_code_id = coupon_obj.get_coupon_records(
         self.have_coupon_code, self.pricelist_id)
     if not coupon_code_id:
         raise UserError(_("Coupon code (%s) not found!"
                           ) % (self.have_coupon_code))
     if coupon_code_id.usage_limit > 0 \
             and coupon_code_id.remaining_limit <= 0:
         raise UserError(_("Coupon code (%s) Remaining Limit exceeds!"
                           ) % (self.have_coupon_code))
     if coupon_code_id.min_order_amount \
             and self.amount_untaxed < coupon_code_id.min_order_amount \
             and not self.env.context.get('remove', False):
         raise UserError(_("Untaxed Amount (%s) must be greater than "
                           "Min Order Amount (%s) which required for "
                           "the apply coupon code!") % (
             formatLang(self.env, self.amount_untaxed, digits=2),
             formatLang(self.env, coupon_code_id.min_order_amount,
                        digits=2)))
     if coupon_code_id.model_id:
         check_coupon = coupon_obj.check_condition(
             coupon_code_id, self.partner_id)
         if check_coupon:
             raise Warning(_("Coupon code (%s) condition criteria not "
                             "match!") % (self.have_coupon_code))
     return coupon_code_id
示例#10
0
 def _get_discount_vals(self):
     payment_vals = []
     price_list_discount = price_rule_discount = coupon_code_discount = 0.0
     coupon_code_obj = self.env['coupon.code']
     partner_id = self.partner_id
     pricelist_id = self.pricelist_id
     for line in self.order_line:
         if not (line.product_id and line.product_uom and
                 partner_id and pricelist_id and
                 pricelist_id.discount_policy == 'without_discount' and
                 self.env.user.has_group(
                     'sale.group_discount_per_so_line')):
             return
         if pricelist_id.pricelist_type == 'basic':
             price_list_discount = self.discount
         else:
             if line.product_uom_qty < 0 and line.coupon_code_id:
                 continue
             if line.order_id.have_coupon_code and line.coupon_code_id:
                 coupon_code_discount += \
                     coupon_code_obj.get_coupon_discount(line, True)
             if line.coupon_code_id and line.price_unit == 0:
                 continue
     if pricelist_id.pricelist_type != 'basic':
         price_rule_discount = (self.discount - coupon_code_discount
                                ) - self.cart_discount
     untaxed_amount = self.gross_amount - self.discount
     payment_vals.append({
         'gross_amount': formatLang(self.env, self.gross_amount, digits=2),
         'price_list_discount':
             formatLang(self.env, price_list_discount, digits=2),
         'price_rule_discount':
             formatLang(self.env, price_rule_discount, digits=2),
         'cart_rule_discount':
             formatLang(self.env, self.cart_discount, digits=2),
         'coupon_code_discount':
             formatLang(self.env, coupon_code_discount, digits=2),
         'currency': self.pricelist_id.currency_id.symbol,
         'untaxed_amount': formatLang(self.env, untaxed_amount, digits=2),
         'position': self.pricelist_id.currency_id.position,
         'amount_words': self.amount_words,
         'discount': formatLang(self.env, self.discount, digits=2),
     })
     return payment_vals
示例#11
0
 def _get_cart_name_price(self):
     for record in self:
         select_option = dict(Cart_Option)
         if record.apply_on in [
                 'subtotal_at_least', 'subtotal_less_than',
                 'item_count_atleast', 'item_count_less_than',
                 'item_sum_qty_atleast', 'item_sum_qty_less_than'
         ]:
             record.name = select_option[record.apply_on] + ' : ' + str(
                 formatLang(self.env, record.amt_value, digits=2))
         elif record.apply_on == 'one_product_al_least' and \
                 record.product_id:
             record.name = select_option[record.apply_on] + ' : ' + str(
                 record.product_id.name)
         elif record.apply_on == 'one_categ_al_least' and \
                 record.categ_id:
             record.name = select_option[record.apply_on] + ' : ' + str(
                 record.categ_id.name)
         elif record.apply_on:
             record.name = select_option[record.apply_on]
示例#12
0
    def act_next(self):
        wiz_line_object = self.env['wiz.indent.line']
        dummy_wiz_line_object = self.env['dummy.wiz.indent.line']
        dup_product_list = []
        list_data = []
        unique_list = []
        check_requisition_qty = False

        for line in self.dummy_wiz_indent_line:
            if line.requisition_qty:
                check_requisition_qty = True
                line.requisition_qty = line.requisition_qty
                if line.product_id.id not in dup_product_list:
                    dup_product_list.append(line.product_id.id)
        if not check_requisition_qty:
            raise Warning(
                _("No Requisition Quantity were \
            found for any line!"))
        msg = 'Following Requisition Quantity is greater than Remaining ' \
              'Quantity!\n'
        check_warning = False
        for line in self.dummy_wiz_indent_line:
            if not line.requisition_qty:
                continue
            if line.requisition_qty > line.remaining_qty:
                check_warning = True
                msg += ("\n %s : Product (%s) => Requisition Quantity (%s) "
                        "and Remaining Quantity (%s)!") % (
                            line.purchase_indent_id.name, line.product_id.name,
                            formatLang(
                                self.env, line.requisition_qty, digits=2),
                            formatLang(self.env, line.remaining_qty, digits=2))
        if check_warning:
            raise Warning(_(msg))
        for line in self.dummy_wiz_indent_line:
            if not line.requisition_qty:
                continue
            line_vals = {
                'purchase_indent_ids': [(4, line.purchase_indent_id.id)],
                'partner_id': line.partner_id.id,
                'name': line.name,
                'product_id': line.product_id.id,
                'product_qty': line.requisition_qty,
                'product_uom': line.product_uom.id,
                'purchase_indent_line_id': line.purchase_indent_line_id.id,
                'wizard_indent_id': self.id,
                'expected_date': line.expected_date,
                'taxes_id': [(6, 0, line.product_id.supplier_taxes_id.ids)],
            }
            if dup_product_list:
                if line.product_id.id not in unique_list:
                    new_line_id = wiz_line_object.create(line_vals)
                    unique_list.append(line.product_id.id)
                    list_data.append(new_line_id.id)
                else:
                    wiz_ids = dummy_wiz_line_object.search([
                        ('wizard_indent_id', '=', line.wizard_indent_id.id),
                        ('product_id', '=', line.product_id.id)
                    ])
                    wiz_indent_line_id = wiz_line_object.search([
                        ('wizard_indent_id', '=', self.id),
                        ('product_id', '=', line.product_id.id)
                    ])
                    indent_list = []
                    qty = 0.0
                    for wiz_id in wiz_ids:
                        indent_list.append(wiz_id.purchase_indent_id.id)
                        qty += wiz_id.requisition_qty
                    wiz_indent_line_id.write({
                        'product_qty':
                        qty,
                        'purchase_indent_ids': [(6, 0, list(set(indent_list)))]
                    })
            else:
                new_line_id = wiz_line_object.create(line_vals)
                list_data.append(new_line_id.id)
        self.write({
            'state': 'confirm',
            'wiz_indent_line': [(6, False, list_data)]
        })
        view_id = \
            self.env.ref('purchase_indent.view_requisition_request_wizard')
        context = dict(self._context)
        return {
            'views': [(view_id.id, 'form')],
            'view_id': view_id.id,
            'type': 'ir.actions.act_window',
            'view_type': 'form',
            'view_mode': 'form',
            'res_model': 'wiz.requisition.request',
            'target': 'new',
            'res_id': self.id,
            'context': context,
        }
示例#13
0
    def test_00_purchase_indent_flow(self):
        self.purchase_indent_id.write({
            'indent_line': [(0, 0, {
                'name': self.product_id_1.name,
                'product_id': self.product_id_1.id,
                'product_qty': 5.0,
                'product_uom': self.product_id_1.uom_po_id.id,
            }),
                            (0, 0, {
                                'name': self.product_id_2.name,
                                'product_id': self.product_id_2.id,
                                'product_qty': 15.0,
                                'product_uom': self.product_id_2.uom_po_id.id,
                            })],
        })

        self.purchase_indent_id_1.write({
            'indent_line': [(0, 0, {
                'name': self.product_id_3.name,
                'product_id': self.product_id_3.id,
                'product_qty': 20.0,
                'product_uom': self.product_id_3.uom_po_id.id,
            }),
                            (0, 0, {
                                'name': self.product_id_1.name,
                                'product_id': self.product_id_1.id,
                                'product_qty': 25.0,
                                'product_uom': self.product_id_1.uom_po_id.id,
                            }),
                            (0, 0, {
                                'name': self.product_id_2.name,
                                'product_id': self.product_id_2.id,
                                'product_qty': 5.0,
                                'product_uom': self.product_id_2.uom_po_id.id,
                            })],
        })

        self.assertTrue(self.purchase_indent_id,
                        'Purchase Indent: no purchase indent created')
        self.assertTrue(self.purchase_indent_id_1,
                        'Purchase Indent: no purchase indent created')

        for line in self.purchase_indent_id.indent_line:
            if line.product_qty < 0:
                raise Warning(
                    _("Quantity (%s) can not be Negative!") %
                    (formatLang(self.env, line.product_qty, digits=2)))

        for line in self.purchase_indent_id_1.indent_line:
            if line.product_qty < 0:
                raise Warning(
                    _("Quantity (%s) can not be Negative!") %
                    (formatLang(self.env, line.product_qty, digits=2)))

        self.purchase_indent_id.action_confirm()
        self.purchase_indent_id_1.action_confirm()

        requisition_id = self.Requisition_Req.create({
            'category_id':
            self.category_id.id,
            'order_type':
            'po',
            'purchase_indent_id':
            self.purchase_indent_id.id,
        })
        requisition_id.onchange_purchase_indent_id()
        requisition_id.dummy_wiz_indent_line[0].write({'requisition_qty': 5})
        requisition_id.dummy_wiz_indent_line[2].write({'requisition_qty': 20})
        requisition_id.act_next()
        requisition_id.write({'partner_id': self.partner_id.id})
        for line in requisition_id.wiz_indent_line:
            line.write({'price_unit': 100})
        requisition_id.action_create()
        logging.info('Successful: Purchase Order Created!')

        # Cancel Purchase Order
        self.purchase_indent_id.indent_history_ids[0].order_id.button_cancel()

        requisition_id_1 = self.Requisition_Req.create({
            'category_id':
            self.category_id.id,
            'order_type':
            'pa',
            'purchase_indent_id':
            self.purchase_indent_id_1.id,
            'requisition_type_id':
            self.agreement_type_id.id,
        })

        requisition_id_1.onchange_purchase_indent_id()
        requisition_id_1.dummy_wiz_indent_line[1].write({'requisition_qty': 4})
        requisition_id_1.dummy_wiz_indent_line[2].write({'requisition_qty': 5})
        requisition_id_1.act_next()
        for line in requisition_id_1.wiz_indent_line:
            line.write({'price_unit': 100})
        requisition_id_1.action_create()
        logging.info('Successful: Purchase Agreement Created!')
    def get_journal_dashboard_datas(self):
        currency = self.currency_id or self.company_id.currency_id
        number_to_reconcile = last_balance = account_sum = 0
        title = ''
        number_draft = number_waiting = number_late = 0
        sum_draft = sum_waiting = sum_late = 0.0
        if self.type in ['bank', 'cash']:
            last_bank_stmt = self.env['account.bank.statement'].search(
                [('journal_id', 'in', self.ids)],
                order="date desc, id desc",
                limit=1)
            last_balance = last_bank_stmt and last_bank_stmt[0].balance_end or 0
            #Get the number of items to reconcile for that bank journal
            self.env.cr.execute(
                """SELECT COUNT(DISTINCT(line.id))
                            FROM account_bank_statement_line AS line
                            LEFT JOIN account_bank_statement AS st
                            ON line.statement_id = st.id
                            WHERE st.journal_id IN %s AND st.state = 'open' AND line.amount != 0.0
                            AND not exists (select 1 from account_move_line aml where aml.statement_line_id = line.id)
                        """, (tuple(self.ids), ))
            number_to_reconcile = self.env.cr.fetchone()[0]
            # optimization to read sum of balance from account_move_line
            account_ids = tuple(ac for ac in [
                self.default_debit_account_id.id,
                self.default_credit_account_id.id
            ] if ac)
            if account_ids:
                amount_field = 'balance' if (
                    not self.currency_id or self.currency_id
                    == self.company_id.currency_id) else 'amount_currency'
                query = """SELECT sum(%s) FROM account_move_line WHERE account_id in %%s AND date <= %%s;""" % (
                    amount_field, )
                self.env.cr.execute(query, (
                    account_ids,
                    fields.Date.today(),
                ))
                query_results = self.env.cr.dictfetchall()
                if query_results and query_results[0].get('sum') != None:
                    account_sum = query_results[0].get('sum')
        #TODO need to check if all invoices are in the same currency than the journal!!!!
        elif self.type in ['sale', 'purchase']:
            title = _('Bills to pay') if self.type == 'purchase' else _(
                'Invoices owed to you')

            (query, query_args) = self._get_open_bills_to_pay_query()
            self.env.cr.execute(query, query_args)
            query_results_to_pay = self.env.cr.dictfetchall()

            (query, query_args) = self._get_draft_bills_query()
            self.env.cr.execute(query, query_args)
            query_results_drafts = self.env.cr.dictfetchall()

            today = datetime.today()
            query = """SELECT amount_total, currency_id AS currency, type FROM account_invoice WHERE journal_id = %s AND date < %s AND state = 'open';"""
            self.env.cr.execute(query, (self.id, today))
            late_query_results = self.env.cr.dictfetchall()
            (number_waiting,
             sum_waiting) = self._count_results_and_sum_amounts(
                 query_results_to_pay, currency)
            (number_draft, sum_draft) = self._count_results_and_sum_amounts(
                query_results_drafts, currency)
            (number_late, sum_late) = self._count_results_and_sum_amounts(
                late_query_results, currency)

        difference = currency.round(last_balance - account_sum) + 0.0
        return {
            'number_to_reconcile':
            number_to_reconcile,
            'account_balance':
            formatLang(self.env,
                       currency.round(account_sum) + 0.0,
                       currency_obj=currency),
            'last_balance':
            formatLang(self.env,
                       currency.round(last_balance) + 0.0,
                       currency_obj=currency),
            'difference':
            formatLang(self.env, difference, currency_obj=currency)
            if difference else False,
            'number_draft':
            number_draft,
            'number_waiting':
            number_waiting,
            'number_late':
            number_late,
            'sum_draft':
            formatLang(self.env,
                       currency.round(sum_draft) + 0.0,
                       currency_obj=currency),
            'sum_waiting':
            formatLang(self.env,
                       currency.round(sum_waiting) + 0.0,
                       currency_obj=currency),
            'sum_late':
            formatLang(self.env,
                       currency.round(sum_late) + 0.0,
                       currency_obj=currency),
            'currency_id':
            currency.id,
            'bank_statements_source':
            self.bank_statements_source,
            'title':
            title,
        }