Пример #1
0
 def portal_my_dms_directory(self,
                             dms_directory_id=False,
                             sortby=None,
                             filterby=None,
                             search=None,
                             search_in="name",
                             access_token=None,
                             **kw):
     """Process user's consent acceptance or rejection."""
     ensure_db()
     try:
         # If there's a website, we need a user to render the template
         request.uid = request.website.user_id.id
     except AttributeError:
         # If there's no website, the default is OK
         pass
     # operations
     searchbar_sortings = {
         "name": {
             "label": _("Name"),
             "order": "name asc"
         }
     }
     # default sortby br
     if not sortby:
         sortby = "name"
     sort_br = searchbar_sortings[sortby]["order"]
     # search
     searchbar_inputs = {
         "name": {
             "input": "name",
             "label": _("Name")
         },
     }
     if not filterby:
         filterby = "name"
     # domain
     domain = [("is_hidden", "=", False),
               ("parent_id", "=", dms_directory_id)]
     # search
     if search and search_in:
         search_domain = []
         if search_in == "name":
             search_domain = OR(
                 [search_domain, [("name", "ilike", search)]])
         domain += search_domain
     # content according to pager and archive selected
     dms_directory_items = (request.env["dms.directory"].with_user(
         request.env.user.id).search(domain, order=sort_br))
     request.session["my_dms_folder_history"] = dms_directory_items.ids
     # check_access
     res = self._dms_check_access("dms.directory", dms_directory_id,
                                  access_token)
     if not res:
         if access_token:
             return request.redirect("/")
         else:
             return request.redirect("/my")
     dms_directory_sudo = res
     # dms_files_count
     domain = [
         ("is_hidden", "=", False),
         ("directory_id", "=", dms_directory_id),
     ]
     # search
     if search and search_in:
         search_domain = []
         if search_in == "name":
             search_domain = OR(
                 [search_domain, [("name", "ilike", search)]])
         domain += search_domain
     # items
     dms_file_items = (request.env["dms.file"].with_user(
         request.env.user.id).search(domain, order=sort_br))
     request.session["my_dms_file_history"] = dms_file_items.ids
     dms_parent_categories = dms_directory_sudo.with_user(
         request.env.user.id)._get_parent_categories(access_token)
     # values
     values = {
         "dms_directories": dms_directory_items.sudo(),
         "page_name": "dms_directory",
         "default_url": "/my/dms",
         "searchbar_sortings": searchbar_sortings,
         "searchbar_inputs": searchbar_inputs,
         "search_in": search_in,
         "sortby": sortby,
         "filterby": filterby,
         "access_token": access_token,
         "dms_directory": dms_directory_sudo,
         "dms_files": dms_file_items.sudo(),
         "dms_parent_categories": dms_parent_categories,
     }
     return request.render("dms.portal_my_dms", values)
