コード例 #1
0
ファイル: product.py プロジェクト: metricsw/swerp
class ProductTemplate(models.Model):
    _inherit = "product.template"

    bom_line_ids = fields.One2many('mrp.bom.line', 'product_tmpl_id',
                                   'BoM Components')
    bom_ids = fields.One2many('mrp.bom', 'product_tmpl_id',
                              'Bill of Materials')
    bom_count = fields.Integer('# Bill of Material',
                               compute='_compute_bom_count')
    used_in_bom_count = fields.Integer('# of BoM Where is Used',
                                       compute='_compute_used_in_bom_count')
    mrp_product_qty = fields.Float('Manufactured',
                                   compute='_compute_mrp_product_qty')
    produce_delay = fields.Float(
        'Manufacturing Lead Time',
        default=0.0,
        help=
        "Average lead time in days to manufacture this product. In the case of multi-level BOM, the manufacturing lead times of the components will be added."
    )

    def _compute_bom_count(self):
        for product in self:
            product.bom_count = self.env['mrp.bom'].search_count([
                ('product_tmpl_id', '=', product.id)
            ])

    @api.multi
    def _compute_used_in_bom_count(self):
        for template in self:
            template.used_in_bom_count = self.env['mrp.bom'].search_count([
                ('bom_line_ids.product_id', 'in',
                 template.product_variant_ids.ids)
            ])

    @api.multi
    def action_used_in_bom(self):
        self.ensure_one()
        action = self.env.ref('mrp.mrp_bom_form_action').read()[0]
        action['domain'] = [('bom_line_ids.product_id', 'in',
                             self.product_variant_ids.ids)]
        return action

    @api.one
    def _compute_mrp_product_qty(self):
        self.mrp_product_qty = float_round(
            sum(self.mapped('product_variant_ids').mapped('mrp_product_qty')),
            precision_rounding=self.uom_id.rounding)

    @api.multi
    def action_view_mos(self):
        action = self.env.ref('mrp.mrp_production_report').read()[0]
        action['domain'] = [('state', '=', 'done'),
                            ('product_tmpl_id', 'in', self.ids)]
        action['context'] = {
            'search_default_last_year_mo_order': 1,
            'search_default_status': 1,
            'search_default_scheduled_month': 1,
            'graph_measure': 'product_uom_qty',
        }
        return action
コード例 #2
0
class HrDepartment(models.Model):
    _inherit = 'hr.department'

    new_applicant_count = fields.Integer(
        compute='_compute_new_applicant_count', string='New Applicant')
    new_hired_employee = fields.Integer(compute='_compute_recruitment_stats',
                                        string='New Hired Employee')
    expected_employee = fields.Integer(compute='_compute_recruitment_stats',
                                       string='Expected Employee')

    @api.multi
    def _compute_new_applicant_count(self):
        applicant_data = self.env['hr.applicant'].read_group(
            [('department_id', 'in', self.ids),
             ('stage_id.sequence', '<=', '1')], ['department_id'],
            ['department_id'])
        result = dict((data['department_id'][0], data['department_id_count'])
                      for data in applicant_data)
        for department in self:
            department.new_applicant_count = result.get(department.id, 0)

    @api.multi
    def _compute_recruitment_stats(self):
        job_data = self.env['hr.job'].read_group(
            [('department_id', 'in', self.ids)],
            ['no_of_hired_employee', 'no_of_recruitment', 'department_id'],
            ['department_id'])
        new_emp = dict((data['department_id'][0], data['no_of_hired_employee'])
                       for data in job_data)
        expected_emp = dict(
            (data['department_id'][0], data['no_of_recruitment'])
            for data in job_data)
        for department in self:
            department.new_hired_employee = new_emp.get(department.id, 0)
            department.expected_employee = expected_emp.get(department.id, 0)
コード例 #3
0
class PreviewModel(models.Model):
    _name = name('preview')
    _description = 'Tests : Base Import Model Preview'

    name = fields.Char('Name')
    somevalue = fields.Integer(string='Some Value', required=True)
    othervalue = fields.Integer(string='Other Variable')
コード例 #4
0
ファイル: hr.py プロジェクト: metricsw/swerp
class Department(models.Model):

    _inherit = 'hr.department'

    absence_of_today = fields.Integer(compute='_compute_leave_count',
                                      string='Absence by Today')
    leave_to_approve_count = fields.Integer(compute='_compute_leave_count',
                                            string='Leave to Approve')
    allocation_to_approve_count = fields.Integer(
        compute='_compute_leave_count', string='Allocation to Approve')
    total_employee = fields.Integer(compute='_compute_total_employee',
                                    string='Total Employee')

    @api.multi
    def _compute_leave_count(self):
        Requests = self.env['hr.leave']
        Allocations = self.env['hr.leave.allocation']
        today_date = datetime.datetime.utcnow().date()
        today_start = fields.Datetime.to_string(
            today_date)  # get the midnight of the current utc day
        today_end = fields.Datetime.to_string(
            today_date + relativedelta(hours=23, minutes=59, seconds=59))

        leave_data = Requests.read_group([('department_id', 'in', self.ids),
                                          ('state', '=', 'confirm')],
                                         ['department_id'], ['department_id'])
        allocation_data = Allocations.read_group(
            [('department_id', 'in', self.ids),
             ('state', '=', 'confirm')], ['department_id'], ['department_id'])
        absence_data = Requests.read_group(
            [('department_id', 'in', self.ids),
             ('state', 'not in', ['cancel', 'refuse']),
             ('date_from', '<=', today_end), ('date_to', '>=', today_start)],
            ['department_id'], ['department_id'])

        res_leave = dict(
            (data['department_id'][0], data['department_id_count'])
            for data in leave_data)
        res_allocation = dict(
            (data['department_id'][0], data['department_id_count'])
            for data in allocation_data)
        res_absence = dict(
            (data['department_id'][0], data['department_id_count'])
            for data in absence_data)

        for department in self:
            department.leave_to_approve_count = res_leave.get(department.id, 0)
            department.allocation_to_approve_count = res_allocation.get(
                department.id, 0)
            department.absence_of_today = res_absence.get(department.id, 0)

    @api.multi
    def _compute_total_employee(self):
        emp_data = self.env['hr.employee'].read_group(
            [('department_id', 'in', self.ids)], ['department_id'],
            ['department_id'])
        result = dict((data['department_id'][0], data['department_id_count'])
                      for data in emp_data)
        for department in self:
            department.total_employee = result.get(department.id, 0)
