Beispiel #1
0
    def automatic_payment(self, amount=None):
        """ Create the payment entries to pay a sale order, respecting
        the payment terms.
        If no amount is defined, it will pay the residual amount of the sale
        order.
        """
        self.ensure_one()
        method = self.payment_method_id
        if not method:
            raise exceptions.Warning(
                _("An automatic payment can not be created for the sale "
                  "order %s because it has no payment method.") % self.name)

        if not method.journal_id:
            raise exceptions.Warning(
                _("An automatic payment should be created for the sale order"
                  " %s but the payment method '%s' has no journal defined.") %
                (self.name, method.name))

        journal = method.journal_id
        date = self.date_order[:10]
        if amount is None:
            amount = self.residual
        if self.payment_term:
            amounts = self.payment_term.compute(amount, date_ref=date)[0]
        else:
            amounts = [(date, amount)]

        # reversed is cosmetic, compute returns terms in the 'wrong' order
        for date, amount in reversed(amounts):
            self._add_payment(journal, amount, date)
        return True
Beispiel #2
0
    def generate_dbname(self, raise_error=True):
        if not self.dbname_template:
            if raise_error:
                raise exceptions.Warning(_('Template for db name is not configured'))
            return ''
        sequence = self.env['ir.sequence'].get('saas_portal.plan')

        return self.dbname_template.replace('%i', sequence).replace('%t', datetime.now().strftime('%m%d%I%M%S'))
Beispiel #3
0
 def action_cancel(self):
     for sale in self:
         if sale.payment_ids:
             raise exceptions.Warning(
                 _('Cannot cancel this sales order '
                   'because automatic payment entries '
                   'are linked with it.'))
     return super(SaleOrder, self).action_cancel()
Beispiel #4
0
def _get_s3_conn(env):
    ir_params = env['ir.config_parameter']
    aws_access_key_id = ir_params.get_param('saas_s3.saas_s3_aws_accessid')
    aws_secret_access_key = ir_params.get_param('saas_s3.saas_s3_aws_accesskey')
    aws_s3_bucket = ir_params.get_param('saas_s3.saas_s3_aws_bucket')
    if not aws_access_key_id or not aws_secret_access_key or not aws_s3_bucket:
        raise exceptions.Warning( _(u'Please provide your AWS Access Key and ID \
        and also the S3 bucket to be used'))
    return boto.connect_s3(aws_access_key_id, aws_secret_access_key), aws_s3_bucket
Beispiel #5
0
    def _get_payment_move_name(self, journal, period):
        sequence = journal.sequence_id
        if not sequence:
            raise exceptions.Warning(
                _('Please define a sequence on the '
                  'journal %s.') % journal.name)
        if not sequence.active:
            raise exceptions.Warning(
                _('Please activate the sequence of the '
                  'journal %s.') % journal.name)

        sequence = sequence.with_context(fiscalyear_id=period.fiscalyear_id.id)
        # next_by_id not compatible with new api
        sequence_model = self.pool['ir.sequence']
        name = sequence_model.next_by_id(self.env.cr,
                                         self.env.uid,
                                         sequence.id,
                                         context=self.env.context)
        return name
Beispiel #6
0
 def get_plan(self, plan_id=None):
     plan = request.registry['saas_portal.plan']
     if not plan_id:
         domain = [('state', '=', 'confirmed')]
         plan_ids = request.registry['saas_portal.plan'].search(
             request.cr, SUPERUSER_ID, domain)
         if plan_ids:
             plan_id = plan_ids[0]
         else:
             raise exceptions.Warning(_('There is no plan configured'))
     return plan.browse(request.cr, SUPERUSER_ID, plan_id)
Beispiel #7
0
 def create(self, vals):
     max_users = self.env["ir.config_parameter"].sudo().get_param(
         "saas_client.max_users")
     if max_users:
         max_users = int(max_users)
         cur_users = self.env['res.users'].search_count([('share', '=',
                                                          False)])
         if cur_users >= max_users:
             raise exceptions.Warning(
                 _('Maximimum allowed users is %(max_users)s, while you already have %(cur_users)s'
                   ) % {
                       'max_users': max_users,
                       'cur_users': cur_users
                   })
     return super(ResUsers, self).create(vals)
