コード例 #1
0
ファイル: lunch.py プロジェクト: Lennon-Liang/odoo-1
class LunchAlert(models.Model):
    """ Alerts to display during a lunch order. An alert can be specific to a
    given day, weekly or daily. The alert is displayed from start to end hour. """
    _name = 'lunch.alert'
    _description = 'Lunch Alert'

    display = fields.Boolean(compute='_compute_display_get')
    message = fields.Text('Message', required=True)
    alert_type = fields.Selection([('specific', 'Specific Day'),
                                   ('week', 'Every Week'),
                                   ('days', 'Every Day')],
                                  string='Recurrency', required=True, select=True, default='specific')
    specific_day = fields.Date('Day', default=fields.Date.context_today)
    monday = fields.Boolean('Monday')
    tuesday = fields.Boolean('Tuesday')
    wednesday = fields.Boolean('Wednesday')
    thursday = fields.Boolean('Thursday')
    friday = fields.Boolean('Friday')
    saturday = fields.Boolean('Saturday')
    sunday = fields.Boolean('Sunday')
    start_hour = fields.Float('Between', oldname='active_from', required=True, default=7)
    end_hour = fields.Float('And', oldname='active_to', required=True, default=23)
    active = fields.Boolean(default=True)

    @api.multi
    def name_get(self):
        return [(alert.id, '%s %s' % (_('Alert'), '#%d' % alert.id)) for alert in self]

    @api.one
    def _compute_display_get(self):
        """
        This method check if the alert can be displayed today
        if alert type is specific : compare specific_day(date) with today's date
        if alert type is week : check today is set as alert (checkbox true) eg. self['monday']
        if alert type is day : True
        return : Message if can_display_alert is True else False
        """

        days_codes = {'0': 'sunday',
                      '1': 'monday',
                      '2': 'tuesday',
                      '3': 'wednesday',
                      '4': 'thursday',
                      '5': 'friday',
                      '6': 'saturday'}
        can_display_alert = {
            'specific': (self.specific_day == fields.Date.context_today(self)),
            'week': self[days_codes[datetime.datetime.now().strftime('%w')]],
            'days': True
        }

        if can_display_alert[self.alert_type]:
            mynow = fields.Datetime.context_timestamp(self, datetime.datetime.now())
            hour_to = int(self.end_hour)
            min_to = int((self.end_hour - hour_to) * 60)
            to_alert = datetime.time(hour_to, min_to)
            hour_from = int(self.start_hour)
            min_from = int((self.start_hour - hour_from) * 60)
            from_alert = datetime.time(hour_from, min_from)

            if from_alert <= mynow.time() <= to_alert:
                self.display = True
            else:
                self.display = False
コード例 #2
0
ファイル: brew.py プロジェクト: VADR670730/addons-1
class BrewOrder(models.Model):
    _name = "brew.order"

    @api.onchange("product_id")
    def onchange_product(self):
        if self.product_id:
            self.product_uom = self.product_id.uom_id

    @api.onchange("start_date")
    def onchange_start_date(self):
        if self.start_date:
            self.end_date = self.start_date
            self.wort_gathering_date = self.start_date

    @api.onchange("end_date")
    def onchange_end_date(self):
        if self.end_date:
            self.wort_gathering_date = self.end_date

    @api.one
    @api.depends("production_order_id")
    def _get_consumed_lines(self):
        for brew_order in self:
            raw_mat_moves = self.env["stock.move"]
            for child_mo in brew_order.production_order_id.child_mo_ids:
                raw_mat_moves |= child_mo.move_lines2.filtered(
                    lambda record: record.state == "done")

            raw_mat_moves |= brew_order.production_order_id.move_lines2.filtered(
                lambda record: record.state == "done")
            brew_order.consumed_lines = raw_mat_moves

    @api.multi
    @api.depends("product_id", "brew_number", "brew_beer_number", "state",
                 "start_date")
    def compute_display_name(self):
        year = date.today().year
        if self.start_date:
            year = datetime.strptime(self.start_date,
                                     DEFAULT_SERVER_DATETIME_FORMAT).year
        for order in self:
            if order.state in ["done", "cancel"]:
                order.name = u"%s_%s_%s" % (
                    order.product_id.code,
                    year,
                    order.brew_beer_number,
                )
            elif order.state == "draft":
                order.name = u"%s_%s_%s" % (
                    order.product_id.code,
                    year,
                    order.state,
                )

    @api.multi
    def get_bom(self):
        for brew_order in self:
            brew_order.bom = brew_order.production_order_id.bom_id

    name = fields.Char(
        string="Brew order",
        compute="compute_display_name",
        store=True,
        copy=False,
    )
    brew_number = fields.Char(string="Brew number", copy=False)
    brew_beer_number = fields.Integer(string="Brew beer number", copy=False)
    state = fields.Selection(
        [("draft", "Draft"), ("done", "Done"), ("cancel", "Cancelled")],
        string="Status",
        readonly=True,
        default="draft",
    )
    brew_declaration_id = fields.Many2one("brew.declaration",
                                          string="Brew declaration")
    start_date = fields.Datetime(string="Planned date", required=True)
    wort_gathering_date = fields.Datetime(string="Wort gathering date",
                                          required=True)
    end_date = fields.Datetime(string="End date", required=True)
    product_id = fields.Many2one(
        "product.product",
        string="Beer",
        domain=[("is_brewable", "=", True)],
        required=True,
        readonly=True,
        states={"draft": [("readonly", False)]},
    )
    product_qty = fields.Float(
        "Product Quantity",
        digits=dp.get_precision("Product Unit of Measure"),
        required=True,
        readonly=True,
        states={"draft": [("readonly", False)]},
    )
    product_uom = fields.Many2one(
        "product.uom",
        "Product Unit of Measure",
        required=True,
        readonly=True,
        states={"draft": [("readonly", False)]},
    )
    production_order_id = fields.Many2one("mrp.production",
                                          string="Production Order",
                                          readonly=True)
    consumed_lines = fields.One2many("stock.move",
                                     string="Consumed lines",
                                     compute=_get_consumed_lines)
    bom = fields.Many2one("mrp.bom",
                          string="Bill of material",
                          compute="get_bom")
    parent_brew_order_id = fields.Many2one("brew.order",
                                           string="parent brew order")
    child_brew_orders = fields.One2many("brew.order",
                                        "parent_brew_order_id",
                                        string="Child brew order")
    used_vessels_tank = fields.Char(string="Used vessels for work in tank")
    dry_extract = fields.Float(string="% dry extract")
    real_bulk_wort = fields.Float(string="Real bulk of wort")
    hl_plato_brewer = fields.Float(string="Hl plato noted by the brewer")
    hl_plato_agent = fields.Float(string="Hl plato noted by the agents")
    collecting_vessels = fields.Char(string="Collecting vessels")
    green_beer_volume = fields.Float(string="Volume of green Beer")
    sugar_quantity = fields.Float(string="Sugar")
    output_wort = fields.Float(string="Output wort")
    output_beer = fields.Float(string="Output beer")
    notes = fields.Char(string="Notes")

    @api.multi
    def action_confirm(self):
        bom_id = self.env["mrp.bom"]._bom_find(product_id=self.product_id.id,
                                               properties=[])
        if self.parent_brew_order_id:
            if self.parent_brew_order_id.state != "done":
                raise UserError(
                    _("You must first confirm the parent brew order."))
            brew_sequence = parent_brew_order_id.brew_number
        else:
            brew_beer_number = (
                self.product_id.brew_product_sequence.next_by_id())
            brew_year_sequence = self.env["ir.sequence"].search([
                ("code", "=", "brew.year.sequence")
            ])
            brew_year_number = brew_year_sequence.next_by_id()
        self.write({
            "state": "done",
            "brew_number": brew_year_number,
            "brew_beer_number": brew_beer_number,
        })

        # create production order
        vals = {
            "product_id": self.product_id.id,
            "product_qty": self.product_qty,
            "product_uom": self.product_uom.id,
            "date_planned": self.start_date,
            "origin": self.name,
            "bom_id": bom_id,
        }

        prod_order_id = self.env["mrp.production"].create(vals)
        self.write({"production_order_id": prod_order_id.id})

    @api.multi
    def action_cancel(self):
        return self.write({"state": "cancel"})

    @api.multi
    def action_draft(self):
        return self.write({"state": "draft"})
コード例 #3
0
ファイル: event.py プロジェクト: smack815/odoo
class event_event(models.Model):
    """Event"""
    _name = 'event.event'
    _description = 'Event'
    _inherit = ['mail.thread', 'ir.needaction_mixin']
    _order = 'date_begin'

    name = fields.Char(string='Name',
                       translate=True,
                       required=True,
                       readonly=False,
                       states={'done': [('readonly', True)]})
    user_id = fields.Many2one('res.users',
                              string='Responsible',
                              default=lambda self: self.env.user,
                              readonly=False,
                              states={'done': [('readonly', True)]})
    company_id = fields.Many2one('res.company',
                                 string='Company',
                                 change_default=True,
                                 default=lambda self: self.env['res.company'].
                                 _company_default_get('event.event'),
                                 required=False,
                                 readonly=False,
                                 states={'done': [('readonly', True)]})
    organizer_id = fields.Many2one(
        'res.partner',
        string='Organizer',
        default=lambda self: self.env.user.company_id.partner_id)
    type = fields.Many2one('event.type',
                           string='Category',
                           readonly=False,
                           states={'done': [('readonly', True)]})
    color = fields.Integer('Kanban Color Index')
    event_mail_ids = fields.One2many(
        'event.mail',
        'event_id',
        string='Mail Schedule',
        default=lambda self: self._default_event_mail_ids())

    @api.model
    def _default_event_mail_ids(self):
        return [(0, 0, {
            'interval_unit':
            'now',
            'interval_type':
            'after_sub',
            'template_id':
            self.env['ir.model.data'].xmlid_to_res_id(
                'event.event_subscription')
        })]

    # Seats and computation
    seats_max = fields.Integer(
        string='Maximum Available Seats',
        oldname='register_max',
        readonly=True,
        states={'draft': [('readonly', False)]},
        help=
        "You can for each event define a maximum registration level. If you have too much registrations you are not able to confirm your event. (put 0 to ignore this rule )"
    )
    seats_availability = fields.Selection([('limited', 'Limited'),
                                           ('unlimited', 'Unlimited')],
                                          'Available Seat',
                                          required=True,
                                          default='unlimited')
    seats_min = fields.Integer(
        string='Minimum Reserved Seats',
        oldname='register_min',
        readonly=True,
        states={'draft': [('readonly', False)]},
        help=
        "You can for each event define a minimum registration level. If you do not enough registrations you are not able to confirm your event. (put 0 to ignore this rule )"
    )
    seats_reserved = fields.Integer(oldname='register_current',
                                    string='Reserved Seats',
                                    store=True,
                                    readonly=True,
                                    compute='_compute_seats')
    seats_available = fields.Integer(oldname='register_avail',
                                     string='Available Seats',
                                     store=True,
                                     readonly=True,
                                     compute='_compute_seats')
    seats_unconfirmed = fields.Integer(oldname='register_prospect',
                                       string='Unconfirmed Seat Reservations',
                                       store=True,
                                       readonly=True,
                                       compute='_compute_seats')
    seats_used = fields.Integer(oldname='register_attended',
                                string='Number of Participations',
                                store=True,
                                readonly=True,
                                compute='_compute_seats')

    @api.multi
    @api.depends('seats_max', 'registration_ids.state')
    def _compute_seats(self):
        """ Determine reserved, available, reserved but unconfirmed and used seats. """
        # initialize fields to 0
        for event in self:
            event.seats_unconfirmed = event.seats_reserved = event.seats_used = event.seats_available = 0
        # aggregate registrations by event and by state
        if self.ids:
            state_field = {
                'draft': 'seats_unconfirmed',
                'open': 'seats_reserved',
                'done': 'seats_used',
            }
            query = """ SELECT event_id, state, count(event_id)
                        FROM event_registration
                        WHERE event_id IN %s AND state IN ('draft', 'open', 'done')
                        GROUP BY event_id, state
                    """
            self._cr.execute(query, (tuple(self.ids), ))
            for event_id, state, num in self._cr.fetchall():
                event = self.browse(event_id)
                event[state_field[state]] += num
        # compute seats_available
        for event in self:
            if event.seats_max > 0:
                event.seats_available = event.seats_max - (
                    event.seats_reserved + event.seats_used)

    # Registration fields
    registration_ids = fields.One2many('event.registration',
                                       'event_id',
                                       string='Attendees',
                                       readonly=False,
                                       states={'done': [('readonly', True)]})
    # Date fields
    date_tz = fields.Selection('_tz_get',
                               string='Timezone',
                               default=lambda self: self.env.user.tz)
    date_begin = fields.Datetime(string='Start Date',
                                 required=True,
                                 readonly=True,
                                 states={'draft': [('readonly', False)]})
    date_end = fields.Datetime(string='End Date',
                               required=True,
                               readonly=True,
                               states={'draft': [('readonly', False)]})
    date_begin_located = fields.Datetime(string='Start Date Located',
                                         compute='_compute_date_begin_tz')
    date_end_located = fields.Datetime(string='End Date Located',
                                       compute='_compute_date_end_tz')

    @api.model
    def _tz_get(self):
        return [(x, x) for x in pytz.all_timezones]

    @api.one
    @api.depends('date_tz', 'date_begin')
    def _compute_date_begin_tz(self):
        if self.date_begin:
            self_in_tz = self.with_context(tz=(self.date_tz or 'UTC'))
            date_begin = fields.Datetime.from_string(self.date_begin)
            self.date_begin_located = fields.Datetime.to_string(
                fields.Datetime.context_timestamp(self_in_tz, date_begin))
        else:
            self.date_begin_located = False

    @api.one
    @api.depends('date_tz', 'date_end')
    def _compute_date_end_tz(self):
        if self.date_end:
            self_in_tz = self.with_context(tz=(self.date_tz or 'UTC'))
            date_end = fields.Datetime.from_string(self.date_end)
            self.date_end_located = fields.Datetime.to_string(
                fields.Datetime.context_timestamp(self_in_tz, date_end))
        else:
            self.date_end_located = False

    state = fields.Selection(
        [('draft', 'Unconfirmed'), ('cancel', 'Cancelled'),
         ('confirm', 'Confirmed'), ('done', 'Done')],
        string='Status',
        default='draft',
        readonly=True,
        required=True,
        copy=False,
        help=
        "If event is created, the status is 'Draft'. If event is confirmed for the particular dates the status is set to 'Confirmed'. If the event is over, the status is set to 'Done'. If event is cancelled the status is set to 'Cancelled'."
    )
    auto_confirm = fields.Boolean(string='Auto Confirmation Activated',
                                  compute='_compute_auto_confirm')

    @api.one
    def _compute_auto_confirm(self):
        self.auto_confirm = self.env['ir.values'].get_default(
            'marketing.config.settings', 'auto_confirmation')

    reply_to = fields.Char(
        'Reply-To Email',
        readonly=False,
        states={'done': [('readonly', True)]},
        help=
        "The email address of the organizer is likely to be put here, with the effect to be in the 'Reply-To' of the mails sent automatically at event or registrations confirmation. You can also put the email address of your mail gateway if you use one."
    )
    address_id = fields.Many2one(
        'res.partner',
        string='Location',
        default=lambda self: self.env.user.company_id.partner_id,
        readonly=False,
        states={'done': [('readonly', True)]})
    country_id = fields.Many2one('res.country',
                                 'Country',
                                 related='address_id.country_id',
                                 store=True)
    description = fields.Html(string='Description',
                              oldname='note',
                              translate=True,
                              readonly=False,
                              states={'done': [('readonly', True)]})

    @api.multi
    @api.depends('name', 'date_begin', 'date_end')
    def name_get(self):
        result = []
        for event in self:
            dates = [
                dt.split(' ')[0] for dt in [event.date_begin, event.date_end]
                if dt
            ]
            dates = sorted(set(dates))
            result.append(
                (event.id, '%s (%s)' % (event.name, ' - '.join(dates))))
        return result

    @api.one
    @api.constrains('seats_max', 'seats_available')
    def _check_seats_limit(self):
        if self.seats_max and self.seats_available < 0:
            raise UserError(_('No more available seats.'))

    @api.one
    @api.constrains('date_begin', 'date_end')
    def _check_closing_date(self):
        if self.date_end < self.date_begin:
            raise UserError(
                _('Closing Date cannot be set before Beginning Date.'))

    @api.model
    def create(self, vals):
        res = super(event_event, self).create(vals)
        if res.organizer_id:
            res.message_subscribe([res.organizer_id.id])
        if res.auto_confirm:
            res.button_confirm()
        return res

    @api.multi
    def write(self, vals):
        res = super(event_event, self).write(vals)
        if vals.get('organizer_id'):
            self.message_subscribe([vals['organizer_id']])
        return res

    @api.one
    def button_draft(self):
        self.state = 'draft'

    @api.one
    def button_cancel(self):
        for event_reg in self.registration_ids:
            if event_reg.state == 'done':
                raise UserError(
                    _("You have already set a registration for this event as 'Attended'. Please reset it to draft if you want to cancel this event."
                      ))
        self.registration_ids.write({'state': 'cancel'})
        self.state = 'cancel'

    @api.one
    def button_done(self):
        self.state = 'done'

    @api.one
    def button_confirm(self):
        self.state = 'confirm'

    @api.onchange('type')
    def _onchange_type(self):
        if self.type:
            self.seats_min = self.type.default_registration_min
            self.seats_max = self.type.default_registration_max
            self.reply_to = self.type.default_reply_to

    @api.multi
    def action_event_registration_report(self):
        res = self.env['ir.actions.act_window'].for_xml_id(
            'event', 'action_report_event_registration')
        res['context'] = {
            "search_default_event_id": self.id,
            "group_by": ['create_date:day'],
        }
        return res

    @api.one
    def mail_attendees(self,
                       template_id,
                       force_send=False,
                       filter_func=lambda self: True):
        for attendee in self.registration_ids.filtered(filter_func):
            self.env['mail.template'].browse(template_id).send_mail(
                attendee.id, force_send=force_send)