コード例 #5
0
class BaseModuleUpdate(models.TransientModel):
    _name = "base.module.update"
    _description = "Update Module"

    updated = fields.Integer('Number of modules updated', readonly=True)
    added = fields.Integer('Number of modules added', readonly=True)
    state = fields.Selection([('init', 'init'), ('done', 'done')],
                             'Status',
                             readonly=True,
                             default='init')

    @api.multi
    def update_module(self):
        for this in self:
            updated, added = self.env['ir.module.module'].update_list()
            this.write({'updated': updated, 'added': added, 'state': 'done'})
        return False

    @api.multi
    def action_module_open(self):
        res = {
            'domain': str([]),
            'name': 'Modules',
            'view_type': 'form',
            'view_mode': 'tree,form',
            'res_model': 'ir.module.module',
            'view_id': False,
            'type': 'ir.actions.act_window',
        }
        return res
コード例 #6
0
class product_price_list(models.TransientModel):
    _name = 'product.price_list'
    _description = 'Product Price per Unit Based on Pricelist Version'

    price_list = fields.Many2one('product.pricelist', 'PriceList', required=True)
    qty1 = fields.Integer('Quantity-1', default=1)
    qty2 = fields.Integer('Quantity-2', default=5)
    qty3 = fields.Integer('Quantity-3', default=10)
    qty4 = fields.Integer('Quantity-4', default=0)
    qty5 = fields.Integer('Quantity-5', default=0)

    @api.multi
    def print_report(self):
        """
        To get the date and print the report
        @return : return report
        """
        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_id):
            raise UserError(_("You have to set your reports's header and footer layout."))

        datas = {'ids': self.env.context.get('active_ids', [])}
        res = self.read(['price_list', 'qty1', 'qty2', 'qty3', 'qty4', 'qty5'])
        res = res and res[0] or {}
        res['price_list'] = res['price_list'][0]
        datas['form'] = res
        return self.env.ref('product.action_report_pricelist').report_action([], data=datas)
コード例 #7
0
class res_partner(models.Model):
    _name = 'res.partner'
    _inherit = 'res.partner'

    @api.multi
    def _compute_purchase_order_count(self):
        # retrieve all children partners and prefetch 'parent_id' on them
        all_partners = self.search([('id', 'child_of', self.ids)])
        all_partners.read(['parent_id'])

        purchase_order_groups = self.env['purchase.order'].read_group(
            domain=[('partner_id', 'in', all_partners.ids)],
            fields=['partner_id'],
            groupby=['partner_id'])
        for group in purchase_order_groups:
            partner = self.browse(group['partner_id'][0])
            while partner:
                if partner in self:
                    partner.purchase_order_count += group['partner_id_count']
                partner = partner.parent_id

    @api.multi
    def _compute_supplier_invoice_count(self):
        # retrieve all children partners and prefetch 'parent_id' on them
        all_partners = self.search([('id', 'child_of', self.ids)])
        all_partners.read(['parent_id'])

        supplier_invoice_groups = self.env['account.invoice'].read_group(
            domain=[('partner_id', 'in', all_partners.ids),
                    ('type', 'in', ['in_invoice', 'in_refund'])],
            fields=['partner_id'],
            groupby=['partner_id'])
        for group in supplier_invoice_groups:
            partner = self.browse(group['partner_id'][0])
            while partner:
                if partner in self:
                    partner.supplier_invoice_count += group['partner_id_count']
                partner = partner.parent_id

    @api.model
    def _commercial_fields(self):
        return super(res_partner, self)._commercial_fields()

    property_purchase_currency_id = fields.Many2one(
        'res.currency',
        string="Supplier Currency",
        company_dependent=True,
        help=
        "This currency will be used, instead of the default one, for purchases from the current partner"
    )
    purchase_order_count = fields.Integer(
        compute='_compute_purchase_order_count', string='Purchase Order Count')
    supplier_invoice_count = fields.Integer(
        compute='_compute_supplier_invoice_count', string='# Vendor Bills')
    purchase_warn = fields.Selection(WARNING_MESSAGE,
                                     'Purchase Order',
                                     help=WARNING_HELP,
                                     default="no-message")
    purchase_warn_msg = fields.Text('Message for Purchase Order')