Пример #2
0
    def portal_my_tasks(self,
                        page=1,
                        date_begin=None,
                        date_end=None,
                        sortby=None,
                        filterby=None,
                        search=None,
                        search_in='content',
                        **kw):
        groupby = kw.get('groupby', 'project')  #TODO master fix this
        values = self._prepare_portal_layout_values()
        searchbar_sortings = {
            'date': {
                'label': _('Newest'),
                'order': 'create_date desc'
            },
            'name': {
                'label': _('Title'),
                'order': 'name'
            },
            'stage': {
                'label': _('Stage'),
                'order': 'stage_id'
            },
            'update': {
                'label': _('Last Stage Update'),
                'order': 'date_last_stage_update desc'
            },
        }
        searchbar_filters = {
            'all': {
                'label': _('All'),
                'domain': []
            },
        }
        searchbar_inputs = {
            'content': {
                'input': 'content',
                'label': _('Search <span class="nolabel"> (in Content)</span>')
            },
            'message': {
                'input': 'message',
                'label': _('Search in Messages')
            },
            'customer': {
                'input': 'customer',
                'label': _('Search in Customer')
            },
            'stage': {
                'input': 'stage',
                'label': _('Search in Stages')
            },
            'all': {
                'input': 'all',
                'label': _('Search in All')
            },
        }
        searchbar_groupby = {
            'none': {
                'input': 'none',
                'label': _('None')
            },
            'project': {
                'input': 'project',
                'label': _('Project')
            },
        }
        # extends filterby criteria with project (criteria name is the project id)
        # Note: portal users can't view projects they don't follow
        partner = request.env.user.partner_id
        domain_projects = [
            '&', ('privacy_visibility', '=', 'portal'), '|',
            ('message_partner_ids', 'child_of',
             [partner.commercial_partner_id.id]),
            ('task_ids.message_partner_ids', 'child_of',
             [partner.commercial_partner_id.id])
        ]

        projects = request.env['project.project'].sudo().search(
            domain_projects)
        domain = [('project_id', 'in', projects.ids)]
        for proj in projects:
            searchbar_filters.update({
                str(proj.id): {
                    'label': proj.name,
                    'domain': [('project_id', '=', proj.id)]
                }
            })

        # default sort by value
        if not sortby:
            sortby = 'date'
        order = searchbar_sortings[sortby]['order']
        # default filter by value
        if not filterby:
            filterby = 'all'
        domain += searchbar_filters[filterby]['domain']

        # archive groups - Default Group By 'create_date'
        archive_groups = self._get_archive_groups('project.task', domain)
        if date_begin and date_end:
            domain += [('create_date', '>', date_begin),
                       ('create_date', '<=', date_end)]

        # search
        if search and search_in:
            search_domain = []
            if search_in in ('content', 'all'):
                search_domain = OR([
                    search_domain,
                    [
                        '|', ('name', 'ilike', search),
                        ('description', 'ilike', search)
                    ]
                ])
            if search_in in ('customer', 'all'):
                search_domain = OR(
                    [search_domain, [('partner_id', 'ilike', search)]])
            if search_in in ('message', 'all'):
                search_domain = OR(
                    [search_domain, [('message_ids.body', 'ilike', search)]])
            if search_in in ('stage', 'all'):
                search_domain = OR(
                    [search_domain, [('stage_id', 'ilike', search)]])
            domain += search_domain

        # task count
        task_count = request.env['project.task'].search_count(domain)
        # pager
        pager = portal_pager(url="/my/tasks",
                             url_args={
                                 'date_begin': date_begin,
                                 'date_end': date_end,
                                 'sortby': sortby,
                                 'filterby': filterby,
                                 'search_in': search_in,
                                 'search': search
                             },
                             total=task_count,
                             page=page,
                             step=self._items_per_page)
        # content according to pager and archive selected
        if groupby == 'project':
            order = "project_id, %s" % order  # force sort on project first to group by project in view
        tasks = request.env['project.task'].search(domain,
                                                   order=order,
                                                   limit=self._items_per_page,
                                                   offset=(page - 1) *
                                                   self._items_per_page)
        request.session['my_tasks_history'] = tasks.ids[:100]
        if groupby == 'project':
            grouped_tasks = [
                request.env['project.task'].concat(*g)
                for k, g in groupbyelem(tasks, itemgetter('project_id'))
            ]
        else:
            grouped_tasks = [tasks]

        values.update({
            'date':
            date_begin,
            'date_end':
            date_end,
            'projects':
            projects,
            'tasks':
            tasks,
            'grouped_tasks':
            grouped_tasks,
            'page_name':
            'task',
            'archive_groups':
            archive_groups,
            'default_url':
            '/my/tasks',
            'pager':
            pager,
            'searchbar_sortings':
            searchbar_sortings,
            'searchbar_groupby':
            searchbar_groupby,
            'searchbar_inputs':
            searchbar_inputs,
            'search_in':
            search_in,
            'sortby':
            sortby,
            'groupby':
            groupby,
            'searchbar_filters':
            OrderedDict(sorted(searchbar_filters.items())),
            'filterby':
            filterby,
        })
        return request.render("project.portal_my_tasks", values)
