def _satisfy_condition(self, localdict): """ @param contract_id: id of hr.contract to be tested @return: returns True if the given rule match the condition for the given contract. Return False otherwise. """ self.ensure_one() if self.condition_select == 'none': return True elif self.condition_select == 'range': try: result = safe_eval(self.condition_range, localdict) return self.condition_range_min <= result and result <= self.condition_range_max or False except: raise UserError( _('Wrong range condition defined for salary rule %s (%s).') % (self.name, self.code)) else: # python code try: safe_eval(self.condition_python, localdict, mode='exec', nocopy=True) return 'result' in localdict and localdict['result'] or False except: raise UserError( _('Wrong python condition defined for salary rule %s (%s).' ) % (self.name, self.code))
def open_statement(self): self.ensure_one() BankStatement = self.env['account.bank.statement'] journals = self.env['account.journal'].search([('journal_user', '=', True)]) if not journals: raise UserError( _('You have to define which payment method must be available in the point of sale by reusing existing bank and cash through "Accounting / Configuration / Journals / Journals". Select a journal and check the field "PoS Payment Method" from the "Point of Sale" tab. You can also create new payment methods directly from menu "PoS Backend / Configuration / Payment Methods".' )) for journal in journals: if journal.sequence_id: number = journal.sequence_id.next_by_id() else: raise UserError(_("No sequence defined on the journal")) BankStatement += BankStatement.create({ 'journal_id': journal.id, 'user_id': self.env.uid, 'name': number }) tree_id = self.env.ref('account.view_bank_statement_tree').id form_id = self.env.ref('account.view_bank_statement_form').id search_id = self.env.ref('account.view_bank_statement_search').id return { 'type': 'ir.actions.act_window', 'name': _('List of Cash Registers'), 'view_type': 'form', 'view_mode': 'tree,form', 'res_model': 'account.bank.statement', 'domain': str([('id', 'in', BankStatement.ids)]), 'views': [(tree_id, 'tree'), (form_id, 'form')], 'search_view_id': search_id, }
def act_update(self): ''' Function called by the wizard. ''' flag, gengo = self.gengo_authentication() if not flag: raise UserError(gengo) for wizard in self: supported_langs = self.env[ 'ir.translation']._get_all_supported_languages() language = self.env[ 'ir.translation']._get_gengo_corresponding_language( wizard.lang_id.code) if language not in supported_langs: raise UserError( _('This language is not supported by the Gengo translation services.' )) ctx = self.env.context.copy() ctx['gengo_language'] = wizard.lang_id.id if wizard.sync_limit > 200 or wizard.sync_limit < 1: raise UserError( _('The number of terms to sync should be between 1 to 200 to work with Gengo translation services.' )) if wizard.sync_type in ['send', 'both']: self.with_context(ctx)._sync_request(wizard.sync_limit) if wizard.sync_type in ['receive', 'both']: self.with_context(ctx)._sync_response(wizard.sync_limit) return {'type': 'ir.actions.act_window_close'}
def _print_report(self, data): res = {} data = self.pre_print_report(data) data['form'].update(self.read(['period_length'])[0]) period_length = data['form']['period_length'] if period_length <= 0: raise UserError(_('You must set a period length greater than 0.')) if not data['form']['date_from']: raise UserError(_('You must set a start date.')) start = datetime.strptime(data['form']['date_from'], "%Y-%m-%d") for i in range(5)[::-1]: stop = start - relativedelta(days=period_length - 1) res[str(i)] = { 'name': (i != 0 and (str( (5 - (i + 1)) * period_length) + '-' + str( (5 - i) * period_length)) or ('+' + str(4 * period_length))), 'stop': start.strftime('%Y-%m-%d'), 'start': (i != 0 and stop.strftime('%Y-%m-%d') or False), } start = stop - relativedelta(days=1) data['form'].update(res) return self.env.ref( 'account.action_report_aged_partner_balance').with_context( landscape=True).report_action(self, data=data)
def geo_find(addr, apikey=False): if not addr: return None if not apikey: raise UserError( _('''API key for GeoCoding (Places) required.\n Save this key in System Parameters with key: google.api_key_geocode, value: <your api key> Visit https://developers.google.com/maps/documentation/geocoding/get-api-key for more information. ''')) url = "https://maps.googleapis.com/maps/api/geocode/json" try: result = requests.get(url, params={ 'sensor': 'false', 'address': addr, 'key': apikey }).json() except Exception as e: raise UserError( _('Cannot contact geolocation servers. Please make sure that your Internet connection is up and running (%s).' ) % e) if result['status'] != 'OK': if result.get('error_message'): _logger.error(result['error_message']) return None try: geo = result['results'][0]['geometry']['location'] return float(geo['lat']), float(geo['lng']) except (KeyError, ValueError): return None
def create_membership_invoice(self, product_id=None, datas=None): """ Create Customer Invoice of Membership for partners. @param datas: datas has dictionary value which consist Id of Membership product and Cost Amount of Membership. datas = {'membership_product_id': None, 'amount': None} """ product_id = product_id or datas.get('membership_product_id') amount = datas.get('amount', 0.0) invoice_list = [] for partner in self: addr = partner.address_get(['invoice']) if partner.free_member: raise UserError(_("Partner is a free Member.")) if not addr.get('invoice', False): raise UserError(_("Partner doesn't have an address to make the invoice.")) invoice = self.env['account.invoice'].create({ 'partner_id': partner.id, 'account_id': partner.property_account_receivable_id.id, 'fiscal_position_id': partner.property_account_position_id.id }) line_values = { 'product_id': product_id, 'price_unit': amount, 'invoice_id': invoice.id, } # create a record in cache, apply onchange then revert back to a dictionnary invoice_line = self.env['account.invoice.line'].new(line_values) invoice_line._onchange_product_id() line_values = invoice_line._convert_to_write({name: invoice_line[name] for name in invoice_line._cache}) line_values['price_unit'] = amount invoice.write({'invoice_line_ids': [(0, 0, line_values)]}) invoice_list.append(invoice.id) invoice.compute_taxes() return invoice_list
def _action_done(self): self.product_price_update_before_done() res = super(StockMove, self)._action_done() for move in res: # Apply restrictions on the stock move to be able to make # consistent accounting entries. if move._is_in() and move._is_out(): raise UserError( _("The move lines are not in a consistent state: some are entering and other are leaving the company. " )) company_src = move.mapped('move_line_ids.location_id.company_id') company_dst = move.mapped( 'move_line_ids.location_dest_id.company_id') try: if company_src: company_src.ensure_one() if company_dst: company_dst.ensure_one() except ValueError: raise UserError( _("The move lines are not in a consistent states: they do not share the same origin or destination company." )) if company_src and company_dst and company_src.id != company_dst.id: raise UserError( _("The move lines are not in a consistent states: they are doing an intercompany in a single step while they should go through the intercompany transit location." )) move._run_valuation() for move in res.filtered( lambda m: m.product_id.valuation == 'real_time' and (m._is_in() or m._is_out() or m._is_dropshipped() or m. _is_dropshipped_returned())): move._account_entry_move() return res
def _prepare_move_line_value(self): self.ensure_one() if self.account_id: account = self.account_id elif self.product_id: account = self.product_id.product_tmpl_id._get_product_accounts( )['expense'] if not account: raise UserError( _("No Expense account found for the product %s (or for its category), please configure one." ) % (self.product_id.name)) else: account = self.env['ir.property'].with_context( force_company=self.company_id.id).get( 'property_account_expense_categ_id', 'product.category') if not account: raise UserError( _('Please configure Default Expense account for Product expense: `property_account_expense_categ_id`.' )) aml_name = self.employee_id.name + ': ' + self.name.split('\n')[0][:64] move_line = { 'type': 'src', 'name': aml_name, 'price_unit': self.unit_amount, 'quantity': self.quantity, 'price': self.total_amount, 'account_id': account.id, 'product_id': self.product_id.id, 'uom_id': self.product_uom_id.id, 'analytic_account_id': self.analytic_account_id.id, 'expense_id': self.id, } return move_line
def action_validate(self): self._check_security_action_validate() current_employee = self.env['hr.employee'].search( [('user_id', '=', self.env.uid)], limit=1) for holiday in self: if holiday.state not in ['confirm', 'validate1']: raise UserError( _('Leave request must be confirmed in order to approve it.' )) if holiday.state == 'validate1' and not holiday.env.user.has_group( 'hr_holidays.group_hr_holidays_manager'): raise UserError( _('Only an HR Manager can apply the second approval on leave requests.' )) holiday.write({'state': 'validate'}) if holiday.double_validation: holiday.write({'second_approver_id': current_employee.id}) else: holiday.write({'first_approver_id': current_employee.id}) if holiday.holiday_type == 'employee' and holiday.type == 'remove': holiday._validate_leave_request() elif holiday.holiday_type == 'category': leaves = self.env['hr.holidays'] for employee in holiday.category_id.employee_ids: values = holiday._prepare_create_by_category(employee) leaves += self.with_context( mail_notify_force_send=False).create(values) # TODO is it necessary to interleave the calls? leaves.action_approve() if leaves and leaves[0].double_validation: leaves.action_validate() return True
def button_start(self): self.ensure_one() # As button_start is automatically called in the new view if self.state in ('done', 'cancel'): return True # Need a loss in case of the real time exceeding the expected timeline = self.env['mrp.workcenter.productivity'] if self.duration < self.duration_expected: loss_id = self.env['mrp.workcenter.productivity.loss'].search([('loss_type','=','productive')], limit=1) if not len(loss_id): raise UserError(_("You need to define at least one productivity loss in the category 'Productivity'. Create one from the Manufacturing app, menu: Configuration / Productivity Losses.")) else: loss_id = self.env['mrp.workcenter.productivity.loss'].search([('loss_type','=','performance')], limit=1) if not len(loss_id): raise UserError(_("You need to define at least one productivity loss in the category 'Performance'. Create one from the Manufacturing app, menu: Configuration / Productivity Losses.")) for workorder in self: if workorder.production_id.state != 'progress': workorder.production_id.write({ 'state': 'progress', 'date_start': datetime.now(), }) timeline.create({ 'workorder_id': workorder.id, 'workcenter_id': workorder.workcenter_id.id, 'description': _('Time Tracking: ')+self.env.user.name, 'loss_id': loss_id[0].id, 'date_start': datetime.now(), 'user_id': self.env.user.id }) return self.write({'state': 'progress', 'date_start': datetime.now(), })
def _inverse_remaining_leaves(self): status_list = self.env['hr.holidays.status'].search([('limit', '=', False)]) # Create leaves (adding remaining leaves) or raise (reducing remaining leaves) actual_remaining = self._get_remaining_leaves() for employee in self.filtered(lambda employee: employee.remaining_leaves): # check the status list. This is done here and not before the loop to avoid raising # exception on employee creation (since we are in a computed field). if len(status_list) != 1: raise UserError(_("The feature behind the field 'Remaining Legal Leaves' can only be used when there is only one " "leave type with the option 'Allow to Override Limit' unchecked. (%s Found). " "Otherwise, the update is ambiguous as we cannot decide on which leave type the update has to be done. " "\n You may prefer to use the classic menus 'Leave Requests' and 'Allocation Requests' located in Leaves Application " "to manage the leave days of the employees if the configuration does not allow to use this field.") % (len(status_list))) status = status_list[0] if status_list else None if not status: continue # if a status is found, then compute remaing leave for current employee difference = employee.remaining_leaves - actual_remaining.get(employee.id, 0) if difference > 0: leave = self.env['hr.holidays'].create({ 'name': _('Allocation for %s') % employee.name, 'employee_id': employee.id, 'holiday_status_id': status.id, 'type': 'add', 'holiday_type': 'employee', 'number_of_days_temp': difference }) leave.action_approve() if leave.double_validation: leave.action_validate() elif difference < 0: raise UserError(_('You cannot reduce validated allocation requests'))
def write(self, vals): has_been_posted = False for order in self: if order.company_id._is_accounting_unalterable(): # write the hash and the secure_sequence_number when posting or invoicing an pos.order if vals.get('state') in ['paid', 'done', 'invoiced']: has_been_posted = True # restrict the operation in case we are trying to write a forbidden field if (order.state in ['paid', 'done', 'invoiced'] and set(vals).intersection(ORDER_FIELDS)): raise UserError( _('According to the French law, you cannot modify a point of sale order. Forbidden fields: %s.' ) % ', '.join(ORDER_FIELDS)) # restrict the operation in case we are trying to overwrite existing hash if (order.l10n_fr_hash and 'l10n_fr_hash' in vals) or ( order.l10n_fr_secure_sequence_number and 'l10n_fr_secure_sequence_number' in vals): raise UserError( _('You cannot overwrite the values ensuring the inalterability of the point of sale.' )) res = super(pos_order, self).write(vals) # write the hash and the secure_sequence_number when posting or invoicing a pos order if has_been_posted: for order in self.filtered( lambda o: o.company_id._is_accounting_unalterable() and not (o.l10n_fr_secure_sequence_number or o.l10n_fr_hash)): new_number = order.company_id.l10n_fr_pos_cert_sequence_id.next_by_id( ) vals_hashing = { 'l10n_fr_secure_sequence_number': new_number, 'l10n_fr_hash': order._get_new_hash(new_number) } res |= super(pos_order, order).write(vals_hashing) return res
def create(self, vals): reference = vals.get('reference', False) reference_type = vals.get('reference_type', False) if vals.get('type') == 'out_invoice' and not reference_type: # fallback on default communication type for partner partner = self.env['res.partner'].browse(vals['partner_id']) reference_type = partner.out_inv_comm_type if reference_type == 'bba': reference = self.generate_bbacomm(vals['type'], reference_type, partner.id, '')['value']['reference'] vals.update({ 'reference_type': reference_type or 'none', 'reference': reference, }) if reference_type == 'bba': if not reference: raise UserError(_('Empty BBA Structured Communication!' '\nPlease fill in a unique BBA Structured Communication.')) if self.check_bbacomm(reference): reference = re.sub('\D', '', reference) vals['reference'] = '+++' + reference[0:3] + '/' + reference[3:7] + '/' + reference[7:] + '+++' same_ids = self.search([('type', '=', 'out_invoice'), ('reference_type', '=', 'bba'), ('reference', '=', vals['reference'])]) if same_ids: raise UserError(_('The BBA Structured Communication has already been used!' '\nPlease create manually a unique BBA Structured Communication.')) return super(AccountInvoice, self).create(vals)
def action_repair_cancel(self): if self.filtered(lambda repair: repair.state == 'done'): raise UserError(_("Cannot cancel completed repairs.")) if any(repair.invoiced for repair in self): raise UserError(_('Repair order is already invoiced.')) self.mapped('operations').write({'state': 'cancel'}) return self.write({'state': 'cancel'})
def unlink(self): for asset in self: if asset.state in ['open', 'close']: raise UserError(_('You cannot delete a document is in %s state.') % (asset.state,)) for depreciation_line in asset.depreciation_line_ids: if depreciation_line.move_id: raise UserError(_('You cannot delete a document that contains posted entries.')) return super(AccountAssetAsset, self).unlink()
def unlink(self): if any(bool(rec.move_line_ids) for rec in self): raise UserError( _("You can not delete a payment that is already posted")) if any(rec.move_name for rec in self): raise UserError( _('It is not allowed to delete a payment that already created a journal entry since it would create a gap in the numbering. You should create the journal entry again and cancel it thanks to a regular revert.' )) return super(account_payment, self).unlink()
def _find_additional_data(self, currency_code, account_number): """ Look for a res.currency and account.journal using values extracted from the statement and make sure it's consistent. """ company_currency = self.env.user.company_id.currency_id journal_obj = self.env['account.journal'] currency = None sanitized_account_number = sanitize_account_number(account_number) if currency_code: currency = self.env['res.currency'].search( [('name', '=ilike', currency_code)], limit=1) if not currency: raise UserError( _("No currency found matching '%s'.") % currency_code) if currency == company_currency: currency = False journal = journal_obj.browse(self.env.context.get('journal_id', [])) if account_number: # No bank account on the journal : create one from the account number of the statement if journal and not journal.bank_account_id: journal.set_bank_account(account_number) # No journal passed to the wizard : try to find one using the account number of the statement elif not journal: journal = journal_obj.search([ ('bank_account_id.sanitized_acc_number', '=', sanitized_account_number) ]) # Already a bank account on the journal : check it's the same as on the statement else: if not self._check_journal_bank_account( journal, sanitized_account_number): raise UserError( _('The account of this statement (%s) is not the same as the journal (%s).' ) % (account_number, journal.bank_account_id.acc_number)) # If importing into an existing journal, its currency must be the same as the bank statement if journal: journal_currency = journal.currency_id if currency is None: currency = journal_currency if currency and currency != journal_currency: statement_cur_code = not currency and company_currency.name or currency.name journal_cur_code = not journal_currency and company_currency.name or journal_currency.name raise UserError( _('The currency of the bank statement (%s) is not the same as the currency of the journal (%s) !' ) % (statement_cur_code, journal_cur_code)) # If we couldn't find / can't create a journal, everything is lost if not journal and not account_number: raise UserError( _('Cannot find in which journal import this statement. Please manually select a journal.' )) return currency, journal
def default_get(self, fields): if len(self.env.context.get('active_ids', list())) > 1: raise UserError("You may only return one picking at a time!") res = super(ReturnPicking, self).default_get(fields) move_dest_exists = False product_return_moves = [] picking = self.env['stock.picking'].browse( self.env.context.get('active_id')) if picking: res.update({'picking_id': picking.id}) if picking.state != 'done': raise UserError(_("You may only return Done pickings")) for move in picking.move_lines: if move.scrapped: continue if move.move_dest_ids: move_dest_exists = True quantity = move.product_qty - sum(move.move_dest_ids.filtered(lambda m: m.state in ['partially_available', 'assigned', 'done']).\ mapped('move_line_ids').mapped('product_qty')) quantity = float_round( quantity, precision_rounding=move.product_uom.rounding) product_return_moves.append((0, 0, { 'product_id': move.product_id.id, 'quantity': quantity, 'move_id': move.id, 'uom_id': move.product_id.uom_id.id })) if not product_return_moves: raise UserError( _("No products to return (only lines in Done state and not fully returned yet can be returned)!" )) if 'product_return_moves' in fields: res.update({'product_return_moves': product_return_moves}) if 'move_dest_exists' in fields: res.update({'move_dest_exists': move_dest_exists}) if 'parent_location_id' in fields and picking.location_id.usage == 'internal': res.update({ 'parent_location_id': picking.picking_type_id.warehouse_id and picking.picking_type_id.warehouse_id.view_location_id.id or picking.location_id.location_id.id }) if 'original_location_id' in fields: res.update({'original_location_id': picking.location_id.id}) if 'location_id' in fields: location_id = picking.location_id.id if picking.picking_type_id.return_picking_type_id.default_location_dest_id.return_location: location_id = picking.picking_type_id.return_picking_type_id.default_location_dest_id.id res['location_id'] = location_id return res
def _check_hash_integrity(self, company_id): """Checks that all posted or invoiced pos orders have still the same data as when they were posted and raises an error with the result. """ def build_order_info(order): entry_reference = _('(Receipt ref.: %s)') order_reference_string = order.pos_reference and entry_reference % order.pos_reference or '' return [ ctx_tz(order, 'date_order'), order.l10n_fr_secure_sequence_number, order.name, order_reference_string, ctx_tz(order, 'write_date') ] orders = self.search([('state', 'in', ['paid', 'done', 'invoiced']), ('company_id', '=', company_id), ('l10n_fr_secure_sequence_number', '!=', 0)], order="l10n_fr_secure_sequence_number ASC") if not orders: raise UserError( _('There isn\'t any order flagged for data inalterability yet for the company %s. This mechanism only runs for point of sale orders generated after the installation of the module France - Certification CGI 286 I-3 bis. - POS' ) % self.env.user.company_id.name) previous_hash = u'' start_order_info = [] for order in orders: if order.l10n_fr_hash != order._compute_hash( previous_hash=previous_hash): raise UserError( _('Corrupted data on point of sale order with id %s.') % order.id) previous_hash = order.l10n_fr_hash orders_sorted_date = orders.sorted(lambda o: o.date_order) start_order_info = build_order_info(orders_sorted_date[0]) end_order_info = build_order_info(orders_sorted_date[-1]) report_dict = { 'start_order_name': start_order_info[2], 'start_order_ref': start_order_info[3], 'start_order_date': start_order_info[0], 'end_order_name': end_order_info[2], 'end_order_ref': end_order_info[3], 'end_order_date': end_order_info[0] } # Raise on success raise UserError( _('''Successful test ! The point of sale orders are guaranteed to be in their original and inalterable state From: %(start_order_name)s %(start_order_ref)s recorded on %(start_order_date)s To: %(end_order_name)s %(end_order_ref)s recorded on %(end_order_date)s For this report to be legally meaningful, please download your certification from your customer account on GECOERP.com (Only for GECOERP Enterprise users).''' ) % report_dict)
def done(self): pickings = self.mapped('picking_ids').filtered( lambda picking: picking.state not in ('cancel', 'done')) if any(picking.state not in ('assigned') for picking in pickings): raise UserError( _('Some pickings are still waiting for goods. Please check or force their availability before setting this batch to done.' )) for picking in pickings: picking.message_post( body= "<b>%s:</b> %s <a href=#id=%s&view_type=form&model=stock.picking.batch>%s</a>" % (_("Transferred by"), _("Batch Picking"), picking.batch_id.id, picking.batch_id.name)) picking_to_backorder = self.env['stock.picking'] picking_without_qty_done = self.env['stock.picking'] for picking in pickings: if all([x.qty_done == 0.0 for x in picking.move_line_ids]): # If no lots when needed, raise error picking_type = picking.picking_type_id if (picking_type.use_create_lots or picking_type.use_existing_lots): for ml in picking.move_line_ids: if ml.product_id.tracking != 'none': raise UserError( _('Some products require lots/serial numbers, so you need to specify those first!' )) # Check if we need to set some qty done. picking_without_qty_done |= picking elif picking._check_backorder(): picking_to_backorder |= picking else: picking.action_done() self.write({'state': 'done'}) if picking_without_qty_done: view = self.env.ref('stock.view_immediate_transfer') wiz = self.env['stock.immediate.transfer'].create({ 'pick_ids': [(4, p.id) for p in picking_without_qty_done], 'pick_to_backorder_ids': [(4, p.id) for p in picking_to_backorder], }) return { 'name': _('Immediate Transfer?'), 'type': 'ir.actions.act_window', 'view_type': 'form', 'view_mode': 'form', 'res_model': 'stock.immediate.transfer', 'views': [(view.id, 'form')], 'view_id': view.id, 'target': 'new', 'res_id': wiz.id, 'context': self.env.context, } if picking_to_backorder: return picking_to_backorder.action_generate_backorder_wizard() return True
def action_apply(self): self.env['res.partner'].check_access_rights('write') """ From selected partners, add corresponding users to chosen portal group. It either granted existing user, or create new one (and add it to the group). """ error_msg = self.get_error_messages() if error_msg: raise UserError("\n\n".join(error_msg)) for wizard_user in self.sudo().with_context(active_test=False): group_portal = wizard_user.wizard_id.portal_id if not group_portal.is_portal: raise UserError( _('Group %s is not a portal') % group_portal.name) user = wizard_user.partner_id.user_ids[ 0] if wizard_user.partner_id.user_ids else None # update partner email, if a new one was introduced if wizard_user.partner_id.email != wizard_user.email: wizard_user.partner_id.write({'email': wizard_user.email}) # add portal group to relative user of selected partners if wizard_user.in_portal: user_portal = None # create a user if necessary, and make sure it is in the portal group if not user: if wizard_user.partner_id.company_id: company_id = wizard_user.partner_id.company_id.id else: company_id = self.env[ 'res.company']._company_default_get('res.users').id user_portal = wizard_user.sudo().with_context( company_id=company_id)._create_user() else: user_portal = user wizard_user.write({'user_id': user_portal.id}) if not wizard_user.user_id.active or group_portal not in wizard_user.user_id.groups_id: wizard_user.user_id.write({ 'active': True, 'groups_id': [(4, group_portal.id)] }) # prepare for the signup process wizard_user.user_id.partner_id.signup_prepare() wizard_user.with_context(active_test=True)._send_email() wizard_user.refresh() else: # remove the user (if it exists) from the portal group if user and group_portal in user.groups_id: # if user belongs to portal only, deactivate it if len(user.groups_id) <= 1: user.write({ 'groups_id': [(3, group_portal.id)], 'active': False }) else: user.write({'groups_id': [(3, group_portal.id)]})
def _check_write(self): """check that the field is created from the menu and not from an database update otherwise the database update can crash:""" if self.env.context.get('manual'): global_state = self._get_global_state() if global_state == 'anonymized': raise UserError(_("The database is currently anonymized, you cannot create, modify or delete fields.")) elif global_state == 'unstable': raise UserError(_("The database anonymization is currently in an unstable state. Some fields are anonymized," " while some fields are not anonymized. You should try to solve this problem before trying to create, write or delete fields.")) return True
def _check_filter_product(self): if self.filter == 'none' and self.product_id and self.location_id and self.lot_id: return if self.filter not in ('product', 'product_owner') and self.product_id: raise UserError(_('The selected inventory options are not coherent.')) if self.filter != 'lot' and self.lot_id: raise UserError(_('The selected inventory options are not coherent.')) if self.filter not in ('owner', 'product_owner') and self.partner_id: raise UserError(_('The selected inventory options are not coherent.')) if self.filter != 'pack' and self.package_id: raise UserError(_('The selected inventory options are not coherent.'))
def post(self): """ Create the journal items for the payment and update the payment's state to 'posted'. A journal entry is created containing an item in the source liquidity account (selected journal's default_debit or default_credit) and another in the destination reconciliable account (see _compute_destination_account_id). If invoice_ids is not empty, there will be one reconciliable move line per invoice to reconcile with. If the payment is a transfer, a second journal entry is created in the destination journal to receive money from the transfer account. """ for rec in self: if rec.state != 'draft': raise UserError(_("Only a draft payment can be posted.")) if any(inv.state != 'open' for inv in rec.invoice_ids): raise ValidationError( _("The payment cannot be processed because the invoice is not open!" )) # Use the right sequence to set the name if rec.payment_type == 'transfer': sequence_code = 'account.payment.transfer' else: if rec.partner_type == 'customer': if rec.payment_type == 'inbound': sequence_code = 'account.payment.customer.invoice' if rec.payment_type == 'outbound': sequence_code = 'account.payment.customer.refund' if rec.partner_type == 'supplier': if rec.payment_type == 'inbound': sequence_code = 'account.payment.supplier.refund' if rec.payment_type == 'outbound': sequence_code = 'account.payment.supplier.invoice' rec.name = self.env['ir.sequence'].with_context( ir_sequence_date=rec.payment_date).next_by_code(sequence_code) if not rec.name and rec.payment_type != 'transfer': raise UserError( _("You have to define a sequence for %s in your company.") % (sequence_code, )) # Create the journal entry amount = rec.amount * (rec.payment_type in ('outbound', 'transfer') and 1 or -1) move = rec._create_payment_entry(amount) # In case of a transfer, the first journal entry created debited the source liquidity account and credited # the transfer account. Now we debit the transfer account and credit the destination liquidity account. if rec.payment_type == 'transfer': transfer_credit_aml = move.line_ids.filtered( lambda r: r.account_id == rec.company_id. transfer_account_id) transfer_debit_aml = rec._create_transfer_entry(amount) (transfer_credit_aml + transfer_debit_aml).reconcile() rec.write({'state': 'posted', 'move_name': move.name}) return True
def _check_parsed_data(self, stmts_vals): """ Basic and structural verifications """ if len(stmts_vals) == 0: raise UserError(_('This file doesn\'t contain any statement.')) no_st_line = True for vals in stmts_vals: if vals['transactions'] and len(vals['transactions']) > 0: no_st_line = False break if no_st_line: raise UserError(_('This file doesn\'t contain any transaction.'))
def get_access_token(self, scope=None): Config = self.env['ir.config_parameter'].sudo() google_drive_refresh_token = Config.get_param( 'google_drive_refresh_token') user_is_admin = self.env['res.users'].browse( self.env.user.id)._is_admin() if not google_drive_refresh_token: if user_is_admin: dummy, action_id = self.env[ 'ir.model.data'].get_object_reference( 'base_setup', 'action_general_configuration') msg = _( "You haven't configured 'Authorization Code' generated from google, Please generate and configure it ." ) raise RedirectWarning(msg, action_id, _('Go to the configuration panel')) else: raise UserError( _("Google Drive is not yet configured. Please contact your administrator." )) google_drive_client_id = Config.get_param('google_drive_client_id') google_drive_client_secret = Config.get_param( 'google_drive_client_secret') #For Getting New Access Token With help of old Refresh Token data = { 'client_id': google_drive_client_id, 'refresh_token': google_drive_refresh_token, 'client_secret': google_drive_client_secret, 'grant_type': "refresh_token", 'scope': scope or 'https://www.googleapis.com/auth/drive' } headers = {"Content-type": "application/x-www-form-urlencoded"} try: req = requests.post(GOOGLE_TOKEN_ENDPOINT, data=data, headers=headers, timeout=TIMEOUT) req.raise_for_status() except requests.HTTPError: if user_is_admin: dummy, action_id = self.env[ 'ir.model.data'].get_object_reference( 'base_setup', 'action_general_configuration') msg = _( "Something went wrong during the token generation. Please request again an authorization code ." ) raise RedirectWarning(msg, action_id, _('Go to the configuration panel')) else: raise UserError( _("Google Drive is not yet configured. Please contact your administrator." )) return req.json().get('access_token')
def button_validate(self): if any(cost.state != 'draft' for cost in self): raise UserError(_('Only draft landed costs can be validated')) if any(not cost.valuation_adjustment_lines for cost in self): raise UserError( _('No valuation adjustments lines. You should maybe recompute the landed costs.' )) if not self._check_sum(): raise UserError( _('Cost and adjustments lines do not match. You should maybe recompute the landed costs.' )) for cost in self: move = self.env['account.move'] move_vals = { 'journal_id': cost.account_journal_id.id, 'date': cost.date, 'ref': cost.name, 'line_ids': [], } for line in cost.valuation_adjustment_lines.filtered( lambda line: line.move_id): # Prorate the value at what's still in stock cost_to_add = ( line.move_id.remaining_qty / line.move_id.product_qty) * line.additional_landed_cost new_landed_cost_value = line.move_id.landed_cost_value + line.additional_landed_cost line.move_id.write({ 'landed_cost_value': new_landed_cost_value, 'value': line.move_id.value + line.additional_landed_cost, 'remaining_value': line.move_id.remaining_value + cost_to_add, 'price_unit': (line.move_id.value + line.additional_landed_cost) / line.move_id.product_qty, }) # `remaining_qty` is negative if the move is out and delivered proudcts that were not # in stock. qty_out = 0 if line.move_id._is_in(): qty_out = line.move_id.product_qty - line.move_id.remaining_qty elif line.move_id._is_out(): qty_out = line.move_id.product_qty move_vals['line_ids'] += line._create_accounting_entries( move, qty_out) move = move.create(move_vals) cost.write({'state': 'done', 'account_move_id': move.id}) move.post() return True
def _run(self, records): for box in self: for record in records: if not record.journal_id: raise UserError( _("Please check that the field 'Journal' is set on the Bank Statement" )) if not record.journal_id.company_id.transfer_account_id: raise UserError( _("Please check that the field 'Transfer Account' is set on the company." )) box._create_bank_statement_line(record) return {}
def button_reg_close(self): """ Close Registration """ today = fields.Datetime.now() if self.event_id.date_begin <= today and self.event_id.state == 'confirm': self.write({'state': 'done', 'date_closed': today}) elif self.event_id.state == 'draft': raise UserError( _("You must wait the event confirmation before doing this action." )) else: raise UserError( _("You must wait the event starting day before doing this action." ))
def generate_report(self): if (not self.env.user.company_id.logo): raise UserError( _("You have to set a logo or a layout for your company.")) elif (not self.env.user.company_id.external_report_layout): raise UserError( _("You have to set your reports's header and footer layout.")) data = { 'date_start': self.start_date, 'date_stop': self.end_date, 'config_ids': self.pos_config_ids.ids } return self.env.ref('point_of_sale.sale_details_report').report_action( [], data=data)