コード例 #8
0
ファイル: mass_mailing.py プロジェクト: metricsw/swerp
class MassMailing(models.Model):
    _name = 'mail.mass_mailing'
    _inherit = 'mail.mass_mailing'

    sale_quotation_count = fields.Integer('Quotation Count', compute='_compute_sale_quotation_count')
    sale_invoiced_amount = fields.Integer('Invoiced Amount', compute='_compute_sale_invoiced_amount')

    @api.depends('mailing_domain')
    def _compute_sale_quotation_count(self):
        has_so_access = self.env['sale.order'].check_access_rights('read', raise_exception=False)
        for mass_mailing in self:
            mass_mailing.sale_quotation_count = self.env['sale.order'].search_count(self._get_sale_utm_domain()) if has_so_access else 0

    @api.depends('mailing_domain')
    def _compute_sale_invoiced_amount(self):
        has_so_access = self.env['sale.order'].check_access_rights('read', raise_exception=False)
        has_invoice_report_access = self.env['account.invoice.report'].check_access_rights('read', raise_exception=False)
        for mass_mailing in self:
            if has_so_access and has_invoice_report_access:
                invoices = self.env['sale.order'].search(self._get_sale_utm_domain()).mapped('invoice_ids')
                res = self.env['account.invoice.report'].search_read([('invoice_id', 'in', invoices.ids)], ['user_currency_price_total'])
                mass_mailing.sale_invoiced_amount = sum(r['user_currency_price_total'] for r in res)
            else:
                mass_mailing.sale_invoiced_amount = 0

    @api.multi
    def action_redirect_to_quotations(self):
        action = self.env.ref('sale.action_quotations_with_onboarding').read()[0]
        action['domain'] = self._get_sale_utm_domain()
        action['context'] = {'default_type': 'lead'}
        return action

    @api.multi
    def action_redirect_to_invoiced(self):
        action = self.env.ref('account.action_invoice_refund_out_tree').read()[0]
        invoices = self.env['sale.order'].search(self._get_sale_utm_domain()).mapped('invoice_ids')
        action['domain'] = [
            ('id', 'in', invoices.ids),
            ('type', 'in', ['out_invoice', 'out_refund']),
            ('state', 'not in', ['draft', 'cancel'])
        ]
        return action

    def _get_sale_utm_domain(self):
        res = []
        if self.campaign_id:
            res.append(('campaign_id', '=', self.campaign_id.id))
        if self.source_id:
            res.append(('source_id', '=', self.source_id.id))
        if self.medium_id:
            res.append(('medium_id', '=', self.medium_id.id))
        if not res:
            res.append((0, '=', 1))
        return res
コード例 #9
0
ファイル: mass_mailing.py プロジェクト: metricsw/swerp
class MassMailing(models.Model):
    _name = 'mail.mass_mailing'
    _inherit = 'mail.mass_mailing'

    crm_lead_activated = fields.Boolean('Use Leads', compute='_compute_crm_lead_activated')
    crm_lead_count = fields.Integer('Lead Count', compute='_compute_crm_lead_count')
    crm_opportunities_count = fields.Integer('Opportunities Count', compute='_compute_crm_opportunities_count')

    def _compute_crm_lead_activated(self):
        for mass_mailing in self:
            mass_mailing.crm_lead_activated = self.env.user.has_group('crm.group_use_lead')

    @api.depends('crm_lead_activated')
    def _compute_crm_lead_count(self):
        for mass_mailing in self:
            if mass_mailing.crm_lead_activated:
                mass_mailing.crm_lead_count = self.env['crm.lead'].search_count(self._get_crm_utm_domain())
            else:
                mass_mailing.crm_lead_count = 0

    @api.depends('crm_lead_activated')
    def _compute_crm_opportunities_count(self):
        for mass_mailing in self:
            if mass_mailing.crm_lead_activated:
                mass_mailing.crm_opportunities_count = 0
            else:
                mass_mailing.crm_opportunities_count = self.env['crm.lead'].search_count(self._get_crm_utm_domain())

    @api.multi
    def action_redirect_to_leads(self):
        action = self.env.ref('crm.crm_lead_all_leads').read()[0]
        action['domain'] = self._get_crm_utm_domain()
        action['context'] = {'default_type': 'lead'}
        return action

    @api.multi
    def action_redirect_to_opportunities(self):
        action = self.env.ref('crm.crm_lead_opportunities').read()[0]
        action['view_mode'] = 'tree,kanban,graph,pivot,form,calendar'
        action['domain'] = self._get_crm_utm_domain()
        return action

    def _get_crm_utm_domain(self):
        res = []
        if self.campaign_id:
            res.append(('campaign_id', '=', self.campaign_id.id))
        if self.source_id:
            res.append(('source_id', '=', self.source_id.id))
        if self.medium_id:
            res.append(('medium_id', '=', self.medium_id.id))
        if not res:
            res.append((0, '=', 1))
        return res