Пример #3
0
    def _import_fattura_pa(self, tree, invoice):
        """ Decodes a fattura_pa invoice into an invoice.

        :param tree:    the fattura_pa tree to decode.
        :param invoice: the invoice to update or an empty recordset.
        :returns:       the invoice where the fattura_pa data was imported.
        """
        invoices = self.env['account.move']
        first_run = True

        # possible to have multiple invoices in the case of an invoice batch, the batch itself is repeated for every invoice of the batch
        for body_tree in tree.xpath('//FatturaElettronicaBody'):
            if not first_run or not invoice:
                # make sure all the iterations create a new invoice record (except the first which could have already created one)
                invoice = self.env['account.move']
            first_run = False

            # Type must be present in the context to get the right behavior of the _default_journal method (account.move).
            # journal_id must be present in the context to get the right behavior of the _default_account method (account.move.line).
            elements = tree.xpath('//CessionarioCommittente//IdCodice')
            company = elements and self.env['res.company'].search(
                [('vat', 'ilike', elements[0].text)], limit=1)
            if not company:
                elements = tree.xpath(
                    '//CessionarioCommittente//CodiceFiscale')
                company = elements and self.env['res.company'].search(
                    [('l10n_it_codice_fiscale', 'ilike', elements[0].text)],
                    limit=1)
                if not company:
                    # Only invoices with a correct VAT or Codice Fiscale can be imported
                    _logger.warning(
                        'No company found with VAT or Codice Fiscale like %r.',
                        elements[0].text)
                    continue

            # Refund type.
            # TD01 == invoice
            # TD02 == advance/down payment on invoice
            # TD03 == advance/down payment on fee
            # TD04 == credit note
            # TD05 == debit note
            # TD06 == fee
            # For unsupported document types, just assume in_invoice, and log that the type is unsupported
            elements = tree.xpath('//DatiGeneraliDocumento/TipoDocumento')
            move_type = 'in_invoice'
            if elements and elements[0].text and elements[0].text == 'TD04':
                move_type = 'in_refund'
            elif elements and elements[0].text and elements[0].text != 'TD01':
                _logger.info(
                    'Document type not managed: %s. Invoice type is set by default.',
                    elements[0].text)

            # Setup the context for the Invoice Form
            invoice_ctx = invoice.with_company(company) \
                                 .with_context(default_move_type=move_type)

            # move could be a single record (editing) or be empty (new).
            with Form(invoice_ctx) as invoice_form:
                message_to_log = []

                # Partner (first step to avoid warning 'Warning! You must first select a partner.'). <1.2>
                elements = tree.xpath('//CedentePrestatore//IdCodice')
                partner = elements and self.env['res.partner'].search([
                    '&', ('vat', 'ilike', elements[0].text), '|',
                    ('company_id', '=', company.id), ('company_id', '=', False)
                ],
                                                                      limit=1)
                if not partner:
                    elements = tree.xpath('//CedentePrestatore//CodiceFiscale')
                    if elements:
                        codice = elements[0].text
                        domains = [[('l10n_it_codice_fiscale', '=', codice)]]
                        if re.match(r'^[0-9]{11}$', codice):
                            domains.append([('l10n_it_codice_fiscale', '=',
                                             'IT' + codice)])
                        elif re.match(r'^IT[0-9]{11}$', codice):
                            domains.append([
                                ('l10n_it_codice_fiscale', '=',
                                 self.env['res.partner'].
                                 _l10n_it_normalize_codice_fiscale(codice))
                            ])
                        partner = elements and self.env['res.partner'].search(
                            AND([
                                OR(domains),
                                OR([[('company_id', '=', company.id)],
                                    [('company_id', '=', False)]])
                            ]),
                            limit=1)
                if not partner:
                    elements = tree.xpath('//DatiTrasmissione//Email')
                    partner = elements and self.env['res.partner'].search(
                        [
                            '&', '|', ('email', '=', elements[0].text),
                            ('l10n_it_pec_email', '=', elements[0].text), '|',
                            ('company_id', '=', company.id),
                            ('company_id', '=', False)
                        ],
                        limit=1)
                if partner:
                    invoice_form.partner_id = partner
                else:
                    message_to_log.append("%s<br/>%s" % (
                        _("Vendor not found, useful informations from XML file:"
                          ),
                        invoice._compose_info_message(tree,
                                                      './/CedentePrestatore')))

                # Numbering attributed by the transmitter. <1.1.2>
                elements = tree.xpath('//ProgressivoInvio')
                if elements:
                    invoice_form.payment_reference = elements[0].text

                elements = body_tree.xpath('.//DatiGeneraliDocumento//Numero')
                if elements:
                    invoice_form.ref = elements[0].text

                # Currency. <2.1.1.2>
                elements = body_tree.xpath('.//DatiGeneraliDocumento/Divisa')
                if elements:
                    currency_str = elements[0].text
                    currency = self.env.ref('base.%s' % currency_str.upper(),
                                            raise_if_not_found=False)
                    if currency != self.env.company.currency_id and currency.active:
                        invoice_form.currency_id = currency

                # Date. <2.1.1.3>
                elements = body_tree.xpath('.//DatiGeneraliDocumento/Data')
                if elements:
                    date_str = elements[0].text
                    date_obj = datetime.strptime(
                        date_str, DEFAULT_FACTUR_ITALIAN_DATE_FORMAT)
                    invoice_form.invoice_date = date_obj

                #  Dati Bollo. <2.1.1.6>
                elements = body_tree.xpath(
                    './/DatiGeneraliDocumento/DatiBollo/ImportoBollo')
                if elements:
                    invoice_form.l10n_it_stamp_duty = float(elements[0].text)

                # List of all amount discount (will be add after all article to avoid to have a negative sum)
                discount_list = []
                percentage_global_discount = 1.0

                # Global discount. <2.1.1.8>
                discount_elements = body_tree.xpath(
                    './/DatiGeneraliDocumento/ScontoMaggiorazione')
                total_discount_amount = 0.0
                if discount_elements:
                    for discount_element in discount_elements:
                        discount_line = discount_element.xpath('.//Tipo')
                        discount_sign = -1
                        if discount_line and discount_line[0].text == 'SC':
                            discount_sign = 1
                        discount_percentage = discount_element.xpath(
                            './/Percentuale')
                        if discount_percentage and discount_percentage[0].text:
                            percentage_global_discount *= 1 - float(
                                discount_percentage[0].text
                            ) / 100 * discount_sign

                        discount_amount_text = discount_element.xpath(
                            './/Importo')
                        if discount_amount_text and discount_amount_text[
                                0].text:
                            discount_amount = float(discount_amount_text[0].
                                                    text) * discount_sign * -1
                            discount = {}
                            discount["seq"] = 0

                            if discount_amount < 0:
                                discount["name"] = _('GLOBAL DISCOUNT')
                            else:
                                discount["name"] = _('GLOBAL EXTRA CHARGE')
                            discount["amount"] = discount_amount
                            discount["tax"] = []
                            discount_list.append(discount)

                # Comment. <2.1.1.11>
                elements = body_tree.xpath('.//DatiGeneraliDocumento//Causale')
                for element in elements:
                    invoice_form.narration = '%s%s\n' % (invoice_form.narration
                                                         or '', element.text)

                # Informations relative to the purchase order, the contract, the agreement,
                # the reception phase or invoices previously transmitted
                # <2.1.2> - <2.1.6>
                for document_type in [
                        'DatiOrdineAcquisto', 'DatiContratto',
                        'DatiConvenzione', 'DatiRicezione',
                        'DatiFattureCollegate'
                ]:
                    elements = body_tree.xpath('.//DatiGenerali/' +
                                               document_type)
                    if elements:
                        for element in elements:
                            message_to_log.append(
                                "%s %s<br/>%s" %
                                (document_type, _("from XML file:"),
                                 invoice._compose_info_message(element, '.')))

                #  Dati DDT. <2.1.8>
                elements = body_tree.xpath('.//DatiGenerali/DatiDDT')
                if elements:
                    message_to_log.append(
                        "%s<br/>%s" %
                        (_("Transport informations from XML file:"),
                         invoice._compose_info_message(
                             body_tree, './/DatiGenerali/DatiDDT')))

                # Due date. <2.4.2.5>
                elements = body_tree.xpath(
                    './/DatiPagamento/DettaglioPagamento/DataScadenzaPagamento'
                )
                if elements:
                    date_str = elements[0].text
                    date_obj = datetime.strptime(
                        date_str, DEFAULT_FACTUR_ITALIAN_DATE_FORMAT)
                    invoice_form.invoice_date_due = fields.Date.to_string(
                        date_obj)

                # Total amount. <2.4.2.6>
                elements = body_tree.xpath('.//ImportoPagamento')
                amount_total_import = 0
                for element in elements:
                    amount_total_import += float(element.text)
                if amount_total_import:
                    message_to_log.append(
                        _("Total amount from the XML File: %s") %
                        (amount_total_import))

                # Bank account. <2.4.2.13>
                if invoice_form.move_type not in ('out_invoice', 'in_refund'):
                    elements = body_tree.xpath(
                        './/DatiPagamento/DettaglioPagamento/IBAN')
                    if elements:
                        if invoice_form.partner_id and invoice_form.partner_id.commercial_partner_id:
                            bank = self.env['res.partner.bank'].search([
                                ('acc_number', '=', elements[0].text),
                                ('partner_id.id', '=', invoice_form.partner_id.
                                 commercial_partner_id.id)
                            ])
                        else:
                            bank = self.env['res.partner.bank'].search([
                                ('acc_number', '=', elements[0].text)
                            ])
                        if bank:
                            invoice_form.partner_bank_id = bank
                        else:
                            message_to_log.append("%s<br/>%s" % (
                                _("Bank account not found, useful informations from XML file:"
                                  ),
                                invoice._compose_multi_info_message(
                                    body_tree, [
                                        './/DatiPagamento//Beneficiario',
                                        './/DatiPagamento//IstitutoFinanziario',
                                        './/DatiPagamento//IBAN',
                                        './/DatiPagamento//ABI',
                                        './/DatiPagamento//CAB',
                                        './/DatiPagamento//BIC',
                                        './/DatiPagamento//ModalitaPagamento'
                                    ])))
                else:
                    elements = body_tree.xpath(
                        './/DatiPagamento/DettaglioPagamento')
                    if elements:
                        message_to_log.append("%s<br/>%s" % (
                            _("Bank account not found, useful informations from XML file:"
                              ),
                            invoice._compose_info_message(
                                body_tree, './/DatiPagamento')))

                # Invoice lines. <2.2.1>
                elements = body_tree.xpath('.//DettaglioLinee')
                if elements:
                    for element in elements:
                        with invoice_form.invoice_line_ids.new(
                        ) as invoice_line_form:

                            # Sequence.
                            line_elements = element.xpath('.//NumeroLinea')
                            if line_elements:
                                invoice_line_form.sequence = int(
                                    line_elements[0].text) * 2

                            # Product.
                            line_elements = element.xpath('.//Descrizione')
                            if line_elements:
                                invoice_line_form.name = " ".join(
                                    line_elements[0].text.split())

                            elements_code = element.xpath('.//CodiceArticolo')
                            if elements_code:
                                for element_code in elements_code:
                                    type_code = element_code.xpath(
                                        './/CodiceTipo')[0]
                                    code = element_code.xpath(
                                        './/CodiceValore')[0]
                                    if type_code.text == 'EAN':
                                        product = self.env[
                                            'product.product'].search([
                                                ('barcode', '=', code.text)
                                            ])
                                        if product:
                                            invoice_line_form.product_id = product
                                            break
                                    if partner:
                                        product_supplier = self.env[
                                            'product.supplierinfo'].search([
                                                ('name', '=', partner.id),
                                                ('product_code', '=',
                                                 code.text)
                                            ])
                                        if product_supplier and product_supplier.product_id:
                                            invoice_line_form.product_id = product_supplier.product_id
                                            break
                                if not invoice_line_form.product_id:
                                    for element_code in elements_code:
                                        code = element_code.xpath(
                                            './/CodiceValore')[0]
                                        product = self.env[
                                            'product.product'].search(
                                                [('default_code', '=',
                                                  code.text)],
                                                limit=1)
                                        if product:
                                            invoice_line_form.product_id = product
                                            break

                            # Price Unit.
                            line_elements = element.xpath('.//PrezzoUnitario')
                            if line_elements:
                                invoice_line_form.price_unit = float(
                                    line_elements[0].text)

                            # Quantity.
                            line_elements = element.xpath('.//Quantita')
                            if line_elements:
                                invoice_line_form.quantity = float(
                                    line_elements[0].text)
                            else:
                                invoice_line_form.quantity = 1

                            # Taxes
                            tax_element = element.xpath('.//AliquotaIVA')
                            natura_element = element.xpath('.//Natura')
                            invoice_line_form.tax_ids.clear()
                            if tax_element and tax_element[0].text:
                                percentage = float(tax_element[0].text)
                                if natura_element and natura_element[0].text:
                                    l10n_it_kind_exoneration = natura_element[
                                        0].text
                                    tax = self.env['account.tax'].search(
                                        [
                                            ('company_id', '=',
                                             invoice_form.company_id.id),
                                            ('amount_type', '=', 'percent'),
                                            ('type_tax_use', '=', 'purchase'),
                                            ('amount', '=', percentage),
                                            ('l10n_it_kind_exoneration', '=',
                                             l10n_it_kind_exoneration),
                                        ],
                                        limit=1)
                                else:
                                    tax = self.env['account.tax'].search(
                                        [
                                            ('company_id', '=',
                                             invoice_form.company_id.id),
                                            ('amount_type', '=', 'percent'),
                                            ('type_tax_use', '=', 'purchase'),
                                            ('amount', '=', percentage),
                                        ],
                                        limit=1)
                                    l10n_it_kind_exoneration = ''

                                if tax:
                                    invoice_line_form.tax_ids.add(tax)
                                else:
                                    if l10n_it_kind_exoneration:
                                        message_to_log.append(
                                            _("Tax not found with percentage: %s and exoneration %s for the article: %s"
                                              ) % (percentage,
                                                   l10n_it_kind_exoneration,
                                                   invoice_line_form.name))
                                    else:
                                        message_to_log.append(
                                            _("Tax not found with percentage: %s for the article: %s"
                                              ) % (percentage,
                                                   invoice_line_form.name))

                            # Discount in cascade mode.
                            # if 3 discounts : -10% -50€ -20%
                            # the result must be : (((price -10%)-50€) -20%)
                            # Generic form : (((price -P1%)-A1€) -P2%)
                            # It will be split in two parts: fix amount and pourcent amount
                            # example: (((((price - A1€) -P2%) -A3€) -A4€) -P5€)
                            # pourcent: 1-(1-P2)*(1-P5)
                            # fix amount: A1*(1-P2)*(1-P5)+A3*(1-P5)+A4*(1-P5) (we must take account of all
                            # percentage present after the fix amount)
                            line_elements = element.xpath(
                                './/ScontoMaggiorazione')
                            total_discount_amount = 0.0
                            total_discount_percentage = percentage_global_discount
                            if line_elements:
                                for line_element in line_elements:
                                    discount_line = line_element.xpath(
                                        './/Tipo')
                                    discount_sign = -1
                                    if discount_line and discount_line[
                                            0].text == 'SC':
                                        discount_sign = 1
                                    discount_percentage = line_element.xpath(
                                        './/Percentuale')
                                    if discount_percentage and discount_percentage[
                                            0].text:
                                        pourcentage_actual = 1 - float(
                                            discount_percentage[0].text
                                        ) / 100 * discount_sign
                                        total_discount_percentage *= pourcentage_actual
                                        total_discount_amount *= pourcentage_actual

                                    discount_amount = line_element.xpath(
                                        './/Importo')
                                    if discount_amount and discount_amount[
                                            0].text:
                                        total_discount_amount += float(
                                            discount_amount[0].text
                                        ) * discount_sign * -1

                                # Save amount discount.
                                if total_discount_amount != 0:
                                    discount = {}
                                    discount[
                                        "seq"] = invoice_line_form.sequence + 1

                                    if total_discount_amount < 0:
                                        discount["name"] = _(
                                            'DISCOUNT: %s',
                                            invoice_line_form.name)
                                    else:
                                        discount["name"] = _(
                                            'EXTRA CHARGE: %s',
                                            invoice_line_form.name)
                                    discount["amount"] = total_discount_amount
                                    discount["tax"] = []
                                    for tax in invoice_line_form.tax_ids:
                                        discount["tax"].append(tax)
                                    discount_list.append(discount)
                            invoice_line_form.discount = (
                                1 - total_discount_percentage) * 100

                # Apply amount discount.
                for discount in discount_list:
                    with invoice_form.invoice_line_ids.new(
                    ) as invoice_line_form_discount:
                        invoice_line_form_discount.tax_ids.clear()
                        invoice_line_form_discount.sequence = discount["seq"]
                        invoice_line_form_discount.name = discount["name"]
                        invoice_line_form_discount.price_unit = discount[
                            "amount"]

            new_invoice = invoice_form.save()
            new_invoice.l10n_it_send_state = "other"

            elements = body_tree.xpath('.//Allegati')
            if elements:
                for element in elements:
                    name_attachment = element.xpath(
                        './/NomeAttachment')[0].text
                    attachment_64 = str.encode(
                        element.xpath('.//Attachment')[0].text)
                    attachment_64 = self.env['ir.attachment'].create({
                        'name':
                        name_attachment,
                        'datas':
                        attachment_64,
                        'type':
                        'binary',
                    })

                    # default_res_id is had to context to avoid facturx to import his content
                    # no_new_invoice to prevent from looping on the message_post that would create a new invoice without it
                    new_invoice.with_context(
                        no_new_invoice=True,
                        default_res_id=new_invoice.id).message_post(
                            body=(_("Attachment from XML")),
                            attachment_ids=[attachment_64.id])

            for message in message_to_log:
                new_invoice.message_post(body=message)

            invoices += new_invoice

        return invoices
