Пример #1
0
    def test_invoice_change_status_in_db(self, status, _):
        self.client.force_login(self.ap_user)
        self.client.post(
            reverse('change-invoice-status', kwargs={
                'pk': self.invoice.id,
            }), {
                'status': invoice_status_lookup(status),
            })

        invoice = get_object_or_404(Invoice, pk=self.invoice.id)
        self.assertEqual(invoice.status, invoice_status_lookup(status))
Пример #2
0
    def test_invoices_list_filter_status(self):
        self.client.force_login(self.ap_user)
        invoice_approved = InvoiceFactory(user=self.user,
                                          taxpayer=self.taxpayer,
                                          invoice_number='4321')
        invoice_approved.status = invoice_status_lookup(
            INVOICE_STATUS_APPROVED)
        invoice_approved.save()

        response = self.client.get('{}?{}'.format(
            reverse('invoices-list'), 'status={}'.format(
                invoice_status_lookup(INVOICE_STATUS_APPROVED))))
        self.assertContains(response, invoice_approved.invoice_number)
        self.assertNotContains(response, self.invoice.invoice_number)
Пример #3
0
    def test_ap_invoices_list_are_in_new_status(self):
        self.client.force_login(self.ap_user)

        self.invoice_from_other_user.status = invoice_status_lookup(
            INVOICE_STATUS_REJECTED)
        self.invoice_from_other_user.save()

        response = self.client.get('{}?{}'.format(
            reverse('invoices-list'),
            'status={}'.format(invoice_status_lookup(INVOICE_STATUS_PENDING))))
        # Only the invoice with PENDING status should be listed
        self.assertNotContains(response,
                               self.invoice_from_other_user.invoice_number)
        self.assertContains(response, self.invoice.invoice_number)
Пример #4
0
    def test_invoice_in_progress_in_db(self):
        self.client.force_login(self.ap_user)
        self.client.post(
            reverse('change-invoice-status', kwargs={
                'pk': self.invoice.id,
            }), {
                'status': invoice_status_lookup(INVOICE_STATUS_IN_PROGRESS),
                'workday_id': 123123,
            },
            follow=True)

        invoice = get_object_or_404(Invoice, pk=self.invoice.id)
        self.assertEqual(invoice.status,
                         invoice_status_lookup(INVOICE_STATUS_IN_PROGRESS))
        self.assertEqual(invoice.workday_id, '123123')
Пример #5
0
    def user_has_permission(self):
        if not self.request.user.has_perm(CAN_CHANGE_INVOICE_STATUS_PERM):
            # Only allow supplier to edit the invoice if status is 'CHANGES REQUEST'
            invoice = get_object_or_404(Invoice, id=self.kwargs['pk'])
            return invoice.status == invoice_status_lookup(INVOICE_STATUS_CHANGES_REQUEST)

        return True
Пример #6
0
 def test_invoice_request_changes_comment_with_reason(self):
     self.client.force_login(self.ap_user)
     message = 'test reason'
     response = self.client.post(
         reverse('change-invoice-status', kwargs={
             'pk': self.invoice.id,
         }), {
             'status':
             invoice_status_lookup(INVOICE_STATUS_CHANGES_REQUEST),
             'message': message,
         })
     comment = invoice_history_comments(self.invoice)[-1]
     self.assertEqual(HTTPStatus.FOUND, response.status_code)
     self.assertIn(
         '{} from {} to {}'.format(
             'Status',
             INVOICE_STATUS_PENDING,
             INVOICE_STATUS_CHANGES_REQUEST,
         ),
         comment.message,
     )
     self.assertIn(
         message,
         comment.message,
     )
     self.assertEqual(comment.user, self.ap_user)
Пример #7
0
    def test_supplier_invoice_edit_and_it_exists_a_new_comment(self):
        # Given an invoice and a logged Supplier
        # invoice : self.invoice
        self.client.force_login(self.user)
        old_invoice_number = self.invoice.invoice_number
        self.invoice.status = invoice_status_lookup(
            INVOICE_STATUS_CHANGES_REQUEST)
        self.invoice.save()

        # When a supplier edits the invoice
        response = self.client.post(
            reverse('taxpayer-invoice-update',
                    kwargs={
                        'taxpayer_id': self.taxpayer.id,
                        'pk': self.invoice.id
                    }), self.invoice_post_data)
        # Then the invoice should have a comment associated to it with its message
        comment = invoice_history_comments(self.invoice)[-1]
        self.assertIn(
            '{} from 1234 to 987654321'.format(
                'Invoice Number',
                old_invoice_number,
                self.invoice.invoice_number,
            ),
            comment.message,
        )
        self.assertEqual(comment.user, self.user)
        self.assertEqual(HTTPStatus.FOUND, response.status_code)