コード例 #10
0
ファイル: im_livechat_channel.py プロジェクト: metricsw/swerp
class ImLivechatChannelRule(models.Model):
    """ Channel Rules
        Rules defining access to the channel (countries, and url matching). It also provide the 'auto pop'
        option to open automatically the conversation.
    """

    _name = 'im_livechat.channel.rule'
    _description = 'Livechat Channel Rules'
    _order = 'sequence asc'


    regex_url = fields.Char('URL Regex',
        help="Regular expression specifying the web pages this rule will be applied on.")
    action = fields.Selection([('display_button', 'Display the button'), ('auto_popup', 'Auto popup'), ('hide_button', 'Hide the button')],
        string='Action', required=True, default='display_button',
        help="* 'Display the button' displays the chat button on the pages.\n"\
             "* 'Auto popup' displays the button and automatically open the conversation pane.\n"\
             "* 'Hide the button' hides the chat button on the pages.")
    auto_popup_timer = fields.Integer('Auto popup timer', default=0,
        help="Delay (in seconds) to automatically open the conversation window. Note: the selected action must be 'Auto popup' otherwise this parameter will not be taken into account.")
    channel_id = fields.Many2one('im_livechat.channel', 'Channel',
        help="The channel of the rule")
    country_ids = fields.Many2many('res.country', 'im_livechat_channel_country_rel', 'channel_id', 'country_id', 'Country',
        help="The rule will only be applied for these countries. Example: if you select 'Belgium' and 'United States' and that you set the action to 'Hide Button', the chat button will be hidden on the specified URL from the visitors located in these 2 countries. This feature requires GeoIP installed on your server.")
    sequence = fields.Integer('Matching order', default=10,
        help="Given the order to find a matching rule. If 2 rules are matching for the given url/country, the one with the lowest sequence will be chosen.")

    def match_rule(self, channel_id, url, country_id=False):
        """ determine if a rule of the given channel matches with the given url
            :param channel_id : the identifier of the channel_id
            :param url : the url to match with a rule
            :param country_id : the identifier of the country
            :returns the rule that matches the given condition. False otherwise.
            :rtype : im_livechat.channel.rule
        """
        def _match(rules):
            for rule in rules:
                # url might not be set because it comes from referer, in that
                # case match the first rule with no regex_url
                if re.search(rule.regex_url or '', url or ''):
                    return rule
            return False
        # first, search the country specific rules (the first match is returned)
        if country_id: # don't include the country in the research if geoIP is not installed
            domain = [('country_ids', 'in', [country_id]), ('channel_id', '=', channel_id)]
            rule = _match(self.search(domain))
            if rule:
                return rule
        # second, fallback on the rules without country
        domain = [('country_ids', '=', False), ('channel_id', '=', channel_id)]
        return _match(self.search(domain))
コード例 #11
0
class ProductAttributeCategory(models.Model):
    _name = "product.attribute.category"
    _description = "Product Attribute Category"
    _order = 'sequence'

    name = fields.Char("Category Name", required=True, translate=True)
    sequence = fields.Integer("Sequence", default=10)
コード例 #12
0
ファイル: pos_restaurant.py プロジェクト: metricsw/swerp
class RestaurantFloor(models.Model):

    _name = 'restaurant.floor'
    _description = 'Restaurant Floor'

    name = fields.Char(
        'Floor Name',
        required=True,
        help='An internal identification of the restaurant floor')
    pos_config_id = fields.Many2one('pos.config', string='Point of Sale')
    background_image = fields.Binary(
        'Background Image',
        attachment=True,
        help=
        'A background image used to display a floor layout in the point of sale interface'
    )
    background_color = fields.Char(
        'Background Color',
        help=
        'The background color of the floor layout, (must be specified in a html-compatible format)',
        default='rgb(210, 210, 210)')
    table_ids = fields.One2many('restaurant.table',
                                'floor_id',
                                string='Tables',
                                help='The list of tables in this floor')
    sequence = fields.Integer('Sequence',
                              help='Used to sort Floors',
                              default=1)
コード例 #13
0
ファイル: test_models.py プロジェクト: metricsw/swerp
class ConverterTest(models.Model):
    _name = 'web_editor.converter.test'
    _description = 'Web Editor Converter Test'

    # disable translation export for those brilliant field labels and values
    _translate = False

    char = fields.Char()
    integer = fields.Integer()
    float = fields.Float()
    numeric = fields.Float(digits=(16, 2))
    many2one = fields.Many2one('web_editor.converter.test.sub')
    binary = fields.Binary()
    date = fields.Date()
    datetime = fields.Datetime()
    selection = fields.Selection([
        (1, "réponse A"),
        (2, "réponse B"),
        (3, "réponse C"),
        (4, "réponse <D>"),
    ])
    selection_str = fields.Selection([
        ('A', "Qu'il n'est pas arrivé à Toronto"),
        ('B', "Qu'il était supposé arriver à Toronto"),
        ('C', "Qu'est-ce qu'il fout ce maudit pancake, tabernacle ?"),
        ('D', "La réponse D"),
    ], string=u"Lorsqu'un pancake prend l'avion à destination de Toronto et "
              u"qu'il fait une escale technique à St Claude, on dit:")
    html = fields.Html()
    text = fields.Text()
