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 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 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 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 on_change_url(self): self.ensure_one() if self.url: res = self._parse_document_url(self.url) if res.get('error'): raise Warning( _('Could not fetch data from url. Document or access right not available:\n%s' ) % res['error']) values = res['values'] if not values.get('document_id'): raise Warning( _('Please enter valid Youtube or Google Doc URL')) for key, value in values.items(): self[key] = value
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 unlink(self): for record in self: if record.purchase_indent_ids: raise Warning( _("You can not delete agreement which have \ reference of Purchase Indent!")) return super(PurchaseRequisition, self).unlink()
def _get_eu_res_country_group(self): eu_group = self.env.ref("base.europe", raise_if_not_found=False) if not eu_group: raise Warning( _('The Europe country group cannot be found. ' 'Please update the base module.')) return eu_group
def unlink(self): for record in self: if record.purchase_indent_ids: raise Warning( _("You can not delete Purchase order which \ have reference of Purchase Indent!")) return super(PurchaseOrder, self).unlink()
def copy(self): self.ensure_one() if self.purchase_indent_ids: raise Warning( _("You can not copy Purchase order which have \ reference of Purchase Indent!")) return super(PurchaseOrder, self).copy()
def check_date(self): for rule_line_id in self: parent_start_date = rule_line_id.rule_id_start_date child_start_date = rule_line_id.start_date if parent_start_date and \ child_start_date and parent_start_date > child_start_date: raise Warning( _("Start Date date not valid in " "Product Rule Lines!")) parent_end_date = rule_line_id.rule_id_end_date child_end_date = rule_line_id.end_date if parent_end_date and \ child_end_date and parent_end_date < child_end_date: raise Warning( _("End Date date not valid in " "Product Rule Lines!"))
def unlink(self): for indent_id in self: if indent_id.state not in ['draft', 'cancel']: raise Warning( _("Invalid Action!\n You cannot delete a \ Purchase Indent which is not in 'Draft' or 'Cancel' State!")) indent_id.indent_line.unlink() return super(PurchaseIndent, self).unlink()
def check_duplicate_coupon_code(self): check_coupon_id = self.search([('coupon_code', '=', self.coupon_code), ('id', '!=', self.id), ('pricelist_id', '=', self.pricelist_id.id)]) if check_coupon_id: raise Warning( _("Coupon code (%s) already exists!") % (self.coupon_code))
def action_cancel(self): group_id = self.sudo().env.ref('purchase.group_purchase_manager') if self._uid != self.create_uid.id \ and self._uid not in group_id.users.ids: raise Warning( _("Can't cancel purchase indent which is \ requested by %s!") % (self.create_uid.name)) self.state = 'cancel'
def copy(self, default=None): self.ensure_one() default = dict(default or {}) if self.purchase_indent_ids: raise Warning( _("You can not copy Purchase Agreement which \ have reference of Purchase Indent!")) default.update(name=_("%s (copy)") % (self.name or '')) return super(PurchaseRequisition, self).copy(default)
def write(self, values): self._get_languages.clear_cache(self) if values.get('website_code') or \ (values.get('is_default_website') and self != self.env.ref('website.default_website')): raise Warning(_('Unexpected bad things will happen!\n' 'Changing website code or default website ' 'can have unintended side effects.\n' '- We will not updated your old views.\n' '- If above action is not properly done ' 'then it will break your current ' 'multi website feature.')) return super(Website, self).write(values)
def button_immediate_install(self): for app in self: if app.category_id and ( app.category_id.name == 'Theme' or app.category_id.parent_id.name == 'Theme') and \ not app.website_ids: raise Warning( _('You are trying to install Theme module!\n' 'As actpy will support multi-website so, ' 'please install theme in specific website.\n' 'Go to...\n' '- Menu: Website/Configuration/Settings\n' '- Select website & its theme & Save it.')) return super(IrModuleModule, self).button_immediate_install()
def _onchange_discount(self): self.discount = 0.0 if not (self.product_id and self.product_uom and self.order_id.partner_id and self.order_id.pricelist_id and self.order_id.pricelist_id.discount_policy == 'without_discount' and self.env.user.has_group('sale.group_discount_per_so_line')): return discount = 0.0 context_partner = dict(self.env.context, partner_id=self.order_id.partner_id.id, date=self.order_id.date_order) pricelist_context = dict(context_partner, uom=self.product_uom.id) if self.order_id.pricelist_id.pricelist_type == 'basic': price, rule_id = self.order_id.pricelist_id.with_context( pricelist_context).get_product_price_rule( self.product_id, self.product_uom_qty or 1.0, self.order_id.partner_id) new_list_price, currency_id = self.with_context( context_partner)._get_real_price_currency( self.product_id, rule_id, self.product_uom_qty, self.product_uom, self.order_id.pricelist_id.id) if new_list_price != 0: if self.order_id.pricelist_id.currency_id.id != currency_id: new_list_price = self.env['res.currency'].browse( currency_id).with_context(context_partner).compute( new_list_price, self.order_id.pricelist_id.currency_id) discount = (new_list_price - price) / new_list_price * 100 if discount > 0: self.discount = discount else: if self.coupon_code_id and (self._context.get( 'quantity', False) or self._context.get( 'price_unit', False) or self._context.get('tax', False)): raise Warning(_('You can not change order line. ' 'Please remove coupon code first!')) discount, product_price = self.get_rule_discount() if discount > 0: self.discount = discount if self.order_id.have_coupon_code and self.coupon_code_id: self.get_total_coupon_code()
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 unlink(self): if self.purchase_indent_line_id: raise Warning( _("You can not delete line which have \ reference of Purchase Indent")) return super(PurchaseOrderLine, self).unlink()
def generate_fec(self): self.ensure_one() # We choose to implement the flat file instead of the XML # file for 2 reasons : # 1) the XSD file impose to have the label on the account.move # but actpy has the label on the account.move.line, so that's a # problem ! # 2) CSV files are easier to read/use for a regular accountant. # So it will be easier for the accountant to check the file before # sending it to the fiscal administration header = [ u'JournalCode', # 0 u'JournalLib', # 1 u'EcritureNum', # 2 u'EcritureDate', # 3 u'CompteNum', # 4 u'CompteLib', # 5 u'CompAuxNum', # 6 We use partner.id u'CompAuxLib', # 7 u'PieceRef', # 8 u'PieceDate', # 9 u'EcritureLib', # 10 u'Debit', # 11 u'Credit', # 12 u'EcritureLet', # 13 u'DateLet', # 14 u'ValidDate', # 15 u'Montantdevise', # 16 u'Idevise', # 17 ] company = self.env.user.company_id if not company.vat: raise Warning( _("Missing VAT number for company %s") % company.name) if company.vat[0:2] != 'FR': raise Warning( _("FEC is for French companies only !")) fecfile = io.BytesIO() w = pycompat.csv_writer(fecfile, delimiter='|') w.writerow(header) # INITIAL BALANCE unaffected_earnings_xml_ref = self.env.ref('account.data_unaffected_earnings') unaffected_earnings_line = True # used to make sure that we add the unaffected earning initial balance only once if unaffected_earnings_xml_ref: #compute the benefit/loss of last year to add in the initial balance of the current year earnings account unaffected_earnings_results = self.do_query_unaffected_earnings() unaffected_earnings_line = False sql_query = ''' SELECT 'OUV' AS JournalCode, 'Balance initiale' AS JournalLib, 'OUVERTURE/' || %s AS EcritureNum, %s AS EcritureDate, MIN(aa.code) AS CompteNum, replace(replace(MIN(aa.name), '|', '/'), '\t', '') AS CompteLib, '' AS CompAuxNum, '' AS CompAuxLib, '-' AS PieceRef, %s AS PieceDate, '/' AS EcritureLib, replace(CASE WHEN sum(aml.balance) <= 0 THEN '0,00' ELSE to_char(SUM(aml.balance), '000000000000000D99') END, '.', ',') AS Debit, replace(CASE WHEN sum(aml.balance) >= 0 THEN '0,00' ELSE to_char(-SUM(aml.balance), '000000000000000D99') END, '.', ',') AS Credit, '' AS EcritureLet, '' AS DateLet, %s AS ValidDate, '' AS Montantdevise, '' AS Idevise, MIN(aa.id) AS CompteID FROM account_move_line aml LEFT JOIN account_move am ON am.id=aml.move_id JOIN account_account aa ON aa.id = aml.account_id LEFT JOIN account_account_type aat ON aa.user_type_id = aat.id WHERE am.date < %s AND am.company_id = %s AND aat.include_initial_balance = 't' AND (aml.debit != 0 OR aml.credit != 0) ''' # For official report: only use posted entries if self.export_type == "official": sql_query += ''' AND am.state = 'posted' ''' sql_query += ''' GROUP BY aml.account_id, aat.type HAVING sum(aml.balance) != 0 AND aat.type not in ('receivable', 'payable') ''' formatted_date_from = self.date_from.replace('-', '') date_from = datetime.strptime(self.date_from, DEFAULT_SERVER_DATE_FORMAT) formatted_date_year = date_from.year self._cr.execute( sql_query, (formatted_date_year, formatted_date_from, formatted_date_from, formatted_date_from, self.date_from, company.id)) for row in self._cr.fetchall(): listrow = list(row) account_id = listrow.pop() if not unaffected_earnings_line: account = self.env['account.account'].browse(account_id) if account.user_type_id.id == self.env.ref('account.data_unaffected_earnings').id: #add the benefit/loss of previous fiscal year to the first unaffected earnings account found. unaffected_earnings_line = True current_amount = float(listrow[11].replace(',', '.')) - float(listrow[12].replace(',', '.')) unaffected_earnings_amount = float(unaffected_earnings_results[11].replace(',', '.')) - float(unaffected_earnings_results[12].replace(',', '.')) listrow_amount = current_amount + unaffected_earnings_amount if listrow_amount > 0: listrow[11] = str(listrow_amount).replace('.', ',') listrow[12] = '0,00' else: listrow[11] = '0,00' listrow[12] = str(-listrow_amount).replace('.', ',') w.writerow(listrow) #if the unaffected earnings account wasn't in the selection yet: add it manually if (not unaffected_earnings_line and unaffected_earnings_results and (unaffected_earnings_results[11] != '0,00' or unaffected_earnings_results[12] != '0,00')): #search an unaffected earnings account unaffected_earnings_account = self.env['account.account'].search([('user_type_id', '=', self.env.ref('account.data_unaffected_earnings').id)], limit=1) if unaffected_earnings_account: unaffected_earnings_results[4] = unaffected_earnings_account.code unaffected_earnings_results[5] = unaffected_earnings_account.name w.writerow(unaffected_earnings_results) # INITIAL BALANCE - receivable/payable sql_query = ''' SELECT 'OUV' AS JournalCode, 'Balance initiale' AS JournalLib, 'OUVERTURE/' || %s AS EcritureNum, %s AS EcritureDate, MIN(aa.code) AS CompteNum, replace(MIN(aa.name), '|', '/') AS CompteLib, CASE WHEN rp.ref IS null OR rp.ref = '' THEN COALESCE('ID ' || rp.id, '') ELSE replace(rp.ref, '|', '/') END AS CompAuxNum, COALESCE(replace(rp.name, '|', '/'), '') AS CompAuxLib, '-' AS PieceRef, %s AS PieceDate, '/' AS EcritureLib, replace(CASE WHEN sum(aml.balance) <= 0 THEN '0,00' ELSE to_char(SUM(aml.balance), '000000000000000D99') END, '.', ',') AS Debit, replace(CASE WHEN sum(aml.balance) >= 0 THEN '0,00' ELSE to_char(-SUM(aml.balance), '000000000000000D99') END, '.', ',') AS Credit, '' AS EcritureLet, '' AS DateLet, %s AS ValidDate, '' AS Montantdevise, '' AS Idevise, MIN(aa.id) AS CompteID FROM account_move_line aml LEFT JOIN account_move am ON am.id=aml.move_id LEFT JOIN res_partner rp ON rp.id=aml.partner_id JOIN account_account aa ON aa.id = aml.account_id LEFT JOIN account_account_type aat ON aa.user_type_id = aat.id WHERE am.date < %s AND am.company_id = %s AND aat.include_initial_balance = 't' AND (aml.debit != 0 OR aml.credit != 0) ''' # For official report: only use posted entries if self.export_type == "official": sql_query += ''' AND am.state = 'posted' ''' sql_query += ''' GROUP BY aml.account_id, aat.type, rp.ref, rp.id HAVING sum(aml.balance) != 0 AND aat.type in ('receivable', 'payable') ''' self._cr.execute( sql_query, (formatted_date_year, formatted_date_from, formatted_date_from, formatted_date_from, self.date_from, company.id)) for row in self._cr.fetchall(): listrow = list(row) account_id = listrow.pop() w.writerow([s.encode("utf-8") for s in listrow]) # LINES sql_query = ''' SELECT replace(replace(aj.code, '|', '/'), '\t', '') AS JournalCode, replace(replace(aj.name, '|', '/'), '\t', '') AS JournalLib, replace(replace(am.name, '|', '/'), '\t', '') AS EcritureNum, TO_CHAR(am.date, 'YYYYMMDD') AS EcritureDate, aa.code AS CompteNum, replace(replace(aa.name, '|', '/'), '\t', '') AS CompteLib, CASE WHEN rp.ref IS null OR rp.ref = '' THEN COALESCE('ID ' || rp.id, '') ELSE replace(rp.ref, '|', '/') END AS CompAuxNum, COALESCE(replace(replace(rp.name, '|', '/'), '\t', ''), '') AS CompAuxLib, CASE WHEN am.ref IS null OR am.ref = '' THEN '-' ELSE replace(replace(am.ref, '|', '/'), '\t', '') END AS PieceRef, TO_CHAR(am.date, 'YYYYMMDD') AS PieceDate, CASE WHEN aml.name IS NULL THEN '/' ELSE replace(replace(aml.name, '|', '/'), '\t', '') END AS EcritureLib, replace(CASE WHEN aml.debit = 0 THEN '0,00' ELSE to_char(aml.debit, '000000000000000D99') END, '.', ',') AS Debit, replace(CASE WHEN aml.credit = 0 THEN '0,00' ELSE to_char(aml.credit, '000000000000000D99') END, '.', ',') AS Credit, CASE WHEN rec.name IS NULL THEN '' ELSE rec.name END AS EcritureLet, CASE WHEN aml.full_reconcile_id IS NULL THEN '' ELSE TO_CHAR(rec.create_date, 'YYYYMMDD') END AS DateLet, TO_CHAR(am.date, 'YYYYMMDD') AS ValidDate, CASE WHEN aml.amount_currency IS NULL OR aml.amount_currency = 0 THEN '' ELSE replace(to_char(aml.amount_currency, '000000000000000D99'), '.', ',') END AS Montantdevise, CASE WHEN aml.currency_id IS NULL THEN '' ELSE rc.name END AS Idevise FROM account_move_line aml LEFT JOIN account_move am ON am.id=aml.move_id LEFT JOIN res_partner rp ON rp.id=aml.partner_id JOIN account_journal aj ON aj.id = am.journal_id JOIN account_account aa ON aa.id = aml.account_id LEFT JOIN res_currency rc ON rc.id = aml.currency_id LEFT JOIN account_full_reconcile rec ON rec.id = aml.full_reconcile_id WHERE am.date >= %s AND am.date <= %s AND am.company_id = %s AND (aml.debit != 0 OR aml.credit != 0) ''' # For official report: only use posted entries if self.export_type == "official": sql_query += ''' AND am.state = 'posted' ''' sql_query += ''' ORDER BY am.date, am.name, aml.id ''' self._cr.execute( sql_query, (self.date_from, self.date_to, company.id)) for row in self._cr.fetchall(): w.writerow(list(row)) siren = company.vat[4:13] end_date = self.date_to.replace('-', '') suffix = '' if self.export_type == "nonofficial": suffix = '-NONOFFICIAL' fecvalue = fecfile.getvalue() self.write({ 'fec_data': base64.encodestring(fecvalue), # Filename = <siren>FECYYYYMMDD where YYYMMDD is the closing date 'filename': '%sFEC%s%s.csv' % (siren, end_date, suffix), }) fecfile.close() action = { 'name': 'FEC', 'type': 'ir.actions.act_url', 'url': "web/content/?model=account.fr.fec&id=" + str(self.id) + "&filename_field=filename&field=fec_data&download=true&filename=" + self.filename, 'target': 'self', } return action
def onchange_discount_method(self): self.discount_amount = 0.0 self.discount_per = 0.0 if self.discount_method and not self.invoice_line_ids: raise Warning('No Invoice Line(s) were found!')
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 apply_coupon_code(self): if self._context.get('website_id', False): coupon_obj = self.env['coupon.code'] coupon_id = coupon_obj.get_coupon_records( self.have_coupon_code, self.pricelist_id) else: coupon_id = self._check_Constraints() order_line = self.order_line coupon_discount_amount = 0.0 have_coupon_code = self.have_coupon_code coupon_flag = True onchange_context = True coupon_ref_id = coupon_id.id remove = False cal_coupon = False if self.coupon_flag: have_coupon_code = '' coupon_flag = False onchange_context = False coupon_ref_id = False remove = True check_coupon = True qty = 0.0 for line in order_line: if coupon_id.apply_on == 'category' and not \ line.product_id.categ_id == coupon_id.categ_id: continue elif coupon_id.apply_on == 'product_template' and not \ line.product_id.product_tmpl_id == \ coupon_id.product_tmpl_id: continue elif coupon_id.apply_on == 'product' and not \ line.product_id == coupon_id.product_id: continue else: if coupon_id.coupon_type == 'percent' or \ coupon_id.coupon_type == 'clubbed': discount_per = coupon_id.discount_amount if coupon_id.coupon_type == 'clubbed': discount_per = coupon_id.flat_discount + \ coupon_id.extra_discount_percentage coupon_discount_amount += \ self._get_percentage_coupon_discount( line, coupon_id, onchange_context, cal_coupon, discount_per, remove) check_coupon = False elif coupon_id.coupon_type == 'fixed_amount': coupon_discount_amount += self._get_fixed_coupon_discount( line, coupon_id, onchange_context, cal_coupon, remove) check_coupon = False elif coupon_id.coupon_type == 'buy_x_get_y' and \ coupon_id.number_of_x_product and \ coupon_id.number_of_y_product: if line.product_uom_qty < \ coupon_id.number_of_x_product and not \ line.coupon_code_id and check_coupon: check_coupon = True continue self._get_same_product_coupon_discount( line, coupon_id, remove) check_coupon = False elif coupon_id.coupon_type == 'buy_x_get_y_other': if line.product_uom_qty < \ coupon_id.number_of_x_product and not \ line.coupon_code_id and check_coupon: check_coupon = True continue qty += self._get_other_product_coupon_discount( line, coupon_id) check_coupon = False elif coupon_id.coupon_type == 'buy_x_get_percent': if line.product_uom_qty < \ coupon_id.number_of_x_product and not \ line.coupon_code_id and check_coupon: check_coupon = True continue coupon_discount_amount += \ self.buy_x_get_percentage_coupon_discount( line, coupon_id, onchange_context, cal_coupon, remove) check_coupon = False if check_coupon and not self._context.get('website_id', False): raise Warning(_("Coupon code (%s) condition criteria not match!" ) % (self.have_coupon_code)) if qty: self.env['sale.order.line'].create({ 'product_id': coupon_id.other_product_id.id, 'product_uom_qty': int(qty), 'order_id': self.id, 'coupon_code_id': coupon_id.id, 'price_unit': 0.0}) self.write({'have_coupon_code': have_coupon_code, 'coupon_flag': coupon_flag, 'coupon_code_id': coupon_ref_id})
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 onchange_discount_method(self): self.discount_amount = 0.0 self.discount_per = 0.0 if self.discount_method and not self.order_line: raise Warning('No Sale Order Line(s) were found!')
def create(self, values): res = super(Website, self).create(values) default_website = self.env['website'].search([( 'is_default_website', '=', True)]) if not len(default_website) or len(default_website) > 1: raise Warning(_('Either default website is not defined ' 'or multiple default website is defined!!\n' 'You can define only one website as ' 'default website.')) website_menu = self.env['website.menu'] ir_model_data = self.env['ir.model.data'] # Menu Entries: # Clone top menu & home menu of default website for new website top_menu = self.env.ref('website.main_menu', False) home_menu = self.env.ref('website.menu_homepage', False) new_home_menu = False if top_menu and home_menu: top_menu = website_menu.search([ ('id', '=', self.env.ref('website.main_menu').id), ('website_id', '=', default_website.id)]) home_menu = website_menu.search([ ('id', '=', self.env.ref('website.menu_homepage').id), ('website_id', '=', default_website.id)]) new_top_menu = top_menu.copy() new_top_menu.write({ 'website_id': res.id, }) new_home_menu = home_menu.copy() new_home_menu.write({ 'website_id': res.id, 'parent_id': new_top_menu.id, }) # Home Page & View Entry: # Clone home page & view of default website for new website home_page = self.env.ref('website.homepage_page', False) if home_page and new_home_menu: new_home_page = home_page.copy() new_home_page.view_id.write({ 'name': home_page.view_id.name, 'website_id': res.id, 'key': home_page.view_id.key + '_' + res.website_code, 'is_cloned': True, }) home_model_data_id = ir_model_data.create({ 'model': home_page.view_id.model_data_id.model, 'name': home_page.view_id.model_data_id.name + '_' + res.website_code, 'res_id': new_home_page.view_id.id, 'module': home_page.view_id.model_data_id.module, }) new_home_page.view_id.write({ 'model_data_id': home_model_data_id }) new_home_page.write({ 'url': home_page.url, 'view_id': new_home_page.view_id.id, 'website_published': True, 'website_ids': [(6, 0, [res.id])], 'menu_ids': [(6, 0, [new_home_menu.id])], }) return res
def execute(self): self.ensure_one() # Multi Website: Do not allow more than 1 website as default website if self.env['website'].search_count([('is_default_website', '=', True) ]) > 1: raise Warning( _('You can define only one website as default one.\n' 'More than one websites are not allowed ' 'as default website.')) if not self.env.user._is_superuser() and not \ self.env.user.has_group('base.group_system'): raise AccessError(_("Only administrators can change the settings")) self = self.with_context(active_test=False) classified = self._get_classified_fields() # default values fields IrDefault = self.env['ir.default'].sudo() for name, model, field in classified['default']: if isinstance(self[name], models.BaseModel): if self._fields[name].type == 'many2one': value = self[name].id else: value = self[name].ids else: value = self[name] IrDefault.set(model, field, value) # group fields: modify group / implied groups for name, groups, implied_group in classified['group']: if self[name]: groups.write({'implied_ids': [(4, implied_group.id)]}) else: groups.write({'implied_ids': [(3, implied_group.id)]}) implied_group.write({ 'users': [(3, user.id) for user in groups.mapped('users')] }) # other fields: execute method 'set_values' # Methods that start with `set_` are now deprecated for method in dir(self): if method.startswith('set_') and method is not 'set_values': _logger.warning( _('Methods that start with `set_` ' 'are deprecated. Override `set_values` ' 'instead (Method %s)') % method) self.set_values() # module fields: install/uninstall the selected modules to_install = [] to_upgrade = self.env['ir.module.module'] to_uninstall_modules = self.env['ir.module.module'] lm = len('module_') for name, module in classified['module']: if self[name]: to_install.append((name[lm:], module)) else: if module and module.state in ('installed', 'to upgrade'): to_uninstall_modules += module if 'install_theme' in classified and 'uninstall_theme' in classified: for theme in classified['install_theme']: if theme: to_install.append((theme.name, theme)) if theme.state == 'installed': to_upgrade += theme for theme in classified['uninstall_theme']: if theme and theme.state in ('installed', 'to upgrade'): to_uninstall_modules += theme if to_uninstall_modules: to_uninstall_modules.button_immediate_uninstall() if to_upgrade: to_upgrade.button_immediate_upgrade() self._install_modules(to_install) if to_install or to_uninstall_modules: # After the uninstall/install calls, the registry and environments # are no longer valid. So we reset the environment. self.env.reset() self = self.env()[self._name] # pylint: disable=next-method-called config = self.env['res.config'].next() or {} if config.get('type') not in ('ir.actions.act_window_close', ): return config # force client-side reload (update user menu and current view) return { 'type': 'ir.actions.client', 'tag': 'reload', }