Пример #8
0
 def test_invoice_change_status_only_ap_fail(self):
     self.client.force_login(self.user)
     request = self.client.post(
         reverse('change-invoice-status', kwargs={
             'pk': self.invoice.id,
         }), {
             'status': invoice_status_lookup(INVOICE_STATUS_APPROVED),
         })
     self.assertEqual(request.status_code, HTTPStatus.FORBIDDEN)
Пример #9
0
 def test_invoice_change_status_code(self, id, expected, _):
     self.client.force_login(self.ap_user)
     request = self.client.post(
         reverse('change-invoice-status', kwargs={
             'pk': id,
         }), {
             'status': invoice_status_lookup(INVOICE_STATUS_REJECTED),
         })
     self.assertEqual(request.status_code, expected)
Пример #10
0
 def test_invoice_change_status_code_to_approved(self):
     self.client.force_login(self.ap_user)
     request = self.client.post(
         reverse('change-invoice-status', kwargs={
             'pk': self.invoice.id,
         }), {
             'status': invoice_status_lookup(INVOICE_STATUS_APPROVED),
             'workday_id': 123123,
         })
     self.assertEqual(request.status_code, 302)
Пример #11
0
 def test_invoice_change_status_to_approved_no_workday_id(self):
     self.client.force_login(self.ap_user)
     request = self.client.post(
         reverse('change-invoice-status', kwargs={
             'pk': self.invoice.id,
         }), {
             'status': invoice_status_lookup(INVOICE_STATUS_IN_PROGRESS),
         },
         follow=True)
     self.assertContains(request, NO_WORKDAY_ID_ERROR)
Пример #12
0
 def test_supplier_invoice_edit(self):
     self.client.force_login(self.user)
     self.invoice.status = invoice_status_lookup(
         INVOICE_STATUS_CHANGES_REQUEST)
     self.invoice.save()
     res = self.client.post(
         reverse('taxpayer-invoice-update',
                 kwargs={
                     'taxpayer_id': self.taxpayer.id,
                     'pk': self.invoice.id
                 }),
         self.invoice_post_data,
     )
     self.assertEqual(res.status_code, HTTPStatus.FOUND)
     self.invoice.refresh_from_db()
     self.assertEqual(self.invoice.invoice_number,
                      self.invoice_post_data['invoice_number'])
     self.assertEqual(self.invoice.status,
                      invoice_status_lookup(INVOICE_STATUS_PENDING))
Пример #13
0
 def test_invoice_create_view(self):
     self.client.force_login(self.user)
     response = self.client.post(
         reverse('invoice-create', kwargs={'taxpayer_id':
                                           self.taxpayer.id}),
         self.invoice_post_data,
     )
     self.assertEqual(response.status_code, HTTPStatus.FOUND)
     invoice = Invoice.objects.get(
         invoice_number=self.invoice_post_data['invoice_number'])
     self.assertEqual(invoice.status,
                      invoice_status_lookup(INVOICE_STATUS_PENDING))
Пример #14
0
 def test_invoice_request_changes_without_comment(self):
     self.client.force_login(self.ap_user)
     response = self.client.post(reverse(
         'change-invoice-status', kwargs={
             'pk': self.invoice.id,
         }), {
             'status':
             invoice_status_lookup(INVOICE_STATUS_CHANGES_REQUEST),
         },
                                 follow=True)
     self.assertEqual(HTTPStatus.OK, response.status_code)
     self.assertContains(response, NO_COMMENT_ERROR)
Пример #15
0
 def test_ap_invoice_edit(self):
     self.client.force_login(self.ap_user)
     res = self.client.post(
         reverse('invoice-update', kwargs={'pk': self.invoice.id}),
         self.invoice_post_data,
     )
     self.assertEqual(res.status_code, HTTPStatus.FOUND)
     self.invoice.refresh_from_db()
     self.assertEqual(self.invoice.invoice_number,
                      self.invoice_post_data['invoice_number'])
     self.assertEqual(self.invoice.status,
                      invoice_status_lookup(INVOICE_STATUS_PENDING))