Beispiel #8
0
    def get_diff(self):
        """Return the Difference between two document."""
        history = self.env["document.page.history"]
        ids = self.env.context.get('active_ids', [])

        diff = ""
        if len(ids) == 2:
            if ids[0] > ids[1]:
                diff = history.getDiff(ids[1], ids[0])
            else:
                diff = history.getDiff(ids[0], ids[1])
        elif len(ids) == 1:
            old = history.browse(ids[0])
            nids = history.search([('page_id', '=', old.page_id.id)],
                                  order='id DESC',
                                  limit=1)
            diff = history.getDiff(ids[0], nids.id)
        else:
            raise exceptions.Warning(
                _("Select one or maximum two history revisions!"))
        return diff
Beispiel #9
0
class SaasPortalPlan(models.Model):
    _name = 'saas_portal.plan'

    name = fields.Char('Plan', required=True)
    summary = fields.Char('Summary')
    template_id = fields.Many2one('saas_portal.database', 'Template', ondelete='restrict')
    demo = fields.Boolean('Install Demo Data')
    maximum_allowed_dbs_per_partner = fields.Integer(help='maximum allowed non-trial databases per customer',
                                                     require=True, default=0)
    maximum_allowed_trial_dbs_per_partner = fields.Integer(help='maximum allowed trial databases per customer',
                                                           require=True, default=0)

    max_users = fields.Char('Initial Max users', default='0')
    total_storage_limit = fields.Integer('Total storage limit (MB)')
    block_on_expiration = fields.Boolean('Block clients on expiration', default=False)
    block_on_storage_exceed = fields.Boolean('Block clients on storage exceed', default=False)

    def _get_default_lang(self):
        return self.env.lang

    def _default_tz(self):
        return self.env.user.tz

    lang = fields.Selection(scan_languages(), 'Language', default=_get_default_lang)
    tz = fields.Selection(_tz_get, 'TimeZone', default=_default_tz)
    sequence = fields.Integer('Sequence')
    state = fields.Selection([('draft', 'Draft'), ('confirmed', 'Confirmed')],
                             'State', compute='_get_state', store=True)
    expiration = fields.Integer('Expiration (hours)', help='time to delete database. Use for demo')
    _order = 'sequence'

    dbname_template = fields.Char('DB Names',
                                  help='Used for generating client database domain name. Use %i for numbering. Ignore if you use manually created db names',
                                  placeholder='crm-%i.yuancloud.com')
    server_id = fields.Many2one('saas_portal.server', string='SaaS Server',
                                ondelete='restrict',
                                help='User this saas server or choose random')

    website_description = fields.Html('Website description')
    logo = fields.Binary('Logo')

    @api.one
    @api.depends('template_id.state')
    def _get_state(self):
        if self.template_id.state == 'template':
            self.state = 'confirmed'
        else:
            self.state = 'draft'

    @api.one
    def _new_database_vals(self, vals):
        vals['max_users'] = self.max_users
        vals['total_storage_limit'] = self.total_storage_limit
        vals['block_on_expiration'] = self.block_on_expiration
        vals['block_on_storage_exceed'] = self.block_on_storage_exceed
        return vals

    @api.multi
    def create_new_database(self, **kwargs):
        return self._create_new_database(**kwargs)

    @api.multi
    def _create_new_database(self, dbname=None, client_id=None, partner_id=None, user_id=None, notify_user=False,
                             trial=False, support_team_id=None, async=None):
        self.ensure_one()

        server = self.server_id
        if not server:
            server = self.env['saas_portal.server'].get_saas_server()

        server.action_sync_server()
        if not partner_id and user_id:
            user = self.env['res.users'].browse(user_id)
            partner_id = user.partner_id.id

        if not trial and self.maximum_allowed_dbs_per_partner != 0:
            db_count = self.env['saas_portal.client'].search_count([('partner_id', '=', partner_id),
                                                                    ('state', '=', 'open'),
                                                                    ('plan_id', '=', self.id),
                                                                    ('trial', '=', False)])
            if db_count >= self.maximum_allowed_dbs_per_partner:
                raise MaximumDBException("Limit of databases for this plan is %(maximum)s reached" % {
                    'maximum': self.maximum_allowed_dbs_per_partner})
        if trial and self.maximum_allowed_trial_dbs_per_partner != 0:
            trial_db_count = self.env['saas_portal.client'].search_count([('partner_id', '=', partner_id),
                                                                          ('state', '=', 'open'),
                                                                          ('plan_id', '=', self.id),
                                                                          ('trial', '=', True)])
            if trial_db_count >= self.maximum_allowed_trial_dbs_per_partner:
                raise MaximumTrialDBException("Limit of trial databases for this plan is %(maximum)s reached" % {
                    'maximum': self.maximum_allowed_trial_dbs_per_partner})

        vals = {'name': dbname or self.generate_dbname()[0],
                'server_id': server.id,
                'plan_id': self.id,
                'partner_id': partner_id,
                'trial': trial,
                'support_team_id': support_team_id,
                }
        client = None
        if client_id:
            vals['client_id'] = client_id
            client = self.env['saas_portal.client'].search([('client_id', '=', client_id)])

        vals = self._new_database_vals(vals)[0]

        if client:
            client.write(vals)
        else:
            client = self.env['saas_portal.client'].create(vals)
        client_id = client.client_id

        scheme = server.request_scheme
        port = server.request_port
        if user_id:
            owner_user = self.env['res.users'].browse(user_id)
        else:
            owner_user = self.env.user
        owner_user_data = {
            'user_id': owner_user.id,
            'login': owner_user.login,
            'name': owner_user.name,
            'email': owner_user.email,
        }
        trial_expiration_datetime = (datetime.strptime(client.create_date,
                                                       DEFAULT_SERVER_DATETIME_FORMAT) + timedelta(
            hours=self.expiration)).strftime(DEFAULT_SERVER_DATETIME_FORMAT)  # for trial
        state = {
            'd': client.name,
            'e': trial and trial_expiration_datetime or client.create_date,
            'r': '%s://%s:%s/web' % (scheme, client.name, port),
            'owner_user': owner_user_data,
            't': client.trial,
            'addons': [addon.technical_name for addon in client.plan_id.app_store_module_ids]
        }
        if self.template_id:
            state.update({'db_template': self.template_id.name})
        scope = ['userinfo', 'force_login', 'trial', 'skiptheuse']
        url = server._request_server(path='/saas_server/new_database',
                                     scheme=scheme,
                                     port=port,
                                     state=state,
                                     client_id=client_id,
                                     scope=scope, )[0]
        res = requests.get(url, verify=(self.server_id.request_scheme == 'https' and self.server_id.verify_ssl))
        if res.status_code != 200:
            # TODO /saas_server/new_database show more details here
            raise exceptions.Warning('Error %s' % res.status_code)
        data = simplejson.loads(res.text)
        params = {
            'state': data.get('state'),
            'access_token': client.oauth_application_id._get_access_token(user_id, create=True),
        }
        url = '{url}?{params}'.format(url=data.get('url'), params=werkzeug.url_encode(params))

        # send email
        if notify_user:
            template = self.env.ref('saas_portal.email_template_create_saas')
            client.message_post_with_template(template.id, composition_mode='comment')

        if trial:
            client.expiration_datetime = trial_expiration_datetime
        client.send_params_to_client_db()
        client.server_id.action_sync_server()

        return {'url': url, 'id': client.id, 'client_id': client_id}