コード例 #14
0
ファイル: account_payment.py プロジェクト: metricsw/swerp
class AccountRegisterPayments(models.TransientModel):
    _inherit = "account.register.payments"

    check_amount_in_words = fields.Char(string="Amount in Words")
    check_manual_sequencing = fields.Boolean(related='journal_id.check_manual_sequencing', readonly=1)
    # Note: a check_number == 0 means that it will be attributed when the check is printed
    check_number = fields.Integer(string="Check Number", readonly=True, copy=False, default=0,
        help="Number of the check corresponding to this payment. If your pre-printed check are not already numbered, "
             "you can manage the numbering in the journal configuration page.")

    @api.onchange('journal_id')
    def _onchange_journal_id(self):
        if hasattr(super(AccountRegisterPayments, self), '_onchange_journal_id'):
            super(AccountRegisterPayments, self)._onchange_journal_id()
        if self.journal_id.check_manual_sequencing:
            self.check_number = self.journal_id.check_sequence_id.number_next_actual

    @api.onchange('amount')
    def _onchange_amount(self):
        if hasattr(super(AccountRegisterPayments, self), '_onchange_amount'):
            super(AccountRegisterPayments, self)._onchange_amount()
        self.check_amount_in_words = self.currency_id.amount_to_text(self.amount) if self.currency_id else False

    def _prepare_payment_vals(self, invoices):
        res = super(AccountRegisterPayments, self)._prepare_payment_vals(invoices)
        if self.payment_method_id == self.env.ref('account_check_printing.account_payment_method_check'):
            res.update({
                'check_amount_in_words': self.currency_id.amount_to_text(res['amount']) if self.multi else self.check_amount_in_words,
            })
        return res
コード例 #15
0
class IrActionsActWindowView(models.Model):
    _name = 'ir.actions.act_window.view'
    _description = 'Action Window View'
    _table = 'ir_act_window_view'
    _rec_name = 'view_id'
    _order = 'sequence,id'

    sequence = fields.Integer()
    view_id = fields.Many2one('ir.ui.view', string='View')
    view_mode = fields.Selection(VIEW_TYPES, string='View Type', required=True)
    act_window_id = fields.Many2one('ir.actions.act_window',
                                    string='Action',
                                    ondelete='cascade')
    multi = fields.Boolean(
        string='On Multiple Doc.',
        help=
        "If set to true, the action will not be displayed on the right toolbar of a form view."
    )

    @api.model_cr_context
    def _auto_init(self):
        res = super(IrActionsActWindowView, self)._auto_init()
        tools.create_unique_index(self._cr,
                                  'act_window_view_unique_mode_per_action',
                                  self._table, ['act_window_id', 'view_mode'])
        return res
コード例 #16
0
ファイル: res_partner.py プロジェクト: metricsw/swerp
class ResPartner(models.Model):
    _inherit = 'res.partner'

    pos_order_count = fields.Integer(
        compute='_compute_pos_order',
        help="The number of point of sales orders related to this customer",
        groups="point_of_sale.group_pos_user",
    )

    def _compute_pos_order(self):
        partners_data = self.env['pos.order'].read_group([('partner_id', 'in', self.ids)], ['partner_id'], ['partner_id'])
        mapped_data = dict([(partner['partner_id'][0], partner['partner_id_count']) for partner in partners_data])
        for partner in self:
            partner.pos_order_count = mapped_data.get(partner.id, 0)

    @api.model
    def create_from_ui(self, partner):
        """ create or modify a partner from the point of sale ui.
            partner contains the partner's fields. """
        # image is a dataurl, get the data after the comma
        if partner.get('image'):
            partner['image'] = partner['image'].split(',')[1]
        partner_id = partner.pop('id', False)
        if partner_id:  # Modifying existing partner
            self.browse(partner_id).write(partner)
        else:
            partner['lang'] = self.env.user.lang
            partner_id = self.create(partner).id
        return partner_id
コード例 #17
0
class ResConfigSettings(models.TransientModel):
    _inherit = 'res.config.settings'

    minlength = fields.Integer(
        "Minimum Password Length",
        help=
        "Minimum number of characters passwords must contain, set to 0 to disable."
    )

    @api.model
    def get_values(self):
        res = super(ResConfigSettings, self).get_values()

        res['minlength'] = int(
            self.env['ir.config_parameter'].sudo().get_param(
                'auth_password_policy.minlength', default=0))

        return res

    @api.model
    def set_values(self):
        self.env['ir.config_parameter'].sudo().set_param(
            'auth_password_policy.minlength', self.minlength)

        super(ResConfigSettings, self).set_values()

    @api.onchange('minlength')
    def _on_change_mins(self):
        """ Password lower bounds must be naturals
        """
        self.minlength = max(0, self.minlength or 0)
コード例 #18
0
class ThemeMenu(models.Model):
    _name = 'theme.website.menu'
    _description = 'Website Theme Menu'

    name = fields.Char(required=True, translate=True)
    url = fields.Char(default='')
    page_id = fields.Many2one('theme.website.page', ondelete='cascade')
    new_window = fields.Boolean('New Window')
    sequence = fields.Integer()
    parent_id = fields.Many2one('theme.website.menu',
                                index=True,
                                ondelete="cascade")
    copy_ids = fields.One2many('website.menu',
                               'theme_template_id',
                               'Menu using a copy of me',
                               copy=False,
                               readonly=True)

    @api.multi
    def _convert_to_base_model(self, website, **kwargs):
        self.ensure_one()
        page_id = self.page_id.copy_ids.filtered(
            lambda x: x.website_id == website)
        parent_id = self.copy_ids.filtered(lambda x: x.website_id == website)
        new_menu = {
            'name': self.name,
            'url': self.url,
            'page_id': page_id and page_id.id or False,
            'new_window': self.new_window,
            'sequence': self.sequence,
            'parent_id': parent_id and parent_id.id or False,
            'theme_template_id': self.id,
        }
        return new_menu