コード例 #4
0
ファイル: donation12-11-2.py プロジェクト: odoo-modules/Mee
class DonationDonation(models.Model):
    _name = 'donation.donation'
    _description = 'Donation'
    _order = 'id desc'
    _rec_name = 'display_name'
    _inherit = ['mail.thread']

    @api.multi
    @api.depends('line_ids', 'line_ids.unit_price', 'line_ids.quantity',
                 'line_ids.product_id', 'donation_date', 'currency_id',
                 'company_id')
    def _compute_total(self):
        for donation in self:
            total = tax_receipt_total = 0.0
            company_currency = donation.company_currency_id
            donation_currency = donation.currency_id
            # Do not consider other currencies for tax receipts
            # because, for the moment, only very very few countries
            # accept tax receipts from other countries, and never in another
            # currency. If you know such cases, please tell us and we will
            # update the code of this module
            for line in donation.line_ids:
                line_total = line.quantity * line.unit_price
                total += line_total
                if (donation_currency == company_currency
                        and line.product_id.tax_receipt_ok):
                    tax_receipt_total += line_total

            donation.amount_total = total
            donation_currency =\
                donation.currency_id.with_context(date=donation.donation_date)
            total_company_currency = donation_currency.compute(
                total, donation.company_id.currency_id)
            donation.amount_total_company_currency = total_company_currency
            donation.tax_receipt_total = tax_receipt_total

    # We don't want a depends on partner_id.country_id, because if the partner
    # moves to another country, we want to keep the old country for
    # past donations to have good statistics
    @api.multi
    @api.depends('donation_by')
    def _compute_country_id(self):
        # Use sudo() to by-pass record rules, because the same partner
        # can have donations in several companies
        for donation in self:
            donation.sudo(
            ).country_id = donation.donation_by.partner_id.country_id

    @api.model
    def _default_currency(self):
        company = self.env['res.company']._company_default_get(
            'donation.donation')
        return company.currency_id

    @api.model
    def _get_default_requested_by(self):
        return self.env['res.users'].browse(self.env.uid)

    currency_id = fields.Many2one('res.currency',
                                  string='Currency',
                                  required=True,
                                  states={3: [('readonly', True)]},
                                  track_visibility='onchange',
                                  ondelete='restrict',
                                  default=_default_currency)
    partner_id = fields.Many2one('res.partner',
                                 string='Donor',
                                 index=True,
                                 states={3: [('readonly', True)]},
                                 track_visibility='onchange',
                                 ondelete='restrict')
    commercial_partner_id = fields.Many2one(
        related='donation_by.partner_id.commercial_partner_id',
        string='Parent Donor',
        readonly=True,
        store=True,
        index=True)
    # country_id is here to have stats per country
    # WARNING : I can't put a related field, because when someone
    # writes on the country_id of a partner, it will trigger a write
    # on all it's donations, including donations in other companies
    # which will be blocked by the record rule
    country_id = fields.Many2one('res.country',
                                 string='Country',
                                 compute='_compute_country_id',
                                 store=True,
                                 readonly=True,
                                 copy=False)
    donation_by = fields.Many2one('res.users',
                                  'Donation by',
                                  required=True,
                                  track_visibility='onchange',
                                  default=_get_default_requested_by)

    donation_place = fields.Many2one('donation.place',
                                     'Donation Place',
                                     store=True)
    donation_section = fields.Many2one('donation.section',
                                       'Section',
                                       store=True)
    gov_id = fields.Many2one('govs.villages.gov',
                             related='donation_by.gov_id',
                             string='Gov',
                             store=True)
    check_total = fields.Monetary(string='Check Amount',
                                  digits=dp.get_precision('Account'),
                                  states={3: [('readonly', True)]},
                                  currency_field='currency_id',
                                  track_visibility='onchange')
    amount_total = fields.Monetary(compute='_compute_total',
                                   string='Amount Total',
                                   currency_field='currency_id',
                                   store=True,
                                   digits=dp.get_precision('Account'),
                                   readonly=True)
    amount_total_company_currency = fields.Monetary(
        compute='_compute_total',
        string='Amount Total in Company Currency',
        currency_field='company_currency_id',
        store=True,
        digits=dp.get_precision('Account'),
        readonly=True)
    donation_date = fields.Date(string='Donation Date',
                                required=True,
                                default=fields.Date.context_today,
                                states={3: [('readonly', True)]},
                                index=True,
                                track_visibility='onchange')
    company_id = fields.Many2one('res.company',
                                 string='Company',
                                 required=True,
                                 states={3: [('readonly', True)]},
                                 default=lambda self: self.env['res.company'].
                                 _company_default_get('donation.donation'))
    line_ids = fields.One2many('donation.line',
                               'donation_id',
                               string='Donation Lines',
                               states={3: [('readonly', True)]},
                               copy=True)
    move_id = fields.Many2one('account.move',
                              string='Account Move',
                              readonly=True,
                              copy=False)
    move_analytic_id = fields.Many2many('account.analytic.line',
                                        string='Account Analytic',
                                        readonly=True)

    number = fields.Char(related='move_id.name',
                         readonly=True,
                         size=64,
                         store=True,
                         string='Donation Number')
    journal_id = fields.Many2one(
        'account.journal',
        string='Payment Method',
        required=True,
        domain=[('type', 'in', ('bank', 'cash')),
                ('allow_donation', '=', True)],
        states={3: [('readonly', True)]},
        track_visibility='onchange',
        default=lambda self: self.env.user.context_donation_journal_id)
    payment_ref = fields.Char(string='Payment Reference',
                              size=32,
                              states={3: [('readonly', True)]})
    state = fields.Selection([
        (1, 'Draft'),
        (2, 'Transfer'),
        (3, 'Done'),
        (4, 'Cancelled'),
    ],
                             string='State',
                             readonly=True,
                             copy=False,
                             default=1,
                             index=True,
                             track_visibility='onchange')
    company_currency_id = fields.Many2one(related='company_id.currency_id',
                                          string="Company Currency",
                                          readonly=True)
    campaign_id = fields.Many2one(
        'donation.campaign',
        string='Donation Campaign',
        track_visibility='onchange',
        ondelete='restrict',
        default=lambda self: self.env.user.context_donation_campaign_id)
    display_name = fields.Char(string='Display Name',
                               compute='_compute_display_name',
                               readonly=True)
    #display_tag = fields.Char(string ='Tag')
    tax_receipt_id = fields.Many2one('donation.tax.receipt',
                                     string='Tax Receipt',
                                     readonly=True,
                                     copy=False)
    tax_receipt_option = fields.Selection([
        ('none', 'None'),
        ('each', 'For Each Donation'),
        ('annual', 'Annual Tax Receipt'),
    ],
                                          string='Tax Receipt Option',
                                          states={3: [('readonly', True)]},
                                          index=True)
    tax_receipt_total = fields.Monetary(
        compute='_compute_total',
        string='Eligible Tax Receipt Sub-total',
        store=True,
        currency_field='company_currency_id')
    tags_id = fields.Many2many('account.analytic.tag',
                               string='Tags',
                               readonly=True)
    donation_method = fields.Many2one('donation.instrument',
                                      store=True,
                                      string='Donation Method')
    account_id = fields.Many2one('account.account',
                                 related='donation_place.account_id',
                                 store=True,
                                 string='Account',
                                 readonly=True)
    product_id = fields.Many2one('product.product',
                                 domain=[('donation', '=', True)],
                                 string='Product',
                                 required=True,
                                 ondelete='restrict')
    #analytic = fields.Integer(string="id",compute='get_analytic_account_id_2')
    #analytic_tag = fields.Integer(string="tegid",compute='get_analytic_account_id_2')

    @api.multi
    @api.constrains('donation_date')
    def _check_donation_date(self):
        for donation in self:
            if donation.donation_date > fields.Date.context_today(self):
                # TODO No error pop-up to user : Odoo 9 BUG ?
                raise ValidationError(
                    _('The date of the donation of %s should be today '
                      'or in the past, not in the future!') %
                    donation.donation_by.partner_id.name)

    @api.multi
    def _prepare_each_tax_receipt(self):
        self.ensure_one()
        vals = {
            'company_id': self.company_id.id,
            'currency_id': self.company_currency_id.id,
            'donation_date': self.donation_date,
            'amount': self.tax_receipt_total,
            'type': 'each',
            'partner_id': self.commercial_partner_id.id,
        }
        return vals

    @api.model
    def _prepare_move_line_name(self):
        name = _('Donation of %s') % self.donation_by.partner_id.name
        return name

    @api.multi
    def _prepare_counterpart_move_line(self, name, amount_total_company_cur,
                                       total_amount_currency, currency_id):
        self.ensure_one()
        precision = self.env['decimal.precision'].precision_get('Account')
        if float_compare(amount_total_company_cur,
                         0,
                         precision_digits=precision) == 1:
            debit = amount_total_company_cur
            credit = 0
            total_amount_currency = self.amount_total
        else:
            credit = amount_total_company_cur * -1
            debit = 0
            total_amount_currency = self.amount_total * -1
        vals = {
            'debit': debit,
            'credit': credit,
            'name': name,
            'account_id': self.journal_id.default_debit_account_id.id,
            'partner_id': self.commercial_partner_id.id,
            'currency_id': currency_id,
            'amount_currency': (currency_id and total_amount_currency or 0.0),
        }
        return vals

    @api.multi
    def _prepare_donation_move(self):
        self.ensure_one()
        if not self.journal_id.default_debit_account_id:
            raise UserError(
                _("Missing Default Debit Account on journal '%s'.") %
                self.journal_id.name)

        movelines = []
        if self.company_id.currency_id.id != self.currency_id.id:
            currency_id = self.currency_id.id
        else:
            currency_id = False
        # Note : we can have negative donations for donors that use direct
        # debit when their direct debit rejected by the bank
        amount_total_company_cur = 0.0
        total_amount_currency = 0.0
        name = self._prepare_move_line_name()
        aml = {}
        # key = (account_id, analytic_account_id)
        # value = {'credit': ..., 'debit': ..., 'amount_currency': ...}
        precision = self.env['decimal.precision'].precision_get('Account')
        for donation_line in self.line_ids:
            if donation_line.in_kind:
                continue
            amount_total_company_cur += donation_line.amount_company_currency
            #account_id = donation_line.product_id.property_account_income_id.id
            #if not account_id:
            #   account_id = donation_line.product_id.categ_id.\
            #      property_account_income_categ_id.id
            account_id = donation_line.get_account_id()
            if not account_id:
                raise UserError(
                    _("Missing income account on product '%s' or on it's "
                      "related product category") %
                    donation_line.product_id.name)
            analytic_account_id = donation_line.get_analytic_account_id()

            amount_currency = 0.0
            if float_compare(donation_line.amount_company_currency,
                             0,
                             precision_digits=precision) == 1:
                credit = donation_line.amount_company_currency
                debit = 0
                amount_currency = donation_line.amount * -1
            else:
                debit = donation_line.amount_company_currency * -1
                credit = 0
                amount_currency = donation_line.amount

            # TODO Take into account the option group_invoice_lines ?
            if (account_id, analytic_account_id) in aml:
                aml[(account_id, analytic_account_id)]['credit'] += credit
                aml[(account_id, analytic_account_id)]['debit'] += debit
                aml[(account_id, analytic_account_id)]['amount_currency'] \
                    += amount_currency
            else:
                aml[(account_id, analytic_account_id)] = {
                    'credit': credit,
                    'debit': debit,
                    'amount_currency': amount_currency,
                }

        if not aml:  # for full in-kind donation
            return False

        for (account_id, analytic_account_id), content in aml.iteritems():
            movelines.append((0, 0, {
                'name':
                name,
                'credit':
                content['credit'],
                'debit':
                content['debit'],
                'account_id':
                account_id,
                'analytic_account_id':
                analytic_account_id,
                'partner_id':
                self.commercial_partner_id.id,
                'currency_id':
                currency_id,
                'amount_currency': (currency_id and content['amount_currency']
                                    or 0.0),
            }))

        # counter-part
        ml_vals = self._prepare_counterpart_move_line(
            name, amount_total_company_cur, total_amount_currency, currency_id)
        movelines.append((0, 0, ml_vals))

        vals = {
            'journal_id': self.journal_id.id,
            'date': self.donation_date,
            'ref': self.payment_ref,
            'line_ids': movelines,
        }
        return vals

    @api.one
    def _prepare_analytic_line(self):
        """ Prepare the values used to create() an account.analytic.line upon validation of an account.move.line having
            an analytic account. This method is intended to be extended in other modules.
        """
        #for donation_line in self.line_ids:
        #if donation_line.in_kind:
        #continue
        #amount = (self.credit or 0.0) - (self.debit or 0.0)
        #account_id = self.line_ids.product_id.property_account_income_id.id
        for donation_line in self.line_ids:
            if donation_line.in_kind:
                continue
            account_id = donation_line.get_account_id()
            analytic_account_id = donation_line.get_analytic_account_id()
        #if not account_id:
        #   account_id = self.line_ids.product_id.categ_id.property_account_income_categ_id.id
        name = self._prepare_move_line_name()
        vals = {
            'name': name,
            'date': self.donation_date,
            'account_id': analytic_account_id,
            'partner_id': self.commercial_partner_id.id,
            #'unit_amount': self.quantity,
            #'product_id': self.product_id and self.product_id.id or False,
            #'product_uom_id': self.product_uom_id and self.product_uom_id.id or False,
            'unit_amount': False,
            'product_id': False,
            'product_uom_id': False,
            #'amount': self.company_currency_id.with_context(date=self.date or fields.Date.context_today(self)).compute(amount, self.analytic_account_id.currency_id) if self.analytic_account_id.currency_id else amount,
            'amount': self.amount_total,
            'general_account_id': account_id,
            'ref': self.payment_ref,
            'move_id': self.move_id.id,
            'user_id': self._uid,
            'tag_ids': self.tags_id,
        }
        return vals

    @api.multi
    def transfer(self):
        for rec in self:
            rec.state = 2
            #self.env.cr.execute("SELECT place.tag_id FROM donation_donation inner join donation_place as place on donation_donation.donation_place = place.id where donation_donation.id= '%s'" %(self.id))
            #res = self.env.cr.fetchone()[0]
            #rec.env.cr.execute("insert INTO account_analytic_tag_donation_line_rel(donation_line_id, account_analytic_tag_id) VALUES ('%s','%s')" %(rec.line_ids.id,res))

            #self.env.cr.execute("SELECT gov.tag_id FROM donation_donation inner join govs_villages_gov as gov on donation_donation.gov_id = gov.id where donation_donation.id= '%s'" %(self.id))
            #res2 = self.env.cr.fetchone()[0]
            #rec.env.cr.execute("insert INTO account_analytic_tag_donation_line_rel(donation_line_id, account_analytic_tag_id) VALUES ('%s','%s')" %(rec.line_ids.id,res2))

            #self.env.cr.execute("SELECT method.tag_id FROM donation_line inner join donation_instrument as method on donation_line.donation_method = method.id where donation_line.id= '%s'" %(self.line_ids.id))
            #res3 = self.env.cr.fetchone()[0]
            #rec.env.cr.execute("insert INTO account_analytic_tag_donation_line_rel(donation_line_id, account_analytic_tag_id) VALUES ('%s','%s')" %(rec.line_ids.id,res3))

            self.env.cr.execute(
                "SELECT place.tag_id FROM donation_donation inner join donation_place as place on donation_donation.donation_place = place.id where donation_donation.id= '%s'"
                % (self.id))
            res11 = self.env.cr.fetchone()[0]
            rec.env.cr.execute(
                "insert INTO account_analytic_tag_donation_donation_rel(donation_donation_id, account_analytic_tag_id) VALUES ('%s','%s')"
                % (rec.id, res11))

            self.env.cr.execute(
                "SELECT gov.tag_id FROM donation_donation inner join govs_villages_gov as gov on donation_donation.gov_id = gov.id where donation_donation.id= '%s'"
                % (self.id))
            res12 = self.env.cr.fetchone()[0]
            rec.env.cr.execute(
                "insert INTO account_analytic_tag_donation_donation_rel(donation_donation_id, account_analytic_tag_id) VALUES ('%s','%s')"
                % (rec.id, res12))

            self.env.cr.execute(
                "SELECT method.tag_id FROM donation_donation inner join donation_instrument as method on donation_donation.donation_method = method.id where donation_donation.id= '%s'"
                % (self.id))
            res13 = self.env.cr.fetchone()[0]
            rec.env.cr.execute(
                "insert INTO account_analytic_tag_donation_donation_rel(donation_donation_id, account_analytic_tag_id) VALUES ('%s','%s')"
                % (rec.id, res13))
        for donation_line in self.line_ids:
            self.env.cr.execute(
                "SELECT place.tag_id FROM donation_line inner join donation_place as place on donation_line.donation_place = place.id where donation_line.id= '%s'"
                % (donation_line.id))
            res11 = self.env.cr.fetchone()[0]
            rec.env.cr.execute(
                "insert INTO account_analytic_tag_donation_line_rel(donation_line_id, account_analytic_tag_id) VALUES ('%s','%s')"
                % (donation_line.id, res11))

            self.env.cr.execute(
                "SELECT gov.tag_id FROM donation_line inner join govs_villages_gov as gov on donation_line.gov_id = gov.id where donation_line.id= '%s'"
                % (donation_line.id))
            res12 = self.env.cr.fetchone()[0]
            rec.env.cr.execute(
                "insert INTO account_analytic_tag_donation_line_rel(donation_line_id, account_analytic_tag_id) VALUES ('%s','%s')"
                % (donation_line.id, res12))

            self.env.cr.execute(
                "SELECT method.tag_id FROM donation_line inner join donation_instrument as method on donation_line.donation_method = method.id where donation_line.id= '%s'"
                % (donation_line.id))
            res13 = self.env.cr.fetchone()[0]
            rec.env.cr.execute(
                "insert INTO account_analytic_tag_donation_line_rel(donation_line_id, account_analytic_tag_id) VALUES ('%s','%s')"
                % (donation_line.id, res13))

    @api.multi
    def validate(self):
        check_total = self.env['res.users'].has_group(
            'donation.group_donation_check_total')
        precision = self.env['decimal.precision'].precision_get('Account')
        for donation in self:
            if not donation.line_ids:
                raise UserError(
                    _("Cannot validate the donation of %s because it doesn't "
                      "have any lines!") %
                    donation.donation_by.partner_id.name)

            if float_is_zero(donation.amount_total,
                             precision_digits=precision):
                raise UserError(
                    _("Cannot validate the donation of %s because the "
                      "total amount is 0 !") %
                    donation.donation_by.partner_id.name)

            if donation.state != 2:
                raise UserError(
                    _("Cannot validate the donation of %s because it is not "
                      "in transfer state.") %
                    donation.donation_by.partner_id.name)

            if check_total and donation.check_total != donation.amount_total:
                raise UserError(
                    _("The amount of the donation of %s (%s) is different "
                      "from the sum of the donation lines (%s).") %
                    (donation.donation_by.partner_id.name,
                     donation.check_total, donation.amount_total))
            vals = {'state': 3}
            if donation.amount_total:
                move_vals = donation._prepare_donation_move()
                move_analytic_vals = donation._prepare_analytic_line()[0]
                # when we have a full in-kind donation: no account move
                if move_vals:
                    move = self.env['account.move'].create(move_vals)
                    #move.post()
                    move_id2 = move.id
                    vals['move_id'] = move.id

                    for donation_line in self.line_ids:
                        move_analytic = self.env[
                            'account.analytic.line'].create(move_analytic_vals)
                        move_analytic2 = move_analytic.id
                        analytic = donation_line.analytic_account2.id
                        account = donation_line.account_id.id
                        #vals['move_analytic_id'] = move_analytic.id
                        self.env.cr.execute(
                            "insert INTO account_analytic_line_donation_donation_rel(donation_donation_id, account_analytic_line_id) VALUES ('%s','%s')"
                            % (donation_line.donation_id.id, move_analytic.id))

                        self.env.cr.execute(
                            "SELECT id FROM account_move_line where move_id = '%s' and account_id ='%d' and analytic_account_id ='%d' "
                            % (move.id, account, analytic))
                        #and analytic_account_id ='%d' , analytic
                        res111 = self.env.cr.fetchone()[0]
                        self.env.cr.execute(
                            "UPDATE account_analytic_line set move_id= '%s' where id= '%d'"
                            % (res111, move_analytic.id))
                        #ress = (move.id*2) - 1
                        self.env.cr.execute(
                            "UPDATE account_analytic_line set account_id= '%s' where id= '%d'"
                            % (analytic, move_analytic.id))

                        self.env.cr.execute(
                            "SELECT credit FROM account_move_line where move_id = '%s' and account_id ='%d' and id ='%d' "
                            % (move.id, account, res111))
                        res111_amount = self.env.cr.fetchone()[0]
                        self.env.cr.execute(
                            "UPDATE account_analytic_line set amount= '%s' where id= '%d'"
                            % (res111_amount, move_analytic.id))

                        resss = self.account_id.id
                        self.env.cr.execute(
                            "UPDATE account_analytic_line set general_account_id= '%s' where id= '%d'"
                            % (resss, move_analytic.id))
                        ressss = self.commercial_partner_id.id
                        self.env.cr.execute(
                            "UPDATE account_analytic_line set partner_id= '%s' where id= '%d'"
                            % (ressss, move_analytic.id))
                        ress2 = move_analytic.id
                        self.env.cr.execute(
                            "SELECT place.tag_id FROM donation_donation inner join donation_place as place on donation_donation.donation_place = place.id where donation_donation.id= '%s'"
                            % (self.id))
                        res11 = self.env.cr.fetchone()[0]
                        self.env.cr.execute(
                            "insert INTO account_analytic_line_tag_rel(line_id, tag_id) VALUES ('%s','%s')"
                            % (ress2, res11))
                        self.env.cr.execute(
                            "SELECT gov.tag_id FROM donation_donation inner join govs_villages_gov as gov on donation_donation.gov_id = gov.id where donation_donation.id= '%s'"
                            % (self.id))
                        res12 = self.env.cr.fetchone()[0]
                        self.env.cr.execute(
                            "insert INTO account_analytic_line_tag_rel(line_id, tag_id) VALUES ('%s','%s')"
                            % (ress2, res12))
                        self.env.cr.execute(
                            "SELECT method.tag_id FROM donation_donation inner join donation_instrument as method on donation_donation.donation_method = method.id where donation_donation.id= '%s'"
                            % (self.id))
                        res13 = self.env.cr.fetchone()[0]
                        self.env.cr.execute(
                            "insert INTO account_analytic_line_tag_rel(line_id, tag_id) VALUES ('%s','%s')"
                            % (ress2, res13))
                else:
                    donation.message_post(
                        _('Full in-kind donation: no account move generated'))
            if (donation.tax_receipt_option == 'each'
                    and donation.tax_receipt_total
                    and not donation.tax_receipt_id):
                receipt_vals = donation._prepare_each_tax_receipt()
                receipt = self.env['donation.tax.receipt'].create(receipt_vals)
                vals['tax_receipt_id'] = receipt.id
            donation.write(vals)
        return

    @api.multi
    def save_default_values(self):
        self.ensure_one()
        self.env.user.write({
            'context_donation_journal_id':
            self.journal_id.id,
            'context_donation_campaign_id':
            self.campaign_id.id,
        })

    #@api.multi
    #def analytic(self):
    #    for rec in self:
    #       ress = (self.move_id.id *2) - 1
    #      self.env.cr.execute("UPDATE account_analytic_line set move_id= '%s' where id= '%d'" %(ress,self.move_analytic_id.id))

    #     ress2 = self.move_analytic_id.id
    #    self.env.cr.execute("SELECT place.tag_id FROM donation_donation inner join donation_place as place on donation_donation.donation_place = place.id where donation_donation.id= '%s'" %(self.id))
    #   res11 = self.env.cr.fetchone()[0]
    #  rec.env.cr.execute("insert INTO account_analytic_line_tag_rel(line_id, tag_id) VALUES ('%s','%s')" %(ress2,res11))

    # self.env.cr.execute("SELECT gov.tag_id FROM donation_donation inner join govs_villages_gov as gov on donation_donation.gov_id = gov.id where donation_donation.id= '%s'" %(self.id))
    #res12 = self.env.cr.fetchone()[0]
    #rec.env.cr.execute("insert INTO account_analytic_line_tag_rel(line_id, tag_id) VALUES ('%s','%s')" %(ress2,res12))

    #self.env.cr.execute("SELECT method.tag_id FROM donation_donation inner join donation_instrument as method on donation_donation.donation_method = method.id where donation_donation.id= '%s'" %(self.id))
    #res13 = self.env.cr.fetchone()[0]
    #rec.env.cr.execute("insert INTO account_analytic_line_tag_rel(line_id, tag_id) VALUES ('%s','%s')" %(ress2,res13))

    #self.env.cr.execute("SELECT place.tag_id FROM donation_donation inner join donation_place as place on donation_donation.donation_place = place.id where donation_donation.id= '%s'" %(self.id))
    #res11 = self.env.cr.fetchone()[0]
    #rec.env.cr.execute("insert INTO account_analytic_line_tag_rel(line_id, tag_id) VALUES ('%s','%s')" %(ress,res11))

    #self.env.cr.execute("SELECT gov.tag_id FROM donation_donation inner join govs_villages_gov as gov on donation_donation.gov_id = gov.id where donation_donation.id= '%s'" %(self.id))
    #res12 = self.env.cr.fetchone()[0]
    #rec.env.cr.execute("insert INTO account_analytic_line_tag_rel(line_id, tag_id) VALUES ('%s','%s')" %(ress,res12))

    #self.env.cr.execute("SELECT method.tag_id FROM donation_donation inner join donation_instrument as method on donation_donation.donation_method = method.id where donation_donation.id= '%s'" %(self.id))
    #res13 = self.env.cr.fetchone()[0]
    #rec.env.cr.execute("insert INTO account_analytic_line_tag_rel(line_id, tag_id) VALUES ('%s','%s')" %(ress,res13))
    @api.multi
    def done2cancel(self):
        '''from Done state to Cancel state'''
        for donation in self:
            if donation.tax_receipt_id:
                raise UserError(
                    _("You cannot cancel this donation because "
                      "it is linked to the tax receipt %s. You should first "
                      "delete this tax receipt (but it may not be legally "
                      "allowed).") % donation.tax_receipt_id.number)
            if donation.move_id:
                donation.move_id.button_cancel()
                donation.move_id.unlink()
            donation.state = 4

    @api.multi
    def cancel2draft(self):
        '''from Cancel state to Draft state'''
        for donation in self:
            if donation.move_id:
                raise UserError(
                    _("A cancelled donation should not be linked to "
                      "an account move"))
            if donation.tax_receipt_id:
                raise UserError(
                    _("A cancelled donation should not be linked to "
                      "a tax receipt"))
            donation.state = 1

    @api.multi
    def unlink(self):
        for donation in self:
            if donation.state == 3:
                raise UserError(
                    _("The donation '%s' is in Done state, so you cannot "
                      "delete it.") % donation.display_name)
            if donation.move_id:
                raise UserError(
                    _("The donation '%s' is linked to an account move, "
                      "so you cannot delete it.") % donation.display_name)
            if donation.tax_receipt_id:
                raise UserError(
                    _("The donation '%s' is linked to the tax receipt %s, "
                      "so you cannot delete it.") %
                    (donation.display_name, donation.tax_receipt_id.number))
        return super(DonationDonation, self).unlink()

    @api.multi
    @api.depends('state', 'donation_by', 'move_id')
    def _compute_display_name(self):
        for donation in self:
            if donation.state == 1:
                name = _('Draft Donation of %s'
                         ) % donation.donation_by.partner_id.name
            elif donation.state == 4:
                name = _('Cancelled Donation of %s'
                         ) % donation.donation_by.partner_id.name
            else:
                name = donation.number
            donation.display_name = name

    @api.onchange('donation_by')
    def partner_id_change(self):
        if self.donation_by.partner_id:
            self.tax_receipt_option = self.donation_by.partner_id.tax_receipt_option

    @api.onchange('tax_receipt_option')
    def tax_receipt_option_change(self):
        res = {}
        if (self.donation_by.partner_id
                and self.donation_by.partner_id.tax_receipt_option == 'annual'
                and self.tax_receipt_option != 'annual'):
            res = {
                'warning': {
                    'title':
                    _('Error:'),
                    'message':
                    _('You cannot change the Tax Receipt '
                      'Option when it is Annual.'),
                },
            }
            self.tax_receipt_option = 'annual'
        return res
コード例 #5
0
class ir_cron(models.Model):
    _inherit = 'ir.cron'

    interval_type = fields.Selection(selection_add=[('seconds', 'Seconds')])
コード例 #6
0
class TaskOutput(models.Model):
    _name = "hc.task.output"
    _description = "Task Output"

    task_id = fields.Many2one(comodel_name="hc.res.task",
                              string="Task",
                              help="Task associated with this Task Output.")
    name = fields.Char(string="Name", required="True", help="Output Name.")
    value_type = fields.Selection(string="Value Type",
                                  selection=[
                                      ("integer", "Integer"),
                                      ("decimal", "Decimal"),
                                      ("date_time", "Date Time"),
                                      ("date", "Date"), ("instant", "Instant"),
                                      ("string", "String"), ("uri", "URI"),
                                      ("boolean", "Boolean"), ("code", "Code"),
                                      ("markdown", "Markdown"),
                                      ("base_64_binary", "Base 64 Binary"),
                                      ("coding", "Coding"),
                                      ("codeable_concept", "Codeable Concept"),
                                      ("attachment", "Attachment"),
                                      ("identifier", "Identifier"),
                                      ("quantity", "Quantity"),
                                      ("range", "Range"), ("period", "Period"),
                                      ("ratio", "Ratio"),
                                      ("human_name", "Human Name"),
                                      ("address", "Address"),
                                      ("contact_point", "Contact Point"),
                                      ("timing", "Timing"),
                                      ("signature", "Signature"),
                                      ("reference", "Reference"),
                                      ("time", "Time"), ("oid", "OID"),
                                      ("id", "ID"),
                                      ("unsigned_int", "Unsigned Integer"),
                                      ("positive_int", "Positive Integer"),
                                      ("annotation", "Annotation"),
                                      ("sampled_data", "Sampled Data"),
                                      ("meta", "Meta")
                                  ],
                                  help="Type of specified output value.")
    value_name = fields.Char(string="Value",
                             compute="_compute_value_name",
                             store="True",
                             help="Specified output value.")
    value_integer = fields.Integer(string="Value Integer",
                                   help="Integer output value.")
    value_decimal = fields.Float(string="Value Decimal",
                                 help="Decimal output value.")
    value_date_time = fields.Datetime(string="Value Date Time",
                                      help="Date Time output value.")
    value_date = fields.Date(string="Value Date", help="Date output value.")
    value_instant = fields.Datetime(string="Value Instant",
                                    help="Instant output value.")
    value_string = fields.Char(string="Value String",
                               help="String output value.")
    value_uri = fields.Char(string="Value URI", help="URI output value.")
    value_boolean = fields.Boolean(string="Value Boolean",
                                   help="Boolean output value.")
    value_code_id = fields.Many2one(comodel_name="hc.vs.task.code",
                                    string="Value Code",
                                    help="Code output value.")
    value_markdown = fields.Text(string="Value Markdown",
                                 help="Markdown output value.")
    value_base_64_binary = fields.Binary(string="Value Base 64 Binary",
                                         help="Base 64 Binary output value.")
    value_coding_id = fields.Many2one(comodel_name="hc.vs.task.code",
                                      string="Value Coding",
                                      help="Coding output value.")
    value_codeable_concept_id = fields.Many2one(
        comodel_name="hc.vs.task.code",
        string="Value Codeable Concept",
        help="Codeable Concept output value.")
    value_attachment_id = fields.Many2one(comodel_name="hc.task.attachment",
                                          string="Value Attachment",
                                          help="Attachment output value.")
    value_identifier_id = fields.Many2one(
        comodel_name="hc.task.value.identifier",
        string="Value Identifier",
        help="Identifier output value.")
    value_quantity = fields.Float(string="Value Quantity",
                                  help="Quantity output value.")
    value_quantity_uom_id = fields.Many2one(comodel_name="product.uom",
                                            string="Value Quantity UOM",
                                            help="Quantity unit of measure.")
    value_range = fields.Char(string="Value Range", help="Range output value.")
    value_period = fields.Char(string="Value Period",
                               help="Period output value.")
    value_period_uom_id = fields.Many2one(comodel_name="product.uom",
                                          string="Value Period UOM",
                                          help="Period unit of measure.")
    value_ratio = fields.Float(string="Value Ratio",
                               help="Ratio of output value.")
    value_human_name_id = fields.Many2one(comodel_name="hc.task.human.name",
                                          string="Value Human Name",
                                          help="Human Name output value.")
    value_address_id = fields.Many2one(comodel_name="hc.task.address",
                                       string="Value Address",
                                       help="Address output value.")
    value_contact_point_id = fields.Many2one(
        comodel_name="hc.task.telecom",
        string="Value Contact Point",
        help="Contact Point output value.")
    value_timing_id = fields.Many2one(comodel_name="hc.task.timing",
                                      string="Value Timing",
                                      help="Timing output value.")
    value_signature_id = fields.Many2one(comodel_name="hc.task.signature",
                                         string="Value Signature",
                                         help="Signature output value.")
    value_reference_id = fields.Many2one(comodel_name="hc.task.reference",
                                         string="Value Reference",
                                         help="Reference output value.")
    value_time = fields.Float(string="Value Time", help="Time output value.")
    value_oid = fields.Char(string="Value OID", help="OID output value.")
    value_id = fields.Char(string="Value ID", help="ID output value.")
    value_unsigned_int = fields.Integer(string="Value Unsigned Integer",
                                        help="Unsigned Integer output value.")
    value_positive_int = fields.Integer(string="Value Positive Integer",
                                        help="Positive Integer output value.")
    value_annotation_id = fields.Many2one(comodel_name="hc.task.annotation",
                                          string="Value Annotation",
                                          help="Annotation output value.")
    value_sampled_data_id = fields.Many2one(
        comodel_name="hc.task.sampled.data",
        string="Value Sampled Data",
        help="Sampled Data output value.")
    value_meta_id = fields.Many2one(comodel_name="hc.task.meta",
                                    string="Value Meta",
                                    help="Meta output value.")
コード例 #7
0
ファイル: project.py プロジェクト: tate11/weiwen
class ProjectTaskType(models.Model):
    _inherit = 'project.task.type'
    state = fields.Selection(_TASK_STATE, 'State')
コード例 #8
0
class ComunicazioneLiquidazioneVp(models.Model):
    _name = 'comunicazione.liquidazione.vp'
    _description = 'Comunicazione Liquidazione IVA - Quadro VP'

    @api.multi
    @api.depends('iva_esigibile', 'iva_detratta')
    def _compute_VP6_iva_dovuta_credito(self):
        for quadro in self:
            quadro.iva_dovuta_debito = 0
            quadro.iva_dovuta_credito = 0
            if quadro.iva_esigibile >= quadro.iva_detratta:
                quadro.iva_dovuta_debito = quadro.iva_esigibile - \
                    quadro.iva_detratta
            else:
                quadro.iva_dovuta_credito = quadro.iva_detratta - \
                    quadro.iva_esigibile

    @api.multi
    @api.depends('iva_dovuta_debito', 'iva_dovuta_credito',
                 'debito_periodo_precedente', 'credito_periodo_precedente',
                 'credito_anno_precedente', 'versamento_auto_UE',
                 'crediti_imposta', 'interessi_dovuti', 'accounto_dovuto')
    def _compute_VP14_iva_da_versare_credito(self):
        """
        Tot Iva a debito = (VP6, col.1 + VP7 + VP12) 
        Tot Iva a credito = (VP6, col.2 + VP8 + VP9 + VP10 + VP11 + VP13)
        """
        for quadro in self:
            quadro.iva_da_versare = 0
            quadro.iva_a_credito = 0
            if quadro.quarter == 5:
                continue
            debito = quadro.iva_dovuta_debito + quadro.debito_periodo_precedente\
                + quadro.interessi_dovuti
            credito = quadro.iva_dovuta_credito \
                + quadro.credito_periodo_precedente\
                + quadro.credito_anno_precedente \
                + quadro.versamento_auto_UE + quadro.crediti_imposta \
                + quadro.accounto_dovuto
            if debito >= credito:
                quadro.iva_da_versare = debito - credito
            else:
                quadro.iva_a_credito = credito - debito

    comunicazione_id = fields.Many2one('comunicazione.liquidazione',
                                       string='Comunicazione',
                                       readonly=True)
    period_type = fields.Selection([('month', 'Monthly'),
                                    ('quarter', 'Quarterly')],
                                   string='Period type',
                                   default='month')
    month = fields.Integer(string='Month', default=False)
    quarter = fields.Integer(string='Quarter', default=False)
    subcontracting = fields.Boolean(string='Subcontracting')
    exceptional_events = fields.Selection([('1', 'Code 1'), ('9', 'Code 9')],
                                          string='Exceptional events')

    imponibile_operazioni_attive = fields.Float(
        string='Totale operazioni attive (al netto dell’IVA)')
    imponibile_operazioni_passive = fields.Float(
        string='Totale operazioni passive (al netto dell’IVA)')
    iva_esigibile = fields.Float(string='IVA esigibile')
    iva_detratta = fields.Float(string='IVA detratta')
    iva_dovuta_debito = fields.Float(string='IVA dovuta debito',
                                     compute="_compute_VP6_iva_dovuta_credito",
                                     store=True)
    iva_dovuta_credito = fields.Float(
        string='IVA dovuta credito',
        compute="_compute_VP6_iva_dovuta_credito",
        store=True)
    debito_periodo_precedente = fields.Float(
        string='Debito periodo precedente')
    credito_periodo_precedente = fields.Float(
        string='Credito periodo precedente')
    credito_anno_precedente = fields.Float(string='Credito anno precedente')
    versamento_auto_UE = fields.Float(string='Versamenti auto UE')
    crediti_imposta = fields.Float(string='Crediti d’imposta')
    interessi_dovuti = fields.Float(
        string='Interessi dovuti per liquidazioni trimestrali')
    accounto_dovuto = fields.Float(string='Acconto dovuto')
    iva_da_versare = fields.Float(
        string='IVA da versare',
        compute="_compute_VP14_iva_da_versare_credito",
        store=True)
    iva_a_credito = fields.Float(
        string='IVA a credito',
        compute="_compute_VP14_iva_da_versare_credito",
        store=True)
コード例 #9
0
ファイル: is_cout.py プロジェクト: tonygalmiche/is_plastigray
class is_cout_calcul(models.Model):
    _name='is.cout.calcul'
    _order='name desc'

    name               = fields.Datetime('Date', required=True     , readonly=True)
    user_id            = fields.Many2one('res.users', 'Responsable', readonly=True)
    product_id         = fields.Many2one('product.product', 'Article')
    segment_id         = fields.Many2one('is.product.segment', 'Segment')
    is_category_id     = fields.Many2one('is.category', 'Catégorie')
    is_gestionnaire_id = fields.Many2one('is.gestionnaire', 'Gestionnaire')
    multiniveaux       = fields.Boolean('Calcul des coûts multi-niveaux')
    cout_actualise_ids = fields.One2many('is.cout.calcul.actualise', 'cout_calcul_id', u"Historique des côuts actualisés")
    niveau_ids         = fields.One2many('is.cout.calcul.niveau'   , 'cout_calcul_id', u"Niveau des articles dans la nomenclature")
    log_ids            = fields.One2many('is.cout.calcul.log', 'cout_calcul_id', u"Logs")
    state              = fields.Selection([('creation',u'Création'), ('prix_achat', u"Calcul des prix d'achat"),('termine', u"Terminé")], u"État", readonly=True, select=True)

    _defaults = {
        'name': lambda *a: time.strftime('%Y-%m-%d %H:%M:%S'),
        'user_id': lambda self, cr, uid, c: uid,
        'multiniveaux': True,
        'state': 'creation',
    }

    detail_nomenclature=[]
    detail_gamme_ma=[]
    detail_gamme_mo=[]

    detail_gamme_ma_pk=[]
    detail_gamme_mo_pk=[]

    mem_couts={}

    @api.multi
    @api.multi
    def nomenclature(self, cout_calcul_obj, product, niveau, multiniveaux=True):
        cr = self._cr
        type_article=self.type_article(product)
        cout=self.creation_cout(cout_calcul_obj, product, type_article)
        if type_article!='A' and multiniveaux==True:
            if niveau>10:
                raise Warning(u"Trop de niveaux (>10) dans la nomenclature du "+product.is_code)
            SQL="""
                select mbl.product_id, mbl.id, mbl.sequence, mb.id
                from mrp_bom mb inner join mrp_bom_line mbl on mbl.bom_id=mb.id
                                inner join product_product pp on pp.product_tmpl_id=mb.product_tmpl_id
                where pp.id="""+str(product.id)+ """ 
                order by mbl.sequence, mbl.id
            """
            #TODO : Voir si ce filtre est necessaire : and (mb.is_sous_traitance='f' or mb.is_sous_traitance is null)
            cr.execute(SQL)
            result = cr.fetchall()
            niv=niveau+1
            for row2 in result:
                composant=self.env['product.product'].browse(row2[0])
                self.nomenclature(cout_calcul_obj, composant, niv)


    @api.multi
    def type_article(self, product):
        type_article=""
        for route in product.route_ids:
            if type_article=='F' and route.name=='Buy':
                type_article='ST'
            if type_article=='A' and route.name=='Manufacture':
                type_article='ST'
            if type_article=='' and route.name=='Manufacture':
                type_article='F'
            if type_article=='' and route.name=='Buy':
                type_article='A'
        return type_article


    @api.multi
    def creation_cout(self, cout_calcul_obj, product, type_article, niveau=0):
        product_id=product.id
        #_logger.info('creation_cout : len(mem_couts)='+str(len(self.mem_couts)))
        if product_id in self.mem_couts:
            action='trouvé'
            cout=self.mem_couts[product_id]
        else:
            cout_obj = self.env['is.cout']
            couts=cout_obj.search([('name', '=', product_id)])
            vals={
                'cout_calcul_id': cout_calcul_obj.id,
                'type_article'  : type_article,
                'niveau'        : niveau,
            }
            if len(couts):
                action='write'
                cout=couts[0]
                cout.write(vals)
            else:
                action='create'
                vals['name'] = product_id
                cout=cout_obj.create(vals)
            self.mem_couts[product_id]=cout
        return cout


    @api.multi
    def action_imprimer_couts(self):
        for obj in self:
            tmp=tempfile.mkdtemp()
            os.system('mkdir '+tmp)
            ct=1
            nb=len(obj.cout_actualise_ids)
            for line in obj.cout_actualise_ids:
                couts=self.env['is.cout'].search([('name', '=', line.product_id.id)])
                for cout in couts:
                    path=tmp+"/"+str(ct)+".pdf"
                    ct=ct+1
                    pdf = self.env['report'].get_pdf(cout, 'is_plastigray.report_is_cout')
                    f = open(path,'wb')
                    f.write(pdf)
                    f.close()

            os.system('pdfjoin -o '+tmp+'/merged.pdf '+tmp+'/*.pdf')
            pdf = open(tmp+'/merged.pdf','rb').read()
            os.system('rm '+tmp+'/*.pdf')
            os.system('rmdir '+tmp)

            # ** Recherche si une pièce jointe est déja associèe ***************
            model=self._name
            name='Couts.pdf'
            attachment_obj = self.env['ir.attachment']
            attachments = attachment_obj.search([('res_model','=',model),('res_id','=',obj.id),('name','=',name)])
            # ******************************************************************

            # ** Creation ou modification de la pièce jointe *******************
            vals = {
                'name':        name,
                'datas_fname': name,
                'type':        'binary',
                'res_model':   model,
                'res_id':      obj.id,
                'datas':       pdf.encode('base64'),
            }
            attachment_id=False
            if attachments:
                for attachment in attachments:
                    attachment.write(vals)
                    attachment_id=attachment.id
            else:
                attachment = attachment_obj.create(vals)
                attachment_id=attachment.id
            return {
                'type' : 'ir.actions.act_url',
                'url': '/web/binary/saveas?model=ir.attachment&field=datas&id='+str(attachment_id)+'&filename_field=name',
                'target': 'self',
            }
            #*******************************************************************




    @api.multi
    def _log(self,operation):
        _logger.info(operation)
        for obj in self:
            vals={
                'cout_calcul_id': obj.id,
                'date'          : datetime.datetime.now(),
                'operation'     : operation,
            }
            res=self.env['is.cout.calcul.log'].create(vals)