Beispiel #10
0
 def _transport_backup(self, dump_db, filename=None):
     '''
     backup transport agents should override this
     '''
     raise exceptions.Warning('Transport agent has not been configured')
Beispiel #11
0
    def create_xml(self, cr, uid, ids, context=None):
        """Creates xml that is to be exported and sent to estate for partner vat intra.
        :return: Value for next action.
        :rtype: dict
        """
        decl_datas = self.browse(cr, uid, ids[0])
        company = decl_datas.company_id
        if not (company.partner_id and company.partner_id.country_id
                and company.partner_id.country_id.id):
            self._company_warning(cr,
                                  uid,
                                  _('The country of your company is not set, '
                                    'please make sure to configure it first.'),
                                  context=context)
        kbo = company.company_registry
        if not kbo:
            self._company_warning(
                cr,
                uid,
                _('The registry number of your company is not set, '
                  'please make sure to configure it first.'),
                context=context)
        if len(decl_datas.year) != 4:
            raise exceptions.Warning(_('Year must be 4 digits number (YYYY)'))

        #Create root declaration
        decl = ET.Element('DeclarationReport')
        decl.set('xmlns', INTRASTAT_XMLNS)

        #Add Administration elements
        admin = ET.SubElement(decl, 'Administration')
        fromtag = ET.SubElement(admin, 'From')
        fromtag.text = kbo
        fromtag.set('declarerType', 'KBO')
        ET.SubElement(admin, 'To').text = "NBB"
        ET.SubElement(admin, 'Domain').text = "SXX"
        if decl_datas.arrivals == 'be-standard':
            decl.append(
                self._get_lines(cr,
                                SUPERUSER_ID,
                                ids,
                                decl_datas,
                                company,
                                dispatchmode=False,
                                extendedmode=False,
                                context=context))
        elif decl_datas.arrivals == 'be-extended':
            decl.append(
                self._get_lines(cr,
                                SUPERUSER_ID,
                                ids,
                                decl_datas,
                                company,
                                dispatchmode=False,
                                extendedmode=True,
                                context=context))
        if decl_datas.dispatches == 'be-standard':
            decl.append(
                self._get_lines(cr,
                                SUPERUSER_ID,
                                ids,
                                decl_datas,
                                company,
                                dispatchmode=True,
                                extendedmode=False,
                                context=context))
        elif decl_datas.dispatches == 'be-extended':
            decl.append(
                self._get_lines(cr,
                                SUPERUSER_ID,
                                ids,
                                decl_datas,
                                company,
                                dispatchmode=True,
                                extendedmode=True,
                                context=context))

        #Get xml string with declaration
        data_file = ET.tostring(decl, encoding='UTF-8', method='xml')

        #change state of the wizard
        self.write(
            cr,
            uid,
            ids, {
                'name': 'intrastat_%s%s.xml' %
                (decl_datas.year, decl_datas.month),
                'file_save': base64.encodestring(data_file),
                'state': 'download'
            },
            context=context)
        return {
            'name': _('Save'),
            'context': context,
            'view_type': 'form',
            'view_mode': 'form',
            'res_model': 'l10n_be_intrastat_xml.xml_decl',
            'type': 'ir.actions.act_window',
            'target': 'new',
            'res_id': ids[0],
        }