Пример #4
0
 def _get_translation_frontend_modules_domain(cls):
     domain = super(Http, cls)._get_translation_frontend_modules_domain()
     return OR([domain, [('name', 'ilike', 'website')]])
Пример #5
0
    def my_tickets(self,
                   page=1,
                   start_date=None,
                   end_date=None,
                   sort=None,
                   search=None,
                   in_search='content',
                   **kw):
        result = self._prepare_portal_layout_values()
        domain = self._get_tickets_domain(request.env.user.partner_id)

        sortings = {
            'name': {
                'label': _('Subject'),
                'order': 'name'
            },
            'date': {
                'label': _('Newest'),
                'order': 'create_date desc'
            },
            'stage': {
                'label': _('Stage'),
                'order': 'stage_id'
            },
        }

        if not sort:
            sort = 'date'
        order = sortings[sort]['order']

        archive_groups = self._get_archive_groups('supportdesk.ticket', domain)
        if start_date and end_date:
            domain += [('create_date', '>', start_date),
                       ('create_date', '<=', end_date)]

        if search and in_search:
            in_search_filter = []
            if in_search in ('customer', 'all'):
                in_search_filter = OR(
                    [in_search_filter, [('partner_id', 'ilike', search)]])
            if in_search in ('content', 'all'):
                in_search_filter = OR([
                    in_search_filter,
                    [
                        '|', ('name', 'ilike', search),
                        ('description', 'ilike', search)
                    ]
                ])
                if in_search in ('stage', 'all'):
                    in_search_filter = OR(
                        [in_search_filter, [('stage_id', 'ilike', search)]])
            if in_search in ('message', 'all'):
                in_search_filter = OR([
                    in_search_filter, [('message_ids.body', 'ilike', search)]
                ])
            domain += in_search_filter

        support_tickets_count = request.env['supportdesk.ticket'].search_count(
            domain)
        pager = portal_pager(url="/my/support_tickets",
                             url_args={
                                 'start_date': start_date,
                                 'end_date': end_date,
                                 'sortby': sort
                             },
                             total=support_tickets_count,
                             page=page,
                             step=self._items_per_page)

        support_tickets = request.env['supportdesk.ticket'].sudo().search(
            domain,
            order=order,
            limit=self._items_per_page,
            offset=pager['offset'])
        request.session['my_tickets_history'] = support_tickets.ids[:50]

        result.update({
            'page_name': 'ticket',
            'pager': pager,
            'date': start_date,
            'tickets': support_tickets,
            'default_url': '/my/support_tickets',
            'sortby': sort,
            'search_in': in_search,
            'search': search,
            'searchbar_sortings': sortings,
            'archive_groups': archive_groups,
        })
        return request.render("support_desk.portal_support_ticket", result)
