@@ -10,7 +10,6 @@ kimai:
|
|||||||
short: 'App\Invoice\ShortInvoiceCalculator'
|
short: 'App\Invoice\ShortInvoiceCalculator'
|
||||||
number_generator:
|
number_generator:
|
||||||
default: 'App\Invoice\DateNumberGenerator'
|
default: 'App\Invoice\DateNumberGenerator'
|
||||||
#random: 'App\Invoice\RandomNumberGenerator'
|
|
||||||
|
|
||||||
twig:
|
twig:
|
||||||
globals:
|
globals:
|
||||||
|
|||||||
@@ -226,7 +226,7 @@ class InvoiceController extends AbstractController
|
|||||||
*/
|
*/
|
||||||
public function invoiceAction(InvoiceModel $model)
|
public function invoiceAction(InvoiceModel $model)
|
||||||
{
|
{
|
||||||
return $this->render('invoice/print.html.twig', [
|
return $this->render('invoice/renderer/print.html.twig', [
|
||||||
'model' => $model,
|
'model' => $model,
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
@@ -237,7 +237,7 @@ class InvoiceController extends AbstractController
|
|||||||
*/
|
*/
|
||||||
public function timesheetAction(InvoiceModel $model)
|
public function timesheetAction(InvoiceModel $model)
|
||||||
{
|
{
|
||||||
return $this->render('invoice/timesheet.html.twig', [
|
return $this->render('invoice/renderer/timesheet.html.twig', [
|
||||||
'model' => $model,
|
'model' => $model,
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -52,6 +52,14 @@ class Project
|
|||||||
*/
|
*/
|
||||||
private $name;
|
private $name;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var string
|
||||||
|
*
|
||||||
|
* @ORM\Column(name="order_number", type="text", length=20, nullable=true)
|
||||||
|
* @Assert\Length(max=20)
|
||||||
|
*/
|
||||||
|
private $orderNumber;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @var string
|
* @var string
|
||||||
*
|
*
|
||||||
@@ -68,7 +76,7 @@ class Project
|
|||||||
private $visible = true;
|
private $visible = true;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @var string
|
* @var float
|
||||||
*
|
*
|
||||||
* @ORM\Column(name="budget", type="decimal", precision=10, scale=2, nullable=false)
|
* @ORM\Column(name="budget", type="decimal", precision=10, scale=2, nullable=false)
|
||||||
* @Assert\NotNull()
|
* @Assert\NotNull()
|
||||||
@@ -114,13 +122,11 @@ class Project
|
|||||||
* Set name
|
* Set name
|
||||||
*
|
*
|
||||||
* @param string $name
|
* @param string $name
|
||||||
*
|
|
||||||
* @return Project
|
* @return Project
|
||||||
*/
|
*/
|
||||||
public function setName($name)
|
public function setName($name)
|
||||||
{
|
{
|
||||||
$this->name = $name;
|
$this->name = $name;
|
||||||
|
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -138,13 +144,11 @@ class Project
|
|||||||
* Set comment
|
* Set comment
|
||||||
*
|
*
|
||||||
* @param string $comment
|
* @param string $comment
|
||||||
*
|
|
||||||
* @return Project
|
* @return Project
|
||||||
*/
|
*/
|
||||||
public function setComment($comment)
|
public function setComment($comment)
|
||||||
{
|
{
|
||||||
$this->comment = $comment;
|
$this->comment = $comment;
|
||||||
|
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -162,13 +166,11 @@ class Project
|
|||||||
* Set visible
|
* Set visible
|
||||||
*
|
*
|
||||||
* @param boolean $visible
|
* @param boolean $visible
|
||||||
*
|
|
||||||
* @return Project
|
* @return Project
|
||||||
*/
|
*/
|
||||||
public function setVisible($visible)
|
public function setVisible($visible)
|
||||||
{
|
{
|
||||||
$this->visible = $visible;
|
$this->visible = $visible;
|
||||||
|
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -185,21 +187,19 @@ class Project
|
|||||||
/**
|
/**
|
||||||
* Set budget
|
* Set budget
|
||||||
*
|
*
|
||||||
* @param string $budget
|
* @param float $budget
|
||||||
*
|
|
||||||
* @return Project
|
* @return Project
|
||||||
*/
|
*/
|
||||||
public function setBudget($budget)
|
public function setBudget($budget)
|
||||||
{
|
{
|
||||||
$this->budget = $budget;
|
$this->budget = $budget;
|
||||||
|
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get budget
|
* Get budget
|
||||||
*
|
*
|
||||||
* @return string
|
* @return float
|
||||||
*/
|
*/
|
||||||
public function getBudget()
|
public function getBudget()
|
||||||
{
|
{
|
||||||
@@ -208,12 +208,11 @@ class Project
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @param Activity[] $activities
|
* @param Activity[] $activities
|
||||||
* @return $this
|
* @return Project
|
||||||
*/
|
*/
|
||||||
public function setActivities($activities)
|
public function setActivities($activities)
|
||||||
{
|
{
|
||||||
$this->activities = $activities;
|
$this->activities = $activities;
|
||||||
|
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -225,6 +224,24 @@ class Project
|
|||||||
return $this->activities;
|
return $this->activities;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public function getOrderNumber(): ?string
|
||||||
|
{
|
||||||
|
return $this->orderNumber;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param string $orderNumber
|
||||||
|
* @return Project
|
||||||
|
*/
|
||||||
|
public function setOrderNumber($orderNumber)
|
||||||
|
{
|
||||||
|
$this->orderNumber = $orderNumber;
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return string
|
* @return string
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -45,29 +45,30 @@ class ProjectEditForm extends AbstractType
|
|||||||
}
|
}
|
||||||
|
|
||||||
$builder
|
$builder
|
||||||
// string - length 255
|
|
||||||
->add('name', TextType::class, [
|
->add('name', TextType::class, [
|
||||||
'label' => 'label.name',
|
'label' => 'label.name',
|
||||||
])
|
])
|
||||||
// text
|
|
||||||
->add('comment', TextareaType::class, [
|
->add('comment', TextareaType::class, [
|
||||||
'label' => 'label.comment',
|
'label' => 'label.comment',
|
||||||
|
'required' => false,
|
||||||
|
])
|
||||||
|
->add('orderNumber', TextType::class, [
|
||||||
|
'label' => 'label.order_number',
|
||||||
|
'required' => false,
|
||||||
])
|
])
|
||||||
// customer
|
|
||||||
->add('customer', CustomerType::class, [
|
->add('customer', CustomerType::class, [
|
||||||
'label' => 'label.customer',
|
'label' => 'label.customer',
|
||||||
'query_builder' => function (CustomerRepository $repo) use ($customer) {
|
'query_builder' => function (CustomerRepository $repo) use ($customer) {
|
||||||
return $repo->builderForEntityType($customer);
|
return $repo->builderForEntityType($customer);
|
||||||
},
|
},
|
||||||
])
|
])
|
||||||
// boolean
|
|
||||||
->add('visible', VisibilityType::class, [
|
->add('visible', VisibilityType::class, [
|
||||||
'label' => 'label.visible',
|
'label' => 'label.visible',
|
||||||
])
|
])
|
||||||
// string
|
|
||||||
->add('budget', MoneyType::class, [
|
->add('budget', MoneyType::class, [
|
||||||
'label' => 'label.budget',
|
'label' => 'label.budget',
|
||||||
'currency' => $builder->getOption('currency'),
|
'currency' => $customer ? $customer->getCurrency() : $builder->getOption('currency'),
|
||||||
|
'required' => false,
|
||||||
])
|
])
|
||||||
;
|
;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,43 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
/*
|
|
||||||
* This file is part of the Kimai package.
|
|
||||||
*
|
|
||||||
* (c) Kevin Papst <kevin@kevinpapst.de>
|
|
||||||
*
|
|
||||||
* For the full copyright and license information, please view the LICENSE
|
|
||||||
* file that was distributed with this source code.
|
|
||||||
*/
|
|
||||||
|
|
||||||
namespace App\Invoice;
|
|
||||||
|
|
||||||
use App\Model\InvoiceModel;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Class RandomNumberGenerator is meant for testing purpose only.
|
|
||||||
*
|
|
||||||
* @author Kevin Papst <kevin@kevinpapst.de>
|
|
||||||
*/
|
|
||||||
class RandomNumberGenerator implements NumberGeneratorInterface
|
|
||||||
{
|
|
||||||
/**
|
|
||||||
* @var InvoiceModel
|
|
||||||
*/
|
|
||||||
protected $model;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param InvoiceModel $model
|
|
||||||
*/
|
|
||||||
public function setModel(InvoiceModel $model)
|
|
||||||
{
|
|
||||||
$this->model = $model;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return string
|
|
||||||
*/
|
|
||||||
public function getInvoiceNumber(): string
|
|
||||||
{
|
|
||||||
return rand(1000000, 9999999);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -77,6 +77,8 @@ class InvoiceModel
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* Do not use this method for rendering the invoice, use InvoiceModel::getCalculator()->getEntries() instead.
|
||||||
|
*
|
||||||
* @return Timesheet[]
|
* @return Timesheet[]
|
||||||
*/
|
*/
|
||||||
public function getEntries(): array
|
public function getEntries(): array
|
||||||
@@ -146,17 +148,6 @@ class InvoiceModel
|
|||||||
return new \DateTime();
|
return new \DateTime();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @param CalculatorInterface $calculator
|
|
||||||
* @return InvoiceModel
|
|
||||||
*/
|
|
||||||
public function setCalculator(CalculatorInterface $calculator)
|
|
||||||
{
|
|
||||||
$this->calculator = $calculator;
|
|
||||||
$this->calculator->setModel($this);
|
|
||||||
return $this;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param NumberGeneratorInterface $generator
|
* @param NumberGeneratorInterface $generator
|
||||||
* @return InvoiceModel
|
* @return InvoiceModel
|
||||||
@@ -176,6 +167,17 @@ class InvoiceModel
|
|||||||
return $this->generator;
|
return $this->generator;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param CalculatorInterface $calculator
|
||||||
|
* @return InvoiceModel
|
||||||
|
*/
|
||||||
|
public function setCalculator(CalculatorInterface $calculator)
|
||||||
|
{
|
||||||
|
$this->calculator = $calculator;
|
||||||
|
$this->calculator->setModel($this);
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return CalculatorInterface
|
* @return CalculatorInterface
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -36,8 +36,13 @@
|
|||||||
<b>{{ 'invoice.number'|trans }}: {{ model.numberGenerator.invoiceNumber }}</b>
|
<b>{{ 'invoice.number'|trans }}: {{ model.numberGenerator.invoiceNumber }}</b>
|
||||||
</p>
|
</p>
|
||||||
<p contenteditable="true">
|
<p contenteditable="true">
|
||||||
<b>{{ 'invoice.due_days'|trans }}:</b> {{ model.dueDate|date(kimai_context.date_1) }}<br>
|
<b>{{ 'invoice.due_days'|trans }}:</b> {{ model.dueDate|date(kimai_context.date_1) }}
|
||||||
{% if model.customer.number is not empty %}<b>{{ 'label.customer_number'|trans }}:</b> {{ model.customer.number }}<br>{% endif %}
|
{% if model.customer.number is not empty %}
|
||||||
|
<br><b>{{ 'label.customer_number'|trans }}:</b> {{ model.customer.number }}
|
||||||
|
{% endif %}
|
||||||
|
{% if model.query.project is not empty and model.query.project.orderNumber is not empty %}
|
||||||
|
<br><b>{{ 'label.order_number'|trans }}:</b> {{ model.query.project.orderNumber }}
|
||||||
|
{% endif %}
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -32,6 +32,14 @@
|
|||||||
{{ model.customer.name }} / {{ model.customer.contact }}
|
{{ model.customer.name }} / {{ model.customer.contact }}
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
|
{% if model.query.project is not empty and model.query.project.orderNumber is not empty %}
|
||||||
|
<tr>
|
||||||
|
<th>{{ 'label.order_number'|trans }}</th>
|
||||||
|
<td contenteditable="true">
|
||||||
|
{{ model.query.project.orderNumber }}
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
{% endif %}
|
||||||
</table>
|
</table>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -30,7 +30,7 @@ class TimesheetVoterTest extends TestCase
|
|||||||
/**
|
/**
|
||||||
* @dataProvider getTestData
|
* @dataProvider getTestData
|
||||||
*/
|
*/
|
||||||
public function testCustomerIsDisallowed($user, $allow, $subject, $attributes, $result)
|
public function testCustomerIsDisallowed(User $user, $allow, $subject, $attributes, $result)
|
||||||
{
|
{
|
||||||
$token = new UsernamePasswordToken($user, 'foo', 'bar', $user->getRoles());
|
$token = new UsernamePasswordToken($user, 'foo', 'bar', $user->getRoles());
|
||||||
|
|
||||||
|
|||||||
@@ -687,10 +687,6 @@
|
|||||||
<source>invoice_number_generator.default</source>
|
<source>invoice_number_generator.default</source>
|
||||||
<target>Datum (Standard)</target>
|
<target>Datum (Standard)</target>
|
||||||
</trans-unit>
|
</trans-unit>
|
||||||
<trans-unit id="invoice_number_generator.random">
|
|
||||||
<source>invoice_number_generator.random</source>
|
|
||||||
<target>Zufallszahl (nur zum Testen)</target>
|
|
||||||
</trans-unit>
|
|
||||||
<trans-unit id="label.invoice_calculator">
|
<trans-unit id="label.invoice_calculator">
|
||||||
<source>label.invoice_calculator</source>
|
<source>label.invoice_calculator</source>
|
||||||
<target>Zahlungsberechnung</target>
|
<target>Zahlungsberechnung</target>
|
||||||
@@ -711,6 +707,10 @@
|
|||||||
<source>invoice.signature_customer</source>
|
<source>invoice.signature_customer</source>
|
||||||
<target>Leistungsbestätigung: Datum / Name Kunde / Unterschrift</target>
|
<target>Leistungsbestätigung: Datum / Name Kunde / Unterschrift</target>
|
||||||
</trans-unit>
|
</trans-unit>
|
||||||
|
<trans-unit id="label.order_number">
|
||||||
|
<source>label.order_number</source>
|
||||||
|
<target>Bestellnummer</target>
|
||||||
|
</trans-unit>
|
||||||
|
|
||||||
<!--
|
<!--
|
||||||
Month names
|
Month names
|
||||||
|
|||||||
@@ -687,10 +687,6 @@
|
|||||||
<source>invoice_number_generator.default</source>
|
<source>invoice_number_generator.default</source>
|
||||||
<target>Date (default)</target>
|
<target>Date (default)</target>
|
||||||
</trans-unit>
|
</trans-unit>
|
||||||
<trans-unit id="invoice_number_generator.random">
|
|
||||||
<source>invoice_number_generator.random</source>
|
|
||||||
<target>Random number (only for testing)</target>
|
|
||||||
</trans-unit>
|
|
||||||
<trans-unit id="label.invoice_calculator">
|
<trans-unit id="label.invoice_calculator">
|
||||||
<source>label.invoice_calculator</source>
|
<source>label.invoice_calculator</source>
|
||||||
<target>Amount calculator</target>
|
<target>Amount calculator</target>
|
||||||
@@ -711,6 +707,10 @@
|
|||||||
<source>invoice.signature_customer</source>
|
<source>invoice.signature_customer</source>
|
||||||
<target>Confirmation: Date / Name Customer / Signature</target>
|
<target>Confirmation: Date / Name Customer / Signature</target>
|
||||||
</trans-unit>
|
</trans-unit>
|
||||||
|
<trans-unit id="label.order_number">
|
||||||
|
<source>label.order_number</source>
|
||||||
|
<target>Order number</target>
|
||||||
|
</trans-unit>
|
||||||
|
|
||||||
<!--
|
<!--
|
||||||
Month names
|
Month names
|
||||||
|
|||||||
Reference in New Issue
Block a user