Пример #16
0
 def get_context_data(self, **kwargs):
     context = super().get_context_data(**kwargs)
     invoice = get_object_or_404(Invoice, id=self.kwargs['pk'])
     if self.request.user.is_AP:
         if invoice.new_comment_from_supplier is True:
             invoice.new_comment_from_supplier = False
             invoice.save()
     elif self.request.user.is_supplier:
         if invoice.new_comment_from_ap is True:
             invoice.new_comment_from_ap = False
             invoice.save()
     context['invoice'] = invoice
     father_taxpayer = get_object_or_404(TaxPayer, id=self.kwargs['taxpayer_id'])
     context['is_AP'] = self.request.user.is_AP
     context['taxpayer'] = father_taxpayer.get_taxpayer_child()
     context['address'] = Address.objects.get(taxpayer=father_taxpayer.get_taxpayer_child())
     context['INVOICE_STATUS_APPROVED'] = invoice_status_lookup(INVOICE_STATUS_APPROVED)
     context['INVOICE_STATUS_PENDING'] = invoice_status_lookup(INVOICE_STATUS_PENDING)
     context['INVOICE_STATUS_CHANGES_REQUEST'] = invoice_status_lookup(INVOICE_STATUS_CHANGES_REQUEST)
     context['INVOICE_STATUS_REJECTED'] = invoice_status_lookup(INVOICE_STATUS_REJECTED)
     context['INVOICE_STATUS_PAID'] = invoice_status_lookup(INVOICE_STATUS_PAID)
     context['INVOICE_STATUS_IN_PROGRESS'] = invoice_status_lookup(INVOICE_STATUS_IN_PROGRESS)
     context['comments'] = self.get_comments(invoice)
     context['date_format'] = DATE_FORMAT
     return context
Пример #17
0
 def test_invoice_change_status_repeated_workday_id(self):
     self.client.force_login(self.ap_user)
     self.invoice.workday_id = 'G-180'
     self.invoice.save()
     response = self.client.post(
         reverse('change-invoice-status', kwargs={
             'pk': self.invoice.id,
         }), {
             'status': invoice_status_lookup(INVOICE_STATUS_IN_PROGRESS),
             'workday_id': "G-180",
         },
         follow=True)
     self.assertContains(response, 'Workday ID already exist')
Пример #18
0
def change_invoice_status(request, pk):

    status = request.POST.get('status')

    if status not in INVOICE_STATUSES_DICT.keys():
        return HttpResponseBadRequest()

    strategy = get_change_status_strategy(status)
    invoice = get_object_or_404(Invoice, pk=pk)

    try:
        strategy(invoice, status, request)
    except ValidationError as err:
        messages.error(request, err.message)
        return redirect(
            reverse(
                'invoices-detail',
                kwargs={
                    'taxpayer_id': invoice.taxpayer.id,
                    'pk': pk,
                }
            )
        )
    except IntegrityError as err:
        messages.error(request, err)
        return redirect(
            reverse(
                'invoices-detail',
                kwargs={
                    'taxpayer_id': invoice.taxpayer.id,
                    'pk': pk,
                }
            )
        )

    invoice.save()
    invoice_changed = _('Invoice status has changed to ')
    messages.success(
                request,
                f'{invoice_changed}{INVOICE_STATUSES_DICT[status]}',
            )

    if status != INVOICE_STATUS_PENDING_CODE:
        _send_email_when_change_invoice_status(request, invoice)

    return redirect(
        '{}?status={}'.format(
            reverse('invoices-list'),
            invoice_status_lookup(INVOICE_STATUS_PENDING)
        )
    )
