Overview
Comment:Remove payoff transaction type, it wasn't very useful and confusing
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | dev | 1.0.0-rc3
Files: files | file ages | folders
SHA1: 1b33573836753302f7c81f96670b3e5c439030d7
User & Date: bohwaz on 2020-11-30 15:05:41
Other Links: branch diff | manifest | tags
Context
2020-11-30
15:30
Automatically select if there is only one result check-in: 38a82aaff0 user: bohwaz tags: dev, 1.0.0-rc3
15:05
Remove payoff transaction type, it wasn't very useful and confusing check-in: 1b33573836 user: bohwaz tags: dev, 1.0.0-rc3
15:04
Make simple tracking use transaction type, not account type check-in: 7427b32fb9 user: bohwaz tags: dev
Changes

Modified src/VERSION from [f702cca799] to [fe6e76a10d].

1
1.0.0-rc2
|
1
1.0.0-rc3

Added src/include/data/1.0.0-rc3_migration.sql version [46b4d521e5].



>
1
UPDATE acc_transactions SET type = 0 WHERE type = 6;

Modified src/include/lib/Garradin/Entities/Accounting/Account.php from [185a3a4c5f] to [bfec22341c].

131
132
133
134
135
136
137



138
139
140
141
142
143
144
		'id_analytical' => [
			'select' => 'l.id_analytical',
		],
		'code_analytical' => [
			'label' => 'Projet',
			'select' => 'b.code',
		],



	];

	protected $id;
	protected $id_chart;
	protected $code;
	protected $label;
	protected $description;







>
>
>







131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
		'id_analytical' => [
			'select' => 'l.id_analytical',
		],
		'code_analytical' => [
			'label' => 'Projet',
			'select' => 'b.code',
		],
		'status' => [
			'select' => 't.status',
		],
	];

	protected $id;
	protected $id_chart;
	protected $code;
	protected $label;
	protected $description;

Modified src/include/lib/Garradin/Entities/Accounting/Transaction.php from [d0d8ba7f1b] to [7f6416e57a].

18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51

	const TYPE_ADVANCED = 0;
	const TYPE_REVENUE = 1;
	const TYPE_EXPENSE = 2;
	const TYPE_TRANSFER = 3;
	const TYPE_DEBT = 4;
	const TYPE_CREDIT = 5;
	const TYPE_PAYOFF = 6;

	const STATUS_WAITING = 1;
	const STATUS_PAID = 2;
	const STATUS_DEPOSIT = 4;

	const STATUS_NAMES = [
		1 => 'En attente de règlement',
		2 => 'Réglé',
		4 => 'Déposé en banque',
	];

	const TYPES_NAMES = [
		'Avancé',
		'Recette',
		'Dépense',
		'Virement',
		'Dette',
		'Créance',
		'Règlement',
	];

	protected $id;
	protected $type;
	protected $status = 0;
	protected $label;
	protected $notes;







<


















<







18
19
20
21
22
23
24

25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42

