def onchange_discount_per(self): if self.discount_method != 'per': return 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_data = self.env['res.config.settings'].sudo().get_values() if config_data.get('global_discount_apply'): if config_data.get('global_discount_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_data.get('global_discount_percentage'), digits=2)))
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)))
def _check_make_stub_line(self, invoice): """ Return the dict used to display an invoice/refund in the stub """ # DEPRECATED: TO BE REMOVED IN MASTER # Find the account.partial.reconcile which are common to the invoice and the payment if invoice.move_type in ['in_invoice', 'out_refund']: invoice_sign = 1 invoice_payment_reconcile = invoice.line_ids.mapped('matched_debit_ids').filtered(lambda r: r.debit_move_id in self.line_ids) else: invoice_sign = -1 invoice_payment_reconcile = invoice.line_ids.mapped('matched_credit_ids').filtered(lambda r: r.credit_move_id in self.line_ids) if self.currency_id != self.journal_id.company_id.currency_id: amount_paid = abs(sum(invoice_payment_reconcile.mapped('amount_currency'))) else: amount_paid = abs(sum(invoice_payment_reconcile.mapped('amount'))) amount_residual = invoice_sign * invoice.amount_residual return { 'due_date': format_date(self.env, invoice.invoice_date_due), 'number': invoice.ref and invoice.name + ' - ' + invoice.ref or invoice.name, 'amount_total': formatLang(self.env, invoice_sign * invoice.amount_total, currency_obj=invoice.currency_id), 'amount_residual': formatLang(self.env, amount_residual, currency_obj=invoice.currency_id) if amount_residual * 10**4 != 0 else '-', 'amount_paid': formatLang(self.env, invoice_sign * amount_paid, currency_obj=self.currency_id), 'currency': invoice.currency_id, }
def _check_fix_amount_value(self): config_data = self.env['res.config.settings'].sudo().get_values() if config_data.get('global_discount_apply') \ and config_data.get('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_data.get('global_discount_fix_amount'), digits=2)))
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)))
def pricelist(self, promo, **post): redirect = post.get('r', '/shop/cart') if request.website.pricelist_id.pricelist_type == 'basic': return super(WebsiteSale, self).pricelist(promo) else: sale_order_id = request.session.get('sale_order_id') sale_order = request.env['sale.order'].sudo().browse( sale_order_id).exists() if sale_order_id else None pricelist_id = request.website.pricelist_id if pricelist_id and not pricelist_id.apply_coupon_code: return request.redirect("%s?apply_coupon_code=1" % redirect) coupon_obj = request.env['coupon.code'] coupon_code_id = coupon_obj.sudo().get_coupon_records( promo, request.website.pricelist_id) params = {} if not coupon_code_id: return request.redirect("%s?coupon_code_id=1" % redirect) if coupon_code_id.usage_limit > 0 \ and coupon_code_id.remaining_limit <= 0: return request.redirect("%s?coupon_exceeds_limit=1" % redirect) min_order_amount = coupon_code_id.min_order_amount if not sale_order.coupon_code_id and min_order_amount \ and sale_order.amount_untaxed < min_order_amount: params['min_order_amount'] = \ formatLang(request.env, min_order_amount, currency_obj=pricelist_id.currency_id) params['subtotal'] = \ formatLang(request.env, sale_order.amount_untaxed, currency_obj=pricelist_id.currency_id) return request.redirect( _build_url_w_params("%s?coupon_min_order=1" % redirect, params)) if coupon_code_id.model_id: partner_id = request.website.user_id.sudo().partner_id check_coupon = coupon_obj.check_condition( coupon_code_id, partner_id) if check_coupon: return request.redirect("%s?coupon_condition=1" % redirect) check_coupon = True for line in sale_order.order_line: if line.product_uom_qty < \ coupon_code_id.number_of_x_product and not \ line.coupon_code_id and check_coupon: check_coupon = True else: check_coupon = False break if check_coupon: return request.redirect("%s?coupon_condition=1" % redirect) sale_order.have_coupon_code = promo sale_order.apply_coupon_code() return request.redirect(redirect)
def _check_percentage(self): if self.percentage < 0 or self.percentage > 100: raise ValueError(_("Percentage should be between 0% to 100%!")) config_data = self.env['res.config.settings'].sudo().get_values() if config_data.get('global_discount_apply') \ and config_data.get('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_dat.get('global_discount_percentage'), digits=2)))
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)))
def _compute_display_name(self): for record in self: record.display_name = "%s: %s - %s (%s)" % ( record.distribution.name, record.type.name, record.ref, formatLang(record.env, record.expense_amount, currency_obj=record.distribution.currency_id) )
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'
def _check_build_page_info(self, i, p): multi_stub = self.company_id.account_check_printing_multi_stub return { 'sequence_number': self.check_number, 'manual_sequencing': self.journal_id.check_manual_sequencing, 'date': format_date(self.env, self.date), 'partner_id': self.partner_id, 'partner_name': self.partner_id.name, 'currency': self.currency_id, 'state': self.state, 'amount': formatLang(self.env, self.amount, currency_obj=self.currency_id) if i == 0 else 'VOID', 'amount_in_word': self._check_fill_line(self.check_amount_in_words) if i == 0 else 'VOID', 'memo': self.ref, 'stub_cropped': not multi_stub and len(self.move_id._get_reconciled_invoices()) > INV_LINES_PER_STUB, # If the payment does not reference an invoice, there is no stub line to display 'stub_lines': p, }
def _get_pricelist_item_name_price(self): for item in self: if item.categ_id and item.applied_on == '2_product_category': item.name = _("Category: %s") % (item.categ_id.display_name) elif item.product_tmpl_id and item.applied_on == '1_product': item.name = _("Product: %s") % ( item.product_tmpl_id.display_name) elif item.product_id and item.applied_on == '0_product_variant': item.name = _("Variant: %s") % (item.product_id.with_context( display_default_code=False).display_name) else: item.name = _("All Products") if item.compute_price == 'fixed': item.price = formatLang(item.env, item.fixed_price, monetary=True, dp="Product Price", currency_obj=item.currency_id) elif item.compute_price == 'percentage': item.price = _("%s %% discount", item.percent_price) else: item.price = _( "%(percentage)s %% discount and %(price)s surcharge", percentage=item.price_discount, price=item.price_surcharge)
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()
def onchange_requisition_qty(self): warning = {} if self.requisition_qty < 0: warning.update({ 'title': _("Warning"), 'message': _("Requisition Quantity (%s) can not be \ Negative!") % ( formatLang(self.env, self.requisition_qty, digits=2)) }) self.requisition_qty = False return {'warning': warning}
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)))
def _balance_check(self): for stmt in self: if not stmt.currency_id.is_zero(stmt.difference): if stmt.journal_type == 'cash': if stmt.difference < 0.0: account = stmt.journal_id.loss_account_id name = _('Loss') else: # statement.difference > 0.0 account = stmt.journal_id.profit_account_id name = _('Profit') if not account: raise UserError( _('Please go on the %s journal and define a %s Account. This account will be used to record cash difference.' ) % (stmt.journal_id.name, name)) values = { 'statement_id': stmt.id, 'account_id': account.id, 'amount': stmt.difference, 'name': _("Cash difference observed during the counting (%s)") % name, } self.env['account.bank.statement.line'].create(values) else: balance_end_real = formatLang( self.env, stmt.balance_end_real, currency_obj=stmt.currency_id) balance_end = formatLang(self.env, stmt.balance_end, currency_obj=stmt.currency_id) raise UserError( _('The ending balance is incorrect !\nThe expected balance (%s) is different from the computed one. (%s)' ) % (balance_end_real, balance_end)) return True
def onchange_discount_amount(self): if self.discount_method != 'fixed': return values = self.get_maximum_per_amount() if self.discount < 0 < self.gross_amount: raise Warning(_("Discount should be less than Gross Amount")) if self.discount > 0 > self.gross_amount: raise Warning(_("Discount should be less than Gross Amount")) discount = self.discount or self.discount_amount if (0 < self.gross_amount < discount) or (0 > self.gross_amount > discount): 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.gross_amount > 0 and self.discount > 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_data = self.env['res.config.settings'].sudo().get_values() if config_data.get('global_discount_apply'): fix_amount = config_data.get('global_discount_fix_amount') if self.gross_amount > 0 and 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_data.get('global_discount_fix_amount'), digits=2)))
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)))
def prepare_vals(invoice, partials): number = ' - '.join([invoice.name, invoice.ref] if invoice.ref else [invoice.name]) if invoice.is_outbound(): invoice_sign = 1 partial_field = 'debit_amount_currency' else: invoice_sign = -1 partial_field = 'credit_amount_currency' if invoice.currency_id.is_zero(invoice.amount_residual): amount_residual_str = '-' else: amount_residual_str = formatLang(self.env, invoice_sign * invoice.amount_residual, currency_obj=invoice.currency_id) return { 'due_date': format_date(self.env, invoice.invoice_date_due), 'number': number, 'amount_total': formatLang(self.env, invoice_sign * invoice.amount_total, currency_obj=invoice.currency_id), 'amount_residual': amount_residual_str, 'amount_paid': formatLang(self.env, invoice_sign * sum(partials.mapped(partial_field)), currency_obj=self.currency_id), 'currency': invoice.currency_id, }
def get_journal_dashboard_datas(self): res = super(AccountJournal, self).get_journal_dashboard_datas() #add the number and sum of expenses to pay to the json defining the accounting dashboard data (query, query_args) = self._get_expenses_to_pay_query() self.env.cr.execute(query, query_args) query_results_to_pay = self.env.cr.dictfetchall() (number_to_pay, sum_to_pay) = self._count_results_and_sum_amounts( query_results_to_pay, self.company_id.currency_id) res['number_expenses_to_pay'] = number_to_pay res['sum_expenses_to_pay'] = formatLang(self.env, sum_to_pay or 0.0, currency_obj=self.currency_id or self.company_id.currency_id) return res
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
def _format_strings(self, string, move, amount): return string.format( percent=self.percentage, name=move.name, id=move.id, amount=formatLang(self.env, abs(amount), currency_obj=self.company_id.currency_id), debit_credit=amount < 0 and _('C') or _('D'), link=self._format_move_link(move), date=format_date(self.env, move.date), new_date=self.date and format_date(self.env, self.date) or _('[Not set]'), account_target_name=self.destination_account_id.display_name, )
def crm_lead_get_by_partner_id(self, partner, limit, offset, **kwargs): partner_leads = request.env['crm.lead'].search( [('partner_id', '=', partner)], offset=offset, limit=limit) leads = [] for lead in partner_leads: leads.append({ 'id': lead.id, 'name': lead.name, 'expected_revenue': formatLang(request.env, lead.expected_revenue, monetary=True, currency_obj=lead.company_currency), }) return {'leads': leads}
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]
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
def onchange_discount_amount(self): values = self.get_maximum_per_amount() if self.discount < 0 < self.gross_amount: raise Warning(_("Discount should be less than Gross Amount")) if self.discount > 0 > self.gross_amount: raise Warning(_("Discount should be less than Gross Amount")) discount = self.discount or self.discount_amount if discount == 0: return if (0 < self.gross_amount < discount) or (0 > self.gross_amount > discount): 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.gross_amount > 0 and 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_data = self.env['res.config.settings'].sudo().get_values() if config_data.get('global_discount_invoice_apply'): fix_amount = config_data.get('global_discount_fix_invoice_amount') if self.gross_amount > 0 and 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_data.get('global_discount_fix_invoice_amount'), digits=2)))
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) return { 'number_to_reconcile': number_to_reconcile, 'account_balance': formatLang(self.env, account_sum, currency_obj=self.currency_id or self.company_id.currency_id), 'last_balance': formatLang(self.env, last_balance, currency_obj=self.currency_id or self.company_id.currency_id), 'difference': (last_balance - account_sum) and formatLang( self.env, last_balance - account_sum, currency_obj=self.currency_id or self.company_id.currency_id) or False, 'number_draft': number_draft, 'number_waiting': number_waiting, 'number_late': number_late, 'sum_draft': formatLang(self.env, sum_draft or 0.0, currency_obj=self.currency_id or self.company_id.currency_id), 'sum_waiting': formatLang(self.env, sum_waiting or 0.0, currency_obj=self.currency_id or self.company_id.currency_id), 'sum_late': formatLang(self.env, sum_late or 0.0, currency_obj=self.currency_id or self.company_id.currency_id), 'currency_id': self.currency_id and self.currency_id.id or self.company_id.currency_id.id, 'bank_statements_source': self.bank_statements_source, 'title': title, }
def get_followup_details(self): self.ensure_one() payment_followup_print = \ self.env['report.payment_followup.report_payment_followup'] assert len(self.ids) == 1 partner = self.commercial_partner_id followup_table = '' if partner.move_line_ids: company = self.env.user.company_id current_date = fields.Date.today() final_res = payment_followup_print._get_related_move_lines( partner, company.id) for currency_dict in final_res: currency = currency_dict.get( 'line', [{ 'currency_id': company.currency_id }])[0]['currency_id'] followup_table += ''' <table border="2" width=100%%> <tr> <td>''' + _("Invoice Date") + '''</td> <td>''' + _("Description") + '''</td> <td>''' + _("Reference") + '''</td> <td>''' + _("Due Date") + '''</td> <td>''' + _( "Amount") + " (%s)" % (currency.symbol) + '''</td> <td>''' + _("Lit.") + '''</td> </tr> ''' total = 0 for aml in currency_dict['line']: block = aml['blocked'] and 'X' or ' ' total += aml['amount_balance'] strbegin = "<TD>" strend = "</TD>" date = aml['date_maturity'] or aml['date'] if date <= current_date and aml['amount_balance'] > 0: strbegin = "<TD><B>" strend = "</B></TD>" followup_table += \ "<TR>" + strbegin + str(aml['date']) + \ strend + strbegin + aml['name'] + \ strend + strbegin + \ (aml['ref'] or '') + \ strend + strbegin + \ str(date) + strend + strbegin + str(aml['amount_balance']) + \ strend + strbegin + block + strend + \ "</TR>" total = reduce(lambda x, y: x + y['amount_balance'], currency_dict['line'], 0.00) total = formatLang(self.env, total, dp='Account', currency_obj=currency) followup_table += '''<tr> </tr> </table> <br> <div align="right"> <B> <font style="font-size: 14px;">''' + \ _("Amount due") + ''' : %s </div>''' % (total) return followup_table
def _compute_invoice_taxes_by_group(self): report_or_portal_view = 'commit_assetsbundle' in self.env.context or \ not self.env.context.get('params', {}).get('view_type') == 'form' if not report_or_portal_view: return super()._compute_invoice_taxes_by_group() move_with_doc_type = self.filtered('l10n_latam_document_type_id') for move in move_with_doc_type: lang_env = move.with_context(lang=move.partner_id.lang).env tax_lines = move.l10n_latam_tax_ids tax_balance_multiplicator = -1 if move.is_inbound(True) else 1 res = {} # There are as many tax line as there are repartition lines done_taxes = set() for line in tax_lines: res.setdefault(line.tax_line_id.tax_group_id, { 'base': 0.0, 'amount': 0.0 }) res[line.tax_line_id. tax_group_id]['amount'] += tax_balance_multiplicator * ( line.amount_currency if line.currency_id else line.balance) tax_key_add_base = tuple( move._get_tax_key_for_group_add_base(line)) if tax_key_add_base not in done_taxes: if line.currency_id and line.company_currency_id and line.currency_id != line.company_currency_id: amount = line.company_currency_id._convert( line.tax_base_amount, line.currency_id, line.company_id, line.date or fields.Date.today()) else: amount = line.tax_base_amount res[line.tax_line_id.tax_group_id]['base'] += amount # The base should be added ONCE done_taxes.add(tax_key_add_base) # At this point we only want to keep the taxes with a zero amount since they do not # generate a tax line. zero_taxes = set() for line in move.line_ids: for tax in line.l10n_latam_tax_ids.flatten_taxes_hierarchy(): if tax.tax_group_id not in res or tax.id in zero_taxes: res.setdefault(tax.tax_group_id, { 'base': 0.0, 'amount': 0.0 }) res[tax.tax_group_id][ 'base'] += tax_balance_multiplicator * ( line.amount_currency if line.currency_id else line.balance) zero_taxes.add(tax.id) res = sorted(res.items(), key=lambda l: l[0].sequence) move.amount_by_group = [ (group.name, amounts['amount'], amounts['base'], formatLang(lang_env, amounts['amount'], currency_obj=move.currency_id), formatLang(lang_env, amounts['base'], currency_obj=move.currency_id), len(res), group.id) for group, amounts in res ] super(AccountMove, self - move_with_doc_type)._compute_invoice_taxes_by_group()
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!')