#    @api.multi
#    def action_calcul_prix_achat(self):
#        cr = self._cr
#        debut=datetime.datetime.now()
#        for obj in self:
#            #obj.log_ids.unlink()
#            self._log("## DEBUT Calcul des prix d'achat")
#            _logger.info('début unlink')
#            for row in obj.cout_actualise_ids:
#                row.unlink()
#            _logger.info('fin unlink')
#            calcul_actualise_obj = self.env['is.cout.calcul.actualise']
#            _logger.info("début get_products")
#            products=self.get_products(obj)
#            _logger.info("fin get_products : nb="+str(len(products)))



#            #TODO : 0.07s par article (88s pour 1233 articles)
#            ct=1
#            nb=len(products)
#            #print _now(debut), "## début boucle products : nb=",nb

#            _logger.info("début boucle products : nb="+str(nb))

#            for product in products:
#                _logger.info(str(ct)+'/'+str(nb)+' : boucle products : '+product.is_code)
#                #print _now(debut), product,ct,'/',nb
#                ct+=1
#                self.nomenclature(obj,product,0, obj.multiniveaux)
#            couts=self.env['is.cout'].search([('cout_calcul_id', '=', obj.id)])
#            product_uom_obj = self.env['product.uom']
#            #print _now(debut), "## fin boucle products"
#            _logger.info("fin boucle products")




#            ct=1
#            nb=len(couts)
#            #print _now(debut), "## début boucle couts : nb=",nb
#            _logger.info("début boucle couts : nb="+str(nb))
#            for cout in couts:
#                product=cout.name

#                _logger.info(str(ct)+'/'+str(nb)+' : boucle couts : '+product.is_code)

#                #print _now(debut), product.is_code,ct,'/',nb
#                ct+=1


#                prix_tarif    = 0
#                prix_commande = 0
#                prix_facture  = 0
#                prix_calcule  = 0
#                ecart_calcule_matiere = 0
#                vals={
#                    'cout_calcul_id': obj.id,
#                    'product_id': product.id,
#                }
#                res=calcul_actualise_obj.create(vals)
#                type_article=cout.type_article

#                if type_article!='F':
#                    #** Recherche du fournisseur par défaut ********************
#                    seller=False
#                    if len(product.seller_ids)>0:
#                        seller=product.seller_ids[0]
#                    pricelist=False
#                    if seller:
#                        partner=seller.name
#                        pricelist=partner.property_product_pricelist_purchase
#                    #***********************************************************


#                    #** Recherche du prix d'achat ******************************
#                    date=time.strftime('%Y-%m-%d') # Date du jour

#                    if pricelist:
#                        #Convertion du lot_mini de US vers UA
#                        min_quantity = product_uom_obj._compute_qty(cout.name.uom_id.id, cout.name.lot_mini, cout.name.uom_po_id.id)

#                        #TODO : Pour contourner un bug d'arrondi (le 31/01/2017)
#                        min_quantity=min_quantity+0.00000000001
#                        #TODO en utilisant la fonction repr à la place de str, cela ne tronque pas les décimales

#                        SQL="""
#                            select ppi.price_surcharge
#                            from product_pricelist_version ppv inner join product_pricelist_item ppi on ppv.id=ppi.price_version_id
#                            where ppv.pricelist_id="""+str(pricelist.id)+ """ 
#                                  and min_quantity<="""+repr(min_quantity)+"""
#                                  and (ppv.date_start <= '"""+date+"""' or ppv.date_start is null)
#                                  and (ppv.date_end   >= '"""+date+"""' or ppv.date_end   is null)

#                                  and ppi.product_id="""+str(product.id)+ """ 
#                                  and (ppi.date_start <= '"""+date+"""' or ppi.date_start is null)
#                                  and (ppi.date_end   >= '"""+date+"""' or ppi.date_end   is null)
#                            order by ppi.sequence
#                            limit 1
#                        """
#                        cr.execute(SQL)
#                        result = cr.fetchall()
#                        for row in result:
#                            #coef=product.uom_po_id.factor_inv
#                            coef=1
#                            if min_quantity:
#                                coef=cout.name.lot_mini/min_quantity
#                            prix_tarif=row[0]/coef
#                    #***********************************************************


#                    #** Recherche prix dernière commande ***********************
#                    SQL="""
#                        select pol.price_unit*pu.factor
#                        from purchase_order_line pol inner join product_uom pu on pol.product_uom=pu.id
#                        where pol.product_id="""+str(product.id)+ """ 
#                              and state in('confirmed','done')
#                        order by pol.id desc limit 1
#                    """
#                    cr.execute(SQL)
#                    result = cr.fetchall()
#                    for row in result:
#                        prix_commande=row[0]
#                    #***********************************************************

#                    #** Recherche prix dernière facture ************************
#                    SQL="""
#                        select ail.price_unit*pu.factor
#                        from account_invoice_line ail inner join product_uom pu on ail.uos_id=pu.id
#                                                      inner join account_invoice ai on ail.invoice_id=ai.id
#                        where ail.product_id="""+str(product.id)+ """ 
#                              and ai.state in('open','paid') and ai.type='in_invoice'
#                        order by ail.id desc limit 1
#                    """
#                    cr.execute(SQL)
#                    result = cr.fetchall()
#                    for row in result:
#                        prix_facture=row[0]
#                    #***********************************************************


#                    if cout.prix_force:
#                        prix_calcule=cout.prix_force
#                    else:
#                        if prix_facture:
#                            prix_calcule=prix_facture
#                        else:
#                            if prix_commande:
#                                prix_calcule=prix_commande
#                            else:
#                                if prix_tarif:
#                                    prix_calcule=prix_tarif



#                    if type_article=='A':
#                        if prix_calcule==0:
#                            prix_calcule=cout.cout_act_matiere
#                        ecart_calcule_matiere  = prix_calcule - cout.cout_act_matiere
#                    if type_article=='ST':
#                        if prix_calcule==0:
#                            prix_calcule=cout.cout_act_st
#                        ecart_calcule_matiere  = prix_calcule - cout.cout_act_st

#                if prix_tarif:
#                    cout.prix_tarif=prix_tarif


#                cout.type_article  = type_article

#                cout.prix_commande = prix_commande
#                cout.prix_facture  = prix_facture
#                cout.prix_calcule  = prix_calcule
#                cout.ecart_calcule_matiere = ecart_calcule_matiere


#            obj.state="prix_achat"

#        self._log("## FIN Calcul des prix d'achat"+_now(debut))

    @api.multi
    def get_products(self,obj):
        cats=self.env['is.category']._calcul_cout()
        products={}
        if obj.product_id:
            products=self.env['product.product'].search([('id', '=', obj.product_id.id), ('is_category_id', 'in', cats)])
        else:
            if obj.segment_id:
                products=self.env['product.product'].search([('segment_id', '=', obj.segment_id.id), ('is_category_id', 'in', cats)], limit=10000)
            else:
                if obj.is_category_id:
                    products=self.env['product.product'].search([('is_category_id', '=', obj.is_category_id.id)], limit=10000)
                else:
                    if obj.is_gestionnaire_id:
                        products=self.env['product.product'].search([('is_gestionnaire_id', '=', obj.is_gestionnaire_id.id), ('is_category_id', 'in', cats)], limit=10000)
                    else:
                        products=self.env['product.product'].search([('is_category_id', 'in', cats)])
        return products



    @api.multi
    def nomenclature_prix_revient(self, cout_calcul_obj, niveau, product, unite=False, quantite_unitaire=1, quantite_total=1, prix_calcule=0):
        cr = self._cr
        type_article=self.type_article(product)
        cout_mat = 0
        cout_st  = 0
        msg_err=''
        if product.is_category_id.name!='80':
            if type_article=='A':
                cout_mat = prix_calcule
                if prix_calcule==0:
                    msg_err=u'Err Coût Mat'
            if type_article=='ST':
                cout_st  = prix_calcule
                if prix_calcule==0:
                    msg_err=u'Err Coût ST'

        cout=self.creation_cout(cout_calcul_obj, product, type_article)



        self.detail_nomenclature.append({
            'product_id'  : product.id,
            'is_code'     : product.is_code,
            'composant'   : '----------'[:niveau]+str(product.is_code),
            'designation' : product.name,
            'unite'       : unite,
            'quantite'    : quantite_unitaire, 
            'cout_mat'    : cout_mat, 
            'total_mat'   : quantite_total*cout_mat,
            'cout_st'     : cout_st, 
            'total_st'    : quantite_total*cout_st,
            'msg_err'     : msg_err,
        })

        if type_article!='A':
            lot_mini=product.lot_mini
            if lot_mini==0:
                lot_mini=1

            #** Recherche de la gamme ******************************************
            SQL="""
                select mb.routing_id
                from mrp_bom mb inner join product_product pp on pp.product_tmpl_id=mb.product_tmpl_id
                where pp.id="""+str(product.id)+ """ 
                      and (mb.is_sous_traitance='f' or mb.is_sous_traitance is null)
                order by mb.id
            """
            cr.execute(SQL)
            result = cr.fetchall()
            for row2 in result:
                routing_id = row2[0]
                if routing_id:
                    routing = self.env['mrp.routing'].browse(routing_id)
                    for line in routing.workcenter_lines:
                        cout_total=quantite_unitaire*line.workcenter_id.costs_hour*round(line.is_nb_secondes/3600,4)
                        vals={
                            'composant'     : '----------'[:niveau]+product.is_code,
                            'sequence'      : line.sequence,
                            'workcenter_id' : line.workcenter_id.id,
                            'quantite'      : quantite_unitaire,
                            'cout_prepa'    : line.workcenter_id.costs_hour,
                            'tps_prepa'     : line.workcenter_id.time_start, 
                            'cout_fab'      : line.workcenter_id.costs_hour, 
                            'tps_fab'       : line.is_nb_secondes,
                            'cout_total'    : cout_total, 
                        }
                        if line.workcenter_id.resource_type=='material':
                            self.detail_gamme_ma.append(vals)
                        else:
                            self.detail_gamme_mo.append(vals)




            #** Recherche de la gamme générique pour Cout Plasti-ka ************
            SQL="""
                select mb.is_gamme_generique_id
                from mrp_bom mb inner join product_product pp on pp.product_tmpl_id=mb.product_tmpl_id
                where pp.id="""+str(product.id)+ """ 
                order by mb.id
            """
            cr.execute(SQL)
            result = cr.fetchall()
            for row2 in result:
                routing_id = row2[0]
                if routing_id:
                    routing = self.env['mrp.routing'].browse(routing_id)
                    for line in routing.workcenter_lines:
                        cout_total=quantite_unitaire*line.workcenter_id.is_cout_pk*round(line.is_nb_secondes/3600,4)
                        vals={
                            'composant'     : '----------'[:niveau]+product.is_code,
                            'sequence'      : line.sequence,
                            'workcenter_id' : line.workcenter_id.id,
                            'quantite'      : quantite_unitaire,
                            'cout_prepa'    : line.workcenter_id.is_cout_pk,
                            'tps_prepa'     : line.workcenter_id.time_start, 
                            'cout_fab'      : line.workcenter_id.is_cout_pk, 
                            'tps_fab'       : line.is_nb_secondes,
                            'cout_total'    : cout_total, 
                        }
                        if line.workcenter_id.resource_type=='material':
                            self.detail_gamme_ma_pk.append(vals)
                        else:
                            self.detail_gamme_mo_pk.append(vals)
            #*******************************************************************

            #** Composants de la nomenclature **********************************
            SQL="""
                select mbl.product_id, mbl.product_uom, mbl.product_qty, ic.prix_calcule
                from mrp_bom mb inner join mrp_bom_line mbl on mbl.bom_id=mb.id
                                inner join product_product pp on pp.product_tmpl_id=mb.product_tmpl_id
                                inner join is_cout ic on ic.name=mbl.product_id
                where pp.id="""+str(product.id)+ """ 
                order by mbl.sequence, mbl.id
            """
            # TODO : Filtre sur ce critère ? => and (mb.is_sous_traitance='f' or mb.is_sous_traitance is null)
            cr.execute(SQL)
            result = cr.fetchall()
            niv=niveau+1
            for row2 in result:
                composant    = self.env['product.product'].browse(row2[0])
                unite        = row2[1]
                qt_unitaire  = row2[2]
                qt_total     = qt_unitaire*quantite_total
                prix_calcule = row2[3]
                self.nomenclature_prix_revient(cout_calcul_obj, niv, composant, unite, qt_unitaire, qt_total, prix_calcule)
            #*******************************************************************







    @api.multi
    def _productid2cout(self,product_id):
        cout_obj = self.env['is.cout']
        couts=cout_obj.search([('name', '=', product_id)])
        return couts


    @api.multi
    def _get_couts(self):
        couts=[]
        for obj in self:
            for row in obj.cout_actualise_ids:
                product=row.product_id
                res=self._productid2cout(product.id)
                for r in res:
                    couts.append(r)
        return couts


    @api.multi
    def _unlink_detail_cout(self,couts):
        """En regroupant la suppression de toutes les lignes, cela permet de gagner beaucoup de temps"""
        cr = self._cr
        if couts:
            ids = self._get_couts_ids(couts)
            if ids:
                ids=','.join(ids)
                SQL=''
                SQL+='DELETE FROM is_cout_nomenclature WHERE cout_id in('+ids+'); '
                SQL+='DELETE FROM is_cout_gamme_ma     WHERE cout_id in('+ids+'); '
                SQL+='DELETE FROM is_cout_gamme_mo     WHERE cout_id in('+ids+'); '
                SQL+='DELETE FROM is_cout_gamme_ma_pk  WHERE cout_id in('+ids+'); '
                SQL+='DELETE FROM is_cout_gamme_mo_pk  WHERE cout_id in('+ids+'); '
                cr.execute(SQL)


    @api.multi
    def _get_couts_ids(self,couts):
        """Retourne la liste des id des couts à partir des couts"""
        ids=[]
        for cout in couts:
            ids.append(str(cout.id))
        return ids


    @api.multi
    def _write_resultats(self):
        "Ecrit les résultats des calculs dans la page récapitulative"
        for obj in self:
            for row in obj.cout_actualise_ids:
                product=row.product_id
                couts=self._productid2cout(product.id)
                for cout in couts:
                    vals={}
                    vals['cout_act_matiere']     = cout.cout_act_matiere
                    vals['cout_act_machine']     = cout.cout_act_machine
                    vals['cout_act_mo']          = cout.cout_act_mo
                    vals['cout_act_st']          = cout.cout_act_st
                    vals['cout_act_total']       = cout.cout_act_total
                    row.write(vals)


    @api.multi
    def action_calcul_prix_revient(self):
        #pr=cProfile.Profile()
        #pr.enable()
        for obj in self:
            self._log("## DEBUT Calcul des prix de revient")
            nb=len(obj.cout_actualise_ids)
            ct=0
            couts = self._get_couts()
            self._unlink_detail_cout(couts)
            for cout in couts:



                product=cout.name
                ct=ct+1
                _logger.info(str(ct)+'/'+str(nb)+' : '+str(product.is_code))

                cout_act_matiere    = 0
                cout_act_st         = 0
                cout_act_condition  = 0
                cout_act_machine    = 0
                cout_act_machine_pk = 0
                cout_act_mo         = 0
                cout_act_mo_pk      = 0
                cout_act_total      = 0

                if cout.type_article=='A':
                    cout_act_matiere = cout.prix_calcule
                    cout_act_st      = 0
                if cout.type_article=='ST':
                    cout_act_matiere = 0
                    cout_act_st      = 0

                nb_err=0
                if cout.type_article!='A':
                    self.detail_nomenclature=[]
                    self.detail_gamme_ma=[]
                    self.detail_gamme_mo=[]
                    self.detail_gamme_ma_pk=[]
                    self.detail_gamme_mo_pk=[]

                    self.nomenclature_prix_revient(obj, 0, product, False, 1, 1, cout.prix_calcule)
                    for vals in self.detail_nomenclature:
                        if vals['msg_err']!='':
                            nb_err=nb_err+1
                        is_code=vals['is_code']
                        if is_code[:1]=="7":
                            cout_act_condition=cout_act_condition+vals['total_mat']
                        del vals['is_code']
                        vals['cout_id']=cout.id
                        cout_act_matiere = cout_act_matiere+vals['total_mat']



                        cout_act_st      = cout_act_st+vals['total_st']




                        res=self.env['is.cout.nomenclature'].create(vals)
                    vals={
                        'cout_id'     : cout.id,
                        'designation' : 'TOTAL  : ',
                        'total_mat'   : cout_act_matiere,
                        'total_st'    : cout_act_st,
                    }
                    res=self.env['is.cout.nomenclature'].create(vals)
                    vals={
                        'cout_id'     : cout.id,
                        'designation' : 'Conditionnement  : ',
                        'total_mat'   : cout_act_condition,
                    }
                    res=self.env['is.cout.nomenclature'].create(vals)

                    for vals in self.detail_gamme_ma:
                        vals['cout_id']=cout.id
                        res=self.env['is.cout.gamme.ma'].create(vals)
                        cout_act_machine = cout_act_machine+vals['cout_total']
                    for vals in self.detail_gamme_mo:
                        vals['cout_id']=cout.id
                        res=self.env['is.cout.gamme.mo'].create(vals)
                        cout_act_mo = cout_act_mo+vals['cout_total']

                    for vals in self.detail_gamme_ma_pk:
                        vals['cout_id']=cout.id
                        res=self.env['is.cout.gamme.ma.pk'].create(vals)
                        cout_act_machine_pk = cout_act_machine_pk+vals['cout_total']
                    for vals in self.detail_gamme_mo_pk:
                        vals['cout_id']=cout.id
                        res=self.env['is.cout.gamme.mo.pk'].create(vals)
                        cout_act_mo_pk = cout_act_mo_pk+vals['cout_total']

                vals={}
                #Client par défaut
                for row in product.is_client_ids:
                    if row.client_defaut:
                        vals['partner_id']=row.client_id.id
                vals['nb_err'] = nb_err
                if nb_err>0:
                    cout_act_matiere=0
                cout_act_total=cout_act_matiere+cout_act_machine+cout_act_mo+cout_act_st
                vals['cout_act_matiere']    = cout_act_matiere
                vals['cout_act_condition']  = cout_act_condition
                vals['cout_act_machine']    = cout_act_machine
                vals['cout_act_mo']         = cout_act_mo
                vals['cout_act_machine_pk'] = cout_act_machine_pk
                vals['cout_act_mo_pk']      = cout_act_mo_pk
                vals['cout_act_st']         = cout_act_st
                vals['cout_act_total']      = cout_act_total
                vals['is_category_id']      = product.is_category_id.id
                vals['is_gestionnaire_id']  = product.is_gestionnaire_id.id
                vals['is_mold_id']          = product.is_mold_id.id
                vals['is_mold_dossierf']    = product.is_mold_dossierf
                vals['uom_id']              = product.uom_id.id
                vals['lot_mini']            = product.lot_mini
                vals['cout_act_prix_vente'] = cout.prix_vente-cout.amortissement_moule-cout.surcout_pre_serie
                cout.write(vals)
            self._write_resultats()
            obj.state="termine"
            self._log("## FIN Calcul des prix de revient")
コード例 #10
0
ファイル: fec.py プロジェクト: Infinityglobalsolutions/odoo9
class AccountFrFec(models.TransientModel):
    _name = 'account.fr.fec'
    _description = 'Ficher Echange Informatise'

    date_from = fields.Date(string='Start Date', required=True)
    date_to = fields.Date(string='End Date', required=True)
    fec_data = fields.Binary('FEC File', readonly=True)
    filename = fields.Char(string='Filename', size=256, readonly=True)
    export_type = fields.Selection([
        ('official', 'Official FEC report (posted entries only)'),
        ('nonofficial', 'Non-official FEC report (posted and unposted entries)'),
        ], string='Export Type', required=True, default='official')

    @api.multi
    def generate_fec(self):
        self.ensure_one()
        # We choose to implement the flat file instead of the XML
        # file for 2 reasons :
        # 1) the XSD file impose to have the label on the account.move
        # but Odoo has the label on the account.move.line, so that's a
        # problem !
        # 2) CSV files are easier to read/use for a regular accountant.
        # So it will be easier for the accountant to check the file before
        # sending it to the fiscal administration
        header = [
            'JournalCode',    # 0
            'JournalLib',     # 1
            'EcritureNum',    # 2
            'EcritureDate',   # 3
            'CompteNum',      # 4
            'CompteLib',      # 5
            'CompAuxNum',     # 6  We use partner.id
            'CompAuxLib',     # 7
            'PieceRef',       # 8
            'PieceDate',      # 9
            'EcritureLib',    # 10
            'Debit',          # 11
            'Credit',         # 12
            'EcritureLet',    # 13
            'DateLet',        # 14
            'ValidDate',      # 15
            'Montantdevise',  # 16
            'Idevise',        # 17
            ]

        company = self.env.user.company_id
        if not company.vat:
            raise Warning(
                _("Missing VAT number for company %s") % company.name)
        if company.vat[0:2] != 'FR':
            raise Warning(
                _("FEC is for French companies only !"))

        fecfile = StringIO.StringIO()
        w = csv.writer(fecfile, delimiter='|')
        w.writerow(header)

        # INITIAL BALANCE
        sql_query = '''
        SELECT
            'OUV' AS JournalCode,
            'Balance initiale' AS JournalLib,
            'Balance initiale ' || MIN(aa.name) AS EcritureNum,
            %s AS EcritureDate,
            MIN(aa.code) AS CompteNum,
            replace(MIN(aa.name), '|', '/') AS CompteLib,
            '' AS CompAuxNum,
            '' AS CompAuxLib,
            '-' AS PieceRef,
            %s AS PieceDate,
            '/' AS EcritureLib,
            replace(CASE WHEN sum(aml.balance) <= 0 THEN '0,00' ELSE to_char(SUM(aml.balance), '999999999999999D99') END, '.', ',') AS Debit,
            replace(CASE WHEN sum(aml.balance) >= 0 THEN '0,00' ELSE to_char(-SUM(aml.balance), '999999999999999D99') END, '.', ',') AS Credit,
            '' AS EcritureLet,
            '' AS DateLet,
            %s AS ValidDate,
            '' AS Montantdevise,
            '' AS Idevise
        FROM
            account_move_line aml
            LEFT JOIN account_move am ON am.id=aml.move_id
            JOIN account_account aa ON aa.id = aml.account_id
        WHERE
            am.date < %s
            AND am.company_id = %s
            AND (aml.debit != 0 OR aml.credit != 0)
        '''

        # For official report: only use posted entries
        if self.export_type == "official":
            sql_query += '''
            AND am.state = 'posted'
            '''

        sql_query += '''
        GROUP BY aml.account_id
        '''
        formatted_date_from = self.date_from.replace('-', '')
        self._cr.execute(
            sql_query, (formatted_date_from, formatted_date_from, formatted_date_from, self.date_from, company.id))

        for row in self._cr.fetchall():
            listrow = list(row)
            w.writerow([s.encode("utf-8") for s in listrow])

        # LINES
        sql_query = '''
        SELECT
            replace(aj.code, '|', '/') AS JournalCode,
            replace(aj.name, '|', '/') AS JournalLib,
            replace(am.name, '|', '/') AS EcritureNum,
            TO_CHAR(am.date, 'YYYYMMDD') AS EcritureDate,
            aa.code AS CompteNum,
            replace(aa.name, '|', '/') AS CompteLib,
            CASE WHEN rp.ref IS null OR rp.ref = ''
            THEN COALESCE('ID ' || rp.id, '')
            ELSE rp.ref
            END
            AS CompAuxNum,
            COALESCE(replace(rp.name, '|', '/'), '') AS CompAuxLib,
            CASE WHEN am.ref IS null OR am.ref = ''
            THEN '-'
            ELSE replace(am.ref, '|', '/')
            END
            AS PieceRef,
            TO_CHAR(am.date, 'YYYYMMDD') AS PieceDate,
            CASE WHEN aml.name IS NULL THEN '/' ELSE replace(aml.name, '|', '/') END AS EcritureLib,
            replace(CASE WHEN aml.debit = 0 THEN '0,00' ELSE to_char(aml.debit, '999999999999999D99') END, '.', ',') AS Debit,
            replace(CASE WHEN aml.credit = 0 THEN '0,00' ELSE to_char(aml.credit, '999999999999999D99') END, '.', ',') AS Credit,
            CASE WHEN rec.name IS NULL THEN '' ELSE rec.name END AS EcritureLet,
            CASE WHEN aml.full_reconcile_id IS NULL THEN '' ELSE TO_CHAR(rec.create_date, 'YYYYMMDD') END AS DateLet,
            TO_CHAR(am.date, 'YYYYMMDD') AS ValidDate,
            CASE
                WHEN aml.amount_currency IS NULL OR aml.amount_currency = 0 THEN ''
                ELSE replace(to_char(aml.amount_currency, '999999999999999D99'), '.', ',')
            END AS Montantdevise,
            CASE WHEN aml.currency_id IS NULL THEN '' ELSE rc.name END AS Idevise
        FROM
            account_move_line aml
            LEFT JOIN account_move am ON am.id=aml.move_id
            LEFT JOIN res_partner rp ON rp.id=aml.partner_id
            JOIN account_journal aj ON aj.id = am.journal_id
            JOIN account_account aa ON aa.id = aml.account_id
            LEFT JOIN res_currency rc ON rc.id = aml.currency_id
            LEFT JOIN account_full_reconcile rec ON rec.id = aml.full_reconcile_id
        WHERE
            am.date >= %s
            AND am.date <= %s
            AND am.company_id = %s
            AND (aml.debit != 0 OR aml.credit != 0)
        '''

        # For official report: only use posted entries
        if self.export_type == "official":
            sql_query += '''
            AND am.state = 'posted'
            '''

        sql_query += '''
        ORDER BY
            am.date,
            am.name,
            aml.id
        '''
        self._cr.execute(
            sql_query, (self.date_from, self.date_to, company.id))

        for row in self._cr.fetchall():
            listrow = list(row)
            w.writerow([s.encode("utf-8") for s in listrow])

        siren = company.vat[4:13]
        end_date = self.date_to.replace('-', '')
        suffix = ''
        if self.export_type == "nonofficial":
            suffix = '-NONOFFICIAL'
        fecvalue = fecfile.getvalue()
        self.write({
            'fec_data': base64.encodestring(fecvalue),
            # Filename = <siren>FECYYYYMMDD where YYYMMDD is the closing date
            'filename': '%sFEC%s%s.csv' % (siren, end_date, suffix),
            })
        fecfile.close()

        action = {
            'name': 'FEC',
            'type': 'ir.actions.act_url',
            'url': "web/content/?model=account.fr.fec&id=" + str(self.id) + "&filename_field=filename&field=fec_data&download=true&filename=" + self.filename,
            'target': 'self',
            }
        return action