43
44
45
46
47
48
49

	const TYPE_ADVANCED = 0;
	const TYPE_REVENUE = 1;
	const TYPE_EXPENSE = 2;
	const TYPE_TRANSFER = 3;
	const TYPE_DEBT = 4;
	const TYPE_CREDIT = 5;


	const STATUS_WAITING = 1;
	const STATUS_PAID = 2;
	const STATUS_DEPOSIT = 4;

	const STATUS_NAMES = [
		1 => 'En attente de règlement',
		2 => 'Réglé',
		4 => 'Déposé en banque',
	];

	const TYPES_NAMES = [
		'Avancé',
		'Recette',
		'Dépense',
		'Virement',
		'Dette',
		'Créance',

	];

	protected $id;
	protected $type;
	protected $status = 0;
	protected $label;
	protected $notes;
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308

		foreach ($this->_old_lines as $line)
		{
			$line->delete();
		}

		// Remove flag
		if (self::TYPE_PAYOFF == $this->type && $this->_related) {
			$this->_related->removeStatus(self::STATUS_WAITING);
			$this->_related->addStatus(self::STATUS_PAID);
			$this->_related->save();
		}

		return true;
	}

	public function removeStatus(int $property) {
		$this->status &= ~$property;
	}

	public function addStatus(int $property) {
		$this->status |= $property;
	}

	public function delete(): bool
	{
		if ($this->validated) {
			throw new ValidationException('Il n\'est pas possible de supprimer une écriture qui a été validée');
		}







|









|



|







278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306

		foreach ($this->_old_lines as $line)
		{
			$line->delete();
		}

		// Remove flag
		if ((self::TYPE_DEBT == $this->type || self::TYPE_CREDIT == $this->type) && $this->_related) {
			$this->_related->removeStatus(self::STATUS_WAITING);
			$this->_related->addStatus(self::STATUS_PAID);
			$this->_related->save();
		}

		return true;
	}

	public function removeStatus(int $property) {
		$this->set('status', $this->status & ~$property);
	}

	public function addStatus(int $property) {
		$this->set('status', $this->status | $property);
	}

	public function delete(): bool
	{
		if ($this->validated) {
			throw new ValidationException('Il n\'est pas possible de supprimer une écriture qui a été validée');
		}
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
			throw new ValidationException('Type d\'écriture inconnu');
		}

		$type = $source['type'];

		$this->importForm($source);

		if (self::TYPE_PAYOFF == $type) {
			if (empty($source['amount'])) {
				throw new UserException('Montant non précisé');
			}

			$amount = $source['amount'];

			$key = 'account_payoff';
			$account = isset($source[$key]) && @count($source[$key]) ? key($source[$key]) : null;

			if (!count($this->getLines())) {
				throw new \LogicException('Invalid operation: payoff must already have one line');
			}

			$line = current($this->_lines);
			$debit = $line->debit ? 0 : $amount;
			$credit = $line->credit ? 0 : $amount;

			$line2 = new Line;
			$line2->importForm([
				'reference'     => $source['payment_reference'],
				'credit'        => $credit,
				'debit'         => $debit,
				'id_account'    => $account,
				'id_analytical' => !empty($source['id_analytical']) ? $source['id_analytical'] : null,
			]);
			$this->addLine($line2);
		}
		elseif (self::TYPE_ADVANCED == $type) {
			$lines = Utils::array_transpose($source['lines']);

			foreach ($lines as $i => $line) {
				$line['id_account'] = @count($line['account']) ? key($line['account']) : null;

				if (!$line['id_account']) {
					throw new ValidationException('Numéro de compte invalide sur la ligne ' . ($i+1));
				}

				$line = (new Line)->import($line);
				$this->addLine($line);
			}
		}
		else {
			$details = self::getTypesDetails();

			if (!array_key_exists($type, $details)) {
				throw new ValidationException('Type d\'écriture inconnu');
			}

			if ($type == self::TYPE_DEBT || $type == self::TYPE_CREDIT) {
				$this->status = self::STATUS_WAITING;
			}

			if (empty($source['amount'])) {
				throw new UserException('Montant non précisé');
			}








<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|




















|







389
390
391
392
393
394
395




























396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
			throw new ValidationException('Type d\'écriture inconnu');
		}

		$type = $source['type'];

		$this->importForm($source);





























		if (self::TYPE_ADVANCED == $type) {
			$lines = Utils::array_transpose($source['lines']);

			foreach ($lines as $i => $line) {
				$line['id_account'] = @count($line['account']) ? key($line['account']) : null;

				if (!$line['id_account']) {
					throw new ValidationException('Numéro de compte invalide sur la ligne ' . ($i+1));
				}

				$line = (new Line)->import($line);
				$this->addLine($line);
			}
		}
		else {
			$details = self::getTypesDetails();

			if (!array_key_exists($type, $details)) {
				throw new ValidationException('Type d\'écriture inconnu');
			}

			if (empty($this->_related) && ($type == self::TYPE_DEBT || $type == self::TYPE_CREDIT)) {
				$this->status = self::STATUS_WAITING;
			}

			if (empty($source['amount'])) {
				throw new UserException('Montant non précisé');
			}

688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705








706
707
708
709
710
711
712
713
714
715
716
717
718

719
720
721
722
723
				$account->targets_string = implode(':', $account->targets);
			}
		}

		return $details;
	}

	public function payOffFrom(int $id): self
	{
		$this->_related = EntityManager::findOneById(self::class, $id);

		if (!$this->_related) {
			throw new \LogicException('Écriture d\'origine invalide');
		}

		$this->id_related = $this->_related->id();
		$this->label = ($this->_related->type == Transaction::TYPE_DEBT ? 'Règlement de dette : ' : 'Règlement de créance : ') . $this->_related->label;
		$this->type = Transaction::TYPE_PAYOFF;









		foreach ($this->_related->getLines() as $line) {
			if (($this->_related->type == self::TYPE_DEBT && $line->debit)
				|| ($this->_related->type == self::TYPE_CREDIT && $line->credit)) {
				// Skip the type of debt/credit, just keep the thirdparty account
				continue;
			}

			// Invert debit/credit
			$line2 = clone $line;
			$line2->debit = $line->debit ? 0 : $line->credit;
			$line2->credit = $line->credit ? 0 : $line->debit;
			$this->addLine($line2);

		}

		return $this->_related;
	}
}