Beispiel #12
0
    def _get_lines(self,
                   cr,
                   uid,
                   ids,
                   decl_datas,
                   company,
                   dispatchmode=False,
                   extendedmode=False,
                   context=None):
        intrastatcode_mod = self.pool['report.intrastat.code']
        invoiceline_mod = self.pool['account.invoice.line']
        product_mod = self.pool['product.product']
        region_mod = self.pool['l10n_be_intrastat.region']
        warehouse_mod = self.pool['stock.warehouse']

        if dispatchmode:
            mode1 = 'out_invoice'
            mode2 = 'in_refund'
            declcode = "29"
        else:
            mode1 = 'in_invoice'
            mode2 = 'out_refund'
            declcode = "19"

        decl = ET.Element('Report')
        if not extendedmode:
            decl.set('code', 'EX%sS' % declcode)
        else:
            decl.set('code', 'EX%sE' % declcode)
        decl.set('date', '%s-%s' % (decl_datas.year, decl_datas.month))
        datas = ET.SubElement(decl, 'Data')
        if not extendedmode:
            datas.set('form', 'EXF%sS' % declcode)
        else:
            datas.set('form', 'EXF%sE' % declcode)
        datas.set('close', 'true')
        intrastatkey = namedtuple(
            "intrastatkey",
            ['EXTRF', 'EXCNT', 'EXTTA', 'EXREG', 'EXGO', 'EXTPC', 'EXDELTRM'])
        entries = {}

        sqlreq = """
            select
                inv_line.id
            from
                account_invoice_line inv_line
                join account_invoice inv on inv_line.invoice_id=inv.id
                left join res_country on res_country.id = inv.intrastat_country_id
                left join res_partner on res_partner.id = inv.partner_id
                left join res_country countrypartner on countrypartner.id = res_partner.country_id
                join product_product on inv_line.product_id=product_product.id
                join product_template on product_product.product_tmpl_id=product_template.id
            where
                inv.state in ('open','paid')
                and inv.company_id=%s
                and not product_template.type='service'
                and (res_country.intrastat=true or (inv.intrastat_country_id is null
                                                    and countrypartner.intrastat=true))
                and ((res_country.code is not null and not res_country.code=%s)
                     or (res_country.code is null and countrypartner.code is not null
                     and not countrypartner.code=%s))
                and inv.type in (%s, %s)
                and to_char(inv.date_invoice, 'YYYY')=%s
                and to_char(inv.date_invoice, 'MM')=%s
            """

        cr.execute(sqlreq, (company.id, company.partner_id.country_id.code,
                            company.partner_id.country_id.code, mode1, mode2,
                            decl_datas.year, decl_datas.month))
        lines = cr.fetchall()
        invoicelines_ids = [rec[0] for rec in lines]
        invoicelines = invoiceline_mod.browse(cr,
                                              uid,
                                              invoicelines_ids,
                                              context=context)
        for inv_line in invoicelines:

            #Check type of transaction
            if inv_line.intrastat_transaction_id:
                extta = inv_line.intrastat_transaction_id.code
            else:
                extta = "1"
            #Check country
            if inv_line.invoice_id.intrastat_country_id:
                excnt = inv_line.invoice_id.intrastat_country_id.code
            else:
                excnt = inv_line.invoice_id.partner_id.country_id.code

            #Check region
            #If purchase, comes from purchase order, linked to a location,
            #which is linked to the warehouse
            #if sales, the sale order is linked to the warehouse
            #if sales, from a delivery order, linked to a location,
            #which is linked to the warehouse
            #If none found, get the company one.
            exreg = None
            if inv_line.invoice_id.type in ('in_invoice', 'in_refund'):
                #comes from purchase
                POL = self.pool['purchase.order.line']
                poline_ids = POL.search(cr,
                                        uid,
                                        [('invoice_lines', 'in', inv_line.id)],
                                        context=context)
                if poline_ids:
                    purchaseorder = POL.browse(cr,
                                               uid,
                                               poline_ids[0],
                                               context=context).order_id
                    region_id = warehouse_mod.get_regionid_from_locationid(
                        cr, uid, purchaseorder.location_id.id, context=context)
                    if region_id:
                        exreg = region_mod.browse(cr, uid, region_id).code
            elif inv_line.invoice_id.type in ('out_invoice', 'out_refund'):
                #comes from sales
                soline_ids = self.pool['sale.order.line'].search(
                    cr,
                    uid, [('invoice_lines', 'in', inv_line.id)],
                    context=context)
                if soline_ids:
                    saleorder = self.pool['sale.order.line'].browse(
                        cr, uid, soline_ids[0], context=context).order_id
                    if saleorder and saleorder.warehouse_id and saleorder.warehouse_id.region_id:
                        exreg = region_mod.browse(
                            cr,
                            uid,
                            saleorder.warehouse_id.region_id.id,
                            context=context).code

            if not exreg:
                if company.region_id:
                    exreg = company.region_id.code
                else:
                    self._company_warning(
                        cr,
                        uid,
                        _('The Intrastat Region of the selected company is not set, '
                          'please make sure to configure it first.'),
                        context=context)

            #Check commodity codes
            intrastat_id = product_mod.get_intrastat_recursively(
                cr, uid, inv_line.product_id.id, context=context)
            if intrastat_id:
                exgo = intrastatcode_mod.browse(cr,
                                                uid,
                                                intrastat_id,
                                                context=context).name
            else:
                raise exceptions.Warning(
                    _('Product "%s" has no intrastat code, please configure it'
                      ) % inv_line.product_id.display_name)

            #In extended mode, 2 more fields required
            if extendedmode:
                #Check means of transport
                if inv_line.invoice_id.transport_mode_id:
                    extpc = inv_line.invoice_id.transport_mode_id.code
                elif company.transport_mode_id:
                    extpc = company.transport_mode_id.code
                else:
                    self._company_warning(
                        cr,
                        uid,
                        _('The default Intrastat transport mode of your company '
                          'is not set, please make sure to configure it first.'
                          ),
                        context=context)

                #Check incoterm
                if inv_line.invoice_id.incoterm_id:
                    exdeltrm = inv_line.invoice_id.incoterm_id.code
                elif company.incoterm_id:
                    exdeltrm = company.incoterm_id.code
                else:
                    self._company_warning(
                        cr,
                        uid,
                        _('The default Incoterm of your company is not set, '
                          'please make sure to configure it first.'),
                        context=context)
            else:
                extpc = ""
                exdeltrm = ""
            linekey = intrastatkey(EXTRF=declcode,
                                   EXCNT=excnt,
                                   EXTTA=extta,
                                   EXREG=exreg,
                                   EXGO=exgo,
                                   EXTPC=extpc,
                                   EXDELTRM=exdeltrm)
            #We have the key
            #calculate amounts
            if inv_line.price_unit and inv_line.quantity:
                amount = inv_line.price_unit * inv_line.quantity
            else:
                amount = 0
            if (not inv_line.uom_id.category_id
                    or not inv_line.product_id.uom_id.category_id
                    or inv_line.uos_id.category_id.id !=
                    inv_line.product_id.uom_id.category_id.id):
                weight = inv_line.product_id.weight * inv_line.quantity
            else:
                weight = (inv_line.product_id.weight * inv_line.quantity *
                          inv_line.uos_id.factor)
            if (not inv_line.uos_id.category_id
                    or not inv_line.product_id.uom_id.category_id
                    or inv_line.uos_id.category_id.id !=
                    inv_line.product_id.uom_id.category_id.id):
                supply_units = inv_line.quantity
            else:
                supply_units = inv_line.quantity * inv_line.uom_id.factor
            amounts = entries.setdefault(linekey, (0, 0, 0))
            amounts = (amounts[0] + amount, amounts[1] + weight,
                       amounts[2] + supply_units)
            entries[linekey] = amounts

        numlgn = 0
        for linekey in entries:
            numlgn += 1
            amounts = entries[linekey]
            item = ET.SubElement(datas, 'Item')
            self._set_Dim(item, 'EXSEQCODE', unicode(numlgn))
            self._set_Dim(item, 'EXTRF', unicode(linekey.EXTRF))
            self._set_Dim(item, 'EXCNT', unicode(linekey.EXCNT))
            self._set_Dim(item, 'EXTTA', unicode(linekey.EXTTA))
            self._set_Dim(item, 'EXREG', unicode(linekey.EXREG))
            self._set_Dim(item, 'EXTGO', unicode(linekey.EXGO))
            if extendedmode:
                self._set_Dim(item, 'EXTPC', unicode(linekey.EXTPC))
                self._set_Dim(item, 'EXDELTRM', unicode(linekey.EXDELTRM))
            self._set_Dim(item, 'EXTXVAL',
                          unicode(round(amounts[0], 0)).replace(".", ","))
            self._set_Dim(item, 'EXWEIGHT',
                          unicode(round(amounts[1], 0)).replace(".", ","))
            self._set_Dim(item, 'EXUNITS',
                          unicode(round(amounts[2], 0)).replace(".", ","))

        if numlgn == 0:
            #no datas
            datas.set('action', 'nihil')
        return decl
Beispiel #13
0
 def check_dates(self):
     if self.date_from >= self.date_to:
         raise exceptions.Warning(
             _('Error! Date to must be lower '
               'than date from.'))