def expense_payments(request, expense_payment_id=None): readOnly = False if not request.user.groups.filter(name="expense_paymaster").exists() and not request.user.is_superuser: readOnly = True try: if expense_payment_id: expensePayment = ExpensePayment.objects.get(id=expense_payment_id) except ExpensePayment.DoesNotExist: messages.add_message(request, messages.ERROR, _("Expense payment %s does not exist" % expense_payment_id)) expense_payment_id = None expensePayment = None if readOnly: expensesToPay = [] else: expensesToPay = Expense.objects.filter(workflow_in_progress=True, corporate_card=False, expensePayment=None) expensesToPay = [expense for expense in expensesToPay if wf.get_state(expense).transitions.count() == 0] if request.method == "POST": if readOnly: # A bad user is playing with urls... return HttpResponseRedirect(urlresolvers.reverse("forbiden")) form = ExpensePaymentForm(request.POST) if form.is_valid(): if expense_payment_id: expensePayment = ExpensePayment.objects.get(id=expense_payment_id) expensePayment.payment_date = form.cleaned_data["payment_date"] else: expensePayment = ExpensePayment(payment_date=form.cleaned_data["payment_date"]) expensePayment.save() for expense in Expense.objects.filter(expensePayment=expensePayment): expense.expensePayment = None # Remove any previous association expense.save() if form.cleaned_data["expenses"]: for expense in form.cleaned_data["expenses"]: expense.expensePayment = expensePayment expense.workflow_in_progress = False expense.save() return HttpResponseRedirect(urlresolvers.reverse("expense.views.expense_payments")) else: print "form is not valid" else: if expense_payment_id: expensePayment = ExpensePayment.objects.get(id=expense_payment_id) form = ExpensePaymentForm({"expenses": list(Expense.objects.filter(expensePayment=expensePayment).values_list("id", flat=True)), "payment_date": expensePayment.payment_date}) # A form that edit current expense payment else: form = ExpensePaymentForm(initial={"payment_date": date.today()}) # An unbound form return render(request, "expense/expense_payments.html", {"modify_expense_payment": bool(expense_payment_id), "data_url": urlresolvers.reverse('expense_payment_table_DT'), "data_options": ''' "pageLength": 25, "order": [[0, "desc"]], "columnDefs": [{ "orderable": false, "targets": [1, 2, 4] }]''', "expense_to_pay_table": ExpenseTable(expensesToPay), "read_only": readOnly, "form": form, "user": request.user})
def expense_payments(request, expense_payment_id=None): readOnly = False if not request.user.groups.filter(name="expense_paymaster").exists() and not request.user.is_superuser: readOnly = True try: if expense_payment_id: expensePayment = ExpensePayment.objects.get(id=expense_payment_id) except ExpensePayment.DoesNotExist: messages.add_message(request, messages.ERROR, _("Expense payment %s does not exist" % expense_payment_id)) expense_payment_id = None expensePayment = None if readOnly: expensesToPay = [] else: expensesToPay = Expense.objects.filter(workflow_in_progress=True, corporate_card=False, expensePayment=None, state="CONTROLLED") if request.method == "POST": if readOnly: # A bad user is playing with urls... return HttpResponseRedirect(reverse("core:forbiden")) form = ExpensePaymentForm(request.POST) if form.is_valid(): if expense_payment_id: expensePayment = ExpensePayment.objects.get(id=expense_payment_id) expensePayment.payment_date = form.cleaned_data["payment_date"] else: expensePayment = ExpensePayment(payment_date=form.cleaned_data["payment_date"]) expensePayment.save() for expense in Expense.objects.filter(expensePayment=expensePayment): expense.expensePayment = None # Remove any previous association expense.save() if form.cleaned_data["expenses"]: for expense in form.cleaned_data["expenses"]: expense.expensePayment = expensePayment expense.workflow_in_progress = False expense.save() return HttpResponseRedirect(reverse("expense:expense_payments")) else: print("form is not valid") else: if expense_payment_id: expensePayment = ExpensePayment.objects.get(id=expense_payment_id) form = ExpensePaymentForm({"expenses": list(Expense.objects.filter(expensePayment=expensePayment).values_list("id", flat=True)), "payment_date": expensePayment.payment_date}) # A form that edit current expense payment else: form = ExpensePaymentForm(initial={"payment_date": date.today()}) # An unbound form return render(request, "expense/expense_payments.html", {"modify_expense_payment": bool(expense_payment_id), "data_url": reverse('expense:expense_payment_table_DT'), "data_options": ''' "pageLength": 25, "order": [[0, "desc"]], "columnDefs": [{ "orderable": false, "targets": [1, 2, 4] }]''', "expense_to_pay_table": ExpenseTable(expensesToPay), "read_only": readOnly, "form": form, "user": request.user})
def test_expense_wf(self): # Setup default workflow install_expense_workflow() ABR = Consultant.objects.get(trigramme="ABR") TCO = Consultant.objects.get(trigramme="TCO") tco = TCO.getUser() abr = ABR.getUser() fla = User.objects.get(username="******") category = ExpenseCategory.objects.create(name="repas") e = Expense.objects.create(user=tco, description="une grande bouffe", category=category, amount=123, creation_date=date.today(), expense_date=date.today()) self.assertEqual(wf.get_state(e), None) wf.set_initial_state(e) self.assertNotEqual(wf.get_state(e), None) # Now wf is setup # state = requested self.assertEqual(len(wf.get_allowed_transitions(e, tco)), 0) # No transition allowed for user self.assertEqual(len(wf.get_allowed_transitions(e, fla)), 0) # No transition allowed for paymaster self.assertEqual(len(wf.get_allowed_transitions(e, abr)), 2) # But for his manager accept/reject # Reject it reject = Transition.objects.get(name="reject") self.assertTrue(wf.do_transition(e, reject, abr)) for user in (tco, abr, fla): self.assertEqual(len(wf.get_allowed_transitions(e, user)), 0) # No transition allowed # Validate it wf.set_initial_state(e) # Returns to requested state validate = Transition.objects.get(name="validate") self.assertTrue(wf.do_transition(e, validate, abr)) for user in (tco, abr): self.assertEqual(len(wf.get_allowed_transitions(e, user)), 0) # No transition allowed self.assertEqual(len(wf.get_allowed_transitions(e, fla)), 2) # Except paymaster accept/ask info # Ask information ask = Transition.objects.get(name="ask information") self.assertTrue(wf.do_transition(e, ask, fla)) self.assertTrue(perm.has_permission(e, tco, "expense_edit")) wf.set_initial_state(e) # Returns to requested state self.assertEqual(len(wf.get_allowed_transitions(e, tco)), 0) # No transition allowed for user self.assertTrue(wf.do_transition(e, validate, abr)) # Validate it again # Check it control = Transition.objects.get(name="control") self.assertTrue(wf.do_transition(e, control, fla)) for user in (tco, abr, fla): self.assertEqual(len(wf.get_allowed_transitions(e, user)), 0) # No transition allowed # Create a payment for that expense expensePayment = ExpensePayment(payment_date=date.today()) expensePayment.save() e.expensePayment = expensePayment e.save() self.assertEqual(expensePayment.user(), tco) self.assertEqual(expensePayment.amount(), 123)
def expense_payments(request, expense_payment_id=None): readOnly = False if not request.user.groups.filter(name="expense_paymaster").exists() and not request.user.is_superuser: readOnly = True try: if expense_payment_id: expensePayment = ExpensePayment.objects.get(id=expense_payment_id) except ExpensePayment.DoesNotExist: messages.add_message(request, messages.ERROR, _("Expense payment %s does not exist" % expense_payment_id)) expense_payment_id = None expensePayment = None if readOnly: expensesToPay = [] else: expensesToPay = Expense.objects.filter(workflow_in_progress=True, corporate_card=False, expensePayment=None) expensesToPay = [expense for expense in expensesToPay if wf.get_state(expense).transitions.count() == 0] try: consultant = Consultant.objects.get(trigramme__iexact=request.user.username) user_team = consultant.userTeam() except Consultant.DoesNotExist: user_team = [] expensePayments = ExpensePayment.objects.all() if not perm.has_role(request.user, "expense paymaster"): expensePayments = expensePayments.filter(Q(expense__user=request.user) | Q(expense__user__in=user_team)).distinct() if request.method == "POST": if readOnly: # A bad user is playing with urls... return HttpResponseRedirect(urlresolvers.reverse("forbiden")) form = ExpensePaymentForm(request.POST) if form.is_valid(): if expense_payment_id: expensePayment = ExpensePayment.objects.get(id=expense_payment_id) else: expensePayment = ExpensePayment(payment_date=form.cleaned_data["payment_date"]) expensePayment.save() for expense in Expense.objects.filter(expensePayment=expensePayment): expense.expensePayment = None # Remove any previous association expense.save() if form.cleaned_data["expenses"]: for expense_id in form.cleaned_data["expenses"]: expense = Expense.objects.get(id=expense_id) expense.expensePayment = expensePayment expense.workflow_in_progress = False expense.save() return HttpResponseRedirect(urlresolvers.reverse("expense.views.expense_payments")) else: if expense_payment_id: form = ExpensePaymentForm({"expenses": "|".join([str(e.id) for e in Expense.objects.filter(expensePayment=expensePayment)]), "payment_date": expensePayment.payment_date}) # A form that edit current expense payment else: form = ExpensePaymentForm(initial={"payment_date": date.today()}) # An unbound form return render(request, "expense/expense_payments.html", {"modify_expense_payment": bool(expense_payment_id), "expense_payment_table": ExpensePaymentTable(expensePayments), "expense_to_pay_table": ExpenseTable(expensesToPay), "read_only": readOnly, "form": form, "user": request.user})
def expense_payments(request, expense_payment_id=None): readOnly = False if not request.user.groups.filter(name="expense_paymaster").exists() and not request.user.is_superuser: readOnly = True try: if expense_payment_id: expensePayment = ExpensePayment.objects.get(id=expense_payment_id) except ExpensePayment.DoesNotExist: messages.add_message(request, messages.ERROR, _("Expense payment %s does not exist" % expense_payment_id)) expense_payment_id = None expensePayment = None if readOnly: expensesToPay = [] else: expensesToPay = Expense.objects.filter(workflow_in_progress=True, corporate_card=False, expensePayment=None) expensesToPay = [expense for expense in expensesToPay if wf.get_state(expense).transitions.count() == 0] try: consultant = Consultant.objects.get(trigramme__iexact=request.user.username) user_team = consultant.userTeam() except Consultant.DoesNotExist: user_team = [] expensePayments = ExpensePayment.objects.all() if not utils.has_role(request.user, "expense paymaster"): expensePayments = expensePayments.filter(Q(expense__user=request.user) | Q(expense__user__in=user_team)).distinct() if request.method == "POST": if readOnly: # A bad user is playing with urls... return HttpResponseRedirect(urlresolvers.reverse("forbiden")) form = ExpensePaymentForm(request.POST) if form.is_valid(): if expense_payment_id: expensePayment = ExpensePayment.objects.get(id=expense_payment_id) expensePayment.payment_date = form.cleaned_data["payment_date"] else: expensePayment = ExpensePayment(payment_date=form.cleaned_data["payment_date"]) expensePayment.save() for expense in Expense.objects.filter(expensePayment=expensePayment): expense.expensePayment = None # Remove any previous association expense.save() if form.cleaned_data["expenses"]: for expense in form.cleaned_data["expenses"]: expense.expensePayment = expensePayment expense.workflow_in_progress = False expense.save() return HttpResponseRedirect(urlresolvers.reverse("expense.views.expense_payments")) else: print "form is not valid" else: if expense_payment_id: expensePayment = ExpensePayment.objects.get(id=expense_payment_id) form = ExpensePaymentForm({"expenses": list(Expense.objects.filter(expensePayment=expensePayment).values_list("id", flat=True)), "payment_date": expensePayment.payment_date}) # A form that edit current expense payment else: form = ExpensePaymentForm(initial={"payment_date": date.today()}) # An unbound form return render(request, "expense/expense_payments.html", {"modify_expense_payment": bool(expense_payment_id), "expense_payment_table": ExpensePaymentTable(expensePayments), "expense_to_pay_table": ExpenseTable(expensesToPay), "read_only": readOnly, "form": form, "user": request.user})
def test_expense_swf(self): """Test expense simple & stupid workflow""" cache.clear() # avoid user team cache tco = User.objects.get(username="******") abr = User.objects.get(username="******") fla = User.objects.get(username="******") sre = User.objects.get(username="******") gba = User.objects.get(username="******") abo = User.objects.get(username="******") category = ExpenseCategory.objects.create(name="repas") e = Expense.objects.create(user=tco, description="une grande bouffe", category=category, amount=123, chargeable=False, creation_date=date.today(), expense_date=date.today()) # current (starting) state is requested self.assertEqual(e.state, "REQUESTED") self.assertEqual(len(expense_next_states(e, tco)), 0) # No transition allowed for user self.assertEqual(len(expense_next_states(e, fla)), 0) # No transition allowed for paymaster self.assertEqual( len(expense_next_states(e, gba)), 0) # No transition allowed for administrator of other subsidiary # But for his manager or administrator for user in (abr, sre): states = expense_next_states(e, user) self.assertIn("VALIDATED", states) self.assertIn("NEEDS_INFORMATION", states) self.assertIn("REJECTED", states) # Not yet validated, so user and his manager can edit it self.assertTrue(can_edit_expense(e, tco)) self.assertTrue(can_edit_expense(e, abr)) # Reject it e.state = "REJECT" e.save() for user in (tco, abr, fla, gba): self.assertEqual(len(expense_next_states(e, user)), 0) # No transition allowed self.assertFalse(can_edit_expense(e, user)) # No edition allowed self.assertTrue(can_edit_expense(e, sre)) # Except admin # Validate it e.state = "VALIDATED" e.save() for user in (tco, abr): self.assertEqual(len(expense_next_states(e, user)), 0) # No transition allowed self.assertFalse(can_edit_expense(e, user)) # No edition allowed # Except paymaster for control/ask info states = expense_next_states(e, fla) self.assertIn("NEEDS_INFORMATION", states) self.assertIn("CONTROLLED", states) self.assertTrue(can_edit_expense(e, sre)) # Ask information e.state = "NEEDS_INFORMATION" e.save() self.assertTrue(can_edit_expense(e, tco)) self.assertTrue(can_edit_expense(e, abr)) # Control it e.state = "CONTROLLED" e.save() for user in (tco, abr, gba): self.assertEqual(len(expense_next_states(e, user)), 0) # No transition allowed self.assertFalse(can_edit_expense(e, user)) # No edition allowed self.assertTrue(can_edit_expense(e, sre)) # Except admin e.corporate_card = True e.save() self.assertEqual(len(expense_next_states(e, fla)), 0) # No payment if corporate card was used # Create a payment for that expense expensePayment = ExpensePayment(payment_date=date.today()) expensePayment.save() e.expensePayment = expensePayment e.state = "PAID" e.save() self.assertEqual(expensePayment.user(), tco) self.assertEqual(expensePayment.amount(), 123) for user in (tco, abr, fla): self.assertEqual(len(expense_next_states(e, user)), 0) # No transition allowed self.assertFalse(can_edit_expense(e, user)) # No edition allowed self.assertTrue(can_edit_expense(e, sre)) # Except admin # Create a new one in other subsidiary e = Expense.objects.create( user=abo, description="une belle quille de vin nature", category=category, amount=123, chargeable=False, creation_date=date.today(), expense_date=date.today()) # gba is not his manager the subsidiary manager, so he should be able to manage its expense states = expense_next_states(e, gba) self.assertIn("VALIDATED", states) self.assertIn("NEEDS_INFORMATION", states) self.assertIn("REJECTED", states) self.assertTrue(can_edit_expense(e, gba)) e.state = "VALIDATED" for user in (abo, gba): self.assertEqual(len(expense_next_states(e, user)), 0) # No transition allowed self.assertFalse(can_edit_expense(e, user)) # No edition allowed
def test_expense_swf(self): """Test expense simple & stupid workflow""" tco = User.objects.get(username="******") abr = User.objects.get(username="******") fla = User.objects.get(username="******") sre = User.objects.get(username="******") category = ExpenseCategory.objects.create(name="repas") e = Expense.objects.create(user=tco, description="une grande bouffe", category=category, amount=123, chargeable=False, creation_date=date.today(), expense_date=date.today()) # current (starting) state is requested self.assertEqual(e.state, "REQUESTED") self.assertEqual(len(expense_next_states(e, tco)), 0) # No transition allowed for user self.assertEqual(len(expense_next_states(e, fla)), 0) # No transition allowed for paymaster # But for his manager... states = expense_next_states(e, abr) self.assertIn("VALIDATED", states) self.assertIn("NEEDS_INFORMATION", states) self.assertIn("REJECTED", states) self.assertTrue(can_edit_expense(e, tco)) # Reject it e.state = "REJECT" e.save() for user in (tco, abr, fla): self.assertEqual(len(expense_next_states(e, user)), 0) # No transition allowed self.assertFalse(can_edit_expense(e, user)) # No edition allowed self.assertTrue(can_edit_expense(e, sre)) # Except admin # Validate it e.state = "VALIDATED" e.save() for user in (tco, abr): self.assertEqual(len(expense_next_states(e, user)), 0) # No transition allowed self.assertFalse(can_edit_expense(e, user)) # No edition allowed # Except paymaster for control/ask info states = expense_next_states(e, fla) self.assertIn("NEEDS_INFORMATION", states) self.assertIn("CONTROLLED", states) self.assertTrue(can_edit_expense(e, sre)) # Ask information e.state = "NEEDS_INFORMATION" e.save() self.assertTrue(can_edit_expense(e, tco)) self.assertTrue(can_edit_expense(e, abr)) # Control it e.state = "CONTROLLED" e.save() for user in (tco, abr): self.assertEqual(len(expense_next_states(e, user)), 0) # No transition allowed self.assertFalse(can_edit_expense(e, user)) # No edition allowed self.assertTrue(can_edit_expense(e, sre)) # Except admin e.corporate_card = True e.save() self.assertEqual(len(expense_next_states(e, fla)), 0) # No payment if corporate card was used # Create a payment for that expense expensePayment = ExpensePayment(payment_date=date.today()) expensePayment.save() e.expensePayment = expensePayment e.state = "PAID" e.save() self.assertEqual(expensePayment.user(), tco) self.assertEqual(expensePayment.amount(), 123) for user in (tco, abr, fla): self.assertEqual(len(expense_next_states(e, user)), 0) # No transition allowed self.assertFalse(can_edit_expense(e, user)) # No edition allowed self.assertTrue(can_edit_expense(e, sre)) # Except admin