コード例 #19
0
class EventTypeMail(models.Model):
    """ Template of event.mail to attach to event.type. Those will be copied
    upon all events created in that type to ease event creation. """
    _name = 'event.type.mail'
    _description = 'Mail Scheduling on Event Category'

    event_type_id = fields.Many2one('event.type',
                                    string='Event Type',
                                    ondelete='cascade',
                                    required=True)
    interval_nbr = fields.Integer('Interval', default=1)
    interval_unit = fields.Selection([('now', 'Immediately'),
                                      ('hours', 'Hour(s)'), ('days', 'Day(s)'),
                                      ('weeks', 'Week(s)'),
                                      ('months', 'Month(s)')],
                                     string='Unit',
                                     default='hours',
                                     required=True)
    interval_type = fields.Selection([('after_sub', 'After each registration'),
                                      ('before_event', 'Before the event'),
                                      ('after_event', 'After the event')],
                                     string='Trigger',
                                     default="before_event",
                                     required=True)
    template_id = fields.Many2one(
        'mail.template',
        string='Email Template',
        domain=[('model', '=', 'event.registration')],
        required=True,
        ondelete='restrict',
        help=
        'This field contains the template of the mail that will be automatically sent'
    )
コード例 #20
0
ファイル: stock.py プロジェクト: metricsw/swerp
class ProductionLot(models.Model):
    _inherit = 'stock.production.lot'

    sale_order_ids = fields.Many2many('sale.order',
                                      string="Sales Orders",
                                      compute='_compute_sale_order_ids')
    sale_order_count = fields.Integer('Sale order count',
                                      compute='_compute_sale_order_ids')

    @api.depends('name')
    def _compute_sale_order_ids(self):
        for lot in self:
            stock_moves = self.env['stock.move.line'].search([
                ('lot_id', '=', lot.id), ('state', '=', 'done')
            ]).mapped('move_id')
            stock_moves = stock_moves.search([
                ('id', 'in', stock_moves.ids)
            ]).filtered(lambda move: move.picking_id.location_dest_id.usage ==
                        'customer' and move.state == 'done')
            lot.sale_order_ids = stock_moves.mapped('sale_line_id.order_id')
            lot.sale_order_count = len(lot.sale_order_ids)

    def action_view_so(self):
        self.ensure_one()
        action = self.env.ref('sale.action_orders').read()[0]
        action['domain'] = [('id', 'in', self.mapped('sale_order_ids.id'))]
        return action
コード例 #21
0
ファイル: slides.py プロジェクト: metricsw/swerp
class EmbeddedSlide(models.Model):
    """ Embedding in third party websites. Track view count, generate statistics. """
    _name = 'slide.embed'
    _description = 'Embedded Slides View Counter'
    _rec_name = 'slide_id'

    slide_id = fields.Many2one('slide.slide',
                               string="Presentation",
                               required=True,
                               index=True)
    url = fields.Char('Third Party Website URL', required=True)
    count_views = fields.Integer('# Views', default=1)

    def add_embed_url(self, slide_id, url):
        baseurl = urls.url_parse(url).netloc
        embeds = self.search([('url', '=', baseurl),
                              ('slide_id', '=', int(slide_id))],
                             limit=1)
        if embeds:
            embeds.count_views += 1
        else:
            embeds = self.create({
                'slide_id': slide_id,
                'url': baseurl,
            })
        return embeds.count_views
コード例 #22
0
ファイル: digest.py プロジェクト: metricsw/swerp
class Digest(models.Model):
    _inherit = 'digest.digest'

    kpi_project_task_opened = fields.Boolean('Open Tasks')
    kpi_project_task_opened_value = fields.Integer(
        compute='_compute_project_task_opened_value')

    def _compute_project_task_opened_value(self):
        if not self.env.user.has_group('project.group_project_user'):
            raise AccessError(
                _("Do not have access, skip this data for user's digest email")
            )
        for record in self:
            start, end, company = record._get_kpi_compute_parameters()
            record.kpi_project_task_opened_value = self.env[
                'project.task'].search_count([('stage_id.fold', '=', False),
                                              ('create_date', '>=', start),
                                              ('create_date', '<', end),
                                              ('company_id', '=', company.id)])

    def compute_kpis_actions(self, company, user):
        res = super(Digest, self).compute_kpis_actions(company, user)
        res['kpi_project_task_opened'] = 'project.open_view_project_all&menu_id=%s' % self.env.ref(
            'project.menu_main_pm').id
        return res
コード例 #23
0
ファイル: event_track.py プロジェクト: metricsw/swerp
class SponsorType(models.Model):
    _name = "event.sponsor.type"
    _description = 'Event Sponsor Type'
    _order = "sequence"

    name = fields.Char('Sponsor Type', required=True, translate=True)
    sequence = fields.Integer('Sequence')