|









|
>
>
>
>
>
>
>
>








<
<
|
<
<
>


|


658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691


692


693
694
695
696
697
698
				$account->targets_string = implode(':', $account->targets);
			}
		}

		return $details;
	}

	public function payOffFrom(int $id): \stdClass
	{
		$this->_related = EntityManager::findOneById(self::class, $id);

		if (!$this->_related) {
			throw new \LogicException('Écriture d\'origine invalide');
		}

		$this->id_related = $this->_related->id();
		$this->label = ($this->_related->type == Transaction::TYPE_DEBT ? 'Règlement de dette : ' : 'Règlement de créance : ') . $this->_related->label;
		$this->type = $this->_related->type;

		$out = (object) [
			'id' => $this->_related->id,
			'sum' => $this->_related->sum(),
			'id_account' => null,
			'form_account_name' => sprintf('account_%d_%d', $this->type, $this->_related->type == self::TYPE_DEBT ? 1 : 0),
			'form_target_name' => sprintf('account_%d_%d', $this->type, $this->_related->type == self::TYPE_DEBT ? 0 : 1),
		];

		foreach ($this->_related->getLines() as $line) {
			if (($this->_related->type == self::TYPE_DEBT && $line->debit)
				|| ($this->_related->type == self::TYPE_CREDIT && $line->credit)) {
				// Skip the type of debt/credit, just keep the thirdparty account
				continue;
			}



			$out->id_account = $line->id_account;


			break;
		}

		return $out;
	}
}

Modified src/include/lib/Garradin/Upgrade.php from [7caefda8d3] to [d98424ca2c].

77
78
79
80
81
82
83







84
85
86
87
88
89
90

			if (version_compare($v, '1.0.0-beta6', '>=') && version_compare($v, '1.0.0-beta8', '<'))
			{
				$db->beginSchemaUpdate();
				$db->import(ROOT . '/include/data/1.0.0-beta8_migration.sql');
				$db->commitSchemaUpdate();
			}








			// Vérification de la cohérence des clés étrangères
			$db->foreignKeyCheck();

			Utils::clearCaches();

			$config->setVersion(garradin_version());







>
>
>
>
>
>
>







77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97

			if (version_compare($v, '1.0.0-beta6', '>=') && version_compare($v, '1.0.0-beta8', '<'))
			{
				$db->beginSchemaUpdate();
				$db->import(ROOT . '/include/data/1.0.0-beta8_migration.sql');
				$db->commitSchemaUpdate();
			}

			if (version_compare($v, '1.0.0-beta1', '>=') && version_compare($v, '1.0.0-rc3', '<'))
			{
				$db->beginSchemaUpdate();
				$db->import(ROOT . '/include/data/1.0.0-rc3_migration.sql');
				$db->commitSchemaUpdate();
			}

			// Vérification de la cohérence des clés étrangères
			$db->foreignKeyCheck();

			Utils::clearCaches();

			$config->setVersion(garradin_version());

Modified src/templates/acc/transactions/details.tpl from [11abde8f01] to [f76172b6ec].

21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
</div>
{/if}

<dl class="describe">
	{if $transaction.id_related}
	<dt>Écriture liée à</dt>
	<dd><a href="{$admin_url}acc/transactions/details.php?id={$transaction.id_related}">#{$transaction.id_related}</a>
		{if $transaction.type == $transaction::TYPE_PAYOFF}(en règlement de){/if}
	</dd>
	{/if}
	<dt>Libellé</dt>
	<dd><h2>{$transaction.label}</h2></dd>
	<dt>Date</dt>
	<dd>{$transaction.date|date_fr:'l j F Y (d/m/Y)'}</dd>
	<dt>Numéro pièce comptable</dt>







|







21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
</div>
{/if}

<dl class="describe">
	{if $transaction.id_related}
	<dt>Écriture liée à</dt>
	<dd><a href="{$admin_url}acc/transactions/details.php?id={$transaction.id_related}">#{$transaction.id_related}</a>
		{if $transaction.type == $transaction::TYPE_DEBT || $transaction.type == $transaction::TYPE_CREDIT}(en règlement de){/if}
	</dd>
	{/if}
	<dt>Libellé</dt>
	<dd><h2>{$transaction.label}</h2></dd>
	<dt>Date</dt>
	<dd>{$transaction.date|date_fr:'l j F Y (d/m/Y)'}</dd>
	<dt>Numéro pièce comptable</dt>

