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_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 _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 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 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_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}
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 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 _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 _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 _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 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, }
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, }