コード例 #11
0
class ComunicazioneLiquidazione(models.Model):
    _name = 'comunicazione.liquidazione'
    _description = 'Comunicazione Liquidazione IVA'

    @api.model
    def _default_company(self):
        company_id = self._context.get('company_id',
                                       self.env.user.company_id.id)
        return company_id

    @api.constrains('identificativo')
    def _check_identificativo(self):
        domain = [('identificativo', '=', self.identificativo)]
        dichiarazioni = self.search(domain)
        if len(dichiarazioni) > 1:
            raise ValidationError(
                _("Dichiarazione già esiste con identificativo {}").format(
                    self.identificativo))

    @api.multi
    def _compute_name(self):
        for dich in self:
            name = ""
            for quadro in dich.quadri_vp_ids:
                if not name:
                    period_type = ''
                    if quadro.period_type == 'month':
                        period_type = _('month')
                    else:
                        period_type = _('quarter')
                    name += '{} {}'.format(str(dich.year), period_type)
                if quadro.period_type == 'month':
                    name += ', {}'.format(str(quadro.month))
                else:
                    name += ', {}'.format(str(quadro.quarter))
            dich.name = name

    def _get_identificativo(self):
        dichiarazioni = self.search([])
        if dichiarazioni:
            return len(dichiarazioni) + 1
        else:
            return 1

    company_id = fields.Many2one('res.company',
                                 string='Company',
                                 required=True,
                                 default=_default_company)
    identificativo = fields.Integer(string='Identificativo',
                                    default=_get_identificativo)
    name = fields.Char(string='Name', compute="_compute_name")
    year = fields.Integer(string='Year', required=True, size=4)
    last_month = fields.Integer(string='Last month')
    liquidazione_del_gruppo = fields.Boolean(string='Liquidazione del gruppo')
    taxpayer_vat = fields.Char(string='Vat', required=True)
    controller_vat = fields.Char(string='Controller Vat')
    taxpayer_fiscalcode = fields.Char(string='Fiscalcode')
    declarant_different = fields.Boolean(
        string='Declarant different from taxpayer')
    declarant_fiscalcode = fields.Char(string='Fiscalcode')
    declarant_fiscalcode_company = fields.Char(string='Fiscalcode company')
    codice_carica_id = fields.Many2one('codice.carica', string='Codice carica')
    declarant_sign = fields.Boolean(string='Declarant sign', default=True)

    delegate_fiscalcode = fields.Char(string='Fiscalcode')
    delegate_commitment = fields.Selection(
        [('1', 'Comunicazione è stata predisposta dal contribuente '),
         ('2', 'Comunicazione è stata predisposta da chi effettua l’invio')],
        string='Commitment')
    delegate_sign = fields.Boolean(string='Delegate sign')
    date_commitment = fields.Date(string='Date commitment')
    quadri_vp_ids = fields.One2many('comunicazione.liquidazione.vp',
                                    'comunicazione_id',
                                    string="Quadri VP")
    iva_da_versare = fields.Float(string='IVA da versare', readonly=True)
    iva_a_credito = fields.Float(string='IVA a credito', readonly=True)

    @api.model
    def create(self, vals):
        comunicazione = super(ComunicazioneLiquidazione, self).create(vals)
        comunicazione._validate()
        return comunicazione

    @api.multi
    def write(self, vals):
        super(ComunicazioneLiquidazione, self).write(vals)
        for comunicazione in self:
            comunicazione._validate()
        return True

    @api.onchange('company_id')
    def onchange_company_id(self):
        if self.company_id:
            if self.company_id.partner_id.vat:
                self.taxpayer_vat = self.company_id.partner_id.vat[2:]
            else:
                self.taxpayer_vat = ''
            self.taxpayer_fiscalcode = \
                self.company_id.partner_id.fiscalcode

    def get_export_xml(self):
        self._validate()
        x1_Fornitura = self._export_xml_get_fornitura()

        x1_1_Intestazione = self._export_xml_get_intestazione()

        attrs = {'identificativo': str(self.identificativo).zfill(5)}
        x1_2_Comunicazione = etree.Element(etree.QName(NS_IV, "Comunicazione"),
                                           attrs)
        x1_2_1_Frontespizio = self._export_xml_get_frontespizio()
        x1_2_Comunicazione.append(x1_2_1_Frontespizio)

        x1_2_2_DatiContabili = etree.Element(
            etree.QName(NS_IV, "DatiContabili"))
        nr_modulo = 0
        for quadro in self.quadri_vp_ids:
            nr_modulo += 1
            modulo = self.with_context(nr_modulo=nr_modulo)\
                ._export_xml_get_dati_modulo(quadro)
            x1_2_2_DatiContabili.append(modulo)
        x1_2_Comunicazione.append(x1_2_2_DatiContabili)
        # Composizione struttura xml con le varie sezioni generate
        x1_Fornitura.append(x1_1_Intestazione)
        x1_Fornitura.append(x1_2_Comunicazione)

        xml_string = etree.tostring(x1_Fornitura,
                                    encoding='utf8',
                                    method='xml',
                                    pretty_print=True)
        return xml_string

    def _validate(self):
        """
        Controllo congruità dati della comunicazione
        """
        # Anno obbligatorio
        if not self.year:
            raise ValidationError(_("Year required"))

        # Codice Fiscale
        if not self.taxpayer_fiscalcode \
                or len(self.taxpayer_fiscalcode) not in [11, 16]:
            raise ValidationError(
                _("Taxpayer Fiscalcode is required. It's accepted codes \
                    with lenght 11 or 16 chars"))

        # Codice Fiscale dichiarante Obbligatorio se il codice fiscale
        # del contribuente è di 11 caratteri
        if self.taxpayer_fiscalcode  and len(self.taxpayer_fiscalcode) == 11\
                and not self.declarant_fiscalcode:
            raise ValidationError(
                _("Declarant Fiscalcode is required. You can enable the \
                section with different declarant option"))

        # LiquidazioneGruppo: elemento opzionale, di tipo DatoCB_Type.
        # Se presente non deve essere presente l’elemento PIVAControllante.
        # Non può essere presente se l’elemento CodiceFiscale è lungo 16
        # caratteri.
        if self.liquidazione_del_gruppo:
            if self.controller_vat:
                raise ValidationError(
                    _("Per liquidazione del gruppo, partita iva controllante\
                     deve essere vuota"))
            if len(self.taxpayer_fiscalcode) == 16:
                raise ValidationError(
                    _("Liquidazione del gruppo non valida, visto il codice\
                     fiscale di 16 caratteri"))
        # CodiceCaricaDichiarante
        if self.declarant_fiscalcode:
            if not self.codice_carica_id:
                raise ValidationError(
                    _("Indicare il codice carica del dichiarante"))
        # CodiceFiscaleSocieta:
        # Obbligatori per codice carica 9
        if self.codice_carica_id and self.codice_carica_id.code == '9':
            if not self.declarant_fiscalcode_company:
                raise ValidationError(
                    _("Visto il codice carica, occorre indicare il codice \
                    fiscale della socità dichiarante"))
        # ImpegnoPresentazione::
        if self.delegate_fiscalcode:
            if not self.delegate_commitment:
                raise ValidationError(
                    _("Visto il codice fiscale dell'intermediario, occorre \
                    indicare il codice l'impegno"))
            if not self.date_commitment:
                raise ValidationError(
                    _("Visto il codice fiscale dell'intermediario, occorre \
                    indicare la data dell'impegno"))
        # ImpegnoPresentazione::
        if self.delegate_fiscalcode and not self.delegate_sign:
            raise ValidationError(
                _("In presenza dell'incaricato nella sezione impegno \
                    alla presentazione telematica, è necessario vistare \
                    l'opzione firma dell'incaricato"))
        return True

    def _export_xml_get_fornitura(self):
        x1_Fornitura = etree.Element(etree.QName(NS_IV, "Fornitura"),
                                     nsmap=NS_MAP)
        return x1_Fornitura

    def _export_xml_validate(self):
        return True

    def _export_xml_get_intestazione(self):
        x1_1_Intestazione = etree.Element(etree.QName(NS_IV, "Intestazione"))
        # Codice Fornitura
        x1_1_1_CodiceFornitura = etree.SubElement(
            x1_1_Intestazione, etree.QName(NS_IV, "CodiceFornitura"))
        code = str(self.year)[-2:]
        x1_1_1_CodiceFornitura.text = unicode('IVP{}'.format(code))
        # Codice Fiscale Dichiarante
        if self.declarant_fiscalcode:
            x1_1_2_CodiceFiscaleDichiarante = etree.SubElement(
                x1_1_Intestazione,
                etree.QName(NS_IV, "CodiceFiscaleDichiarante"))
            x1_1_2_CodiceFiscaleDichiarante.text = unicode(
                self.declarant_fiscalcode)
        # Codice Carica
        if self.codice_carica_id:
            x1_1_3_CodiceCarica = etree.SubElement(
                x1_1_Intestazione, etree.QName(NS_IV, "CodiceCarica"))
            x1_1_3_CodiceCarica.text = unicode(self.codice_carica_id.code)
        return x1_1_Intestazione

    def _export_xml_get_frontespizio(self):
        x1_2_1_Frontespizio = etree.Element(etree.QName(NS_IV, "Frontespizio"))
        # Codice Fiscale
        x1_2_1_1_CodiceFiscale = etree.SubElement(
            x1_2_1_Frontespizio, etree.QName(NS_IV, "CodiceFiscale"))
        x1_2_1_1_CodiceFiscale.text = unicode(self.taxpayer_fiscalcode) \
            if self.taxpayer_fiscalcode else ''
        # Anno Imposta
        x1_2_1_2_AnnoImposta = etree.SubElement(
            x1_2_1_Frontespizio, etree.QName(NS_IV, "AnnoImposta"))
        x1_2_1_2_AnnoImposta.text = str(self.year)
        # Partita IVA
        x1_2_1_3_PartitaIVA = etree.SubElement(
            x1_2_1_Frontespizio, etree.QName(NS_IV, "PartitaIVA"))
        x1_2_1_3_PartitaIVA.text = self.taxpayer_vat
        # PIVA Controllante
        if self.controller_vat:
            x1_2_1_4_PIVAControllante = etree.SubElement(
                x1_2_1_Frontespizio, etree.QName(NS_IV, "PIVAControllante"))
            x1_2_1_4_PIVAControllante.text = self.controller_vat
        # Ultimo Mese
        if self.last_month:
            x1_2_1_5_UltimoMese = etree.SubElement(
                x1_2_1_Frontespizio, etree.QName(NS_IV, "UltimoMese"))
            x1_2_1_5_UltimoMese.text = self.last_month
        # Liquidazione Gruppo
        x1_2_1_6_LiquidazioneGruppo = etree.SubElement(
            x1_2_1_Frontespizio, etree.QName(NS_IV, "LiquidazioneGruppo"))
        x1_2_1_6_LiquidazioneGruppo.text = \
            '1' if self.liquidazione_del_gruppo else '0'
        # CF Dichiarante
        if self.declarant_fiscalcode:
            x1_2_1_7_CFDichiarante = etree.SubElement(
                x1_2_1_Frontespizio, etree.QName(NS_IV, "CFDichiarante"))
            x1_2_1_7_CFDichiarante.text = self.declarant_fiscalcode
        # CodiceCaricaDichiarante
        if self.codice_carica_id:
            x1_2_1_8_CodiceCaricaDichiarante = etree.SubElement(
                x1_2_1_Frontespizio,
                etree.QName(NS_IV, "CodiceCaricaDichiarante"))
            x1_2_1_8_CodiceCaricaDichiarante.text = self.codice_carica_id.code
        # CodiceFiscaleSocieta
        if self.declarant_fiscalcode_company:
            x1_2_1_9_CodiceFiscaleSocieta = etree.SubElement(
                x1_2_1_Frontespizio, etree.QName(NS_IV,
                                                 "CodiceFiscaleSocieta"))
            x1_2_1_9_CodiceFiscaleSocieta.text =\
                self.declarant_fiscalcode_company.code
        # FirmaDichiarazione
        x1_2_1_10_FirmaDichiarazione = etree.SubElement(
            x1_2_1_Frontespizio, etree.QName(NS_IV, "FirmaDichiarazione"))
        x1_2_1_10_FirmaDichiarazione.text = '1' if self.declarant_sign else '0'
        # CFIntermediario
        if self.delegate_fiscalcode:
            x1_2_1_11_CFIntermediario = etree.SubElement(
                x1_2_1_Frontespizio, etree.QName(NS_IV, "CFIntermediario"))
            x1_2_1_11_CFIntermediario.text = self.delegate_fiscalcode
        # ImpegnoPresentazione
        if self.delegate_commitment:
            x1_2_1_12_ImpegnoPresentazione = etree.SubElement(
                x1_2_1_Frontespizio, etree.QName(NS_IV,
                                                 "ImpegnoPresentazione"))
            x1_2_1_12_ImpegnoPresentazione.text = self.delegate_commitment
        # DataImpegno
        if self.date_commitment:
            x1_2_1_13_DataImpegno = etree.SubElement(
                x1_2_1_Frontespizio, etree.QName(NS_IV, "DataImpegno"))
            x1_2_1_13_DataImpegno.text = datetime.strptime(
                self.date_commitment, "%Y-%m-%d").strftime('%d%m%Y')
        # FirmaIntermediario
        if self.delegate_fiscalcode:
            x1_2_1_14_FirmaIntermediario = etree.SubElement(
                x1_2_1_Frontespizio, etree.QName(NS_IV, "FirmaIntermediario"))
            x1_2_1_14_FirmaIntermediario.text =\
                '1' if self.delegate_sign else '0'

        return x1_2_1_Frontespizio

    def _export_xml_get_dati_modulo(self, quadro):
        # 1.2.2.1 Modulo
        xModulo = etree.Element(etree.QName(NS_IV, "Modulo"))
        # Numero Modulo
        NumeroModulo = etree.SubElement(xModulo,
                                        etree.QName(NS_IV, "NumeroModulo"))
        NumeroModulo.text = str(self._context.get('nr_modulo', 1))

        if quadro.period_type == 'month':
            # 1.2.2.1.1 Mese
            Mese = etree.SubElement(xModulo, etree.QName(NS_IV, "Mese"))
            Mese.text = str(quadro.month)
        else:
            # 1.2.2.1.2 Trimestre
            Trimestre = etree.SubElement(xModulo,
                                         etree.QName(NS_IV, "Trimestre"))
            Trimestre.text = str(quadro.quarter)
        # Da escludere per liquidazione del gruppo
        if not self.liquidazione_del_gruppo:
            # 1.2.2.1.3 Subfornitura
            if quadro.subcontracting:
                Subfornitura = etree.SubElement(
                    xModulo, etree.QName(NS_IV, "Subfornitura"))
                Subfornitura.text = '1' if quadro.subcontracting \
                    else '0'
            # 1.2.2.1.4 EventiEccezionali
            if quadro.exceptional_events:
                EventiEccezionali = etree.SubElement(
                    xModulo, etree.QName(NS_IV, "EventiEccezionali"))
                EventiEccezionali.text = quadro.exceptional_events
            # 1.2.2.1.5 TotaleOperazioniAttive
            TotaleOperazioniAttive = etree.SubElement(
                xModulo, etree.QName(NS_IV, "TotaleOperazioniAttive"))
            TotaleOperazioniAttive.text = "{:.2f}"\
                .format(quadro.imponibile_operazioni_attive).replace('.', ',')
            # 1.2.2.1.6  TotaleOperazioniPassive
            TotaleOperazioniPassive = etree.SubElement(
                xModulo, etree.QName(NS_IV, "TotaleOperazioniPassive"))
            TotaleOperazioniPassive.text = "{:.2f}"\
                .format(quadro.imponibile_operazioni_passive).replace('.', ',')
        # 1.2.2.1.7  IvaEsigibile
        IvaEsigibile = etree.SubElement(xModulo,
                                        etree.QName(NS_IV, "IvaEsigibile"))
        IvaEsigibile.text = "{:.2f}".format(quadro.iva_esigibile)\
            .replace('.', ',')
        # 1.2.2.1.8  IvaDetratta
        IvaDetratta = etree.SubElement(xModulo,
                                       etree.QName(NS_IV, "IvaDetratta"))
        IvaDetratta.text = "{:.2f}".format(quadro.iva_detratta)\
            .replace('.', ',')
        # 1.2.2.1.9  IvaDovuta
        if quadro.iva_dovuta_debito:
            IvaDovuta = etree.SubElement(xModulo,
                                         etree.QName(NS_IV, "IvaDovuta"))
            IvaDovuta.text = "{:.2f}".format(quadro.iva_dovuta_debito)\
                .replace('.', ',')
        # 1.2.2.1.10  IvaCredito
        if quadro.iva_dovuta_credito:
            IvaCredito = etree.SubElement(xModulo,
                                          etree.QName(NS_IV, "IvaCredito"))
            IvaCredito.text = "{:.2f}".format(quadro.iva_dovuta_credito)\
                .replace('.', ',')
        # 1.2.2.1.11 DebitoPrecedente
        DebitoPrecedente = etree.SubElement(
            xModulo, etree.QName(NS_IV, "DebitoPrecedente"))
        DebitoPrecedente.text = "{:.2f}".format(
            quadro.debito_periodo_precedente).replace('.', ',')
        # 1.2.2.1.12 CreditoPeriodoPrecedente
        CreditoPeriodoPrecedente = etree.SubElement(
            xModulo, etree.QName(NS_IV, "CreditoPeriodoPrecedente"))
        CreditoPeriodoPrecedente.text = "{:.2f}".format(
            quadro.credito_periodo_precedente).replace('.', ',')
        # 1.2.2.1.13 CreditoAnnoPrecedente
        CreditoAnnoPrecedente = etree.SubElement(
            xModulo, etree.QName(NS_IV, "CreditoAnnoPrecedente"))
        CreditoAnnoPrecedente.text = "{:.2f}".format(
            quadro.credito_anno_precedente).replace('.', ',')
        # 1.2.2.1.14 VersamentiAutoUE
        VersamentiAutoUE = etree.SubElement(
            xModulo, etree.QName(NS_IV, "VersamentiAutoUE"))
        VersamentiAutoUE.text = "{:.2f}".format(
            quadro.versamento_auto_UE).replace('.', ',')
        # 1.2.2.1.15 CreditiImposta
        CreditiImposta = etree.SubElement(xModulo,
                                          etree.QName(NS_IV, "CreditiImposta"))
        CreditiImposta.text = "{:.2f}".format(quadro.crediti_imposta).replace(
            '.', ',')
        # 1.2.2.1.16 InteressiDovuti
        InteressiDovuti = etree.SubElement(
            xModulo, etree.QName(NS_IV, "InteressiDovuti"))
        InteressiDovuti.text = "{:.2f}".format(
            quadro.interessi_dovuti).replace('.', ',')
        # 1.2.2.1.17 Acconto
        Acconto = etree.SubElement(xModulo, etree.QName(NS_IV, "Acconto"))
        Acconto.text = "{:.2f}".format(quadro.accounto_dovuto).replace(
            '.', ',')
        # 1.2.2.1.18 ImportoDaVersare
        ImportoDaVersare = etree.SubElement(
            xModulo, etree.QName(NS_IV, "ImportoDaVersare"))
        ImportoDaVersare.text = "{:.2f}".format(quadro.iva_da_versare).replace(
            '.', ',')
        # 1.2.2.1.19 ImportoACredito
        ImportoACredito = etree.SubElement(
            xModulo, etree.QName(NS_IV, "ImportoACredito"))
        ImportoACredito.text = "{:.2f}".format(quadro.iva_a_credito).replace(
            '.', ',')

        return xModulo
コード例 #12
0
ファイル: sale.py プロジェクト: eksotama/OCB
class SaleOrderLine(models.Model):
    _name = 'sale.order.line'
    _description = 'Sales Order Line'
    _order = 'order_id desc, sequence, id'

    @api.depends('state', 'product_uom_qty', 'qty_delivered', 'qty_to_invoice',
                 'qty_invoiced')
    def _compute_invoice_status(self):
        """
        Compute the invoice status of a SO line. Possible statuses:
        - no: if the SO is not in status 'sale' or 'done', we consider that there is nothing to
          invoice. This is also hte default value if the conditions of no other status is met.
        - to invoice: we refer to the quantity to invoice of the line. Refer to method
          `_get_to_invoice_qty()` for more information on how this quantity is calculated.
        - upselling: this is possible only for a product invoiced on ordered quantities for which
          we delivered more than expected. The could arise if, for example, a project took more
          time than expected but we decided not to invoice the extra cost to the client. This
          occurs onyl in state 'sale', so that when a SO is set to done, the upselling opportunity
          is removed from the list.
        - invoiced: the quantity invoiced is larger or equal to the quantity ordered.
        """
        precision = self.env['decimal.precision'].precision_get(
            'Product Unit of Measure')
        for line in self:
            if line.state not in ('sale', 'done'):
                line.invoice_status = 'no'
            elif not float_is_zero(line.qty_to_invoice,
                                   precision_digits=precision):
                line.invoice_status = 'to invoice'
            elif line.state == 'sale' and line.product_id.invoice_policy == 'order' and\
                    float_compare(line.qty_delivered, line.product_uom_qty, precision_digits=precision) == 1:
                line.invoice_status = 'upselling'
            elif float_compare(line.qty_invoiced,
                               line.product_uom_qty,
                               precision_digits=precision) >= 0:
                line.invoice_status = 'invoiced'
            else:
                line.invoice_status = 'no'

    @api.depends('product_uom_qty', 'discount', 'price_unit', 'tax_id')
    def _compute_amount(self):
        """
        Compute the amounts of the SO line.
        """
        for line in self:
            price = line.price_unit * (1 - (line.discount or 0.0) / 100.0)
            taxes = line.tax_id.compute_all(price,
                                            line.order_id.currency_id,
                                            line.product_uom_qty,
                                            product=line.product_id,
                                            partner=line.order_id.partner_id)
            line.update({
                'price_tax':
                taxes['total_included'] - taxes['total_excluded'],
                'price_total':
                taxes['total_included'],
                'price_subtotal':
                taxes['total_excluded'],
            })

    @api.depends('product_id.invoice_policy', 'order_id.state')
    def _compute_qty_delivered_updateable(self):
        for line in self:
            line.qty_delivered_updateable = line.product_id.invoice_policy in (
                'order', 'delivery'
            ) and line.order_id.state == 'sale' and line.product_id.track_service == 'manual'

    @api.depends('qty_invoiced', 'qty_delivered', 'product_uom_qty',
                 'order_id.state')
    def _get_to_invoice_qty(self):
        """
        Compute the quantity to invoice. If the invoice policy is order, the quantity to invoice is
        calculated from the ordered quantity. Otherwise, the quantity delivered is used.
        """
        for line in self:
            if line.order_id.state in ['sale', 'done']:
                if line.product_id.invoice_policy == 'order':
                    line.qty_to_invoice = line.product_uom_qty - line.qty_invoiced
                else:
                    line.qty_to_invoice = line.qty_delivered - line.qty_invoiced
            else:
                line.qty_to_invoice = 0

    @api.depends('invoice_lines.invoice_id.state', 'invoice_lines.quantity')
    def _get_invoice_qty(self):
        """
        Compute the quantity invoiced. If case of a refund, the quantity invoiced is decreased. Note
        that this is the case only if the refund is generated from the SO and that is intentional: if
        a refund made would automatically decrease the invoiced quantity, then there is a risk of reinvoicing
        it automatically, which may not be wanted at all. That's why the refund has to be created from the SO
        """
        for line in self:
            qty_invoiced = 0.0
            for invoice_line in line.invoice_lines:
                if invoice_line.invoice_id.state != 'cancel':
                    if invoice_line.invoice_id.type == 'out_invoice':
                        qty_invoiced += invoice_line.quantity
                    elif invoice_line.invoice_id.type == 'out_refund':
                        qty_invoiced -= invoice_line.quantity
            line.qty_invoiced = qty_invoiced

    @api.depends('price_subtotal', 'product_uom_qty')
    def _get_price_reduce(self):
        for line in self:
            line.price_reduce = line.price_subtotal / line.product_uom_qty if line.product_uom_qty else 0.0

    @api.multi
    def _compute_tax_id(self):
        for line in self:
            fpos = line.order_id.fiscal_position_id or line.order_id.partner_id.property_account_position_id
            if fpos:
                # The superuser is used by website_sale in order to create a sale order. We need to make
                # sure we only select the taxes related to the company of the partner. This should only
                # apply if the partner is linked to a company.
                if self.env.uid == SUPERUSER_ID and line.order_id.company_id:
                    taxes = fpos.map_tax(line.product_id.taxes_id).filtered(
                        lambda r: r.company_id == line.order_id.company_id)
                else:
                    taxes = fpos.map_tax(line.product_id.taxes_id)
                line.tax_id = taxes
            else:
                line.tax_id = line.product_id.taxes_id if line.product_id.taxes_id else False

    @api.multi
    def _prepare_order_line_procurement(self, group_id=False):
        self.ensure_one()
        return {
            'name':
            self.name,
            'origin':
            self.order_id.name,
            'date_planned':
            datetime.strptime(self.order_id.date_order,
                              DEFAULT_SERVER_DATETIME_FORMAT) +
            timedelta(days=self.customer_lead),
            'product_id':
            self.product_id.id,
            'product_qty':
            self.product_uom_qty,
            'product_uom':
            self.product_uom.id,
            'company_id':
            self.order_id.company_id.id,
            'group_id':
            group_id,
            'sale_line_id':
            self.id
        }

    @api.multi
    def _action_procurement_create(self):
        """
        Create procurements based on quantity ordered. If the quantity is increased, new
        procurements are created. If the quantity is decreased, no automated action is taken.
        """
        precision = self.env['decimal.precision'].precision_get(
            'Product Unit of Measure')
        new_procs = self.env['procurement.order']  #Empty recordset
        for line in self:
            if line.state != 'sale' or not line.product_id._need_procurement():
                continue
            qty = 0.0
            for proc in line.procurement_ids:
                qty += proc.product_qty
            if float_compare(qty,
                             line.product_uom_qty,
                             precision_digits=precision) >= 0:
                return False

            if not line.order_id.procurement_group_id:
                vals = line.order_id._prepare_procurement_group()
                line.order_id.procurement_group_id = self.env[
                    "procurement.group"].create(vals)

            vals = line._prepare_order_line_procurement(
                group_id=line.order_id.procurement_group_id.id)
            vals['product_qty'] = line.product_uom_qty - qty
            new_proc = self.env["procurement.order"].create(vals)
            new_procs += new_proc
        new_procs.run()
        return new_procs

    @api.model
    def _get_analytic_invoice_policy(self):
        return ['cost']

    @api.model
    def _get_analytic_track_service(self):
        return []

    @api.model
    def create(self, values):
        line = super(SaleOrderLine, self).create(values)
        if line.state == 'sale':
            if line.product_id.track_service in self._get_analytic_track_service(
            ) or line.product_id.invoice_policy in self._get_analytic_invoice_policy(
            ) and not line.order_id.project_id:
                line.order_id._create_analytic_account()
            line._action_procurement_create()

        return line

    @api.multi
    def write(self, values):
        lines = False
        if 'product_uom_qty' in values:
            precision = self.env['decimal.precision'].precision_get(
                'Product Unit of Measure')
            lines = self.filtered(
                lambda r: r.state == 'sale' and float_compare(
                    r.product_uom_qty,
                    values['product_uom_qty'],
                    precision_digits=precision) == -1)
        result = super(SaleOrderLine, self).write(values)
        if lines:
            lines._action_procurement_create()
        return result

    order_id = fields.Many2one('sale.order',
                               string='Order Reference',
                               required=True,
                               ondelete='cascade',
                               index=True,
                               copy=False)
    name = fields.Text(string='Description', required=True)
    sequence = fields.Integer(string='Sequence', default=10)

    invoice_lines = fields.Many2many('account.invoice.line',
                                     'sale_order_line_invoice_rel',
                                     'order_line_id',
                                     'invoice_line_id',
                                     string='Invoice Lines',
                                     copy=False)
    invoice_status = fields.Selection([('upselling', 'Upselling Opportunity'),
                                       ('invoiced', 'Fully Invoiced'),
                                       ('to invoice', 'To Invoice'),
                                       ('no', 'Nothing to Invoice')],
                                      string='Invoice Status',
                                      compute='_compute_invoice_status',
                                      store=True,
                                      readonly=True,
                                      default='no')
    price_unit = fields.Float('Unit Price',
                              required=True,
                              digits=dp.get_precision('Product Price'),
                              default=0.0)

    price_subtotal = fields.Monetary(compute='_compute_amount',
                                     string='Subtotal',
                                     readonly=True,
                                     store=True)
    price_tax = fields.Monetary(compute='_compute_amount',
                                string='Taxes',
                                readonly=True,
                                store=True)
    price_total = fields.Monetary(compute='_compute_amount',
                                  string='Total',
                                  readonly=True,
                                  store=True)

    price_reduce = fields.Monetary(compute='_get_price_reduce',
                                   string='Price Reduce',
                                   readonly=True,
                                   store=True)
    tax_id = fields.Many2many('account.tax', string='Taxes')

    discount = fields.Float(string='Discount (%)',
                            digits=dp.get_precision('Discount'),
                            default=0.0)

    product_id = fields.Many2one('product.product',
                                 string='Product',
                                 domain=[('sale_ok', '=', True)],
                                 change_default=True,
                                 ondelete='restrict',
                                 required=True)
    product_uom_qty = fields.Float(
        string='Quantity',
        digits=dp.get_precision('Product Unit of Measure'),
        required=True,
        default=1.0)
    product_uom = fields.Many2one('product.uom',
                                  string='Unit of Measure',
                                  required=True)

    qty_delivered_updateable = fields.Boolean(
        compute='_compute_qty_delivered_updateable',
        string='Can Edit Delivered',
        readonly=True,
        default=True)
    qty_delivered = fields.Float(
        string='Delivered',
        copy=False,
        digits=dp.get_precision('Product Unit of Measure'),
        default=0.0)
    qty_to_invoice = fields.Float(
        compute='_get_to_invoice_qty',
        string='To Invoice',
        store=True,
        readonly=True,
        digits=dp.get_precision('Product Unit of Measure'),
        default=0.0)
    qty_invoiced = fields.Float(
        compute='_get_invoice_qty',
        string='Invoiced',
        store=True,
        readonly=True,
        digits=dp.get_precision('Product Unit of Measure'),
        default=0.0)

    salesman_id = fields.Many2one(related='order_id.user_id',
                                  store=True,
                                  string='Salesperson',
                                  readonly=True)
    currency_id = fields.Many2one(related='order_id.currency_id',
                                  store=True,
                                  string='Currency',
                                  readonly=True)
    company_id = fields.Many2one(related='order_id.company_id',
                                 string='Company',
                                 store=True,
                                 readonly=True)
    order_partner_id = fields.Many2one(related='order_id.partner_id',
                                       store=True,
                                       string='Customer')

    state = fields.Selection([
        ('draft', 'Quotation'),
        ('sent', 'Quotation Sent'),
        ('sale', 'Sale Order'),
        ('done', 'Done'),
        ('cancel', 'Cancelled'),
    ],
                             related='order_id.state',
                             string='Order Status',
                             readonly=True,
                             copy=False,
                             store=True,
                             default='draft')

    customer_lead = fields.Float(
        'Delivery Lead Time',
        required=True,
        default=0.0,
        help=
        "Number of days between the order confirmation and the shipping of the products to the customer",
        oldname="delay")
    procurement_ids = fields.One2many('procurement.order',
                                      'sale_line_id',
                                      string='Procurements')

    @api.multi
    def _prepare_invoice_line(self, qty):
        """
        Prepare the dict of values to create the new invoice line for a sales order line.

        :param qty: float quantity to invoice
        """
        self.ensure_one()
        res = {}
        account = self.product_id.property_account_income_id or self.product_id.categ_id.property_account_income_categ_id
        if not account:
            raise UserError(_('Please define income account for this product: "%s" (id:%d) - or for its category: "%s".') % \
                            (self.product_id.name, self.product_id.id, self.product_id.categ_id.name))

        fpos = self.order_id.fiscal_position_id or self.order_id.partner_id.property_account_position_id
        if fpos:
            account = fpos.map_account(account)

        res = {
            'name': self.name,
            'sequence': self.sequence,
            'origin': self.order_id.name,
            'account_id': account.id,
            'price_unit': self.price_unit,
            'quantity': qty,
            'discount': self.discount,
            'uom_id': self.product_uom.id,
            'product_id': self.product_id.id or False,
            'invoice_line_tax_ids': [(6, 0, self.tax_id.ids)],
            'account_analytic_id': self.order_id.project_id.id,
        }
        return res

    @api.multi
    def invoice_line_create(self, invoice_id, qty):
        """
        Create an invoice line. The quantity to invoice can be positive (invoice) or negative
        (refund).

        :param invoice_id: integer
        :param qty: float quantity to invoice
        """
        precision = self.env['decimal.precision'].precision_get(
            'Product Unit of Measure')
        for line in self:
            if not float_is_zero(qty, precision_digits=precision):
                vals = line._prepare_invoice_line(qty=qty)
                vals.update({
                    'invoice_id': invoice_id,
                    'sale_line_ids': [(6, 0, [line.id])]
                })
                self.env['account.invoice.line'].create(vals)

    @api.multi
    @api.onchange('product_id')
    def product_id_change(self):
        if not self.product_id:
            return {'domain': {'product_uom': []}}

        vals = {}
        domain = {
            'product_uom':
            [('category_id', '=', self.product_id.uom_id.category_id.id)]
        }
        if not (self.product_uom and (self.product_id.uom_id.category_id.id
                                      == self.product_uom.category_id.id)):
            vals['product_uom'] = self.product_id.uom_id

        product = self.product_id.with_context(
            lang=self.order_id.partner_id.lang,
            partner=self.order_id.partner_id.id,
            quantity=self.product_uom_qty,
            date=self.order_id.date_order,
            pricelist=self.order_id.pricelist_id.id,
            uom=self.product_uom.id)

        name = product.name_get()[0][1]
        if product.description_sale:
            name += '\n' + product.description_sale
        vals['name'] = name

        self._compute_tax_id()

        if self.order_id.pricelist_id and self.order_id.partner_id:
            vals['price_unit'] = self.env[
                'account.tax']._fix_tax_included_price(product.price,
                                                       product.taxes_id,
                                                       self.tax_id)
        self.update(vals)
        return {'domain': domain}

    @api.onchange('product_uom', 'product_uom_qty')
    def product_uom_change(self):
        if not self.product_uom:
            self.price_unit = 0.0
            return
        if self.order_id.pricelist_id and self.order_id.partner_id:
            product = self.product_id.with_context(
                lang=self.order_id.partner_id.lang,
                partner=self.order_id.partner_id.id,
                quantity=self.product_uom_qty,
                date_order=self.order_id.date_order,
                pricelist=self.order_id.pricelist_id.id,
                uom=self.product_uom.id)
            self.price_unit = self.env['account.tax']._fix_tax_included_price(
                product.price, product.taxes_id, self.tax_id)

    @api.multi
    def unlink(self):
        if self.filtered(lambda x: x.state in ('sale', 'done')):
            raise UserError(
                _('You can not remove a sale order line.\nDiscard changes and try setting the quantity to 0.'
                  ))
        return super(SaleOrderLine, self).unlink()

    @api.multi
    def _get_delivered_qty(self):
        '''
        Intended to be overridden in sale_stock and sale_mrp
        :return: the quantity delivered
        :rtype: float
        '''
        return 0.0
