コード例 #1
0
    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))
コード例 #2
0
ファイル: pos_open_statement.py プロジェクト: gecoerp/gecoerp
    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,
        }
コード例 #3
0
    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'}
コード例 #4
0
    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)
コード例 #5
0
ファイル: res_partner.py プロジェクト: gecoerp/gecoerp
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
コード例 #6
0
ファイル: partner.py プロジェクト: gecoerp/gecoerp
 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
コード例 #7
0
ファイル: stock.py プロジェクト: gecoerp/gecoerp
 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
コード例 #8
0
 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
コード例 #9
0
    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
コード例 #10
0
    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(),
        })
コード例 #11
0
 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'))
コード例 #12
0
    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
コード例 #13
0
ファイル: account_invoice.py プロジェクト: gecoerp/gecoerp
    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)
コード例 #14
0
ファイル: mrp_repair.py プロジェクト: gecoerp/gecoerp
 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'})
コード例 #15
0
 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()
コード例 #16
0
ファイル: account_payment.py プロジェクト: gecoerp/gecoerp
 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()
コード例 #17
0
    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
コード例 #18
0
    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
コード例 #19
0
    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)
コード例 #20
0
    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
コード例 #21
0
    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)]})
コード例 #22
0
 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
コード例 #23
0
ファイル: stock_inventory.py プロジェクト: gecoerp/gecoerp
 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.'))
コード例 #24
0
ファイル: account_payment.py プロジェクト: gecoerp/gecoerp
    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
コード例 #25
0
    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.'))
コード例 #26
0
 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')
コード例 #27
0
ファイル: stock_landed_cost.py プロジェクト: gecoerp/gecoerp
    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
コード例 #28
0
 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 {}
コード例 #29
0
 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."
               ))
コード例 #30
0
 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)