Пример #6
0
    def portal_my_tasks(self,
                        page=1,
                        date_begin=None,
                        date_end=None,
                        sortby=None,
                        filterby=None,
                        search=None,
                        search_in='content',
                        **kw):
        values = self._prepare_portal_layout_values()
        domain = [('project_id.privacy_visibility', '=', 'portal')]

        searchbar_sortings = {
            'date': {
                'label': _('Newest'),
                'order': 'create_date desc'
            },
            'name': {
                'label': _('Title'),
                'order': 'name'
            },
            'stage': {
                'label': _('Stage'),
                'order': 'stage_id'
            },
            'update': {
                'label': _('Last Stage Update'),
                'order': 'date_last_stage_update desc'
            },
        }
        searchbar_filters = {
            'all': {
                'label': _('All'),
                'domain': []
            },
        }
        searchbar_inputs = {
            'content': {
                'input': 'content',
                'label': _('Search <span class="nolabel"> (in Content)</span>')
            },
            'message': {
                'input': 'message',
                'label': _('Search in Messages')
            },
            'customer': {
                'input': 'customer',
                'label': _('Search in Customer')
            },
            'stage': {
                'input': 'stage',
                'label': _('Search in Stages')
            },
            'all': {
                'input': 'all',
                'label': _('Search in All')
            },
        }
        # extends filterby criteria with project (criteria name is the project id)
        projects = request.env['project.project'].search([
            ('privacy_visibility', '=', 'portal')
        ])
        for proj in projects:
            searchbar_filters.update({
                str(proj.id): {
                    'label': proj.name,
                    'domain': [('project_id', '=', proj.id)]
                }
            })

        # default sort by value
        if not sortby:
            sortby = 'date'
        order = searchbar_sortings[sortby]['order']
        # default filter by value
        if not filterby:
            filterby = 'all'
        domain += searchbar_filters[filterby]['domain']

        # archive groups - Default Group By 'create_date'
        archive_groups = self._get_archive_groups('project.task', domain)
        if date_begin and date_end:
            domain += [('create_date', '>', date_begin),
                       ('create_date', '<=', date_end)]

        # search
        if search and search_in:
            search_domain = []
            if search_in in ('content', 'all'):
                search_domain = OR([
                    search_domain,
                    [
                        '|', ('name', 'ilike', search),
                        ('description', 'ilike', search)
                    ]
                ])
            if search_in in ('customer', 'all'):
                search_domain = OR(
                    [search_domain, [('partner_id', 'ilike', search)]])
            if search_in in ('message', 'all'):
                search_domain = OR(
                    [search_domain, [('message_ids.body', 'ilike', search)]])
            if search_in in ('stage', 'all'):
                search_domain = OR(
                    [search_domain, [('stage_id', 'ilike', search)]])
            domain += search_domain

        # task count
        task_count = request.env['project.task'].search_count(domain)
        # pager
        pager = portal_pager(url="/my/tasks",
                             url_args={
                                 'date_begin': date_begin,
                                 'date_end': date_end,
                                 'sortby': sortby,
                                 'filterby': filterby
                             },
                             total=task_count,
                             page=page,
                             step=self._items_per_page)
        # content according to pager and archive selected
        tasks = request.env['project.task'].search(domain,
                                                   order=order,
                                                   limit=self._items_per_page,
                                                   offset=pager['offset'])
        request.session['my_tasks_history'] = tasks.ids[:100]

        values.update({
            'date':
            date_begin,
            'date_end':
            date_end,
            'projects':
            projects,
            'tasks':
            tasks,
            'page_name':
            'task',
            'archive_groups':
            archive_groups,
            'default_url':
            '/my/tasks',
            'pager':
            pager,
            'searchbar_sortings':
            searchbar_sortings,
            'searchbar_inputs':
            searchbar_inputs,
            'search_in':
            search_in,
            'sortby':
            sortby,
            'searchbar_filters':
            OrderedDict(sorted(searchbar_filters.items())),
            'filterby':
            filterby,
        })
        return request.render("project.portal_my_tasks", values)