コード例 #13
0
ファイル: sale.py プロジェクト: eksotama/OCB
class SaleOrder(models.Model):
    _name = "sale.order"
    _inherit = ['mail.thread', 'ir.needaction_mixin']
    _description = "Sales Order"
    _order = 'date_order desc, id desc'

    @api.depends('order_line.price_total')
    def _amount_all(self):
        """
        Compute the total amounts of the SO.
        """
        for order in self:
            amount_untaxed = amount_tax = 0.0
            for line in order.order_line:
                amount_untaxed += line.price_subtotal
                amount_tax += line.price_tax
            order.update({
                'amount_untaxed':
                order.pricelist_id.currency_id.round(amount_untaxed),
                'amount_tax':
                order.pricelist_id.currency_id.round(amount_tax),
                'amount_total':
                amount_untaxed + amount_tax,
            })

    @api.depends('state', 'order_line.invoice_status')
    def _get_invoiced(self):
        """
        Compute the invoice status of a SO. Possible statuses:
        - no: if the SO is not in status 'sale' or 'done', we consider that there is nothing to
          invoice. This is also hte default value if the conditions of no other status is met.
        - to invoice: if any SO line is 'to invoice', the whole SO is 'to invoice'
        - invoiced: if all SO lines are invoiced, the SO is invoiced.
        - upselling: if all SO lines are invoiced or upselling, the status is upselling.

        The invoice_ids are obtained thanks to the invoice lines of the SO lines, and we also search
        for possible refunds created directly from existing invoices. This is necessary since such a
        refund is not directly linked to the SO.
        """
        for order in self:
            invoice_ids = order.order_line.mapped('invoice_lines').mapped(
                'invoice_id')
            # Search for refunds as well
            refund_ids = self.env['account.invoice'].browse()
            if invoice_ids:
                refund_ids = refund_ids.search([
                    ('type', '=', 'out_refund'),
                    ('origin', 'in', invoice_ids.mapped('number'))
                ])

            line_invoice_status = [
                line.invoice_status for line in order.order_line
            ]

            if order.state not in ('sale', 'done'):
                invoice_status = 'no'
            elif any(invoice_status == 'to invoice'
                     for invoice_status in line_invoice_status):
                invoice_status = 'to invoice'
            elif all(invoice_status == 'invoiced'
                     for invoice_status in line_invoice_status):
                invoice_status = 'invoiced'
            elif all(invoice_status in ['invoiced', 'upselling']
                     for invoice_status in line_invoice_status):
                invoice_status = 'upselling'
            else:
                invoice_status = 'no'

            order.update({
                'invoice_count':
                len(set(invoice_ids.ids + refund_ids.ids)),
                'invoice_ids':
                invoice_ids.ids + refund_ids.ids,
                'invoice_status':
                invoice_status
            })

    @api.model
    def _default_note(self):
        return self.env.user.company_id.sale_note

    @api.model
    def _get_default_team(self):
        default_team_id = self.env['crm.team']._get_default_team_id()
        return self.env['crm.team'].browse(default_team_id)

    @api.onchange('fiscal_position_id')
    def _compute_tax_id(self):
        """
        Trigger the recompute of the taxes if the fiscal position is changed on the SO.
        """
        for order in self:
            order.order_line._compute_tax_id()

    name = fields.Char(string='Order Reference',
                       required=True,
                       copy=False,
                       readonly=True,
                       index=True,
                       default='New')
    origin = fields.Char(
        string='Source Document',
        help=
        "Reference of the document that generated this sales order request.")
    client_order_ref = fields.Char(string='Customer Reference', copy=False)

    state = fields.Selection([
        ('draft', 'Quotation'),
        ('sent', 'Quotation Sent'),
        ('sale', 'Sale Order'),
        ('done', 'Done'),
        ('cancel', 'Cancelled'),
    ],
                             string='Status',
                             readonly=True,
                             copy=False,
                             index=True,
                             track_visibility='onchange',
                             default='draft')
    date_order = fields.Datetime(string='Order Date',
                                 required=True,
                                 readonly=True,
                                 index=True,
                                 states={
                                     'draft': [('readonly', False)],
                                     'sent': [('readonly', False)]
                                 },
                                 copy=False,
                                 default=fields.Datetime.now)
    validity_date = fields.Date(string='Expiration Date',
                                readonly=True,
                                states={
                                    'draft': [('readonly', False)],
                                    'sent': [('readonly', False)]
                                })
    create_date = fields.Datetime(string='Creation Date',
                                  readonly=True,
                                  index=True,
                                  help="Date on which sales order is created.")

    user_id = fields.Many2one('res.users',
                              string='Salesperson',
                              index=True,
                              track_visibility='onchange',
                              default=lambda self: self.env.user)
    partner_id = fields.Many2one('res.partner',
                                 string='Customer',
                                 readonly=True,
                                 states={
                                     'draft': [('readonly', False)],
                                     'sent': [('readonly', False)]
                                 },
                                 required=True,
                                 change_default=True,
                                 index=True,
                                 track_visibility='always')
    partner_invoice_id = fields.Many2one(
        'res.partner',
        string='Invoice Address',
        readonly=True,
        required=True,
        states={
            'draft': [('readonly', False)],
            'sent': [('readonly', False)]
        },
        help="Invoice address for current sales order.")
    partner_shipping_id = fields.Many2one(
        'res.partner',
        string='Delivery Address',
        readonly=True,
        required=True,
        states={
            'draft': [('readonly', False)],
            'sent': [('readonly', False)]
        },
        help="Delivery address for current sales order.")

    pricelist_id = fields.Many2one('product.pricelist',
                                   string='Pricelist',
                                   required=True,
                                   readonly=True,
                                   states={
                                       'draft': [('readonly', False)],
                                       'sent': [('readonly', False)]
                                   },
                                   help="Pricelist for current sales order.")
    currency_id = fields.Many2one("res.currency",
                                  related='pricelist_id.currency_id',
                                  string="Currency",
                                  readonly=True,
                                  required=True)
    project_id = fields.Many2one(
        'account.analytic.account',
        'Analytic Account',
        readonly=True,
        states={
            'draft': [('readonly', False)],
            'sent': [('readonly', False)]
        },
        help="The analytic account related to a sales order.",
        copy=False)

    order_line = fields.One2many('sale.order.line',
                                 'order_id',
                                 string='Order Lines',
                                 states={
                                     'cancel': [('readonly', True)],
                                     'done': [('readonly', True)]
                                 },
                                 copy=True)

    invoice_count = fields.Integer(string='# of Invoices',
                                   compute='_get_invoiced',
                                   readonly=True)
    invoice_ids = fields.Many2many("account.invoice",
                                   string='Invoices',
                                   compute="_get_invoiced",
                                   readonly=True,
                                   copy=False)
    invoice_status = fields.Selection([('upselling', 'Upselling Opportunity'),
                                       ('invoiced', 'Fully Invoiced'),
                                       ('to invoice', 'To Invoice'),
                                       ('no', 'Nothing to Invoice')],
                                      string='Invoice Status',
                                      compute='_get_invoiced',
                                      store=True,
                                      readonly=True,
                                      default='no')

    note = fields.Text('Terms and conditions', default=_default_note)

    amount_untaxed = fields.Monetary(string='Untaxed Amount',
                                     store=True,
                                     readonly=True,
                                     compute='_amount_all',
                                     track_visibility='always')
    amount_tax = fields.Monetary(string='Taxes',
                                 store=True,
                                 readonly=True,
                                 compute='_amount_all',
                                 track_visibility='always')
    amount_total = fields.Monetary(string='Total',
                                   store=True,
                                   readonly=True,
                                   compute='_amount_all',
                                   track_visibility='always')

    payment_term_id = fields.Many2one('account.payment.term',
                                      string='Payment Term',
                                      oldname='payment_term')
    fiscal_position_id = fields.Many2one('account.fiscal.position',
                                         oldname='fiscal_position',
                                         string='Fiscal Position')
    company_id = fields.Many2one('res.company',
                                 'Company',
                                 default=lambda self: self.env['res.company'].
                                 _company_default_get('sale.order'))
    team_id = fields.Many2one('crm.team',
                              'Sales Team',
                              change_default=True,
                              default=_get_default_team)
    procurement_group_id = fields.Many2one('procurement.group',
                                           'Procurement Group',
                                           copy=False)

    product_id = fields.Many2one('product.product',
                                 related='order_line.product_id',
                                 string='Product')

    @api.multi
    def button_dummy(self):
        return True

    @api.multi
    def unlink(self):
        for order in self:
            if order.state != 'draft':
                raise UserError(_('You can only delete draft quotations!'))
        return super(SaleOrder, self).unlink()

    @api.multi
    def _track_subtype(self, init_values):
        self.ensure_one()
        if 'state' in init_values and self.state == 'sale':
            return 'sale.mt_order_confirmed'
        elif 'state' in init_values and self.state == 'sent':
            return 'sale.mt_order_sent'
        return super(SaleOrder, self)._track_subtype(init_values)

    @api.multi
    @api.onchange('partner_shipping_id')
    def onchange_partner_shipping_id(self):
        """
        Trigger the change of fiscal position when the shipping address is modified.
        """
        fiscal_position = self.env[
            'account.fiscal.position'].get_fiscal_position(
                self.partner_id.id, self.partner_shipping_id.id)
        if fiscal_position:
            self.fiscal_position_id = fiscal_position
        return {}

    @api.multi
    @api.onchange('partner_id')
    def onchange_partner_id(self):
        """
        Update the following fields when the partner is changed:
        - Pricelist
        - Payment term
        - Invoice address
        - Delivery address
        """
        if not self.partner_id:
            self.update({
                'partner_invoice_id': False,
                'partner_shipping_id': False,
                'payment_term_id': False,
                'fiscal_position_id': False,
            })
            return

        addr = self.partner_id.address_get(['delivery', 'invoice'])
        values = {
            'pricelist_id':
            self.partner_id.property_product_pricelist
            and self.partner_id.property_product_pricelist.id or False,
            'payment_term_id':
            self.partner_id.property_payment_term_id
            and self.partner_id.property_payment_term_id.id or False,
            'partner_invoice_id':
            addr['invoice'],
            'partner_shipping_id':
            addr['delivery'],
            'note':
            self.with_context(
                lang=self.partner_id.lang).env.user.company_id.sale_note,
        }

        if self.partner_id.user_id:
            values['user_id'] = self.partner_id.user_id.id
        if self.partner_id.team_id:
            values['team_id'] = self.partner_id.team_id.id
        self.update(values)

    @api.model
    def create(self, vals):
        if vals.get('name', 'New') == 'New':
            vals['name'] = self.env['ir.sequence'].next_by_code(
                'sale.order') or 'New'

        # Makes sure partner_invoice_id', 'partner_shipping_id' and 'pricelist_id' are defined
        if any(f not in vals for f in
               ['partner_invoice_id', 'partner_shipping_id', 'pricelist_id']):
            partner = self.env['res.partner'].browse(vals.get('partner_id'))
            addr = partner.address_get(['delivery', 'invoice'])
            vals['partner_invoice_id'] = vals.setdefault(
                'partner_invoice_id', addr['invoice'])
            vals['partner_shipping_id'] = vals.setdefault(
                'partner_shipping_id', addr['delivery'])
            vals['pricelist_id'] = vals.setdefault(
                'pricelist_id', partner.property_product_pricelist
                and partner.property_product_pricelist.id)
        result = super(SaleOrder, self).create(vals)
        return result

    @api.multi
    def _prepare_invoice(self):
        """
        Prepare the dict of values to create the new invoice for a sales order. This method may be
        overridden to implement custom invoice generation (making sure to call super() to establish
        a clean extension chain).
        """
        self.ensure_one()
        journal_id = self.env['account.invoice'].default_get(['journal_id'
                                                              ])['journal_id']
        if not journal_id:
            raise UserError(
                _('Please define an accounting sale journal for this company.')
            )
        invoice_vals = {
            'name':
            self.client_order_ref or '',
            'origin':
            self.name,
            'type':
            'out_invoice',
            'reference':
            self.client_order_ref or self.name,
            'account_id':
            self.partner_invoice_id.property_account_receivable_id.id,
            'partner_id':
            self.partner_invoice_id.id,
            'journal_id':
            journal_id,
            'currency_id':
            self.pricelist_id.currency_id.id,
            'comment':
            self.note,
            'payment_term_id':
            self.payment_term_id.id,
            'fiscal_position_id':
            self.fiscal_position_id.id
            or self.partner_invoice_id.property_account_position_id.id,
            'company_id':
            self.company_id.id,
            'user_id':
            self.user_id and self.user_id.id,
            'team_id':
            self.team_id.id
        }
        return invoice_vals

    @api.multi
    def print_quotation(self):
        self.filtered(lambda s: s.state == 'draft').write({'state': 'sent'})
        return self.env['report'].get_action(self, 'sale.report_saleorder')

    @api.multi
    def action_view_invoice(self):
        invoice_ids = self.mapped('invoice_ids')
        imd = self.env['ir.model.data']
        action = imd.xmlid_to_object('account.action_invoice_tree1')
        list_view_id = imd.xmlid_to_res_id('account.invoice_tree')
        form_view_id = imd.xmlid_to_res_id('account.invoice_form')

        result = {
            'name':
            action.name,
            'help':
            action.help,
            'type':
            action.type,
            'views': [[list_view_id, 'tree'], [form_view_id, 'form'],
                      [False, 'graph'], [False, 'kanban'], [False, 'calendar'],
                      [False, 'pivot']],
            'target':
            action.target,
            'context':
            action.context,
            'res_model':
            action.res_model,
        }
        if len(invoice_ids) > 1:
            result['domain'] = "[('id','in',%s)]" % invoice_ids.ids
        elif len(invoice_ids) == 1:
            result['views'] = [(form_view_id, 'form')]
            result['res_id'] = invoice_ids.ids[0]
        else:
            result = {'type': 'ir.actions.act_window_close'}
        return result

    @api.multi
    def action_invoice_create(self, grouped=False, final=False):
        """
        Create the invoice associated to the SO.
        :param grouped: if True, invoices are grouped by SO id. If False, invoices are grouped by
                        (partner, currency)
        :param final: if True, refunds will be generated if necessary
        :returns: list of created invoices
        """
        inv_obj = self.env['account.invoice']
        precision = self.env['decimal.precision'].precision_get(
            'Product Unit of Measure')
        invoices = {}

        for order in self:
            group_key = order.id if grouped else (order.partner_id.id,
                                                  order.currency_id.id)
            for line in order.order_line.sorted(
                    key=lambda l: l.qty_to_invoice < 0):
                if float_is_zero(line.qty_to_invoice,
                                 precision_digits=precision):
                    continue
                if group_key not in invoices:
                    inv_data = order._prepare_invoice()
                    invoice = inv_obj.create(inv_data)
                    invoices[group_key] = invoice
                elif group_key in invoices and order.name not in invoices[
                        group_key].origin.split(', '):
                    invoices[group_key].write({
                        'origin':
                        invoices[group_key].origin + ', ' + order.name
                    })
                if line.qty_to_invoice > 0:
                    line.invoice_line_create(invoices[group_key].id,
                                             line.qty_to_invoice)
                elif line.qty_to_invoice < 0 and final:
                    line.invoice_line_create(invoices[group_key].id,
                                             line.qty_to_invoice)

        for invoice in invoices.values():
            # If invoice is negative, do a refund invoice instead
            if invoice.amount_untaxed < 0:
                invoice.type = 'out_refund'
                for line in invoice.invoice_line_ids:
                    line.quantity = -line.quantity
            # Necessary to force computation of taxes. In account_invoice, they are triggered
            # by onchanges, which are not triggered when doing a create.
            invoice.compute_taxes()

        return [inv.id for inv in invoices.values()]

    @api.multi
    def action_draft(self):
        self.filtered(lambda s: s.state in ['cancel', 'sent']).write(
            {'state': 'draft'})

    @api.multi
    def action_cancel(self):
        self.write({'state': 'cancel'})

    @api.multi
    def action_quotation_send(self):
        '''
        This function opens a window to compose an email, with the edi sale template message loaded by default
        '''
        self.ensure_one()
        ir_model_data = self.env['ir.model.data']
        try:
            template_id = ir_model_data.get_object_reference(
                'sale', 'email_template_edi_sale')[1]
        except ValueError:
            template_id = False
        try:
            compose_form_id = ir_model_data.get_object_reference(
                'mail', 'email_compose_message_wizard_form')[1]
        except ValueError:
            compose_form_id = False
        ctx = dict()
        ctx.update({
            'default_model': 'sale.order',
            'default_res_id': self.ids[0],
            'default_use_template': bool(template_id),
            'default_template_id': template_id,
            'default_composition_mode': 'comment',
            'mark_so_as_sent': True
        })
        return {
            'type': 'ir.actions.act_window',
            'view_type': 'form',
            'view_mode': 'form',
            'res_model': 'mail.compose.message',
            'views': [(compose_form_id, 'form')],
            'view_id': compose_form_id,
            'target': 'new',
            'context': ctx,
        }

    @api.multi
    def force_quotation_send(self):
        for order in self:
            email_act = order.action_quotation_send()
            if email_act and email_act.get('context'):
                email_ctx = email_act['context']
                email_ctx.update(default_email_from=order.company_id.email)
                order.with_context(email_ctx).message_post_with_template(
                    email_ctx.get('default_template_id'))
        return True

    @api.multi
    def action_done(self):
        self.write({'state': 'done'})

    @api.model
    def _prepare_procurement_group(self):
        return {'name': self.name}

    @api.multi
    def action_confirm(self):
        for order in self:
            order.state = 'sale'
            if self.env.context.get('send_email'):
                self.force_quotation_send()
            order.order_line._action_procurement_create()
            if not order.project_id:
                for line in order.order_line:
                    if line.product_id.invoice_policy == 'cost':
                        order._create_analytic_account()
                        break
        if self.env['ir.values'].get_default('sale.config.settings',
                                             'auto_done_setting'):
            self.action_done()

    @api.multi
    def _create_analytic_account(self, prefix=None):
        for order in self:
            name = order.name
            if prefix:
                name = prefix + ": " + order.name
            analytic = self.env['account.analytic.account'].create({
                'name':
                name,
                'code':
                order.client_order_ref,
                'company_id':
                order.company_id.id,
                'partner_id':
                order.partner_id.id
            })
            order.project_id = analytic
コード例 #14
0
ファイル: lunch.py プロジェクト: Lennon-Liang/odoo-1
class LunchOrder(models.Model):
    """
    A lunch order contains one or more lunch order line(s). It is associated to a user for a given
    date. When creating a lunch order, applicable lunch alerts are displayed.
    """
    _name = 'lunch.order'
    _description = 'Lunch Order'
    _order = 'date desc'

    def _default_previous_order_ids(self):
        prev_order = self.env['lunch.order.line'].search([('user_id', '=', self.env.uid), ('product_id.active', '!=', False)], limit=20, order='id desc')
        # If we return return prev_order.ids, we will have duplicates (identical orders).
        # Therefore, this following part removes duplicates based on product_id and note.
        return {
            (order.product_id, order.note): order.id
            for order in prev_order
        }.values()

    user_id = fields.Many2one('res.users', 'User', required=True, readonly=True,
                              states={'new': [('readonly', False)]},
                              default=lambda self: self.env.uid)
    date = fields.Date('Date', required=True, readonly=True,
                       states={'new': [('readonly', False)]},
                       default=fields.Date.context_today)
    order_line_ids = fields.One2many('lunch.order.line', 'order_id', 'Products',
                                     ondelete="cascade", readonly=True, copy=True,
                                     states={'new': [('readonly', False)], False: [('readonly', False)]})
    total = fields.Float(compute='_compute_total', string="Total", store=True)
    state = fields.Selection([('new', 'New'),
                              ('confirmed', 'Received'),
                              ('cancelled', 'Cancelled')],
                             'Status', readonly=True, index=True, copy=False, default='new',
                             compute='_compute_order_state', store=True)
    alerts = fields.Text(compute='_compute_alerts_get', string="Alerts")
    previous_order_ids = fields.Many2many('lunch.order.line', compute='_compute_previous_order_ids',
                                          default=lambda self: self._default_previous_order_ids())
    company_id = fields.Many2one('res.company', related='user_id.company_id', store=True)
    currency_id = fields.Many2one('res.currency', related='company_id.currency_id', readonly=True, store=True)
    cash_move_balance = fields.Monetary(compute='_compute_cash_move_balance', multi='cash_move_balance')
    balance_visible = fields.Boolean(compute='_compute_cash_move_balance', multi='cash_move_balance')

    @api.one
    @api.depends('order_line_ids')
    def _compute_total(self):
        """
        get and sum the order lines' price
        """
        self.total = sum(
            orderline.price for orderline in self.order_line_ids)

    @api.multi
    def name_get(self):
        return [(order.id, '%s %s' % (_('Lunch Order'), '#%d' % order.id)) for order in self]

    @api.depends('state')
    def _compute_alerts_get(self):
        """
        get the alerts to display on the order form
        """
        alert_msg = [alert.message
                     for alert in self.env['lunch.alert'].search([])
                     if alert.display]

        if self.state == 'new':
            self.alerts = alert_msg and '\n'.join(alert_msg) or False

    @api.depends('user_id')
    def _compute_previous_order_ids(self):
        self.previous_order_ids = self._default_previous_order_ids()

    @api.one
    @api.depends('user_id')
    def _compute_cash_move_balance(self):
        domain = [('user_id', '=', self.user_id.id)]
        lunch_cash = self.env['lunch.cashmove'].read_group(domain, ['amount', 'user_id'], ['user_id'])
        if len(lunch_cash):
            self.cash_move_balance = lunch_cash[0]['amount']
        self.balance_visible = (self.user_id == self.env.user) or self.user_has_groups('lunch.group_lunch_manager')

    @api.one
    @api.constrains('date')
    def _check_date(self):
        """
        Prevents the user to create an order in the past
        """
        date_order = datetime.datetime.strptime(self.date, '%Y-%m-%d')
        date_today = datetime.datetime.strptime(fields.Date.context_today(self), '%Y-%m-%d')
        if (date_order < date_today):
            raise ValidationError(_('The date of your order is in the past.'))

    @api.one
    @api.depends('order_line_ids.state')
    def _compute_order_state(self):
        """
        Update the state of lunch.order based on its orderlines. Here is the logic:
        - if at least one order line is cancelled, the order is set as cancelled
        - if no line is cancelled but at least one line is not confirmed, the order is set as new
        - if all lines are confirmed, the order is set as confirmed
        """
        if not self.order_line_ids:
            self.state = 'new'
        else:
            isConfirmed = True
            for orderline in self.order_line_ids:
                if orderline.state == 'cancelled':
                    self.state = 'cancelled'
                    return
                elif orderline.state == 'confirmed':
                    continue
                else:
                    isConfirmed = False

            if isConfirmed:
                self.state = 'confirmed'
            else:
                self.state = 'new'
        return