Пример #19
0
 def get_context_data(self, **kwargs):
     context = super().get_context_data(**kwargs)
     context['date_format'] = str(DATE_FORMAT)
     context['INVOICE_STATUS_APPROVED'] = invoice_status_lookup(INVOICE_STATUS_APPROVED)
     context['INVOICE_STATUS_PENDING'] = invoice_status_lookup(INVOICE_STATUS_PENDING)
     context['INVOICE_STATUS_CHANGES_REQUEST'] = invoice_status_lookup(INVOICE_STATUS_CHANGES_REQUEST)
     context['INVOICE_STATUS_REJECTED'] = invoice_status_lookup(INVOICE_STATUS_REJECTED)
     context['INVOICE_STATUS_PAID'] = invoice_status_lookup(INVOICE_STATUS_PAID)
     context['INVOICE_STATUS_IN_PROGRESS'] = invoice_status_lookup(INVOICE_STATUS_IN_PROGRESS)
     return context
Пример #20
0
 def test_ap_invoice_edit_permissions(self):
     self.client.force_login(self.ap_user)
     self.invoice.status = invoice_status_lookup(INVOICE_STATUS_APPROVED)
     self.invoice.save()
     res = self.client.post(
         reverse('taxpayer-invoice-update',
                 kwargs={
                     'taxpayer_id': self.taxpayer.id,
                     'pk': self.invoice.id
                 }),
         self.invoice_post_data,
     )
     self.assertEqual(res.status_code, HTTPStatus.FOUND)
     self.invoice.refresh_from_db()
     self.assertEqual(self.invoice.invoice_number,
                      self.invoice_post_data['invoice_number'])
Пример #21
0
 def get_context_data(self, **kwargs):
     context = super().get_context_data(**kwargs)
     context['taxpayer'] = TaxPayer.objects.get(id=self.kwargs['taxpayer_id'])
     context['INVOICE_STATUS_APPROVED'] = invoice_status_lookup(INVOICE_STATUS_APPROVED)
     context['INVOICE_STATUS_PENDING'] = invoice_status_lookup(INVOICE_STATUS_PENDING)
     context['INVOICE_STATUS_CHANGES_REQUEST'] = invoice_status_lookup(INVOICE_STATUS_CHANGES_REQUEST)
     context['INVOICE_STATUS_REJECTED'] = invoice_status_lookup(INVOICE_STATUS_REJECTED)
     context['INVOICE_STATUS_PAID'] = invoice_status_lookup(INVOICE_STATUS_PAID)
     context['INVOICE_STATUS_IN_PROGRESS'] = invoice_status_lookup(INVOICE_STATUS_IN_PROGRESS)
     context['date_format'] = DATE_FORMAT
     return context
Пример #22
0
    def test_supplier_invalid_invoice_edit_request(self):
        self.client.force_login(self.user)
        self.invoice.status = invoice_status_lookup(
            INVOICE_STATUS_CHANGES_REQUEST)
        self.invoice.save()

        old_invoice_number = self.invoice.invoice_number
        res = self.client.post(
            reverse('taxpayer-invoice-update',
                    kwargs={
                        'taxpayer_id': self.taxpayer.id,
                        'pk': self.invoice.id
                    }), {})
        self.assertEqual(res.status_code, HTTPStatus.OK)
        self.invoice.refresh_from_db()
        self.assertEqual(self.invoice.invoice_number, old_invoice_number)
        self.assertContains(res, 'This field is required.')
Пример #23
0
    def test_supplier_invoice_edit_permissions(self):
        self.client.force_login(self.user)

        self.invoice.status = invoice_status_lookup(
            INVOICE_STATUS_CHANGES_REQUEST)
        self.invoice.save()
        res = self.client.post(
            reverse('taxpayer-invoice-update',
                    kwargs={
                        'taxpayer_id': self.taxpayer.id,
                        'pk': self.invoice.id
                    }),
            self.invoice_post_data,
            follow=True,
        )
        self.assertIn((reverse('invoices-list'), 302), res.redirect_chain)
        self.assertEqual(res.status_code, HTTPStatus.OK)
Пример #24
0
    def test_generate_a_comment_when_invoice_changes_his_state(
            self, new_status, _):
        # Given an invoice and a logged AP
        # invoice : self.invoice
        self.client.force_login(self.ap_user)
        old_status = self.invoice.get_status_display()
        # When AP changes its state
        response = self.client.post(
            reverse('change-invoice-status', kwargs={
                'pk': self.invoice.id,
            }), {'status': invoice_status_lookup(new_status)})

        # Then the invoice should have a comment associated to it with its message
        comment = invoice_history_comments(self.invoice)[0]
        self.assertEqual(
            comment.message,
            'Changed: \n{} from {} to {}\n'.format('Status', old_status,
                                                   new_status))
        self.assertEqual(comment.user, self.ap_user)
        self.assertEqual(HTTPStatus.FOUND, response.status_code)