Пример #7
0
    def portal_my_tasks(self, page=1, date_begin=None, date_end=None, sortby=None, filterby=None, search=None, search_in='content', groupby=None, **kw):
        values = self._prepare_portal_layout_values()
        searchbar_sortings = {
            'date': {'label': _('Newest'), 'order': 'create_date desc'},
            'name': {'label': _('Title'), 'order': 'name'},
            'stage': {'label': _('Stage'), 'order': 'stage_id, project_id'},
            'project': {'label': _('Project'), 'order': 'project_id, stage_id'},
            'update': {'label': _('Last Stage Update'), 'order': 'date_last_stage_update desc'},
        }
        searchbar_filters = {
            'all': {'label': _('All'), 'domain': []},
        }
        searchbar_inputs = {
            'content': {'input': 'content', 'label': _('Search <span class="nolabel"> (in Content)</span>')},
            'message': {'input': 'message', 'label': _('Search in Messages')},
            'customer': {'input': 'customer', 'label': _('Search in Customer')},
            'stage': {'input': 'stage', 'label': _('Search in Stages')},
            'project': {'input': 'project', 'label': _('Search in Project')},
            'all': {'input': 'all', 'label': _('Search in All')},
        }
        searchbar_groupby = {
            'none': {'input': 'none', 'label': _('None')},
            'project': {'input': 'project', 'label': _('Project')},
            'stage': {'input': 'stage', 'label': _('Stage')},
        }

        # extends filterby criteria with project the customer has access to
        projects = request.env['project.project'].search([])
        for project in projects:
            searchbar_filters.update({
                str(project.id): {'label': project.name, 'domain': [('project_id', '=', project.id)]}
            })

        # extends filterby criteria with project (criteria name is the project id)
        # Note: portal users can't view projects they don't follow
        project_groups = request.env['project.task'].read_group([('project_id', 'not in', projects.ids)],
                                                                ['project_id'], ['project_id'])
        for group in project_groups:
            proj_id = group['project_id'][0] if group['project_id'] else False
            proj_name = group['project_id'][1] if group['project_id'] else _('Others')
            searchbar_filters.update({
                str(proj_id): {'label': proj_name, 'domain': [('project_id', '=', proj_id)]}
            })

        # default sort by value
        if not sortby:
            sortby = 'date'
        order = searchbar_sortings[sortby]['order']

        # default filter by value
        if not filterby:
            filterby = 'all'
        domain = searchbar_filters.get(filterby, searchbar_filters.get('all'))['domain']

        # default group by value
        if not groupby:
            groupby = 'project'

        if date_begin and date_end:
            domain += [('create_date', '>', date_begin), ('create_date', '<=', date_end)]

        # search
        if search and search_in:
            search_domain = []
            if search_in in ('content', 'all'):
                search_domain = OR([search_domain, ['|', ('name', 'ilike', search), ('description', 'ilike', search)]])
            if search_in in ('customer', 'all'):
                search_domain = OR([search_domain, [('partner_id', 'ilike', search)]])
            if search_in in ('message', 'all'):
                search_domain = OR([search_domain, [('message_ids.body', 'ilike', search)]])
            if search_in in ('stage', 'all'):
                search_domain = OR([search_domain, [('stage_id', 'ilike', search)]])
            if search_in in ('project', 'all'):
                search_domain = OR([search_domain, [('project_id', 'ilike', search)]])
            domain += search_domain

        # task count
        task_count = request.env['project.task'].search_count(domain)
        # pager
        pager = portal_pager(
            url="/my/tasks",
            url_args={'date_begin': date_begin, 'date_end': date_end, 'sortby': sortby, 'filterby': filterby, 'groupby': groupby, 'search_in': search_in, 'search': search},
            total=task_count,
            page=page,
            step=self._items_per_page
        )
        # content according to pager and archive selected
        if groupby == 'project':
            order = "project_id, %s" % order  # force sort on project first to group by project in view
        elif groupby == 'stage':
            order = "stage_id, %s" % order  # force sort on stage first to group by stage in view

        tasks = request.env['project.task'].search(domain, order=order, limit=self._items_per_page, offset=pager['offset'])
        request.session['my_tasks_history'] = tasks.ids[:100]

        if groupby == 'project':
            grouped_tasks = [request.env['project.task'].concat(*g) for k, g in groupbyelem(tasks, itemgetter('project_id'))]
        elif groupby == 'stage':
            grouped_tasks = [request.env['project.task'].concat(*g) for k, g in groupbyelem(tasks, itemgetter('stage_id'))]
        else:
            grouped_tasks = [tasks]

        values.update({
            'date': date_begin,
            'date_end': date_end,
            'grouped_tasks': grouped_tasks,
            'page_name': 'task',
            'default_url': '/my/tasks',
            'pager': pager,
            'searchbar_sortings': searchbar_sortings,
            'searchbar_groupby': searchbar_groupby,
            'searchbar_inputs': searchbar_inputs,
            'search_in': search_in,
            'search': search,
            'sortby': sortby,
            'groupby': groupby,
            'searchbar_filters': OrderedDict(sorted(searchbar_filters.items())),
            'filterby': filterby,
        })
        return request.render("project.portal_my_tasks", values)