コード例 #15
0
class PurchaseRequest(models.Model):

    _name = 'purchase.request'
    _description = 'Purchase Request'
    _inherit = ['mail.thread', 'ir.needaction_mixin']

    @api.model
    def _company_get(self):
        company_id = self.env['res.company']._company_default_get(self._name)
        return self.env['res.company'].browse(company_id.id)

    @api.model
    def _get_default_requested_by(self):
        return self.env['res.users'].browse(self.env.uid)

    @api.model
    def _get_default_name(self):
        return self.env['ir.sequence'].get('purchase.request')

    @api.model
    def _default_picking_type(self):
        type_obj = self.env['stock.picking.type']
        company_id = self.env.context.get('company_id') or \
            self.env.user.company_id.id
        types = type_obj.search([('code', '=', 'incoming'),
                                 ('warehouse_id.company_id', '=', company_id)])
        if not types:
            types = type_obj.search([('code', '=', 'incoming'),
                                     ('warehouse_id', '=', False)])
        return types[:1]

    @api.multi
    @api.depends('state')
    def _compute_is_editable(self):
        for rec in self:
            if rec.state in ('to_approve', 'approved', 'rejected'):
                rec.is_editable = False
            else:
                rec.is_editable = True

    @api.multi
    def _track_subtype(self, init_values):
        for rec in self:
            if 'state' in init_values and rec.state == 'to_approve':
                return 'purchase_request.mt_request_to_approve'
            elif 'state' in init_values and rec.state == 'to_department_manager_approved':
                return 'purchase_request.mt_request_to_department_manager_approved'
            elif 'state' in init_values and rec.state == 'to_accountant_manager_approved':
                return 'purchase_request.mt_request_to_accountant_manager_approved'
            elif 'state' in init_values and rec.state == 'approved':
                return 'purchase_request.mt_request_approved'
            elif 'state' in init_values and rec.state == 'rejected':
                return 'purchase_request.mt_request_rejected'
        return super(PurchaseRequest, self)._track_subtype(init_values)

    name = fields.Char('Request Reference',
                       size=32,
                       required=True,
                       default=_get_default_name,
                       track_visibility='onchange')
    origin = fields.Char('Source Document', size=32)
    date_start = fields.Date('Creation date',
                             help="Date when the user initiated the "
                             "request.",
                             default=fields.Date.context_today,
                             track_visibility='onchange')
    date_finish = fields.Date('Expected date',
                              help="Date when the Request will  "
                              "Finish.",
                              default=fields.Date.context_today,
                              compute='_check_the_date',
                              track_visibility='onchange')
    requested_by = fields.Many2one('res.users',
                                   'Requested by',
                                   required=True,
                                   track_visibility='onchange',
                                   default=_get_default_requested_by)
    assigned_to = fields.Many2one('res.users',
                                  'Department Managers',
                                  domain=[('x_department_manager', '=', True)],
                                  track_visibility='onchange')
    assigned_to_2 = fields.Many2one('res.users',
                                    'Department Managers',
                                    domain=[('x_department_manager', '=', True)
                                            ],
                                    track_visibility='onchange')
    assigned_to_3 = fields.Many2one('res.users',
                                    'Projects or Sections Managers',
                                    domain=[('x_project_manager', '=', True)],
                                    track_visibility='onchange')
    description = fields.Text('Description')
    direct_manager_notes = fields.Text('Direct manager notes')
    department_manager_notes = fields.Text('Director notes')
    accountant_manager_notes = fields.Text('CFO notes')
    executive_manager_notes = fields.Text('Executive manager notes')
    treasurer_manager_notes = fields.Text('Treasurer notes')
    president_manager_notes = fields.Text('Chairman notes')
    company_id = fields.Many2one('res.company',
                                 'Company',
                                 required=True,
                                 default=_company_get,
                                 track_visibility='onchange')
    line_ids = fields.One2many('purchase.request.line',
                               'request_id',
                               'Products to Purchase',
                               readonly=False,
                               copy=True,
                               track_visibility='onchange')
    state = fields.Selection(selection=_STATES,
                             string='Status',
                             index=True,
                             track_visibility='onchange',
                             required=True,
                             copy=False,
                             default='draft')
    stage = fields.Selection(selection=_STAGES, default=1, string='Stage')
    steps = fields.Selection(selection=_STEPS,
                             string='Technical Specifications Steps')
    request_type = fields.Selection(selection=_TYPES,
                                    default=1,
                                    string='Request Type')
    type_reason = fields.Text('Reason')

    department = fields.Many2one('hr.department',
                                 'Department',
                                 track_visibility='onchange')
    project = fields.Many2one('hr.department',
                              'Project',
                              track_visibility='onchange')
    is_editable = fields.Boolean(string="Is editable",
                                 compute="_compute_is_editable",
                                 readonly=True)

    picking_type_id = fields.Many2one('stock.picking.type',
                                      'Picking Type',
                                      required=True,
                                      default=_default_picking_type)

    ontime = fields.Integer(string='On Time',
                            compute="change_ontime",
                            readonly=True)
    ontime_stage = fields.Integer(string='On Time Stage',
                                  compute="change_ontime_stage",
                                  readonly=True)
    done1 = fields.Char(string='Done',
                        compute="change_done_stage",
                        default='early')
    progress = fields.Float(string='Progress',
                            compute='change_progress',
                            readonly=True)
    color = fields.Integer('Color Index', compute="change_colore_on_kanban")
    price_alltotal = fields.Float(string='Total Price',
                                  compute='_compute_amount_all',
                                  store=True)

    @api.multi
    @api.depends('line_ids.price_total')
    def _compute_amount_all(self):
        for request in self:
            for line in request.line_ids:
                request.price_alltotal += line.price_total
            if request.price_alltotal > 0:
                request.stage = 5

    @api.multi
    def copy(self, default=None):
        default = dict(default or {})
        self.ensure_one()
        default.update({
            'state': 'draft',
            'name': self.env['ir.sequence'].get('purchase.request'),
        })
        return super(PurchaseRequest, self).copy(default)

    @api.model
    def create(self, vals):
        request = super(PurchaseRequest, self).create(vals)
        if vals.get('assigned_to'):
            request.message_subscribe_users(user_ids=[request.assigned_to.id])
        return request

    @api.multi
    def write(self, vals):
        res = super(PurchaseRequest, self).write(vals)
        for request in self:
            if vals.get('assigned_to'):
                self.message_subscribe_users(user_ids=[request.assigned_to.id])
        return res

    @api.multi
    def button_draft(self):
        for rec in self:
            rec.state = 'draft'
        return True

    @api.multi
    def button_to_approve(self):
        for rec in self:
            rec.state = 'to_approve'
        return True

    @api.multi
    def button_to_department_manager_approved(self):
        for rec in self:
            rec.state = 'to_department_manager_approved'
        return True

    @api.multi
    def button_to_accountant_manager_approved(self):
        for rec in self:
            rec.state = 'to_accountant_manager_approved'
            rec.stage = 2
        return True

    @api.multi
    def button_approved(self):
        for rec in self:
            rec.state = 'approved'
            rec.stage = 6
        return True

    @api.multi
    def button_rejected(self):
        for rec in self:
            rec.state = 'rejected'
        return True

    @api.multi
    def _check_the_date(self):
        #for rec in self:
        #   d1 = datetime.datetime.strptime((rec.date_start),'%Y-%m-%d')
        #  new_date = d1 + datetime.timedelta(days=18)
        # rec.date_finish = new_date
        for rec in self:
            if rec.price_alltotal <= 500:
                d1 = datetime.datetime.strptime((rec.date_start), '%Y-%m-%d')
                new_date = d1 + datetime.timedelta(days=4)
                rec.date_finish = new_date
            elif rec.price_alltotal > 500 and rec.price_alltotal <= 5000:
                d1 = datetime.datetime.strptime((rec.date_start), '%Y-%m-%d')
                new_date = d1 + datetime.timedelta(days=5)
                rec.date_finish = new_date
            elif rec.price_alltotal > 5000 and rec.price_alltotal <= 100000:
                d1 = datetime.datetime.strptime((rec.date_start), '%Y-%m-%d')
                new_date = d1 + datetime.timedelta(days=7)
                rec.date_finish = new_date
            elif rec.price_alltotal > 100000:
                d1 = datetime.datetime.strptime((rec.date_start), '%Y-%m-%d')
                new_date = d1 + datetime.timedelta(days=15)
                rec.date_finish = new_date

    def change_progress(self):
        for rec in self:
            x = rec.stage
            y = x * 100 / 14
            rec.progress = y

    def change_ontime(self):
        for rec in self:
            d1 = datetime.datetime.today()
            d2 = datetime.datetime.strptime((rec.date_finish), '%Y-%m-%d')
            d = str((d2 - d1).days + 1)
            rec.ontime = d

    def change_ontime_stage(self):
        for rec in self:
            d1 = datetime.datetime.today()
            d2 = datetime.datetime.strptime((rec.date_start), '%Y-%m-%d')
            d = str((d1 - d2).days + 1)
            rec.ontime_stage = d

    def change_done_stage(self):
        for rec in self:
            if rec.price_alltotal <= 500:
                if rec.stage == 1 and rec.ontime_stage > 1:
                    dd = "late"
                    rec.done1 = dd
                elif rec.stage == 2 and rec.ontime_stage > 2:
                    dd = "late"
                    rec.done1 = dd
                elif rec.stage == 3 and rec.ontime_stage > 4:
                    dd = "late"
                    rec.done1 = dd
                elif rec.stage == 4 and rec.ontime_stage > 4:
                    dd = "late"
                    rec.done1 = dd
                elif rec.stage == 5 and rec.ontime_stage > 4:
                    dd = "late"
                    rec.done1 = dd
                elif rec.stage == 6 and rec.ontime_stage > 4:
                    dd = "late"
                    rec.done1 = dd
            elif rec.price_alltotal > 500 and rec.price_alltotal <= 5000:
                if rec.stage == 1 and rec.ontime_stage > 1:
                    dd = "late"
                    rec.done1 = dd
                elif rec.stage == 2 and rec.ontime_stage > 2:
                    dd = "late"
                    rec.done1 = dd
                elif rec.stage == 3 and rec.ontime_stage > 5:
                    dd = "late"
                    rec.done1 = dd
                elif rec.stage == 4 and rec.ontime_stage > 5:
                    dd = "late"
                    rec.done1 = dd
                elif rec.stage == 5 and rec.ontime_stage > 5:
                    dd = "late"
                    rec.done1 = dd
                elif rec.stage == 6 and rec.ontime_stage > 5:
                    dd = "late"
                    rec.done1 = dd
            elif rec.price_alltotal > 5000 and rec.price_alltotal <= 100000:
                if rec.stage == 1 and rec.ontime_stage > 1:
                    dd = "late"
                    rec.done1 = dd
                elif rec.stage == 2 and rec.ontime_stage > 2:
                    dd = "late"
                    rec.done1 = dd
                elif rec.stage == 3 and rec.ontime_stage > 5:
                    dd = "late"
                    rec.done1 = dd
                elif rec.stage == 4 and rec.ontime_stage > 5:
                    dd = "late"
                    rec.done1 = dd
                elif rec.stage == 5 and rec.ontime_stage > 5:
                    dd = "late"
                    rec.done1 = dd
                elif rec.stage == 6 and rec.ontime_stage > 5:
                    dd = "late"
                    rec.done1 = dd
            elif rec.price_alltotal > 100000:
                if rec.stage == 1 and rec.ontime_stage > 1:
                    dd = "late"
                    rec.done1 = dd
                elif rec.stage == 2 and rec.ontime_stage > 2:
                    dd = "late"
                    rec.done1 = dd
                elif rec.stage == 3 and rec.ontime_stage > 7:
                    dd = "late"
                    rec.done1 = dd
                elif rec.stage == 4 and rec.ontime_stage > 7:
                    dd = "late"
                    rec.done1 = dd
                elif rec.stage == 5 and rec.ontime_stage > 7:
                    dd = "late"
                    rec.done1 = dd
                elif rec.stage == 6 and rec.ontime_stage > 7:
                    dd = "late"
                    rec.done1 = dd
                elif (rec.stage == 7 or rec.stage == 8 or rec.stage == 9
                      or rec.stage == 10) and rec.ontime_stage > 15:
                    dd = "late"
                    rec.done1 = dd
                elif (rec.stage == 11 or rec.stage == 12
                      or rec.stage == 13) and rec.ontime_stage > 12:
                    dd = "late"
                    rec.done1 = dd

    def change_colore_on_kanban(self):
        for record in self:
            color = 0
            if record.ontime < 0:
                color = 2
            elif record.ontime == 0:
                color = 3
            elif record.ontime > 0:
                color = 5
            record.color = color
コード例 #16
0
ファイル: is_cout.py プロジェクト: tonygalmiche/is_plastigray
class is_cout(models.Model):
    _name='is.cout'
    _order='name'
    _sql_constraints = [('name_uniq', 'unique(name)', u"Ce code existe déja !")]

    name                   = fields.Many2one('product.product', 'Article', required=True, readonly=False, select=True)
    code_pg                = fields.Char('Code PG'    , related='name.product_tmpl_id.is_code', readonly=True)
    designation            = fields.Char('Désignation', related='name.product_tmpl_id.name'   , readonly=True)
    cout_calcul_id         = fields.Many2one('is.cout.calcul', 'Calcul des coût')
    is_category_id         = fields.Many2one('is.category', 'Catégorie')
    is_gestionnaire_id     = fields.Many2one('is.gestionnaire', 'Gestionnaire')
    is_mold_id             = fields.Many2one('is.mold', 'Moule')
    is_mold_dossierf       = fields.Char('Moule ou Dossier F')
    partner_id             = fields.Many2one('res.partner', 'Client par défaut')
    type_article           = fields.Selection([('A', u'Acheté'),('F', u'Fabriqué'),('ST', u'Sous-traité')], "Type d'article")
    uom_id                 = fields.Many2one('product.uom', 'Unité')
    lot_mini               = fields.Float("Lot d'appro.")
    prix_tarif             = fields.Float("Prix tarif"                  , digits=(12, 4))
    prix_commande          = fields.Float("Prix dernière commande"      , digits=(12, 4))
    prix_facture           = fields.Float("Prix dernière facture"       , digits=(12, 4))
    prix_force             = fields.Float("Prix forcé (saisie manuelle)", digits=(12, 4))
    prix_force_commentaire = fields.Char("Commentaire")
    prix_calcule           = fields.Float("Prix calculé"                , digits=(12, 4))
    prix_sous_traitance    = fields.Float("Prix sous-traitance"         , digits=(12, 4))
    ecart_calcule_matiere  = fields.Float("Ecart Calculé/Matière"       , digits=(12, 4))

    cout_act_matiere       = fields.Float("Coût act matière"        , digits=(12, 4))
    cout_act_condition     = fields.Float("Coût act conditionnement", digits=(12, 4))
    cout_act_machine       = fields.Float("Coût act machine"        , digits=(12, 4))
    cout_act_mo            = fields.Float("Coût act main d'oeuvre"  , digits=(12, 4))
    cout_act_machine_pk    = fields.Float("Coût act machine PK"      , digits=(12, 4))
    cout_act_mo_pk         = fields.Float("Coût act main d'oeuvre PK", digits=(12, 4))
    cout_act_st            = fields.Float("Coût act sous-traitance" , digits=(12, 4))
    cout_act_total         = fields.Float("Coût act Total"          , digits=(12, 4))
    cout_act_prix_vente    = fields.Float("Prix de vente actualisé" , digits=(12, 4))

    cout_std_matiere       = fields.Float("Coût std matière"         , digits=(12, 4))
    cout_std_condition     = fields.Float("Coût std conditionnement" , digits=(12, 4))
    cout_std_machine       = fields.Float("Coût std machine"         , digits=(12, 4))
    cout_std_mo            = fields.Float("Coût std main d'oeuvre"   , digits=(12, 4))
    cout_std_st            = fields.Float("Coût std sous-traitance"  , digits=(12, 4))
    cout_std_total         = fields.Float("Coût std Total"           , digits=(12, 4))
    cout_std_prix_vente    = fields.Float("Prix de vente standard"   , digits=(12, 4))

    cout_budget_matiere       = fields.Float("Coût budget matière"         , digits=(12, 4))
    cout_budget_condition     = fields.Float("Coût budget conditionnement" , digits=(12, 4))
    cout_budget_machine       = fields.Float("Coût budget machine"         , digits=(12, 4))
    cout_budget_mo            = fields.Float("Coût budget main d'oeuvre"   , digits=(12, 4))
    cout_budget_st            = fields.Float("Coût budget sous-traitance"  , digits=(12, 4))
    cout_budget_total         = fields.Float("Coût budget Total"           , digits=(12, 4))
    cout_budget_prix_vente    = fields.Float("Prix de vente budget"        , digits=(12, 4))

    amortissement_moule    = fields.Float("Amortissement Moule"     , digits=(12, 4), compute='_compute')
    surcout_pre_serie      = fields.Float("Surcôut pré-série"       , digits=(12, 4), compute='_compute')
    prix_vente             = fields.Float("Prix de Vente"           , digits=(12, 4), compute='_compute')
    nomenclature_ids       = fields.One2many('is.cout.nomenclature', 'cout_id', u"Lignes de la nomenclature")
    gamme_ma_ids           = fields.One2many('is.cout.gamme.ma'    , 'cout_id', u"Lignes gamme machine")
    gamme_mo_ids           = fields.One2many('is.cout.gamme.mo'    , 'cout_id', u"Lignes gamme MO")
    gamme_ma_pk_ids        = fields.One2many('is.cout.gamme.ma.pk' , 'cout_id', u"Lignes gamme machine PK")
    gamme_mo_pk_ids        = fields.One2many('is.cout.gamme.mo.pk' , 'cout_id', u"Lignes gamme MO PK")
    niveau                 = fields.Integer('Niveau le plus bas dans la nomenclature')
    nb_err                 = fields.Integer('Nb Err', help=u"Nombre d'erreures détectées lors du calcul de coûts")


    @api.depends('name')
    def _compute(self):
        for obj in self:
            #** Recherche du tarif commercial pour le client par défaut ********
            code_client=mem_code_client=False
            for client in obj.name.product_tmpl_id.is_client_ids:
                mem_code_client=client.client_id.is_code
                if client.client_defaut:
                    code_client=mem_code_client
            if code_client==False:
                code_client=mem_code_client
            tarifs=self.env['is.tarif.cial'].search([
                ('product_id', '=', obj.name.product_tmpl_id.id),
                ('indice_prix', '=', 999),
                ('partner_id.is_code', '=', code_client)
            ])
            for tarif in tarifs:
                obj.amortissement_moule = tarif.amortissement_moule
                obj.surcout_pre_serie   = tarif.surcout_pre_serie
                obj.prix_vente          = tarif.prix_vente


    @api.multi
    def write(self, vals):
        for obj in self:
            matiere   = vals.get('cout_std_matiere'  , obj.cout_std_matiere)
            machine   = vals.get('cout_std_machine'  , obj.cout_std_machine)
            mo        = vals.get('cout_std_mo'       , obj.cout_std_mo)
            st        = vals.get('cout_std_st'       , obj.cout_std_st)
            vals['cout_std_total']=matiere+machine+mo+st
        res=super(is_cout, self).write(vals)
        return res


    @api.multi
    def action_calcul_cout(self):
        for obj in self:
            vals={
                'product_id'   : obj.name.id,
                'multiniveaux' : False,
            }
            cout_calcul=self.env['is.cout.calcul'].create(vals)
            cout_calcul.action_calcul_prix_achat_thread(nb_threads=0)
            cout_calcul.action_calcul_prix_revient()
            
            return {
                'name': obj.name.name,
                'view_mode': 'form',
                'view_type': 'form',
                'res_model': 'is.cout',
                'type': 'ir.actions.act_window',
                'res_id': obj.id,
            }


    @api.multi
    def action_calcul_cout_pk(self):
        for obj in self:
            vals={
                'product_id'   : obj.name.id,
                'multiniveaux' : False,
            }
            cout_calcul=self.env['is.cout.calcul'].create(vals)
            cout_calcul.action_calcul_prix_achat_thread(nb_threads=0)
            cout_calcul.action_calcul_prix_revient()
            dummy, view_id = self.env['ir.model.data'].get_object_reference('is_plastigray', 'is_cout_pk_form_view')
            return {
                'name': obj.name.name,
                'view_mode': 'form',
                'view_type': 'form',
                'res_model': 'is.cout',
                'type': 'ir.actions.act_window',
                'view_id': view_id,
                'res_id': obj.id,
            }


    @api.multi
    def _copie_cout_actualise_dans_cout_standard(self,obj):
        vals={
            'cout_std_matiere'    : obj.cout_act_matiere,
            'cout_std_condition'  : obj.cout_act_condition,
            'cout_std_machine'    : obj.cout_act_machine,
            'cout_std_mo'         : obj.cout_act_mo,
            'cout_std_st'         : obj.cout_act_st,
            'cout_std_total'      : obj.cout_act_total,
            'cout_std_prix_vente' : obj.cout_act_prix_vente,
        }
        obj.write(vals)


    @api.multi
    def copie_cout_actualise_dans_cout_standard(self):
        for obj in self:
            self._copie_cout_actualise_dans_cout_standard(obj)




    @api.multi
    def _copie_cout_actualise_dans_cout_budget(self,obj):
        vals={
            'cout_budget_matiere'    : obj.cout_act_matiere,
            'cout_budget_condition'  : obj.cout_act_condition,
            'cout_budget_machine'    : obj.cout_act_machine,
            'cout_budget_mo'         : obj.cout_act_mo,
            'cout_budget_st'         : obj.cout_act_st,
            'cout_budget_total'      : obj.cout_act_total,
            'cout_budget_prix_vente' : obj.cout_act_prix_vente,
        }
        obj.write(vals)


    @api.multi
    def copie_cout_actualise_dans_cout_budget(self):
        for obj in self:
            self._copie_cout_actualise_dans_cout_budget(obj)










    @api.multi
    def initialisation_prix_vente_standard(self):
        for obj in self:
            obj.cout_std_prix_vente = obj.prix_vente-obj.amortissement_moule-obj.surcout_pre_serie

    @api.model
    def print_btn_report(self):
        threaded_calculation = threading.Thread(target=self.save_cout_report, args=())
        threaded_calculation.start()
        return True

    def save_cout_report(self):
        user = self.env['res.users'].browse(self._uid)
        with api.Environment.manage():
            new_cr = self.pool.cursor()
            self = self.with_env(self.env(cr=new_cr))
            report_service = 'is_plastigray.report_is_cout'
            #file_param  = self.env['ir.config_parameter'].get_param('path_report_pdf')
            db=self._cr.dbname
            path="/tmp/couts-" + db
            cde="rm -Rf " + path
            os.popen(cde).readlines()
            if not os.path.exists(path):
                os.makedirs(path)
            recs=self.search([], order="name",limit=50000)
            nb=len(recs)
            _logger.info("#### Début sauvegarde Coûts ####")
            ct=0
            for rec in recs:
                ct=ct+1
                code_pg=rec.name.is_code
                _logger.info('- '+str(ct)+'/'+str(nb)+' : '+str(code_pg))
                result, format = self.env['report'].get_pdf(rec, report_service), 'pdf'
                file_name = path + '/'+str(code_pg) +'.pdf'
                fd = os.open(file_name,os.O_RDWR|os.O_CREAT)
                try:
                    os.write(fd, result)
                finally:
                    os.close(fd)
            filename="/var/www/odoo/couts/"+db+".zip"
            cde="rm -f " + filename + " && cd /tmp && zip -r " + filename + " couts-" +db+" && chmod 755 "+filename
            os.popen(cde).readlines()
            self.send_mail_notyfy_user()
            new_cr.close()
            _logger.info("#### Fin sauvegarde Coûts ####")
            return {}

    def send_mail_notyfy_user(self):
        db=self._cr.dbname
        user = self.env['res.users'].browse(self._uid)
        mail_pool = self.env['mail.mail']
        values={}
        values.update({'subject': 'Génération des PDF des coûts terminée'})
        values.update({'email_from': user.partner_id.email})
        values.update({'email_to': user.partner_id.email})
        values.update({'body_html': '<p>Bonjour,</p><p>Le zip contenant tous les PDF est disponible <a href="http://odoo/couts/'+db+'.zip">ici</a></p>' })
        #values.update({'body': 'Bonjour,\nLe zip contenant tous les PDF est disonible ici http://odoo/couts-odoo1.zip' })
#         values.update({'res_id': 'obj.id' }) #[optional] here is the record id, where you want to post that email after sending
        values.update({'model': 'is.cout' }) #[optional] here is the object(like 'project.project')  to whose record id you want to post that email after sending
        msg_id = mail_pool.sudo().create(values)
        # And then call send function of the mail.mail,
        if msg_id:
            msg_id.send()
        return True

    @api.multi
    def cout_standard_indice_precedent(self):
        if len(self)>1:
            raise Warning(u"Modification multiple non autorisée !")
        for obj in self:
            is_code=obj.name.is_code
            indice=is_code[6:7]
            if indice=='':
                raise Warning(u"Code sans indice !")
            code=is_code[0:6]
            if indice!='A':
                code=code+chr(ord(indice)-1)
            couts=self.env['is.cout'].search([('name.is_code', '=', code)])
            if len(couts)==0:
                raise Warning(u"Coût précédent non trouvé !")
            for cout in couts:
                obj.cout_std_matiere    = cout.cout_std_matiere
                obj.cout_std_condition  = cout.cout_std_condition
                obj.cout_std_machine    = cout.cout_std_machine
                obj.cout_std_mo         = cout.cout_std_mo
                obj.cout_std_st         = cout.cout_std_st
                obj.cout_std_total      = cout.cout_std_total
                obj.cout_std_prix_vente = cout.cout_std_prix_vente
コード例 #17
0
class PurchaseRequestLine(models.Model):

    _name = "purchase.request.line"
    _description = "Purchase Request Line"
    _inherit = ['mail.thread', 'ir.needaction_mixin']

    @api.multi
    @api.depends('product_id', 'name', 'product_uom_id', 'product_qty',
                 'analytic_account_id', 'date_required', 'specifications')
    def _compute_is_editable(self):
        for rec in self:
            if rec.request_id.state in ('to_approve', 'approved', 'rejected'):
                rec.is_editable = False
            else:
                rec.is_editable = True

    @api.multi
    def _compute_supplier_id(self):
        for rec in self:
            if rec.product_id:
                if rec.product_id.seller_ids:
                    rec.supplier_id = rec.product_id.seller_ids[0].name

    product_id = fields.Many2one('product.product',
                                 'Product',
                                 domain=[('purchase_ok', '=', True)],
                                 track_visibility='onchange')
    name = fields.Char('Description', size=256, track_visibility='onchange')
    product_uom_id = fields.Many2one('product.uom',
                                     'Product Unit of Measure',
                                     track_visibility='onchange')
    product_qty = fields.Float(
        'Quantity',
        track_visibility='onchange',
        digits_compute=dp.get_precision('Product Unit of Measure'))
    product_price = fields.Float('Price', track_visibility='onchange')
    accepted = fields.Boolean('Accepted', track_visibility='onchange')
    request_id = fields.Many2one('purchase.request',
                                 'Purchase Request',
                                 ondelete='cascade',
                                 readonly=True)
    company_id = fields.Many2one('res.company',
                                 related='request_id.company_id',
                                 string='Company',
                                 store=True,
                                 readonly=True)
    analytic_account_id = fields.Many2one('account.analytic.account',
                                          'Analytic Account',
                                          track_visibility='onchange')
    requested_by = fields.Many2one('res.users',
                                   related='request_id.requested_by',
                                   string='Requested by',
                                   store=True,
                                   readonly=True)
    assigned_to = fields.Many2one('res.users',
                                  related='request_id.assigned_to',
                                  string='Assigned to',
                                  store=True,
                                  readonly=True)
    date_start = fields.Date(related='request_id.date_start',
                             string='Request Date',
                             readonly=True,
                             store=True)
    description = fields.Text(related='request_id.description',
                              string='Description',
                              readonly=True,
                              store=True)
    origin = fields.Char(related='request_id.origin',
                         size=32,
                         string='Source Document',
                         readonly=True,
                         store=True)
    date_required = fields.Date(string='Request Date',
                                required=True,
                                track_visibility='onchange',
                                default=fields.Date.context_today)
    is_editable = fields.Boolean(string='Is editable',
                                 compute="_compute_is_editable",
                                 readonly=True)
    specifications = fields.Text(string='Specifications')
    request_state = fields.Selection(string='Request state',
                                     readonly=True,
                                     related='request_id.state',
                                     selection=_STATES,
                                     store=True)
    supplier_id = fields.Many2one('res.partner',
                                  string='Preferred supplier',
                                  compute="_compute_supplier_id")

    procurement_id = fields.Many2one('procurement.order',
                                     'Procurement Order',
                                     readonly=True)

    attachment_ids = fields.Many2many('ir.attachment',
                                      'class_ir_attachments_rel', 'class_id',
                                      'attachment_id', 'Attachments')
    price_total = fields.Float(string='Total',
                               track_visibility='onchange',
                               compute="_compute_amount",
                               store=True)

    @api.onchange('product_id')
    def onchange_product_id(self):
        if self.product_id:
            name = self.product_id.name
            if self.product_id.code:
                name = '[%s] %s' % (name, self.product_id.code)
            if self.product_id.description_purchase:
                name += '\n' + self.product_id.description_purchase
            self.product_uom_id = self.product_id.uom_id.id
            self.product_qty = 1
            self.name = name

    @api.multi
    @api.depends('product_qty', 'product_price')
    def _compute_amount(self):
        if self.product_qty > 0:
            self.price_total = self.product_price * self.product_qty
コード例 #18
0
ファイル: res_partner.py プロジェクト: TinPlusIT05/tms
class res_partner(models.Model):

    _inherit = 'res.partner'

    # F#13145 In the tree view of partner,
    # replace the column Phone by "Phone/Mobile"

    @api.multi
    def _get_full_phone(self):
        for record in self:
            full_phone = []
            if record.phone:
                full_phone.append(record.phone)
            if record.mobile:
                full_phone.append(record.mobile)
            record.phone_mobile = " / ".join(full_phone) if full_phone else ''

    @api.depends('is_company')
    def _get_title_domain(self):
        """
        Use for the domain on field Title:
        - NOT Is Company: titles with type `contact`
        - Is Company: titles with type `partner`
        """
        for record in self:
            if record.is_company:
                record.title_domain = 'partner'
            else:
                record.title_domain = 'contact'

    phone_mobile = fields.Char(compute='_get_full_phone',
                               string='Phone/Mobile')

    event_ids = fields.One2many(comodel_name='trobz.crm.event',
                                inverse_name='partner_id',
                                string='Events')
    lead_ids = fields.One2many(comodel_name='crm.lead',
                               inverse_name='partner_id',
                               string='Leads')
    skype_contact = fields.Char('Skype Contact', size=64)
    linkedin_profile = fields.Char('Linkedin Profile', size=64)
    create_uid = fields.Many2one(comodel_name='res.users', string='Creator')
    create_date = fields.Datetime('Creation Date')
    prospect = fields.Boolean(
        'Prospect', help="Check this box if this contact is a prospect.")
    business_sector_id = fields.Many2one(
        comodel_name='trobz.crm.business.sector', string='Business Sector')
    title_domain = fields.Selection([('contact', 'Contact'),
                                     ('partner', 'Partner')],
                                    'Title Domain',
                                    compute='_get_title_domain',
                                    store=True)

    @api.onchange('customer')
    def check_cutomer(self):
        if self.customer:
            self.prospect = False

    @api.onchange('prospect')
    def check_prospect(self):
        if self.prospect:
            self.customer = False

    @api.onchange('parent_id')
    def onchange_parent_id(self):
        if self.parent_id:
            self.customer = self.parent_id.customer
            self.prospect = self.parent_id.prospect
            self.supplier = self.parent_id.supplier

    # Can not migrate this function because onchange_state is called from Odoo
    def onchange_state(self, cr, uid, ids, state_id, context=None):
        if state_id:
            country_id = self.pool.get('res.country.state').browse(
                cr, uid, state_id, context).country_id.id
            return {'value': {'country_id': country_id}}
        return {}

    @api.model
    def default_get(self, fields):
        ctx = self._context and self._context.copy() or {}
        res = super(res_partner, self).default_get(fields)
        res.update({
            'is_company': False,
        })

        # F#12640 : Update Related User and company for Partner.contact
        # Get customer/prospect/supplier like company
        if ctx.get('default_parent_id', False):
            parent_obj = self.browse(ctx['default_parent_id'])
            res.update({
                'customer': parent_obj.customer,
                'prospect': parent_obj.prospect,
                'supplier': parent_obj.supplier,
                'use_parent_address': True,
            })

        return res

    @api.multi
    def write(self, vals):
        context = self._context and self._context.copy() or {}
        context.update({'from_partner': 1})
        res = super(res_partner, self).write(vals)
        # F#12640: For partner set as is_company, when updating the fields
        # ‘Customer/Supplier/Prospect’, automatically set the same value
        # on the contacts of that company.
        child_new_vals = {}
        if 'customer' in vals:
            child_new_vals['customer'] = vals.get('customer', False)
        if 'prospect' in vals:
            child_new_vals['prospect'] = vals.get('prospect', False)
        if 'supplier' in vals:
            child_new_vals['supplier'] = vals.get('supplier', False)

        if child_new_vals:
            for parent_obj in self:
                if parent_obj.is_company and parent_obj.child_ids:
                    parent_obj.child_ids.write(child_new_vals)
        return res

    @api.multi
    def name_get(self):
        context = self._context or {}
        if not self:
            return []
        res = []
        for r in self:
            if context.get('contact_display', 'contact') == 'partner' and \
                    r.parent_id:
                res.append((r.id, r.parent_id.id))
            else:
                res.append((r.id, r.name or '/'))
        return res

    @api.model
    def name_search(self, name='', args=None, operator='ilike', limit=100):
        if not args:
            args = []
        context = dict(self._context)
        if 'crm_partner_id' in context:
            crm_partner_id = context.get('crm_partner_id', False)
            if not crm_partner_id:
                args = [('id', 'in', [])]
            else:
                partners = self.env['res.partner'].search([('id', '=',
                                                            crm_partner_id)])
                if partners:
                    partner = partners[0]
                    contact_ids = [contact.id for contact in partner.child_ids]
                    args = [('id', 'in', contact_ids)]

        return super(res_partner, self).name_search(name=name,
                                                    args=args,
                                                    operator=operator,
                                                    limit=limit)