コード例 #24
0
ファイル: event.py プロジェクト: metricsw/swerp
class EventQuestion(models.Model):
    _name = 'event.question'
    _rec_name = 'title'
    _order = 'sequence,id'
    _description = 'Event Question'

    title = fields.Char(required=True, translate=True)
    event_type_id = fields.Many2one('event.type', 'Event Type', ondelete='cascade')
    event_id = fields.Many2one('event.event', 'Event', ondelete='cascade')
    answer_ids = fields.One2many('event.answer', 'question_id', "Answers", required=True, copy=True)
    sequence = fields.Integer(default=10)
    is_individual = fields.Boolean('Ask each attendee',
                                   help="If True, this question will be asked for every attendee of a reservation. If "
                                        "not it will be asked only once and its value propagated to every attendees.")

    @api.constrains('event_type_id', 'event_id')
    def _constrains_event(self):
        if any(question.event_type_id and question.event_id for question in self):
            raise UserError(_('Question cannot belong to both the event category and itself.'))

    @api.model
    def create(self, vals):
        event_id = vals.get('event_id', False)
        if event_id:
            event = self.env['event.event'].browse([event_id])
            if event.event_type_id.use_questions and event.event_type_id.question_ids and not vals.get('answer_ids'):
                vals['answer_ids'] = [(0, 0, {
                    'name': answer.name,
                    'sequence': answer.sequence,
                }) for answer in event.event_type_id.question_ids.filtered(lambda question: question.title == vals.get('title')).mapped('answer_ids')]
        return super(EventQuestion, self).create(vals)
コード例 #25
0
class ProductionLot(models.Model):
    _inherit = 'stock.production.lot'

    purchase_order_ids = fields.Many2many(
        'purchase.order',
        string="Purchase Orders",
        compute='_compute_purchase_order_ids',
        readonly=True,
        store=False)
    purchase_order_count = fields.Integer(
        'Purchase order count', compute='_compute_purchase_order_ids')

    @api.depends('name')
    def _compute_purchase_order_ids(self):
        for lot in self:
            stock_moves = self.env['stock.move.line'].search([
                ('lot_id', '=', lot.id), ('state', '=', 'done')
            ]).mapped('move_id')
            stock_moves = stock_moves.search([
                ('id', 'in', stock_moves.ids)
            ]).filtered(lambda move: move.picking_id.location_id.usage ==
                        'supplier' and move.state == 'done')
            lot.purchase_order_ids = stock_moves.mapped(
                'purchase_line_id.order_id')
            lot.purchase_order_count = len(lot.purchase_order_ids)

    def action_view_po(self):
        self.ensure_one()
        action = self.env.ref('purchase.purchase_form_action').read()[0]
        action['domain'] = [('id', 'in', self.mapped('purchase_order_ids.id'))]
        return action
コード例 #26
0
ファイル: res_config_settings.py プロジェクト: metricsw/swerp
class ResConfigSettings(models.TransientModel):
    """ Inherit the base settings to add a counter of failed email + configure
    the alias domain. """
    _inherit = 'res.config.settings'

    fail_counter = fields.Integer('Fail Mail', readonly=True)
    alias_domain = fields.Char('Alias Domain', help="If you have setup a catch-all email domain redirected to "
                               "the Swerp server, enter the domain name here.", config_parameter='mail.catchall.domain')

    @api.model
    def get_values(self):
        res = super(ResConfigSettings, self).get_values()

        previous_date = datetime.datetime.now() - datetime.timedelta(days=30)

        res.update(
            fail_counter=self.env['mail.mail'].sudo().search_count([
                ('date', '>=', previous_date.strftime(tools.DEFAULT_SERVER_DATETIME_FORMAT)),
                ('state', '=', 'exception')]),
        )

        return res

    def set_values(self):
        super(ResConfigSettings, self).set_values()
        self.env['ir.config_parameter'].set_param("mail.catchall.domain", self.alias_domain or '')
コード例 #27
0
ファイル: hr_recruitment.py プロジェクト: metricsw/swerp
class RecruitmentStage(models.Model):
    _name = "hr.recruitment.stage"
    _description = "Recruitment Stages"
    _order = 'sequence'

    name = fields.Char("Stage name", required=True, translate=True)
    sequence = fields.Integer(
        "Sequence", default=10,
        help="Gives the sequence order when displaying a list of stages.")
    job_id = fields.Many2one('hr.job', string='Job Specific',
                             ondelete='cascade',
                             help='Specific job that uses this stage. Other jobs will not use this stage.')
    requirements = fields.Text("Requirements")
    template_id = fields.Many2one(
        'mail.template', "Automated Email",
        help="If set, a message is posted on the applicant using the template when the applicant is set to the stage.")
    fold = fields.Boolean(
        "Folded in Recruitment Pipe",
        help="This stage is folded in the kanban view when there are no records in that stage to display.")
    legend_blocked = fields.Char(
        'Red Kanban Label', default=lambda self: _('Blocked'), translate=True, required=True)
    legend_done = fields.Char(
        'Green Kanban Label', default=lambda self: _('Ready for Next Stage'), translate=True, required=True)
    legend_normal = fields.Char(
        'Grey Kanban Label', default=lambda self: _('In Progress'), translate=True, required=True)

    @api.model
    def default_get(self, fields):
        if self._context and self._context.get('default_job_id') and not self._context.get('hr_recruitment_stage_mono', False):
            context = dict(self._context)
            context.pop('default_job_id')
            self = self.with_context(context)
        return super(RecruitmentStage, self).default_get(fields)