Modified src/templates/acc/transactions/new.tpl from [a1c3d7a7ba] to [0ea620ce9f].

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17

18
19
20
21
22
23
24
25
26
27
28
29
30
{include file="admin/_head.tpl" title="Saisie d'une écriture" current="acc/new" js=1}

{include file="acc/_year_select.tpl"}

<form method="post" action="{$self_url_no_qs}" enctype="multipart/form-data" data-focus="1">
	{form_errors}

	{if $ok}
		<p class="block confirm">
			L'écriture numéro <a href="details.php?id={$ok}">{$ok}</a> a été ajoutée.
			(<a href="details.php?id={$ok}">Voir l'écriture</a>)
		</p>
	{/if}

	{if $payoff_for}
		<input type="hidden" name="type" value="{$transaction::TYPE_PAYOFF}" />
		<input type="hidden" name="payoff_for" value="{$payoff_for.id}" />

		<fieldset>
			<legend>{if $payoff_for->type == $transaction::TYPE_DEBT}Règlement de dette{else}Règlement de créance{/if}</legend>
			<dl>
				<dt>Écriture d'origine</dt>
				<dd><a class="num" href="{$admin_url}acc/transactions/details.php?id={$payoff_for.id}">#{$payoff_for.id}</a></dd>
				{input type="list" target="acc/charts/accounts/selector.php?targets=%s&chart=%d"|args:$payoff_targets,$chart_id name="account_payoff" label="Compte de règlement" required=1}
			</dl>
		</fieldset>
	{else}
		<fieldset>
			<legend>Type d'écriture</legend>
			<dl>
			{foreach from=$types_details item="type"}




|










|

>

|



|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
{include file="admin/_head.tpl" title="Saisie d'une écriture" current="acc/new" js=1}

{include file="acc/_year_select.tpl"}

<form method="post" action="{$self_url}" enctype="multipart/form-data" data-focus="1">
	{form_errors}

	{if $ok}
		<p class="block confirm">
			L'écriture numéro <a href="details.php?id={$ok}">{$ok}</a> a été ajoutée.
			(<a href="details.php?id={$ok}">Voir l'écriture</a>)
		</p>
	{/if}

	{if $payoff_for}
		<input type="hidden" name="type" value="{$transaction.type}" />
		<input type="hidden" name="payoff_for" value="{$payoff_for.id}" />
		<input type="hidden" name="{$payoff_for.form_account_name}[{$payoff_for.id_account}]" value="-" />
		<fieldset>
			<legend>{if $payoff_for.type == $transaction::TYPE_DEBT}Règlement de dette{else}Règlement de créance{/if}</legend>
			<dl>
				<dt>Écriture d'origine</dt>
				<dd><a class="num" href="{$admin_url}acc/transactions/details.php?id={$payoff_for.id}">#{$payoff_for.id}</a></dd>
				{input type="list" target="acc/charts/accounts/selector.php?targets=%s&chart=%d"|args:$payoff_targets,$chart_id name=$payoff_for.form_target_name label="Compte de règlement" required=1}
			</dl>
		</fieldset>
	{else}
		<fieldset>
			<legend>Type d'écriture</legend>
			<dl>
			{foreach from=$types_details item="type"}

Modified src/www/admin/acc/transactions/new.php from [e1558cb4be] to [7173ab8670].

21
22
23
24
25
26
27





28
29
30
31
32
33
34
35
$lines = [[], []];
$amount = 0;
$payoff_for = qg('payoff_for') ?: f('payoff_for');

// Quick pay-off for debts and credits, directly from a debt/credit details page
if ($id = $payoff_for) {
	$payoff_for = $transaction->payOffFrom($id);





	$amount = $payoff_for->sum();
}

// Quick transaction from an account journal page
if ($id = qg('account')) {
	$account = $accounts::get($id);

	if (!$account || $account->id_chart != $current_year->id_chart) {







>
>
>
>
>
|







21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
$lines = [[], []];
$amount = 0;
$payoff_for = qg('payoff_for') ?: f('payoff_for');

// Quick pay-off for debts and credits, directly from a debt/credit details page
if ($id = $payoff_for) {
	$payoff_for = $transaction->payOffFrom($id);

	if (!$payoff_for) {
		throw new UserException('Écriture inconnue');
	}

	$amount = $payoff_for->sum;
}

// Quick transaction from an account journal page
if ($id = qg('account')) {
	$account = $accounts::get($id);

	if (!$account || $account->id_chart != $current_year->id_chart) {