コード例 #19
0
class Task(models.Model):
    _name = "hc.res.task"
    _description = "Task"

    identifier_id = fields.One2many(comodel_name="hc.task.identifier",
                                    inverse_name="task_id",
                                    string="Identifier",
                                    help="Task Instance Identifier.")
    definition_type = fields.Selection(
        string="Defintion Type",
        selection=[("uri", "URI"),
                   ("activity_definition", "Activity Definition")],
        help="Type of formal definition of task.")
    definition_name = fields.Char(string="Definition",
                                  help="Formal definition of task.")
    definition_uri = fields.Char(string="Definition URI",
                                 help="URI of formal definition of task.")
    definition_activity_definition_id = fields.Many2one(
        comodel_name="hc.res.activity.definition",
        string="Definition Activity Definition",
        help="Activity Definition formal definition of task.")
    based_on_ids = fields.One2many(comodel_name="hc.task.based.on",
                                   inverse_name="task_id",
                                   string="Based Ons",
                                   help="Request fulfilled by this request.")
    group_identifier_id = fields.Many2one(
        comodel_name="hc.task.group.identifier",
        string="Group Identifier",
        help="Identifier of requisition or grouper id.")
    part_of_ids = fields.One2many(comodel_name="hc.task.part.of",
                                  inverse_name="task_id",
                                  string="Part Of",
                                  help="Identifier of composite task.")
    status = fields.Selection(string="Task Status",
                              required="True",
                              selection=[("draft", "Draft"),
                                         ("requested", "Requested"),
                                         ("received", "Received"),
                                         ("accepted", "Accepted")],
                              help="The current status of the task.")
    status_history_ids = fields.One2many(
        comodel_name="hc.task.status.history",
        inverse_name="task_id",
        string="Status History",
        help="The status of the task over time.")
    status_reason_id = fields.Many2one(comodel_name="hc.vs.task.status.reason",
                                       string="Status Reason",
                                       help="Reason for current status.")
    business_status_id = fields.Many2one(
        comodel_name="hc.vs.task.business.status",
        string="Business Status",
        help='E.g. "Specimen collected", "IV prepped".')
    intent = fields.Selection(
        string="Intent",
        required="True",
        selection=[("proposal", "Proposal"), ("plan", "Plan"),
                   ("order", "Order")],
        help=
        'Indicates the "level" of actionability associated with the Task. I.e. Is this a proposed task, a planned task, an actionable task, etc.'
    )
    priority = fields.Selection(
        string="Priority",
        selection=[("normal", "Normal"), ("urgent", "Urgent"),
                   ("asap", "Asap"), ("stat", "Stat")],
        help=
        "Indicates how quickly the Task should be addressed with respect to other requests."
    )
    code_id = fields.Many2one(
        comodel_name="hc.vs.task.type",
        string="Code",
        help=
        "A name or code (or both) briefly describing what the task involves..")
    description = fields.Text(string="Description",
                              help="Human-readable explanation of task.")
    focus_id = fields.Many2one(comodel_name="hc.task.focus",
                               string="Focus",
                               help="What task is acting on.")
    for_id = fields.Many2one(comodel_name="hc.task.for",
                             string="For",
                             help="Beneficiary of the Task.")
    context_type = fields.Selection(string="Context Type",
                                    selection=[("encounter", "Encounter"),
                                               ("episode_of_care",
                                                "Episode Of Care")],
                                    help="Type of supplemental instruction.")
    context_name = fields.Char(
        string="Context",
        compute="_compute_context_name",
        store="True",
        help="Healthcare event during which this task originated.")
    context_encounter_id = fields.Many2one(
        comodel_name="hc.res.encounter",
        string="Context Encounter",
        help="Encounter healthcare event during which this task originated.")
    context_episode_of_care_id = fields.Many2one(
        comodel_name="hc.res.episode.of.care",
        string="Context Episode Of Care",
        help=
        "Episode Of Care healthcare event during which this task originated.")
    execution_period_start_date = fields.Datetime(
        string="Execution Period Start Date", help="Start of execution.")
    execution_period_end_date = fields.Datetime(
        string="Execution Period End Date", help="End of execution.")
    authored_on = fields.Datetime(string="Authored On",
                                  help="Task Creation Date.")
    last_modified = fields.Datetime(string="Last Modified",
                                    required="True",
                                    help="Task Last Modified Date.")
    performer_type_ids = fields.Many2many(
        comodel_name="hc.vs.task.performer.type",
        string="Performer Types",
        help="The type of participant that can execute the task.")
    owner_type = fields.Selection(string="Owner Type",
                                  selection=[("device", "Device"),
                                             ("organization", "Organization"),
                                             ("patient", "Patient"),
                                             ("practitioner", "Practitioner"),
                                             ("related_person",
                                              "Related Person")],
                                  help="Type of task owner.")
    owner_name = fields.Char(string="Owner",
                             compute="_compute_owner_name",
                             store="True",
                             help="Task Owner.")
    owner_device_id = fields.Many2one(comodel_name="hc.res.device",
                                      string="Owner Device",
                                      help="Device responsible individual.")
    owner_organization_id = fields.Many2one(
        comodel_name="hc.res.organization",
        string="Owner Organization",
        help="Organization responsible individual.")
    owner_patient_id = fields.Many2one(comodel_name="hc.res.patient",
                                       string="Owner Patient",
                                       help="Patient responsible individual.")
    owner_practitioner_id = fields.Many2one(
        comodel_name="hc.res.practitioner",
        string="Owner Practitioner",
        help="Practitioner responsible individual.")
    owner_related_person_id = fields.Many2one(
        comodel_name="hc.res.related.person",
        string="Owner Related Person",
        help="Related Person responsible individual.")
    reason_id = fields.Many2one(comodel_name="hc.vs.task.reason",
                                string="Reason",
                                help="Why task is needed.")
    note_ids = fields.One2many(comodel_name="hc.task.note",
                               inverse_name="task_id",
                               string="Notes",
                               help="Comments made about the task.")
    relevant_history_ids = fields.One2many(
        comodel_name="hc.task.relevant.history",
        inverse_name="task_id",
        string="Relevant Histories",
        help="Identifier of key events in history of the task.")
    requester_id = fields.Many2one(comodel_name="hc.task.requester",
                                   string="Requester",
                                   help="Who is asking for task to be done.")
    restriction_id = fields.Many2one(comodel_name="hc.task.restriction",
                                     string="Restriction",
                                     help="Constraints on fulfillment tasks.")
    input_ids = fields.One2many(comodel_name="hc.task.input",
                                inverse_name="task_id",
                                string="Inputs",
                                help="Task Input.")
    output_ids = fields.One2many(comodel_name="hc.task.output",
                                 inverse_name="task_id",
                                 string="Outputs",
                                 help="Task Output.")

    @api.model
    def create(self, vals):
        business_status_history_obj = self.env[
            'hc.task.business.status.history']
        status_history_obj = self.env['hc.task.status.history']
        res = super(Condition, self).create(vals)

        # For Status
        if vals and vals.get('status'):
            status_history_vals = {
                'task_id': res.id,
                'status': res.status,
                'start_date': datetime.today()
            }
            if vals.get('status') == 'entered-in-error':
                status_history_vals.update({'end_date': datetime.today()})
            status_history_obj.create(status_history_vals)

        # For Business Status
        if vals.get('status') != 'entered-in-error':
            if vals and vals.get('business_status_id'):
                business_status_history_vals = {
                    'task_id': res.id,
                    'business_status_id': res.business_status_id,
                    'start_date': datetime.today()
                }
                business_status_history_obj.create(
                    business_status_history_vals)
        return res

    @api.multi
    def write(self, vals):
        business_status_history_obj = self.env[
            'hc.task.business.status.history']
        status_history_obj = self.env['hc.task.status.history']
        res = super(Condition, self).write(vals)

        # For Status
        status_history_record_ids = status_history_obj.search([('end_date',
                                                                '=', False)])
        if status_history_record_ids:
            if vals.get('status') and status_history_record_ids[
                    0].status != vals.get('status'):
                for status_history in status_history_record_ids:
                    status_history.end_date = datetime.strftime(
                        datetime.today(), DTF)
                    time_diff = datetime.today() - datetime.strptime(
                        status_history.start_date, DTF)
                    if time_diff:
                        days = str(time_diff).split(',')
                        if days and len(days) > 1:
                            status_history.time_diff_day = str(days[0])
                            times = str(days[1]).split(':')
                            if times and times > 1:
                                status_history.time_diff_hour = str(times[0])
                                status_history.time_diff_min = str(times[1])
                                status_history.time_diff_sec = str(times[2])
                        else:
                            times = str(time_diff).split(':')
                            if times and times > 1:
                                status_history.time_diff_hour = str(times[0])
                                status_history.time_diff_min = str(times[1])
                                status_history.time_diff_sec = str(times[2])
                status_history_vals = {
                    'task_id': self.id,
                    'status': vals.get('status'),
                    'start_date': datetime.today()
                }
                if vals.get('status') == 'entered-in-error':
                    status_history_vals.update({'end_date': datetime.today()})
                status_history_obj.create(status_history_vals)

        # For Clinical Status
        business_status_history_record_ids = business_status_history_obj.search(
            [('end_date', '=', False)])
        if business_status_history_record_ids:
            if vals.get('status') == 'entered-in-error' or (
                    vals.get('business_status_id') and
                    business_status_history_record_ids[0].business_status_id !=
                    vals.get('business_status_id')):
                for business_status_history in business_status_history_record_ids:
                    business_status_history.end_date = datetime.strftime(
                        datetime.today(), DTF)
                    time_diff = datetime.today() - datetime.strptime(
                        business_status_history.start_date, DTF)
                    if time_diff:
                        days = str(time_diff).split(',')
                        if days and len(days) > 1:
                            business_status_history.time_diff_day = str(
                                days[0])
                            times = str(days[1]).split(':')
                            if times and times > 1:
                                business_status_history.time_diff_hour = str(
                                    times[0])
                                business_status_history.time_diff_min = str(
                                    times[1])
                                business_status_history.time_diff_sec = str(
                                    times[2])
                        else:
                            times = str(time_diff).split(':')
                            if times and times > 1:
                                business_status_history.time_diff_hour = str(
                                    times[0])
                                business_status_history.time_diff_min = str(
                                    times[1])
                                business_status_history.time_diff_sec = str(
                                    times[2])
                    business_status_history_vals = {
                        'task_id': self.id,
                        'business_status_id': vals.get('business_status_id'),
                        'start_date': datetime.today()
                    }
                    if vals.get('status') == 'entered-in-error':
                        business_status_history_vals.update(
                            {'end_date': datetime.today()})
                    if vals.get('status') != 'entered-in-error':
                        business_status_history_obj.create(
                            business_status_history_vals)
        else:
            business_status_history_vals = {
                'task_id': self.id,
                'business_status_id': vals.get('business_status_id'),
                'start_date': datetime.today()
            }
            if vals.get('status') == 'entered-in-error':
                business_status_history_vals.update(
                    {'end_date': datetime.today()})
            business_status_history_obj.create(business_status_history_vals)
        return res
コード例 #20
0
class banking_export_ch_dd(models.Model):

    ''' Swiss Direct Debit export containing the file created
        by the appropriate wizard
    '''
    _name = 'banking.export.ch.dd'
    _rec_name = 'filename'

    def _generate_filename(self):
        self.ensure_one()
        ref = self.env['ir.sequence'].next_by_code(
            'l10n.banking.export.filename')
        username = self.env.user.name
        initials = ''.join([subname[0] for subname in username.split()])
        if self.type == 'LSV':
            res = 'lsv_%s_%s.lsv' % (ref, initials)
        else:
            res = 'dd_%s_%s.dd' % (ref, initials)
        self.filename = res
        return True

    @api.model
    def create(self, vals):
        res = super(banking_export_ch_dd, self).create(vals)
        res._generate_filename()
        return res

    payment_order_ids = fields.Many2many(
        'payment.order',
        'account_payment_order_ch_dd_rel',
        'banking_export_ch_dd_id',
        'account_order_id',
        _('Payment Orders'),
        readonly=True
    )
    nb_transactions = fields.Integer(
        _('Number of Transactions'),
        readonly=True
    )
    total_amount = fields.Float(
        _('Total Amount'),
        readonly=True,
        digits_compute=dp.get_precision('Account')
    )
    create_date = fields.Datetime(
        _('Generation Date'),
        readonly=True
    )
    file = fields.Binary(
        _('Generated file'),
        readonly=True
    )
    filename = fields.Char(
        string=_('Filename'),
        size=256,
        readonly=True,
    )
    state = fields.Selection(
        [('draft', _('Draft')), ('sent', _('Sent'))],
        'State',
        readonly=True,
        default='draft'
    )
    type = fields.Char(
        _('Type'),
        size=128,
        readonly=True
    )
コード例 #21
0
ファイル: project.py プロジェクト: tate11/weiwen
class ProjectTask(models.Model):
    _inherit = 'project.task'
    state = fields.Selection(related='stage_id.state',
                             store=True,
                             readonly=True)
コード例 #22
0
class ResPartner(models.Model):
    _inherit = "res.partner"

    discount_computation = fields.Selection(
        selection=[('total', 'Total'), ('unit_price', 'Unit Price')],
        string="Discount Computation")
コード例 #23
0
ファイル: donation12-11-2.py プロジェクト: odoo-modules/Mee
class DonationLine(models.Model):
    _name = 'donation.line'
    _description = 'Donation Lines'
    _rec_name = 'product_id'

    @api.onchange('donation_id.donation_method')
    def onchange_donation_method(self):
        res = {}
        res['domain'] = {
            'product_id':
            [('donation_method', '=', donation_id.donation_method.id)]
        }
        return res

    @api.multi
    @api.depends('unit_price', 'quantity', 'donation_id.currency_id',
                 'donation_id.donation_date', 'donation_id.company_id')
    def _compute_amount_company_currency(self):
        for line in self:
            amount = line.quantity * line.unit_price
            line.amount = amount
            donation_currency = line.donation_id.currency_id.with_context(
                date=line.donation_id.donation_date)
            line.amount_company_currency = donation_currency.compute(
                amount, line.donation_id.company_id.currency_id)

    donation_id = fields.Many2one('donation.donation',
                                  string='Donation',
                                  ondelete='cascade')
    recipt_number = fields.Char(string='Recipt Number', size=32)
    state = fields.Selection([
        (1, 'Draft'),
        (2, 'Transfer'),
        (3, 'Done'),
        (4, 'Cancelled'),
    ],
                             string='State',
                             related='donation_id.state',
                             readonly=True,
                             copy=False,
                             default=1,
                             index=True,
                             track_visibility='onchange')
    currency_id = fields.Many2one('res.currency',
                                  related='donation_id.currency_id',
                                  readonly=True)
    company_currency_id = fields.Many2one(
        'res.currency',
        related='donation_id.company_id.currency_id',
        readonly=True)
    product_id = fields.Many2one('product.product',
                                 related='donation_id.product_id',
                                 readonly=True,
                                 store=True,
                                 string='Product',
                                 ondelete='restrict')

    gov_id = fields.Many2one('govs.villages.gov',
                             related='donation_id.gov_id',
                             readonly=True,
                             store=True,
                             string='Gov',
                             ondelete='restrict')

    donation_date = fields.Date(related='donation_id.donation_date',
                                readonly=True,
                                store=True,
                                string='Date')
    donation_place = fields.Many2one('donation.place',
                                     related='donation_id.donation_place',
                                     readonly=True,
                                     store=True,
                                     string='Place')
    partner_id = fields.Many2one('res.partner',
                                 string='Donor',
                                 required=True,
                                 index=True,
                                 track_visibility='onchange',
                                 ondelete='restrict')
    donation_by = fields.Many2one('res.users',
                                  string='Donation by',
                                  related='donation_id.donation_by',
                                  readonly=True,
                                  store=True)
    donation_collector = fields.Many2one('res.partner',
                                         string='Collector',
                                         track_visibility='onchange')
    quantity = fields.Integer(string='Quantity', default=1)
    unit_price = fields.Monetary(string='Unit Price',
                                 digits=dp.get_precision('Account'),
                                 currency_field='currency_id')
    amount = fields.Monetary(compute='_compute_amount_company_currency',
                             string='Amount',
                             currency_field='currency_id',
                             digits=dp.get_precision('Account'),
                             store=True)
    amount_company_currency = fields.Monetary(
        compute='_compute_amount_company_currency',
        string='Amount in Company Currency',
        currency_field='company_currency_id',
        digits=dp.get_precision('Account'),
        store=True)
    campaign_id = fields.Many2one(
        'donation.campaign',
        string='Donation Campaign',
        track_visibility='onchange',
        ondelete='restrict',
        default=lambda self: self.env.user.context_donation_campaign_id)
    analytic_account_id = fields.Many2one('account.analytic.account',
                                          string='Analytic Account',
                                          domain=[('account_type', '!=',
                                                   'closed')],
                                          ondelete='restrict')
    #campaign_id = fields.Many2one(
    analytic_account2 = fields.Many2one(
        'account.analytic.account',
        related='campaign_id.analytic_account_id',
        string='Analytic Account',
        readonly=True,
        store=True)
    account_id = fields.Many2one(
        'account.account',
        related='donation_id.donation_place.account_id',
        string='Account',
        readonly=True,
        store=True)
    #analytic2 = fields.Integer(string = 'id', compute='get_analytic_account_id_3',store=True)
    #analytic3 = fields.Integer(string = 'id2',related='analytic_account_id.id' ,store=True)
    sequence = fields.Integer('Sequence')
    # for the fields tax_receipt_ok and in_kind, we made an important change
    # between v8 and v9: in v8, it was a reglar field set by an onchange
    # in v9, it is a related stored field
    tax_receipt_ok = fields.Boolean(related='product_id.tax_receipt_ok',
                                    readonly=True,
                                    store=True)
    donation_method = fields.Many2one(related='donation_id.donation_method',
                                      readonly=True,
                                      store=True,
                                      string='Method')
    in_kind = fields.Boolean(related='product_id.in_kind_donation',
                             readonly=True,
                             store=True,
                             string='In Kind')
    tags_id = fields.Many2many('account.analytic.tag',
                               string='Tags',
                               readonly=True)

    @api.onchange('donation_id.product_id')
    def product_id_change(self):
        if donation_id.product_id:
            # We should change that one day...
            if donation_id.product_id.list_price:
                self.unit_price = donation_id.product_id.list_price

            #self.env.cr.execute("INSERT INTO account_analytic_tag_donation_line_rel(donation_line_id, account_analytic_tag_id)VALUES ('%s', '%d')" %(self.id,))

    #@api.one
    #@api.depends('analytic_account_id', 'analytic_account2')
    #@api.model
    #def get_analytic_account_id_3(self):
    #for rec in self:
    #rec.env.cr.execute("SELECT method.tag_id FROM donation_line inner join donation_instrument as method on donation_line.donation_method = method.id where donation_line.id= '%s'" %(rec.id))
    #res = rec.env.cr.fetchone()[0]
    #rec.env.cr.execute("insert INTO account_analytic_tag_donation_line_rel(donation_line_id, account_analytic_tag_id) VALUES ('%s','%s')" %(rec.id,res))11
    #rec.analytic_tag = 1
    #@api.one
    #@api.depends('analytic_account2')
    #@api.model
    #def get_analytic_account_id_2(self):
    #self.analytic2 = self.analytic_account_id.id
    #   return self.analytic_account2.id or False
    #return self.analytic_account_id.id or False

    @api.model
    def get_analytic_account_id(self):
        #self.analytic2 = self.analytic_account_id.id
        return self.analytic_account2.id or False
        #return self.analytic_account_id.id or False
    @api.model
    def get_account_id(self):
        #self.analytic2 = self.analytic_account_id.id
        return self.account_id.id or False
コード例 #24
0
ファイル: account_move.py プロジェクト: pabi2/pb2_addons
class AccountMove(models.Model):
    _inherit = 'account.move'

    document = fields.Char(
        string='Document',
        compute='_compute_document',
        store=True,
        readonly=True,
    )
    document_id = fields.Reference(
        REFERENCE_SELECT,
        string='Document',
        compute='_compute_document',
        store=True,
        readonly=True,
    )
    doctype = fields.Selection(
        DOCTYPE_SELECT,
        string='Doctype',
        compute='_compute_document',
        store=True,
        index=True,
        help="Use selection as refer_type in res_doctype",
    )
    date_value = fields.Date(
        string='Value Date',
        compute='_compute_document',
        store=True,
        help="If origin document have value date. Otherwise, use move date",
    )
    invoice_ids = fields.One2many(
        'account.invoice',
        'move_id',
        string='Invoice',
        readonly=True,
    )
    invoice_cancel_ids = fields.One2many(
        'account.invoice',
        'cancel_move_id',
        string='Invoice Cancel',
        readonly=True,
    )
    invoice_clear_prepaid_ids = fields.One2many(
        'account.invoice',
        'clear_prepaid_move_id',
        string='Invoice Clear Prepaid',
        readonly=True,
    )
    voucher_ids = fields.One2many(
        'account.voucher',
        'move_id',
        string='Payment',
        readonly=True,
    )
    voucher_cancel_ids = fields.One2many(
        'account.voucher',
        'cancel_move_id',
        string='Payment Cancel',
        readonly=True,
    )
    voucher_recognize_vat_ids = fields.One2many(
        'account.voucher',
        'recognize_vat_move_id',
        string='Payment Recognize VAT',
        readonly=True,
    )
    bank_receipt_ids = fields.One2many(
        'account.bank.receipt',
        'move_id',
        string='Bank Receipt',
        readonly=True,
    )
    bank_receipt_cancel_ids = fields.One2many(
        'account.bank.receipt',
        'cancel_move_id',
        string='Bank Receipt Cancel',
        readonly=True,
    )
    salary_expense_ids = fields.One2many(
        'hr.salary.expense',
        'move_id',
        string='Salary Expense',
        readonly=True,
    )
    salary_expense_cancel_ids = fields.One2many(
        'hr.salary.expense',
        'cancel_move_id',
        string='Salary Expense Cancel',
        readonly=True,
    )
    expense_rev_ic_ids = fields.One2many(
        'hr.expense.expense',
        'rev_ic_move_id',
        string='IC Revenue',
        readonly=True,
    )
    expense_exp_ic_ids = fields.One2many(
        'hr.expense.expense',
        'exp_ic_move_id',
        string='IC Expense',
        readonly=True,
    )
    account_interface_ids = fields.One2many(
        'interface.account.entry',
        'move_id',
        string='Account Interface',
        readonly=True,
    )

    @api.multi
    @api.depends('invoice_ids.internal_number',
                 'invoice_cancel_ids.internal_number',
                 'invoice_clear_prepaid_ids.internal_number',
                 'voucher_ids.number',
                 'voucher_cancel_ids.number',
                 'voucher_recognize_vat_ids.number',
                 'bank_receipt_ids.name',
                 'bank_receipt_cancel_ids.name',
                 'salary_expense_ids.name',
                 'salary_expense_cancel_ids.name',
                 'expense_rev_ic_ids.number',
                 'expense_exp_ic_ids.number',
                 'account_interface_ids.number',
                 'ref',  # check for stock.picking case, as it has no move_id
                 )
    def _compute_document(self):
        for rec in self:
            document = False
            # Invoice
            if rec.invoice_ids:
                document = rec.invoice_ids[0]
            elif rec.invoice_cancel_ids:
                document = rec.invoice_cancel_ids[0]
            elif rec.invoice_clear_prepaid_ids:
                document = rec.invoice_clear_prepaid_ids[0]
            # Voucher
            elif rec.voucher_ids:
                document = rec.voucher_ids[0]
            elif rec.voucher_cancel_ids:
                document = rec.voucher_cancel_ids[0]
            elif rec.voucher_recognize_vat_ids:
                document = rec.voucher_recognize_vat_ids[0]
            # Bank Receipt
            elif rec.bank_receipt_ids:
                document = rec.bank_receipt_ids[0]
            elif rec.bank_receipt_cancel_ids:
                document = rec.bank_receipt_cancel_ids[0]
            # Salary Expense
            elif rec.salary_expense_ids:
                document = rec.salary_expense_ids[0]
            elif rec.salary_expense_cancel_ids:
                document = rec.salary_expense_cancel_ids[0]
            # Expense IC
            elif rec.expense_rev_ic_ids:
                document = rec.expense_rev_ic_ids[0]
            elif rec.expense_exp_ic_ids:
                document = rec.expense_exp_ic_ids[0]
            # Account Interface
            elif rec.account_interface_ids:
                document = rec.account_interface_ids[0]
            elif rec.ref:  # Last chance for picking, as it not have move_id
                Picking = self.env['stock.picking']
                picking = Picking.search([('name', '=', rec.ref)])
                document = picking and picking[0] or False

            # Assign reference
            if document:
                rec.document_id = '%s,%s' % (document._name, document.id)
                if document._name in ('stock.picking', 'account.bank.receipt'):
                    rec.document = document.name
                elif document._name == 'account.invoice':
                    rec.document = document.internal_number
                else:
                    rec.document = document.number
                rec.doctype = self._get_doctype(document._name, document)
                if 'date_value' in document._fields:
                    rec.date_value = document.date_value
            else:
                rec.doctype = 'adjustment'  # <-- Not related to any doc
            if not rec.date_value:
                rec.date_value = rec.date  # No Value Date, same as date

    @api.model
    def _get_doctype(self, model, document):
        if model == 'account.invoice':
            return INVOICE_DOCTYPE[document.journal_id.type]
        if model == 'account.voucher':
            return VOUCHER_DOCTYPE[document.type]
        if model == 'account.bank.receipt':
            return 'bank_receipt'
        if model == 'hr.expense.expense':
            return 'employee_expense'
        if model == 'hr.salary.expense':
            return 'salary_expense'
        if model == 'stock.picking':
            return PICKING_DOCTYPE[document.picking_type_id.code]
        if model == 'interface.account.entry':
            return 'interface_account'
コード例 #25
0
ファイル: budget_plan_unit.py プロジェクト: BTCTON/pb2_addons
class BudgetPlanUnitLine(BPLMonthCommon, ActivityCommon, models.Model):
    _name = 'budget.plan.unit.line'
    _description = "Unit - Budget Plan Line"
    _rec_name = 'activity_group_id'

    charge_type = fields.Selection(
        [('internal', 'Internal'), ('external', 'External')],
        string='Charge Type',
        required=True,
        default='external',
        help="Specify whether the budget plan line is for Internal Charge or "
        "External Charge. Internal charged is for Unit Based only.")
    # COMMON
    chart_view = fields.Selection(
        default='unit_base',  # Unit
    )
    plan_id = fields.Many2one(
        'budget.plan.unit',
        string='Budget Plan',
        ondelete='cascade',
        index=True,
        required=True,
    )
    # Extra
    section_id = fields.Many2one(
        related='plan_id.section_id',
        string='Section',
        store=True,
        readonly=True,
    )
    section_name = fields.Char(
        related='section_id.name',
        string='Section Name',
        store=True,
        readonly=True,
    )
    section_name_short = fields.Char(
        related='section_id.name_short',
        string='Section Alias',
        store=True,
        readonly=True,
    )
    section_code = fields.Char(
        related='section_id.code',
        string='Section Code',
        store=True,
        readonly=True,
    )
    section_program_id = fields.Many2one(
        related='plan_id.section_id.section_program_id',
        string='Section Program',
        store=True,
        readonly=True,
    )
    mission_id = fields.Many2one(
        related='section_id.mission_id',
        string='Mission',
        store=True,
        readonly=True,
    )
    # program_rpt_id = fields.Many2one(
    #     related='section_id.program_rpt_id',
    #     string='Program',
    #     store=True,
    #     readonly=True,
    # )
    division_id = fields.Many2one(
        related='plan_id.section_id.division_id',
        store=True,
        readonly=True,
    )
    subsector_id = fields.Many2one(
        related='plan_id.section_id.subsector_id',
        store=True,
        readonly=True,
    )
    sector_id = fields.Many2one(
        related='plan_id.section_id.sector_id',
        store=True,
        readonly=True,
    )
    org_id = fields.Many2one(
        related='plan_id.section_id.org_id',
        store=True,
        readonly=True,
    )
    cost_control_type_id = fields.Many2one(
        related='cost_control_id.cost_control_type_id',
        store=True,
        readonly=True,
    )
    unit = fields.Float(string='Unit', )
    activity_unit_price = fields.Float(string='Unit Price', )
    activity_unit = fields.Float(string='Activity Unit', )
    total_budget = fields.Float(string='Total Budget', )
    cost_control_code = fields.Char(
        related='cost_control_id.code',
        string='Job Order Code',
        readonly=True,
        store=True,
    )
    cost_control_name = fields.Char(
        related='cost_control_id.name',
        string='Job Order Name',
        readonly=True,
        store=True,
    )
    reason = fields.Text(string='Reason', )
    # Converted to equivalant status
    # status = fields.Selection(
    #     _STATUS,
    #     related='plan_id.status',
    #     string='Status',
    #     store=True,
    #     help="This virtual field is being used to sort the status in view",
    # )
    next_fy_commitment = fields.Float(
        string='Next FY Commitment',
        readonly=True,
        help="Comitment on next fy PR/PO/EX",
    )

    @api.model
    def search(self, args, offset=0, limit=None, order=None, count=False):
        """ Add additional filter criteria """
        return super(BudgetPlanUnitLine, self).search(self.search_args(args),
                                                      offset=offset,
                                                      limit=limit,
                                                      order=order,
                                                      count=count)