Пример #25
0
 def get_context_data(self, **kwargs):
     context = super().get_context_data(**kwargs)
     context['filter_to_xls'] = urllib.parse.urlparse(self.request.get_raw_uri()).query
     context['is_AP'] = self.request.user.is_AP
     context['INVOICE_STATUS_APPROVED'] = invoice_status_lookup(INVOICE_STATUS_APPROVED)
     context['INVOICE_STATUS_PENDING'] = invoice_status_lookup(INVOICE_STATUS_PENDING)
     context['INVOICE_STATUS_CHANGES_REQUEST'] = invoice_status_lookup(INVOICE_STATUS_CHANGES_REQUEST)
     context['INVOICE_STATUS_REJECTED'] = invoice_status_lookup(INVOICE_STATUS_REJECTED)
     context['INVOICE_STATUS_PAID'] = invoice_status_lookup(INVOICE_STATUS_PAID)
     context['INVOICE_STATUS_IN_PROGRESS'] = invoice_status_lookup(INVOICE_STATUS_IN_PROGRESS)
     context['date_format'] = DATE_FORMAT
     all_taxpayers = self.get_taxpayers()
     context['all_taxpayers'] = all_taxpayers
     if not self.request.user.is_AP:
         context['has_approved_taxpayer'] = any(taxpayer.taxpayer_state == 'APPROVED' for taxpayer in all_taxpayers)
     
     return context
Пример #26
0
 def test_invoice_status_lookup(self, expected_value, tag):
     self.assertEqual(invoice_status_lookup(tag), expected_value)
Пример #27
0
class Invoice(models.Model):

    class Meta:
        unique_together = ('taxpayer', 'invoice_number',)

    taxpayer = models.ForeignKey(TaxPayer, on_delete=models.PROTECT)
    currency = models.CharField(max_length=200, choices=CURRENCIES, verbose_name=_('Currency'))
    status = models.CharField(
        max_length=40,
        choices=INVOICE_STATUS,
        default=invoice_status_lookup(INVOICE_STATUS_PENDING),
        verbose_name=_('Status')
    )
    po_number = models.CharField(max_length=200, help_text="ex: 12341234", verbose_name=_('PO number'))
    invoice_date = models.DateField(verbose_name=_('Invoice date'))
    invoice_due_date = models.DateField(verbose_name=_('Due Date'))
    invoice_date_received = models.DateTimeField(auto_now_add=True, verbose_name=_('Date Received'))
    invoice_number = models.CharField(max_length=20, verbose_name=_('Invoice Number'))
    net_amount = models.DecimalField(
        verbose_name=_('Net amount'),
        max_digits=20,
        decimal_places=2,
        validators=[MinValueValidator(Decimal('0.01'))],
        blank=True,
        null=True,
    )
    vat = models.DecimalField(
        max_digits=20,
        decimal_places=2,
        validators=[MinValueValidator(Decimal('0.00'))],
        verbose_name=_('Tax Liens'),
        blank=True,
        null=True,
    )
    total_amount = models.DecimalField(
        max_digits=20,
        decimal_places=2,
        validators=[MinValueValidator(Decimal('0.01'))],
        verbose_name=_('Total'),
    )
    user = models.ForeignKey(
      settings.AUTH_USER_MODEL,
      on_delete=models.CASCADE
    )
    invoice_file = models.FileField(
        upload_to='file',
        verbose_name=_('Invoice File'),
        validators=[
            FileExtensionValidator(allowed_extensions=['pdf']),
            FileSizeValidator(limit_size=INVOICE_MAX_SIZE_FILE),
        ]
    )
    workday_id = models.CharField(max_length=50, blank=True, null=True)

    invoice_eb_entity = models.ForeignKey(EBEntity, default=None)

    new_comment_from_supplier = models.BooleanField(default=False)

    new_comment_from_ap = models.BooleanField(default=False)

    history = HistoricalRecords()

    @property
    def taxpayer_name(self):
        return self.taxpayer.business_name
Пример #28
0
 def form_valid(self, form):
     form.instance.status = invoice_status_lookup(INVOICE_STATUS_PENDING)
     return super().form_valid(form)