コード例 #28
0
class PurchaseRequisitionType(models.Model):
    _name = "purchase.requisition.type"
    _description = "Purchase Requisition Type"
    _order = "sequence"

    name = fields.Char(string='Agreement Type', required=True, translate=True)
    sequence = fields.Integer(default=1)
    exclusive = fields.Selection(
        [('exclusive', 'Select only one RFQ (exclusive)'),
         ('multiple', 'Select multiple RFQ')],
        string='Agreement Selection Type',
        required=True,
        default='multiple',
        help=
        """Select only one RFQ (exclusive):  when a purchase order is confirmed, cancel the remaining purchase order.\n
                    Select multiple RFQ: allows multiple purchase orders. On confirmation of a purchase order it does not cancel the remaining orders"""
    )
    quantity_copy = fields.Selection([('copy', 'Use quantities of agreement'),
                                      ('none', 'Set quantities manually')],
                                     string='Quantities',
                                     required=True,
                                     default='none')
    line_copy = fields.Selection(
        [('copy', 'Use lines of agreement'),
         ('none', 'Do not create RfQ lines automatically')],
        string='Lines',
        required=True,
        default='copy')
コード例 #29
0
ファイル: report_paperformat.py プロジェクト: metricsw/swerp
class report_paperformat(models.Model):
    _name = "report.paperformat"
    _description = "Paper Format Config"

    name = fields.Char('Name', required=True)
    default = fields.Boolean('Default paper format ?')
    format = fields.Selection([(ps['key'], ps['description']) for ps in PAPER_SIZES], 'Paper size', default='A4', help="Select Proper Paper size")
    margin_top = fields.Float('Top Margin (mm)', default=40)
    margin_bottom = fields.Float('Bottom Margin (mm)', default=20)
    margin_left = fields.Float('Left Margin (mm)', default=7)
    margin_right = fields.Float('Right Margin (mm)', default=7)
    page_height = fields.Integer('Page height (mm)', default=False)
    page_width = fields.Integer('Page width (mm)', default=False)
    orientation = fields.Selection([
        ('Landscape', 'Landscape'),
        ('Portrait', 'Portrait')
        ], 'Orientation', default='Landscape')
    header_line = fields.Boolean('Display a header line', default=False)
    header_spacing = fields.Integer('Header spacing', default=35)
    dpi = fields.Integer('Output DPI', required=True, default=90)
    report_ids = fields.One2many('ir.actions.report', 'paperformat_id', 'Associated reports', help="Explicitly associated reports")
    print_page_width = fields.Float('Print page width (mm)', compute='_compute_print_page_size')
    print_page_height = fields.Float('Print page height (mm)', compute='_compute_print_page_size')

    @api.constrains('format')
    def _check_format_or_page(self):
        if self.filtered(lambda x: x.format != 'custom' and (x.page_width or x.page_height)):
            raise ValidationError(_('You can select either a format or a specific page width/height, but not both.'))

    def _compute_print_page_size(self):
        for record in self:
            width = height = 0.0
            if record.format:
                if record.format == 'custom':
                    width = record.page_width
                    height = record.page_height
                else:
                    paper_size = next(ps for ps in PAPER_SIZES if ps['key'] == record.format)
                    width = paper_size['width']
                    height = paper_size['height']

            if record.orientation == 'Landscape':
                # swap sizes
                width, height = height, width

            record.print_page_width = width
            record.print_page_height = height
コード例 #30
0
class IrLogging(models.Model):
    _name = 'ir.logging'
    _description = 'Logging'
    _order = 'id DESC'

    # The _log_access fields are defined manually for the following reasons:
    #
    # - The entries in ir_logging are filled in with sql queries bypassing the orm. As the --log-db
    #   cli option allows to insert ir_logging entries into a remote database, the one2many *_uid
    #   fields make no sense in the first place but we will keep it for backward compatibility.
    #
    # - Also, when an ir_logging entry is triggered by the orm (when using --log-db) at the moment
    #   it is making changes to the res.users model, the ALTER TABLE will aquire an exclusive lock
    #   on res_users, preventing the ir_logging INSERT to be processed, hence the ongoing module
    #   install/update will hang forever as the orm is blocked by the ir_logging query that will
    #   never occur.
    create_uid = fields.Integer(string='Created by', readonly=True)
    create_date = fields.Datetime(string='Created on', readonly=True)
    write_uid = fields.Integer(string='Last Updated by', readonly=True)
    write_date = fields.Datetime(string='Last Updated on', readonly=True)

    name = fields.Char(required=True)
    type = fields.Selection([('client', 'Client'), ('server', 'Server')],
                            required=True,
                            index=True)
    dbname = fields.Char(string='Database Name', index=True)
    level = fields.Char(index=True)
    message = fields.Text(required=True)
    path = fields.Char(required=True)
    func = fields.Char(string='Function', required=True)
    line = fields.Char(required=True)

    @api.model_cr
    def init(self):
        super(IrLogging, self).init()
        self._cr.execute(
            "select 1 from information_schema.constraint_column_usage where table_name = 'ir_logging' and constraint_name = 'ir_logging_write_uid_fkey'"
        )
        if self._cr.rowcount:
            # DROP CONSTRAINT unconditionally takes an ACCESS EXCLUSIVE lock
            # on the table, even "IF EXISTS" is set and not matching; disabling
            # the relevant trigger instead acquires SHARE ROW EXCLUSIVE, which
            # still conflicts with the ROW EXCLUSIVE needed for an insert
            self._cr.execute(
                "ALTER TABLE ir_logging DROP CONSTRAINT ir_logging_write_uid_fkey"
            )