コード例 #26
0
class SaasServerClient(models.Model):
    _name = 'saas_server.client'
    _inherit = ['mail.thread', 'saas_base.client']

    name = fields.Char('Database name', readonly=True)
    client_id = fields.Char('Database UUID', readonly=True, select=True)
    state = fields.Selection([('template', 'Template'),
                              ('draft','New'),
                              ('open','In Progress'),
                              ('cancelled', 'Cancelled'),
                              ('pending','Pending'),
                              ('deleted','Deleted')],
                             'State', default='draft', track_visibility='onchange')

    _sql_constraints = [
        ('client_id_uniq', 'unique (client_id)', 'client_id should be unique!'),
    ]

    @api.one
    def create_database(self, template_db=None, demo=False, lang='en_US'):
        new_db = self.name
        if template_db:
            openerp.service.db._drop_conn(self.env.cr, template_db)
            openerp.service.db.exp_duplicate_database(template_db, new_db)
        else:
            password = ''.join(random.SystemRandom().choice(string.ascii_uppercase + string.digits) for _ in range(32))
            openerp.service.db.exp_create_database(new_db, demo, lang, user_password=password)
        self.state = 'open'

    @api.one
    def registry(self, new=False, **kwargs):
        m = openerp.modules.registry.RegistryManager
        if new:
            return m.new(self.name, **kwargs)
        else:
            return m.get(self.name, **kwargs)

    @api.one
    def install_addons(self, addons, is_template_db):
        addons = set(addons)
        addons.add('mail_delete_sent_by_footer')  # debug
        if is_template_db:
            addons.add('auth_oauth')
            addons.add('saas_client')
        else:
            addons.add('saas_client')
        if not addons:
            return
        with self.registry()[0].cursor() as cr:
            env = api.Environment(cr, SUPERUSER_ID, self._context)
            self._install_addons(env, addons)
    @api.one
    def disable_mail_servers(self):
        '''
        disables mailserver on db to stop it from sending and receiving mails
        '''
        # let's disable incoming mail servers
        incoming_mail_servers = self.env['fetchmail.server'].search([])
        if len(incoming_mail_servers):
            incoming_mail_servers.write({'active': False})
            
        # let's disable outgoing mailservers too
        outgoing_mail_servers = self.env['ir.mail_server'].search([])
        if len(outgoing_mail_servers):
            outgoing_mail_servers.write({'active': False})

    @api.one
    def _install_addons(self, client_env, addons):
        for addon in client_env['ir.module.module'].search([('name', 'in', list(addons))]):
            addon.button_install()

    @api.one
    def update_registry(self):
        self.registry(new=True, update_module=True)

    @api.one
    def prepare_database(self, **kwargs):
        with self.registry()[0].cursor() as cr:
            env = api.Environment(cr, SUPERUSER_ID, self._context)
            self._prepare_database(env, **kwargs)

    @api.model
    def _config_parameters_to_copy(self):
        return ['saas_client.ab_location', 'saas_client.ab_register']

    @api.one
    def _prepare_database(self, client_env, saas_portal_user=None, is_template_db=False, addons=[], access_token=None, tz=None):
        client_id = self.client_id

        # update saas_server.client state
        if is_template_db:
            self.state = 'template'

        # set tz
        if tz:
            client_env['res.users'].search([]).write({'tz': tz})
            client_env['ir.values'].set_default('res.partner', 'tz', tz)

        # update database.uuid
        client_env['ir.config_parameter'].set_param('database.uuid', client_id)

        # copy configs
        for key in self._config_parameters_to_copy():
            value = self.env['ir.config_parameter'].get_param(key, default='')
            client_env['ir.config_parameter'].set_param(key, value)

        # copy auth provider from saas_server
        saas_oauth_provider = self.env.ref('saas_server.saas_oauth_provider')
        oauth_provider = None
        if is_template_db and not client_env.ref('saas_server.saas_oauth_provider', raise_if_not_found=False):
            oauth_provider_data = {'enabled': False, 'client_id': client_id}
            for attr in ['name', 'auth_endpoint', 'scope', 'validation_endpoint', 'data_endpoint', 'css_class', 'body']:
                oauth_provider_data[attr] = getattr(saas_oauth_provider, attr)
            oauth_provider = client_env['auth.oauth.provider'].create(oauth_provider_data)
            client_env['ir.model.data'].create({
                'name': 'saas_oauth_provider',
                'module': 'saas_server',
                'noupdate': True,
                'model': 'auth.oauth.provider',
                'res_id': oauth_provider.id,
            })
        if not oauth_provider:
            oauth_provider = client_env.ref('saas_server.saas_oauth_provider')

        if not is_template_db:
            oauth_provider.client_id = client_id

        # prepare users
        OWNER_TEMPLATE_LOGIN = '******'
        user = None
        if is_template_db:
            client_env['res.users'].create({
                'login': OWNER_TEMPLATE_LOGIN,
                'name': 'NAME',
                'email': '*****@*****.**',
            })

            client_env['res.users'].browse(SUPERUSER_ID).write({
                'oauth_provider_id': oauth_provider.id,
                'oauth_uid': SUPERUSER_ID,
                'oauth_access_token': access_token
            })
        else:
            domain = [('login', '=', OWNER_TEMPLATE_LOGIN)]
            res = client_env['res.users'].search(domain)
            if res:
                user = res[0]
            res = client_env['res.users'].search([('login', '=', saas_portal_user['email'])])
            if res:
                # user already exists (e.g. administrator)
                user = res[0]
            if not user:
                user = client_env['res.users'].browse(SUPERUSER_ID)
            user.write({
                'login': saas_portal_user['email'],
                'name': saas_portal_user['name'],
                'email': saas_portal_user['email'],
                'oauth_provider_id': oauth_provider.id,
                'oauth_uid': saas_portal_user['user_id'],
                'oauth_access_token': access_token
            })


    @api.model
    def update_all(self):
        self.sudo().search([]).update()

    @api.one
    def update(self):
        try:
            registry = self.registry()[0]
        except psycopg2.OperationalError:
            if self.state != 'draft':
                self.state = 'deleted'
            return
        with registry.cursor() as client_cr:
            client_env = api.Environment(client_cr, SUPERUSER_ID, self._context)
            data = self._get_data(client_env, self.client_id)[0]
            self.write(data)

    @api.one
    def _get_data(self, client_env, check_client_id):
        client_id = client_env['ir.config_parameter'].get_param('database.uuid')
        if check_client_id != client_id:
            return {'state': 'deleted'}
        users = client_env['res.users'].search([('share', '=', False)])
        users_len = len(users)
        data_dir = openerp.tools.config['data_dir']

        file_storage = get_size('%s/filestore/%s' % (data_dir, self.name))
        file_storage = int(file_storage / (1024 * 1024))

        client_env.cr.execute("select pg_database_size('%s')" % self.name)
        db_storage = client_env.cr.fetchone()[0]
        db_storage = int(db_storage / (1024 * 1024))

        data = {
            'client_id': client_id,
            'users_len': users_len,
            'file_storage': file_storage,
            'db_storage': db_storage,
        }
        return data

    @api.one
    def upgrade_database(self, **kwargs):
        with self.registry()[0].cursor() as cr:
            env = api.Environment(cr, SUPERUSER_ID, self._context)
            return self._upgrade_database(env, **kwargs)[0]


    @api.one
    def _upgrade_database(self, client_env, data):
        # "data" comes from saas_portal/models/wizard.py::upgrade_database
        post = data
        module = client_env['ir.module.module']
        print '_upgrade_database', data
        # 1. Update addons
        update_addons = post.get('update_addons', [])
        if update_addons:
            module.search([('name', 'in', update_addons)]).button_immediate_upgrade()

        # 2. Install addons
        install_addons = post.get('install_addons', [])
        if install_addons:
            module.search([('name', 'in', install_addons)]).button_immediate_install()

        # 3. Uninstall addons
        uninstall_addons = post.get('uninstall_addons', [])
        if uninstall_addons:
            module.search([('name', 'in', uninstall_addons)]).button_immediate_uninstall()

        # 4. Run fixes
        fixes = post.get('fixes', [])
        for model, method in fixes:
            getattr(request.registry[model], method)()

        # 5. update parameters
        params = post.get('params', [])
        for key, value in params:
            client_env['ir.config_parameter'].set_param(key, value)

        return 'OK'

    @api.model
    def delete_expired_databases(self):
        now = time.strftime(DEFAULT_SERVER_DATETIME_FORMAT)
        res = self.search([('state','not in', ['deleted']), ('expiration_datetime', '<=', now)])
        _logger.info('delete_expired_databases %s', res)
        res.delete_database()

    @api.one
    def delete_database(self):
        openerp.service.db.exp_drop(self.name)
        self.write({'state': 'deleted'})
コード例 #27
0
ファイル: emp_data_wizard.py プロジェクト: wmde/tictac
class employee_data_export(models.TransientModel):

    _name = 'employee.data.export'

    name = fields.Binary('Timesheet CSV')
    file_name = fields.Char('File')
    report_selection = fields.Selection(
        [('export_employee', 'Personalübersicht'),
         ('export_workcouncil', 'BR Übersicht')],
        string='Report',
        default='export_employee',
        required=True)

    @api.multi
    def export_emp_data_csv(self):
        """
        This function is use to export the employee data records which are preselected.
        """

        if self._context and 'active_model' in self._context and self._context[
                'active_model'] == 'hr.employee':
            context = self._context.copy()
            hr_employee = self.env['hr.employee']
            if self.report_selection == 'export_workcouncil':
                hr_employee_records = hr_employee.search([
                    ('executive_employee', '=', False),
                    ('id', 'in', context['active_ids'])
                ])
            else:
                hr_employee_records = hr_employee.browse(context['active_ids'])
            # print"analytic_timesheet_records----",analytic_timesheet_records
            context = self.export_csv_subfunction(hr_employee_records)

            return {
                'name': _('Exported Employee Data'),
                'view_type': 'form',
                "view_mode": 'form',
                'res_model': 'employee.data.export',
                'type': 'ir.actions.act_window',
                'context': context,
                'target': 'new',
            }

    def get_date_format(self, date):
        if date:
            return datetime.strptime(date, '%Y-%m-%d').strftime('%d.%m.%Y')
        else:
            return ''

    def export_csv_subfunction(self, emp_data_records):
        """
        It is a subfunction for the export csv.
        """

        data_list = []
        if self._context.get(
                'for_work_council'
        ) or self.report_selection == 'export_workcouncil':
            csv_header = [
                'Personalnummer',
                'Vorname',
                'Nachname',
                'Bereich',
                'Team',
                'Stellenbezeichnung',
                'Vertragstyp',
                'Ersteintrittsdatum',
                'Enddatum befristeter Vertrag',
                'Befristungsgrund',
                'Probezeit Enddatum',
                'letztes MA Gespraech',
            ]
            csv_name = "Betriebsratsübersicht"

        else:
            csv_header = [
                'Personalnummer', 'Vorname', 'Nachname', 'Geburtstag',
                'Company', 'Bereich', 'Team', 'Planstellenbezeichnung',
                'Stellenbezeichnung', 'Vertragstyp', 'Ersteintrittsdatum',
                'Enddatum befristeter Vertrag', 'Befristungsgrund',
                'Probezeit Enddatum', 'letztes MA Gespraech',
                '5-Jahresjubilaeum', 'Arbeitszeit', 'Urlaub',
                'Schwerbehinderung', 'letzte Vertragsaenderung_L&G',
                'Startdatum der letzten Vertragversänderung', 'Verguetung',
                'Verguetung bei VZ', 'Verguetung inkl. AG Kosten (25%)',
                'BR Mitglied', 'Bemerkungen', 'Manager'
            ]
            csv_name = "Personalübersicht"
        time_csv = datetime.now().strftime('%Y-%m-%d_%H%M%S') + '.csv'
        csv_path = "/tmp/" + time_csv
        for emp_record in emp_data_records:

            if self._context.get(
                    'for_work_council'
            ) or self.report_selection == 'export_workcouncil':
                vals = {
                    'Personalnummer': (emp_record.identification_id
                                       or '').encode('utf-8'),
                    'Nachname': (emp_record.second_name or '').encode('utf-8'),
                    'Vorname': (emp_record.surname or '').encode('utf-8'),
                    'Bereich': (emp_record.bereich and emp_record.bereich.name
                                or '').encode('utf-8'),
                    'Team':
                    (emp_record.department_id and emp_record.department_id.name
                     or '').encode('utf-8'),
                    'Stellenbezeichnung':
                    (emp_record.job_id and emp_record.job_id.name
                     or '').encode('utf-8'),
                    'Vertragstyp': (emp_record.sudo().contract_type
                                    and emp_record.sudo().contract_type.name
                                    or '').encode('utf-8'),
                    'Ersteintrittsdatum':
                    self.get_date_format(emp_record.initial_date),
                    'Enddatum befristeter Vertrag':
                    self.get_date_format(emp_record.temp_contract_end_date),
                    'Befristungsgrund':
                    (emp_record.contract_limitation_reason
                     and emp_record.contract_limitation_reason.name
                     or '').encode('utf-8'),
                    'Probezeit Enddatum':
                    self.get_date_format(emp_record.contract_trial_end_date),
                    'letztes MA Gespraech':
                    self.get_date_format(emp_record.last_ma_conversation_date),
                }

            else:
                notes = ''
                if emp_record.contract_notes:
                    notes = emp_record.contract_notes.replace("\n", " / ")
                vals = {
                    'Personalnummer': (emp_record.identification_id
                                       or '').encode('utf-8'),
                    'Nachname': (emp_record.second_name or '').encode('utf-8'),
                    'Vorname': (emp_record.surname or '').encode('utf-8'),
                    'Geburtstag':
                    self.get_date_format(emp_record.birthday),
                    'Company': (emp_record.address_id
                                and emp_record.address_id.sudo().name
                                or '').encode('utf-8'),
                    'Bereich': (emp_record.bereich and emp_record.bereich.name
                                or '').encode('utf-8'),
                    'Team':
                    (emp_record.department_id and emp_record.department_id.name
                     or '').encode('utf-8'),
                    'Planstellenbezeichnung':
                    (emp_record.planned_job_id
                     and emp_record.planned_job_id.name or '').encode('utf-8'),
                    'Stellenbezeichnung':
                    (emp_record.job_id and emp_record.job_id.name
                     or '').encode('utf-8'),
                    'Vertragstyp': (emp_record.sudo().contract_type
                                    and emp_record.sudo().contract_type.name
                                    or '').encode('utf-8'),
                    'Ersteintrittsdatum':
                    self.get_date_format(emp_record.initial_date),
                    'Enddatum befristeter Vertrag':
                    self.get_date_format(emp_record.temp_contract_end_date),
                    'Befristungsgrund':
                    (emp_record.contract_limitation_reason
                     and emp_record.contract_limitation_reason.name
                     or '').encode('utf-8'),
                    'Probezeit Enddatum':
                    self.get_date_format(emp_record.contract_trial_end_date),
                    'letztes MA Gespraech':
                    self.get_date_format(emp_record.last_ma_conversation_date),
                    '5-Jahresjubilaeum':
                    self.get_date_format(emp_record.five_years),
                    'Arbeitszeit': (emp_record.contract_working_hours
                                    and emp_record.contract_working_hours.name
                                    or '').encode('utf-8'),
                    'Urlaub':
                    emp_record.contract_leaves or '',
                    'Schwerbehinderung':
                    ('ja' if emp_record.disability == 'yes' else 'nein' or ''),
                    # 'letzte Vertragsaenderung_L&G': emp_record.last_contract_changed_wage or '',
                    'letzte Vertragsaenderung_L&G':
                    ("%.2f" % emp_record.last_contract_changed_wage).replace(
                        '.', ',') or '',
                    'Startdatum der letzten Vertragversänderung':
                    self.get_date_format(
                        emp_record.last_contract_changed_date),
                    'Verguetung':
                    ("%.2f" % emp_record.emp_wage_cal).replace('.', ',') or '',
                    # 'Verguetung bei VZ':  emp_record.compensation_at_vz or '',
                    'Verguetung bei VZ':
                    ("%.2f" % emp_record.compensation_at_vz).replace('.', ',')
                    or '',
                    # 'Verguetung inkl. AG Kosten (25%)': emp_record.remuneration_incl_ag_costs or '',
                    'Verguetung inkl. AG Kosten (25%)':
                    ("%.2f" % emp_record.remuneration_incl_ag_costs).replace(
                        '.', ',') or '',
                    'BR Mitglied': ('ja' if emp_record.br_member == 'yes' else
                                    'nein' or '').encode('utf-8'),
                    'Bemerkungen': (notes).encode('utf-8'),
                    'Manager':
                    (emp_record.parent_id and emp_record.parent_id.name
                     or '').encode('utf-8'),
                }
            data_list.append(vals)

        with open(csv_path, 'wb') as csvfile:

            w = csv.DictWriter(csvfile,
                               fieldnames=csv_header,
                               delimiter=';',
                               quoting=csv.QUOTE_ALL)
            w.writeheader()
            w.writerows(data_list)
        csvfile.close()

        data = ''
        with open(csv_path, 'rb') as csvfile:
            data = csvfile.read()
            data = data.encode('base64')
        csvfile.close()
        context = self._context.copy()
        file_name = datetime.now().strftime(
            '%Y%m%d_%H_%M') + '_' + csv_name + '.csv'
        context.update({'default_name': data, 'default_file_name': file_name})
        os.remove(csv_path)
        return context
コード例 #28
0
class GithubRepositoryBranch(models.Model):
    _name = 'github.repository.branch'
    _inherit = ['github.connector']
    _order = 'complete_name'

    _SELECTION_STATE = [
        ('to_download', 'To Download'),
        ('to_analyze', 'To Analyze'),
        ('analyzed', 'Analyzed'),
    ]

    # Column Section
    name = fields.Char(string='Name',
                       select=True,
                       required=True,
                       readonly=True)

    complete_name = fields.Char(string='Complete Name',
                                compute='_compute_complete_name',
                                store=True)

    state = fields.Selection(string='State',
                             selection=_SELECTION_STATE,
                             default='to_download')

    repository_id = fields.Many2one(comodel_name='github.repository',
                                    string='Repository',
                                    required=True,
                                    select=True,
                                    readonly=True,
                                    ondelete='cascade')

    organization_id = fields.Many2one(comodel_name='github.organization',
                                      string='Organization',
                                      related='repository_id.organization_id',
                                      store=True,
                                      readonly=True)

    last_download_date = fields.Datetime(string='Last Download Date')

    last_analyze_date = fields.Datetime(string='Last Analyze Date')

    module_paths = fields.Text(
        string='Module Paths',
        help="Set here extra relative paths"
        " you want to scan to find modules. If not set, root path will be"
        " scanned. One repository per line. Exemple:\n"
        "./addons/\n"
        "./openerp/addons/")

    module_version_ids = fields.One2many(comodel_name='oca.module.version',
                                         inverse_name='repository_branch_id',
                                         string='Module Versions')

    module_version_qty = fields.Integer(string='Module Versions Quantity',
                                        compute='compute_module_version_qty')

    # Compute Section
    @api.multi
    @api.depends('name', 'repository_id.complete_name')
    def _compute_complete_name(self):
        for repository_branch in self:
            repository_branch.complete_name =\
                repository_branch.repository_id.complete_name +\
                '/' + repository_branch.name

    # Compute Section
    @api.one
    def name_get(self):
        return [self.id, self.complete_name]

    @api.multi
    @api.depends('module_version_ids',
                 'module_version_ids.repository_branch_id')
    def compute_module_version_qty(self):
        for repository_branch in self:
            repository_branch.module_version_qty =\
                len(repository_branch.module_version_ids)

    # Action Section
    @api.multi
    def button_download_code(self):
        return self._download_code()

    @api.multi
    def button_update_code(self):
        return self._download_code()

    @api.multi
    def button_analyze_code(self):
        return self._analyze_code()

    # Custom Section
    def create_or_update_from_name(self, repository_id, name):
        repository_branch = self.search([('name', '=', name),
                                         ('repository_id', '=', repository_id)
                                         ])
        if not repository_branch:
            repository_branch = self.create({
                'name': name,
                'repository_id': repository_id
            })
        return repository_branch

    def _download_code(self):
        for repository_branch in self:
            path = self._get_local_path(repository_branch.complete_name)
            if not os.path.exists(path):
                _logger.info("Cloning new repository into %s ..." % (path))
                # Cloning the repository
                os.makedirs(path)
                os.system("cd %s &&"
                          " git clone https://github.com/%s.git -b %s ." %
                          (path, repository_branch.repository_id.complete_name,
                           repository_branch.name))
                repository_branch.write({
                    'last_download_date': datetime.today(),
                    'state': 'to_analyze',
                })
            else:
                # Update repository
                _logger.info("Pulling existing repository %s ..." % (path))
                try:
                    res = check_output(
                        ['git', 'pull', 'origin', repository_branch.name],
                        cwd=path)
                except:
                    raise exceptions.Warning(
                        _("Git Access Error"),
                        _("Unable to access to pull repository in %s.") %
                        (path))
                if repository_branch.state == 'to_download' or\
                        'up-to-date' not in res:
                    repository_branch.write({
                        'last_download_date':
                        datetime.today(),
                        'state':
                        'to_analyze',
                    })
                else:
                    repository_branch.write({
                        'last_download_date':
                        datetime.today(),
                    })
            self._cr.commit()

    @api.multi
    def _analyze_code(self):
        module_version_obj = self.env['oca.module.version']
        for repository_branch in self:
            # Delete all associated module versions
            module_versions = module_version_obj.search([
                ('repository_branch_id', '=', repository_branch.id)
            ])
            module_versions.with_context(
                dont_change_repository_branch_state=True).unlink()

            # Compute path(s) to analyze
            if repository_branch.module_paths:
                paths = []
                for path in repository_branch.module_paths.split('\n'):
                    if path.strip():
                        paths.append(
                            self._get_local_path(
                                repository_branch.complete_name) + '/' + path)
            else:
                paths = [self._get_local_path(repository_branch.complete_name)]
            # Scan each path, if exists
            for path in paths:
                if not os.path.exists(path):
                    _logger.warning(
                        "Unable to analyse %s. Source code not found." %
                        (path))
                else:
                    # Scan folder
                    _logger.info("Analyzing repository %s ..." % (path))
                    for module_name in self.listdir(path):
                        module_info = load_information_from_description_file(
                            module_name, path + '/' + module_name)
                        # Create module version, if the module is installable
                        # in the serie
                        if module_info.get('installable', False):
                            module_info['name'] = module_name
                            module_version_obj.create_or_update_from_manifest(
                                module_info, repository_branch)
                        self._cr.commit()
                    repository_branch.write({
                        'last_analyze_date':
                        datetime.today(),
                        'state':
                        'analyzed',
                    })
            self._cr.commit()

    # Copy Paste from Odoo Core
    # This function is for the time being in another function.
    # (Ref: openerp/modules/module.py)
    def listdir(self, dir):
        def clean(name):
            name = os.path.basename(name)
            if name[-4:] == '.zip':
                name = name[:-4]
            return name

        def is_really_module(name):
            manifest_name = opj(dir, name, MANIFEST)
            return os.path.isfile(manifest_name)

        return map(clean, filter(is_really_module, os.listdir(dir)))
コード例 #29
0
ファイル: event.py プロジェクト: smack815/odoo
class event_registration(models.Model):
    _name = 'event.registration'
    _description = 'Attendee'
    _inherit = ['mail.thread', 'ir.needaction_mixin']
    _order = 'name, create_date desc'

    origin = fields.Char(
        string='Source Document',
        readonly=True,
        help=
        "Reference of the document that created the registration, for example a sale order"
    )
    event_id = fields.Many2one('event.event',
                               string='Event',
                               required=True,
                               readonly=True,
                               states={'draft': [('readonly', False)]})
    partner_id = fields.Many2one('res.partner',
                                 string='Contact',
                                 states={'done': [('readonly', True)]})
    date_open = fields.Datetime(string='Registration Date',
                                readonly=True,
                                default=lambda self: fields.datetime.now()
                                )  # weird crash is directly now
    date_closed = fields.Datetime(string='Attended Date', readonly=True)
    event_begin_date = fields.Datetime(string="Event Start Date",
                                       related='event_id.date_begin',
                                       readonly=True)
    event_end_date = fields.Datetime(string="Event End Date",
                                     related='event_id.date_end',
                                     readonly=True)
    company_id = fields.Many2one('res.company',
                                 string='Company',
                                 related='event_id.company_id',
                                 store=True,
                                 readonly=True,
                                 states={'draft': [('readonly', False)]})
    state = fields.Selection([('draft', 'Unconfirmed'),
                              ('cancel', 'Cancelled'), ('open', 'Confirmed'),
                              ('done', 'Attended')],
                             string='Status',
                             default='draft',
                             readonly=True,
                             copy=False,
                             track_visibility='onchange')
    email = fields.Char(string='Email')
    phone = fields.Char(string='Phone')
    name = fields.Char(string='Attendee Name', select=True)

    @api.one
    @api.constrains('event_id', 'state')
    def _check_seats_limit(self):
        if self.event_id.seats_max and self.event_id.seats_available < (
                1 if self.state == 'draft' else 0):
            raise UserError(_('No more seats available for this event.'))

    @api.multi
    def _check_auto_confirmation(self):
        if self._context.get('registration_force_draft'):
            return False
        if any(registration.event_id.state != 'confirm'
               or not registration.event_id.auto_confirm
               or not registration.event_id.seats_available
               for registration in self):
            return False
        return True

    @api.model
    def create(self, vals):
        registration = super(event_registration, self).create(vals)
        if registration._check_auto_confirmation():
            registration.sudo().confirm_registration()
        return registration

    @api.one
    def do_draft(self):
        self.state = 'draft'

    @api.one
    def confirm_registration(self):
        self.event_id.message_post(body=_('New registration confirmed: %s.') %
                                   (self.name or ''),
                                   subtype="event.mt_event_registration")
        self.state = 'open'

    @api.one
    def button_reg_close(self):
        """ Close Registration """
        today = fields.Datetime.now()
        if self.event_id.date_begin <= today:
            self.write({'state': 'done', 'date_closed': today})
        else:
            raise UserError(
                _("You must wait for the starting day of the event to do this action."
                  ))

    @api.one
    def button_reg_cancel(self):
        self.state = 'cancel'

    @api.onchange('partner_id')
    def _onchange_partner(self):
        if self.partner_id:
            contact_id = self.partner_id.address_get().get('default', False)
            if contact_id:
                contact = self.env['res.partner'].browse(contact_id)
                self.name = self.name or contact.name
                self.email = self.email or contact.email
                self.phone = self.phone or contact.phone

    @api.multi
    def message_get_suggested_recipients(self):
        recipients = super(event_registration,
                           self).message_get_suggested_recipients()
        for attendee in self:
            if attendee.email:
                self._message_add_suggested_recipient(
                    recipients,
                    attendee,
                    email=attendee.email,
                    reason=_('Customer Email'))
            if attendee.partner_id:
                self._message_add_suggested_recipient(
                    recipients,
                    attendee,
                    partner=attendee.partner_id,
                    reason=_('Customer'))
        return recipients
コード例 #30
0
ファイル: lunch.py プロジェクト: Lennon-Liang/odoo-1
class LunchOrderLine(models.Model):
    _name = 'lunch.order.line'
    _description = 'lunch order line'

    name = fields.Char(related='product_id.name', string="Product Name", readonly=True)
    order_id = fields.Many2one('lunch.order', 'Order', ondelete='cascade', required=True)
    product_id = fields.Many2one('lunch.product', 'Product', required=True)
    category_id = fields.Many2one('lunch.product.category', string='Product Category',
                                  related='product_id.category_id', readonly=True, store=True)
    date = fields.Date(string='Date', related='order_id.date', readonly=True, store=True)
    supplier = fields.Many2one('res.partner', string='Vendor', related='product_id.supplier',
                               readonly=True, store=True)
    user_id = fields.Many2one('res.users', string='User', related='order_id.user_id',
                              readonly=True, store=True)
    note = fields.Text('Note')
    price = fields.Float(related='product_id.price', readonly=True, store=True,
                         digits=dp.get_precision('Account'))
    state = fields.Selection([('new', 'New'),
                              ('confirmed', 'Received'),
                              ('ordered', 'Ordered'),
                              ('cancelled', 'Cancelled')],
                             'Status', readonly=True, select=True, default='new')
    cashmove = fields.One2many('lunch.cashmove', 'order_id', 'Cash Move')
    currency_id = fields.Many2one('res.currency', related='order_id.currency_id')

    @api.one
    def order(self):
        """
        The order_line is ordered to the vendor but isn't received yet
        """
        if self.user_has_groups("lunch.group_lunch_manager"):
            self.state = 'ordered'
        else:
            raise AccessError(_("Only your lunch manager processes the orders."))

    @api.one
    def confirm(self):
        """
        confirm one or more order line, update order status and create new cashmove
        """
        if self.user_has_groups("lunch.group_lunch_manager"):
            if self.state != 'confirmed':
                values = {
                    'user_id': self.user_id.id,
                    'amount': -self.price,
                    'description': self.product_id.name,
                    'order_id': self.id,
                    'state': 'order',
                    'date': self.date,
                }
            self.env['lunch.cashmove'].create(values)
            self.state = 'confirmed'
        else:
            raise AccessError(_("Only your lunch manager sets the orders as received."))

    @api.one
    def cancel(self):
        """
        cancel one or more order.line, update order status and unlink existing cashmoves
        """
        if self.user_has_groups("lunch.group_lunch_manager"):
            self.state = 'cancelled'
            self.cashmove.unlink()
        else:
            raise AccessError(_("Only your lunch manager cancels the orders."))