mirror of
https://github.com/Part-DB/Part-DB-server.git
synced 2025-06-21 09:35:49 +02:00
Merge branch 'part_owners'
This commit is contained in:
commit
ccae58cb2f
28 changed files with 732 additions and 69 deletions
|
@ -96,6 +96,8 @@ const PLACEHOLDERS = [
|
||||||
['[[AMOUNT]]', 'Lot amount'],
|
['[[AMOUNT]]', 'Lot amount'],
|
||||||
['[[LOCATION]]', 'Storage location'],
|
['[[LOCATION]]', 'Storage location'],
|
||||||
['[[LOCATION_FULL]]', 'Storage location (Full path)'],
|
['[[LOCATION_FULL]]', 'Storage location (Full path)'],
|
||||||
|
['[[OWNER]]', 'Full name of the lot owner'],
|
||||||
|
['[[OWNER_USERNAME]]', 'Username of the lot owner'],
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|
|
@ -55,6 +55,8 @@ Object.assign( window.CKEDITOR_TRANSLATIONS[ 'de' ].dictionary, {
|
||||||
'Lot amount': 'Lot Menge',
|
'Lot amount': 'Lot Menge',
|
||||||
'Storage location': 'Lagerort',
|
'Storage location': 'Lagerort',
|
||||||
'Storage location (Full path)': 'Lagerort (Vollständiger Pfad)',
|
'Storage location (Full path)': 'Lagerort (Vollständiger Pfad)',
|
||||||
|
'Full name of the lot owner': 'Name des Besitzers des Lots',
|
||||||
|
'Username of the lot owner': 'Benutzername des Besitzers des Lots',
|
||||||
|
|
||||||
|
|
||||||
'Barcodes': 'Barcodes',
|
'Barcodes': 'Barcodes',
|
||||||
|
|
|
@ -281,7 +281,7 @@ final class Version20230219225340 extends AbstractMultiPlatformMigration
|
||||||
$this->addSql('CREATE INDEX IDX_1AA2DD313FFDCD60 ON project_bom_entries (price_currency_id)');
|
$this->addSql('CREATE INDEX IDX_1AA2DD313FFDCD60 ON project_bom_entries (price_currency_id)');
|
||||||
$this->addSql('CREATE TEMPORARY TABLE __temp__projects AS SELECT id, parent_id, id_preview_attachement, order_quantity, order_only_missing_parts, comment, not_selectable, name, last_modified, datetime_added, status, description FROM projects');
|
$this->addSql('CREATE TEMPORARY TABLE __temp__projects AS SELECT id, parent_id, id_preview_attachement, order_quantity, order_only_missing_parts, comment, not_selectable, name, last_modified, datetime_added, status, description FROM projects');
|
||||||
$this->addSql('DROP TABLE projects');
|
$this->addSql('DROP TABLE projects');
|
||||||
$this->addSql('CREATE TABLE projects (id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, parent_id INTEGER DEFAULT NULL, id_preview_attachment INTEGER DEFAULT NULL, order_quantity INTEGER NOT NULL, order_only_missing_parts BOOLEAN NOT NULL, comment CLOB NOT NULL, not_selectable BOOLEAN NOT NULL, name VARCHAR(255) NOT NULL, last_modified DATETIME DEFAULT CURRENT_TIMESTAMP NOT NULL, datetime_added DATETIME DEFAULT CURRENT_TIMESTAMP NOT NULL, status VARCHAR(64) DEFAULT NULL, description DEFAULT \'\', CONSTRAINT FK_11074E9A727ACA70 FOREIGN KEY (parent_id) REFERENCES projects (id) ON UPDATE NO ACTION ON DELETE NO ACTION NOT DEFERRABLE INITIALLY IMMEDIATE, CONSTRAINT FK_5C93B3A4EA7100A1 FOREIGN KEY (id_preview_attachment) REFERENCES "attachments" (id) ON DELETE SET NULL NOT DEFERRABLE INITIALLY IMMEDIATE)');
|
$this->addSql('CREATE TABLE projects (id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, parent_id INTEGER DEFAULT NULL, id_preview_attachment INTEGER DEFAULT NULL, order_quantity INTEGER NOT NULL, order_only_missing_parts BOOLEAN NOT NULL, comment CLOB NOT NULL, not_selectable BOOLEAN NOT NULL, name VARCHAR(255) NOT NULL, last_modified DATETIME DEFAULT CURRENT_TIMESTAMP NOT NULL, datetime_added DATETIME DEFAULT CURRENT_TIMESTAMP NOT NULL, status VARCHAR(64) DEFAULT NULL, description CLOB DEFAULT \'\', CONSTRAINT FK_11074E9A727ACA70 FOREIGN KEY (parent_id) REFERENCES projects (id) ON UPDATE NO ACTION ON DELETE NO ACTION NOT DEFERRABLE INITIALLY IMMEDIATE, CONSTRAINT FK_5C93B3A4EA7100A1 FOREIGN KEY (id_preview_attachment) REFERENCES "attachments" (id) ON DELETE SET NULL NOT DEFERRABLE INITIALLY IMMEDIATE)');
|
||||||
$this->addSql('INSERT INTO projects (id, parent_id, id_preview_attachment, order_quantity, order_only_missing_parts, comment, not_selectable, name, last_modified, datetime_added, status, description) SELECT id, parent_id, id_preview_attachement, order_quantity, order_only_missing_parts, comment, not_selectable, name, last_modified, datetime_added, status, description FROM __temp__projects');
|
$this->addSql('INSERT INTO projects (id, parent_id, id_preview_attachment, order_quantity, order_only_missing_parts, comment, not_selectable, name, last_modified, datetime_added, status, description) SELECT id, parent_id, id_preview_attachement, order_quantity, order_only_missing_parts, comment, not_selectable, name, last_modified, datetime_added, status, description FROM __temp__projects');
|
||||||
$this->addSql('DROP TABLE __temp__projects');
|
$this->addSql('DROP TABLE __temp__projects');
|
||||||
$this->addSql('CREATE INDEX IDX_5C93B3A4727ACA70 ON projects (parent_id)');
|
$this->addSql('CREATE INDEX IDX_5C93B3A4727ACA70 ON projects (parent_id)');
|
||||||
|
|
300
migrations/Version20230402170923.php
Normal file
300
migrations/Version20230402170923.php
Normal file
|
@ -0,0 +1,300 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace DoctrineMigrations;
|
||||||
|
|
||||||
|
use App\Migration\AbstractMultiPlatformMigration;
|
||||||
|
use Doctrine\DBAL\Schema\Schema;
|
||||||
|
use Doctrine\Migrations\AbstractMigration;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Auto-generated Migration: Please modify to your needs!
|
||||||
|
*/
|
||||||
|
final class Version20230402170923 extends AbstractMultiPlatformMigration
|
||||||
|
{
|
||||||
|
public function getDescription(): string
|
||||||
|
{
|
||||||
|
return 'Create database schema for user aboutMe and part lot owners';
|
||||||
|
}
|
||||||
|
|
||||||
|
public function mySQLUp(Schema $schema): void
|
||||||
|
{
|
||||||
|
$this->addSql('ALTER TABLE part_lots ADD id_owner INT DEFAULT NULL');
|
||||||
|
$this->addSql('ALTER TABLE part_lots ADD CONSTRAINT FK_EBC8F94321E5A74C FOREIGN KEY (id_owner) REFERENCES `users` (id) ON DELETE SET NULL');
|
||||||
|
$this->addSql('CREATE INDEX IDX_EBC8F94321E5A74C ON part_lots (id_owner)');
|
||||||
|
$this->addSql('ALTER TABLE projects ADD CONSTRAINT FK_5C93B3A4727ACA70 FOREIGN KEY (parent_id) REFERENCES projects (id)');
|
||||||
|
$this->addSql('ALTER TABLE storelocations ADD id_owner INT DEFAULT NULL, ADD part_owner_must_match TINYINT(1) DEFAULT 0 NOT NULL');
|
||||||
|
$this->addSql('ALTER TABLE storelocations ADD CONSTRAINT FK_751702021E5A74C FOREIGN KEY (id_owner) REFERENCES `users` (id) ON DELETE SET NULL');
|
||||||
|
$this->addSql('CREATE INDEX IDX_751702021E5A74C ON storelocations (id_owner)');
|
||||||
|
$this->addSql('ALTER TABLE users ADD about_me LONGTEXT DEFAULT \'\' NOT NULL');
|
||||||
|
|
||||||
|
$this->addSql('ALTER TABLE projects CHANGE description description LONGTEXT DEFAULT \'\' NOT NULL');
|
||||||
|
}
|
||||||
|
|
||||||
|
public function mySQLDown(Schema $schema): void
|
||||||
|
{
|
||||||
|
$this->addSql('ALTER TABLE log CHANGE level level TINYINT(1) NOT NULL');
|
||||||
|
$this->addSql('ALTER TABLE part_lots DROP FOREIGN KEY FK_EBC8F94321E5A74C');
|
||||||
|
$this->addSql('DROP INDEX IDX_EBC8F94321E5A74C ON part_lots');
|
||||||
|
$this->addSql('ALTER TABLE part_lots DROP id_owner');
|
||||||
|
$this->addSql('ALTER TABLE projects DROP FOREIGN KEY FK_5C93B3A4727ACA70');
|
||||||
|
$this->addSql('ALTER TABLE `storelocations` DROP FOREIGN KEY FK_751702021E5A74C');
|
||||||
|
$this->addSql('DROP INDEX IDX_751702021E5A74C ON `storelocations`');
|
||||||
|
$this->addSql('ALTER TABLE `storelocations` DROP id_owner, DROP part_owner_must_match');
|
||||||
|
$this->addSql('ALTER TABLE `users` DROP about_me');
|
||||||
|
}
|
||||||
|
|
||||||
|
public function sqLiteUp(Schema $schema): void
|
||||||
|
{
|
||||||
|
//In Version20230219225340 the type of project description was set to an empty string, which caused problems with doctrine migrations, fix it here
|
||||||
|
$this->addSql('CREATE TEMPORARY TABLE __temp__projects AS SELECT id, parent_id, id_preview_attachment, order_quantity, order_only_missing_parts, comment, not_selectable, name, last_modified, datetime_added, status, description FROM projects');
|
||||||
|
$this->addSql('DROP TABLE projects');
|
||||||
|
$this->addSql('CREATE TABLE projects (id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, parent_id INTEGER DEFAULT NULL, id_preview_attachment INTEGER DEFAULT NULL, order_quantity INTEGER NOT NULL, order_only_missing_parts BOOLEAN NOT NULL, comment CLOB NOT NULL, not_selectable BOOLEAN NOT NULL, name VARCHAR(255) NOT NULL, last_modified DATETIME DEFAULT CURRENT_TIMESTAMP NOT NULL, datetime_added DATETIME DEFAULT CURRENT_TIMESTAMP NOT NULL, status VARCHAR(64) DEFAULT NULL, description CLOB DEFAULT \'\', CONSTRAINT FK_11074E9A727ACA70 FOREIGN KEY (parent_id) REFERENCES projects (id) ON UPDATE NO ACTION ON DELETE NO ACTION NOT DEFERRABLE INITIALLY IMMEDIATE, CONSTRAINT FK_5C93B3A4EA7100A1 FOREIGN KEY (id_preview_attachment) REFERENCES "attachments" (id) ON DELETE SET NULL NOT DEFERRABLE INITIALLY IMMEDIATE)');
|
||||||
|
$this->addSql('INSERT INTO projects (id, parent_id, id_preview_attachment, order_quantity, order_only_missing_parts, comment, not_selectable, name, last_modified, datetime_added, status, description) SELECT id, parent_id, id_preview_attachment, order_quantity, order_only_missing_parts, comment, not_selectable, name, last_modified, datetime_added, status, description FROM __temp__projects');
|
||||||
|
$this->addSql('DROP TABLE __temp__projects');
|
||||||
|
$this->addSql('CREATE INDEX IDX_5C93B3A4727ACA70 ON projects (parent_id)');
|
||||||
|
$this->addSql('CREATE INDEX IDX_5C93B3A4EA7100A1 ON projects (id_preview_attachment)');
|
||||||
|
|
||||||
|
$this->addSql('CREATE TEMPORARY TABLE __temp__currencies AS SELECT id, parent_id, id_preview_attachment, exchange_rate, iso_code, comment, not_selectable, name, last_modified, datetime_added FROM currencies');
|
||||||
|
$this->addSql('DROP TABLE currencies');
|
||||||
|
$this->addSql('CREATE TABLE currencies (id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, parent_id INTEGER DEFAULT NULL, id_preview_attachment INTEGER DEFAULT NULL, exchange_rate NUMERIC(11, 5) DEFAULT NULL --(DC2Type:big_decimal)
|
||||||
|
, iso_code VARCHAR(255) NOT NULL, comment CLOB NOT NULL, not_selectable BOOLEAN NOT NULL, name VARCHAR(255) NOT NULL, last_modified DATETIME DEFAULT CURRENT_TIMESTAMP NOT NULL, datetime_added DATETIME DEFAULT CURRENT_TIMESTAMP NOT NULL, CONSTRAINT FK_37C44693727ACA70 FOREIGN KEY (parent_id) REFERENCES currencies (id) ON UPDATE NO ACTION ON DELETE NO ACTION NOT DEFERRABLE INITIALLY IMMEDIATE, CONSTRAINT FK_37C44693EA7100A1 FOREIGN KEY (id_preview_attachment) REFERENCES attachments (id) ON UPDATE NO ACTION ON DELETE SET NULL NOT DEFERRABLE INITIALLY IMMEDIATE)');
|
||||||
|
$this->addSql('INSERT INTO currencies (id, parent_id, id_preview_attachment, exchange_rate, iso_code, comment, not_selectable, name, last_modified, datetime_added) SELECT id, parent_id, id_preview_attachment, exchange_rate, iso_code, comment, not_selectable, name, last_modified, datetime_added FROM __temp__currencies');
|
||||||
|
$this->addSql('DROP TABLE __temp__currencies');
|
||||||
|
$this->addSql('CREATE INDEX IDX_37C44693EA7100A1 ON currencies (id_preview_attachment)');
|
||||||
|
$this->addSql('CREATE INDEX currency_idx_parent_name ON currencies (parent_id, name)');
|
||||||
|
$this->addSql('CREATE INDEX currency_idx_name ON currencies (name)');
|
||||||
|
$this->addSql('CREATE INDEX IDX_37C44693727ACA70 ON currencies (parent_id)');
|
||||||
|
$this->addSql('CREATE TEMPORARY TABLE __temp__groups AS SELECT id, parent_id, id_preview_attachment, enforce_2fa, comment, not_selectable, name, last_modified, datetime_added, permissions_data FROM groups');
|
||||||
|
$this->addSql('DROP TABLE groups');
|
||||||
|
$this->addSql('CREATE TABLE groups (id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, parent_id INTEGER DEFAULT NULL, id_preview_attachment INTEGER DEFAULT NULL, enforce_2fa BOOLEAN NOT NULL, comment CLOB NOT NULL, not_selectable BOOLEAN NOT NULL, name VARCHAR(255) NOT NULL, last_modified DATETIME DEFAULT CURRENT_TIMESTAMP NOT NULL, datetime_added DATETIME DEFAULT CURRENT_TIMESTAMP NOT NULL, permissions_data CLOB DEFAULT \'[]\' NOT NULL --(DC2Type:json)
|
||||||
|
, CONSTRAINT FK_F06D3970727ACA70 FOREIGN KEY (parent_id) REFERENCES groups (id) ON UPDATE NO ACTION ON DELETE NO ACTION NOT DEFERRABLE INITIALLY IMMEDIATE, CONSTRAINT FK_F06D3970EA7100A1 FOREIGN KEY (id_preview_attachment) REFERENCES attachments (id) ON UPDATE NO ACTION ON DELETE SET NULL NOT DEFERRABLE INITIALLY IMMEDIATE)');
|
||||||
|
$this->addSql('INSERT INTO groups (id, parent_id, id_preview_attachment, enforce_2fa, comment, not_selectable, name, last_modified, datetime_added, permissions_data) SELECT id, parent_id, id_preview_attachment, enforce_2fa, comment, not_selectable, name, last_modified, datetime_added, permissions_data FROM __temp__groups');
|
||||||
|
$this->addSql('DROP TABLE __temp__groups');
|
||||||
|
$this->addSql('CREATE INDEX IDX_F06D3970EA7100A1 ON groups (id_preview_attachment)');
|
||||||
|
$this->addSql('CREATE INDEX IDX_F06D3970727ACA70 ON groups (parent_id)');
|
||||||
|
$this->addSql('CREATE INDEX group_idx_name ON groups (name)');
|
||||||
|
$this->addSql('CREATE INDEX group_idx_parent_name ON groups (parent_id, name)');
|
||||||
|
$this->addSql('CREATE TEMPORARY TABLE __temp__log AS SELECT id, id_user, datetime, level, target_id, target_type, extra, type, username FROM log');
|
||||||
|
$this->addSql('DROP TABLE log');
|
||||||
|
$this->addSql('CREATE TABLE log (id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, id_user INTEGER DEFAULT NULL, datetime DATETIME NOT NULL, level TINYINT(4) NOT NULL, target_id INTEGER NOT NULL, target_type SMALLINT NOT NULL, extra CLOB NOT NULL --(DC2Type:json)
|
||||||
|
, type SMALLINT NOT NULL, username VARCHAR(255) NOT NULL, CONSTRAINT FK_8F3F68C56B3CA4B FOREIGN KEY (id_user) REFERENCES users (id) ON UPDATE NO ACTION ON DELETE SET NULL NOT DEFERRABLE INITIALLY IMMEDIATE)');
|
||||||
|
$this->addSql('INSERT INTO log (id, id_user, datetime, level, target_id, target_type, extra, type, username) SELECT id, id_user, datetime, level, target_id, target_type, extra, type, username FROM __temp__log');
|
||||||
|
$this->addSql('DROP TABLE __temp__log');
|
||||||
|
$this->addSql('CREATE INDEX IDX_8F3F68C56B3CA4B ON log (id_user)');
|
||||||
|
$this->addSql('CREATE INDEX log_idx_type ON log (type)');
|
||||||
|
$this->addSql('CREATE INDEX log_idx_type_target ON log (type, target_type, target_id)');
|
||||||
|
$this->addSql('CREATE INDEX log_idx_datetime ON log (datetime)');
|
||||||
|
$this->addSql('CREATE TEMPORARY TABLE __temp__part_lots AS SELECT id, id_store_location, id_part, description, comment, expiration_date, instock_unknown, amount, needs_refill, last_modified, datetime_added FROM part_lots');
|
||||||
|
$this->addSql('DROP TABLE part_lots');
|
||||||
|
$this->addSql('CREATE TABLE part_lots (id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, id_store_location INTEGER DEFAULT NULL, id_part INTEGER NOT NULL, id_owner INTEGER DEFAULT NULL, description CLOB NOT NULL, comment CLOB NOT NULL, expiration_date DATETIME DEFAULT NULL, instock_unknown BOOLEAN NOT NULL, amount DOUBLE PRECISION NOT NULL, needs_refill BOOLEAN NOT NULL, last_modified DATETIME DEFAULT CURRENT_TIMESTAMP NOT NULL, datetime_added DATETIME DEFAULT CURRENT_TIMESTAMP NOT NULL, CONSTRAINT FK_EBC8F9435D8F4B37 FOREIGN KEY (id_store_location) REFERENCES storelocations (id) ON UPDATE NO ACTION ON DELETE NO ACTION NOT DEFERRABLE INITIALLY IMMEDIATE, CONSTRAINT FK_EBC8F943C22F6CC4 FOREIGN KEY (id_part) REFERENCES parts (id) ON UPDATE NO ACTION ON DELETE CASCADE NOT DEFERRABLE INITIALLY IMMEDIATE, CONSTRAINT FK_EBC8F94321E5A74C FOREIGN KEY (id_owner) REFERENCES "users" (id) ON DELETE SET NULL NOT DEFERRABLE INITIALLY IMMEDIATE)');
|
||||||
|
$this->addSql('INSERT INTO part_lots (id, id_store_location, id_part, description, comment, expiration_date, instock_unknown, amount, needs_refill, last_modified, datetime_added) SELECT id, id_store_location, id_part, description, comment, expiration_date, instock_unknown, amount, needs_refill, last_modified, datetime_added FROM __temp__part_lots');
|
||||||
|
$this->addSql('DROP TABLE __temp__part_lots');
|
||||||
|
$this->addSql('CREATE INDEX part_lots_idx_needs_refill ON part_lots (needs_refill)');
|
||||||
|
$this->addSql('CREATE INDEX part_lots_idx_instock_un_expiration_id_part ON part_lots (instock_unknown, expiration_date, id_part)');
|
||||||
|
$this->addSql('CREATE INDEX IDX_EBC8F9435D8F4B37 ON part_lots (id_store_location)');
|
||||||
|
$this->addSql('CREATE INDEX IDX_EBC8F943C22F6CC4 ON part_lots (id_part)');
|
||||||
|
$this->addSql('CREATE INDEX IDX_EBC8F94321E5A74C ON part_lots (id_owner)');
|
||||||
|
$this->addSql('CREATE TEMPORARY TABLE __temp__pricedetails AS SELECT id, id_currency, orderdetails_id, price, price_related_quantity, min_discount_quantity, manual_input, last_modified, datetime_added FROM pricedetails');
|
||||||
|
$this->addSql('DROP TABLE pricedetails');
|
||||||
|
$this->addSql('CREATE TABLE pricedetails (id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, id_currency INTEGER DEFAULT NULL, orderdetails_id INTEGER NOT NULL, price NUMERIC(11, 5) NOT NULL --(DC2Type:big_decimal)
|
||||||
|
, price_related_quantity DOUBLE PRECISION NOT NULL, min_discount_quantity DOUBLE PRECISION NOT NULL, manual_input BOOLEAN NOT NULL, last_modified DATETIME DEFAULT CURRENT_TIMESTAMP NOT NULL, datetime_added DATETIME DEFAULT CURRENT_TIMESTAMP NOT NULL, CONSTRAINT FK_C68C4459398D64AA FOREIGN KEY (id_currency) REFERENCES currencies (id) ON UPDATE NO ACTION ON DELETE NO ACTION NOT DEFERRABLE INITIALLY IMMEDIATE, CONSTRAINT FK_C68C44594A01DDC7 FOREIGN KEY (orderdetails_id) REFERENCES orderdetails (id) ON UPDATE NO ACTION ON DELETE CASCADE NOT DEFERRABLE INITIALLY IMMEDIATE)');
|
||||||
|
$this->addSql('INSERT INTO pricedetails (id, id_currency, orderdetails_id, price, price_related_quantity, min_discount_quantity, manual_input, last_modified, datetime_added) SELECT id, id_currency, orderdetails_id, price, price_related_quantity, min_discount_quantity, manual_input, last_modified, datetime_added FROM __temp__pricedetails');
|
||||||
|
$this->addSql('DROP TABLE __temp__pricedetails');
|
||||||
|
$this->addSql('CREATE INDEX pricedetails_idx_min_discount_price_qty ON pricedetails (min_discount_quantity, price_related_quantity)');
|
||||||
|
$this->addSql('CREATE INDEX pricedetails_idx_min_discount ON pricedetails (min_discount_quantity)');
|
||||||
|
$this->addSql('CREATE INDEX IDX_C68C4459398D64AA ON pricedetails (id_currency)');
|
||||||
|
$this->addSql('CREATE INDEX IDX_C68C44594A01DDC7 ON pricedetails (orderdetails_id)');
|
||||||
|
$this->addSql('CREATE TEMPORARY TABLE __temp__project_bom_entries AS SELECT id, id_device, id_part, price_currency_id, quantity, mountnames, name, comment, price, last_modified, datetime_added FROM project_bom_entries');
|
||||||
|
$this->addSql('DROP TABLE project_bom_entries');
|
||||||
|
$this->addSql('CREATE TABLE project_bom_entries (id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, id_device INTEGER DEFAULT NULL, id_part INTEGER DEFAULT NULL, price_currency_id INTEGER DEFAULT NULL, quantity DOUBLE PRECISION NOT NULL, mountnames CLOB NOT NULL, name VARCHAR(255) DEFAULT NULL, comment CLOB NOT NULL, price NUMERIC(11, 5) DEFAULT NULL --(DC2Type:big_decimal)
|
||||||
|
, last_modified DATETIME DEFAULT CURRENT_TIMESTAMP NOT NULL, datetime_added DATETIME DEFAULT CURRENT_TIMESTAMP NOT NULL, CONSTRAINT FK_AFC547992F180363 FOREIGN KEY (id_device) REFERENCES projects (id) ON UPDATE NO ACTION ON DELETE NO ACTION NOT DEFERRABLE INITIALLY IMMEDIATE, CONSTRAINT FK_AFC54799C22F6CC4 FOREIGN KEY (id_part) REFERENCES parts (id) ON UPDATE NO ACTION ON DELETE NO ACTION NOT DEFERRABLE INITIALLY IMMEDIATE, CONSTRAINT FK_1AA2DD313FFDCD60 FOREIGN KEY (price_currency_id) REFERENCES currencies (id) ON UPDATE NO ACTION ON DELETE NO ACTION NOT DEFERRABLE INITIALLY IMMEDIATE)');
|
||||||
|
$this->addSql('INSERT INTO project_bom_entries (id, id_device, id_part, price_currency_id, quantity, mountnames, name, comment, price, last_modified, datetime_added) SELECT id, id_device, id_part, price_currency_id, quantity, mountnames, name, comment, price, last_modified, datetime_added FROM __temp__project_bom_entries');
|
||||||
|
$this->addSql('DROP TABLE __temp__project_bom_entries');
|
||||||
|
$this->addSql('CREATE INDEX IDX_1AA2DD313FFDCD60 ON project_bom_entries (price_currency_id)');
|
||||||
|
$this->addSql('CREATE INDEX IDX_1AA2DD312F180363 ON project_bom_entries (id_device)');
|
||||||
|
$this->addSql('CREATE INDEX IDX_1AA2DD31C22F6CC4 ON project_bom_entries (id_part)');
|
||||||
|
$this->addSql('CREATE TEMPORARY TABLE __temp__projects AS SELECT id, parent_id, id_preview_attachment, order_quantity, order_only_missing_parts, comment, not_selectable, name, last_modified, datetime_added, status, description FROM projects');
|
||||||
|
$this->addSql('DROP TABLE projects');
|
||||||
|
$this->addSql('CREATE TABLE projects (id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, parent_id INTEGER DEFAULT NULL, id_preview_attachment INTEGER DEFAULT NULL, order_quantity INTEGER NOT NULL, order_only_missing_parts BOOLEAN NOT NULL, comment CLOB NOT NULL, not_selectable BOOLEAN NOT NULL, name VARCHAR(255) NOT NULL, last_modified DATETIME DEFAULT CURRENT_TIMESTAMP NOT NULL, datetime_added DATETIME DEFAULT CURRENT_TIMESTAMP NOT NULL, status VARCHAR(64) DEFAULT NULL, description CLOB DEFAULT \'\' NOT NULL, CONSTRAINT FK_11074E9A727ACA70 FOREIGN KEY (parent_id) REFERENCES projects (id) ON UPDATE NO ACTION ON DELETE NO ACTION NOT DEFERRABLE INITIALLY IMMEDIATE, CONSTRAINT FK_5C93B3A4EA7100A1 FOREIGN KEY (id_preview_attachment) REFERENCES attachments (id) ON UPDATE NO ACTION ON DELETE SET NULL NOT DEFERRABLE INITIALLY IMMEDIATE)');
|
||||||
|
$this->addSql('INSERT INTO projects (id, parent_id, id_preview_attachment, order_quantity, order_only_missing_parts, comment, not_selectable, name, last_modified, datetime_added, status, description) SELECT id, parent_id, id_preview_attachment, order_quantity, order_only_missing_parts, comment, not_selectable, name, last_modified, datetime_added, status, description FROM __temp__projects');
|
||||||
|
$this->addSql('DROP TABLE __temp__projects');
|
||||||
|
$this->addSql('CREATE INDEX IDX_5C93B3A4EA7100A1 ON projects (id_preview_attachment)');
|
||||||
|
$this->addSql('CREATE INDEX IDX_5C93B3A4727ACA70 ON projects (parent_id)');
|
||||||
|
$this->addSql('CREATE TEMPORARY TABLE __temp__storelocations AS SELECT id, parent_id, storage_type_id, id_preview_attachment, is_full, only_single_part, limit_to_existing_parts, comment, not_selectable, name, last_modified, datetime_added FROM storelocations');
|
||||||
|
$this->addSql('DROP TABLE storelocations');
|
||||||
|
$this->addSql('CREATE TABLE storelocations (id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, parent_id INTEGER DEFAULT NULL, storage_type_id INTEGER DEFAULT NULL, id_preview_attachment INTEGER DEFAULT NULL, id_owner INTEGER DEFAULT NULL, is_full BOOLEAN NOT NULL, only_single_part BOOLEAN NOT NULL, limit_to_existing_parts BOOLEAN NOT NULL, comment CLOB NOT NULL, not_selectable BOOLEAN NOT NULL, name VARCHAR(255) NOT NULL, last_modified DATETIME DEFAULT CURRENT_TIMESTAMP NOT NULL, datetime_added DATETIME DEFAULT CURRENT_TIMESTAMP NOT NULL, part_owner_must_match BOOLEAN DEFAULT 0 NOT NULL, CONSTRAINT FK_7517020727ACA70 FOREIGN KEY (parent_id) REFERENCES storelocations (id) ON UPDATE NO ACTION ON DELETE NO ACTION NOT DEFERRABLE INITIALLY IMMEDIATE, CONSTRAINT FK_7517020B270BFF1 FOREIGN KEY (storage_type_id) REFERENCES measurement_units (id) ON UPDATE NO ACTION ON DELETE NO ACTION NOT DEFERRABLE INITIALLY IMMEDIATE, CONSTRAINT FK_7517020EA7100A1 FOREIGN KEY (id_preview_attachment) REFERENCES attachments (id) ON UPDATE NO ACTION ON DELETE SET NULL NOT DEFERRABLE INITIALLY IMMEDIATE, CONSTRAINT FK_751702021E5A74C FOREIGN KEY (id_owner) REFERENCES "users" (id) ON DELETE SET NULL NOT DEFERRABLE INITIALLY IMMEDIATE)');
|
||||||
|
$this->addSql('INSERT INTO storelocations (id, parent_id, storage_type_id, id_preview_attachment, is_full, only_single_part, limit_to_existing_parts, comment, not_selectable, name, last_modified, datetime_added) SELECT id, parent_id, storage_type_id, id_preview_attachment, is_full, only_single_part, limit_to_existing_parts, comment, not_selectable, name, last_modified, datetime_added FROM __temp__storelocations');
|
||||||
|
$this->addSql('DROP TABLE __temp__storelocations');
|
||||||
|
$this->addSql('CREATE INDEX IDX_7517020EA7100A1 ON storelocations (id_preview_attachment)');
|
||||||
|
$this->addSql('CREATE INDEX IDX_7517020B270BFF1 ON storelocations (storage_type_id)');
|
||||||
|
$this->addSql('CREATE INDEX IDX_7517020727ACA70 ON storelocations (parent_id)');
|
||||||
|
$this->addSql('CREATE INDEX location_idx_name ON storelocations (name)');
|
||||||
|
$this->addSql('CREATE INDEX location_idx_parent_name ON storelocations (parent_id, name)');
|
||||||
|
$this->addSql('CREATE INDEX IDX_751702021E5A74C ON storelocations (id_owner)');
|
||||||
|
$this->addSql('CREATE TEMPORARY TABLE __temp__suppliers AS SELECT id, parent_id, default_currency_id, id_preview_attachment, shipping_costs, address, phone_number, fax_number, email_address, website, auto_product_url, comment, not_selectable, name, last_modified, datetime_added FROM suppliers');
|
||||||
|
$this->addSql('DROP TABLE suppliers');
|
||||||
|
$this->addSql('CREATE TABLE suppliers (id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, parent_id INTEGER DEFAULT NULL, default_currency_id INTEGER DEFAULT NULL, id_preview_attachment INTEGER DEFAULT NULL, shipping_costs NUMERIC(11, 5) DEFAULT NULL --(DC2Type:big_decimal)
|
||||||
|
, address VARCHAR(255) NOT NULL, phone_number VARCHAR(255) NOT NULL, fax_number VARCHAR(255) NOT NULL, email_address VARCHAR(255) NOT NULL, website VARCHAR(255) NOT NULL, auto_product_url VARCHAR(255) NOT NULL, comment CLOB NOT NULL, not_selectable BOOLEAN NOT NULL, name VARCHAR(255) NOT NULL, last_modified DATETIME DEFAULT CURRENT_TIMESTAMP NOT NULL, datetime_added DATETIME DEFAULT CURRENT_TIMESTAMP NOT NULL, CONSTRAINT FK_AC28B95C727ACA70 FOREIGN KEY (parent_id) REFERENCES suppliers (id) ON UPDATE NO ACTION ON DELETE NO ACTION NOT DEFERRABLE INITIALLY IMMEDIATE, CONSTRAINT FK_AC28B95CECD792C0 FOREIGN KEY (default_currency_id) REFERENCES currencies (id) ON UPDATE NO ACTION ON DELETE NO ACTION NOT DEFERRABLE INITIALLY IMMEDIATE, CONSTRAINT FK_AC28B95CEA7100A1 FOREIGN KEY (id_preview_attachment) REFERENCES attachments (id) ON UPDATE NO ACTION ON DELETE SET NULL NOT DEFERRABLE INITIALLY IMMEDIATE)');
|
||||||
|
$this->addSql('INSERT INTO suppliers (id, parent_id, default_currency_id, id_preview_attachment, shipping_costs, address, phone_number, fax_number, email_address, website, auto_product_url, comment, not_selectable, name, last_modified, datetime_added) SELECT id, parent_id, default_currency_id, id_preview_attachment, shipping_costs, address, phone_number, fax_number, email_address, website, auto_product_url, comment, not_selectable, name, last_modified, datetime_added FROM __temp__suppliers');
|
||||||
|
$this->addSql('DROP TABLE __temp__suppliers');
|
||||||
|
$this->addSql('CREATE INDEX IDX_AC28B95CEA7100A1 ON suppliers (id_preview_attachment)');
|
||||||
|
$this->addSql('CREATE INDEX supplier_idx_parent_name ON suppliers (parent_id, name)');
|
||||||
|
$this->addSql('CREATE INDEX supplier_idx_name ON suppliers (name)');
|
||||||
|
$this->addSql('CREATE INDEX IDX_AC28B95C727ACA70 ON suppliers (parent_id)');
|
||||||
|
$this->addSql('CREATE INDEX IDX_AC28B95CECD792C0 ON suppliers (default_currency_id)');
|
||||||
|
$this->addSql('CREATE TEMPORARY TABLE __temp__users AS SELECT id, group_id, currency_id, id_preview_attachment, disabled, config_theme, pw_reset_token, config_instock_comment_a, config_instock_comment_w, trusted_device_cookie_version, backup_codes, google_authenticator_secret, config_timezone, config_language, email, department, last_name, first_name, need_pw_change, password, name, settings, backup_codes_generation_date, pw_reset_expires, last_modified, datetime_added, permissions_data, saml_user FROM users');
|
||||||
|
$this->addSql('DROP TABLE users');
|
||||||
|
$this->addSql('CREATE TABLE users (id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, group_id INTEGER DEFAULT NULL, currency_id INTEGER DEFAULT NULL, id_preview_attachment INTEGER DEFAULT NULL, disabled BOOLEAN NOT NULL, config_theme VARCHAR(255) DEFAULT NULL, pw_reset_token VARCHAR(255) DEFAULT NULL, config_instock_comment_a CLOB NOT NULL, config_instock_comment_w CLOB NOT NULL, trusted_device_cookie_version INTEGER NOT NULL, backup_codes CLOB NOT NULL --(DC2Type:json)
|
||||||
|
, google_authenticator_secret VARCHAR(255) DEFAULT NULL, config_timezone VARCHAR(255) DEFAULT NULL, config_language VARCHAR(255) DEFAULT NULL, email VARCHAR(255) DEFAULT NULL, department VARCHAR(255) DEFAULT NULL, last_name VARCHAR(255) DEFAULT NULL, first_name VARCHAR(255) DEFAULT NULL, need_pw_change BOOLEAN NOT NULL, password VARCHAR(255) DEFAULT NULL, name VARCHAR(180) NOT NULL, settings CLOB NOT NULL --(DC2Type:json)
|
||||||
|
, backup_codes_generation_date DATETIME DEFAULT NULL, pw_reset_expires DATETIME DEFAULT NULL, last_modified DATETIME DEFAULT CURRENT_TIMESTAMP NOT NULL, datetime_added DATETIME DEFAULT CURRENT_TIMESTAMP NOT NULL, permissions_data CLOB DEFAULT \'[]\' NOT NULL --(DC2Type:json)
|
||||||
|
, saml_user BOOLEAN NOT NULL, about_me CLOB DEFAULT \'\' NOT NULL, CONSTRAINT FK_1483A5E9FE54D947 FOREIGN KEY (group_id) REFERENCES groups (id) ON UPDATE NO ACTION ON DELETE NO ACTION NOT DEFERRABLE INITIALLY IMMEDIATE, CONSTRAINT FK_1483A5E938248176 FOREIGN KEY (currency_id) REFERENCES currencies (id) ON UPDATE NO ACTION ON DELETE NO ACTION NOT DEFERRABLE INITIALLY IMMEDIATE, CONSTRAINT FK_1483A5E9EA7100A1 FOREIGN KEY (id_preview_attachment) REFERENCES attachments (id) ON UPDATE NO ACTION ON DELETE SET NULL NOT DEFERRABLE INITIALLY IMMEDIATE)');
|
||||||
|
$this->addSql('INSERT INTO users (id, group_id, currency_id, id_preview_attachment, disabled, config_theme, pw_reset_token, config_instock_comment_a, config_instock_comment_w, trusted_device_cookie_version, backup_codes, google_authenticator_secret, config_timezone, config_language, email, department, last_name, first_name, need_pw_change, password, name, settings, backup_codes_generation_date, pw_reset_expires, last_modified, datetime_added, permissions_data, saml_user) SELECT id, group_id, currency_id, id_preview_attachment, disabled, config_theme, pw_reset_token, config_instock_comment_a, config_instock_comment_w, trusted_device_cookie_version, backup_codes, google_authenticator_secret, config_timezone, config_language, email, department, last_name, first_name, need_pw_change, password, name, settings, backup_codes_generation_date, pw_reset_expires, last_modified, datetime_added, permissions_data, saml_user FROM __temp__users');
|
||||||
|
$this->addSql('DROP TABLE __temp__users');
|
||||||
|
$this->addSql('CREATE INDEX IDX_1483A5E9EA7100A1 ON users (id_preview_attachment)');
|
||||||
|
$this->addSql('CREATE INDEX IDX_1483A5E938248176 ON users (currency_id)');
|
||||||
|
$this->addSql('CREATE INDEX IDX_1483A5E9FE54D947 ON users (group_id)');
|
||||||
|
$this->addSql('CREATE UNIQUE INDEX UNIQ_1483A5E95E237E06 ON users (name)');
|
||||||
|
$this->addSql('CREATE INDEX user_idx_username ON users (name)');
|
||||||
|
$this->addSql('CREATE TEMPORARY TABLE __temp__webauthn_keys AS SELECT id, user_id, public_key_credential_id, type, transports, attestation_type, trust_path, aaguid, credential_public_key, user_handle, counter, name, last_modified, datetime_added FROM webauthn_keys');
|
||||||
|
$this->addSql('DROP TABLE webauthn_keys');
|
||||||
|
$this->addSql('CREATE TABLE webauthn_keys (id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, user_id INTEGER DEFAULT NULL, public_key_credential_id CLOB NOT NULL --(DC2Type:base64)
|
||||||
|
, type VARCHAR(255) NOT NULL, transports CLOB NOT NULL --(DC2Type:array)
|
||||||
|
, attestation_type VARCHAR(255) NOT NULL, trust_path CLOB NOT NULL --(DC2Type:trust_path)
|
||||||
|
, aaguid CLOB NOT NULL --(DC2Type:aaguid)
|
||||||
|
, credential_public_key CLOB NOT NULL --(DC2Type:base64)
|
||||||
|
, user_handle VARCHAR(255) NOT NULL, counter INTEGER NOT NULL, name VARCHAR(255) NOT NULL, last_modified DATETIME DEFAULT CURRENT_TIMESTAMP NOT NULL, datetime_added DATETIME DEFAULT CURRENT_TIMESTAMP NOT NULL, CONSTRAINT FK_799FD143A76ED395 FOREIGN KEY (user_id) REFERENCES users (id) ON UPDATE NO ACTION ON DELETE NO ACTION NOT DEFERRABLE INITIALLY IMMEDIATE)');
|
||||||
|
$this->addSql('INSERT INTO webauthn_keys (id, user_id, public_key_credential_id, type, transports, attestation_type, trust_path, aaguid, credential_public_key, user_handle, counter, name, last_modified, datetime_added) SELECT id, user_id, public_key_credential_id, type, transports, attestation_type, trust_path, aaguid, credential_public_key, user_handle, counter, name, last_modified, datetime_added FROM __temp__webauthn_keys');
|
||||||
|
$this->addSql('DROP TABLE __temp__webauthn_keys');
|
||||||
|
$this->addSql('CREATE INDEX IDX_799FD143A76ED395 ON webauthn_keys (user_id)');
|
||||||
|
}
|
||||||
|
|
||||||
|
public function sqLiteDown(Schema $schema): void
|
||||||
|
{
|
||||||
|
$this->addSql('CREATE TEMPORARY TABLE __temp__currencies AS SELECT id, parent_id, id_preview_attachment, exchange_rate, iso_code, comment, not_selectable, name, last_modified, datetime_added FROM currencies');
|
||||||
|
$this->addSql('DROP TABLE currencies');
|
||||||
|
$this->addSql('CREATE TABLE currencies (id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, parent_id INTEGER DEFAULT NULL, id_preview_attachment INTEGER DEFAULT NULL, exchange_rate NUMERIC(11, 5) DEFAULT NULL --
|
||||||
|
(DC2Type:big_decimal)
|
||||||
|
, iso_code VARCHAR(255) NOT NULL, comment CLOB NOT NULL, not_selectable BOOLEAN NOT NULL, name VARCHAR(255) NOT NULL, last_modified DATETIME DEFAULT CURRENT_TIMESTAMP NOT NULL, datetime_added DATETIME DEFAULT CURRENT_TIMESTAMP NOT NULL, CONSTRAINT FK_37C44693727ACA70 FOREIGN KEY (parent_id) REFERENCES currencies (id) NOT DEFERRABLE INITIALLY IMMEDIATE, CONSTRAINT FK_37C44693EA7100A1 FOREIGN KEY (id_preview_attachment) REFERENCES "attachments" (id) ON DELETE SET NULL NOT DEFERRABLE INITIALLY IMMEDIATE)');
|
||||||
|
$this->addSql('INSERT INTO currencies (id, parent_id, id_preview_attachment, exchange_rate, iso_code, comment, not_selectable, name, last_modified, datetime_added) SELECT id, parent_id, id_preview_attachment, exchange_rate, iso_code, comment, not_selectable, name, last_modified, datetime_added FROM __temp__currencies');
|
||||||
|
$this->addSql('DROP TABLE __temp__currencies');
|
||||||
|
$this->addSql('CREATE INDEX IDX_37C44693727ACA70 ON currencies (parent_id)');
|
||||||
|
$this->addSql('CREATE INDEX IDX_37C44693EA7100A1 ON currencies (id_preview_attachment)');
|
||||||
|
$this->addSql('CREATE INDEX currency_idx_name ON currencies (name)');
|
||||||
|
$this->addSql('CREATE INDEX currency_idx_parent_name ON currencies (parent_id, name)');
|
||||||
|
$this->addSql('CREATE TEMPORARY TABLE __temp__groups AS SELECT id, parent_id, id_preview_attachment, enforce_2fa, comment, not_selectable, name, last_modified, datetime_added, permissions_data FROM "groups"');
|
||||||
|
$this->addSql('DROP TABLE "groups"');
|
||||||
|
$this->addSql('CREATE TABLE "groups" (id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, parent_id INTEGER DEFAULT NULL, id_preview_attachment INTEGER DEFAULT NULL, enforce_2fa BOOLEAN NOT NULL, comment CLOB NOT NULL, not_selectable BOOLEAN NOT NULL, name VARCHAR(255) NOT NULL, last_modified DATETIME DEFAULT CURRENT_TIMESTAMP NOT NULL, datetime_added DATETIME DEFAULT CURRENT_TIMESTAMP NOT NULL, permissions_data CLOB DEFAULT \'[]\' NOT NULL --
|
||||||
|
(DC2Type:json)
|
||||||
|
, CONSTRAINT FK_F06D3970727ACA70 FOREIGN KEY (parent_id) REFERENCES "groups" (id) NOT DEFERRABLE INITIALLY IMMEDIATE, CONSTRAINT FK_F06D3970EA7100A1 FOREIGN KEY (id_preview_attachment) REFERENCES "attachments" (id) ON DELETE SET NULL NOT DEFERRABLE INITIALLY IMMEDIATE)');
|
||||||
|
$this->addSql('INSERT INTO "groups" (id, parent_id, id_preview_attachment, enforce_2fa, comment, not_selectable, name, last_modified, datetime_added, permissions_data) SELECT id, parent_id, id_preview_attachment, enforce_2fa, comment, not_selectable, name, last_modified, datetime_added, permissions_data FROM __temp__groups');
|
||||||
|
$this->addSql('DROP TABLE __temp__groups');
|
||||||
|
$this->addSql('CREATE INDEX IDX_F06D3970727ACA70 ON "groups" (parent_id)');
|
||||||
|
$this->addSql('CREATE INDEX IDX_F06D3970EA7100A1 ON "groups" (id_preview_attachment)');
|
||||||
|
$this->addSql('CREATE INDEX group_idx_name ON "groups" (name)');
|
||||||
|
$this->addSql('CREATE INDEX group_idx_parent_name ON "groups" (parent_id, name)');
|
||||||
|
$this->addSql('CREATE TEMPORARY TABLE __temp__log AS SELECT id, id_user, username, datetime, level, target_id, target_type, extra, type FROM log');
|
||||||
|
$this->addSql('DROP TABLE log');
|
||||||
|
$this->addSql('CREATE TABLE log (id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, id_user INTEGER DEFAULT NULL, username VARCHAR(255) NOT NULL, datetime DATETIME NOT NULL, level BOOLEAN NOT NULL, target_id INTEGER NOT NULL, target_type SMALLINT NOT NULL, extra CLOB NOT NULL --
|
||||||
|
(DC2Type:json)
|
||||||
|
, type SMALLINT NOT NULL, CONSTRAINT FK_8F3F68C56B3CA4B FOREIGN KEY (id_user) REFERENCES "users" (id) ON DELETE SET NULL NOT DEFERRABLE INITIALLY IMMEDIATE)');
|
||||||
|
$this->addSql('INSERT INTO log (id, id_user, username, datetime, level, target_id, target_type, extra, type) SELECT id, id_user, username, datetime, level, target_id, target_type, extra, type FROM __temp__log');
|
||||||
|
$this->addSql('DROP TABLE __temp__log');
|
||||||
|
$this->addSql('CREATE INDEX IDX_8F3F68C56B3CA4B ON log (id_user)');
|
||||||
|
$this->addSql('CREATE INDEX log_idx_type ON log (type)');
|
||||||
|
$this->addSql('CREATE INDEX log_idx_type_target ON log (type, target_type, target_id)');
|
||||||
|
$this->addSql('CREATE INDEX log_idx_datetime ON log (datetime)');
|
||||||
|
$this->addSql('CREATE TEMPORARY TABLE __temp__part_lots AS SELECT id, id_store_location, id_part, description, comment, expiration_date, instock_unknown, amount, needs_refill, last_modified, datetime_added FROM part_lots');
|
||||||
|
$this->addSql('DROP TABLE part_lots');
|
||||||
|
$this->addSql('CREATE TABLE part_lots (id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, id_store_location INTEGER DEFAULT NULL, id_part INTEGER NOT NULL, description CLOB NOT NULL, comment CLOB NOT NULL, expiration_date DATETIME DEFAULT NULL, instock_unknown BOOLEAN NOT NULL, amount DOUBLE PRECISION NOT NULL, needs_refill BOOLEAN NOT NULL, last_modified DATETIME DEFAULT CURRENT_TIMESTAMP NOT NULL, datetime_added DATETIME DEFAULT CURRENT_TIMESTAMP NOT NULL, CONSTRAINT FK_EBC8F9435D8F4B37 FOREIGN KEY (id_store_location) REFERENCES "storelocations" (id) NOT DEFERRABLE INITIALLY IMMEDIATE, CONSTRAINT FK_EBC8F943C22F6CC4 FOREIGN KEY (id_part) REFERENCES "parts" (id) ON DELETE CASCADE NOT DEFERRABLE INITIALLY IMMEDIATE)');
|
||||||
|
$this->addSql('INSERT INTO part_lots (id, id_store_location, id_part, description, comment, expiration_date, instock_unknown, amount, needs_refill, last_modified, datetime_added) SELECT id, id_store_location, id_part, description, comment, expiration_date, instock_unknown, amount, needs_refill, last_modified, datetime_added FROM __temp__part_lots');
|
||||||
|
$this->addSql('DROP TABLE __temp__part_lots');
|
||||||
|
$this->addSql('CREATE INDEX IDX_EBC8F9435D8F4B37 ON part_lots (id_store_location)');
|
||||||
|
$this->addSql('CREATE INDEX IDX_EBC8F943C22F6CC4 ON part_lots (id_part)');
|
||||||
|
$this->addSql('CREATE INDEX part_lots_idx_instock_un_expiration_id_part ON part_lots (instock_unknown, expiration_date, id_part)');
|
||||||
|
$this->addSql('CREATE INDEX part_lots_idx_needs_refill ON part_lots (needs_refill)');
|
||||||
|
$this->addSql('CREATE TEMPORARY TABLE __temp__pricedetails AS SELECT id, id_currency, orderdetails_id, price, price_related_quantity, min_discount_quantity, manual_input, last_modified, datetime_added FROM "pricedetails"');
|
||||||
|
$this->addSql('DROP TABLE "pricedetails"');
|
||||||
|
$this->addSql('CREATE TABLE "pricedetails" (id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, id_currency INTEGER DEFAULT NULL, orderdetails_id INTEGER NOT NULL, price NUMERIC(11, 5) NOT NULL --
|
||||||
|
(DC2Type:big_decimal)
|
||||||
|
, price_related_quantity DOUBLE PRECISION NOT NULL, min_discount_quantity DOUBLE PRECISION NOT NULL, manual_input BOOLEAN NOT NULL, last_modified DATETIME DEFAULT CURRENT_TIMESTAMP NOT NULL, datetime_added DATETIME DEFAULT CURRENT_TIMESTAMP NOT NULL, CONSTRAINT FK_C68C4459398D64AA FOREIGN KEY (id_currency) REFERENCES currencies (id) NOT DEFERRABLE INITIALLY IMMEDIATE, CONSTRAINT FK_C68C44594A01DDC7 FOREIGN KEY (orderdetails_id) REFERENCES "orderdetails" (id) ON DELETE CASCADE NOT DEFERRABLE INITIALLY IMMEDIATE)');
|
||||||
|
$this->addSql('INSERT INTO "pricedetails" (id, id_currency, orderdetails_id, price, price_related_quantity, min_discount_quantity, manual_input, last_modified, datetime_added) SELECT id, id_currency, orderdetails_id, price, price_related_quantity, min_discount_quantity, manual_input, last_modified, datetime_added FROM __temp__pricedetails');
|
||||||
|
$this->addSql('DROP TABLE __temp__pricedetails');
|
||||||
|
$this->addSql('CREATE INDEX IDX_C68C4459398D64AA ON "pricedetails" (id_currency)');
|
||||||
|
$this->addSql('CREATE INDEX IDX_C68C44594A01DDC7 ON "pricedetails" (orderdetails_id)');
|
||||||
|
$this->addSql('CREATE INDEX pricedetails_idx_min_discount ON "pricedetails" (min_discount_quantity)');
|
||||||
|
$this->addSql('CREATE INDEX pricedetails_idx_min_discount_price_qty ON "pricedetails" (min_discount_quantity, price_related_quantity)');
|
||||||
|
$this->addSql('CREATE TEMPORARY TABLE __temp__project_bom_entries AS SELECT id, id_device, id_part, price_currency_id, quantity, mountnames, name, comment, price, last_modified, datetime_added FROM project_bom_entries');
|
||||||
|
$this->addSql('DROP TABLE project_bom_entries');
|
||||||
|
$this->addSql('CREATE TABLE project_bom_entries (id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, id_device INTEGER DEFAULT NULL, id_part INTEGER DEFAULT NULL, price_currency_id INTEGER DEFAULT NULL, quantity DOUBLE PRECISION NOT NULL, mountnames CLOB NOT NULL, name VARCHAR(255) DEFAULT NULL, comment CLOB NOT NULL, price NUMERIC(11, 5) DEFAULT NULL --
|
||||||
|
(DC2Type:big_decimal)
|
||||||
|
, last_modified DATETIME DEFAULT CURRENT_TIMESTAMP NOT NULL, datetime_added DATETIME DEFAULT CURRENT_TIMESTAMP NOT NULL, CONSTRAINT FK_1AA2DD312F180363 FOREIGN KEY (id_device) REFERENCES projects (id) NOT DEFERRABLE INITIALLY IMMEDIATE, CONSTRAINT FK_1AA2DD31C22F6CC4 FOREIGN KEY (id_part) REFERENCES "parts" (id) NOT DEFERRABLE INITIALLY IMMEDIATE, CONSTRAINT FK_1AA2DD313FFDCD60 FOREIGN KEY (price_currency_id) REFERENCES currencies (id) NOT DEFERRABLE INITIALLY IMMEDIATE)');
|
||||||
|
$this->addSql('INSERT INTO project_bom_entries (id, id_device, id_part, price_currency_id, quantity, mountnames, name, comment, price, last_modified, datetime_added) SELECT id, id_device, id_part, price_currency_id, quantity, mountnames, name, comment, price, last_modified, datetime_added FROM __temp__project_bom_entries');
|
||||||
|
$this->addSql('DROP TABLE __temp__project_bom_entries');
|
||||||
|
$this->addSql('CREATE INDEX IDX_1AA2DD312F180363 ON project_bom_entries (id_device)');
|
||||||
|
$this->addSql('CREATE INDEX IDX_1AA2DD31C22F6CC4 ON project_bom_entries (id_part)');
|
||||||
|
$this->addSql('CREATE INDEX IDX_1AA2DD313FFDCD60 ON project_bom_entries (price_currency_id)');
|
||||||
|
$this->addSql('CREATE TEMPORARY TABLE __temp__projects AS SELECT id, parent_id, id_preview_attachment, order_quantity, status, order_only_missing_parts, description, comment, not_selectable, name, last_modified, datetime_added FROM projects');
|
||||||
|
$this->addSql('DROP TABLE projects');
|
||||||
|
$this->addSql('CREATE TABLE projects (id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, parent_id INTEGER DEFAULT NULL, id_preview_attachment INTEGER DEFAULT NULL, order_quantity INTEGER NOT NULL, status VARCHAR(64) DEFAULT NULL, order_only_missing_parts BOOLEAN NOT NULL, description CLOB DEFAULT \'\', comment CLOB NOT NULL, not_selectable BOOLEAN NOT NULL, name VARCHAR(255) NOT NULL, last_modified DATETIME DEFAULT CURRENT_TIMESTAMP NOT NULL, datetime_added DATETIME DEFAULT CURRENT_TIMESTAMP NOT NULL, CONSTRAINT FK_5C93B3A4727ACA70 FOREIGN KEY (parent_id) REFERENCES projects (id) NOT DEFERRABLE INITIALLY IMMEDIATE, CONSTRAINT FK_5C93B3A4EA7100A1 FOREIGN KEY (id_preview_attachment) REFERENCES "attachments" (id) ON DELETE SET NULL NOT DEFERRABLE INITIALLY IMMEDIATE)');
|
||||||
|
$this->addSql('INSERT INTO projects (id, parent_id, id_preview_attachment, order_quantity, status, order_only_missing_parts, description, comment, not_selectable, name, last_modified, datetime_added) SELECT id, parent_id, id_preview_attachment, order_quantity, status, order_only_missing_parts, description, comment, not_selectable, name, last_modified, datetime_added FROM __temp__projects');
|
||||||
|
$this->addSql('DROP TABLE __temp__projects');
|
||||||
|
$this->addSql('CREATE INDEX IDX_5C93B3A4727ACA70 ON projects (parent_id)');
|
||||||
|
$this->addSql('CREATE INDEX IDX_5C93B3A4EA7100A1 ON projects (id_preview_attachment)');
|
||||||
|
$this->addSql('CREATE TEMPORARY TABLE __temp__storelocations AS SELECT id, parent_id, storage_type_id, id_preview_attachment, is_full, only_single_part, limit_to_existing_parts, comment, not_selectable, name, last_modified, datetime_added FROM "storelocations"');
|
||||||
|
$this->addSql('DROP TABLE "storelocations"');
|
||||||
|
$this->addSql('CREATE TABLE "storelocations" (id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, parent_id INTEGER DEFAULT NULL, storage_type_id INTEGER DEFAULT NULL, id_preview_attachment INTEGER DEFAULT NULL, is_full BOOLEAN NOT NULL, only_single_part BOOLEAN NOT NULL, limit_to_existing_parts BOOLEAN NOT NULL, comment CLOB NOT NULL, not_selectable BOOLEAN NOT NULL, name VARCHAR(255) NOT NULL, last_modified DATETIME DEFAULT CURRENT_TIMESTAMP NOT NULL, datetime_added DATETIME DEFAULT CURRENT_TIMESTAMP NOT NULL, CONSTRAINT FK_7517020727ACA70 FOREIGN KEY (parent_id) REFERENCES "storelocations" (id) NOT DEFERRABLE INITIALLY IMMEDIATE, CONSTRAINT FK_7517020B270BFF1 FOREIGN KEY (storage_type_id) REFERENCES "measurement_units" (id) NOT DEFERRABLE INITIALLY IMMEDIATE, CONSTRAINT FK_7517020EA7100A1 FOREIGN KEY (id_preview_attachment) REFERENCES "attachments" (id) ON DELETE SET NULL NOT DEFERRABLE INITIALLY IMMEDIATE)');
|
||||||
|
$this->addSql('INSERT INTO "storelocations" (id, parent_id, storage_type_id, id_preview_attachment, is_full, only_single_part, limit_to_existing_parts, comment, not_selectable, name, last_modified, datetime_added) SELECT id, parent_id, storage_type_id, id_preview_attachment, is_full, only_single_part, limit_to_existing_parts, comment, not_selectable, name, last_modified, datetime_added FROM __temp__storelocations');
|
||||||
|
$this->addSql('DROP TABLE __temp__storelocations');
|
||||||
|
$this->addSql('CREATE INDEX IDX_7517020727ACA70 ON "storelocations" (parent_id)');
|
||||||
|
$this->addSql('CREATE INDEX IDX_7517020B270BFF1 ON "storelocations" (storage_type_id)');
|
||||||
|
$this->addSql('CREATE INDEX IDX_7517020EA7100A1 ON "storelocations" (id_preview_attachment)');
|
||||||
|
$this->addSql('CREATE INDEX location_idx_name ON "storelocations" (name)');
|
||||||
|
$this->addSql('CREATE INDEX location_idx_parent_name ON "storelocations" (parent_id, name)');
|
||||||
|
$this->addSql('CREATE TEMPORARY TABLE __temp__suppliers AS SELECT id, parent_id, default_currency_id, id_preview_attachment, shipping_costs, address, phone_number, fax_number, email_address, website, auto_product_url, comment, not_selectable, name, last_modified, datetime_added FROM "suppliers"');
|
||||||
|
$this->addSql('DROP TABLE "suppliers"');
|
||||||
|
$this->addSql('CREATE TABLE "suppliers" (id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, parent_id INTEGER DEFAULT NULL, default_currency_id INTEGER DEFAULT NULL, id_preview_attachment INTEGER DEFAULT NULL, shipping_costs NUMERIC(11, 5) DEFAULT NULL --
|
||||||
|
(DC2Type:big_decimal)
|
||||||
|
, address VARCHAR(255) NOT NULL, phone_number VARCHAR(255) NOT NULL, fax_number VARCHAR(255) NOT NULL, email_address VARCHAR(255) NOT NULL, website VARCHAR(255) NOT NULL, auto_product_url VARCHAR(255) NOT NULL, comment CLOB NOT NULL, not_selectable BOOLEAN NOT NULL, name VARCHAR(255) NOT NULL, last_modified DATETIME DEFAULT CURRENT_TIMESTAMP NOT NULL, datetime_added DATETIME DEFAULT CURRENT_TIMESTAMP NOT NULL, CONSTRAINT FK_AC28B95C727ACA70 FOREIGN KEY (parent_id) REFERENCES "suppliers" (id) NOT DEFERRABLE INITIALLY IMMEDIATE, CONSTRAINT FK_AC28B95CECD792C0 FOREIGN KEY (default_currency_id) REFERENCES currencies (id) NOT DEFERRABLE INITIALLY IMMEDIATE, CONSTRAINT FK_AC28B95CEA7100A1 FOREIGN KEY (id_preview_attachment) REFERENCES "attachments" (id) ON DELETE SET NULL NOT DEFERRABLE INITIALLY IMMEDIATE)');
|
||||||
|
$this->addSql('INSERT INTO "suppliers" (id, parent_id, default_currency_id, id_preview_attachment, shipping_costs, address, phone_number, fax_number, email_address, website, auto_product_url, comment, not_selectable, name, last_modified, datetime_added) SELECT id, parent_id, default_currency_id, id_preview_attachment, shipping_costs, address, phone_number, fax_number, email_address, website, auto_product_url, comment, not_selectable, name, last_modified, datetime_added FROM __temp__suppliers');
|
||||||
|
$this->addSql('DROP TABLE __temp__suppliers');
|
||||||
|
$this->addSql('CREATE INDEX IDX_AC28B95C727ACA70 ON "suppliers" (parent_id)');
|
||||||
|
$this->addSql('CREATE INDEX IDX_AC28B95CECD792C0 ON "suppliers" (default_currency_id)');
|
||||||
|
$this->addSql('CREATE INDEX IDX_AC28B95CEA7100A1 ON "suppliers" (id_preview_attachment)');
|
||||||
|
$this->addSql('CREATE INDEX supplier_idx_name ON "suppliers" (name)');
|
||||||
|
$this->addSql('CREATE INDEX supplier_idx_parent_name ON "suppliers" (parent_id, name)');
|
||||||
|
$this->addSql('CREATE TEMPORARY TABLE __temp__users AS SELECT id, group_id, currency_id, id_preview_attachment, disabled, config_theme, pw_reset_token, config_instock_comment_a, config_instock_comment_w, trusted_device_cookie_version, backup_codes, google_authenticator_secret, config_timezone, config_language, email, department, last_name, first_name, need_pw_change, password, name, settings, backup_codes_generation_date, pw_reset_expires, saml_user, last_modified, datetime_added, permissions_data FROM "users"');
|
||||||
|
$this->addSql('DROP TABLE "users"');
|
||||||
|
$this->addSql('CREATE TABLE "users" (id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, group_id INTEGER DEFAULT NULL, currency_id INTEGER DEFAULT NULL, id_preview_attachment INTEGER DEFAULT NULL, disabled BOOLEAN NOT NULL, config_theme VARCHAR(255) DEFAULT NULL, pw_reset_token VARCHAR(255) DEFAULT NULL, config_instock_comment_a CLOB NOT NULL, config_instock_comment_w CLOB NOT NULL, trusted_device_cookie_version INTEGER NOT NULL, backup_codes CLOB NOT NULL --
|
||||||
|
(DC2Type:json)
|
||||||
|
, google_authenticator_secret VARCHAR(255) DEFAULT NULL, config_timezone VARCHAR(255) DEFAULT NULL, config_language VARCHAR(255) DEFAULT NULL, email VARCHAR(255) DEFAULT NULL, department VARCHAR(255) DEFAULT NULL, last_name VARCHAR(255) DEFAULT NULL, first_name VARCHAR(255) DEFAULT NULL, need_pw_change BOOLEAN NOT NULL, password VARCHAR(255) DEFAULT NULL, name VARCHAR(180) NOT NULL, settings CLOB NOT NULL --
|
||||||
|
(DC2Type:json)
|
||||||
|
, backup_codes_generation_date DATETIME DEFAULT NULL, pw_reset_expires DATETIME DEFAULT NULL, saml_user BOOLEAN DEFAULT 0 NOT NULL, last_modified DATETIME DEFAULT CURRENT_TIMESTAMP NOT NULL, datetime_added DATETIME DEFAULT CURRENT_TIMESTAMP NOT NULL, permissions_data CLOB DEFAULT \'[]\' NOT NULL --
|
||||||
|
(DC2Type:json)
|
||||||
|
, CONSTRAINT FK_1483A5E9FE54D947 FOREIGN KEY (group_id) REFERENCES "groups" (id) NOT DEFERRABLE INITIALLY IMMEDIATE, CONSTRAINT FK_1483A5E938248176 FOREIGN KEY (currency_id) REFERENCES currencies (id) NOT DEFERRABLE INITIALLY IMMEDIATE, CONSTRAINT FK_1483A5E9EA7100A1 FOREIGN KEY (id_preview_attachment) REFERENCES "attachments" (id) ON DELETE SET NULL NOT DEFERRABLE INITIALLY IMMEDIATE)');
|
||||||
|
$this->addSql('INSERT INTO "users" (id, group_id, currency_id, id_preview_attachment, disabled, config_theme, pw_reset_token, config_instock_comment_a, config_instock_comment_w, trusted_device_cookie_version, backup_codes, google_authenticator_secret, config_timezone, config_language, email, department, last_name, first_name, need_pw_change, password, name, settings, backup_codes_generation_date, pw_reset_expires, saml_user, last_modified, datetime_added, permissions_data) SELECT id, group_id, currency_id, id_preview_attachment, disabled, config_theme, pw_reset_token, config_instock_comment_a, config_instock_comment_w, trusted_device_cookie_version, backup_codes, google_authenticator_secret, config_timezone, config_language, email, department, last_name, first_name, need_pw_change, password, name, settings, backup_codes_generation_date, pw_reset_expires, saml_user, last_modified, datetime_added, permissions_data FROM __temp__users');
|
||||||
|
$this->addSql('DROP TABLE __temp__users');
|
||||||
|
$this->addSql('CREATE UNIQUE INDEX UNIQ_1483A5E95E237E06 ON "users" (name)');
|
||||||
|
$this->addSql('CREATE INDEX IDX_1483A5E9FE54D947 ON "users" (group_id)');
|
||||||
|
$this->addSql('CREATE INDEX IDX_1483A5E938248176 ON "users" (currency_id)');
|
||||||
|
$this->addSql('CREATE INDEX IDX_1483A5E9EA7100A1 ON "users" (id_preview_attachment)');
|
||||||
|
$this->addSql('CREATE INDEX user_idx_username ON "users" (name)');
|
||||||
|
$this->addSql('CREATE TEMPORARY TABLE __temp__webauthn_keys AS SELECT id, user_id, public_key_credential_id, type, transports, attestation_type, trust_path, aaguid, credential_public_key, user_handle, counter, name, last_modified, datetime_added FROM webauthn_keys');
|
||||||
|
$this->addSql('DROP TABLE webauthn_keys');
|
||||||
|
$this->addSql('CREATE TABLE webauthn_keys (id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, user_id INTEGER DEFAULT NULL, public_key_credential_id CLOB NOT NULL --
|
||||||
|
(DC2Type:base64)
|
||||||
|
, type VARCHAR(255) NOT NULL, transports CLOB NOT NULL --
|
||||||
|
(DC2Type:array)
|
||||||
|
, attestation_type VARCHAR(255) NOT NULL, trust_path CLOB NOT NULL --
|
||||||
|
(DC2Type:trust_path)
|
||||||
|
, aaguid CLOB NOT NULL --
|
||||||
|
(DC2Type:aaguid)
|
||||||
|
, credential_public_key CLOB NOT NULL --
|
||||||
|
(DC2Type:base64)
|
||||||
|
, user_handle VARCHAR(255) NOT NULL, counter INTEGER NOT NULL, name VARCHAR(255) NOT NULL, last_modified DATETIME DEFAULT CURRENT_TIMESTAMP NOT NULL, datetime_added DATETIME DEFAULT CURRENT_TIMESTAMP NOT NULL, CONSTRAINT FK_799FD143A76ED395 FOREIGN KEY (user_id) REFERENCES "users" (id) NOT DEFERRABLE INITIALLY IMMEDIATE)');
|
||||||
|
$this->addSql('INSERT INTO webauthn_keys (id, user_id, public_key_credential_id, type, transports, attestation_type, trust_path, aaguid, credential_public_key, user_handle, counter, name, last_modified, datetime_added) SELECT id, user_id, public_key_credential_id, type, transports, attestation_type, trust_path, aaguid, credential_public_key, user_handle, counter, name, last_modified, datetime_added FROM __temp__webauthn_keys');
|
||||||
|
$this->addSql('DROP TABLE __temp__webauthn_keys');
|
||||||
|
$this->addSql('CREATE INDEX IDX_799FD143A76ED395 ON webauthn_keys (user_id)');
|
||||||
|
}
|
||||||
|
}
|
|
@ -55,8 +55,11 @@ use Symfony\Component\HttpFoundation\Request;
|
||||||
use Symfony\Component\HttpFoundation\Response;
|
use Symfony\Component\HttpFoundation\Response;
|
||||||
use Symfony\Component\HttpKernel\Exception\BadRequestHttpException;
|
use Symfony\Component\HttpKernel\Exception\BadRequestHttpException;
|
||||||
use Symfony\Component\Routing\Annotation\Route;
|
use Symfony\Component\Routing\Annotation\Route;
|
||||||
|
use Symfony\Component\Security\Core\Exception\AccessDeniedException;
|
||||||
use Symfony\Contracts\Translation\TranslatorInterface;
|
use Symfony\Contracts\Translation\TranslatorInterface;
|
||||||
|
|
||||||
|
use function Symfony\Component\Translation\t;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @Route("/part")
|
* @Route("/part")
|
||||||
*/
|
*/
|
||||||
|
@ -360,7 +363,7 @@ class PartController extends AbstractController
|
||||||
$action = $request->request->get('action');
|
$action = $request->request->get('action');
|
||||||
|
|
||||||
|
|
||||||
|
try {
|
||||||
switch ($action) {
|
switch ($action) {
|
||||||
case "withdraw":
|
case "withdraw":
|
||||||
case "remove":
|
case "remove":
|
||||||
|
@ -373,11 +376,16 @@ class PartController extends AbstractController
|
||||||
break;
|
break;
|
||||||
case "move":
|
case "move":
|
||||||
$this->denyAccessUnlessGranted('move', $partLot);
|
$this->denyAccessUnlessGranted('move', $partLot);
|
||||||
|
$this->denyAccessUnlessGranted('move', $targetLot);
|
||||||
$withdrawAddHelper->move($partLot, $targetLot, $amount, $comment);
|
$withdrawAddHelper->move($partLot, $targetLot, $amount, $comment);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
throw new \RuntimeException("Unknown action!");
|
throw new \RuntimeException("Unknown action!");
|
||||||
}
|
}
|
||||||
|
} catch (AccessDeniedException $exception) {
|
||||||
|
$this->addFlash('error', t('part.withdraw.access_denied'));
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
|
|
||||||
//Save the changes to the DB
|
//Save the changes to the DB
|
||||||
$em->flush();
|
$em->flush();
|
||||||
|
@ -387,6 +395,7 @@ class PartController extends AbstractController
|
||||||
$this->addFlash('error', 'CSRF Token invalid!');
|
$this->addFlash('error', 'CSRF Token invalid!');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
err:
|
||||||
//If an redirect was passed, then redirect there
|
//If an redirect was passed, then redirect there
|
||||||
if($request->request->get('_redirect')) {
|
if($request->request->get('_redirect')) {
|
||||||
return $this->redirect($request->request->get('_redirect'));
|
return $this->redirect($request->request->get('_redirect'));
|
||||||
|
|
|
@ -26,6 +26,7 @@ use App\Entity\Base\AbstractDBElement;
|
||||||
use App\Entity\Base\TimestampTrait;
|
use App\Entity\Base\TimestampTrait;
|
||||||
use App\Entity\Contracts\NamedElementInterface;
|
use App\Entity\Contracts\NamedElementInterface;
|
||||||
use App\Entity\Contracts\TimeStampableInterface;
|
use App\Entity\Contracts\TimeStampableInterface;
|
||||||
|
use App\Entity\UserSystem\User;
|
||||||
use App\Validator\Constraints\Selectable;
|
use App\Validator\Constraints\Selectable;
|
||||||
use App\Validator\Constraints\ValidPartLot;
|
use App\Validator\Constraints\ValidPartLot;
|
||||||
use DateTime;
|
use DateTime;
|
||||||
|
@ -33,6 +34,7 @@ use Doctrine\ORM\Mapping as ORM;
|
||||||
use Exception;
|
use Exception;
|
||||||
use Symfony\Component\Serializer\Annotation\Groups;
|
use Symfony\Component\Serializer\Annotation\Groups;
|
||||||
use Symfony\Component\Validator\Constraints as Assert;
|
use Symfony\Component\Validator\Constraints as Assert;
|
||||||
|
use Symfony\Component\Validator\Context\ExecutionContextInterface;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This entity describes a lot where parts can be stored.
|
* This entity describes a lot where parts can be stored.
|
||||||
|
@ -111,6 +113,13 @@ class PartLot extends AbstractDBElement implements TimeStampableInterface, Named
|
||||||
*/
|
*/
|
||||||
protected Part $part;
|
protected Part $part;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var User|null The owner of this part lot
|
||||||
|
* @ORM\ManyToOne(targetEntity="App\Entity\UserSystem\User")
|
||||||
|
* @ORM\JoinColumn(name="id_owner", referencedColumnName="id", nullable=true, onDelete="SET NULL")
|
||||||
|
*/
|
||||||
|
protected ?User $owner;
|
||||||
|
|
||||||
public function __clone()
|
public function __clone()
|
||||||
{
|
{
|
||||||
if ($this->id) {
|
if ($this->id) {
|
||||||
|
@ -304,8 +313,46 @@ class PartLot extends AbstractDBElement implements TimeStampableInterface, Named
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the owner of this part lot.
|
||||||
|
* @return User|null
|
||||||
|
*/
|
||||||
|
public function getOwner(): ?User
|
||||||
|
{
|
||||||
|
return $this->owner;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the owner of this part lot.
|
||||||
|
* @param User|null $owner
|
||||||
|
* @return PartLot
|
||||||
|
*/
|
||||||
|
public function setOwner(?User $owner): PartLot
|
||||||
|
{
|
||||||
|
$this->owner = $owner;
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
public function getName(): string
|
public function getName(): string
|
||||||
{
|
{
|
||||||
return $this->description;
|
return $this->description;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Assert\Callback
|
||||||
|
*/
|
||||||
|
public function validate(ExecutionContextInterface $context, $payload)
|
||||||
|
{
|
||||||
|
//When the storage location sets the owner must match, the part lot owner must match the storage location owner
|
||||||
|
if ($this->getStorageLocation() && $this->getStorageLocation()->isPartOwnerMustMatch()
|
||||||
|
&& $this->getStorageLocation()->getOwner() && $this->getOwner()) {
|
||||||
|
if ($this->getOwner() !== $this->getStorageLocation()->getOwner()
|
||||||
|
&& $this->owner->getID() !== $this->getStorageLocation()->getOwner()->getID()) {
|
||||||
|
$context->buildViolation('validator.part_lot.owner_must_match_storage_location_owner')
|
||||||
|
->setParameter('%owner_name%', $this->getStorageLocation()->getOwner()->getFullName(true))
|
||||||
|
->atPath('owner')
|
||||||
|
->addViolation();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,6 +25,7 @@ namespace App\Entity\Parts;
|
||||||
use App\Entity\Attachments\StorelocationAttachment;
|
use App\Entity\Attachments\StorelocationAttachment;
|
||||||
use App\Entity\Base\AbstractPartsContainingDBElement;
|
use App\Entity\Base\AbstractPartsContainingDBElement;
|
||||||
use App\Entity\Parameters\StorelocationParameter;
|
use App\Entity\Parameters\StorelocationParameter;
|
||||||
|
use App\Entity\UserSystem\User;
|
||||||
use Doctrine\Common\Collections\Collection;
|
use Doctrine\Common\Collections\Collection;
|
||||||
use Doctrine\ORM\Mapping as ORM;
|
use Doctrine\ORM\Mapping as ORM;
|
||||||
use Symfony\Component\Serializer\Annotation\Groups;
|
use Symfony\Component\Serializer\Annotation\Groups;
|
||||||
|
@ -89,6 +90,19 @@ class Storelocation extends AbstractPartsContainingDBElement
|
||||||
*/
|
*/
|
||||||
protected bool $limit_to_existing_parts = false;
|
protected bool $limit_to_existing_parts = false;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var User|null The owner of this storage location
|
||||||
|
* @ORM\ManyToOne(targetEntity="App\Entity\UserSystem\User")
|
||||||
|
* @ORM\JoinColumn(name="id_owner", referencedColumnName="id", nullable=true, onDelete="SET NULL")
|
||||||
|
*/
|
||||||
|
protected ?User $owner;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var bool If this is set to true, only parts lots, which are owned by the same user as the store location are allowed to be stored here.
|
||||||
|
* @ORM\Column(type="boolean", options={"default"=false})
|
||||||
|
*/
|
||||||
|
protected bool $part_owner_must_match = false;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @var Collection<int, StorelocationAttachment>
|
* @var Collection<int, StorelocationAttachment>
|
||||||
* @ORM\OneToMany(targetEntity="App\Entity\Attachments\StorelocationAttachment", mappedBy="element", cascade={"persist", "remove"}, orphanRemoval=true)
|
* @ORM\OneToMany(targetEntity="App\Entity\Attachments\StorelocationAttachment", mappedBy="element", cascade={"persist", "remove"}, orphanRemoval=true)
|
||||||
|
@ -166,6 +180,49 @@ class Storelocation extends AbstractPartsContainingDBElement
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the owner of this storage location
|
||||||
|
* @return User|null
|
||||||
|
*/
|
||||||
|
public function getOwner(): ?User
|
||||||
|
{
|
||||||
|
return $this->owner;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the owner of this storage location
|
||||||
|
* @param User|null $owner
|
||||||
|
* @return Storelocation
|
||||||
|
*/
|
||||||
|
public function setOwner(?User $owner): Storelocation
|
||||||
|
{
|
||||||
|
$this->owner = $owner;
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* If this is set to true, only parts lots, which are owned by the same user as the store location are allowed to be stored here.
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
public function isPartOwnerMustMatch(): bool
|
||||||
|
{
|
||||||
|
return $this->part_owner_must_match;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* If this is set to true, only parts lots, which are owned by the same user as the store location are allowed to be stored here.
|
||||||
|
* @param bool $part_owner_must_match
|
||||||
|
* @return Storelocation
|
||||||
|
*/
|
||||||
|
public function setPartOwnerMustMatch(bool $part_owner_must_match): Storelocation
|
||||||
|
{
|
||||||
|
$this->part_owner_must_match = $part_owner_must_match;
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/********************************************************************************
|
/********************************************************************************
|
||||||
*
|
*
|
||||||
* Setters
|
* Setters
|
||||||
|
|
|
@ -88,7 +88,7 @@ class Project extends AbstractStructuralDBElement
|
||||||
protected bool $order_only_missing_parts = false;
|
protected bool $order_only_missing_parts = false;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @ORM\Column(type="text", nullable=false, columnDefinition="DEFAULT ''")
|
* @ORM\Column(type="text", nullable=false, options={"default" : ""})
|
||||||
* @Groups({"simple", "extended", "full"})
|
* @Groups({"simple", "extended", "full"})
|
||||||
*/
|
*/
|
||||||
protected string $description = '';
|
protected string $description = '';
|
||||||
|
|
|
@ -103,6 +103,13 @@ class User extends AttachmentContainingDBElement implements UserInterface, HasPe
|
||||||
*/
|
*/
|
||||||
protected string $instock_comment_w = '';
|
protected string $instock_comment_w = '';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var string A self-description of the user
|
||||||
|
* @ORM\Column(type="text", options={"default": ""})
|
||||||
|
* @Groups({"full", "import"})
|
||||||
|
*/
|
||||||
|
protected string $aboutMe = '';
|
||||||
|
|
||||||
/** @var int The version of the trusted device cookie. Used to invalidate all trusted device cookies at once.
|
/** @var int The version of the trusted device cookie. Used to invalidate all trusted device cookies at once.
|
||||||
* @ORM\Column(type="integer")
|
* @ORM\Column(type="integer")
|
||||||
*/
|
*/
|
||||||
|
@ -254,7 +261,7 @@ class User extends AttachmentContainingDBElement implements UserInterface, HasPe
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @var DateTime the time until the password reset token is valid
|
* @var DateTime the time until the password reset token is valid
|
||||||
* @ORM\Column(type="datetime", nullable=true, columnDefinition="DEFAULT NULL")
|
* @ORM\Column(type="datetime", nullable=true, options={"default": null})
|
||||||
*/
|
*/
|
||||||
protected $pw_reset_expires;
|
protected $pw_reset_expires;
|
||||||
|
|
||||||
|
@ -625,6 +632,28 @@ class User extends AttachmentContainingDBElement implements UserInterface, HasPe
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the about me text of the user.
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public function getAboutMe(): string
|
||||||
|
{
|
||||||
|
return $this->aboutMe;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Change the about me text of the user.
|
||||||
|
* @param string $aboutMe
|
||||||
|
* @return User
|
||||||
|
*/
|
||||||
|
public function setAboutMe(string $aboutMe): User
|
||||||
|
{
|
||||||
|
$this->aboutMe = $aboutMe;
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the language the user prefers (as 2 letter ISO code).
|
* Gets the language the user prefers (as 2 letter ISO code).
|
||||||
*
|
*
|
||||||
|
|
|
@ -24,7 +24,9 @@ namespace App\Form\AdminPages;
|
||||||
|
|
||||||
use App\Entity\Base\AbstractNamedDBElement;
|
use App\Entity\Base\AbstractNamedDBElement;
|
||||||
use App\Entity\Parts\MeasurementUnit;
|
use App\Entity\Parts\MeasurementUnit;
|
||||||
|
use App\Entity\UserSystem\User;
|
||||||
use App\Form\Type\StructuralEntityType;
|
use App\Form\Type\StructuralEntityType;
|
||||||
|
use App\Form\Type\UserSelectType;
|
||||||
use Symfony\Component\Form\Extension\Core\Type\CheckboxType;
|
use Symfony\Component\Form\Extension\Core\Type\CheckboxType;
|
||||||
use Symfony\Component\Form\FormBuilderInterface;
|
use Symfony\Component\Form\FormBuilderInterface;
|
||||||
|
|
||||||
|
@ -63,5 +65,16 @@ class StorelocationAdminForm extends BaseEntityAdminForm
|
||||||
'disable_not_selectable' => true,
|
'disable_not_selectable' => true,
|
||||||
'disabled' => !$this->security->isGranted($is_new ? 'create' : 'edit', $entity),
|
'disabled' => !$this->security->isGranted($is_new ? 'create' : 'edit', $entity),
|
||||||
]);
|
]);
|
||||||
|
|
||||||
|
$builder->add('owner', UserSelectType::class, [
|
||||||
|
'required' => false,
|
||||||
|
'label' => 'storelocation.owner.label',
|
||||||
|
'disabled' => !$this->security->isGranted($is_new ? 'create' : 'edit', $entity),
|
||||||
|
]);
|
||||||
|
$builder->add('part_owner_must_match', CheckboxType::class, [
|
||||||
|
'required' => false,
|
||||||
|
'label' => 'storelocation.part_owner_must_match.label',
|
||||||
|
'disabled' => !$this->security->isGranted($is_new ? 'create' : 'edit', $entity),
|
||||||
|
]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -27,6 +27,7 @@ use App\Entity\Parts\PartLot;
|
||||||
use App\Entity\Parts\Storelocation;
|
use App\Entity\Parts\Storelocation;
|
||||||
use App\Form\Type\SIUnitType;
|
use App\Form\Type\SIUnitType;
|
||||||
use App\Form\Type\StructuralEntityType;
|
use App\Form\Type\StructuralEntityType;
|
||||||
|
use App\Form\Type\UserSelectType;
|
||||||
use Symfony\Component\Form\AbstractType;
|
use Symfony\Component\Form\AbstractType;
|
||||||
use Symfony\Component\Form\Extension\Core\Type\CheckboxType;
|
use Symfony\Component\Form\Extension\Core\Type\CheckboxType;
|
||||||
use Symfony\Component\Form\Extension\Core\Type\DateType;
|
use Symfony\Component\Form\Extension\Core\Type\DateType;
|
||||||
|
@ -98,6 +99,12 @@ class PartLotType extends AbstractType
|
||||||
'required' => false,
|
'required' => false,
|
||||||
'empty_data' => '',
|
'empty_data' => '',
|
||||||
]);
|
]);
|
||||||
|
|
||||||
|
$builder->add('owner', UserSelectType::class, [
|
||||||
|
'label' => 'part_lot.owner',
|
||||||
|
'required' => false,
|
||||||
|
'help' => 'part_lot.owner.help',
|
||||||
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function configureOptions(OptionsResolver $resolver): void
|
public function configureOptions(OptionsResolver $resolver): void
|
||||||
|
|
|
@ -21,8 +21,13 @@
|
||||||
namespace App\Form\Type\Helper;
|
namespace App\Form\Type\Helper;
|
||||||
|
|
||||||
use App\Entity\Attachments\AttachmentType;
|
use App\Entity\Attachments\AttachmentType;
|
||||||
|
use App\Entity\Base\AbstractDBElement;
|
||||||
|
use App\Entity\Base\AbstractNamedDBElement;
|
||||||
use App\Entity\Base\AbstractStructuralDBElement;
|
use App\Entity\Base\AbstractStructuralDBElement;
|
||||||
|
use App\Entity\Contracts\HasMasterAttachmentInterface;
|
||||||
use App\Entity\PriceInformations\Currency;
|
use App\Entity\PriceInformations\Currency;
|
||||||
|
use App\Entity\UserSystem\User;
|
||||||
|
use App\Form\Type\MasterPictureAttachmentType;
|
||||||
use App\Services\Attachments\AttachmentURLGenerator;
|
use App\Services\Attachments\AttachmentURLGenerator;
|
||||||
use RuntimeException;
|
use RuntimeException;
|
||||||
use Symfony\Component\Intl\Currencies;
|
use Symfony\Component\Intl\Currencies;
|
||||||
|
@ -43,14 +48,18 @@ class StructuralEntityChoiceHelper
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Generates the choice attributes for the given AbstractStructuralDBElement.
|
* Generates the choice attributes for the given AbstractStructuralDBElement.
|
||||||
* @param AbstractStructuralDBElement $choice
|
* @param AbstractNamedDBElement $choice
|
||||||
* @param Options|array $options
|
* @param Options|array $options
|
||||||
* @return array|string[]
|
* @return array|string[]
|
||||||
*/
|
*/
|
||||||
public function generateChoiceAttr(AbstractStructuralDBElement $choice, $options): array
|
public function generateChoiceAttr(AbstractNamedDBElement $choice, $options): array
|
||||||
{
|
{
|
||||||
$tmp = [];
|
$tmp = [
|
||||||
|
'data-level' => 0,
|
||||||
|
'data-path' => $choice->getName(),
|
||||||
|
];
|
||||||
|
|
||||||
|
if ($choice instanceof AbstractStructuralDBElement) {
|
||||||
//Disable attribute if the choice is marked as not selectable
|
//Disable attribute if the choice is marked as not selectable
|
||||||
if (($options['disable_not_selectable'] ?? false) && $choice->isNotSelectable()) {
|
if (($options['disable_not_selectable'] ?? false) && $choice->isNotSelectable()) {
|
||||||
$tmp += ['disabled' => 'disabled'];
|
$tmp += ['disabled' => 'disabled'];
|
||||||
|
@ -71,8 +80,16 @@ class StructuralEntityChoiceHelper
|
||||||
'data-level' => $level,
|
'data-level' => $level,
|
||||||
'data-parent' => $choice->getParent() ? $choice->getParent()->getFullPath() : null,
|
'data-parent' => $choice->getParent() ? $choice->getParent()->getFullPath() : null,
|
||||||
'data-path' => $choice->getFullPath('->'),
|
'data-path' => $choice->getFullPath('->'),
|
||||||
'data-image' => $choice->getMasterPictureAttachment() ? $this->attachmentURLGenerator->getThumbnailURL($choice->getMasterPictureAttachment(), 'thumbnail_xs') : null,
|
|
||||||
];
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($choice instanceof HasMasterAttachmentInterface) {
|
||||||
|
$tmp['data-image'] = $choice->getMasterPictureAttachment() ?
|
||||||
|
$this->attachmentURLGenerator->getThumbnailURL($choice->getMasterPictureAttachment(),
|
||||||
|
'thumbnail_xs')
|
||||||
|
: null
|
||||||
|
;
|
||||||
|
}
|
||||||
|
|
||||||
if ($choice instanceof AttachmentType && !empty($choice->getFiletypeFilter())) {
|
if ($choice instanceof AttachmentType && !empty($choice->getFiletypeFilter())) {
|
||||||
$tmp += ['data-filetype_filter' => $choice->getFiletypeFilter()];
|
$tmp += ['data-filetype_filter' => $choice->getFiletypeFilter()];
|
||||||
|
@ -112,20 +129,20 @@ class StructuralEntityChoiceHelper
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the choice label for the given AbstractStructuralDBElement.
|
* Returns the choice label for the given AbstractStructuralDBElement.
|
||||||
* @param AbstractStructuralDBElement $choice
|
* @param AbstractNamedDBElement $choice
|
||||||
* @return string
|
* @return string
|
||||||
*/
|
*/
|
||||||
public function generateChoiceLabel(AbstractStructuralDBElement $choice): string
|
public function generateChoiceLabel(AbstractNamedDBElement $choice): string
|
||||||
{
|
{
|
||||||
return $choice->getName();
|
return $choice->getName();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the choice value for the given AbstractStructuralDBElement.
|
* Returns the choice value for the given AbstractStructuralDBElement.
|
||||||
* @param AbstractStructuralDBElement|null $element
|
* @param AbstractNamedDBElement|null $element
|
||||||
* @return string|int|null
|
* @return string|int|null
|
||||||
*/
|
*/
|
||||||
public function generateChoiceValue(?AbstractStructuralDBElement $element)
|
public function generateChoiceValue(?AbstractNamedDBElement $element)
|
||||||
{
|
{
|
||||||
if ($element === null) {
|
if ($element === null) {
|
||||||
return null;
|
return null;
|
||||||
|
@ -138,18 +155,21 @@ class StructuralEntityChoiceHelper
|
||||||
* So please do not change this!
|
* So please do not change this!
|
||||||
*/
|
*/
|
||||||
if ($element->getID() === null) {
|
if ($element->getID() === null) {
|
||||||
|
if ($element instanceof AbstractStructuralDBElement) {
|
||||||
//Must be the same as the separator in the choice_loader, otherwise this will not work!
|
//Must be the same as the separator in the choice_loader, otherwise this will not work!
|
||||||
return $element->getFullPath('->');
|
return $element->getFullPath('->');
|
||||||
}
|
}
|
||||||
|
return $element->getName();
|
||||||
|
}
|
||||||
|
|
||||||
return $element->getID();
|
return $element->getID();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param AbstractStructuralDBElement $element
|
* @param AbstractDBElement $element
|
||||||
* @return string|null
|
* @return string|null
|
||||||
*/
|
*/
|
||||||
public function generateGroupBy(AbstractStructuralDBElement $element): ?string
|
public function generateGroupBy(AbstractDBElement $element): ?string
|
||||||
{
|
{
|
||||||
//Show entities that are not added to DB yet separately from other entities
|
//Show entities that are not added to DB yet separately from other entities
|
||||||
if ($element->getID() === null) {
|
if ($element->getID() === null) {
|
||||||
|
|
|
@ -23,6 +23,7 @@ declare(strict_types=1);
|
||||||
namespace App\Form\Type;
|
namespace App\Form\Type;
|
||||||
|
|
||||||
use App\Entity\Attachments\AttachmentType;
|
use App\Entity\Attachments\AttachmentType;
|
||||||
|
use App\Entity\Base\AbstractNamedDBElement;
|
||||||
use App\Entity\Base\AbstractStructuralDBElement;
|
use App\Entity\Base\AbstractStructuralDBElement;
|
||||||
use App\Form\Type\Helper\StructuralEntityChoiceHelper;
|
use App\Form\Type\Helper\StructuralEntityChoiceHelper;
|
||||||
use App\Form\Type\Helper\StructuralEntityChoiceLoader;
|
use App\Form\Type\Helper\StructuralEntityChoiceLoader;
|
||||||
|
@ -105,7 +106,7 @@ class StructuralEntityType extends AbstractType
|
||||||
'show_fullpath_in_subtext' => true, //When this is enabled, the full path will be shown in subtext
|
'show_fullpath_in_subtext' => true, //When this is enabled, the full path will be shown in subtext
|
||||||
'subentities_of' => null, //Only show entities with the given parent class
|
'subentities_of' => null, //Only show entities with the given parent class
|
||||||
'disable_not_selectable' => false, //Disable entries with not selectable property
|
'disable_not_selectable' => false, //Disable entries with not selectable property
|
||||||
'choice_value' => function (?AbstractStructuralDBElement $element) {
|
'choice_value' => function (?AbstractNamedDBElement $element) {
|
||||||
return $this->choice_helper->generateChoiceValue($element);
|
return $this->choice_helper->generateChoiceValue($element);
|
||||||
}, //Use the element id as option value and for comparing items
|
}, //Use the element id as option value and for comparing items
|
||||||
'choice_loader' => function (Options $options) {
|
'choice_loader' => function (Options $options) {
|
||||||
|
@ -121,7 +122,7 @@ class StructuralEntityType extends AbstractType
|
||||||
return $this->choice_helper->generateChoiceAttr($choice, $options);
|
return $this->choice_helper->generateChoiceAttr($choice, $options);
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
'group_by' => function (AbstractStructuralDBElement $element) {
|
'group_by' => function (AbstractNamedDBElement $element) {
|
||||||
return $this->choice_helper->generateGroupBy($element);
|
return $this->choice_helper->generateGroupBy($element);
|
||||||
},
|
},
|
||||||
'choice_translation_domain' => false, //Don't translate the entity names
|
'choice_translation_domain' => false, //Don't translate the entity names
|
||||||
|
|
47
src/Form/Type/UserSelectType.php
Normal file
47
src/Form/Type/UserSelectType.php
Normal file
|
@ -0,0 +1,47 @@
|
||||||
|
<?php
|
||||||
|
/*
|
||||||
|
* This file is part of Part-DB (https://github.com/Part-DB/Part-DB-symfony).
|
||||||
|
*
|
||||||
|
* Copyright (C) 2019 - 2023 Jan Böhmer (https://github.com/jbtronics)
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Affero General Public License as published
|
||||||
|
* by the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU Affero General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Affero General Public License
|
||||||
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace App\Form\Type;
|
||||||
|
|
||||||
|
use App\Entity\UserSystem\User;
|
||||||
|
use Symfony\Component\Form\AbstractType;
|
||||||
|
use Symfony\Component\OptionsResolver\Options;
|
||||||
|
use Symfony\Component\OptionsResolver\OptionsResolver;
|
||||||
|
|
||||||
|
class UserSelectType extends AbstractType
|
||||||
|
{
|
||||||
|
|
||||||
|
public function configureOptions(OptionsResolver $resolver)
|
||||||
|
{
|
||||||
|
$resolver->setDefaults([
|
||||||
|
'class' => User::class,
|
||||||
|
'choice_label' => function (Options $options) {
|
||||||
|
return function (User $choice, $key, $value) {
|
||||||
|
return $choice->getFullName(true);
|
||||||
|
};
|
||||||
|
},
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getParent()
|
||||||
|
{
|
||||||
|
return StructuralEntityType::class;
|
||||||
|
}
|
||||||
|
}
|
|
@ -29,6 +29,7 @@ use App\Entity\UserSystem\User;
|
||||||
use App\Form\Permissions\PermissionsType;
|
use App\Form\Permissions\PermissionsType;
|
||||||
use App\Form\Type\CurrencyEntityType;
|
use App\Form\Type\CurrencyEntityType;
|
||||||
use App\Form\Type\MasterPictureAttachmentType;
|
use App\Form\Type\MasterPictureAttachmentType;
|
||||||
|
use App\Form\Type\RichTextEditorType;
|
||||||
use App\Form\Type\StructuralEntityType;
|
use App\Form\Type\StructuralEntityType;
|
||||||
use App\Form\Type\ThemeChoiceType;
|
use App\Form\Type\ThemeChoiceType;
|
||||||
use Symfony\Component\Form\AbstractType;
|
use Symfony\Component\Form\AbstractType;
|
||||||
|
@ -126,6 +127,16 @@ class UserAdminForm extends AbstractType
|
||||||
'required' => false,
|
'required' => false,
|
||||||
'disabled' => !$this->security->isGranted('edit_infos', $entity),
|
'disabled' => !$this->security->isGranted('edit_infos', $entity),
|
||||||
])
|
])
|
||||||
|
->add('aboutMe', RichTextEditorType::class, [
|
||||||
|
'required' => false,
|
||||||
|
'empty_data' => '',
|
||||||
|
'label' => 'user.aboutMe.label',
|
||||||
|
'attr' => [
|
||||||
|
'rows' => 4,
|
||||||
|
],
|
||||||
|
'mode' => 'markdown-full',
|
||||||
|
'disabled' => !$this->security->isGranted('edit_infos', $entity),
|
||||||
|
])
|
||||||
|
|
||||||
//Config section
|
//Config section
|
||||||
->add('language', LanguageType::class, [
|
->add('language', LanguageType::class, [
|
||||||
|
|
|
@ -24,6 +24,7 @@ namespace App\Form;
|
||||||
|
|
||||||
use App\Entity\UserSystem\User;
|
use App\Entity\UserSystem\User;
|
||||||
use App\Form\Type\CurrencyEntityType;
|
use App\Form\Type\CurrencyEntityType;
|
||||||
|
use App\Form\Type\RichTextEditorType;
|
||||||
use App\Form\Type\ThemeChoiceType;
|
use App\Form\Type\ThemeChoiceType;
|
||||||
use Symfony\Component\Form\AbstractType;
|
use Symfony\Component\Form\AbstractType;
|
||||||
use Symfony\Component\Form\Event\PreSetDataEvent;
|
use Symfony\Component\Form\Event\PreSetDataEvent;
|
||||||
|
@ -93,6 +94,16 @@ class UserSettingsType extends AbstractType
|
||||||
]),
|
]),
|
||||||
],
|
],
|
||||||
])
|
])
|
||||||
|
->add('aboutMe', RichTextEditorType::class, [
|
||||||
|
'required' => false,
|
||||||
|
'empty_data' => '',
|
||||||
|
'label' => 'user.aboutMe.label',
|
||||||
|
'attr' => [
|
||||||
|
'rows' => 4,
|
||||||
|
],
|
||||||
|
'mode' => 'markdown-full',
|
||||||
|
'disabled' => !$this->security->isGranted('edit_infos', $options['data']) || $this->demo_mode,
|
||||||
|
])
|
||||||
->add('language', LanguageType::class, [
|
->add('language', LanguageType::class, [
|
||||||
'disabled' => $this->demo_mode,
|
'disabled' => $this->demo_mode,
|
||||||
'required' => false,
|
'required' => false,
|
||||||
|
|
|
@ -59,4 +59,14 @@ class NamedDBElementRepository extends DBElementRepository
|
||||||
|
|
||||||
return $result;
|
return $result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the list of all nodes to use in a select box.
|
||||||
|
* @return AbstractNamedDBElement[]
|
||||||
|
*/
|
||||||
|
public function toNodesList(): array
|
||||||
|
{
|
||||||
|
//All nodes are sorted by name
|
||||||
|
return $this->findBy([], ['name' => 'ASC']);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -67,7 +67,15 @@ class PartLotVoter extends ExtendedVoter
|
||||||
|
|
||||||
if (in_array($attribute, ['withdraw', 'add', 'move']))
|
if (in_array($attribute, ['withdraw', 'add', 'move']))
|
||||||
{
|
{
|
||||||
return $this->resolver->inherit($user, 'parts_stock', $attribute) ?? false;
|
$base_permission = $this->resolver->inherit($user, 'parts_stock', $attribute) ?? false;
|
||||||
|
|
||||||
|
$lot_permission = true;
|
||||||
|
//If the lot has an owner, we need to check if the user is the owner of the lot to be allowed to withdraw it.
|
||||||
|
if ($subject instanceof PartLot && $subject->getOwner()) {
|
||||||
|
$lot_permission = $subject->getOwner() === $user || $subject->getOwner()->getID() === $user->getID();
|
||||||
|
}
|
||||||
|
|
||||||
|
return $base_permission && $lot_permission;
|
||||||
}
|
}
|
||||||
|
|
||||||
switch ($attribute) {
|
switch ($attribute) {
|
||||||
|
|
|
@ -102,6 +102,14 @@ final class PartLotProvider implements PlaceholderProviderInterface
|
||||||
return $label_target->getStorageLocation() ? $label_target->getStorageLocation()->getFullPath() : '';
|
return $label_target->getStorageLocation() ? $label_target->getStorageLocation()->getFullPath() : '';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ('[[OWNER]]' === $placeholder) {
|
||||||
|
return $label_target->getOwner() ? $label_target->getOwner()->getFullName() : '';
|
||||||
|
}
|
||||||
|
|
||||||
|
if ('[[OWNER_USERNAME]]' === $placeholder) {
|
||||||
|
return $label_target->getOwner() ? $label_target->getOwner()->getUsername() : '';
|
||||||
|
}
|
||||||
|
|
||||||
return $this->labelTextReplacer->handlePlaceholder($placeholder, $label_target->getPart());
|
return $this->labelTextReplacer->handlePlaceholder($placeholder, $label_target->getPart());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -46,7 +46,7 @@ class NodesListBuilder
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets a flattened hierachical tree. Useful for generating option lists.
|
* Gets a flattened hierarchical tree. Useful for generating option lists.
|
||||||
* In difference to the Repository Function, the results here are cached.
|
* In difference to the Repository Function, the results here are cached.
|
||||||
*
|
*
|
||||||
* @param string $class_name the class name of the entity you want to retrieve
|
* @param string $class_name the class name of the entity you want to retrieve
|
||||||
|
@ -66,6 +66,7 @@ class NodesListBuilder
|
||||||
$item->tag(['groups', 'tree_list', $this->keyGenerator->generateKey(), $secure_class_name]);
|
$item->tag(['groups', 'tree_list', $this->keyGenerator->generateKey(), $secure_class_name]);
|
||||||
/** @var StructuralDBElementRepository $repo */
|
/** @var StructuralDBElementRepository $repo */
|
||||||
$repo = $this->em->getRepository($class_name);
|
$repo = $this->em->getRepository($class_name);
|
||||||
|
|
||||||
return $repo->toNodesList($parent);
|
return $repo->toNodesList($parent);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,6 +25,8 @@
|
||||||
{{ form_row(form.is_full) }}
|
{{ form_row(form.is_full) }}
|
||||||
{{ form_row(form.limit_to_existing_parts) }}
|
{{ form_row(form.limit_to_existing_parts) }}
|
||||||
{{ form_row(form.only_single_part) }}
|
{{ form_row(form.only_single_part) }}
|
||||||
|
{{ form_row(form.owner) }}
|
||||||
|
{{ form_row(form.part_owner_must_match) }}
|
||||||
</div>
|
</div>
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
||||||
|
|
|
@ -22,6 +22,7 @@
|
||||||
{{ form_row(form.last_name) }}
|
{{ form_row(form.last_name) }}
|
||||||
{{ form_row(form.email) }}
|
{{ form_row(form.email) }}
|
||||||
{{ form_row(form.department) }}
|
{{ form_row(form.department) }}
|
||||||
|
{{ form_row(form.aboutMe) }}
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
||||||
{% block additional_panes %}
|
{% block additional_panes %}
|
||||||
|
@ -33,9 +34,11 @@
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="tab-pane" id="password">
|
<div class="tab-pane" id="password">
|
||||||
|
{% if entity.samlUser %}
|
||||||
<div class="offset-3 mb-3 col-9">
|
<div class="offset-3 mb-3 col-9">
|
||||||
<span class="badge badge-warning bg-warning"><i class="fa-solid fa-house-user"></i> {% trans %}user.saml_user{% endtrans %}</span>
|
<span class="badge badge-warning bg-warning"><i class="fa-solid fa-house-user"></i> {% trans %}user.saml_user{% endtrans %}</span>
|
||||||
</div>
|
</div>
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
{{ form_row(form.new_password) }}
|
{{ form_row(form.new_password) }}
|
||||||
{{ form_row(form.need_pw_change) }}
|
{{ form_row(form.need_pw_change) }}
|
||||||
|
|
|
@ -159,11 +159,7 @@
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
{% if user is not null %}
|
{% if user is not null %}
|
||||||
{% if user.fullName is not empty %}
|
({{ _self.user_icon_link(user) }})
|
||||||
({{ _self.user_icon(user) }} <a href="{{ path('user_info', {"id": user.id}) }}" title="@{{ user.name }}">{{ user.fullName }}</a>)
|
|
||||||
{% else %}
|
|
||||||
({{ _self.user_icon(user) }} <a href="{{ path('user_info', {"id": user.id}) }}" title="@{{ user.name }}">@{{ user.name }}</a>)
|
|
||||||
{% endif %}
|
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% endmacro %}
|
{% endmacro %}
|
||||||
|
@ -180,6 +176,14 @@
|
||||||
<img src="{{ avatar_helper.avatarSmURL(user) }}" class="avatar-xs" alt="User avatar" {{ stimulus_controller('elements/hoverpic') }} data-thumbnail="{{ avatar_helper.avatarMdURL(user) }}">
|
<img src="{{ avatar_helper.avatarSmURL(user) }}" class="avatar-xs" alt="User avatar" {{ stimulus_controller('elements/hoverpic') }} data-thumbnail="{{ avatar_helper.avatarMdURL(user) }}">
|
||||||
{% endmacro %}
|
{% endmacro %}
|
||||||
|
|
||||||
|
{% macro user_icon_link(user) %}
|
||||||
|
{% if user.fullName is not empty %}
|
||||||
|
{{ _self.user_icon(user) }} <a href="{{ path('user_info', {"id": user.id}) }}" title="@{{ user.name }}">{{ user.fullName }}</a>
|
||||||
|
{% else %}
|
||||||
|
{{ _self.user_icon(user) }} <a href="{{ path('user_info', {"id": user.id}) }}" title="@{{ user.name }}">@{{ user.name }}</a>
|
||||||
|
{% endif %}
|
||||||
|
{% endmacro %}
|
||||||
|
|
||||||
{% macro entity_preview_sm(entity) %}
|
{% macro entity_preview_sm(entity) %}
|
||||||
{# @var entity \App\Entity\Contracts\HasMasterAttachmentInterface #}
|
{# @var entity \App\Entity\Contracts\HasMasterAttachmentInterface #}
|
||||||
{% if entity.masterPictureAttachment and entity.masterPictureAttachment.picture and attachment_manager.fileExisting(entity.masterPictureAttachment) %}
|
{% if entity.masterPictureAttachment and entity.masterPictureAttachment.picture and attachment_manager.fileExisting(entity.masterPictureAttachment) %}
|
||||||
|
|
|
@ -41,21 +41,26 @@
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
<h6>
|
<h6>
|
||||||
|
{% if lot.owner %}
|
||||||
|
<span class="badge bg-light mb-1" title="{% trans %}part_lot.owner{% endtrans %}">
|
||||||
|
{{ helper.user_icon_link(lot.owner) }}
|
||||||
|
</span><br>
|
||||||
|
{% endif %}
|
||||||
{% if lot.expirationDate %}
|
{% if lot.expirationDate %}
|
||||||
<span class="badge bg-info" title="{% trans %}part_lots.expiration_date{% endtrans %}">
|
<span class="badge bg-info mb-1" title="{% trans %}part_lots.expiration_date{% endtrans %}">
|
||||||
<i class="fas fa-calendar-alt fa-fw"></i> {{ lot.expirationDate | format_date() }}
|
<i class="fas fa-calendar-alt fa-fw"></i> {{ lot.expirationDate | format_date() }}<br>
|
||||||
</span>
|
</span>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% if lot.expired %}
|
{% if lot.expired %}
|
||||||
<br>
|
<br>
|
||||||
<span class="badge bg-warning">
|
<span class="badge bg-warning mb-1">
|
||||||
<i class="fas fa-exclamation-circle fa-fw"></i>
|
<i class="fas fa-exclamation-circle fa-fw"></i>
|
||||||
{% trans %}part_lots.is_expired{% endtrans %}
|
{% trans %}part_lots.is_expired{% endtrans %}
|
||||||
</span>
|
</span>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% if lot.needsRefill %}
|
{% if lot.needsRefill %}
|
||||||
<br>
|
<br>
|
||||||
<span class="badge bg-warning">
|
<span class="badge bg-warning mb-1">
|
||||||
<i class="fas fa-dolly fa-fw"></i>
|
<i class="fas fa-dolly fa-fw"></i>
|
||||||
{% trans %}part_lots.need_refill{% endtrans %}
|
{% trans %}part_lots.need_refill{% endtrans %}
|
||||||
</span>
|
</span>
|
||||||
|
|
|
@ -64,6 +64,11 @@
|
||||||
{% endif %}
|
{% endif %}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
{% if user.aboutMe is not empty %}
|
||||||
|
<hr>
|
||||||
|
<h5>{% trans %}user.aboutMe.label{% endtrans %}</h5>
|
||||||
|
{{ user.aboutMe | format_markdown }}
|
||||||
|
{% endif %}
|
||||||
</div>
|
</div>
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
||||||
|
|
|
@ -34,6 +34,7 @@
|
||||||
{{ form_widget(settings_form.remove_avatar) }}
|
{{ form_widget(settings_form.remove_avatar) }}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
{{ form_row(settings_form.aboutMe) }}
|
||||||
</div>
|
</div>
|
||||||
<div class="tab-pane fade" id="configuration" role="tabpanel" aria-labelledby="profile-tab">
|
<div class="tab-pane fade" id="configuration" role="tabpanel" aria-labelledby="profile-tab">
|
||||||
{{ form_row(settings_form.language) }}
|
{{ form_row(settings_form.language) }}
|
||||||
|
|
|
@ -11199,5 +11199,59 @@ Element 3</target>
|
||||||
<target>Edit Measurement Unit</target>
|
<target>Edit Measurement Unit</target>
|
||||||
</segment>
|
</segment>
|
||||||
</unit>
|
</unit>
|
||||||
|
<unit id="gRatnCn" name="user.aboutMe.label">
|
||||||
|
<segment>
|
||||||
|
<source>user.aboutMe.label</source>
|
||||||
|
<target>About Me</target>
|
||||||
|
</segment>
|
||||||
|
</unit>
|
||||||
|
<unit id="WsHXARp" name="storelocation.owner.label">
|
||||||
|
<segment>
|
||||||
|
<source>storelocation.owner.label</source>
|
||||||
|
<target>Owner</target>
|
||||||
|
</segment>
|
||||||
|
</unit>
|
||||||
|
<unit id="VQ97Dh0" name="storelocation.part_owner_must_match.label">
|
||||||
|
<segment>
|
||||||
|
<source>storelocation.part_owner_must_match.label</source>
|
||||||
|
<target>Part Lot owner must match storage location owner</target>
|
||||||
|
</segment>
|
||||||
|
</unit>
|
||||||
|
<unit id="sddE1L." name="part_lot.owner">
|
||||||
|
<segment>
|
||||||
|
<source>part_lot.owner</source>
|
||||||
|
<target>Owner</target>
|
||||||
|
</segment>
|
||||||
|
</unit>
|
||||||
|
<unit id="XKIMr8j" name="part_lot.owner.help">
|
||||||
|
<segment>
|
||||||
|
<source>part_lot.owner.help</source>
|
||||||
|
<target>Only the owner can withdraw or add stock to this lot.</target>
|
||||||
|
</segment>
|
||||||
|
</unit>
|
||||||
|
<unit id="61.yfNy" name="log.element_edited.changed_fields.owner">
|
||||||
|
<segment>
|
||||||
|
<source>log.element_edited.changed_fields.owner</source>
|
||||||
|
<target>Owner</target>
|
||||||
|
</segment>
|
||||||
|
</unit>
|
||||||
|
<unit id="YkZAIS8" name="log.element_edited.changed_fields.instock_unknown">
|
||||||
|
<segment>
|
||||||
|
<source>log.element_edited.changed_fields.instock_unknown</source>
|
||||||
|
<target>Amount unknown</target>
|
||||||
|
</segment>
|
||||||
|
</unit>
|
||||||
|
<unit id="xf7NNZ9" name="log.element_edited.changed_fields.needs_refill">
|
||||||
|
<segment>
|
||||||
|
<source>log.element_edited.changed_fields.needs_refill</source>
|
||||||
|
<target>Refill needed</target>
|
||||||
|
</segment>
|
||||||
|
</unit>
|
||||||
|
<unit id="Gfw_MWL" name="part.withdraw.access_denied">
|
||||||
|
<segment>
|
||||||
|
<source>part.withdraw.access_denied</source>
|
||||||
|
<target>Not allowed to do the desired action. Please check your permissions and the owner of the part lots.</target>
|
||||||
|
</segment>
|
||||||
|
</unit>
|
||||||
</file>
|
</file>
|
||||||
</xliff>
|
</xliff>
|
||||||
|
|
|
@ -305,5 +305,11 @@
|
||||||
<target>Set a value here, or upload a file to automatically use its filename as name for the attachment.</target>
|
<target>Set a value here, or upload a file to automatically use its filename as name for the attachment.</target>
|
||||||
</segment>
|
</segment>
|
||||||
</unit>
|
</unit>
|
||||||
|
<unit id="nwGaNBW" name="validator.part_lot.owner_must_match_storage_location_owner">
|
||||||
|
<segment>
|
||||||
|
<source>validator.part_lot.owner_must_match_storage_location_owner</source>
|
||||||
|
<target>The owner of this lot must match the owner of the selected storage location (%owner_name%)!</target>
|
||||||
|
</segment>
|
||||||
|
</unit>
|
||||||
</file>
|
</file>
|
||||||
</xliff>
|
</xliff>
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue